diff --git a/Jenkinsfile b/Jenkinsfile index 7ca498696b..d78ed6f5c9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,2 +1,2 @@ @Library('pipeline-library')_ -FullVitisLibPipeline (branch: 'next', libname: 'Vitis_Libraries', TARGETS: 'hls_csim:hls_csynth:hls_cosim:hls_vivado_impl:vitis_sw_emu:vitis_hw_emu:vitis_hw_build:vitis_aie_sim:vitis_aie_x86sim', TOOLVERSION: '2021.2_stable_latest') +FullVitisLibPipeline (branch: 'master', libname: 'Vitis_Libraries', TARGETS: 'hls_csim:hls_csynth:hls_cosim:hls_vivado_impl:vitis_sw_emu:vitis_hw_emu:vitis_hw_build:vitis_aie_sim:vitis_aie_x86sim', TOOLVERSION: '2021.2_released') diff --git a/codec/Jenkinsfile b/codec/Jenkinsfile index 1bc0e483d0..f9f137189a 100644 --- a/codec/Jenkinsfile +++ b/codec/Jenkinsfile @@ -1,4 +1,4 @@ @Library('pipeline-library')_ -VitisLibPipeline (branch: 'next', libname: 'xf_codec', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', - upstream_dependencies: 'xf_utils_hw,next,../utils; xf_database,next,../database; xf_fintech,next,../quantitative_finance', - email: 'siyangw@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_stable_latest') +VitisLibPipeline (branch: 'master', libname: 'xf_codec', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', + upstream_dependencies: 'xf_utils_hw,master,../utils; xf_database,master,../database; xf_fintech,master,../quantitative_finance', + email: 'siyangw@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_released') diff --git a/codec/L1/include/hls_EncodeCoeffOrders.hpp b/codec/L1/include/hls_EncodeCoeffOrders.hpp new file mode 100644 index 0000000000..9b833c3427 --- /dev/null +++ b/codec/L1/include/hls_EncodeCoeffOrders.hpp @@ -0,0 +1,484 @@ +/* + * Copyright 2019 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file hls_EncodeCoeffOrders.hpp + * + * @brief This file contains top function of test case. + */ + +#ifndef _HLS_ENCODE_TOKENS_HPP_ +#define _HLS_ENCODE_TOKENS_HPP_ + +#include +#include +#include + +namespace xf { +namespace codec { +namespace internal { + +const size_t LENGTH = 1024; +const size_t kBlockDim = 8; +const size_t kDCTBlockSize = 64; +const size_t kMaxCoeffBlocks = 32; +const size_t kMaxBlockDim = kBlockDim * kMaxCoeffBlocks; +const size_t kMaxCoeffArea = kMaxBlockDim * kMaxBlockDim; +const uint32_t kPermutationContexts = 8; + +struct HybridUint { + HybridUint(ap_uint<32> split, ap_uint<32> msb, ap_uint<32> lsb) + : split_exponent(split), msb_in_token(msb), lsb_in_token(lsb) {} + ap_uint<32> split_exponent; + ap_uint<32> msb_in_token; + ap_uint<32> lsb_in_token; +}; + +enum Type { + // Regular block size DCT + DCT = 0, + // Encode pixels without transforming + IDENTITY = 1, + // Use 2-by-2 DCT + DCT2X2 = 2, + // Use 4-by-4 DCT + DCT4X4 = 3, + // Use 16-by-16 DCT + DCT16X16 = 4, + // Use 32-by-32 DCT + DCT32X32 = 5, + // Use 16-by-8 DCT + DCT16X8 = 6, + // Use 8-by-16 DCT + DCT8X16 = 7, + // Use 32-by-8 DCT + DCT32X8 = 8, + // Use 8-by-32 DCT + DCT8X32 = 9, + // Use 32-by-16 DCT + DCT32X16 = 10, + // Use 16-by-32 DCT + DCT16X32 = 11, + // 4x8 and 8x4 DCT + DCT4X8 = 12, + DCT8X4 = 13, + // Corner-DCT. + AFV0 = 14, + AFV1 = 15, + AFV2 = 16, + AFV3 = 17, + // Larger DCTs + DCT64X64 = 18, + DCT64X32 = 19, + DCT32X64 = 20, + DCT128X128 = 21, + DCT128X64 = 22, + DCT64X128 = 23, + DCT256X256 = 24, + DCT256X128 = 25, + DCT128X256 = 26, + // Marker for num of valid strategies. + kNumValidStrategies +}; + +static constexpr size_t kOffset[kNumValidStrategies + 1] = { + 0, 1, 2, 3, 4, 8, 24, 26, 28, 32, 36, 44, 52, 53, + 54, 55, 56, 57, 58, 122, 154, 186, 442, 570, 698, 1722, 2234, 2746, +}; + +constexpr uint8_t kStrategyOrder[] = {0, 1, 1, 1, 2, 3, 4, 4, 5, 5, 6, 6, 1, 1, + 1, 1, 1, 1, 7, 8, 8, 9, 10, 10, 11, 12, 12}; + +static constexpr size_t coeffOrderLut[1536] = { + 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, + 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, + 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, + 63, 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, + 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, + 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, + 62, 63, 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, + 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, + 58, 62, 63, 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, + 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, + 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, + 57, 58, 62, 63, 0, 1, 5, 6, 14, 15, 27, 28, 44, 45, 65, 66, 90, 91, 119, 120, 2, + 3, 7, 13, 16, 26, 29, 43, 46, 64, 67, 89, 92, 118, 121, 150, 4, 8, 12, 17, 25, 30, + 42, 47, 63, 68, 88, 93, 117, 122, 149, 151, 9, 11, 18, 24, 31, 41, 48, 62, 69, 87, 94, + 116, 123, 148, 152, 177, 10, 19, 23, 32, 40, 49, 61, 70, 86, 95, 115, 124, 147, 153, 176, 178, + 20, 22, 33, 39, 50, 60, 71, 85, 96, 114, 125, 146, 154, 175, 179, 200, 21, 34, 38, 51, 59, + 72, 84, 97, 113, 126, 145, 155, 174, 180, 199, 201, 35, 37, 52, 58, 73, 83, 98, 112, 127, 144, + 156, 173, 181, 198, 202, 219, 36, 53, 57, 74, 82, 99, 111, 128, 143, 157, 172, 182, 197, 203, 218, + 220, 54, 56, 75, 81, 100, 110, 129, 142, 158, 171, 183, 196, 204, 217, 221, 234, 55, 76, 80, 101, + 109, 130, 141, 159, 170, 184, 195, 205, 216, 222, 233, 235, 77, 79, 102, 108, 131, 140, 160, 169, 185, + 194, 206, 215, 223, 232, 236, 245, 78, 103, 107, 132, 139, 161, 168, 186, 193, 207, 214, 224, 231, 237, + 244, 246, 104, 106, 133, 138, 162, 167, 187, 192, 208, 213, 225, 230, 238, 243, 247, 252, 105, 134, 137, + 163, 166, 188, 191, 209, 212, 226, 229, 239, 242, 248, 251, 253, 135, 136, 164, 165, 189, 190, 210, 211, + 227, 228, 240, 241, 249, 250, 254, 255, 0, 1, 2, 3, 17, 18, 27, 28, 44, 45, 65, 66, 90, + 91, 119, 120, 152, 153, 189, 190, 230, 231, 275, 276, 324, 325, 377, 378, 434, 435, 495, 496, 4, 5, + 6, 7, 19, 26, 29, 43, 46, 64, 67, 89, 92, 118, 121, 151, 154, 188, 191, 229, 232, 274, 277, + 323, 326, 376, 379, 433, 436, 494, 497, 558, 8, 9, 10, 11, 25, 30, 42, 47, 63, 68, 88, 93, + 117, 122, 150, 155, 187, 192, 228, 233, 273, 278, 322, 327, 375, 380, 432, 437, 493, 498, 557, 559, 12, + 13, 14, 15, 31, 41, 48, 62, 69, 87, 94, 116, 123, 149, 156, 186, 193, 227, 234, 272, 279, 321, + 328, 374, 381, 431, 438, 492, 499, 556, 560, 617, 16, 20, 24, 32, 40, 49, 61, 70, 86, 95, 115, + 124, 148, 157, 185, 194, 226, 235, 271, 280, 320, 329, 373, 382, 430, 439, 491, 500, 555, 561, 616, 618, + 21, 23, 33, 39, 50, 60, 71, 85, 96, 114, 125, 147, 158, 184, 195, 225, 236, 270, 281, 319, 330, + 372, 383, 429, 440, 490, 501, 554, 562, 615, 619, 672, 22, 34, 38, 51, 59, 72, 84, 97, 113, 126, + 146, 159, 183, 196, 224, 237, 269, 282, 318, 331, 371, 384, 428, 441, 489, 502, 553, 563, 614, 620, 671, + 673, 35, 37, 52, 58, 73, 83, 98, 112, 127, 145, 160, 182, 197, 223, 238, 268, 283, 317, 332, 370, + 385, 427, 442, 488, 503, 552, 564, 613, 621, 670, 674, 723, 36, 53, 57, 74, 82, 99, 111, 128, 144, + 161, 181, 198, 222, 239, 267, 284, 316, 333, 369, 386, 426, 443, 487, 504, 551, 565, 612, 622, 669, 675, + 722, 724, 54, 56, 75, 81, 100, 110, 129, 143, 162, 180, 199, 221, 240, 266, 285, 315, 334, 368, 387, + 425, 444, 486, 505, 550, 566, 611, 623, 668, 676, 721, 725, 770, 55, 76, 80, 101, 109, 130, 142, 163, + 179, 200, 220, 241, 265, 286, 314, 335, 367, 388, 424, 445, 485, 506, 549, 567, 610, 624, 667, 677, 720, + 726, 769, 771, 77, 79, 102, 108, 131, 141, 164, 178, 201, 219, 242, 264, 287, 313, 336, 366, 389, 423, + 446, 484, 507, 548, 568, 609, 625, 666, 678, 719, 727, 768, 772, 813, 78, 103, 107, 132, 140, 165, 177, + 202, 218, 243, 263, 288, 312, 337, 365, 390, 422, 447, 483, 508, 547, 569, 608, 626, 665, 679, 718, 728, + 767, 773, 812, 814, 104, 106, 133, 139, 166, 176, 203, 217, 244, 262, 289, 311, 338, 364, 391, 421, 448, + 482, 509, 546, 570, 607, 627, 664, 680, 717, 729, 766, 774, 811, 815, 852, 105, 134, 138, 167, 175, 204, + 216, 245, 261, 290, 310, 339, 363, 392, 420, 449, 481, 510, 545, 571, 606, 628, 663, 681, 716, 730, 765, + 775, 810, 816, 851, 853, 135, 137, 168, 174, 205, 215, 246, 260, 291, 309, 340, 362, 393, 419, 450, 480, + 511, 544, 572, 605, 629, 662, 682, 715, 731, 764, 776, 809, 817, 850, 854, 887, 136, 169, 173, 206, 214, + 247, 259, 292, 308, 341, 361, 394, 418, 451, 479, 512, 543, 573, 604, 630, 661, 683, 714, 732, 763, 777, + 808, 818, 849, 855, 886, 888, 170, 172, 207, 213, 248, 258, 293, 307, 342, 360, 395, 417, 452, 478, 513, + 542, 574, 603, 631, 660, 684, 713, 733, 762, 778, 807, 819, 848, 856, 885, 889, 918, 171, 208, 212, 249, + 257, 294, 306, 343, 359, 396, 416, 453, 477, 514, 541, 575, 602, 632, 659, 685, 712, 734, 761, 779, 806, + 820, 847, 857, 884, 890, 917, 919, 209, 211, 250, 256, 295, 305, 344, 358, 397, 415, 454, 476, 515, 540, + 576, 601, 633, 658, 686, 711, 735, 760, 780, 805, 821, 846, 858, 883, 891, 916, 920, 945, 210, 251, 255, + 296, 304, 345, 357, 398, 414, 455, 475, 516, 539, 577, 600, 634, 657, 687, 710, 736, 759, 781, 804, 822, + 845, 859, 882, 892, 915, 921, 944, 946, 252, 254, 297, 303, 346, 356, 399, 413, 456, 474, 517, 538, 578, + 599, 635, 656, 688, 709, 737, 758, 782, 803, 823, 844, 860, 881, 893, 914, 922, 943, 947, 968, 253, 298, + 302, 347, 355, 400, 412, 457, 473, 518, 537, 579, 598, 636, 655, 689, 708, 738, 757, 783, 802, 824, 843, + 861, 880, 894, 913, 923, 942, 948, 967, 969, 299, 301, 348, 354, 401, 411, 458, 472, 519, 536, 580, 597, + 637, 654, 690, 707, 739, 756, 784, 801, 825, 842, 862, 879, 895, 912, 924, 941, 949, 966, 970, 987, 300, + 349, 353, 402, 410, 459, 471, 520, 535, 581, 596, 638, 653, 691, 706, 740, 755, 785, 800, 826, 841, 863, + 878, 896, 911, 925, 940, 950, 965, 971, 986, 988, 350, 352, 403, 409, 460, 470, 521, 534, 582, 595, 639, + 652, 692, 705, 741, 754, 786, 799, 827, 840, 864, 877, 897, 910, 926, 939, 951, 964, 972, 985, 989, 1002, + 351, 404, 408, 461, 469, 522, 533, 583, 594, 640, 651, 693, 704, 742, 753, 787, 798, 828, 839, 865, 876, + 898, 909, 927, 938, 952, 963, 973, 984, 990, 1001, 1003, 405, 407, 462, 468, 523, 532, 584, 593, 641, 650, + 694, 703, 743, 752, 788, 797, 829, 838, 866, 875, 899, 908, 928, 937, 953, 962, 974, 983, 991, 1000, 1004, + 1013, 406, 463, 467, 524, 531, 585, 592, 642, 649, 695, 702, 744, 751, 789, 796, 830, 837, 867, 874, 900, + 907, 929, 936, 954, 961, 975, 982, 992, 999, 1005, 1012, 1014, 464, 466, 525, 530, 586, 591, 643, 648, 696, + 701, 745, 750, 790, 795, 831, 836, 868, 873, 901, 906, 930, 935, 955, 960, 976, 981, 993, 998, 1006, 1011, + 1015, 1020, 465, 526, 529, 587, 590, 644, 647, 697, 700, 746, 749, 791, 794, 832, 835, 869, 872, 902, 905, + 931, 934, 956, 959, 977, 980, 994, 997, 1007, 1010, 1016, 1019, 1021, 527, 528, 588, 589, 645, 646, 698, 699, + 747, 748, 792, 793, 833, 834, 870, 871, 903, 904, 932, 933, 957, 958, 978, 979, 995, 996, 1008, 1009, 1017, + 1018, 1022, 1023}; + +static constexpr size_t kTotalTableSize = kOffset[kNumValidStrategies] * kDCTBlockSize; + +void hls_Encode(HybridUint& config, ap_uint<32> value, ap_uint<32>& token, ap_uint<32>& nbits, ap_uint<32>& bits) { + ap_uint<32> split_exponent = config.split_exponent; + ap_uint<32> split_token = 1 << split_exponent; + ap_uint<32> msb_in_token = config.msb_in_token; + ap_uint<32> lsb_in_token = config.lsb_in_token; + + // if(split_exponent >= msb_in_token + lsb_in_token) + // std::cout << "split_exponent" << "\n"; + if (value < split_token) { + token = value; + nbits = 0; + bits = 0; + } else { + ap_uint<32> n = 32 - value.countLeadingZeros() - 1; // FloorLog2Nonzero(value); + ap_uint<32> m = value - (1 << n); + token = split_token + ((n - split_exponent) << (msb_in_token + lsb_in_token)) + + ((m >> (n - msb_in_token)) << lsb_in_token) + (m & ((1 << lsb_in_token) - 1)); + nbits = n - msb_in_token - lsb_in_token; + bits = (value >> lsb_in_token) & ((1UL << nbits) - 1); + } +} + +ap_uint<32> hls_CoeffOrderContext(ap_uint<32> val) { + ap_uint<32> token, nbits, bits; + ap_uint<32> mins = 7; + HybridUint config(0, 0, 0); + hls_Encode(config, val, token, nbits, bits); + return (token < mins) ? token : mins; +} + +void scanStrategy(uint16_t used_orders, + ap_uint<32>& num_strategy, + hls::stream >& strategyStrm, + hls::stream > skipStrm[3]) { +#pragma HLS INLINE off + uint16_t computed = 0; + ap_uint<32> order; +SCAN_STRATEGY: + for (ap_uint<3> o = 0; o < 6; o++) { +#pragma HLS PIPELINE II = 1 + ap_uint<8> order = kStrategyOrder[o]; + if (!(computed & (1 << order))) { + computed |= 1 << order; + if ((used_orders & (1 << order)) != 0) { + num_strategy++; + strategyStrm.write(o); + if (o == Type::DCT) { + skipStrm[0].write(1); + skipStrm[1].write(1); + skipStrm[2].write(1); + } else if (o == Type::IDENTITY) { + skipStrm[0].write(1); + skipStrm[1].write(1); + skipStrm[2].write(1); + } else if (o == Type::DCT2X2) { + skipStrm[0].write(1); + skipStrm[1].write(1); + skipStrm[2].write(1); + } else if (o == Type::DCT4X4) { + skipStrm[0].write(1); + skipStrm[1].write(1); + skipStrm[2].write(1); + } else if (o == Type::DCT16X16) { + skipStrm[0].write(4); + skipStrm[1].write(4); + skipStrm[2].write(4); + } else if (o == Type::DCT32X32) { + skipStrm[0].write(16); + skipStrm[1].write(16); + skipStrm[2].write(16); + } + } + } + } +} + +void loadZigzag(ap_uint<32>& num_strategy, + hls::stream >& strategyStrm, + hls::stream >& skipStrm, + hls::stream >& orderStrm, + hls::stream >& zigzagStrm) { +#pragma HLS INLINE off + + ap_uint<32> skip; + ap_uint<32> order; + ap_uint<32> zigzag; + ap_uint<32> kOffset; + ap_uint<8> strategy; + for (ap_uint<8> o = 0; o < num_strategy; o++) { + strategyStrm.read(strategy); + if (strategy == Type::DCT) { + kOffset = 0; + } else if (strategy == Type::IDENTITY) { + kOffset = 64; + } else if (strategy == Type::DCT2X2) { + kOffset = 128; + } else if (strategy == Type::DCT4X4) { + kOffset = 192; + } else if (strategy == Type::DCT16X16) { + kOffset = 256; + } else if (strategy == Type::DCT32X32) { + kOffset = 512; + } else { + std::cerr << "The strategy is invaild!" << std::endl; + } + skipStrm.read(skip); + ap_uint<32> size = skip << 6; + CHANNELS: + for (ap_uint<2> c = 0; c < 3; c++) { + ZIGZAG_LOOP: + for (ap_uint<32> i = 0; i < size; i++) { +#pragma HLS PIPELINE II = 1 + orderStrm.read(order); + zigzag = coeffOrderLut[kOffset + order]; + zigzagStrm.write(zigzag); + } + } + } +} + +void initTemp(ap_uint<16> temp[LENGTH + 1]) { +#pragma HLS INLINE off +INIT_TEMP_PONG: + for (ap_uint<32> i = 0; i < LENGTH + 1; i++) { +#pragma HLS PIPELINE II = 1 + temp[i] = 0; + } +} + +void lehmerCore(ap_uint<32> skip, + ap_uint<32> size, + ap_uint<16> temp[LENGTH + 1], + ap_uint<32>& end, + hls::stream >& zigzagStrm, + hls::stream >& lehmerStrm) { +#pragma HLS INLINE off + ap_uint<32> lehmer; // [LENGTH]; + for (ap_uint<32> idx = 0; idx < size; idx++) { + ap_uint<32> penalty = 0; + ap_uint<32> s = zigzagStrm.read(); + uint32_t i = s + 1; + LEHMER_LOOP0: + while (i != 0) { +#pragma HLS PIPELINE II = 1 + penalty += temp[i]; + i &= i - 1; + } + // if(s >= penalty) + // std::cout << "Warning: s>=penalty!" << std::endl; + lehmer = s - penalty; + if (lehmer != 0) end = idx; + if (idx >= skip) lehmerStrm.write(lehmer); + i = s + 1; + LEHMER_LOOP1: + while (i < size + 1) { +#pragma HLS PIPELINE II = 1 + temp[i] += 1; + i += (i & -i); + } + } +} + +void updateCore(ap_uint<32> skip, + ap_uint<32> size, + ap_uint<16> ping[LENGTH + 1], + ap_uint<16> pong[LENGTH + 1], + ap_uint<32>& end, + hls::stream >& zigzagStrm, + hls::stream >& lehmerStrm) { +#pragma HLS INLINE off +#pragma HLS DATAFLOW + initTemp(ping); + lehmerCore(skip, size, pong, end, zigzagStrm, lehmerStrm); +} + +void updateLehmer(ap_uint<32> acs, + hls::stream >& skipStrm, + hls::stream >& endStrm, + hls::stream >& zigzagStrm, + hls::stream >& lehmerStrm) { +#pragma HLS INLINE off + ap_uint<1> flag = 0; + ap_uint<16> temp[2][LENGTH + 1]; +#pragma HLS RESOURCE variable = temp core = RAM_2P_BRAM +#pragma HLS ARRAY_PARTITION variable = temp complete dim = 1 +INIT_TEMP_PING: + for (ap_uint<32> i = 0; i < LENGTH + 1; i++) { +#pragma HLS PIPELINE II = 1 + temp[1][i] = 0; + } + for (ap_uint<8> o = 0; o < acs; o++) { + ap_uint<32> skip = skipStrm.read(); + ap_uint<32> size = kDCTBlockSize * skip; + for (ap_uint<2> c = 0; c < 3; c++) { + ap_uint<32> end = 0; + if (flag == 0) + updateCore(skip, size, temp[0], temp[1], end, zigzagStrm, lehmerStrm); + else + updateCore(skip, size, temp[1], temp[0], end, zigzagStrm, lehmerStrm); + flag++; + endStrm.write(++end); + } + } +} + +void updateToken(ap_uint<32> acs, + hls::stream >& skipStrm, + hls::stream >& endStrm, + hls::stream >& lehmerStrm, + hls::stream >& tokenStrm, + hls::stream& e_token) { +#pragma HLS INLINE off + + ap_uint<64> token; + ap_uint<32> lehmer; + ap_uint<32> skip; + for (ap_uint<8> o = 0; o < acs; o++) { + skipStrm.read(skip); + ap_uint<32> size = kDCTBlockSize * skip; + for (ap_uint<2> c = 0; c < 3; c++) { + ap_uint<32> last = 0; + token.range(31, 0) = hls_CoeffOrderContext(size); + ap_uint<32> end = endStrm.read(); + token.range(63, 32) = end - skip; + tokenStrm.write(token); + e_token.write(false); + + TOKEN_LOOP: + for (ap_uint<32> i = skip; i < end; ++i) { +#pragma HLS PIPELINE II = 1 + token.range(31, 0) = hls_CoeffOrderContext(last); + lehmerStrm.read(lehmer); + token.range(63, 32) = lehmer; + tokenStrm.write(token); + e_token.write(false); + last = lehmer; + } + TOKEN_LEFTOVER: + for (ap_uint<32> i = end; i < size; ++i) +#pragma HLS PIPELINE II = 1 + lehmerStrm.read(lehmer); + } + } + e_token.write(true); +} + +} // internal + +/** + * @brief jpegxl order tokenize function. + * + * @tparam used_orders the input for complete ac type + * @tparam orderStrm the input for image scan order + * @tparam tokenStrm the output for tokens initialization + * @tparam e_tokenStrm the output for tokens stream + */ +void hls_EncodeCoeffOrders(ap_uint<32> used_orders, + hls::stream >& orderStrm, + hls::stream >& tokenStrm, + hls::stream& e_tokenStrm) { +#pragma HLS INLINE off +#pragma HLS DATAFLOW + + hls::stream > strategyStrm("strategyStrm"); + +#pragma HLS ARRAY_PARTITION variable = strategyStrm complete dim = 0 +#pragma HLS RESOURCE variable = strategyStrm core = FIFO_LUTRAM +#pragma HLS STREAM variable = strategyStrm depth = 32 + + hls::stream > zigzagStrm("zigzagStrm"); + +#pragma HLS ARRAY_PARTITION variable = zigzagStrm complete dim = 0 +#pragma HLS RESOURCE variable = zigzagStrm core = FIFO_LUTRAM +#pragma HLS STREAM variable = zigzagStrm depth = 128 + + hls::stream > skipStrm[3]; + +#pragma HLS ARRAY_PARTITION variable = skipStrm complete dim = 0 +#pragma HLS RESOURCE variable = skipStrm core = FIFO_LUTRAM +#pragma HLS STREAM variable = skipStrm depth = 32 + + hls::stream > endStrm("endStrm"); + +#pragma HLS ARRAY_PARTITION variable = endStrm complete dim = 0 +#pragma HLS RESOURCE variable = endStrm core = FIFO_LUTRAM +#pragma HLS STREAM variable = endStrm depth = 32 + + hls::stream > lehmerStrm("lehmerStrm"); + +#pragma HLS ARRAY_PARTITION variable = lehmerStrm complete dim = 0 +#pragma HLS RESOURCE variable = lehmerStrm core = FIFO_LUTRAM +#pragma HLS STREAM variable = lehmerStrm depth = 1024 + + ap_uint<32> num_strategy = 0; + internal::scanStrategy(used_orders, num_strategy, strategyStrm, skipStrm); + internal::loadZigzag(num_strategy, strategyStrm, skipStrm[0], orderStrm, zigzagStrm); + internal::updateLehmer(num_strategy, skipStrm[1], endStrm, zigzagStrm, lehmerStrm); + internal::updateToken(num_strategy, skipStrm[2], endStrm, lehmerStrm, tokenStrm, e_tokenStrm); +} +} // namespace +} // xf + +#endif // _HLS_ENCODE_TOKENS_HPP_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/Makefile b/codec/L1/tests/jxlEnc/order_tokenize/Makefile similarity index 99% rename from dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/Makefile rename to codec/L1/tests/jxlEnc/order_tokenize/Makefile index a6115a1db1..cb709456ae 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/Makefile +++ b/codec/L1/tests/jxlEnc/order_tokenize/Makefile @@ -239,7 +239,7 @@ runhls: data setup | check_vivado check_vpp $(HLS) -f run_hls.tcl; clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r4_l16.prj + rm -rf settings.tcl *_hls.log tokenize.prj # Used by Jenkins test cleanall: clean diff --git a/codec/L1/tests/jxlEnc/order_tokenize/data/goldens.txt b/codec/L1/tests/jxlEnc/order_tokenize/data/goldens.txt new file mode 100644 index 0000000000..43687af033 --- /dev/null +++ b/codec/L1/tests/jxlEnc/order_tokenize/data/goldens.txt @@ -0,0 +1,151 @@ +150 +7 0 +7 60 +0 0 +0 0 +0 2 +2 1 +1 1 +1 0 +0 0 +0 0 +0 4 +3 4 +3 0 +0 2 +2 5 +3 1 +1 1 +1 2 +2 1 +1 0 +0 6 +3 6 +3 5 +3 5 +3 0 +0 3 +2 0 +0 6 +3 4 +3 0 +0 1 +1 2 +2 1 +1 0 +0 0 +0 0 +0 5 +3 4 +3 0 +0 0 +0 0 +0 1 +1 7 +3 1 +1 0 +0 5 +3 1 +1 0 +0 0 +0 1 +1 8 +4 4 +3 0 +0 2 +2 0 +0 0 +0 0 +0 1 +1 1 +1 2 +2 0 +0 1 +7 6 +0 0 +0 0 +0 1 +1 0 +0 0 +0 2 +7 1 +0 1 +7 76 +0 1 +1 1 +1 0 +0 0 +0 0 +0 5 +3 0 +0 3 +2 2 +2 1 +1 1 +1 1 +1 1 +1 1 +1 0 +0 0 +0 4 +3 5 +3 5 +3 4 +3 3 +2 0 +0 1 +1 2 +2 2 +2 2 +2 2 +2 1 +1 1 +1 1 +1 6 +3 6 +3 0 +0 4 +3 4 +3 4 +3 4 +3 9 +4 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 1 +1 1 +1 1 +1 1 +1 3 +2 3 +2 3 +2 5 +3 5 +3 10 +4 10 +4 13 +4 14 +4 16 +5 27 +5 38 +7 1 +0 1 diff --git a/codec/L1/tests/jxlEnc/order_tokenize/data/orders.txt b/codec/L1/tests/jxlEnc/order_tokenize/data/orders.txt new file mode 100644 index 0000000000..4bff596536 --- /dev/null +++ b/codec/L1/tests/jxlEnc/order_tokenize/data/orders.txt @@ -0,0 +1,961 @@ +5 960 +0 +1 +8 +16 +9 +2 +3 +10 +17 +24 +32 +25 +18 +11 +4 +5 +12 +19 +26 +33 +40 +48 +41 +34 +27 +20 +13 +6 +7 +14 +21 +28 +35 +42 +49 +56 +57 +50 +43 +36 +29 +22 +15 +23 +30 +37 +44 +51 +58 +59 +52 +45 +38 +31 +39 +46 +53 +60 +61 +54 +47 +55 +62 +63 +0 +1 +8 +2 +9 +3 +16 +10 +17 +11 +4 +24 +18 +26 +25 +5 +19 +12 +32 +20 +13 +27 +6 +33 +34 +40 +35 +21 +48 +7 +28 +14 +41 +42 +49 +29 +36 +56 +57 +50 +22 +58 +15 +43 +59 +30 +23 +37 +51 +60 +31 +44 +38 +52 +45 +39 +53 +61 +47 +46 +55 +54 +62 +63 +0 +1 +8 +9 +16 +2 +17 +3 +10 +24 +32 +25 +18 +11 +4 +5 +12 +19 +26 +33 +40 +48 +41 +34 +27 +20 +13 +6 +7 +14 +21 +28 +35 +42 +49 +56 +57 +50 +43 +36 +29 +22 +15 +23 +30 +37 +44 +51 +58 +59 +52 +45 +38 +31 +39 +46 +53 +60 +61 +54 +47 +55 +62 +63 +0 +1 +16 +17 +2 +32 +3 +18 +33 +48 +64 +49 +34 +19 +4 +5 +20 +35 +50 +65 +80 +96 +81 +66 +51 +36 +21 +6 +7 +22 +37 +52 +67 +82 +97 +112 +128 +113 +98 +83 +68 +53 +38 +23 +8 +9 +24 +39 +54 +69 +84 +99 +114 +129 +144 +160 +145 +130 +115 +100 +85 +70 +55 +40 +25 +10 +11 +26 +41 +56 +71 +86 +101 +116 +131 +146 +161 +176 +192 +177 +162 +147 +132 +117 +102 +87 +72 +57 +42 +27 +12 +13 +28 +43 +58 +73 +88 +103 +118 +133 +148 +163 +178 +193 +208 +224 +209 +194 +179 +164 +149 +134 +119 +104 +89 +74 +59 +44 +29 +14 +15 +30 +45 +60 +75 +90 +105 +120 +135 +150 +165 +180 +195 +210 +225 +240 +241 +226 +211 +196 +181 +166 +151 +136 +121 +106 +91 +76 +61 +46 +31 +47 +62 +77 +92 +107 +122 +137 +152 +167 +182 +197 +212 +227 +242 +243 +228 +213 +198 +183 +168 +153 +138 +123 +108 +93 +78 +63 +79 +94 +109 +124 +139 +154 +169 +184 +199 +214 +229 +244 +245 +230 +215 +200 +185 +170 +155 +140 +125 +110 +95 +111 +126 +141 +156 +171 +186 +201 +216 +231 +246 +247 +232 +217 +202 +187 +172 +157 +142 +127 +143 +158 +173 +188 +203 +218 +233 +248 +249 +234 +219 +204 +189 +174 +159 +175 +190 +205 +220 +235 +250 +251 +236 +221 +206 +191 +207 +222 +237 +252 +253 +238 +223 +239 +254 +255 +0 +1 +16 +17 +2 +3 +32 +18 +33 +4 +48 +19 +34 +49 +5 +20 +35 +50 +64 +65 +51 +21 +6 +36 +66 +80 +81 +22 +37 +52 +67 +7 +82 +97 +68 +53 +96 +83 +38 +23 +8 +84 +112 +128 +113 +98 +9 +24 +39 +54 +69 +99 +114 +129 +144 +160 +145 +130 +115 +100 +85 +70 +55 +40 +10 +11 +26 +41 +86 +101 +116 +161 +176 +117 +102 +42 +12 +43 +224 +44 +25 +56 +71 +131 +146 +192 +177 +162 +147 +132 +87 +72 +57 +27 +13 +28 +58 +73 +88 +103 +118 +133 +148 +163 +178 +193 +208 +209 +194 +179 +164 +149 +134 +119 +104 +89 +74 +59 +29 +14 +15 +30 +45 +60 +75 +90 +105 +120 +135 +150 +165 +180 +195 +210 +225 +240 +241 +226 +211 +196 +181 +166 +151 +136 +121 +106 +91 +76 +61 +46 +31 +47 +62 +77 +92 +107 +122 +137 +152 +167 +182 +197 +212 +227 +242 +243 +228 +213 +198 +183 +168 +153 +138 +123 +108 +93 +78 +63 +79 +94 +109 +124 +139 +154 +169 +184 +199 +214 +229 +244 +245 +230 +215 +200 +185 +170 +155 +140 +125 +110 +95 +111 +126 +141 +156 +171 +186 +201 +216 +231 +246 +247 +232 +217 +202 +187 +172 +157 +142 +127 +143 +158 +173 +188 +203 +218 +233 +248 +249 +234 +219 +204 +189 +174 +159 +175 +190 +205 +220 +235 +250 +251 +236 +221 +206 +191 +207 +222 +237 +252 +253 +238 +223 +239 +254 +255 +0 +1 +16 +17 +2 +32 +3 +18 +33 +48 +64 +49 +34 +19 +4 +5 +20 +35 +50 +65 +80 +96 +81 +66 +51 +36 +21 +6 +7 +22 +37 +52 +67 +82 +97 +112 +128 +113 +98 +83 +68 +53 +38 +23 +8 +9 +24 +39 +54 +69 +84 +99 +114 +129 +144 +160 +145 +130 +115 +100 +85 +70 +55 +40 +25 +10 +11 +26 +41 +56 +71 +86 +101 +116 +131 +146 +161 +176 +192 +177 +162 +147 +132 +117 +102 +87 +72 +57 +42 +27 +12 +13 +28 +43 +58 +73 +88 +103 +118 +133 +148 +163 +178 +193 +208 +224 +209 +194 +179 +164 +149 +134 +119 +104 +89 +74 +59 +44 +29 +14 +15 +30 +45 +60 +75 +90 +105 +120 +135 +150 +165 +180 +195 +210 +225 +240 +241 +226 +211 +196 +181 +166 +151 +136 +121 +106 +91 +76 +61 +46 +31 +47 +62 +77 +92 +107 +122 +137 +152 +167 +182 +197 +212 +227 +242 +243 +228 +213 +198 +183 +168 +153 +138 +123 +108 +93 +78 +63 +79 +94 +109 +124 +139 +154 +169 +184 +199 +214 +229 +244 +245 +230 +215 +200 +185 +170 +155 +140 +125 +110 +95 +111 +126 +141 +156 +171 +186 +201 +216 +231 +246 +247 +232 +217 +202 +187 +172 +157 +142 +127 +143 +158 +173 +188 +203 +218 +233 +248 +249 +234 +219 +204 +189 +174 +159 +175 +190 +205 +220 +235 +250 +251 +236 +221 +206 +191 +207 +222 +237 +252 +253 +238 +223 +239 +254 +255 diff --git a/codec/L1/tests/jxlEnc/order_tokenize/description.json b/codec/L1/tests/jxlEnc/order_tokenize/description.json new file mode 100644 index 0000000000..79271d6ad1 --- /dev/null +++ b/codec/L1/tests/jxlEnc/order_tokenize/description.json @@ -0,0 +1,67 @@ +{ + "name": "Xilinx Order Tokenize HLS Test", + "description": "Xilinx jxl Order Tokenize HLS Test", + "flow": "hls", + "platform_whitelist": [ + "u200" + ], + "platform_blacklist": [], + "part_whitelist": [], + "part_blacklist": [], + "project": "tokenize", + "solution": "solution1", + "clock": "3.33", + "topfunction": "top_order_tokenize", + "top": { + "source": [ + "kernel/topOrderTokenize.cpp" + ], + "cflags": "-I${XF_PROJ_ROOT}/L1/include -I${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/kernel" + }, + "testbench": { + "source": [ + "host/test_orderTokenize.cpp" + + ], + "cflags": "-I${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/kernel", + "ldflags": "-pthread -std=c++11", + "argv": { + "hls_csim": "-i ${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/data/orders.txt -g ${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/data/goldens.txt", + "hls_cosim": "-i ${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/data/orders.txt -g ${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/data/goldens.txt" + }, + "stdmath": false + }, + "testinfo": { + "disable": false, + "jobs": [ + { + "index": 0, + "dependency": [], + "env": "", + "cmd": "", + "max_memory_MB": { + "hls_vivado_syn": 16384, + "hls_csim": 16384, + "hls_cosim": 16384, + "hls_vivado_impl": 16384, + "hls_csynth": 16384 + }, + "max_time_min": { + "hls_vivado_syn": 480, + "hls_csim": 120, + "hls_cosim": 480, + "hls_vivado_impl": 480, + "hls_csynth": 240 + } + } + ], + "targets": [ + "hls_csim", + "hls_csynth", + "hls_cosim", + "hls_vivado_syn", + "hls_vivado_impl" + ], + "category": "canary" + } +} diff --git a/codec/L1/tests/jxlEnc/order_tokenize/host/test_orderTokenize.cpp b/codec/L1/tests/jxlEnc/order_tokenize/host/test_orderTokenize.cpp new file mode 100644 index 0000000000..f1c3809a37 --- /dev/null +++ b/codec/L1/tests/jxlEnc/order_tokenize/host/test_orderTokenize.cpp @@ -0,0 +1,100 @@ +/* + * Copyright 2019 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils.hpp" +#include +#include +#include "topOrderTokenize.hpp" + +int main(int argc, const char* argv[]) { + std::cout << "\n-----------------Order Tokenize----------------\n"; + + // cmd parser + ArgParser parser(argc, argv); + + std::string infile; + if (!parser.getCmdOption("-i", infile)) { + std::cout << "ERROR: input file path is not set!\n"; + return 1; + } + + std::string goldenfile; + if (!parser.getCmdOption("-g", goldenfile)) { + std::cout << "ERROR: golden input file path is not set!\n"; + return 1; + } + + hls::stream > orderStrm("orderStrm"); + hls::stream > tokenStrm("tokenStrm"); + hls::stream e_tokenStrm("e_tokenStrm"); + + // read data + FILE* pFile; + pFile = fopen(infile.c_str(), "r"); + int num_orders; + int used_orders; + fscanf(pFile, "%d %d", &used_orders, &num_orders); + printf("INFO: num_orders is %d \n", num_orders); + for (int j = 0; j < num_orders; j++) { + int tmp; + fscanf(pFile, "%d", &tmp); + orderStrm.write(tmp); + } + fclose(pFile); + + top_order_tokenize(used_orders, orderStrm, tokenStrm, e_tokenStrm); + + uint32_t num_tokens; + uint32_t context, value; + + FILE* outFile; + std::string outfile(infile); + std::size_t found = outfile.find_last_of("."); + outfile.insert(found, "_tokens"); + outFile = fopen(outfile.c_str(), "w"); + int err = 0; + + bool e_kens(false); + ap_uint<64> tokenTmp; + uint32_t contextTmp, valueTmp; + + pFile = fopen(goldenfile.c_str(), "r"); + fscanf(pFile, "%d", &num_tokens); + while (!e_kens) { + e_kens = e_tokenStrm.read(); + if (!e_kens) { + tokenStrm.read(tokenTmp); + contextTmp = tokenTmp.range(31, 0).to_uint(); + valueTmp = tokenTmp.range(63, 32).to_uint(); + fscanf(pFile, "%d %d", &context, &value); + fprintf(outFile, "%d %d\n", contextTmp, valueTmp); + if (contextTmp != context || valueTmp != value) { + err++; + } + } + } + + fclose(pFile); + fclose(outFile); + + if (err) { + std::cerr << "INFO: Tokenize \033[31merrors " << err << "\033[0m" << std::endl; + } else { + std::cout << "INFO: Tokenize CSim Pass!" << std::endl; + } + + return err; +} diff --git a/codec/L1/tests/jxlEnc/order_tokenize/host/utils.hpp b/codec/L1/tests/jxlEnc/order_tokenize/host/utils.hpp new file mode 100644 index 0000000000..76cffecea0 --- /dev/null +++ b/codec/L1/tests/jxlEnc/order_tokenize/host/utils.hpp @@ -0,0 +1,58 @@ +/* + * Copyright 2020 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UTILS_H +#define UTILS_H +#include +inline int tvdiff(struct timeval* tv0, struct timeval* tv1) { + return (tv1->tv_sec - tv0->tv_sec) * 1000000 + (tv1->tv_usec - tv0->tv_usec); +} +//-------------------------------------------------------------- + +#include + +#include +#include +#include +#include + +class ArgParser { + public: + ArgParser(int& argc, const char** argv) { + for (int i = 1; i < argc; ++i) mTokens.push_back(std::string(argv[i])); + } + bool getCmdOption(const std::string option, std::string& value) const { + std::vector::const_iterator itr; + itr = std::find(this->mTokens.begin(), this->mTokens.end(), option); + if (itr != this->mTokens.end() && ++itr != this->mTokens.end()) { + value = *itr; + return true; + } + return false; + } + + private: + std::vector mTokens; +}; + +template +T* aligned_alloc(std::size_t num) { + void* ptr = NULL; + + if (posix_memalign(&ptr, 4096, num * sizeof(T))) throw std::bad_alloc(); + + return reinterpret_cast(ptr); +} +#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/fft_size.hpp b/codec/L1/tests/jxlEnc/order_tokenize/kernel/topOrderTokenize.cpp similarity index 58% rename from dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/fft_size.hpp rename to codec/L1/tests/jxlEnc/order_tokenize/kernel/topOrderTokenize.cpp index 24a888bed4..2c87ec02f9 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/fft_size.hpp +++ b/codec/L1/tests/jxlEnc/order_tokenize/kernel/topOrderTokenize.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2019 Xilinx, Inc. + * Copyright 2020 Xilinx, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,13 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ + */ + +#include "hls_EncodeCoeffOrders.hpp" + +void top_order_tokenize(ap_uint<32> used_orders, + hls::stream >& orderStrm, + hls::stream >& tokenStrm, + hls::stream& e_tokenStrm) { + xf::codec::hls_EncodeCoeffOrders(used_orders, orderStrm, tokenStrm, e_tokenStrm); +} diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/fft_size.hpp b/codec/L1/tests/jxlEnc/order_tokenize/kernel/topOrderTokenize.hpp similarity index 57% rename from dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/fft_size.hpp rename to codec/L1/tests/jxlEnc/order_tokenize/kernel/topOrderTokenize.hpp index 965578a579..bc1fd23da3 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/fft_size.hpp +++ b/codec/L1/tests/jxlEnc/order_tokenize/kernel/topOrderTokenize.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2019 Xilinx, Inc. + * Copyright 2020 Xilinx, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,16 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (128) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ + */ +#ifndef TOP_ORDER_TOKENIZE_HPP +#define TOP_ORDER_TOKENIZE_HPP + +#include +#include + +void top_order_tokenize(ap_uint<32> used_orders, + hls::stream >& orderStrm, + hls::stream >& tokenStrm, + hls::stream& e_tokenStrm); + +#endif // TOP_ORDER_TOKENIZE_HPP diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/run_hls.tcl b/codec/L1/tests/jxlEnc/order_tokenize/run_hls.tcl old mode 100755 new mode 100644 similarity index 56% rename from dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/run_hls.tcl rename to codec/L1/tests/jxlEnc/order_tokenize/run_hls.tcl index ccef1626eb..66ffcea5aa --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/run_hls.tcl +++ b/codec/L1/tests/jxlEnc/order_tokenize/run_hls.tcl @@ -1,5 +1,5 @@ # -# Copyright 2019-2020 Xilinx, Inc. +# Copyright 2019-2021 Xilinx, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,18 +16,18 @@ source settings.tcl -set PROJ "prj_ssr_fft_dro_reg_test_r16_l32.prj" +set PROJ "tokenize.prj" set SOLN "solution1" if {![info exists CLKP]} { - set CLKP 3.3 + set CLKP 3.33 } open_project -reset $PROJ -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L32.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L32.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top +add_files "kernel/topOrderTokenize.cpp" -cflags "-I${XF_PROJ_ROOT}/L1/include -I${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/kernel" +add_files -tb "host/test_orderTokenize.cpp" -cflags "-I${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/kernel" +set_top top_order_tokenize open_solution -reset $SOLN @@ -38,7 +38,7 @@ set_part $XPART create_clock -period $CLKP if {$CSIM == 1} { - csim_design + csim_design -ldflags "-pthread -std=c++11" -argv "-i ${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/data/orders.txt -g ${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/data/goldens.txt" } if {$CSYNTH == 1} { @@ -46,7 +46,7 @@ if {$CSYNTH == 1} { } if {$COSIM == 1} { - cosim_design + cosim_design -ldflags "-pthread -std=c++11" -argv "-i ${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/data/orders.txt -g ${XF_PROJ_ROOT}/L1/tests/jxlEnc/order_tokenize/data/goldens.txt" } if {$VIVADO_SYN == 1} { diff --git a/codec/L2/demos/jpegDec/Makefile b/codec/L2/demos/jpegDec/Makefile index 461ff18521..1b60de1613 100644 --- a/codec/L2/demos/jpegDec/Makefile +++ b/codec/L2/demos/jpegDec/Makefile @@ -43,7 +43,7 @@ help:: TARGET ?= sw_emu # ################### Setting up default value of DEVICE ############################## -DEVICE ?= xilinx_u200_xdma_201830_2 +DEVICE ?= xilinx_u50_gen3x16_xdma_201920_3 # ###################### Setting up default value of HOST_ARCH ####################### HOST_ARCH ?= x86 @@ -54,13 +54,11 @@ $(error [ERROR]: This project is not supported for $(DEVICE).) endif # #################### Checking if DEVICE in whitelist ############################ -ifneq ($(findstring u200, $(DEVICE)), u200) -ifneq ($(findstring u250, $(DEVICE)), u250) ifneq ($(findstring u50, $(DEVICE)), u50) +ifneq ($(findstring u280, $(DEVICE)), u280) $(warning [WARNING]: This project has not been tested for $(DEVICE). It may or may not work.) endif endif -endif # ######################## Setting up Project Variables ################################# MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) @@ -99,7 +97,7 @@ endif # ######################### Host compiler global settings ############################ CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++11 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE +LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -pthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE CXXFLAGS += -fmessage-length=0 -O3 CXXFLAGS += -I$(CUR_DIR)/src/ @@ -108,27 +106,27 @@ LDFLAGS += -L$(XILINX_HLS)/lnx64/tools/fpo_v7_0 -Wl,--as-needed -lgmp -lmpfr -lI endif ifneq (,$(shell echo $(XPLATFORM) | awk '/u50/')) CXXFLAGS += -D USE_HBM +else ifneq (,$(shell echo $(XPLATFORM) | awk '/u280/')) +CXXFLAGS += -D USE_HBM endif # ################### Setting package and image directory ####################### EXE_NAME := host.exe EXE_FILE := $(BUILD_DIR)/$(EXE_NAME) -HOST_ARGS := -xclbin $(BUILD_DIR)/kernelJpegDecoder.xclbin -JPEGFile images/t0.jpg +HOST_ARGS := -xclbin $(BUILD_DIR)/kernelJpegDecoder.xclbin -JPEGFile $(CUR_DIR)/images/t0.jpg +LIBRARY_PATH =$(LD_LIBRARY_PATH):$(XILINX_XRT)/lib # ##################### Kernel compiler global settings ########################## VPP_FLAGS += -t $(TARGET) --platform $(XPLATFORM) --save-temps --optimize 2 VPP_FLAGS += --hls.jobs 8 VPP_LDFLAGS += --vivado.synth.jobs 8 --vivado.impl.jobs 8 -ifneq (,$(shell echo $(XPLATFORM) | awk '/u200/')) -VPP_FLAGS += --config $(CUR_DIR)/conn_u200_u250.ini -endif -ifneq (,$(shell echo $(XPLATFORM) | awk '/u250/')) -VPP_FLAGS += --config $(CUR_DIR)/conn_u200_u250.ini +ifneq (,$(shell echo $(XPLATFORM) | awk '/u50/')) +VPP_FLAGS += --config $(CUR_DIR)/conn_u280_u50.ini endif -ifneq (,$(shell echo $(XPLATFORM) | awk '/u50/')) +ifneq (,$(shell echo $(XPLATFORM) | awk '/u280/')) VPP_FLAGS += --config $(CUR_DIR)/conn_u280_u50.ini endif @@ -142,6 +140,8 @@ kernelJpegDecoder_VPP_FLAGS += --hls.clock 300000000:kernelJpegDecoder VPP_LDFLAGS_kernelJpegDecoder += --kernel_frequency 300 +# Kernel args + # ############################ Declaring Binary Containers ########################## BINARY_CONTAINERS += $(BUILD_DIR)/kernelJpegDecoder.xclbin @@ -150,13 +150,25 @@ BINARY_CONTAINER_kernelJpegDecoder_OBJS += $(TEMP_DIR)/kernelJpegDecoder.xo # ######################### Setting Targets of Makefile ################################ .PHONY: all clean cleanall docs emconfig -all: check_vpp check_platform check_sysroot $(EXE_FILE) $(BINARY_CONTAINERS) emconfig +ifeq ($(HOST_ARCH), x86) +all: check_version check_vpp check_platform check_xrt $(EXE_FILE) $(BINARY_CONTAINERS) emconfig +else +all: check_version check_vpp check_platform check_sysroot $(EXE_FILE) $(BINARY_CONTAINERS) emconfig sd_card +endif .PHONY: host -host: check_xrt check_sysroot $(EXE_FILE) +ifeq ($(HOST_ARCH), x86) +host: check_xrt $(EXE_FILE) +else +host: check_sysroot $(EXE_FILE) +endif .PHONY: xclbin -xclbin: check_vpp check_sysroot $(BINARY_CONTAINERS) +ifeq ($(HOST_ARCH), x86) +xclbin: check_vpp check_xrt $(BINARY_CONTAINERS) +else +xclbin: check_vpp check_sysroot $(BINARY_CONTAINERS) +endif .PHONY: build build: xclbin @@ -165,7 +177,7 @@ build: xclbin $(TEMP_DIR)/kernelJpegDecoder.xo: $(XFLIB_DIR)/L2/demos/jpegDec/kernel/kernelJpegDecoder.cpp $(ECHO) "Compiling Kernel: kernelJpegDecoder" mkdir -p $(TEMP_DIR) - $(VPP) -c $(kernelJpegDecoder_VPP_FLAGS) $(VPP_FLAGS) -k kernelJpegDecoder -I'$(axi_width[0]*8, bas_info->axi_height[0]*8); + printf("Please open the YUV file with fmt %d and (width, height) = (%d, %d) \n", fmt, bas_info->axi_width[0] * 8, + bas_info->axi_height[0] * 8); + + // write yuv info to a file + fn = file_name.substr(0, file_name.find(".")) + ".yuv.h"; + f = fopen(fn.c_str(), "aw"); + std::cout << "WARNING: " << fn << " will be opened for binary write." << std::endl; + if (!f) { + std::cerr << "ERROR: " << fn << " cannot be opened for binary write." << std::endl; + } + fprintf(f, "INFO: fmt=%d, bas_info->mcu_cmp=%d\n", fmt, (int)(bas_info->mcu_cmp)); + fprintf(f, "INFO: bas_info->hls_mbs[cmp] %d, %d, %d \n", bas_info->hls_mbs[0], bas_info->hls_mbs[1], + bas_info->hls_mbs[2]); + fprintf(f, "Please open the YUV file with fmt %d and (width, height) = (%d, %d) \n", fmt, + bas_info->axi_width[0] * 8, bas_info->axi_height[0] * 8); + fclose(f); } // ------------------------------------------------------------ @@ -379,7 +394,6 @@ int main(int argc, const char* argv[]) { "'-JPEGFile' to specified it. \n"; } - ///// declaration // load data to simulate the ddr data @@ -402,7 +416,7 @@ int main(int argc, const char* argv[]) { // Variables to measure time struct timeval startE2E, endE2E; gettimeofday(&startE2E, 0); - + // To test SYNTHESIS top hls::stream > block_strm; xf::codec::cmp_info cmp_info[MAX_NUM_COLOR]; @@ -530,20 +544,30 @@ int main(int argc, const char* argv[]) { // Setup kernel std::cout << "INFO: Finish kernel setup" << std::endl; - std::vector events_write(1); - std::vector > events_kernel(1); - std::vector events_read(1); + const int num_runs = 10; + std::vector > events_write(num_runs); + std::vector > events_kernel(num_runs); + std::vector > events_read(num_runs); - events_kernel[0].resize(1); - - q.enqueueMigrateMemObjects(ob_in, 0, nullptr, &events_write[0]); // 0 : migrate from host to dev - - // Launch kernel and compute kernel execution time - q.enqueueTask(kernel_jpegDecoder, &events_write, &events_kernel[0][0]); + for (int i = 0; i < num_runs; ++i) { + events_kernel[i].resize(1); + events_write[i].resize(1); + events_read[i].resize(1); + } - // Data transfer from device buffer to host buffer - q.enqueueMigrateMemObjects(ob_out, 1, &events_kernel[0], &events_read[0]); // 1 : migrate from dev to host + for (int i = 0; i < num_runs; ++i) { + if (i < 1) { + q.enqueueMigrateMemObjects(ob_in, 0, nullptr, &events_write[i][0]); // 0 : migrate from host to dev + } else { + q.enqueueMigrateMemObjects(ob_in, 0, &events_read[i - 1], + &events_write[i][0]); // 0 : migrate from host to dev + } + // Launch kernel and compute kernel execution time + q.enqueueTask(kernel_jpegDecoder, &events_write[i], &events_kernel[i][0]); + // Data transfer from device buffer to host buffer + q.enqueueMigrateMemObjects(ob_out, 1, &events_kernel[i], &events_read[i][0]); // 1 : migrate from dev to host + } q.finish(); gettimeofday(&endE2E, 0); @@ -553,25 +577,27 @@ int main(int argc, const char* argv[]) { // print related times unsigned long timeStart, timeEnd, exec_time0, write_time, read_time; std::cout << "-------------------------------------------------------" << std::endl; - events_write[0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - events_write[0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); + events_write[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); + events_write[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); write_time = (timeEnd - timeStart) / 1000.0; std::cout << "INFO: Data transfer from host to device: " << write_time << " us\n"; std::cout << "-------------------------------------------------------" << std::endl; - events_read[0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - events_read[0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); + events_read[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); + events_read[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); read_time = (timeEnd - timeStart) / 1000.0; std::cout << "INFO: Data transfer from device to host: " << read_time << " us\n"; std::cout << "-------------------------------------------------------" << std::endl; exec_time0 = 0; - int num_runs = 1; for (int i = 0; i < num_runs; ++i) { - events_kernel[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - events_kernel[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); + events_kernel[i][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); + events_kernel[i][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); exec_time0 += (timeEnd - timeStart) / 1000.0; + unsigned long t = (timeEnd - timeStart) / 1000.0; + printf("INFO: kernel %d: execution time %lu usec\n", i, t); } - std::cout << "INFO: Average kernel execution per run: " << exec_time0 / num_runs << " us\n"; + exec_time0 = exec_time0 / (unsigned long)num_runs; + std::cout << "INFO: Average kernel execution per run: " << exec_time0 << " us\n"; std::cout << "-------------------------------------------------------" << std::endl; unsigned long exec_timeE2E = diff(&endE2E, &startE2E); std::cout << "INFO: Average E2E per run: " << exec_timeE2E << " us\n"; diff --git a/codec/L2/demos/jpegDec/utils.mk b/codec/L2/demos/jpegDec/utils.mk index 6eb1d68ea8..3a6a92a467 100644 --- a/codec/L2/demos/jpegDec/utils.mk +++ b/codec/L2/demos/jpegDec/utils.mk @@ -1,5 +1,5 @@ # -# Copyright 2019-2020 Xilinx, Inc. +# Copyright 2019-2021 Xilinx, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -39,14 +39,17 @@ ifeq ($(DEBUG), yes) VPP_LDFLAGS += --dk protocol:all:all:all endif -#Check environment setup +#Checks for XILINX_XRT +ifeq ($(HOST_ARCH), x86) +ifndef XILINX_XRT + XILINX_XRT = /opt/xilinx/xrt + export XILINX_XRT +endif +else ifndef XILINX_VITIS XILINX_VITIS = /opt/xilinx/Vitis/$(TOOL_VERSION) export XILINX_VITIS endif -ifndef XILINX_XRT - XILINX_XRT = /opt/xilinx/xrt - export XILINX_XRT endif #Checks for Device Family @@ -71,6 +74,13 @@ ifndef SYSROOT endif endif +check_version: +ifneq (, $(shell which git)) +ifneq (,$(wildcard $(XFLIB_DIR)/.git)) + @cd $(XFLIB_DIR) && git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -n 1 && cd - +endif +endif + #Checks for g++ CXX := g++ ifeq ($(HOST_ARCH), x86) @@ -112,9 +122,11 @@ endif .PHONY: check_xrt check_xrt: +ifeq ($(HOST_ARCH), x86) ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false endif +endif export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) ifeq ($(HOST_ARCH), x86) diff --git a/codec/L2/demos/pikEnc/Makefile b/codec/L2/demos/pikEnc/Makefile index 747c31ceef..bc8937c052 100755 --- a/codec/L2/demos/pikEnc/Makefile +++ b/codec/L2/demos/pikEnc/Makefile @@ -235,7 +235,7 @@ endif # ######################### Host compiler global settings ############################ CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++11 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE +LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -pthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE CXXFLAGS += -fmessage-length=0 -O3 CXXFLAGS += -I$(CUR_DIR)/src/ diff --git a/codec/docs/benchmark.rst b/codec/docs/benchmark.rst index dbb63c3255..8644b2014e 100644 --- a/codec/docs/benchmark.rst +++ b/codec/docs/benchmark.rst @@ -25,49 +25,80 @@ Benchmark .. _pictures: -Pictures +Pictures & Performance ----------- -The data is used by benchmarks, our commonly used pictures are listed in table 1. +1. JPEG Decoder: This API supports the ‘Sequential DCT-based mode’ of ISO/IEC 10918-1 standard. It is a high-performance implementation based-on Xilinx HLS design methodolygy. + It can process 1 Huffman token and create up to 8 DCT coeffiects within one cycle. + It is also an easy-to-use decoder as it can direct parser the JPEG file header without help of software functions. +2. Pik Encoder: This API is based on Google’s PIK, which was ‘chosen as the base framework for JPEG XL’. + The pikEnc is based on the ‘fast mode’ of PIK which can provide better encoding efficnty than most of other still image encoding methods. + The pikEnc is based on Xilinx HLS design methodology and optimized for FPGA arthitecture. + It can proved higher throughput and lower latency compared to software-based solutions. +our commonly used pictures are listed in table below. -.. table:: Table 1 Pictures for benchmark +.. table:: Table 1 Cosim benchmark for Huffman Decoder(L1) :align: center - +--------------------+----------+-------------+ - | Pictures | Format | Size | - +====================+==========+=============+ - | android.jpg | 420 | 960*1280 | - +--------------------+----------+-------------+ - | offset.jpg | 422 | 5184*3456 | - +--------------------+----------+-------------+ - | hq.jpg | 444 | 5760*3840 | - +--------------------+----------+-------------+ - | iphone.jpg | 420 | 3264*2448 | - +--------------------+----------+-------------+ - | lena_c_512.png | 444 | 512*512 | - +--------------------+----------+-------------+ - | 1920x1080.png | 444 | 1920*1080 | - +--------------------+----------+-------------+ - -Performance + +--------------------+----------+-------------+----------------+-----------------+------------------+-----+----------+ + | Pictures | Format | Size | Compress ratio | cosim Freq(MHz) | input speed(MB/s)| QPS | time(ms) | + +====================+==========+=============+================+=================+==================+=====+==========+ + | lena_c_512.jpg | 420 | 512*512 | 5.2 | 300 | 174 | 2288| 0.437 | + +--------------------+----------+-------------+----------------+-----------------+------------------+-----+----------+ + | t0.jpg | 420 | 616*516 | 9.3 | 300 | 147 | 2890| 0.346 | + +--------------------+----------+-------------+----------------+-----------------+------------------+-----+----------+ + | android.jpg | 420 | 960*1280 | 14.2 | 300 | 145 | 1125| 0.889 | + +--------------------+----------+-------------+----------------+-----------------+------------------+-----+----------+ + | offset.jpg | 422 | 5184*3456 | 4.6 | 300 | 209 | 27 | 37.25 | + +--------------------+----------+-------------+----------------+-----------------+------------------+-----+----------+ + | hq.jpg | 444 | 5760*3840 | 2.8 | 300 | 233 | 10 | 101.1 | + +--------------------+----------+-------------+----------------+-----------------+------------------+-----+----------+ + | iphone.jpg | 420 | 3264*2448 | 5.4 | 300 | 213 | 96 | 10.47 | + +--------------------+----------+-------------+----------------+-----------------+------------------+-----+----------+ + + +.. table:: Table 2 On board benchmark for JPEG Decoder(L2) + :align: center + + +--------------------+----------+-------------+----------------+-----------+------------------+-----+----------+ + | Pictures | Format | Size | Compress ratio | Freq(MHz) | input speed(MB/s)| QPS | time(ms) | + +====================+==========+=============+================+===========+==================+=====+==========+ + | lena_c_512.jpg | 420 | 512*512 | 5.2 | 243 | 87 | 1148| 0.871 | + +--------------------+----------+-------------+----------------+-----------+------------------+-----+----------+ + | t0.jpg | 420 | 616*516 | 9.3 | 243 | 66 | 1292| 0.774 | + +--------------------+----------+-------------+----------------+-----------+------------------+-----+----------+ +.. table:: Table 3 On board benchmark for Pik Eecoder(L2) + :align: center + + +--------------------+------------------+-------------+-------------+-------------+------------+---------------------+------+ + | Pictures | Size | Kernel1(ms) | Kernel2(ms) | Kernel3(ms) | Freq(MHz) | input speed(MPIX/s) | QPS | + +====================+==================+=============+=============+=============+============+=====================+======+ + | lena_c_512.png | 512*512 | 16 | 14 | 7 | 200 | 16.4 | 62.5 | + +--------------------+------------------+-------------+-------------+-------------+------------+---------------------+------+ + | lena_c_1024.png | 1024*1024 | 52 | 48 | 24 | 200 | 20.2 | 19.2 | + +--------------------+------------------+-------------+-------------+-------------+------------+---------------------+------+ + | lena_c_2048.png | 2048*2048 | 191 | 180 | 86 | 200 | 22.0 | 5.2 | + +--------------------+------------------+-------------+-------------+-------------+------------+---------------------+------+ + +Resource Utilization ----------- For representing the resource utilization in each benchmark, we separate the overall utilization into 2 parts, where P stands for the resource usage in platform, that is those instantiated in static region of the FPGA card, as well as K represents those used in kernels (dynamic region). The input is png, jpg, pik, e.g. format, and the target device is set to Alveo U200. -.. table:: Table 2 Performance for processing pictures on FPGA +.. table:: Table 4 Resource Utilization :align: center - +---------------------+------------------+--------------+----------+----------------+-------------+------------+------------+ - | Architecture | Picture | Latency(ms) | Timing | LUT(P/K) | BRAM(P/K) | URAM(P/K) | DSP(P/K) | - +=====================+==================+==============+==========+================+=============+============+============+ - | JPEG Huffman Decoder| android.jpg | 0.889 | 270MHz | 108.1K/7.9K | 178/5 | 0/0 | 4/12 | - +---------------------+------------------+--------------+----------+----------------+-------------+------------+------------+ - | JPEG Decoder | android.jpg | 1.515 | 243MHz | 108.1K/23.1K | 178/28 | 0/0 | 4/39 | - +---------------------+------------------+--------------+----------+----------------+-------------+------------+------------+ - | PIK Encoder | lena_c_512.png | 16.0 | 300MHz | 150.9K/439.4K | 338/62 | 0/16 | 7/0 | - +---------------------+------------------+--------------+----------+----------------+-------------+------------+------------+ + +------------------------+----------+----------------+-------------+------------+------------+ + | Architecture | Freq | LUT(P/K) | BRAM(P/K) | URAM(P/K) | DSP(P/K) | + +========================+==========+================+=============+============+============+ + | JPEG Huffman Decoder | 270MHz | 108.1K/7.9K | 178/5 | 0/0 | 4/12 | + +------------------------+----------+----------------+-------------+------------+------------+ + | JPEG Decoder | 243MHz | 108.1K/23.1K | 178/28 | 0/0 | 4/39 | + +------------------------+----------+----------------+-------------+------------+------------+ + | PIK Encoder | 300MHz | 150.9K/439.4K | 338/62 | 0/16 | 7/0 | + +------------------------+----------+----------------+-------------+------------+------------+ These are details for benchmark result and usage steps. diff --git a/codec/docs/guide_L1/IPs/jxlOrderTokenize.rst b/codec/docs/guide_L1/IPs/jxlOrderTokenize.rst new file mode 100644 index 0000000000..071d5a11e4 --- /dev/null +++ b/codec/docs/guide_L1/IPs/jxlOrderTokenize.rst @@ -0,0 +1,82 @@ +.. + Copyright 2019 Xilinx, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +*********************************** +Internal Design of Order Tokenize +*********************************** + +Overview +=========== + +This API is a submodule of the jpegXL encoder. It is an optimized implementation of the Xilinx HLS design methodology. This API is able to construct tokens of the orders of the ac coefficients of jpegXL. The supported AC strategy includes 8x8, IDENTITY, 16x16 and 32x32 DCT. The input of this API is a set of orders of coefficients to be encoded under all the supported strategies. And the output is a number of tokens which can be encoded by the following ANS encoder. + +Implemention +============ + +The detail algorithm implemention is illustrated as below: + +.. image:: /images/jxlOrderTokenize.png + :alt: desigh of Order Tokenize + :width: 60% + :align: center + +As it is shown in the aboved pictures, the whole orderTokenize have 4 functions and dataflow between these functions. + +* scanStrategy: the function gets ac strategy from the input "used_orders" and compute the size according to ac strategy type. + +* loadZigzag: the function lookups the created table to get zigzag according to its input orders stream. + +* updateLehmer: the function computes Lehmer according to its input zigzag stream. + +* updateToken: the function computes token value and context according to its lehmer stream. + +Profiling +============ + +The Post-Synthesis Resource usage are shown in the table1 below. +The Order Tokenize C/RTL co-simulation on CPU, and the result is based it in table2. + +.. table:: Table 1 Post-Synthesis Resource usage + :align: center + + +------------------+-----------+-----------+----------+----------+--------+ + | Name | LUT | Register | BRAM | URAM | DSP | + +------------------+-----------+-----------+----------+----------+--------+ + | orderTokenize | 2581 | 1835 | 6 | 0 | 0 | + +------------------+-----------+-----------+----------+----------+--------+ + + +.. table:: Table 2 Comparison between orderTokenize on CPU and Cosim + :align: center + + +------------------+----------+-----------+------------+------------+ + | Image | Size | Cpu | Cosim | Speed | + +------------------+----------+-----------+------------+------------+ + | t0.png | 960 | 0.139 | 0.058 | 2.4x | + +------------------+----------+-----------+------------+------------+ + | Ali_512x512.png | 960 | 0.233 | 0.058 | 4.0x | + +------------------+----------+-----------+------------+------------+ + | 853x640.png | 1152 | 0.152 | 0.069 | 2.2x | + +------------------+----------+-----------+------------+------------+ + | hq_2Kx2K.png | 1152 | 0.120 | 0.069 | 1.7x | + +------------------+----------+-----------+------------+------------+ + +.. note:: + | 1. orderTokenize running on platform with Intel(R) Xeon(R) CPU E5-2690 v4 @ 2.60GHz, 28 Threads (14 Core(s)). + | 2. Time unit: ms. + +.. toctree:: + :maxdepth: 1 diff --git a/codec/docs/guide_L1/internals.rst b/codec/docs/guide_L1/internals.rst index ea5a7286ce..95ca376e54 100644 --- a/codec/docs/guide_L1/internals.rst +++ b/codec/docs/guide_L1/internals.rst @@ -22,4 +22,5 @@ Design Internals :maxdepth: 1 IPs/jpegHuffmanDecoder.rst + IPs/jxlOrderTokenize.rst diff --git a/codec/docs/images/jxlOrderTokenize.png b/codec/docs/images/jxlOrderTokenize.png new file mode 100644 index 0000000000..ca742a0b02 Binary files /dev/null and b/codec/docs/images/jxlOrderTokenize.png differ diff --git a/data_analytics/Jenkinsfile b/data_analytics/Jenkinsfile index 7da9b8285a..f55639503a 100644 --- a/data_analytics/Jenkinsfile +++ b/data_analytics/Jenkinsfile @@ -1,4 +1,4 @@ @Library('pipeline-library')_ -VitisLibPipeline (branch: 'next', libname: 'xf_DataAnalytics', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', - upstream_dependencies: 'xf_utils_hw,next,../utils', - email: 'tuol@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_stable_latest') +VitisLibPipeline (branch: 'master', libname: 'xf_DataAnalytics', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', + upstream_dependencies: 'xf_utils_hw,master,../utils', + email: 'tuol@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_released') diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/csv_parser.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/csv_parser.hpp index f69b748ab5..b17b4d93ce 100644 --- a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/csv_parser.hpp +++ b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/csv_parser.hpp @@ -27,7 +27,7 @@ #include "xf_data_analytics/common/obj_interface.hpp" #include "xf_data_analytics/dataframe/df_utils.hpp" #include "xf_data_analytics/dataframe/parser_blocks/read_block.hpp" -#include "xf_data_analytics/dataframe/parser_blocks/parse_block.hpp" +#include "xf_data_analytics/dataframe/parser_blocks/csv_parse_block.hpp" #ifndef __SYNTHESIS__ #include diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/json_parser.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/json_parser.hpp new file mode 100644 index 0000000000..e6d82cdefa --- /dev/null +++ b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/json_parser.hpp @@ -0,0 +1,301 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file json_parser.hpp + * @brief parse one standard pre-flatten JSON file, output each field row by row with obj-stream interface + * + * This file is part of Vitis Data Analytics Library. + */ + +#ifndef XF_DATA_ANALYTICS_L1_DATAFRAME_JSON_PARSER_HPP +#define XF_DATA_ANALYTICS_L1_DATAFRAME_JSON_PARSER_HPP + +#include "xf_data_analytics/common/obj_interface.hpp" +#include "xf_data_analytics/dataframe/df_utils.hpp" +#include "xf_data_analytics/dataframe/parser_blocks/read_block.hpp" +#include "xf_data_analytics/dataframe/parser_blocks/json_parse_block.hpp" + +#ifndef __SYNTHESIS__ +#include +#endif + +namespace xf { +namespace data_analytics { +namespace dataframe { + +namespace internal { + +/** + * @brief read the schema and cache the type of each enable column + **/ +template +void readSchema(ap_uint<8>* schema, + + ap_uint<9>& num_of_column, + ap_uint& mask_cfg, + ap_uint<8> key_buff[PU_NUM][COL_NUM][256], + ap_uint<4> type_buff[PU_NUM][COL_NUM]) { + int cnt = 0; + int addr = 4; + bool str_start = false; + bool val_start = false; + ap_uint<8> str_len = 0; + ap_uint<9> column_nm = 0; + + ap_uint<16> nm; + mask_cfg.range(7, 0) = schema[0]; + mask_cfg.range(15, 8) = schema[1]; + nm.range(7, 0) = schema[2]; + nm.range(15, 8) = schema[3]; + // init key buffer + for (int i = 0; i < 256; ++i) { + for (int j = 0; j < COL_NUM; ++j) { +#pragma HLS pipeline II = 1 + for (int k = 0; k < PU_NUM; ++k) { + key_buff[k][j][i] = '\0'; + } + } + } + +READ_SCHEMA_CORE_LOOP: + for (int i = 0; i < nm; ++i) { +#pragma HLS pipeline II = 1 + ap_uint<8> in = schema[addr + i]; + if (in == '\n') + cnt++; + else if (!str_start && in == '"') { + str_start = true; + } else if (str_start && in == '"') { + str_start = false; + str_len = 0; + } else if (!str_start && in == ':') { + val_start = true; + } else if (val_start) { + val_start = false; + for (int j = 0; j < PU_NUM; ++j) { +#pragma HLS unroll + type_buff[j][cnt] = in; + } + column_nm++; + } else { + for (int j = 0; j < PU_NUM; ++j) { +#pragma HLS unroll + key_buff[j][cnt][str_len] = in; + } + str_len++; + } + } + + num_of_column = column_nm; +} + +/** + * @brief merge two obj-stream by load-balance type, and sink the line break signal + **/ +inline void mergeLineUnitL1(hls::stream i_obj_array_strm[2], + hls::stream i_ln_e_strm[2], + + hls::stream& o_obj_strm) { + ap_uint<1> pu_idx = 0; + + ap_uint<2> e = 0; + Object obj; + +MERGE_CORE_LOOP: + while (e != (ap_uint<2>)-1) { +#pragma HLS pipeline II = 1 + if (!e[pu_idx] && !i_ln_e_strm[pu_idx].empty()) { + i_obj_array_strm[pu_idx] >> obj; + if (obj.get_type() == FEOL || obj.get_type() == FEOF) i_ln_e_strm[pu_idx].read(); + if (obj.get_type() == FEOF) { + e[pu_idx] = true; + } else { + o_obj_strm << obj; + } + } + + if (e[pu_idx] || i_ln_e_strm[pu_idx].empty() || (!e[pu_idx] && obj.get_type() == FEOL)) { + pu_idx = !pu_idx; + } + } + + obj.set_type(FEOF); // EOF + o_obj_strm << obj; +} + +/** + * @brief merge two obj-stream by load-balance type + **/ +inline void mergeLineUnitL2(hls::stream i_obj_array_strm[2], + + hls::stream& o_obj_strm) { + ap_uint<1> pu_idx = 0; + + ap_uint<2> e = 0; + Object obj; + +MERGE_CORE_LOOP: + while (e != (ap_uint<2>)-1) { +#pragma HLS pipeline II = 1 + if (!e[pu_idx]) { + i_obj_array_strm[pu_idx] >> obj; + if (obj.get_type() == FEOF) { + e[pu_idx] = true; + } else { + o_obj_strm << obj; + } + } + + if (e[pu_idx] || (!e[pu_idx] && obj.get_type() == FEOL)) { + pu_idx = !pu_idx; + } + } + + obj.set_type(FEOF); // EOF + o_obj_strm << obj; +} + +/** + * @brief top function of merging obj-stream from PUs, support 2/4/8-to-1 only + **/ +template +inline void mergeLine(hls::stream i_obj_array_strm[PU_NUM / 2][2], + hls::stream i_ln_e_strm[PU_NUM / 2][2], + hls::stream& o_obj_strm) { +#pragma HLS dataflow + + if (PU_NUM == 2) { + mergeLineUnitL1(i_obj_array_strm[0], i_ln_e_strm[0], o_obj_strm); + } + if (PU_NUM == 4) { + hls::stream obj_l2_strm[2]; +#pragma HLS stream variable = obj_l2_strm depth = 8 + + mergeLineUnitL1(i_obj_array_strm[0], i_ln_e_strm[0], obj_l2_strm[0]); + mergeLineUnitL1(i_obj_array_strm[1], i_ln_e_strm[1], obj_l2_strm[1]); + + mergeLineUnitL2(obj_l2_strm, o_obj_strm); + } + if (PU_NUM == 8) { + hls::stream obj_l1_strm[2][2]; +#pragma HLS stream variable = obj_l1_strm depth = 8 + hls::stream obj_l2_strm[2]; +#pragma HLS stream variable = obj_l2_strm depth = 8 + + mergeLineUnitL1(i_obj_array_strm[0], i_ln_e_strm[0], obj_l1_strm[0][0]); + mergeLineUnitL1(i_obj_array_strm[1], i_ln_e_strm[1], obj_l1_strm[0][1]); + mergeLineUnitL1(i_obj_array_strm[2], i_ln_e_strm[2], obj_l1_strm[1][0]); + mergeLineUnitL1(i_obj_array_strm[3], i_ln_e_strm[3], obj_l1_strm[1][1]); + + mergeLineUnitL2(obj_l1_strm[0], obj_l2_strm[0]); + mergeLineUnitL2(obj_l1_strm[1], obj_l2_strm[1]); + + mergeLineUnitL2(obj_l2_strm, o_obj_strm); + } +} + +/** + * @brief main function of JSON parser + **/ +template +void parseJSONCore(ap_uint<128>* json_buff, + ap_uint<9> num_of_column, + ap_uint mask_cfg, + ap_uint<8> key_buff[PU_NUM][COL_NUM][256], + ap_uint<4> type_buff[PU_NUM][COL_NUM], + hls::stream& o_obj_strm) { +#pragma HLS dataflow + + hls::stream > s_w8_strm[PU_NUM]; +#pragma HLS stream variable = s_w8_strm depth = 8 +#pragma HLS array_partition variable = s_w8_strm dim = 0 + hls::stream s_e_strm[PU_NUM]; +#pragma HLS stream variable = s_e_strm depth = 8 +#pragma HLS array_partition variable = s_e_strm dim = 0 + + hls::stream t_obj_array_strm[PU_NUM / 2][2]; +#pragma HLS stream variable = t_obj_array_strm depth = 1024 +#pragma HLS array_partition variable = t_obj_array_strm dim = 0 +#pragma HLS bind_storage variable = t_obj_array_strm type = fifo impl = bram + hls::stream o_ln_e_strm[PU_NUM / 2][2]; +#pragma HLS stream variable = o_ln_e_strm depth = 64 +#pragma HLS array_partition variable = o_ln_e_strm dim = 0 +#pragma HLS bind_storage variable = o_ln_e_strm type = fifo impl = lutram + + readJSON(json_buff, s_w8_strm, s_e_strm); + + if (PU_NUM >= 2) { + parseBlock(num_of_column, mask_cfg, key_buff[0], type_buff[0], s_w8_strm[0], s_e_strm[0], o_ln_e_strm[0][0], + t_obj_array_strm[0][0]); + parseBlock(num_of_column, mask_cfg, key_buff[1], type_buff[1], s_w8_strm[1], s_e_strm[1], o_ln_e_strm[0][1], + t_obj_array_strm[0][1]); + } + if (PU_NUM >= 4) { + parseBlock(num_of_column, mask_cfg, key_buff[2], type_buff[2], s_w8_strm[2], s_e_strm[2], o_ln_e_strm[1][0], + t_obj_array_strm[1][0]); + parseBlock(num_of_column, mask_cfg, key_buff[3], type_buff[3], s_w8_strm[3], s_e_strm[3], o_ln_e_strm[1][1], + t_obj_array_strm[1][1]); + } + if (PU_NUM >= 8) { + parseBlock(num_of_column, mask_cfg, key_buff[4], type_buff[4], s_w8_strm[4], s_e_strm[4], o_ln_e_strm[2][0], + t_obj_array_strm[2][0]); + parseBlock(num_of_column, mask_cfg, key_buff[5], type_buff[5], s_w8_strm[5], s_e_strm[5], o_ln_e_strm[2][1], + t_obj_array_strm[2][1]); + parseBlock(num_of_column, mask_cfg, key_buff[6], type_buff[6], s_w8_strm[6], s_e_strm[6], o_ln_e_strm[3][0], + t_obj_array_strm[3][0]); + parseBlock(num_of_column, mask_cfg, key_buff[7], type_buff[7], s_w8_strm[7], s_e_strm[7], o_ln_e_strm[3][1], + t_obj_array_strm[3][1]); + } + + mergeLine(t_obj_array_strm, o_ln_e_strm, o_obj_strm); +} + +} // namespace internal + +/** + * @brief read one standard JSON file from DDR and parse into object stream with schma defination + * + * @tparam PU_NUM number of JSON parse core, only support 2/4/8 + * @tparam COL_NUM number of maximum column, should be power of 2 + * @param json_buf buffer of JSON file + * @param schema name, data type and is_filter flag for each column + * @param o_obj_strm output object stream for selected columns + * + **/ +template +void jsonParser(ap_uint<128>* json_buf, ap_uint<8>* schema, hls::stream& o_obj_strm) { + ap_uint<8> key_buf[PU_NUM][COL_NUM][256]; +#pragma HLS array_partition variable = key_buf dim = 1 +#pragma HLS array_partition variable = key_buf dim = 2 +#pragma HLS bind_storage variable = key_buf type = ram_1p impl = lutram + ap_uint<4> type_buf[PU_NUM][COL_NUM]; +#pragma HLS array_partition variable = type_buf dim = 1 +#pragma HLS bind_storage variable = type_buf type = ram_1p impl = lutram + + static_assert((PU_NUM == 2 || PU_NUM == 4 || PU_NUM == 8), "Only support 2/4/8 PU setting"); + + ap_uint<9> num_of_column; + ap_uint mask_cfg; + + internal::readSchema(schema, num_of_column, mask_cfg, key_buf, type_buf); + + internal::parseJSONCore(json_buf, num_of_column, mask_cfg, key_buf, type_buf, o_obj_strm); +} +} // namespace dataframe +} // namespace data_analytics +} // namespace xf +#endif diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/line_parser.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/csv_line_parser.hpp similarity index 100% rename from data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/line_parser.hpp rename to data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/csv_line_parser.hpp diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/parse_block.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/csv_parse_block.hpp similarity index 99% rename from data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/parse_block.hpp rename to data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/csv_parse_block.hpp index 747e16fc10..fe3ca24a72 100644 --- a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/parse_block.hpp +++ b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/csv_parse_block.hpp @@ -19,7 +19,7 @@ */ #ifndef XF_DATA_ANALYTICS_L1_DATAFRAME_CSV_PARSE_BLOCK_HPP #define XF_DATA_ANALYTICS_L1_DATAFRAME_CSV_PARSE_BLOCK_HPP -#include "xf_data_analytics/dataframe/parser_blocks/line_parser.hpp" +#include "xf_data_analytics/dataframe/parser_blocks/csv_line_parser.hpp" #include "xf_data_analytics/dataframe/parser_blocks/parse_double.hpp" #include "xf_data_analytics/dataframe/parser_blocks/parse_date.hpp" #include "xf_data_analytics/dataframe/df_utils.hpp" diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/json_line_parser.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/json_line_parser.hpp new file mode 100644 index 0000000000..e9022bbe6b --- /dev/null +++ b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/json_line_parser.hpp @@ -0,0 +1,397 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef XF_DATA_ANALYTICS_L1_DATAFRAME_INTERNAL_JSON_LINE_PARSE_HPP +#define XF_DATA_ANALYTICS_L1_DATAFRAME_INTERNAL_JSON_LINE_PARSE_HPP +#include "hls_stream.h" +#include "ap_int.h" +#include + +namespace xf { +namespace data_analytics { +namespace dataframe { +namespace internal { + +// States (15) +enum IterativeParsingState { + IterativeParsingFinishState = 0, // sink states at top + IterativeParsingErrorState, // sink states at top + IterativeParsingStartState, + + // Object states + IterativeParsingObjectInitialState, + IterativeParsingMemberKeyStartState, + IterativeParsingMemberKeyEndState, + IterativeParsingMemberStringStartState, + IterativeParsingMemberNumberStartState, + IterativeParsingMemberValueEndState, + IterativeParsingObjectFinishState, + + // Delimiter states (at bottom) + IterativeParsingKeyValueDelimiterState, + IterativeParsingMemberDelimiterState, + + cIterativeParsingStateCount +}; +// Tokens (11) +enum Token { + LeftCurlyBracketToken = 0, + RightCurlyBracketToken, + + CommaToken, + ColonToken, + + StringToken, + NumberToken, + + SpaceToken, + + kTokenCount +}; +#define N NumberToken +#define N16 N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N +#define N8 N, N, N, N, N, N, N, N +// Maps from ASCII to Token +static const unsigned char tokenMap[256] = { + SpaceToken, //\0 + N8, // 1-8 + SpaceToken, //\t + N, N, + N, + SpaceToken, //\r + N, N, + N16, // 10~1F + SpaceToken, N, + StringToken, N, + N, N, + N, N, + N, N, + N, N, + CommaToken, N, + N, + N, // 20~2F + N, N, + N, N, + N, N, + N, N, + N, N, + ColonToken, N, + N, N, + N, + N, // 30~3F + N16, // 40~4F + N, N, + N, N, + N, N, + N, N, + N, N, + N, + N, // LeftBracketToken, + N, + N, // RightBracketToken, + N, + N, // 50~5F + N, N, + N, N, + N, NumberToken, + NumberToken, N, + N, N, + N, N, + NumberToken, N, + NumberToken, + N, // 60~6F + N, N, + N, N, + N, N, + N, N, + N, N, + N, LeftCurlyBracketToken, + N, RightCurlyBracketToken, + N, + N, // 70~7F + N16, N16, + N16, N16, + N16, N16, + N16, + N16 // 80~FF +}; + +#undef N +#undef N16 + +// array +static const char G[cIterativeParsingStateCount][kTokenCount] = { + // Finish(sink state) + { + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // Number + IterativeParsingFinishState // Space + }, + // Error(sink state) + { + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // Number + IterativeParsingErrorState // Space + }, + // Start + { + IterativeParsingObjectInitialState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // Number + IterativeParsingStartState // Space + }, + // ObjectInitial + { + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyStartState, // String + IterativeParsingErrorState, // Number + IterativeParsingObjectInitialState // Space + }, + // MemberKeyStartState + { + IterativeParsingMemberKeyStartState, // Left curly bracket + IterativeParsingMemberKeyStartState, // Right curly bracket + IterativeParsingMemberKeyStartState, // Comma + IterativeParsingMemberKeyStartState, // Colon + IterativeParsingMemberKeyEndState, // String + IterativeParsingMemberKeyStartState, // Number + IterativeParsingMemberKeyStartState // Space + }, + // MemberKeyEnd + { + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingKeyValueDelimiterState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // Number + IterativeParsingMemberKeyEndState // Space + }, + // MemberStringStart + { + IterativeParsingMemberStringStartState, // Left curly bracket + IterativeParsingMemberStringStartState, // Right curly bracket + IterativeParsingMemberStringStartState, // Comma + IterativeParsingMemberStringStartState, // Colon + IterativeParsingMemberValueEndState, // String + IterativeParsingMemberStringStartState, // Number + IterativeParsingMemberStringStartState // Space + }, + // MemberNumberStart + { + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingMemberDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingMemberNumberStartState, // Number + IterativeParsingMemberNumberStartState // Space + }, + // ValueEnd + { + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingMemberDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // Number + IterativeParsingMemberValueEndState // Space + }, + // ObjectFinish(sink state) + { + IterativeParsingObjectInitialState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // Number + IterativeParsingObjectFinishState // Space + }, // Number + + // KeyValueDelimiter + { + IterativeParsingErrorState, // Left curly bracket(push MemberValue state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberStringStartState, // String + IterativeParsingMemberNumberStartState, // Number + IterativeParsingKeyValueDelimiterState // Space + }, + // memberDelimiter + { + IterativeParsingErrorState, // Left curly bracket(push MemberValue state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyStartState, // String + IterativeParsingErrorState, // Number + IterativeParsingMemberDelimiterState // Space + }}; // End of G + +inline IterativeParsingState Transit(ap_uint<8> in_byte, + hls::stream >& o_k_strm, + hls::stream& k_vld_strm, + hls::stream& e_k_strm, + + hls::stream >& o_val_strm, + hls::stream& val_vld_strm, + hls::stream& e_val_strm, + + hls::stream& ln_e_strm, + + IterativeParsingState src, + Token token, + IterativeParsingState dst) { +#pragma HLS inline + switch (dst) { + case IterativeParsingMemberKeyStartState: { + // keep write out the char of key + o_k_strm.write(in_byte); + k_vld_strm.write(true); + e_k_strm.write(false); + ln_e_strm.write(false); + break; + } + case IterativeParsingMemberKeyEndState: { + // stop write-out the key + if (src == IterativeParsingMemberKeyStartState) { + o_k_strm.write(in_byte); + k_vld_strm.write(false); + e_k_strm.write(false); + ln_e_strm.write(false); + } + break; + } + case IterativeParsingMemberDelimiterState: + case IterativeParsingObjectFinishState: { + // end of value + if (src == IterativeParsingMemberNumberStartState) { + o_val_strm.write(in_byte); + val_vld_strm.write(false); + e_val_strm.write(false); + } + // write the flag to indicate the end of the line + if (dst == IterativeParsingObjectFinishState) { + o_k_strm.write(0); + k_vld_strm.write(false); + e_k_strm.write(false); + ln_e_strm.write(true); + } + break; + } + case IterativeParsingMemberStringStartState: + case IterativeParsingMemberNumberStartState: { + // keep write-out the value + o_val_strm.write(in_byte); + val_vld_strm.write(true); + e_val_strm.write(false); + break; + } + case IterativeParsingMemberValueEndState: { + // end of value + if (src == IterativeParsingMemberStringStartState) { + o_val_strm.write(in_byte); + val_vld_strm.write(false); + e_val_strm.write(false); + } + break; + } + default: + break; + } + + return dst; +} + +/** + * + * @brief Parse the input line of JSON file iteratively. + * + * There is no complete error check mechanism. Currently it doesn't support nested-object and array. + * This module seperates the key and value for each fields based on state machine. + * + * + * @param in_strm input the char of each line every cycle. + * @param i_e_strm end flag for in_strm. + * @param o_k_strm ouput key for each field char by char. + * @param e_k_strm end flag for o_k_strm. + * @param k_vld_strm valid flag for o_k_strm, it indicates the start and end of each key. + * @param o_val_strm output the value for each field char by char. + * @param e_val_strm end flag for o_val_strm. + * @param val_vld_strm valid flag for o_val_strm, it indicates the start and end of each value. + * @param ln_e_strm end flag for each line. + * + */ + +static void iterativeParse(hls::stream >& in_strm, + hls::stream& i_e_strm, + // output key to the parsekey module + hls::stream >& o_k_strm, + hls::stream& e_k_strm, + // valid signal for each key + hls::stream& k_vld_strm, + // output value to the parseValue module + hls::stream >& o_val_strm, + hls::stream& e_val_strm, + // valid signal for each value + hls::stream& val_vld_strm, + hls::stream& ln_e_strm) { + IterativeParsingState state = IterativeParsingStartState; + bool e = i_e_strm.read(); + ap_uint<8> in_byte; + bool skip_space = true; + Token t; + static int cnt1 = 0; + // write on dummy + e_k_strm.write(false); + while (!e) { +#pragma HLS pipeline II = 1 + in_byte = in_strm.read(); + e = i_e_strm.read(); + t = (Token)tokenMap[(unsigned char)in_byte]; + IterativeParsingState n = (IterativeParsingState)G[state][t]; + IterativeParsingState d = Transit(in_byte, o_k_strm, k_vld_strm, e_k_strm, o_val_strm, val_vld_strm, e_val_strm, + ln_e_strm, state, t, n); + // Transition to the new state. + state = d; + } + e_val_strm.write(true); + // write one more dummy data + e_k_strm.write(true); + k_vld_strm.write(false); + o_k_strm.write(0); + ln_e_strm.write(false); +} +} +} +} +} +#endif diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/json_parse_block.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/json_parse_block.hpp new file mode 100644 index 0000000000..512cac2b84 --- /dev/null +++ b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/json_parse_block.hpp @@ -0,0 +1,429 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This file is part of Vitis Data Analytics Library. + */ +#ifndef XF_DATA_ANALYTICS_L1_DATAFRAME_JSON_PARSE_BLOCK_HPP +#define XF_DATA_ANALYTICS_L1_DATAFRAME_JSON_PARSE_BLOCK_HPP +#include "ap_int.h" +#include "hls_stream.h" +#include +#include "strtod.hpp" +#include "json_line_parser.hpp" +#include "parse_key.hpp" +#include "parse_value.hpp" +#include "parse_double.hpp" +#include "parse_date.hpp" +#include "utils.hpp" + +namespace xf { +namespace data_analytics { +namespace dataframe { +namespace internal { +/** + * + * @brief parse the input string stream, generate the offset. + * + * @param i_strm input stream of characters for each value. + * @param i_e_strm input end flag of i_hash_strm. + * @param vld_strm input valid flag for each character. + * @param o_strm output formated 64-bits width stream for string. + * @param o_byte_valid_strm byte valid for 64-bit o_strm + * @param o_vld_strm last frame flag for each string. + * + */ +void parseString(hls::stream >& i_strm, + hls::stream& i_e_strm, + hls::stream& i_vld_strm, + + hls::stream >& o_strm, + hls::stream >& o_byte_valid_strm, + hls::stream& o_vld_strm) { + ap_uint<64> str; + ap_uint<4> len = 0; + + bool e = i_e_strm.read(); + bool vld = i_vld_strm.read(); + ap_uint<8> in = i_strm.read(); + bool nb_1 = true; + bool nb_2 = true; + bool nb_3 = true; + + while (!e) { +#pragma HLS pipeline II = 1 + if (len == 8 || (!vld && nb_1 && nb_2 && nb_3)) { + o_vld_strm.write(!vld); // 1-last frame, 0-continue + if (len == 8) { + o_strm << str(63, 0); + o_byte_valid_strm << 0x8; + } else if (len > 0) { + ap_uint<64> t; + t(8 * len - 1, 0) = str(63, 8 * (8 - len)); + o_strm << t; + o_byte_valid_strm << len; + } + } + + if (vld && nb_1 && nb_2 && nb_3) { + str(55, 0) = str(63, 8); + str(63, 56) = in; + + if (len == 8) + len = 1; + else + len++; + } else if (!vld) + len = 0; + + nb_1 = i_strm.read_nb(in); + nb_2 = i_e_strm.read_nb(e); + nb_3 = i_vld_strm.read_nb(vld); + } +} +/** + * + * @brief parse the input string stream and convert it to int64. + * + * @param i_strm input stream of characters for each value. + * @param i_e_strm input end flag of i_strm. + * @param vld_strm input valid flag for each character. + * @param o_strm, output interger. + * + */ +static void parseInt64(hls::stream >& i_strm, + hls::stream& i_e_strm, + hls::stream& vld_strm, + hls::stream >& o_strm) { + ap_uint<64> value = 0; + bool e = false; + bool vld = true; + bool is_neg = false; + bool nb_1 = false; + bool nb_2 = false; + bool nb_3 = false; + while (!e) { +#pragma HLS pipeline II = 1 + if (!vld && nb_1 && nb_2 && nb_3) { + int64_t out = 0; + if (is_neg) + out = -value; + else + out = value; + o_strm.write(out); + value = 0; + is_neg = false; + } + // non-blocking read input + ap_uint<8> in; + nb_1 = vld_strm.read_nb(vld); + nb_2 = i_e_strm.read_nb(e); + nb_3 = i_strm.read_nb(in); + if (vld && nb_1 && nb_2 && nb_3) { + if (in == '-') + is_neg = true; + else if (in >= '0' && in <= '9') { + value = value * 10 + (in - '0'); + } + } + } +} + +/* + * @brief merge each valid field into a new row by object stream + * + **/ +static void mergeField(ap_uint<9> num_of_column, + // info for each column + hls::stream >& i_hash_strm, + hls::stream >& i_dt_strm, + hls::stream& i_null_strm, + hls::stream& i_e_strm, + // int64 + hls::stream >& i_int_strm, + // double + hls::stream >& i_double_strm, + // float + hls::stream >& i_float_strm, + // string + hls::stream >& i_str_strm, + hls::stream >& i_str_vld_strm, + hls::stream& i_str_e_strm, + // Boolean + hls::stream& i_bool_strm, + // Date + hls::stream >& i_date_strm, + // output + hls::stream& o_ln_e_strm, + hls::stream& o_obj_strm) { + ap_uint<8> col_cnt = 0; + ap_uint<4> data_type = i_dt_strm.read(); + ap_uint<8> col_idx = i_hash_strm.read(); + bool is_null = i_null_strm.read(); + bool e = i_e_strm.read(); + while (!e) { +#pragma HLS pipeline II = 2 + ap_uint<64> d; + ap_uint<4> byte_vld; + bool e_vld; + Object obj; + + obj.set_id(col_idx); + obj.set_type(data_type); + if (!is_null) { + switch (data_type) { + case (TInt64): { + e_vld = true; + i_int_strm >> d; + obj.set_data(d); + obj.set_valid(8); + break; + } + case (TFloat32): { + e_vld = true; + i_double_strm.read(); // consume the dummy + d(31, 0) = i_float_strm.read(); + obj.set_data(d); + obj.set_valid(4); + break; + } + case (TDouble): { + e_vld = true; + i_float_strm.read(); // consume the dummy + i_double_strm >> d; + obj.set_data(d); + obj.set_valid(8); + break; + } + case (TString): { + i_str_strm >> d; + i_str_vld_strm >> byte_vld; + i_str_e_strm >> e_vld; + obj.set_data(d); + obj.set_valid(byte_vld); + break; + } + case (TBoolean): { + e_vld = true; + bool b = i_bool_strm.read(); + d(7, 0) = b ? 1 : 0; + obj.set_data(d); + obj.set_valid(1); + break; + } + case (TDate): { + e_vld = true; + i_date_strm >> d; + obj.set_data(d); + obj.set_valid(8); + break; + } + } + } else { + e_vld = true; + obj.set_data(0); + obj.set_valid(0); // Null + } + + // emit the object + o_obj_strm << obj; + + // update the column index + if (e_vld) { // only variable-length TString/TNumeric will pull down the `e_vld` + if (col_cnt == num_of_column - 1) { // move to the next line + Object t; + t.set_type(FEOL); + o_obj_strm << t; // end of line + o_ln_e_strm << false; // flag of EOL + col_cnt = 0; + } else + col_cnt++; + + i_dt_strm >> data_type; + i_hash_strm >> col_idx; + i_null_strm >> is_null; + i_e_strm >> e; + } + } + + // end of part of file + Object obj; + obj.set_type(FEOF); + o_obj_strm << obj; + o_ln_e_strm << false; // flag of EOF +} + +/** + * + * @brief parse the input string and store them in buffer. + * + * @param mask_cfg input valid flag of i_strm. + * @param key_buf input key configuration. + * @param type_buf input data type configuration. + * @param i_strm input stream of string. + * @param i_e_strm input end flag of i_strm. + * @param o_ln_e_strm ouput line end flag + * + */ + +template +void parseBlock(ap_uint<9> num_of_column, + ap_uint mask_cfg, + ap_uint<8> key_buf[COL_NUM][256], + ap_uint<4> type_buf[COL_NUM], + hls::stream >& i_strm, + hls::stream& i_e_strm, + hls::stream& o_ln_e_strm, + hls::stream& o_obj_strm) { +#pragma HLS dataflow +#ifndef __SYNTHESIS__ + static int PU_ID = 0; +#endif + hls::stream > k_strm("k_strm"); +#pragma HLS stream variable = k_strm depth = 8 + hls::stream e_k_strm("e_k_strm"); +#pragma HLS stream variable = e_k_strm depth = 8 + hls::stream k_vld_strm("k_vld_strm"); +#pragma HLS stream variable = k_vld_strm depth = 8 + + hls::stream > val_strm("val_strm"); +#pragma HLS stream variable = val_strm depth = 8 + hls::stream e_val_strm("e_val_strm"); +#pragma HLS stream variable = e_val_strm depth = 8 + hls::stream val_vld_strm("val_vld_strm"); +#pragma HLS stream variable = val_vld_strm depth = 8 + + hls::stream ln_e_strm("ln_e_strm"); +#pragma HLS stream variable = ln_e_strm depth = 8 + + // split the key and value, remove the delimiter + iterativeParse(i_strm, i_e_strm, k_strm, e_k_strm, k_vld_strm, val_strm, e_val_strm, val_vld_strm, ln_e_strm); + + hls::stream > hash_strm("hash_strm"); +#pragma HLS stream variable = hash_strm depth = 8 + hls::stream le_strm_0("le_strm_0"); +#pragma HLS stream variable = le_strm_0 depth = 8 + hls::stream e_strm_0_0("e_strm_0_0"); +#pragma HLS stream variable = e_strm_0_0 depth = 8 + hls::stream e_strm_0_1("e_strm_0_1"); +#pragma HLS stream variable = e_strm_0_1 depth = 8 + hls::stream > mk_strm("mk_strm"); +#pragma HLS stream variable = mk_strm depth = 8 + // compare the key and find the index + parseKey(k_strm, k_vld_strm, e_k_strm, ln_e_strm, mask_cfg, hash_strm, le_strm_0, e_strm_0_1, mk_strm, + e_strm_0_0, key_buf); + + hls::stream > hash_strm_0_1("hash_strm_0_1"); +#pragma HLS stream variable = hash_strm_0_1 depth = 8 + hls::stream le_strm_1("le_strm_1"); +#pragma HLS stream variable = le_strm_1 depth = 8 + addNull(mk_strm, e_strm_0_0, hash_strm_0_1, le_strm_1); + + hls::stream > int_strm("int_strm"); +#pragma HLS stream variable = int_strm depth = 8 + + hls::stream e_i_strm("e_i_strm"); +#pragma HLS stream variable = e_i_strm depth = 8 + hls::stream v_i_strm("v_i_strm"); +#pragma HLS stream variable = v_i_strm depth = 8 + + hls::stream > db_strm("db_strm"); +#pragma HLS stream variable = db_strm depth = 8 + hls::stream e_d_strm("e_d_strm"); +#pragma HLS stream variable = e_d_strm depth = 8 + hls::stream v_d_strm("v_d_strm"); +#pragma HLS stream variable = v_d_strm depth = 8 + + hls::stream > str_strm("str_strm"); +#pragma HLS stream variable = str_strm depth = 8 + hls::stream e_s_strm("e_s_strm"); +#pragma HLS stream variable = e_s_strm depth = 8 + hls::stream v_s_strm("v_s_strm"); +#pragma HLS stream variable = v_s_strm depth = 8 + + hls::stream bool_strm("bool_strm"); +#pragma HLS stream variable = bool_strm depth = 8 + + hls::stream > val_strm_0("val_strm_0"); +#pragma HLS stream variable = val_strm_0 depth = 8 + hls::stream val_vld_strm_0("val_vld_strm_0"); +#pragma HLS stream variable = val_vld_strm_0 depth = 8 + hls::stream e_val_strm_0("e_val_strm_0"); +#pragma HLS stream variable = e_val_strm_0 depth = 8 + + hls::stream > hash_strm_0("hash_strm_0"); +#pragma HLS stream variable = hash_strm_0 depth = 8 + hls::stream > dt_strm_0("dt_strm_0"); +#pragma HLS stream variable = dt_strm_0 depth = 8 + + hls::stream > date_strm("date_strm"); +#pragma HLS stream variable = date_strm depth = 8 + hls::stream e_dt_strm("e_dt_strm"); +#pragma HLS stream variable = e_dt_strm depth = 8 + + hls::stream > hash_strm_1("hash_strm_1"); +#pragma HLS stream variable = hash_strm_1 depth = 64 + hls::stream > dt_strm_1("dt_strm_1"); +#pragma HLS stream variable = dt_strm_1 depth = 64 + hls::stream null_strm("null_strm"); +#pragma HLS stream variable = null_strm depth = 64 + hls::stream e_strm_1("e_strm_1"); +#pragma HLS stream variable = e_strm_1 depth = 64 + + // merge the columns with null fields + duplicate(val_strm, val_vld_strm, e_val_strm, hash_strm, le_strm_0, e_strm_0_1, hash_strm_0_1, le_strm_1, + type_buf, val_strm_0, val_vld_strm_0, e_val_strm_0, hash_strm_0, dt_strm_0); + + // dispatch based on data type + parseValue(val_strm_0, val_vld_strm_0, e_val_strm_0, hash_strm_0, dt_strm_0, int_strm, e_i_strm, v_i_strm, + db_strm, e_d_strm, v_d_strm, str_strm, e_s_strm, v_s_strm, bool_strm, date_strm, e_dt_strm, + hash_strm_1, dt_strm_1, null_strm, e_strm_1); + + hls::stream > int64_strm("int64_strm"); +#pragma HLS stream variable = int64_strm depth = 8 + parseInt64(int_strm, e_i_strm, v_i_strm, int64_strm); + + hls::stream > db64_strm("db64_strm"); +#pragma HLS stream variable = db64_strm depth = 8 + hls::stream > ft32_strm("ft32_strm"); +#pragma HLS stream variable = ft32_strm depth = 8 + parseDouble(db_strm, e_d_strm, v_d_strm, db64_strm, ft32_strm); + + hls::stream > s_w64_strm("s_w64_strm"); +#pragma HLS stream variable = s_w64_strm depth = 8 + hls::stream > s_byte_valid_strm("s_byte_valid_strm"); +#pragma HLS stream variable = s_byte_valid_strm depth = 8 + hls::stream s_vld_strm("s_vld_strm"); +#pragma HLS stream variable = s_vld_strm depth = 8 + // combine char to form 64-bit data + parseString(str_strm, e_s_strm, v_s_strm, s_w64_strm, s_byte_valid_strm, s_vld_strm); + + hls::stream > date64_strm("date64_strm"); +#pragma HLS stream variable = date64_strm depth = 8 + parseDate(date_strm, e_dt_strm, date64_strm); + + // re-order and packet each into Object stream + mergeField(num_of_column, hash_strm_1, dt_strm_1, null_strm, e_strm_1, int64_strm, db64_strm, ft32_strm, s_w64_strm, + s_byte_valid_strm, s_vld_strm, bool_strm, date64_strm, o_ln_e_strm, o_obj_strm); +#ifndef __SYNTHESIS__ + PU_ID++; +#endif +} +} +} +} +} +#endif diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/parse_key.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/parse_key.hpp new file mode 100644 index 0000000000..4aa2c024ac --- /dev/null +++ b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/parse_key.hpp @@ -0,0 +1,188 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef XF_DATA_ANALYTICS_L1_DATAFRAME_INTERNAL_PARSE_KEY_HPP +#define XF_DATA_ANALYTICS_L1_DATAFRAME_INTERNAL_PARSE_KEY_HPP +#include "hls_stream.h" +#include "ap_int.h" +#include + +namespace xf { +namespace data_analytics { +namespace dataframe { +namespace internal { +/** + * + * @brief parse the key to find the index for it and filter out the key is not included in the schema. + * + * @param i_strm input stream for char of key. + * @param i_vld_strm valid flag for each char. + * @param i_e_strm end flag of i_strm. + * @param i_ln_e_strm line end flag. + * @param mask_cfg It configures which key is valid. + * @param o_hash_strm_0 ouput index which corresponds to input key. + * @param o_ln_e_strm_0 ouput line end flag + * @param o_e_strm_0 output end flag of o_hash_strm_0 + * @param o_mk_strm output mask flag to indicates the missing key for each line. + * @param o_e_strm output end flag of o_mk_strm; + * @param key_buff Input key in schema. + */ + +template +void parseKey(hls::stream >& i_strm, + hls::stream& i_vld_strm, + hls::stream& i_e_strm, + hls::stream& ln_e_strm, + ap_uint mask_cfg, + + hls::stream >& o_hash_strm_0, + hls::stream& o_ln_e_strm_0, + hls::stream& o_e_strm_0, + + // To addNull + hls::stream >& o_mk_strm, + hls::stream& o_e_strm, + + ap_uint<8> key_buff[COL_NUM][256]) { + ap_uint<9> hash_val = 0; + bool flag[COL_NUM]; + // Initialize the flag + for (int i = 0; i < COL_NUM; ++i) { +#pragma HLS unroll + flag[i] = true; + } + bool e = i_e_strm.read(); + bool first = true; + ap_uint<8> idx = 0; + ap_uint record = 0; + bool i_vld = true; + bool nb_1 = false; + bool nb_2 = false; + bool nb_3 = false; + bool nb_4 = false; + bool ln_e = false; + // write out one more dummy data + o_e_strm.write(false); + while (!e) { +#pragma HLS pipeline II = 1 + if (!i_vld && nb_1 && nb_2 && nb_3 && nb_4) { + idx = 0; + hash_val = (1 << 8); + // find the matched index of input key + for (int i = 0; i < COL_NUM; ++i) { + if (flag[i]) hash_val = i; + flag[i] = true; + } + ap_uint ch = 0; + if (ln_e) { + // check the missing key. + ch = record ^ mask_cfg; + record = 0; + o_mk_strm.write(ch); + o_e_strm.write(false); + } else if (hash_val < COL_NUM) { + // record the input key + record[hash_val] = 1; + } + first = true; + + // output the index + o_hash_strm_0.write(hash_val); + o_ln_e_strm_0.write(ln_e); + o_e_strm_0.write(false); + } + ap_uint<8> in_byte; + // non-blocking read the input stream. + nb_1 = i_strm.read_nb(in_byte); + nb_2 = i_vld_strm.read_nb(i_vld); + nb_3 = i_e_strm.read_nb(e); + nb_4 = ln_e_strm.read_nb(ln_e); + if (i_vld && nb_1 && nb_2 && nb_3 && nb_4) { + if (first) + // ignore the '\"' + first = false; + else { + // compare each char + for (int i = 0; i < COL_NUM; ++i) { +#pragma HLS unroll + flag[i] = flag[i] && (in_byte == key_buff[i][idx]); + } + idx++; + } + } + } + // write-out one more dummay data + o_hash_strm_0.write(0); + o_ln_e_strm_0.write(false); + o_e_strm_0.write(true); + + o_mk_strm.write(0); + o_e_strm.write(true); +} + +/** + * + * @brief add index for missing field. + * + * @param i_mk_strm input mask flag to indicate the missing field. + * @param i_e_strm input end flag for i_mk_strm + * @param o_hash_strm ouput index for missing field. + * @param o_ln_e_strm output line end flag. + */ +template +void addNull(hls::stream >& i_mk_strm, + hls::stream& i_e_strm, + + hls::stream >& o_hash_strm, + hls::stream& o_ln_e_strm) { + bool e = i_e_strm.read(); + bool ln_e = true; + ap_uint ch = 0; + while (!e) { +#pragma HLS pipeline II = 2 + if (!ln_e) { + if (ch == 0) { + // no missing field for this line. + ln_e = true; + o_hash_strm.write(0); + o_ln_e_strm.write(false); + } else { + // add the index for missing field + ln_e = false; + ap_uint<9> rd = 0; + for (int i = 0; i < COL_NUM; ++i) { +#pragma HLS unroll + if (ch[i]) { + rd = i; + ch[i] = 0; + break; + } + } + o_hash_strm.write(rd); + o_ln_e_strm.write(true); + } + } else { + e = i_e_strm.read(); + ch = i_mk_strm.read(); + ln_e = false; + } + } +} +} +} +} +} +#endif diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/parse_value.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/parse_value.hpp new file mode 100644 index 0000000000..4c9f5cc343 --- /dev/null +++ b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/parse_value.hpp @@ -0,0 +1,284 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef XF_DATA_ANALYTICS_L1_DATAFRAME_INTERNAL_PARSE_VALUE_HPP +#define XF_DATA_ANALYTICS_L1_DATAFRAME_INTERNAL_PARSE_VALUE_HPP +#include "hls_stream.h" +#include "ap_int.h" +#include "xf_data_analytics/dataframe/df_utils.hpp" +#include + +#ifndef __SYNTHESIS__ +#include +#endif + +namespace xf { +namespace data_analytics { +namespace dataframe { +namespace internal { +/** + * + * @brief parse the value and dispatched it based one data type. + * + * @param i_strm input value stream. + * @param i_vld_strm input valid flag for each character of value. + * @param i_e_strm input end flag of i_strm. + * @param i_hash_strm input index for each value. + * @param i_type_strm input data type for each value. + * @param o_int_strm output value with int type. + * @param e_i_strm output end flag of o_int_strm. + * @param v_i_strm output valid flag for o_int_strm. + * @param o_double_strm output value with double type. + * @param e_d_strm output end flag of o_double_strm. + * @param v_d_strm output valid flag of o_double_strm. + * @param o_str_strm output value with string type. + * @param e_s_strm output end flag of o_str_strm. + * @param v_s_strm output valid flag of o_str_strm. + * @param o_bool_strm output value with boolean type. + * @param o_date_strm output value with date type. + * @param e_dt_strm output end flag of o_date_strm. + * @param o_hash_strm output index for each value + * @param o_dt_strm output data type for each index. + * @param o_null_strm output value is null. + * @param o_e_strm output end flag for o_hash_strm. + */ +template +void parseValue(hls::stream >& i_strm, + hls::stream& i_vld_strm, + hls::stream& i_e_strm, + + hls::stream >& i_hash_strm, + hls::stream >& i_type_strm, + // int64 + hls::stream >& o_int_strm, + hls::stream& e_i_strm, + hls::stream& v_i_strm, + // double + hls::stream >& o_double_strm, + hls::stream& e_d_strm, + hls::stream& v_d_strm, + // string + hls::stream >& o_str_strm, + hls::stream& e_s_strm, + hls::stream& v_s_strm, + // Boolean + hls::stream& o_bool_strm, + // Date + hls::stream >& o_date_strm, + hls::stream& e_dt_strm, + + hls::stream >& o_hash_strm, + hls::stream >& o_dt_strm, + hls::stream& o_null_strm, + hls::stream& o_e_strm) { + bool first = true; + bool e = i_e_strm.read(); + ap_uint<4> data_type; + ap_uint<8> idx; + bool i_vld = false; + + bool is_null = false; + // write one dummy flag. + e_dt_strm.write(false); + while (!e) { +#pragma HLS pipeline II = 1 + ap_uint<8> in = i_strm.read(); + e = i_e_strm.read(); + data_type = i_type_strm.read(); + idx = i_hash_strm.read(); + if (!i_vld) { + first = true; + is_null = (in == 'n'); + + // output index + o_hash_strm.write(idx); + o_dt_strm.write(data_type); + o_null_strm.write(is_null); + o_e_strm.write(false); + + // output for boolean data type. + if (data_type == TBoolean && !is_null) { + if (in == 'f' || in == 'F') + o_bool_strm.write(false); + else + o_bool_strm.write(true); + } + } + i_vld = i_vld_strm.read(); + switch (data_type) { + case (TString): { + // ignore the first '\"' and null. + if ((!first && !is_null)) { + o_str_strm.write(in); + e_s_strm.write(false); + v_s_strm.write(i_vld); + } + first = false; + break; + } + case (TInt64): { + // ignore the null + if (!is_null) { + o_int_strm.write(in); + e_i_strm.write(false); + v_i_strm.write(i_vld); + } + break; + } + case (TDate): { + // ignore the null and concat the output stream into one stream. + ap_uint<9> tmp = 0; + tmp.range(8, 1) = in; + if (!is_null) { + tmp[0] = i_vld; + o_date_strm.write(tmp); + e_dt_strm.write(false); + } + break; + } + case (TDouble): + case (TFloat32): { + if (!is_null) { + o_double_strm.write(in); + e_d_strm.write(false); + v_d_strm.write(i_vld); + } + break; + } + case (TBoolean): + break; + default: +#ifndef __SYNTHESIS__ + std::cout << "This data type is not supported.\n"; +#endif + break; + } + } + + // int + e_i_strm.write(true); + o_int_strm.write(0); + v_i_strm.write(false); + // dobule + e_d_strm.write(true); + // Date + e_dt_strm.write(true); + // String + e_s_strm.write(true); + // end flag + o_e_strm.write(true); + o_hash_strm.write(0); + o_dt_strm.write(0); + o_null_strm.write(true); +} +/** + * + * @brief merge the two input stream and compose a pair of output. + * One input stream is from parseKey and the other one is from addNull. + * + * @param i_strm input value stream. + * @param i_vld_strm input valid flag for each character of value. + * @param i_e_strm input end flag of i_strm. + * @param i_hash_strm_0 input index 0 from parseKey. + * @param i_ln_e_strm_0 input line end flag from parseKey. + * @param i_e_strm_0 input end flag ofr i_hash_strm_0. + * @param i_hash_strm_1 input index 1 from addNull + * @param i_ln_e_strm_1 input line end flag from addNull. + * @param type_buff data type buffer. + * @param o_strm output value stream. + * @param o_vld_strm output valid flag for each character, + * @param o_e_strm output end flag for o_strm. + * @param o_hash_strm output merged index. + * @param o_type_strm output data type for input index. + * + */ + +template +void duplicate(hls::stream >& i_strm, + hls::stream& i_vld_strm, + hls::stream& i_e_strm, + + hls::stream >& i_hash_strm_0, + hls::stream& i_ln_e_strm_0, + hls::stream& i_e_strm_0, + + hls::stream >& i_hash_strm_1, + hls::stream& i_ln_e_strm_1, + ap_uint<4> type_buff[COL_NUM], + + hls::stream >& o_strm, + hls::stream& o_vld_strm, + hls::stream& o_e_strm, + hls::stream >& o_hash_strm, + hls::stream >& o_type_strm) { + ap_uint<4> type_buff_local[COL_NUM]; +#pragma HLS array_partition variable = type_buff_local + // intialize the local buffer + for (int i = 0; i < COL_NUM; ++i) { +#pragma HLS pipeline II = 1 + type_buff_local[i] = type_buff[i]; + } + const int invalid_idx = COL_NUM; + ap_uint<4> data_type; + ap_uint<9> idx; + bool i_vld = false; + + bool ln_e = false; + bool e1 = false; + bool e = i_e_strm.read(); + while (!e || !e1) { +#pragma HLS pipeline II = 1 + // read index when value ended + if (!i_vld) { + // read from key + idx = i_hash_strm_0.read(); + ln_e = i_ln_e_strm_0.read(); + e1 = i_e_strm_0.read(); + i_vld = true; + } else if (ln_e) { + // add null for missing field + idx = i_hash_strm_1.read(); + ln_e = i_ln_e_strm_1.read(); + i_vld = ln_e; + if (ln_e) { + o_hash_strm.write(idx); + o_type_strm.write(type_buff_local[idx]); + o_strm.write('n'); + o_vld_strm.write(false); + o_e_strm.write(false); + } + } else if (i_vld) { + // keep read the input value until it ends. + ap_uint<8> in = i_strm.read(); + e = i_e_strm.read(); + i_vld = i_vld_strm.read(); + if (idx < invalid_idx) { + o_hash_strm.write(idx); + o_type_strm.write(type_buff_local[idx]); + o_strm.write(in); + o_vld_strm.write(i_vld); + o_e_strm.write(false); + } + } + } + + o_e_strm.write(true); +} +} +} +} +} +#endif diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/read_block.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/read_block.hpp index 0de7385022..4b69db5450 100644 --- a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/read_block.hpp +++ b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/read_block.hpp @@ -31,6 +31,7 @@ namespace xf { namespace data_analytics { namespace dataframe { namespace internal { +template static void split(bool last, bool first, hls::stream >& i_strm, @@ -55,10 +56,15 @@ static void split(bool last, is_delimiter = true; else is_delimiter = false; - // reserve the line delimiter for CSV parser + if (fnd_head) { - o_strm.write(i_8); - o_e_strm.write(false); + if (MODE == 1 && !is_delimiter) { // JSON, remove '\n' + o_strm.write(i_8); + o_e_strm.write(false); + } else if (MODE == 0) { // CSV, reserve '\n' + o_strm.write(i_8); + o_e_strm.write(false); + } } if (!fnd_head && is_delimiter) fnd_head = true; } @@ -136,7 +142,7 @@ void readBlock(ap_uint<29> base_addr_buff[NM], } } -template +template void readWrapper(ap_uint<29> base_addr_buff[NM], ap_uint<29> nm_buff[NM], ap_uint<128>* ddr_buff, @@ -156,11 +162,11 @@ void readWrapper(ap_uint<29> base_addr_buff[NM], for (int i = 0; i < NM; ++i) { #pragma HLS unroll if (i == 0) - split(false, true, d_128_strm[i], m_e_strm[i], o_strm[i], e_strm[i]); + split(false, true, d_128_strm[i], m_e_strm[i], o_strm[i], e_strm[i]); else if (i == NM - 1) - split(true, false, d_128_strm[i], m_e_strm[i], o_strm[i], e_strm[i]); + split(true, false, d_128_strm[i], m_e_strm[i], o_strm[i], e_strm[i]); else - split(false, false, d_128_strm[i], m_e_strm[i], o_strm[i], e_strm[i]); + split(false, false, d_128_strm[i], m_e_strm[i], o_strm[i], e_strm[i]); } } @@ -222,7 +228,24 @@ void readCSV(ap_uint<128> ddr_buff[2000], hls::stream > o_strm[NM], h ap_uint<29> nm_buff[NM]; blockDivide(base_addr_buff, nm_buff, ddr_buff); - readWrapper(base_addr_buff, nm_buff, ddr_buff, o_strm, e_strm); + readWrapper(base_addr_buff, nm_buff, ddr_buff, o_strm, e_strm); +} + +/** + * @brief read JSON line to multiple stream for PUs + * + * @tparam NM number of PU + * @param ddr_buff buffer of JSON file + * @param o_strm output stream of string + * @param e_strm output end flag of i_strm + **/ +template +void readJSON(ap_uint<128> ddr_buff[2000], hls::stream > o_strm[NM], hls::stream e_strm[NM]) { + ap_uint<29> base_addr_buff[NM]; + ap_uint<29> nm_buff[NM]; + + blockDivide(base_addr_buff, nm_buff, ddr_buff); + readWrapper(base_addr_buff, nm_buff, ddr_buff, o_strm, e_strm); } } } diff --git a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/utils.hpp b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/utils.hpp index 806c610ce5..ed01c8fbf9 100644 --- a/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/utils.hpp +++ b/data_analytics/L1/include/hw/xf_data_analytics/dataframe/parser_blocks/utils.hpp @@ -24,15 +24,6 @@ namespace xf { namespace data_analytics { namespace dataframe { namespace internal { -struct Node { - ap_uint<12> next; - ap_uint<12> base_addr; -}; -struct FieldInfo { - ap_uint<12> head; - ap_uint<12> tail; - ap_uint<20> size; // ap_uint<32> -}; inline double bitsToDouble(uint64_t in) { union { diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/Makefile b/data_analytics/L1/tests/dataframe/jsonParser/Makefile similarity index 98% rename from dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/Makefile rename to data_analytics/L1/tests/dataframe/jsonParser/Makefile index df2a6cb184..97c7937fa3 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/Makefile +++ b/data_analytics/L1/tests/dataframe/jsonParser/Makefile @@ -239,9 +239,9 @@ runhls: data setup | check_vivado check_vpp $(HLS) -f run_hls.tcl; clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l64.prj + rm -rf settings.tcl *_hls.log json_parser.prj # Used by Jenkins test cleanall: clean -# MK_INC_END hls_test_rules.mk \ No newline at end of file +# MK_INC_END hls_test_rules.mk diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/description.json b/data_analytics/L1/tests/dataframe/jsonParser/description.json similarity index 57% rename from dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/description.json rename to data_analytics/L1/tests/dataframe/jsonParser/description.json index ee20ffa7c3..06a4e3a521 100644 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/description.json +++ b/data_analytics/L1/tests/dataframe/jsonParser/description.json @@ -1,6 +1,6 @@ { - "name": "Xilinx SSR FFT Float Rate4_Length16", - "description": "HLS case", + "name": "Xilinx JSON Parser", + "description": "", "flow": "hls", "platform_whitelist": [ "u200", @@ -10,28 +10,24 @@ "platform_blacklist": [], "part_whitelist": [], "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r4_l16", + "project": "json_parser", "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", + "clock": "3.33", + "topfunction": "json_dut", "top": { "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" + "test.cpp" ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" + "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw -I./" }, "testbench": { "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L16.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L16.verif" + "test.cpp", + "schema.txt" ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", + "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw", "ldflags": "", - "argv": {}, - "stdmath": false + "argv": {} }, "testinfo": { "disable": false, @@ -49,10 +45,10 @@ "hls_csynth": 10240 }, "max_time_min": { - "hls_vivado_syn": 470, + "hls_vivado_syn": 420, "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, + "hls_cosim": 420, + "hls_vivado_impl": 420, "hls_csynth": 60 } } @@ -66,4 +62,4 @@ ], "category": "canary" } -} \ No newline at end of file +} diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/run_hls.tcl b/data_analytics/L1/tests/dataframe/jsonParser/run_hls.tcl old mode 100755 new mode 100644 similarity index 65% rename from dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/run_hls.tcl rename to data_analytics/L1/tests/dataframe/jsonParser/run_hls.tcl index 473d27d31a..848e4bf350 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/run_hls.tcl +++ b/data_analytics/L1/tests/dataframe/jsonParser/run_hls.tcl @@ -16,24 +16,21 @@ source settings.tcl -set PROJ "prj_ssr_fft_reg_test_r4_l16.prj" +set PROJ "json_parser.prj" set SOLN "solution1" if {![info exists CLKP]} { - set CLKP 3.3 + set CLKP 3.33 } open_project -reset $PROJ -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L16.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L16.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top +add_files "test.cpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw -I./" +add_files -tb "test.cpp schema.txt" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw" +set_top json_dut open_solution -reset $SOLN - - - set_part $XPART create_clock -period $CLKP @@ -57,4 +54,4 @@ if {$VIVADO_IMPL == 1} { export_design -flow impl -rtl verilog } -exit \ No newline at end of file +exit diff --git a/data_analytics/L1/tests/dataframe/jsonParser/schema.txt b/data_analytics/L1/tests/dataframe/jsonParser/schema.txt new file mode 100644 index 0000000000..cc9149411b --- /dev/null +++ b/data_analytics/L1/tests/dataframe/jsonParser/schema.txt @@ -0,0 +1,6 @@ +"bool column":0 +"int column":1 +"float column":2 +"double column":3 +"date column":4 +"string column":5 diff --git a/data_analytics/L1/tests/dataframe/jsonParser/test.cpp b/data_analytics/L1/tests/dataframe/jsonParser/test.cpp new file mode 100644 index 0000000000..bf0795ddbe --- /dev/null +++ b/data_analytics/L1/tests/dataframe/jsonParser/test.cpp @@ -0,0 +1,249 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xf_data_analytics/common/obj_interface.hpp" +#include "xf_data_analytics/dataframe/df_utils.hpp" +#include "xf_data_analytics/dataframe/json_parser.hpp" + +enum { PU_NM = 2 }; + +std::string gen_int_random() { + std::string str; + int rd = rand(); + int sg = rand(); + if (sg % 2 == 0) + str = std::to_string(-rd); + else + str = std::to_string(rd); + return str; +} + +std::string gen_float_random() { + std::string str; + int base = rand() % 1000; + double db = base + (double)(rand()) / RAND_MAX; + str = std::to_string(db); + return str; +} + +std::string gen_string_random() { + std::string str; + int len = rand() % 1024 + 1; + + str.push_back('"'); + for (int i = 0; i < len; i++) { + str.push_back('a'); + } + str.push_back('"'); + return str; +} + +std::string gen_bool_random() { + std::string str; + int rd = rand(); + if (rd % 2 == 1) + str = "false"; + else + str = "true"; + return str; +} + +std::string gen_date_random() { + int rd = rand(); + std::string test_array[10] = {"\"1970-01-01 00:00:01\"", // time just 1 sec after epoch + "\"2018-11-13 17:11:10\"", // casual time after epoch + "\"1969-12-31 23:59:59\"", // time just 1 sec before epoch + "\"1969-01-01 00:00:00\"", // casual time before epoch + "\"1970-01-01\"", // date without time + "\"0000-01-01 00:00:00\"", // the starting point of time + "\"9999-12-31 23:59:59\"", // the stopping point of time + "\"1970-01-01 01\"", // date with hour + "\"1970-01-01 01:01\"", // date with hour & min + "\"\""}; // not supported + return test_array[rd % 7]; +} + +void check_unit(const int valid_field_nm, hls::stream& o_obj_strm, int info[2]) { + int nerror = 0; + int cnt_hw_lines = 0, cnt_hw_fields = 0; + ap_uint<16> prev_id = 0xFFFF; + + xf::data_analytics::dataframe::Object t = o_obj_strm.read(); + while (t.get_type() != 15) { +#pragma HLS pipeline + if (t.get_type() == 13) { + if (cnt_hw_fields != valid_field_nm && valid_field_nm > 0) { + std::cout << "Error! " << cnt_hw_fields << ", at line " << cnt_hw_lines << std::endl; + nerror++; + } + cnt_hw_lines++; + cnt_hw_fields = 0; + } + if (t.get_id() != prev_id && t.get_type() != 13) cnt_hw_fields++; + if (t.get_type() != 13) + prev_id = t.get_id(); + else + prev_id = 0xFFFF; + // std::cout << std::hex << t.get_type() << " " << t.get_valid() << " " << t.get_id() << " " << t.get_data() + // << std::dec << std::endl; + + o_obj_strm >> t; + } + + info[0] = nerror; + info[1] = cnt_hw_lines; +} + +void json_dut(const int valid_field_nm, ap_uint<128> json_buf[50000], ap_uint<8> schema[300], int return_flag[2]) { +#pragma HLS dataflow + hls::stream o_obj_strm; +#pragma HLS stream variable = o_obj_strm depth = 32 + xf::data_analytics::dataframe::jsonParser(json_buf, schema, o_obj_strm); + + check_unit(valid_field_nm, o_obj_strm, return_flag); +} + +int main() { + const int input_lines = 1000; + std::string schemafile = "./schema.txt"; + std::ifstream sfile(schemafile.c_str(), std::ios::in); + if (!sfile.is_open()) { + std::cout << "Failed to open file " << schemafile << std::endl; + return -1; + } + + std::vector field_name; + char ty_arr[256]; + int field_nm = 0; + ap_uint<16> valid_field = 0; + char line[256]; + std::string schema_lines; + while (sfile.getline(line, sizeof(line))) { + std::stringstream tmp(line); + schema_lines.append(tmp.str()); + schema_lines.push_back('\n'); + + std::size_t del_pos = tmp.str().find(':'); + field_name.push_back(tmp.str().substr(0, del_pos)); + valid_field[field_nm] = 1; + ty_arr[field_nm++] = tmp.str()[del_pos + 1]; + } + + std::string json_lines; + for (int i = 0; i < input_lines; i++) { + json_lines += "{"; + for (int j = 0; j < field_nm; j++) { + int null_col_idx_0 = rand() % field_nm; + int null_col_idx_1 = rand() % field_nm; + if (i % 2 == 1 && j == null_col_idx_0) { + // insert missing column + } else { + json_lines += field_name[j]; + json_lines += ":"; + if (i % 2 == 0 && j == null_col_idx_1) + json_lines.append("null"); + else if (ty_arr[j] == '0') + json_lines.append(gen_bool_random()); + else if (ty_arr[j] == '1') + json_lines.append(gen_int_random()); + else if (ty_arr[j] == '2') + json_lines.append(gen_float_random()); + else if (ty_arr[j] == '3') + json_lines.append(gen_float_random()); + else if (ty_arr[j] == '4') + json_lines.append(gen_date_random()); + else if (ty_arr[j] == '5') + json_lines.append(gen_string_random()); + else { + std::cout << "Invalid type for column setting" << std::endl; + return -1; + } + if (j < field_nm - 1) json_lines.push_back(','); + } + if (i % 2 == 1 && j == field_nm - 1 && null_col_idx_0 == field_nm - 1) json_lines.pop_back(); + } + json_lines += "}\n"; + } + // std::cout << json_lines << std::endl; + std::cout << "Size in bytes: " << json_lines.length() << std::endl; + + int input_size = json_lines.size(); + int dep = 50000; + ap_uint<128>* ddr_in = (ap_uint<128>*)malloc(sizeof(ap_uint<128>) * dep); + ap_uint<128> d_128; + ap_uint<4> vec_len = 0; + int rnm = 1; + for (int i = 0; i < input_size; i++) { + int8_t c = json_lines[i]; + d_128((vec_len + 1) * 8 - 1, vec_len * 8) = c; + vec_len++; + if (vec_len == 0) { + ddr_in[rnm] = d_128; + rnm++; + } + } + if (vec_len != 0) { + ap_uint<128> t = 0; + t(vec_len * 8 - 1, 0) = d_128(vec_len * 8 - 1, 0); + ddr_in[rnm++] = t; + } + + const int NM = PU_NM; + int avg = (rnm - 1) / NM; + int left = rnm - 1 - avg * NM; + int last = avg + left; + ap_uint<128> head = 0; + head.range(31, 0) = avg; + head.range(63, 32) = last; + ddr_in[0] = head; + + int dep2 = 300; + ap_uint<8>* schema_in = (ap_uint<8>*)malloc(dep2); + schema_in[0] = valid_field(7, 0); + schema_in[1] = valid_field(15, 8); + schema_in[2] = schema_lines.size() % 256; + schema_in[3] = schema_lines.size() / 256; + for (int i = 0; i < schema_lines.size(); i++) { + int8_t c = schema_lines[i]; + schema_in[i + 4] = c; + } + + int return_flag[2]; + json_dut(field_nm, ddr_in, schema_in, return_flag); + + int nerror = return_flag[0]; + int cnt_hw_lines = return_flag[1]; + std::cout << "Total lines: " << cnt_hw_lines << std::endl; + if (nerror == 0 && cnt_hw_lines == input_lines) + std::cout << "TEST PASSED!!" << std::endl; + else + std::cout << "TEST FAILED!!" << std::endl; + + free(ddr_in); + free(schema_in); + sfile.close(); + + return 0; +} diff --git a/data_analytics/docs/design_flows.rst b/data_analytics/docs/design_flows.rst index e74d79c33b..59bbc7be07 100644 --- a/data_analytics/docs/design_flows.rst +++ b/data_analytics/docs/design_flows.rst @@ -30,7 +30,7 @@ Setup the build environment using the Vitis and XRT scripts, and set the ``PLATF source /opt/xilinx/xrt/setup.sh export PLATFORM_REPO_PATHS=/opt/xilinx/platforms -The recommend flow to evaluate and test L1 components is described as follows using Vivado HLS tool. +The recommend flow to evaluate and test L1 components is described as follows using Vitis HLS tool. A top level C/C++ testbench (typically ``algorithm_name.cpp``) prepares the input data, passes them to the design under test, then performs any output data post processing and validation checks. diff --git a/data_analytics/docs/guide_L1/internals/jsonParser.rst b/data_analytics/docs/guide_L1/internals/jsonParser.rst new file mode 100644 index 0000000000..668f6f53fa --- /dev/null +++ b/data_analytics/docs/guide_L1/internals/jsonParser.rst @@ -0,0 +1,54 @@ +.. + Copyright 2019 Xilinx, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +.. + Copyright 2019 Xilinx, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +****************************** +JSON Parser +****************************** + +JSON is a popular file format used to store and transmit data objects consisting of key-value pairs. JSON parser can be used to accelerate explaining the flatten key-value pairs in memory, just like the CSV parser. All the parsed value will be packaged into the standard object-stream including the missing key. + +Features +============================= +Currently, JSON parser supports the following 6 data type: bool, integer, string, float, double and date. This parser don't support data type inference, so user should give the right setting for each column in the input schema defination like the CSV parser does. + +For the input JSON file, each json line should be stored in one buffer compactly line by line without any padding. Currently, nested object is NOT supported. In one json line, the absent of some keys are allowed. And the parser would figure out each of them and then fill a none-type into the output object-stream. + +Overall Structure +============================ +JSON parser is implemented as multiple PU architecture to provide high throughput. The diagram is illustrated as below. + +.. image:: /images/json_parser.png + :alt: JSON Parser Diagram + :width: 80% + :align: center + +The full JSON file should be loaded in a compacted buffer firstly. For the parallel execution of each PU, the read block will divide the input file into several chunks by its size. Line parser is a FSM-based module to parse-and-split out each key-value pair at one byte per cycle. Also, all the trivial characters will be removed in this stage. For each data type input, there is one dedicated parse-unit to translate the raw bytes into its own value. At the final stage, each selected field will be merged into one full column before structuring into the output object-stream protocal. + diff --git a/data_analytics/docs/images/json_parser.png b/data_analytics/docs/images/json_parser.png new file mode 100644 index 0000000000..6bec65ddad Binary files /dev/null and b/data_analytics/docs/images/json_parser.png differ diff --git a/data_compression/Jenkinsfile b/data_compression/Jenkinsfile index 5e1985ebc0..6c54a11b09 100644 --- a/data_compression/Jenkinsfile +++ b/data_compression/Jenkinsfile @@ -1,5 +1,5 @@ @Library('pipeline-library')_ -VitisLibPipeline (branch: 'next', libname: 'xf_compression', run_sw_in_pr: 'true', +VitisLibPipeline (branch: 'master', libname: 'xf_compression', run_sw_in_pr: 'true', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu', -upstream_dependencies: 'xf_security,next,../security', email: 'heeran@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_stable_latest') +upstream_dependencies: 'xf_security,master,../security', email: 'heeran@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_released') diff --git a/data_compression/L1/include/hw/inflate.hpp b/data_compression/L1/include/hw/inflate.hpp index 7476fde2ad..dd07f7ddb5 100644 --- a/data_compression/L1/include/hw/inflate.hpp +++ b/data_compression/L1/include/hw/inflate.hpp @@ -423,6 +423,76 @@ void kStreamReadZlibDecomp(hls::stream >& in, outEos << 1; // Terminate condition } +template +void axi2HlsDistributor(hls::stream >& in, hls::stream > out[NUM_CORE]) { + for (auto i = 0; i < NUM_CORE; i++) { + bool last = false; + ap_axiu<64, 0, 0, 0> tmp; + ap_uint<8> kp = 0; + ap_uint<8> cntr = 0; + ap_uint<72> tmpVal = 0; + while (last == false) { +#pragma HLS PIPELINE II = 1 + tmp = in.read(); + tmpVal.range(71, 8) = tmp.data; + kp = tmp.keep; + tmpVal.range(7, 0) = tmp.keep; + if (kp == 0xFF) + tmpVal.range(7, 0) = 8; + else + break; + out[i] << tmpVal; + last = tmp.last; + } + if (kp != 0xFF) { + while (kp) { + cntr += (kp & 0x1); + kp >>= 1; + } + tmpVal.range(7, 0) = cntr; + out[i] << tmpVal; + } + out[i] << 0; // Terminate condition + } +} + +template +void hls2AxiMerger(hls::stream >& outKStream, hls::stream > outDataStream[NUM_CORE]) { + for (auto i = 0; i < NUM_CORE; i++) { + ap_uint<8> strb = 0; + ap_uint<64> data; + ap_uint<72> tmp; + ap_axiu<64, 0, 0, 0> t1; + + tmp = outDataStream[i].read(); + + strb = tmp.range(7, 0); + t1.data = tmp.range(71, 8); + t1.strb = strb; + t1.keep = strb; + t1.last = 0; + if (strb == 0) { + t1.last = 1; + outKStream << t1; + } + while (strb != 0) { +#pragma HLS PIPELINE II = 1 + tmp = outDataStream[i].read(); + + strb = tmp.range(7, 0); + if (strb == 0) { + t1.last = 1; + } + outKStream << t1; + + t1.data = tmp.range(71, 8); + t1.strb = strb; + t1.keep = strb; + t1.last = 0; + } + } +} + template void kStreamWriteZlibDecomp(hls::stream >& outKStream, hls::stream >& outDataStream) { @@ -701,6 +771,42 @@ void inflateWithChkSum(hls::stream >& inStream, } // namespace details +template +void inflateMultiCores(hls::stream >& inaxistream, + hls::stream >& outaxistream) { + constexpr int c_parallelBit = PARALLEL_BYTES * 8; + + hls::stream > axi2HlsStrm[NUM_CORE]; + hls::stream > inflateOut[NUM_CORE]; + hls::stream > hlsDownStrm[NUM_CORE]; + hls::stream hlsEos[NUM_CORE]; + +#pragma HLS STREAM variable = axi2HlsStrm depth = 4096 +#pragma HLS STREAM variable = inflateOut depth = 4096 +#pragma HLS STREAM variable = hlsDownStrm depth = 32 +#pragma HLS STREAM variable = hlsEos depth = 32 + +#pragma HLS BIND_STORAGE variable = axi2HlsStrm type = FIFO impl = URAM +#pragma HLS BIND_STORAGE variable = inflateOut type = fifo impl = URAM + +#pragma HLS dataflow disable_start_propagation + details::axi2HlsDistributor(inaxistream, axi2HlsStrm); + + for (auto i = 0; i < NUM_CORE; i++) { +#pragma HLS UNROLL + details::bufferDownsizer(axi2HlsStrm[i], hlsDownStrm[i], hlsEos[i]); + details::inflateMultiByteCore( + hlsDownStrm[i], hlsEos[i], inflateOut[i]); + } + + details::hls2AxiMerger(outaxistream, inflateOut); +} + template void inflateMultiByte(hls::stream >& inaxistream, hls::stream >& outaxistream) { @@ -714,7 +820,6 @@ void inflateMultiByte(hls::stream >& inaxistream, #pragma HLS STREAM variable = axi2HlsStrm depth = 32 #pragma HLS STREAM variable = axi2HlsEos depth = 32 #pragma HLS STREAM variable = inflateOut depth = 32 -//#pragma HLS STREAM variable = inflateOut depth = 4096 #pragma HLS BIND_STORAGE variable = axi2HlsStrm type = FIFO impl = SRL #pragma HLS BIND_STORAGE variable = axi2HlsEos type = FIFO impl = SRL diff --git a/data_compression/L1/include/hw/stream_downsizer.hpp b/data_compression/L1/include/hw/stream_downsizer.hpp index ac4877121c..be943216db 100644 --- a/data_compression/L1/include/hw/stream_downsizer.hpp +++ b/data_compression/L1/include/hw/stream_downsizer.hpp @@ -99,6 +99,43 @@ void bufferDownsizer(hls::stream >& inStream, outStream << outVal; } +template +void bufferDownsizer(hls::stream >& inStream, + hls::stream >& outStream, + hls::stream& outEos) { + constexpr int16_t c_factor = 4; // = 64 / 16 + constexpr int16_t c_outWord = 2; // = 16 / 2 + ap_uint<16> outVal; + + ap_uint dsize = 0; + ap_uint cntr = 0; + auto inVal = inStream.read(); + // proceed further if valid size + ap_uint inSize = inVal.range(7, 0); + // if (inSize == 0) break; + auto outSizeV = ((inSize - 1) / c_outWord) + 1; +downsizer_assign: + while (inSize > 0) { +#pragma HLS PIPELINE II = 1 + outVal = inVal.range(23, 8); + inVal >>= 16; + outStream << outVal; + + outEos << 0; + dsize++; + if (dsize == outSizeV) { + inVal = inStream.read(); + inSize = inVal.range(7, 0); + + dsize = 0; + outSizeV = ((inSize - 1) / c_outWord) + 1; + } + } + // Block end Condition + outEos << 1; + outStream << 0; +} + template void bufferDownsizer(hls::stream >& inStream, hls::stream >& outStream) { @@ -380,8 +417,6 @@ void streamDownSizerP2PComp(hls::stream >& inStream, // Send ouputSize of the module outStreamSize << size; - // printf("[ %s ] sizeOutputV %d input_size %d size_4m_mm2s %d \n", __FUNCTION__, sizeOutputV, input_size, size); - conv512toV: for (int i = 0; i < sizeOutputV; i++) { #pragma HLS PIPELINE II = 1 diff --git a/data_compression/L1/tests/gzipc_16KB/description.json b/data_compression/L1/tests/gzipc_16KB/description.json index ef9a43878c..8c7674ee7e 100644 --- a/data_compression/L1/tests/gzipc_16KB/description.json +++ b/data_compression/L1/tests/gzipc_16KB/description.json @@ -52,7 +52,7 @@ "hls_vivado_syn": 16384, "hls_csim": 10240, "hls_cosim": 16384, - "hls_vivado_impl": 16384, + "hls_vivado_impl": 32768, "hls_csynth": 10240 }, "max_time_min": 300 diff --git a/data_compression/L2/demos/gzip/Makefile b/data_compression/L2/demos/gzip/Makefile index 9b89bef105..d42525eda7 100644 --- a/data_compression/L2/demos/gzip/Makefile +++ b/data_compression/L2/demos/gzip/Makefile @@ -109,14 +109,14 @@ endif ifneq (,$(shell echo $(XPLATFORM) | awk '/vck190/')) HOST_SRCS += $(CUR_DIR)/src/host.cpp $(XFLIB_DIR)/common/libs/compress/gzipOCLHost.cpp $(XFLIB_DIR)/common/libs/compress/gzipBase.cpp $(XFLIB_DIR)/common/libs/compress/gzipApp.cpp $(XFLIB_DIR)/common/libs/compress/compressApp.cpp $(XFLIB_DIR)/common/libs/xcl2/xcl2.cpp $(XFLIB_DIR)/common/libs/cmdparser/cmdlineparser.cpp $(XFLIB_DIR)/common/libs/logger/logger.cpp $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/crc32.c $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/adler32.c CXXFLAGS += -D GZIP_MULTICORE_COMPRESS -D PARALLEL_BLOCK=1 -D GZIP_MODE=1 -CXXFLAGS += -I $(SYSROOT)/usr/include -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger +CXXFLAGS += -I $(SYSROOT)/usr/include -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/L2/tests/src -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger CXXFLAGS += --sysroot=$(SYSROOT) LDFLAGS += -L $(SYSROOT)/usr/lib -L ${SYSROOT}/opt/xilinx/xrt/lib else HOST_SRCS += $(CUR_DIR)/src/host.cpp $(XFLIB_DIR)/common/libs/compress/gzipOCLHost.cpp $(XFLIB_DIR)/common/libs/compress/gzipBase.cpp $(XFLIB_DIR)/common/libs/compress/gzipApp.cpp $(XFLIB_DIR)/common/libs/compress/compressApp.cpp $(XFLIB_DIR)/common/libs/xcl2/xcl2.cpp $(XFLIB_DIR)/common/libs/cmdparser/cmdlineparser.cpp $(XFLIB_DIR)/common/libs/logger/logger.cpp $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/crc32.c $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/adler32.c CXXFLAGS += -D GZIP_MULTICORE_COMPRESS -D PARALLEL_BLOCK=1 -D GZIP_MODE=1 -CXXFLAGS += -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger +CXXFLAGS += -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/L2/tests/src -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger endif EXE_NAME := xil_gzip diff --git a/data_compression/L2/demos/gzip/description.json b/data_compression/L2/demos/gzip/description.json index ae7cb2b371..612e31acb7 100644 --- a/data_compression/L2/demos/gzip/description.json +++ b/data_compression/L2/demos/gzip/description.json @@ -50,7 +50,8 @@ "includepaths": [ "LIB_DIR/L1/include/hw", "LIB_DIR/common/thirdParty/zlib-1.2.7", - "LIB_DIR/common/libs/compress/" + "LIB_DIR/common/libs/compress/", + "LIB_DIR/L2/tests/src" ], "symbols": [ "GZIP_MULTICORE_COMPRESS", diff --git a/data_compression/L2/include/gzip_decompress_multicore.hpp b/data_compression/L2/include/gzip_decompress_multicore.hpp new file mode 100644 index 0000000000..31fd416ada --- /dev/null +++ b/data_compression/L2/include/gzip_decompress_multicore.hpp @@ -0,0 +1,57 @@ +/* + * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _XFCOMPRESSION_ZLIB_DECOMPRESS_QUAD_HPP_ +#define _XFCOMPRESSION_ZLIB_DECOMPRESS_QUAD_HPP_ + +#include +#include +#include +#include +#include "hls_stream.h" +#include "huffman_decoder.hpp" +#include "zlib_specs.hpp" +#include "lz_decompress.hpp" +#include "inflate.hpp" +#include "stream_downsizer.hpp" +#include "ap_axi_sdata.h" + +// use dynamic decoder by default +#ifndef DECODER_TYPE +#define DECODER_TYPE c_fullDecoder +#endif + +// by default disable low latency model +#ifndef LL_MODEL +#define LL_MODEL true +#endif + +#ifndef NUM_CORE +#define NUM_CORE 4 +#endif + +#ifndef MULTIPLE_BYTES +#define MULTIPLE_BYTES 8 +#endif + +#define LZ_MAX_OFFSET_LIMIT 32768 +#define LOW_OFFSET 10 + +extern "C" { +void xilDecompress(hls::stream >& inaxistreamd, hls::stream >& outaxistreamd); +} +#endif // _XFCOMPRESSION_ZLIB_DECOMPRESS_QUAD_HPP_ diff --git a/data_compression/L2/include/lz4_p2p_decompress_kernel.hpp b/data_compression/L2/include/lz4_p2p_decompress_kernel.hpp deleted file mode 100644 index 697abd965a..0000000000 --- a/data_compression/L2/include/lz4_p2p_decompress_kernel.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef _XFCOMPRESSION_LZ4_P2P_DECOMPRESS_KERNEL_HPP_ -#define _XFCOMPRESSION_LZ4_P2P_DECOMPRESS_KERNEL_HPP_ - -/** - * @file lz4_p2p_decompress_kernel.hpp - * @brief Header for LZ4 P2P decompression kernel. - * - * This file is part of Vitis Data Compression Library. - */ - -#include -#include -#include -#include "hls_stream.h" -#include - -#include "lz_decompress.hpp" -#include "mm2s.hpp" -#include "s2mm.hpp" -#include "stream_downsizer.hpp" -#include "stream_upsizer.hpp" -#include "lz4_decompress.hpp" -#include "lz4_p2p.hpp" -#define GMEM_DWIDTH 512 -#define GMEM_BURST_SIZE 16 - -// Kernel top functions -extern "C" { - -/** - * @brief LZ4 P2P decompression kernel is responsible for decompressing data - * which is in LZ4 encoded form. - * - * @param in input stream width - * @param out output stream width - * @param in_block_size input size - * @param in_compress_size output size - * @param block_start_idx start index of block - * @param no_blocks number of blocks for each compute unit - * @param block_size_in_kb block input size - * @param compute_unit particular compute unit - * @param total_no_cu number of compute units - * @param num_blocks number of blocks base don host buffersize - */ -void xilLz4P2PDecompress(const xf::compression::uintMemWidth_t* in, - xf::compression::uintMemWidth_t* out, - dt_blockInfo* bObj, - dt_chunkInfo* cObj, - uint32_t block_size_in_kb, - uint32_t compute_unit, - uint8_t total_no_cu, - uint32_t num_blocks); -} - -#endif // _XFCOMPRESSION_LZ4_P2P_DECOMPRESS_KERNEL_HPP_ diff --git a/data_compression/L2/include/lz4_unpacker_kernel.hpp b/data_compression/L2/include/lz4_unpacker_kernel.hpp deleted file mode 100644 index 6ffdcc815c..0000000000 --- a/data_compression/L2/include/lz4_unpacker_kernel.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef _XFCOMPRESSION_LZ4_UNPACKER_KERNEL_HPP_ -#define _XFCOMPRESSION_LZ4_UNPACKER_KERNEL_HPP_ - -/** - * @file lz4_unpacker_kernel.hpp - * @brief Header for Unpacker kernel. - * - * This file is part of Vitis Data Compression Library. - */ - -#include -#include -#include -#include "hls_stream.h" -#include - -#include "mm2s.hpp" -#include "s2mm.hpp" -#include "stream_downsizer.hpp" -#include "stream_upsizer.hpp" -#include "lz4_p2p.hpp" -#define GMEM_DWIDTH 512 - -// Kernel top functions -extern "C" { - -/** - * @brief LZ4 unpacker kernel is responsible in unpacking LZ4 compressed block - * information. - * - * @param in input stream width - * @param in_block_size input block size - * @param in_compress_size input compress size - * @param block_start_idx start index of each input block - * @param no_blocks_per_cu number of blocks for each compute unit - * @param original_size original file size - * @param in_start_index input start index - * @param no_blocks number of blocks - * @param block_size_in_kb size of each block - * @param first_chunk first chunk to determine header - * @param total_no_cu number of decompress compute units - * @param num_blocks number of blocks based on host buffersize - */ -void xilLz4Unpacker(const xf::compression::uintMemWidth_t* in, - dt_blockInfo* bObj, - dt_chunkInfo* cObj, - uint32_t block_size_in_kb, - uint8_t first_chunk, - uint8_t total_no_cu, - uint32_t num_blocks); -} - -#endif // _XFCOMPRESSION_LZ4_UNPACKER_KERNEL_HPP_ diff --git a/data_compression/L2/include/snappy_decompress_mm.hpp b/data_compression/L2/include/snappy_decompress_mm.hpp deleted file mode 100644 index 075168161b..0000000000 --- a/data_compression/L2/include/snappy_decompress_mm.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef _XFCOMPRESSION_SNAPPY_DECOMPRESS_MM_HPP_ -#define _XFCOMPRESSION_SNAPPY_DECOMPRESS_MM_HPP_ - -/** - * @file snappy_decompress_mm.hpp - * @brief C++ Header for snappy decompression kernel. - * - * This file is part of Vitis Data Compression Library. - */ -#include -#include -#include -#include "hls_stream.h" -#include - -#include "lz_decompress.hpp" -#include "lz_optional.hpp" -#include "mm2s.hpp" -#include "s2mm.hpp" -#include "stream_downsizer.hpp" -#include "stream_upsizer.hpp" - -#include "snappy_decompress.hpp" - -#define GMEM_DWIDTH 512 -#define GMEM_BURST_SIZE 16 -#define MAX_OFFSET 65536 -#define HISTORY_SIZE MAX_OFFSET - -extern "C" { -/** - * @brief Snappy decompression kernel takes compressed data as input and process in - * block based fashion and writes the raw data to global memory. - * - * @param in input compressed data - * @param out output raw data - * @param in_block_size input block size of each block - * @param in_compress_size compress size of each block - * @param block_size_in_kb block size in bytes - * @param no_blocks number of blocks - */ -void xilSnappyDecompress(const xf::compression::uintMemWidth_t* in, - xf::compression::uintMemWidth_t* out, - uint32_t* in_block_size, - uint32_t* in_compress_size, - uint32_t block_size_in_kb, - uint32_t no_blocks); -} -#endif // _XFCOMPRESSION_SNAPPY_DECOMPRESS_MM_HPP_ diff --git a/data_compression/L2/include/snappy_decompress_stream.hpp b/data_compression/L2/include/snappy_decompress_stream.hpp deleted file mode 100644 index 9744b32294..0000000000 --- a/data_compression/L2/include/snappy_decompress_stream.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef _XFCOMPRESSION_SNAPPY_DECOMPRESS_STREAM_HPP_ -#define _XFCOMPRESSION_SNAPPY_DECOMPRESS_STREAM_HPP_ - -/** - * @file snappy_decompress_stream.hpp - * @brief C++ Header for snappy decompression kernel. - * - * This file is part of XF Compression Library. - */ -#include -#include -#include -#include "hls_stream.h" -#include "ap_axi_sdata.h" -#include - -#include "kernel_stream_utils.hpp" -#include "lz_decompress.hpp" -#include "lz_optional.hpp" -#include "snappy_decompress.hpp" - -#define MAX_OFFSET 65536 -#define HISTORY_SIZE MAX_OFFSET - -extern "C" { -/** - * @brief Snappy decompression streaming kernel takes compressed data as input from kernel axi stream - * and process in block based fashion and writes the raw data to global memory. - * - * @param inaxistream input kernel axi stream for compressed data - * @param outaxistream output kernel axi stream for decompressed data - * @param inputSize input data size - * @param outputSize output data size - */ -void xilSnappyDecompressStream(hls::stream >& inaxistream, - hls::stream >& outaxistream, - uint32_t inputSize, - uint32_t outputSize); -} -#endif // _XFCOMPRESSION_SNAPPY_DECOMPRESS_STREAM_HPP_ diff --git a/data_compression/L2/src/gzip_decompress_multicore.cpp b/data_compression/L2/src/gzip_decompress_multicore.cpp new file mode 100644 index 0000000000..f75bd22289 --- /dev/null +++ b/data_compression/L2/src/gzip_decompress_multicore.cpp @@ -0,0 +1,33 @@ +/* + * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "gzip_decompress_multicore.hpp" + +const int c_historySize = LZ_MAX_OFFSET_LIMIT; + +extern "C" { +void xilDecompress(hls::stream >& inaxistreamd, + hls::stream >& outaxistreamd) { +#pragma HLS interface ap_ctrl_none port = return +#pragma HLS interface axis port = inaxistreamd +#pragma HLS interface axis port = outaxistreamd +#pragma HLS dataflow disable_start_propagation + // Call for decompression + xf::compression::inflateMultiCores(inaxistreamd, outaxistreamd); +} +} diff --git a/data_compression/L2/src/lz4_p2p_decompress_kernel.cpp b/data_compression/L2/src/lz4_p2p_decompress_kernel.cpp deleted file mode 100644 index bebb3e6e90..0000000000 --- a/data_compression/L2/src/lz4_p2p_decompress_kernel.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -/** - * @file lz4_p2p_decompress_kernel.cpp - * @brief Source for LZ4 decompression kernel. - * - * This file is part of Vitis Data Compression Library. - */ - -#include "lz4_p2p_decompress_kernel.hpp" - -#define MAX_OFFSET 65536 -#define HISTORY_SIZE MAX_OFFSET -const int c_gmemBurstSize = (2 * GMEM_BURST_SIZE); - -#define READ_STATE 0 -#define MATCH_STATE 1 -#define LOW_OFFSET_STATE 2 - -typedef ap_uint<8> uintV_t; - -void lz4CoreDec(hls::stream& inStreamMemWidth, - hls::stream& outStreamMemWidth, - const uint32_t _input_size, - const uint32_t _output_size, - const uint32_t _input_start_idx) { - uint32_t input_size = _input_size; - uint32_t output_size = _output_size; - uint32_t input_size1 = input_size; - uint32_t output_size1 = output_size; - uint32_t input_start_idx = _input_start_idx; - hls::stream instreamV("instreamV"); - hls::stream > decompressd_stream("decompressd_stream"); - hls::stream decompressed_stream("decompressed_stream"); -#pragma HLS STREAM variable = instreamV depth = 8 -#pragma HLS STREAM variable = decompressd_stream depth = 8 -#pragma HLS STREAM variable = decompressed_stream depth = 8 -#pragma HLS BIND_STORAGE variable = instreamV type = FIFO impl = SRL -#pragma HLS BIND_STORAGE variable = decompressd_stream type = FIFO impl = SRL -#pragma HLS BIND_STORAGE variable = decompressed_stream type = FIFO impl = SRL - bool uncomp_flag = 0; - if (input_size == output_size) uncomp_flag = 1; - -#pragma HLS dataflow - xf::compression::details::streamDownsizerP2P(inStreamMemWidth, instreamV, input_size, - input_start_idx); - xf::compression::lz4DecompressSimple(instreamV, decompressd_stream, input_size1, uncomp_flag); - xf::compression::lzDecompress(decompressd_stream, decompressed_stream, output_size); - xf::compression::details::streamUpsizer(decompressed_stream, outStreamMemWidth, - output_size1); -} - -void lz4Dec(const xf::compression::uintMemWidth_t* in, - xf::compression::uintMemWidth_t* out, - const uint32_t input_idx[PARALLEL_BLOCK], - const uint32_t input_idx1[PARALLEL_BLOCK], - const uint32_t input_size[PARALLEL_BLOCK], - const uint32_t output_size[PARALLEL_BLOCK], - const uint32_t input_size1[PARALLEL_BLOCK], - const uint32_t output_size1[PARALLEL_BLOCK], - const uint32_t output_idx[PARALLEL_BLOCK]) { - hls::stream inStreamMemWidth[PARALLEL_BLOCK]; - hls::stream outStreamMemWidth[PARALLEL_BLOCK]; -#pragma HLS STREAM variable = inStreamMemWidth depth = c_gmemBurstSize -#pragma HLS STREAM variable = outStreamMemWidth depth = c_gmemBurstSize -#pragma HLS BIND_STORAGE variable = inStreamMemWidth type = FIFO impl = SRL -#pragma HLS BIND_STORAGE variable = outStreamMemWidth type = FIFO impl = SRL - -#pragma HLS dataflow - // Transfer data from global memory to kernel - xf::compression::details::mm2sNbRoundOff( - in, input_idx, inStreamMemWidth, input_size); - for (uint8_t i = 0; i < PARALLEL_BLOCK; i++) { -#pragma HLS UNROLL - // lz4CoreDec is instantiated based on the PARALLEL_BLOCK - lz4CoreDec(inStreamMemWidth[i], outStreamMemWidth[i], input_size1[i], output_size1[i], input_idx1[i]); - } - - // Transfer data from kernel to global memory - xf::compression::details::s2mmNb( - out, output_idx, outStreamMemWidth, output_size); -} -//} // namespace end - -extern "C" { - -void xilLz4P2PDecompress(const xf::compression::uintMemWidth_t* in, - xf::compression::uintMemWidth_t* out, - dt_blockInfo* decompress_block_info, - dt_chunkInfo* decompress_chunk_info, - uint32_t block_size_in_kb, - uint32_t compute_unit, - uint8_t total_no_cu, - uint32_t num_blocks) { -#pragma HLS INTERFACE m_axi port = in offset = slave bundle = gmem -#pragma HLS INTERFACE m_axi port = out offset = slave bundle = gmem -#pragma HLS INTERFACE m_axi port = decompress_block_info offset = slave bundle = gmem -#pragma HLS INTERFACE m_axi port = decompress_chunk_info offset = slave bundle = gmem -#pragma HLS INTERFACE s_axilite port = in bundle = control -#pragma HLS INTERFACE s_axilite port = out bundle = control -#pragma HLS INTERFACE s_axilite port = decompress_block_info bundle = control -#pragma HLS INTERFACE s_axilite port = decompress_chunk_info bundle = control -#pragma HLS INTERFACE s_axilite port = block_size_in_kb bundle = control -#pragma HLS INTERFACE s_axilite port = compute_unit bundle = control -#pragma HLS INTERFACE s_axilite port = total_no_cu bundle = control -#pragma HLS INTERFACE s_axilite port = num_blocks bundle = control -#pragma HLS INTERFACE s_axilite port = return bundle = control - - uint32_t max_block_size = block_size_in_kb * 1024; - uint32_t compress_size[PARALLEL_BLOCK]; - uint32_t compress_size1[PARALLEL_BLOCK]; - uint32_t block_size[PARALLEL_BLOCK]; - uint32_t block_size1[PARALLEL_BLOCK]; - uint32_t input_idx[PARALLEL_BLOCK]; - uint32_t input_idx1[PARALLEL_BLOCK]; - uint32_t output_idx[PARALLEL_BLOCK]; -#pragma HLS ARRAY_PARTITION variable = input_idx dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = input_idx1 dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = output_idx dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = compress_size dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = compress_size1 dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = block_size dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = block_size1 dim = 0 complete - - uint32_t curr_no_blocks = decompress_chunk_info->numBlocksPerCU[compute_unit]; - int offset = num_blocks * compute_unit; - // printf ("In decode compute unit %d no_blocks %d\n", D_COMPUTE_UNIT, curr_no_blocks); - - for (uint32_t i = 0; i < curr_no_blocks; i += PARALLEL_BLOCK) { - uint32_t nblocks = PARALLEL_BLOCK; - if ((i + PARALLEL_BLOCK) > curr_no_blocks) { - nblocks = curr_no_blocks - i; - } - - for (uint32_t j = 0; j < PARALLEL_BLOCK; j++) { - dt_blockInfo bInfo = decompress_block_info[i + j + offset]; - if (j < nblocks) { - uint32_t iSize = bInfo.compressedSize; - uint32_t oSize = bInfo.blockSize; - uint32_t startIdx = bInfo.blockStartIdx; - compress_size[j] = iSize; - block_size[j] = oSize; - compress_size1[j] = iSize; - block_size1[j] = oSize; - input_idx[j] = startIdx; - input_idx1[j] = startIdx; - // printf("iSize:%d\toSize:%d\tblockIdx:%d\n", iSize, oSize, input_idx[j]); - output_idx[j] = (i + j) * max_block_size; - } else { - compress_size[j] = 0; - block_size[j] = 0; - compress_size1[j] = 0; - block_size1[j] = 0; - input_idx[j] = 0; - input_idx1[j] = 0; - output_idx[j] = 0; - } - } - - lz4Dec(in, out, input_idx, input_idx1, compress_size, block_size, compress_size1, block_size1, output_idx); - } -} -} diff --git a/data_compression/L2/src/lz4_unpacker_kernel.cpp b/data_compression/L2/src/lz4_unpacker_kernel.cpp deleted file mode 100644 index 82ce1ee157..0000000000 --- a/data_compression/L2/src/lz4_unpacker_kernel.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -/** - * @file lz4_unpacker_kernel.cpp - * @brief Source for LZ4 P2P uncompress kernel. - * - * This file is part of Vitis Data Compression Library. - */ - -#include -#include -#include -#include "hls_stream.h" -#include - -#include "lz4_unpacker_kernel.hpp" - -/** - * This value is used to set - * uncompressed block size value. - * 4th byte is always set to below - * and placed as uncompressed byte - */ -#define NO_COMPRESS_BIT 128 - -/** - * In case of uncompressed block - * Values below are used to set - * 3rd byte to following values - * w.r.t various maximum block sizes - * supported by standard - */ -#define BSIZE_NCOMP_64 1 -#define BSIZE_NCOMP_256 4 -#define BSIZE_NCOMP_1024 16 -#define BSIZE_NCOMP_4096 64 - -/** - * Below are the codes as per LZ4 standard for - * various maximum block sizes supported. - */ -#define BSIZE_STD_64KB 0x40 -#define BSIZE_STD_256KB 0x50 -#define BSIZE_STD_1024KB 0x60 -#define BSIZE_STD_4096KB 0x70 - -typedef ap_uint uintMemWidth_t; - -// Stream in_block_size, in_compress_size, block_start_idx to decompress kernel. And need to put Macro or use array -// based on number of compute units - -extern "C" { -void xilLz4Unpacker(const xf::compression::uintMemWidth_t* in, - dt_blockInfo* unpacker_block_info, - dt_chunkInfo* unpacker_chunk_info, - uint32_t block_size_in_kb, - uint8_t first_chunk, - uint8_t total_no_cu, - uint32_t num_blocks) { -#pragma HLS INTERFACE m_axi port = in offset = slave bundle = gmem -#pragma HLS INTERFACE m_axi port = unpacker_block_info offset = slave bundle = gmem -#pragma HLS INTERFACE m_axi port = unpacker_chunk_info offset = slave bundle = gmem -#pragma HLS INTERFACE s_axilite port = in bundle = control -#pragma HLS INTERFACE s_axilite port = unpacker_block_info bundle = control -#pragma HLS INTERFACE s_axilite port = unpacker_chunk_info bundle = control -#pragma HLS INTERFACE s_axilite port = block_size_in_kb bundle = control -#pragma HLS INTERFACE s_axilite port = first_chunk bundle = control -#pragma HLS INTERFACE s_axilite port = total_no_cu bundle = control -#pragma HLS INTERFACE s_axilite port = num_blocks bundle = control -#pragma HLS INTERFACE s_axilite port = return bundle = control - - uint32_t block_size_in_bytes = block_size_in_kb * 1024; - uint32_t max_no_blocks = num_blocks * total_no_cu; - - dt_chunkInfo cInfo; - - if (first_chunk) { - uintMemWidth_t inTemp; - /*Magic headers*/ - inTemp = in[0]; - uint8_t m1 = inTemp.range(7, 0); - uint8_t m2 = inTemp.range(15, 8); - uint8_t m3 = inTemp.range(23, 16); - uint8_t m4 = inTemp.range(31, 24); - - /*Header checksum*/ - uint8_t hc = inTemp.range(39, 32); - - /*Block size*/ - uint32_t code = inTemp.range(47, 40); - switch (code) { - case BSIZE_STD_64KB: - block_size_in_kb = 64; - break; - case BSIZE_STD_256KB: - block_size_in_kb = 256; - break; - case BSIZE_STD_1024KB: - block_size_in_kb = 1024; - break; - case BSIZE_STD_4096KB: - block_size_in_kb = 4096; - break; - default: - break; - } - block_size_in_bytes = block_size_in_kb * 1024; - - /*Original file size*/ - cInfo.originalSize = inTemp.range(111, 48); - - /*Calculate no of blocks based on original size of file*/ - cInfo.numBlocks = (cInfo.originalSize - 1) / block_size_in_bytes + 1; - - /*Initialize start index for first chunk*/ - cInfo.inStartIdx = 15; - } - - uint32_t curr_no_blocks = (cInfo.numBlocks >= max_no_blocks) ? max_no_blocks : cInfo.numBlocks; - - cInfo.numBlocks = cInfo.numBlocks - curr_no_blocks; - - const int c_byte_size = 8; - uint64_t inIdx = cInfo.inStartIdx; - uint32_t Idx1 = (inIdx * c_byte_size) / GMEM_DWIDTH; - uint32_t Idx2 = (inIdx * c_byte_size) % GMEM_DWIDTH; - uint32_t compressed_size = 0; - uint32_t compressed_size1 = 0; - - // struct object - dt_blockInfo bInfo; - - for (uint32_t blkIdx = 0; blkIdx < curr_no_blocks; blkIdx++) { -#pragma HLS PIPELINE off - if (Idx2 + 32 <= GMEM_DWIDTH) { - uintMemWidth_t inTemp; - inTemp = in[Idx1]; - compressed_size = inTemp.range(Idx2 + 32 - 1, Idx2); - } else { - uintMemWidth_t inTemp; - uintMemWidth_t inTemp1; - ap_uint<32> ctemp; - inTemp = in[Idx1]; - int c_word_size = GMEM_DWIDTH / c_byte_size; - inTemp1 = in[Idx1 + 1]; - ctemp = (inTemp1.range(Idx2 + 32 - GMEM_DWIDTH - 1, 0), inTemp.range(GMEM_DWIDTH - 1, Idx2)); - compressed_size = ctemp; - } - inIdx = inIdx + 4; - uint32_t tmp; - tmp = compressed_size; - tmp >>= 24; - if (tmp == NO_COMPRESS_BIT) { - uint8_t b1 = compressed_size; - uint8_t b2 = compressed_size >> 8; - uint8_t b3 = compressed_size >> 16; - if (b3 == BSIZE_NCOMP_64 || b3 == BSIZE_NCOMP_4096 || b3 == BSIZE_NCOMP_256 || b3 == BSIZE_NCOMP_1024) { - compressed_size = block_size_in_bytes; - } else { - uint32_t size = 0; - size = b3; - size <<= 16; - uint32_t temp = b2; - temp <<= 8; - size |= temp; - temp = b1; - size |= temp; - compressed_size = size; - } - } - bInfo.blockStartIdx = inIdx; - bInfo.compressedSize = compressed_size; - bInfo.blockSize = block_size_in_bytes; - unpacker_block_info[blkIdx] = bInfo; - // printf("blockStartIdx:%d\tcompressSize:%d\tblock_size_in_bytes:%d\n", - // unpacker_block_info[blkIdx].blockStartIdx, - // unpacker_block_info[blkIdx].compressedSize, unpacker_block_info[blkIdx].blockSize); - inIdx = inIdx + compressed_size; - Idx1 = (inIdx * c_byte_size) / GMEM_DWIDTH; - Idx2 = (inIdx * c_byte_size) % GMEM_DWIDTH; - } - cInfo.inStartIdx = inIdx; - - if (cInfo.numBlocks == 0) { - unpacker_block_info[curr_no_blocks - 1].blockSize = cInfo.originalSize % (block_size_in_bytes); - // If original size is multiple of block size - if (unpacker_block_info[curr_no_blocks - 1].blockSize == 0) // If original size is multiple of block size - unpacker_block_info[curr_no_blocks - 1].blockSize = block_size_in_bytes; - } - - for (int i = 0; i < total_no_cu; i++) { - if (curr_no_blocks > num_blocks) - cInfo.numBlocksPerCU[i] = num_blocks; - else - cInfo.numBlocksPerCU[i] = curr_no_blocks; - curr_no_blocks = curr_no_blocks - num_blocks; - } - - *unpacker_chunk_info = cInfo; -} -} diff --git a/data_compression/L2/src/snappy_decompress_mm.cpp b/data_compression/L2/src/snappy_decompress_mm.cpp deleted file mode 100644 index 71f67ede03..0000000000 --- a/data_compression/L2/src/snappy_decompress_mm.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -/** - * @file snappy_decompress_mm.cpp - * @brief Source for snappy decompression kernel. - * - * This file is part of Vitis Data Compression Library. - */ -#include -#include -#include -#include "hls_stream.h" -#include - -#include "snappy_decompress_mm.hpp" - -typedef ap_uint<8> uintV_t; -const int c_gmemBurstSize = (2 * GMEM_BURST_SIZE); - -// namespace hw_decompress { - -void snappyCoreDec(hls::stream& inStreamMemWidth, - hls::stream& outStreamMemWidth, - const uint32_t _input_size, - const uint32_t _output_size) { - uint32_t input_size = _input_size; - uint32_t output_size = _output_size; - uint32_t input_size1 = input_size; - uint32_t output_size1 = output_size; - hls::stream instreamV("instreamV"); - hls::stream decompressd_stream("decompressd_stream"); - hls::stream decompressed_stream("decompressed_stream"); -#pragma HLS STREAM variable = instreamV depth = 8 -#pragma HLS STREAM variable = decompressd_stream depth = 8 -#pragma HLS STREAM variable = decompressed_stream depth = 8 -#pragma HLS BIND_STORAGE variable = instreamV type = FIFO impl = SRL -#pragma HLS BIND_STORAGE variable = decompressd_stream type = FIFO impl = SRL -#pragma HLS BIND_STORAGE variable = decompressed_stream type = FIFO impl = SRL - -#pragma HLS dataflow - xf::compression::details::streamDownsizer(inStreamMemWidth, instreamV, input_size); - xf::compression::snappyDecompress(instreamV, decompressd_stream, input_size1); - xf::compression::lzDecompress(decompressd_stream, decompressed_stream, output_size); - xf::compression::details::streamUpsizer(decompressed_stream, outStreamMemWidth, - output_size1); -} - -void snappyDec(const xf::compression::uintMemWidth_t* in, - xf::compression::uintMemWidth_t* out, - const uint32_t input_idx[PARALLEL_BLOCK], - const uint32_t input_size[PARALLEL_BLOCK], - const uint32_t output_size[PARALLEL_BLOCK], - const uint32_t input_size1[PARALLEL_BLOCK], - const uint32_t output_size1[PARALLEL_BLOCK]) { - hls::stream inStreamMemWidth[PARALLEL_BLOCK]; - hls::stream outStreamMemWidth[PARALLEL_BLOCK]; - -#pragma HLS STREAM variable = inStreamMemWidth depth = c_gmemBurstSize -#pragma HLS STREAM variable = outStreamMemWidth depth = c_gmemBurstSize -#pragma HLS BIND_STORAGE variable = inStreamMemWidth type = FIFO impl = SRL -#pragma HLS BIND_STORAGE variable = outStreamMemWidth type = FIFO impl = SRL - -#pragma HLS dataflow - // Transfer data from global memory to kernel - xf::compression::details::mm2sNb(in, input_idx, inStreamMemWidth, - input_size); - for (uint8_t i = 0; i < PARALLEL_BLOCK; i++) { -#pragma HLS UNROLL - snappyCoreDec(inStreamMemWidth[i], outStreamMemWidth[i], input_size1[i], output_size1[i]); - } - // Transfer data from kernel to global memory - xf::compression::details::s2mmNb( - out, input_idx, outStreamMemWidth, output_size); -} - -//}//end of namepsace - -extern "C" { - -void xilSnappyDecompress(const xf::compression::uintMemWidth_t* in, - xf::compression::uintMemWidth_t* out, - uint32_t* in_block_size, - uint32_t* in_compress_size, - uint32_t block_size_in_kb, - uint32_t no_blocks) { -#pragma HLS INTERFACE m_axi port = in offset = slave bundle = gmem0 -#pragma HLS INTERFACE m_axi port = out offset = slave bundle = gmem0 -#pragma HLS INTERFACE m_axi port = in_block_size offset = slave bundle = gmem1 -#pragma HLS INTERFACE m_axi port = in_compress_size offset = slave bundle = gmem1 -#pragma HLS INTERFACE s_axilite port = in bundle = control -#pragma HLS INTERFACE s_axilite port = out bundle = control -#pragma HLS INTERFACE s_axilite port = in_block_size bundle = control -#pragma HLS INTERFACE s_axilite port = in_compress_size bundle = control -#pragma HLS INTERFACE s_axilite port = block_size_in_kb bundle = control -#pragma HLS INTERFACE s_axilite port = no_blocks bundle = control -#pragma HLS INTERFACE s_axilite port = return bundle = control - - uint32_t max_block_size = block_size_in_kb * 1024; - uint32_t compress_size[PARALLEL_BLOCK]; - uint32_t compress_size1[PARALLEL_BLOCK]; - uint32_t block_size[PARALLEL_BLOCK]; - uint32_t block_size1[PARALLEL_BLOCK]; - uint32_t input_idx[PARALLEL_BLOCK]; -#pragma HLS ARRAY_PARTITION variable = input_idx dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = compress_size dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = compress_size1 dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = block_size dim = 0 complete -#pragma HLS ARRAY_PARTITION variable = block_size1 dim = 0 complete - - for (int i = 0; i < no_blocks; i += PARALLEL_BLOCK) { - int nblocks = PARALLEL_BLOCK; - if ((i + PARALLEL_BLOCK) > no_blocks) { - nblocks = no_blocks - i; - } - - for (int j = 0; j < PARALLEL_BLOCK; j++) { - if (j < nblocks) { - uint32_t iSize = in_compress_size[i + j]; - uint32_t oSize = in_block_size[i + j]; - compress_size[j] = iSize; - block_size[j] = oSize; - compress_size1[j] = iSize; - block_size1[j] = oSize; - input_idx[j] = (i + j) * max_block_size; - } else { - compress_size[j] = 0; - block_size[j] = 0; - compress_size1[j] = 0; - block_size1[j] = 0; - input_idx[j] = 0; - } - } - snappyDec(in, out, input_idx, compress_size, block_size, compress_size1, block_size1); - } -} -} diff --git a/data_compression/L2/src/snappy_decompress_stream.cpp b/data_compression/L2/src/snappy_decompress_stream.cpp deleted file mode 100644 index 7133c67703..0000000000 --- a/data_compression/L2/src/snappy_decompress_stream.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -/** - * @file snappy_decompress_stream.cpp - * @brief Source for snappy decompression kernel. - * - * This file is part of Vitis Compression Library. - */ -#include -#include -#include -#include "hls_stream.h" -#include - -#include "snappy_decompress_stream.hpp" - -typedef ap_uint<8> streamDt; - -extern "C" { - -void xilSnappyDecompressStream(hls::stream >& inaxistream, - hls::stream >& outaxistream, - uint32_t inputSize, - uint32_t outputSize) { -#pragma HLS interface axis port = inaxistream -#pragma HLS interface axis port = outaxistream -#pragma HLS interface s_axilite port = inputSize bundle = control -#pragma HLS interface s_axilite port = outputSize bundle = control -#pragma HLS interface s_axilite port = return bundle = control - - hls::stream decompressedStream("decompressedStream"); - hls::stream inStream("inStream"); - hls::stream outStream("outStream"); - -#pragma HLS STREAM variable = inStream depth = 2 -#pragma HLS STREAM variable = outStream depth = 2 -#pragma HLS STREAM variable = decompressedStream depth = 8 - -#pragma HLS dataflow - - xf::compression::details::kStreamRead<8>(inaxistream, inStream, inputSize); - - xf::compression::snappyDecompress(inStream, decompressedStream, inputSize); - xf::compression::lzDecompress(decompressedStream, outStream, outputSize); - - xf::compression::details::kStreamWriteFixedSize<8>(outaxistream, outStream, outputSize); -} -} diff --git a/data_compression/L2/tests/gzip_p2p_decompress/src/host.cpp b/data_compression/L2/tests/gzip_p2p_decompress/src/host.cpp index 946a386b41..e9afdbc2ec 100644 --- a/data_compression/L2/tests/gzip_p2p_decompress/src/host.cpp +++ b/data_compression/L2/tests/gzip_p2p_decompress/src/host.cpp @@ -112,6 +112,8 @@ void xil_decompress_top(std::string& decompress_mod, std::string& decompress_bin std::cout << std::fixed << std::setprecision(3) << std::endl << "File Size(" << sizes[order] << ")\t\t:" << len << std::endl << "File Name\t\t:" << lz_decompress_in << std::endl; + std::cout << "\nDecompression is successful. No errors found.\n"; + std::cout << std::endl; } void xil_validate(std::string& file_list) { @@ -173,4 +175,5 @@ int main(int argc, char* argv[]) { } else if (!decompress_mod.empty()) // "-d" - DeCompress Mode xil_decompress_top(decompress_mod, decompress_bin, deviceId, enable_p2p); + return 0; } diff --git a/data_compression/L2/tests/gzipc_8KB/Makefile b/data_compression/L2/tests/gzipc_8KB/Makefile index d99e87add7..18410938f9 100644 --- a/data_compression/L2/tests/gzipc_8KB/Makefile +++ b/data_compression/L2/tests/gzipc_8KB/Makefile @@ -109,14 +109,14 @@ endif ifneq (,$(shell echo $(XPLATFORM) | awk '/vck190/')) HOST_SRCS += $(CUR_DIR)/src/host.cpp $(XFLIB_DIR)/common/libs/compress/gzipOCLHost.cpp $(XFLIB_DIR)/common/libs/compress/gzipBase.cpp $(XFLIB_DIR)/common/libs/compress/gzipApp.cpp $(XFLIB_DIR)/common/libs/compress/compressApp.cpp $(XFLIB_DIR)/common/libs/xcl2/xcl2.cpp $(XFLIB_DIR)/common/libs/cmdparser/cmdlineparser.cpp $(XFLIB_DIR)/common/libs/logger/logger.cpp $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/crc32.c $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/adler32.c CXXFLAGS += -D GZIP_STREAM -D PERF_DM -D BLOCK_SIZE_IN_KB=8 -CXXFLAGS += -I $(SYSROOT)/usr/include -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger +CXXFLAGS += -I $(SYSROOT)/usr/include -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/L2/tests/src -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger CXXFLAGS += --sysroot=$(SYSROOT) LDFLAGS += -L $(SYSROOT)/usr/lib -L ${SYSROOT}/opt/xilinx/xrt/lib else HOST_SRCS += $(CUR_DIR)/src/host.cpp $(XFLIB_DIR)/common/libs/compress/gzipOCLHost.cpp $(XFLIB_DIR)/common/libs/compress/gzipBase.cpp $(XFLIB_DIR)/common/libs/compress/gzipApp.cpp $(XFLIB_DIR)/common/libs/compress/compressApp.cpp $(XFLIB_DIR)/common/libs/xcl2/xcl2.cpp $(XFLIB_DIR)/common/libs/cmdparser/cmdlineparser.cpp $(XFLIB_DIR)/common/libs/logger/logger.cpp $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/crc32.c $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/adler32.c CXXFLAGS += -D GZIP_STREAM -D PERF_DM -D BLOCK_SIZE_IN_KB=8 -CXXFLAGS += -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger +CXXFLAGS += -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/L2/tests/src -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger endif EXE_NAME := xil_gzip diff --git a/data_compression/L2/tests/gzipc_8KB/description.json b/data_compression/L2/tests/gzipc_8KB/description.json index 0e3c62e273..4c04080818 100644 --- a/data_compression/L2/tests/gzipc_8KB/description.json +++ b/data_compression/L2/tests/gzipc_8KB/description.json @@ -50,7 +50,8 @@ "includepaths": [ "LIB_DIR/L1/include/hw", "LIB_DIR/common/libs/compress/", - "LIB_DIR/common/thirdParty/zlib-1.2.7" + "LIB_DIR/common/thirdParty/zlib-1.2.7", + "LIB_DIR/L2/tests/src" ], "symbols": [ "GZIP_STREAM", @@ -66,7 +67,7 @@ ], "compiler": { "includepaths": [ - "LIB_DIR/../security/L1/include" + "LIB_DIR/../security/L1/include" ], "symbols": [ "GZIP_STREAM", diff --git a/data_compression/L2/tests/gzipc_chain_dm/Makefile b/data_compression/L2/tests/gzipc_chain_dm/Makefile index 70d9a2dbb7..ac4e2c5220 100644 --- a/data_compression/L2/tests/gzipc_chain_dm/Makefile +++ b/data_compression/L2/tests/gzipc_chain_dm/Makefile @@ -108,7 +108,7 @@ endif #Inclue Required Host Source Files HOST_SRCS += $(CUR_DIR)/src/host.cpp $(XFLIB_DIR)/common/libs/compress/gzipOCLHost.cpp $(XFLIB_DIR)/common/libs/compress/gzipBase.cpp $(XFLIB_DIR)/common/libs/compress/gzipApp.cpp $(XFLIB_DIR)/common/libs/compress/compressApp.cpp $(XFLIB_DIR)/common/libs/xcl2/xcl2.cpp $(XFLIB_DIR)/common/libs/cmdparser/cmdlineparser.cpp $(XFLIB_DIR)/common/libs/logger/logger.cpp $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/crc32.c $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/adler32.c CXXFLAGS += -D GZIP_STREAM -CXXFLAGS += -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger +CXXFLAGS += -I $(XFLIB_DIR)/L2/tests/src/ -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger EXE_NAME := xil_gzip EXE_FILE := $(BUILD_DIR)/$(EXE_NAME) diff --git a/data_compression/L2/tests/gzipc_chain_dm/description.json b/data_compression/L2/tests/gzipc_chain_dm/description.json index 1b24733c10..573e68e2b2 100644 --- a/data_compression/L2/tests/gzipc_chain_dm/description.json +++ b/data_compression/L2/tests/gzipc_chain_dm/description.json @@ -44,6 +44,7 @@ "LIB_DIR/common/thirdParty/zlib-1.2.7/adler32.c" ], "includepaths": [ + "LIB_DIR/L2/tests/src/", "LIB_DIR/L1/include/hw", "LIB_DIR/common/libs/compress/", "LIB_DIR/common/thirdParty/zlib-1.2.7" diff --git a/data_compression/L2/tests/gzipd_quadcores/Makefile b/data_compression/L2/tests/gzipd_quadcores/Makefile new file mode 100644 index 0000000000..5fea4b8e8d --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/Makefile @@ -0,0 +1,299 @@ +# Copyright 2019-2021 Xilinx, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# vitis makefile-generator v2.0.4 + +############################## Help Section ############################## +.PHONY: help + +help:: + $(ECHO) "Makefile Usage:" + $(ECHO) " make all TARGET= PLATFORM= HOST_ARCH=" + $(ECHO) " Command to generate the design for specified Target and Shell." + $(ECHO) " By default, HOST_ARCH=. HOST_ARCH is required for SoC shells" + $(ECHO) "" + $(ECHO) " make run TARGET= PLATFORM= HOST_ARCH=" + $(ECHO) " Command to run application in emulation." + $(ECHO) " By default, HOST_ARCH=. HOST_ARCH required for SoC shells" + $(ECHO) "" + $(ECHO) " make xclbin TARGET= PLATFORM= HOST_ARCH=" + $(ECHO) " Command to build xclbin application." + $(ECHO) " By default, HOST_ARCH=. HOST_ARCH is required for SoC shells" + $(ECHO) "" + $(ECHO) " make host HOST_ARCH=" + $(ECHO) " Command to build host application." + $(ECHO) " By default, HOST_ARCH=. HOST_ARCH is required for SoC shells" + $(ECHO) "" + $(ECHO) " NOTE: For embedded devices, e.g. zcu102/zcu104/vck190, env variable SYSROOT and EDGE_COMMON_SW need to be set first, and HOST_ARCH is either aarch32 or aarch64. For example," + $(ECHO) " export SYSROOT=< path-to-platform-sysroot >" + $(ECHO) " export EDGE_COMMON_SW=< path-to-rootfs-and-Image-files >" + $(ECHO) "" + $(ECHO) " make clean " + $(ECHO) " Command to remove the generated non-hardware files." + $(ECHO) "" + $(ECHO) " make cleanall" + $(ECHO) " Command to remove all the generated files." + $(ECHO) "" + +############################## Setting up Project Variables ############################## + +MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) +XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L2/*}') +CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) +XFLIB_DIR = $(XF_PROJ_ROOT) + +# setting devault value +TARGET ?= sw_emu +HOST_ARCH ?= + +#setting PLATFORM +ifeq ($(PLATFORM),) +PLATFORM := $(DEVICE) +endif +ifeq ($(PLATFORM),) +PLATFORM := xilinx_u250_gen3x16_xdma_3_1_202020_1 +endif + +# #################### Checking if PLATFORM in whitelist ############################ +PLATFORM_ALLOWLIST += xilinx_u250_gen3x16_xdma_3_1_202020_1 u200 u50 +PLATFORM_BLOCKLIST += zc vck + +include ./utils.mk +TEMP_DIR := _x_temp.$(TARGET).$(PLATFORM_NAME) +TEMP_REPORT_DIR := $(CUR_DIR)/reports/_x.$(TARGET).$(PLATFORM_NAME) +BUILD_DIR := build_dir.$(TARGET).$(PLATFORM_NAME) +BUILD_REPORT_DIR := $(CUR_DIR)/reports/_build.$(TARGET).$(PLATFORM_NAME) +EMCONFIG := $(BUILD_DIR)/emconfig.json +XCLBIN_DIR := $(CUR_DIR)/$(BUILD_DIR) +export XCL_BINDIR = $(XCLBIN_DIR) +include ././config.mk + +EXE_FILE_DEPS := +BINARY_CONTAINERS_DEPS := +RUN_DEPS := + +# get global setting +ifeq ($(HOST_ARCH), x86) +CXXFLAGS += -fmessage-length=0 -I$(CUR_DIR)/src/ -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++14 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label +LDFLAGS += -pthread -L$(XILINX_XRT)/lib -Wl,--as-needed -lOpenCL -lxrt_coreutil +VPP_FLAGS += -t $(TARGET) --platform $(XPLATFORM) --save-temps +VPP_LDFLAGS += --optimize 2 -R 2 +else ifeq ($(HOST_ARCH), aarch64) +CXXFLAGS += -I$(CUR_DIR)/src/ -fmessage-length=0 --sysroot=$(SYSROOT) -I$(SYSROOT)/usr/include/xrt -I$(XILINX_HLS)/include -std=c++14 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label +LDFLAGS += -pthread -L$(SYSROOT)/usr/lib -L$(XILINX_VITIS_AIETOOLS)/lib/aarch64.o -Wl,--as-needed -lxilinxopencl -lxrt_coreutil +VPP_FLAGS += -t $(TARGET) --platform $(XPLATFORM) --save-temps +VPP_LDFLAGS += --optimize 2 -R 2 +endif +CXXFLAGS += $(EXTRA_CXXFLAGS) +VPP_FLAGS += $(EXTRA_VPP_FLAGS) + +########################## Setting up Host Variables ########################## +ifeq ($(TARGET),sw_emu) +CXXFLAGS += -D SW_EMU_TEST +endif +ifeq ($(TARGET),hw_emu) +CXXFLAGS += -D HW_EMU_TEST +endif + +#Inclue Required Host Source Files +HOST_SRCS += $(CUR_DIR)/src/host.cpp $(XFLIB_DIR)/common/libs/xcl2/xcl2.cpp +CXXFLAGS += -D BLOCK_SIZE_IN_KB=32 +CXXFLAGS += -I $(XFLIB_DIR)/L2/tests/src/ -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger + +EXE_NAME := xil_zlib +EXE_FILE := $(BUILD_DIR)/$(EXE_NAME) +EXE_FILE_DEPS := $(HOST_SRCS) $(EXE_FILE_DEPS) + +HOST_ARGS := $(BUILD_DIR)/decompress.xclbin $(CUR_DIR)/sample.txt.gz +ifneq ($(HOST_ARCH), x86) +PKG_HOST_ARGS = $(foreach args,$(HOST_ARGS),$(subst $(dir $(patsubst %/,%,$(args))),,$(args))) +endif + +########################## Kernel compiler global settings ########################## +VPP_FLAGS += --config $(CUR_DIR)/hls.cfg +VPP_FLAGS += -D GZIP_STREAM -D BLOCKSIZE_IN_KB=32 -D STRTGY=1 +VPP_FLAGS += -I $(XFLIB_DIR)/../security/L1/include -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/L2/include -I $(XFLIB_DIR)/L2/src + +######################### binary container global settings ########################## +VPP_LDFLAGS_decompress_temp := --config $(CUR_DIR)/connectivity.cfg +VPP_LDFLAGS_decompress += $(VPP_LDFLAGS_decompress_temp) + +ifeq ($(HOST_ARCH), x86) +BINARY_CONTAINERS += $(BUILD_DIR)/decompress.xclbin +else +BINARY_CONTAINERS += $(BUILD_DIR)/decompress_pkg.xclbin +BINARY_CONTAINERS_PKG += $(BUILD_DIR)/decompress.xclbin +endif + +# ################ Setting Rules for Binary Containers (Building Kernels) ################ +$(TEMP_DIR)/xilDecompress.xo: $(XFLIB_DIR)/L2/src/gzip_decompress_multicore.cpp + $(ECHO) "Compiling Kernel: xilDecompress" + mkdir -p $(TEMP_DIR) + $(VPP) -c $(VPP_FLAGS_xilDecompress) $(VPP_FLAGS) -k xilDecompress -I'$(> $(RUN_SCRIPT) +ifneq ($(filter sw_emu hw_emu, $(TARGET)),) + @echo 'export XCL_EMULATION_MODE=$(TARGET)' >> $(RUN_SCRIPT) +endif + @echo 'export XILINX_VITIS=/mnt' >> $(RUN_SCRIPT) + @echo 'export XILINX_XRT=/usr' >> $(RUN_SCRIPT) + @echo 'if [ -f platform_desc.txt ]; then' >> $(RUN_SCRIPT) + @echo ' cp platform_desc.txt /etc/xocl.txt' >> $(RUN_SCRIPT) + @echo 'fi' >> $(RUN_SCRIPT) + @echo './$(EXE_NAME) $(PKG_HOST_ARGS)' >> $(RUN_SCRIPT) + @echo 'return_code=$$?' >> $(RUN_SCRIPT) + @echo 'if [ $$return_code -ne 0 ]; then' >> $(RUN_SCRIPT) + @echo ' echo "ERROR: Embedded host run failed, RC=$$return_code"' >> $(RUN_SCRIPT) + @echo 'else' >> $(RUN_SCRIPT) + @echo ' echo "INFO: TEST PASSED, RC=0"' >> $(RUN_SCRIPT) + @echo 'fi' >> $(RUN_SCRIPT) + @echo 'echo "INFO: Embedded host run completed."' >> $(RUN_SCRIPT) + @echo 'exit $$return_code' >> $(RUN_SCRIPT) +DATA_FILE := +DATA_DIR := +SD_FILES += $(RUN_SCRIPT) +SD_FILES += $(EXE_FILE) +SD_FILES += $(EMCONFIG) +SD_FILES += xrt.ini +SD_FILES += $(DATA_FILE)# where define DATAFILE in json +SD_FILES_WITH_PREFIX = $(foreach sd_file,$(SD_FILES), $(if $(filter $(sd_file),$(wildcard $(sd_file))), --package.sd_file $(sd_file))) +SD_DIRS_WITH_PREFIX = $(foreach sd_dir,$(DATA_DIR),--package.sd_dir $(sd_dir)) +PACKAGE_FILES := $(BINARY_CONTAINERS) +PACKAGE_FILES += $(AIE_CONTAINER) +SD_CARD := $(CUR_DIR)/package_$(TARGET) +$(SD_CARD): $(EXE_FILE) $(BINARY_CONTAINERS) $(RUN_SCRIPT) $(EMCONFIG) + @echo "Generating sd_card folder...." + mkdir -p $(SD_CARD) + chmod a+rx $(BUILD_DIR)/run_script.sh + $(VPP) -t $(TARGET) --platform $(XPLATFORM) -o $(BINARY_CONTAINERS_PKG) -p $(PACKAGE_FILES) $(VPP_PACKAGE) --package.out_dir $(SD_CARD) --package.rootfs $(SYSROOT)/../../rootfs.ext4 --package.kernel_image $(K_IMAGE) $(SD_FILES_WITH_PREFIX) $(SD_DIRS_WITH_PREFIX) + @echo "### ***** sd_card generation done! ***** ###" + +.PHONY: sd_card +sd_card: $(SD_CARD) +endif +############################## Setting Essential Checks and Building Rules ############################## +RUN_DEPS += $(EXE_FILE) $(BINARY_CONTAINERS) $(EMCONFIG) +RUN_DEPS += $(SD_CARD) +run: check_device $(RUN_DEPS) +#hw_emu +ifneq (,$(filter hw_emu, $(TARGET))) +ifeq ($(HOST_ARCH), x86) + LD_LIBRARY_PATH=$(LIBRARY_PATH):$$LD_LIBRARY_PATH \ + XCL_EMULATION_MODE=$(TARGET) $(EXE_FILE) $(HOST_ARGS) + +else + @echo $(RUN_DEPS) + $(SD_CARD)/launch_$(TARGET).sh -no-reboot -run-app $(notdir $(RUN_SCRIPT)) + grep "TEST PASSED, RC=0" $(SD_CARD)/qemu_output.log || exit 1 + +endif +endif +#sw_emu +ifneq (,$(filter sw_emu, $(TARGET))) +ifeq ($(HOST_ARCH), x86) + LD_LIBRARY_PATH=$(LIBRARY_PATH):$$LD_LIBRARY_PATH \ + XCL_EMULATION_MODE=$(TARGET) $(EXE_FILE) $(HOST_ARGS) + +else + @echo $(RUN_DEPS) + $(SD_CARD)/launch_$(TARGET).sh -no-reboot -run-app $(notdir $(RUN_SCRIPT)) + grep "TEST PASSED, RC=0" $(SD_CARD)/qemu_output.log || exit 1 + +endif +endif +#hw +ifeq ($(TARGET), hw) +ifeq ($(HOST_ARCH), x86) + $(EXE_FILE) $(HOST_ARGS) + +else + $(ECHO) "Please copy the content of sd_card folder and data to an SD Card and run on the board" +endif +endif + +############################## Setting Targets ############################## + +.PHONY: all clean cleanall emconfig +emconfig: $(EMCONFIG) +ifeq ($(HOST_ARCH), x86) +all: check_vpp check_platform check_xrt $(EXE_FILE) $(BINARY_CONTAINERS) emconfig +else +all: check_vpp check_platform check_sysroot $(EXE_FILE) $(BINARY_CONTAINERS) emconfig sd_card +endif + +.PHONY: host +ifeq ($(HOST_ARCH), x86) +host: check_xrt $(EXE_FILE) +else +host: check_sysroot $(EXE_FILE) +endif + +.PHONY: xclbin +ifeq ($(HOST_ARCH), x86) +xclbin: check_vpp check_xrt $(BINARY_CONTAINERS) +else +xclbin: check_vpp check_sysroot $(BINARY_CONTAINERS) +endif + +############################## Cleaning Rules ############################## +cleanh: + -$(RMDIR) $(EXE_FILE) vitis_* TempConfig system_estimate.xtxt *.rpt .run/ + -$(RMDIR) src/*.ll _xocc_* .Xil dltmp* xmltmp* *.log *.jou *.wcfg *.wdb sample_link.ini sample_compile.ini obj* bin* *.csv *.jpg *.jpeg *.png + +cleank: + -$(RMDIR) $(BUILD_DIR)/*.xclbin _vimage *xclbin.run_summary qemu-memory-_* emulation/ _vimage/ pl*start_simulation. sh *.xclbin + -$(RMDIR) _x_temp.*/_x.* _x_temp.*/.Xil _x_temp.*/profile_summary.* xo_* _x* + -$(RMDIR) _x_temp.*/dltmp* _x_temp.*/kernel_info.dat _x_temp.*/*.log + -$(RMDIR) _x_temp.* $(CUR_DIR)/test.list $(CUR_DIR)/sample_run.* + +cleanall: cleanh cleank + -$(RMDIR) $(BUILD_DIR) build_dir.* emconfig.json *.html $(TEMP_DIR) $(CUR_DIR)/reports *.csv *.run_summary $(CUR_DIR)/*.raw package_* $(BUILD_DIR)/run_script.sh .ipcache *.str + -$(RMDIR) $(XFLIB_DIR)/common/data/*.xe2xd* $(XFLIB_DIR)/common/data/*.orig* + -$(RMDIR) $(CUR_DIR)/Work $(CUR_DIR)/*.xpe $(CUR_DIR)/hw.o $(CUR_DIR)/*.xsa $(CUR_DIR)/xnwOut + +clean: cleanh \ No newline at end of file diff --git a/data_compression/L2/tests/gzipd_quadcores/README.rst b/data_compression/L2/tests/gzipd_quadcores/README.rst new file mode 100644 index 0000000000..de4e3cd223 --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/README.rst @@ -0,0 +1,46 @@ +============================================ +Xilinx Zlib Streaming Quadcore Decompression +============================================ + +Zlib example resides in ``L2/tests/zlibd`` directory. + +Follow build instructions to generate host executable and binary. + +The binary host file generated is named as "**xil_zlib**" and it is present in ``./build`` directory. + +Executable Usage +---------------- + +To execute single file for compression : ``./build/xil_zlib ./build/xclbin__/compress.xclbin `` + +Results +------- + +Resource Utilization +~~~~~~~~~~~~~~~~~~~~~ + +Table below presents resource utilization of Xilinx Zlib Decompress +kernels. The final Fmax achieved is 250MHz. + +========== ===== ====== ===== ===== ===== +Flow LUT LUTMem REG BRAM URAM +========== ===== ====== ===== ===== ===== +Decompress 27.2K 3.1K 20.8K 32 8 +========== ===== ====== ===== ===== ===== + +Performance Data +~~~~~~~~~~~~~~~~ + +Table below presents kernel throughput achieved for a single compute +unit. + +============================= ========================= +Topic Results +============================= ========================= +Compression Throughput 2 GB/s +============================= ========================= + +Standard GZip Support +--------------------- + +This application is compatible with standard Gzip/Zlib application (compress/decompress). diff --git a/data_compression/L2/tests/gzipd_quadcores/config.mk b/data_compression/L2/tests/gzipd_quadcores/config.mk new file mode 100644 index 0000000000..5d318b215d --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/config.mk @@ -0,0 +1,26 @@ +# +# Copyright 2019-2021 Xilinx, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifeq ($(TARGET),$(filter $(TARGET), hw_emu)) +ifeq ($(findstring 2018, $(DEVICE)), 2018) + CXXFLAGS += -DDISABLE_FREE_RUNNING_KERNEL + VPP_FLAGS += -DDISABLE_FREE_RUNNING_KERNEL +endif +endif + +ifeq ($(TARGET),$(filter $(TARGET), sw_emu)) + VPP_FLAGS += -DTUSER_DWIDTH=0 + VPP_FLAGS += -DNO_SYNTH -DAVOID_STATIC_MODE +endif diff --git a/data_compression/L2/tests/gzipd_quadcores/connectivity.cfg b/data_compression/L2/tests/gzipd_quadcores/connectivity.cfg new file mode 100644 index 0000000000..0446798f0d --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/connectivity.cfg @@ -0,0 +1,3 @@ +[connectivity] +stream_connect=xilDataMover_1.instream_orig:xilDecompress_1.inaxistreamd:32 +stream_connect=xilDecompress_1.outaxistreamd:xilDataMover_1.outstream_dest:32 diff --git a/data_compression/L2/tests/gzipd_quadcores/description.json b/data_compression/L2/tests/gzipd_quadcores/description.json new file mode 100644 index 0000000000..9d5394b82f --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/description.json @@ -0,0 +1,109 @@ +{ + "name": "Xilinx GZIP Streaming Quadcore Decompression", + "gui": false, + "description": [ + "Xilinx GZIP Streaming Quadcore Decompression" + ], + "flow": "vitis", + "launch": [ + { + "cmd_args": "BUILD/decompress.xclbin PROJECT/sample.txt.gz", + "name": "generic launch for all flows" + } + ], + "config_make": "./config.mk", + "platform_blacklist": [ + "zc", + "vck" + ], + "platform_whitelist": [ + "xilinx_u250_gen3x16_xdma_3_1_202020_1", + "u200", + "u50" + ], + "host": { + "host_exe": "xil_zlib", + "compiler": { + "sources": [ + "./src/host.cpp", + "LIB_DIR/common/libs/xcl2/xcl2.cpp" + ], + "includepaths": [ + "LIB_DIR/L2/tests/src/", + "LIB_DIR/L1/include/hw", + "LIB_DIR/common/libs/compress/", + "LIB_DIR/common/thirdParty/zlib-1.2.7" + ], + "symbols": [ + "BLOCK_SIZE_IN_KB=32" + ] + } + }, + "v++": { + "build_datafiles": [ + "PROJECT/hls.cfg" + ], + "compiler": { + "includepaths": [ + "LIB_DIR/../security/L1/include" + ], + "symbols": [ + "GZIP_STREAM", + "BLOCKSIZE_IN_KB=32", + "STRTGY=1" + ], + "clflags": [ + "--config PROJECT/hls.cfg" + ] + } + }, + "containers": [ + { + "name": "decompress", + "ldclflags": "--config PROJECT/connectivity.cfg", + "accelerators": [ + { + "name": "xilDecompress", + "location": "LIB_DIR/L2/src/gzip_decompress_multicore.cpp" + }, + { + "name": "xilDataMover", + "location": "LIB_DIR/L2/tests/src/block_stream_perf_dm.cpp" + } + ] + } + ], + "output_files": [ + "sample_run.*", + "test.list" + ], + "testinfo": { + "disable": false, + "jobs": [ + { + "index": 0, + "dependency": [], + "env": "", + "cmd": "", + "max_memory_MB": { + "vitis_hw_build": 40960, + "vitis_hw_emu": 28672, + "vitis_sw_emu": 10240, + "vitis_hw_run": 10240 + }, + "max_time_min": { + "vitis_hw_build": 470, + "vitis_hw_emu": 300, + "vitis_sw_emu": 25, + "vitis_hw_run": 10 + } + } + ], + "targets": [ + "vitis_sw_emu", + "vitis_hw_emu", + "vitis_hw" + ], + "category": "canary" + } +} diff --git a/data_compression/L2/tests/gzipd_quadcores/hls.cfg b/data_compression/L2/tests/gzipd_quadcores/hls.cfg new file mode 100644 index 0000000000..b8c8b1e50d --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/hls.cfg @@ -0,0 +1,2 @@ +[hls] +pre_tcl=hls_directives.tcl diff --git a/data_compression/L2/tests/gzipd_quadcores/hls_directives.tcl b/data_compression/L2/tests/gzipd_quadcores/hls_directives.tcl new file mode 100644 index 0000000000..418569df30 --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/hls_directives.tcl @@ -0,0 +1 @@ +config_dataflow -start_fifo_depth 32 -scalar_fifo_depth 32 -task_level_fifo_depth 32 diff --git a/data_compression/L2/tests/gzipd_quadcores/qor.json b/data_compression/L2/tests/gzipd_quadcores/qor.json new file mode 100644 index 0000000000..75f588e653 --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/qor.json @@ -0,0 +1,20 @@ +{ + "vitis": "2021.1", + "device_name": "xilinx_u200_xdma_201830_2", + "containers": [ + { + "name": "decompress", + "meet_system_timing": "true", + "accelerators": [ + { + "name": "xilDecompress", + "check_timing": "true", + "PipelineType": "none", + "check_latency": "true", + "check_warning": "true", + "FMax": "300 MHz" + } + ] + } + ] +} diff --git a/data_compression/L2/tests/gzipd_quadcores/run.sh b/data_compression/L2/tests/gzipd_quadcores/run.sh new file mode 100755 index 0000000000..dac38195c9 --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/run.sh @@ -0,0 +1,18 @@ +#!/bin/bash +EXE_FILE=$1 +LIB_PROJ_ROOT=$2 +XCLBIN_FILE=$3 +echo "XCL_MODE=${XCL_EMULATION_MODE}" +if [ "${XCL_EMULATION_MODE}" != "hw_emu" ] +then + cp $LIB_PROJ_ROOT/common/data/sample.txt ./sample_run.txt + for ((i = 0 ; i < 10 ; i++)) + do + find ./reports/ -type f | xargs cat >> ./sample_run.txt + done + + echo -e "\n\n-----------Running Compression for large file-----------\n" + cmd1="$EXE_FILE $XCLBIN_FILE ./sample_run.txt" + echo $cmd1 + $cmd1 +fi diff --git a/data_compression/L2/tests/gzipd_quadcores/sample.txt.gz b/data_compression/L2/tests/gzipd_quadcores/sample.txt.gz new file mode 100644 index 0000000000..f1bdc13a14 Binary files /dev/null and b/data_compression/L2/tests/gzipd_quadcores/sample.txt.gz differ diff --git a/data_compression/L2/tests/gzipd_quadcores/src/host.cpp b/data_compression/L2/tests/gzipd_quadcores/src/host.cpp new file mode 100644 index 0000000000..e4eaa03ccf --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/src/host.cpp @@ -0,0 +1,139 @@ +/* + * (c) Copyright 2019-2021 Xilinx, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "xcl2.hpp" +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) { + if (argc != 3) { + std::cout << "Usage: " << argv[0] << " " << std::endl; + return EXIT_FAILURE; + } + + // Read input file + std::ifstream ifs; + std::string binaryFile = argv[1]; + + std::string inFile_name = argv[2]; + ifs.open(argv[2], std::ofstream::binary | std::ofstream::in); + if (!ifs.is_open()) { + std::cout << "Cannot open the input file!!" << std::endl; + exit(0); + } + + ifs.seekg(0, std::ios::end); + uint32_t size = ifs.tellg(); + ifs.seekg(0, std::ios::beg); + + auto blockSize = BLOCK_SIZE_IN_KB * 1024; // can be changed for custom testing of block sizes upto 4KB. + auto blckNum = (size - 1) / blockSize + 1; + auto output_size = 10 * blckNum * BLOCK_SIZE_IN_KB * 1024; + auto num_itr = xcl::is_emulation() ? 4 : 400000; + + std::vector > h_input_buffer(size); + std::vector > h_output_buffer(output_size); + std::vector > h_compressSize(2 * blckNum); + ifs.read(reinterpret_cast(h_input_buffer.data()), size); + + // OPENCL HOST CODE AREA START + cl_int err; + cl::Context context; + cl::Kernel krnl_dm; + cl::CommandQueue q; + std::chrono::duration kernel_time_ns_1(0); + + // get_xil_devices() is a utility API which will find the xilinx + // platforms and will return list of devices connected to Xilinx platform + auto devices = xcl::get_xil_devices(); + // read_binary_file() is a utility API which will load the binaryFile + // and will return the pointer to file buffer. + auto fileBuf = xcl::read_binary_file(binaryFile); + cl::Program::Binaries bins{{fileBuf.data(), fileBuf.size()}}; + bool valid_device = false; + for (unsigned int i = 0; i < devices.size(); i++) { + auto device = devices[i]; + // Creating Context and Command Queue for selected Device + OCL_CHECK(err, context = cl::Context(device, nullptr, nullptr, nullptr, &err)); + OCL_CHECK(err, q = cl::CommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &err)); + std::cout << "Trying to program device[" << i << "]: " << device.getInfo() << std::endl; + cl::Program program(context, {device}, bins, nullptr, &err); + if (err != CL_SUCCESS) { + std::cout << "Failed to program device[" << i << "] with xclbin file!\n"; + } else { + std::cout << "Device[" << i << "]: program successful!\n"; + OCL_CHECK(err, krnl_dm = cl::Kernel(program, "xilDataMover", &err)); + valid_device = true; + break; // we break because we found a valid device + } + } + if (!valid_device) { + std::cout << "Failed to program any device found, exit!\n"; + exit(EXIT_FAILURE); + } + + // Device buffers + OCL_CHECK(err, cl::Buffer buffer_input(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(uint8_t) * size, + h_input_buffer.data(), &err)); + OCL_CHECK(err, cl::Buffer buffer_output(context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, + sizeof(uint8_t) * output_size, h_output_buffer.data(), &err)); + OCL_CHECK(err, cl::Buffer buffer_cSize(context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, + sizeof(uint32_t) * blckNum * 2, h_compressSize.data(), &err)); + auto narg = 0; + krnl_dm.setArg(narg++, buffer_input); + krnl_dm.setArg(narg++, buffer_output); + krnl_dm.setArg(narg++, size); + krnl_dm.setArg(narg++, num_itr); + krnl_dm.setArg(narg++, blockSize); + krnl_dm.setArg(narg++, buffer_cSize); + + // Copy input data to device global memory + OCL_CHECK(err, + err = q.enqueueMigrateMemObjects({buffer_input, buffer_output, buffer_cSize}, 0 /* 0 means from host*/)); + + // Launch the Kernel + // For HLS kernels global and local size is always (1,1,1). So, it is + // recommended + // to always use enqueueTask() for invoking HLS kernel + auto kernel_start = std::chrono::high_resolution_clock::now(); + OCL_CHECK(err, err = q.enqueueTask(krnl_dm)); + q.finish(); + auto kernel_stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration(kernel_stop - kernel_start); + kernel_time_ns_1 += duration; + + // Copy Result from Device Global Memory to Host Local Memory + OCL_CHECK(err, err = q.enqueueMigrateMemObjects({buffer_output, buffer_cSize}, CL_MIGRATE_MEM_OBJECT_HOST)); + q.finish(); + std::string outFile_name = inFile_name + ".orig"; + std::ofstream outFile(outFile_name.c_str(), std::ofstream::binary); + uint32_t uncompressedSize = h_compressSize[0]; + outFile.write((char*)h_output_buffer.data(), uncompressedSize); + + // OPENCL HOST CODE AREA END + std::cout << "**********************************************************************\n"; + std::cout << "\t\t\tXilinx Decompress\n"; + std::cout << "**********************************************************************\n"; + std::cout << "File Name \t\t:" << argv[2] << "\n"; + float throughput_in_mbps_1 = (float)blockSize * 1000 * num_itr / kernel_time_ns_1.count(); + std::cout << "Throughput \t\t:" << std::fixed << std::setprecision(2) << throughput_in_mbps_1 << "MB/s\n"; + std::cout << "**********************************************************************\n"; +} diff --git a/data_compression/L2/tests/gzipd_quadcores/utils.mk b/data_compression/L2/tests/gzipd_quadcores/utils.mk new file mode 100644 index 0000000000..1d75eeb3c7 --- /dev/null +++ b/data_compression/L2/tests/gzipd_quadcores/utils.mk @@ -0,0 +1,242 @@ +# +# Copyright 2019-2021 Xilinx, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# vitis makefile-generator v2.0.4 +# +#+------------------------------------------------------------------------------- +# The following parameters are assigned with default values. These parameters can +# be overridden through the make command line +#+------------------------------------------------------------------------------- + +REPORT := no +PROFILE := no +DEBUG := no + +#'estimate' for estimate report generation +#'system' for system report generation +ifneq ($(REPORT), no) +VPP_LDFLAGS += --report estimate +VPP_LDFLAGS += --report system +endif + +#Generates profile summary report +ifeq ($(PROFILE), yes) +VPP_LDFLAGS += --profile_kernel data:all:all:all +endif + +#Generates debug summary report +ifeq ($(DEBUG), yes) +VPP_LDFLAGS += --dk protocol:all:all:all +endif + +#Check environment setup +ifndef XILINX_VITIS + XILINX_VITIS = /opt/xilinx/Vitis/$(TOOL_VERSION) + export XILINX_VITIS +endif +ifndef XILINX_XRT + XILINX_XRT = /opt/xilinx/xrt + export XILINX_XRT +endif + +check_device: + @set -eu; \ + inallowlist=False; \ + inblocklist=False; \ + for dev in $(PLATFORM_ALLOWLIST); \ + do if [[ $$(echo $(PLATFORM_NAME) | grep $$dev) != "" ]]; \ + then inallowlist=True; fi; \ + done ;\ + for dev in $(PLATFORM_BLOCKLIST); \ + do if [[ $$(echo $(PLATFORM_NAME) | grep $$dev) != "" ]]; \ + then inblocklist=True; fi; \ + done ;\ + if [[ $$inallowlist == False ]]; \ + then echo "[Warning]: The device $(PLATFORM_NAME) not in allowlist."; \ + fi; \ + if [[ $$inblocklist == True ]]; \ + then echo "[ERROR]: The device $(PLATFORM_NAME) in blocklist."; exit 1;\ + fi; + +#get HOST_ARCH by PLATFORM +HOST_ARCH_temp = $(shell platforminfo -p $(PLATFORM) | grep 'CPU Type' | sed 's/.*://' | sed '/ai_engine/d' | sed 's/^[[:space:]]*//') +$(warning HOST_ARCH_temp:$(HOST_ARCH_temp)) +ifeq ($(HOST_ARCH_temp), x86) +HOST_ARCH := x86 +else ifeq ($(HOST_ARCH_temp), cortex-a9) +HOST_ARCH := aarch32 +else ifeq ($(HOST_ARCH_temp), cortex-a*) +HOST_ARCH := aarch64 +endif + +#Checks for Device Family +ifeq ($(HOST_ARCH), aarch32) + DEV_FAM = 7Series +else ifeq ($(HOST_ARCH), aarch64) + DEV_FAM = Ultrascale +endif + +#Checks for Correct architecture +ifneq ($(HOST_ARCH), $(filter $(HOST_ARCH),aarch64 aarch32 x86)) +$(error HOST_ARCH variable not set, please set correctly and rerun) +endif + +check_version: +ifneq (, $(shell which git)) +ifneq (,$(wildcard $(XFLIB_DIR)/.git)) + @cd $(XFLIB_DIR) && git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -n 1 && cd - +endif +endif + +#Checks for SYSROOT +check_sysroot: +ifneq ($(HOST_ARCH), x86) +ifndef SYSROOT + $(error SYSROOT ENV variable is not set, please set ENV variable correctly and rerun) +endif +endif + +#Checks for g++ +CXX := g++ +ifeq ($(HOST_ARCH), x86) +ifneq ($(shell expr $(shell echo "__GNUG__" | g++ -E -x c++ - | tail -1) \>= 5), 1) +ifndef XILINX_VIVADO +$(error [ERROR]: g++ version too old. Please use 5.0 or above) +else +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +ifeq ($(LD_LIBRARY_PATH),) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +else +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +endif +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) +endif +endif +else ifeq ($(HOST_ARCH), aarch64) +CXX := $(XILINX_VITIS)/gnu/aarch64/lin/aarch64-linux/bin/aarch64-linux-gnu-g++ +else ifeq ($(HOST_ARCH), aarch32) +CXX := $(XILINX_VITIS)/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++ +endif + +#Check OS and setting env +OSDIST = $(shell lsb_release -i |awk -F: '{print tolower($$2)}' | tr -d ' \t' ) +OSREL = $(shell lsb_release -r |awk -F: '{print tolower($$2)}' |tr -d ' \t') + +ifeq ($(OSDIST), centos) +ifeq (7,$(shell echo $(OSREL) | awk -F. '{print tolower($$1)}' )) +ifeq ($(HOST_ARCH), x86) +CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 +endif +endif +endif + +#Setting VPP +VPP := v++ + +#Cheks for aiecompiler +AIECXX := aiecompiler +AIESIMULATOR := aiesimulator +X86SIMULATOR := x86simulator + +.PHONY: check_vivado +check_vivado: +ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) + @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false +endif + +.PHONY: check_vpp +check_vpp: +ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) + @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false +endif + +.PHONY: check_xrt +check_xrt: +ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) + @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false +endif + +export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) +ifeq ($(HOST_ARCH), x86) +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(XILINX_XRT)/lib +else +LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) +endif +endif + +ifneq (,$(wildcard $(PLATFORM))) +# Use PLATFORM as a file path +XPLATFORM := $(PLATFORM) +else +# Use PLATFORM as a file name pattern +# 1. search paths specified by variable +ifneq (,$(PLATFORM_REPO_PATHS)) +# 1.1 as exact name +XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(PLATFORM)/$(PLATFORM).xpfm))) +# 1.2 as a pattern +ifeq (,$(XPLATFORM)) +XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) +XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(PLATFORM)/'))) +endif # 1.2 +endif # 1 +# 2. search Vitis installation +ifeq (,$(XPLATFORM)) +# 2.1 as exact name +XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(PLATFORM)/$(PLATFORM).xpfm)) +# 2.2 as a pattern +ifeq (,$(XPLATFORM)) +XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) +XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(PLATFORM)/'))) +endif # 2.2 +endif # 2 +# 3. search default locations +ifeq (,$(XPLATFORM)) +# 3.1 as exact name +XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(PLATFORM)/$(PLATFORM).xpfm)) +# 3.2 as a pattern +ifeq (,$(XPLATFORM)) +XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) +XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(PLATFORM)/'))) +endif # 3.2 +endif # 3 +endif + +define MSG_PLATFORM +No platform matched pattern '$(PLATFORM)'. +Available platforms are: $(XPLATFORMS) +To add more platform directories, set the PLATFORM_REPO_PATHS variable or point PLATFORM variable to the full path of platform .xpfm file. +endef +export MSG_PLATFORM + + +.PHONY: check_platform +check_platform: +ifeq (,$(XPLATFORM)) + @echo "$${MSG_PLATFORM}" && false +endif +#Check ends + +# device2xsa - create a filesystem friendly name from device name +# $(1) - full name of device +PLATFORM_NAME = $(strip $(patsubst %.xpfm, % , $(shell basename $(PLATFORM)))) + + +# Cleaning stuff +RM = rm -f +RMDIR = rm -rf + +MV = mv -f +CP = cp -rf +ECHO:= @echo diff --git a/vision/L2/tests/aie/blobFromImage/xrt.ini b/data_compression/L2/tests/gzipd_quadcores/xrt.ini old mode 100755 new mode 100644 similarity index 100% rename from vision/L2/tests/aie/blobFromImage/xrt.ini rename to data_compression/L2/tests/gzipd_quadcores/xrt.ini diff --git a/data_compression/L2/tests/lz4_p2p_decompress/src/host.cpp b/data_compression/L2/tests/lz4_p2p_decompress/src/host.cpp index 08eff809b5..d2f7347f0d 100644 --- a/data_compression/L2/tests/lz4_p2p_decompress/src/host.cpp +++ b/data_compression/L2/tests/lz4_p2p_decompress/src/host.cpp @@ -165,6 +165,8 @@ void xilDecompressTop(std::string& decompress_mod, uint32_t block_size, std::str std::cout << "Output Location: " << lz_decompress_out.c_str() << std::endl; #endif delete (xlz); + std::cout << "\nDecompression is successful. No errors found.\n"; + std::cout << std::endl; } int main(int argc, char* argv[]) { @@ -221,4 +223,5 @@ int main(int argc, char* argv[]) { if (!filelist.empty()) { xilBatchVerify(filelist, bSize, decompress_bin, enable_p2p); } + return 0; } diff --git a/data_compression/L3/benchmarks/lz4_p2p_compress/src/host.cpp b/data_compression/L3/benchmarks/lz4_p2p_compress/src/host.cpp index cf3c2e0c1a..1e5da5b9dd 100644 --- a/data_compression/L3/benchmarks/lz4_p2p_compress/src/host.cpp +++ b/data_compression/L3/benchmarks/lz4_p2p_compress/src/host.cpp @@ -88,6 +88,7 @@ void xil_compress_file_list(std::string& file_list, uint32_t block_size, std::st outFileList.push_back(out_file); } compress_multiple_files(inFileList, outFileList, block_size, compress_bin, enable_p2p); + std::cout << "\nCompression is successful. No errors found.\n"; std::cout << std::endl; } @@ -104,6 +105,7 @@ void xil_compress_file(std::string& file, uint32_t block_size, std::string& comp origFileList.push_back(orig_file); outFileList.push_back(out_file); compress_multiple_files(inFileList, outFileList, block_size, compress_bin, enable_p2p); + std::cout << "\nCompression is successful. No errors found.\n"; std::cout << std::endl; } diff --git a/data_compression/L3/demos/gzip_app/Makefile b/data_compression/L3/demos/gzip_app/Makefile index de3ce753dc..c4b2f0f3b9 100644 --- a/data_compression/L3/demos/gzip_app/Makefile +++ b/data_compression/L3/demos/gzip_app/Makefile @@ -108,7 +108,7 @@ endif #Inclue Required Host Source Files HOST_SRCS += $(CUR_DIR)/src/host.cpp $(XFLIB_DIR)/common/libs/compress/gzipOCLHost.cpp $(XFLIB_DIR)/common/libs/compress/gzipBase.cpp $(XFLIB_DIR)/common/libs/compress/gzipApp.cpp $(XFLIB_DIR)/common/libs/compress/compressApp.cpp $(XFLIB_DIR)/common/libs/xcl2/xcl2.cpp $(XFLIB_DIR)/common/libs/cmdparser/cmdlineparser.cpp $(XFLIB_DIR)/common/libs/logger/logger.cpp $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/crc32.c $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7/adler32.c CXXFLAGS += -D C_COMPUTE_UNIT=2 -D D_COMPUTE_UNIT=8 -D PARALLEL_BLOCK=4 -CXXFLAGS += -I $(XFLIB_DIR)/L3/include -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger +CXXFLAGS += -I $(XFLIB_DIR)/L3/include -I $(XFLIB_DIR)/L1/include/hw -I $(XFLIB_DIR)/common/thirdParty/zlib-1.2.7 -I $(XFLIB_DIR)/common/libs/compress/ -I $(XFLIB_DIR)/L2/tests/src/ -I $(XFLIB_DIR)/common/libs/xcl2 -I $(XFLIB_DIR)/common/libs/cmdparser -I $(XFLIB_DIR)/common/libs/logger CXXFLAGS += -O3 EXE_NAME := xil_gzip diff --git a/data_compression/L3/demos/gzip_app/description.json b/data_compression/L3/demos/gzip_app/description.json index 4ce324bdef..eb963cd70a 100644 --- a/data_compression/L3/demos/gzip_app/description.json +++ b/data_compression/L3/demos/gzip_app/description.json @@ -45,7 +45,8 @@ "LIB_DIR/L3/include", "LIB_DIR/L1/include/hw", "LIB_DIR/common/thirdParty/zlib-1.2.7", - "LIB_DIR/common/libs/compress/" + "LIB_DIR/common/libs/compress/", + "LIB_DIR/L2/tests/src/" ], "options": "-O3 ", "symbols": [ diff --git a/dsp/Jenkinsfile b/dsp/Jenkinsfile index 7a655329db..34e9432701 100644 --- a/dsp/Jenkinsfile +++ b/dsp/Jenkinsfile @@ -1,7 +1,7 @@ @Library('pipeline-library')_ -VitisLibPipeline (branch: 'next', libname: 'xf_dsp', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build:vitis_hw_run:vitis_aie_sim:vitis_aie_x86sim', - upstream_dependencies: 'xf_utils_hw,next,../utils; dsplib_internal_scripts,main,../dsplib_internal_scripts', - email: 'lingl@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_stable_latest', +VitisLibPipeline (branch: 'master', libname: 'xf_dsp', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build:vitis_hw_run:vitis_aie_sim:vitis_aie_x86sim', + upstream_dependencies: 'xf_utils_hw,master,../utils; dsplib_internal_scripts,main,../dsplib_internal_scripts', + email: 'lingl@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_released', post_launch: '../dsplib_internal_scripts/scripts/create_html_report.sh') diff --git a/dsp/L1/examples/1Dfix_impluse/src/main.cpp b/dsp/L1/examples/1Dfix_impluse/src/main.cpp index 30719b19ca..09d7ea16e5 100644 --- a/dsp/L1/examples/1Dfix_impluse/src/main.cpp +++ b/dsp/L1/examples/1Dfix_impluse/src/main.cpp @@ -19,17 +19,22 @@ #include int main(int argc, char** argv) { - T_in inData[SSR][FFT_LEN / SSR]; - T_out outData[SSR][FFT_LEN / SSR]; + hls::stream inData[SSR]; + hls::stream outData[SSR]; + T_in inDataArr[SSR][FFT_LEN / SSR]; + T_out outDataArr[SSR][FFT_LEN / SSR]; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (r == 0 && t == 0) - inData[r][t] = 1; - else - inData[r][t] = 0; + if (r == 0 && t == 0) { + inData[r].write(T_in(1)); + inDataArr[r][t] = 1; + } else { + inData[r].write(T_in(0)); + inDataArr[r][t] = 0; + } } } - for (int t = 0; t < 4; ++t) { + for (int t = 0; t < 1; ++t) { // Added Dummy loop iterations // to make II measurable in cosim fft_top(inData, outData); @@ -37,14 +42,16 @@ int main(int argc, char** argv) { int errs = 0; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (outData[r][t].real() != 1 || outData[r][t].imag() != 0) errs++; + T_out tmp = outData[r].read(); + outDataArr[r][t] = tmp; + if (tmp.real() != 1 || tmp.imag() != 0) errs++; } } std::cout << "===============================================================" << std::endl; std::cout << "--Input Impulse:" << std::endl; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - std::cout << inData[r][t] << std::endl; + std::cout << inDataArr[r][t] << std::endl; } } std::cout << "===============================================================" << std::endl; @@ -53,7 +60,7 @@ int main(int argc, char** argv) { std::cout << "--Output Step fuction:" << std::endl; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - std::cout << outData[r][t] << std::endl; + std::cout << outDataArr[r][t] << std::endl; } } std::cout << "===============================================================" << std::endl; diff --git a/dsp/L1/examples/1Dfix_impluse/src/top_module.cpp b/dsp/L1/examples/1Dfix_impluse/src/top_module.cpp index 42abae8eb0..92916265b6 100644 --- a/dsp/L1/examples/1Dfix_impluse/src/top_module.cpp +++ b/dsp/L1/examples/1Dfix_impluse/src/top_module.cpp @@ -18,6 +18,6 @@ #include "top_module.hpp" #include "data_path.hpp" -void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]) { +void fft_top(hls::stream p_inData[SSR], hls::stream p_outData[SSR]) { xf::dsp::fft::fft(p_inData, p_outData); } diff --git a/dsp/L1/examples/1Dfix_impluse/src/top_module.hpp b/dsp/L1/examples/1Dfix_impluse/src/top_module.hpp index 263932efcc..a4444d1fb6 100644 --- a/dsp/L1/examples/1Dfix_impluse/src/top_module.hpp +++ b/dsp/L1/examples/1Dfix_impluse/src/top_module.hpp @@ -19,4 +19,4 @@ #include "data_path.hpp" #include -void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]); +void fft_top(hls::stream p_inData[SSR], hls::stream p_outData[SSR]); diff --git a/dsp/L1/examples/1Dfloat_impluse/src/main.cpp b/dsp/L1/examples/1Dfloat_impluse/src/main.cpp index 30719b19ca..09d7ea16e5 100644 --- a/dsp/L1/examples/1Dfloat_impluse/src/main.cpp +++ b/dsp/L1/examples/1Dfloat_impluse/src/main.cpp @@ -19,17 +19,22 @@ #include int main(int argc, char** argv) { - T_in inData[SSR][FFT_LEN / SSR]; - T_out outData[SSR][FFT_LEN / SSR]; + hls::stream inData[SSR]; + hls::stream outData[SSR]; + T_in inDataArr[SSR][FFT_LEN / SSR]; + T_out outDataArr[SSR][FFT_LEN / SSR]; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (r == 0 && t == 0) - inData[r][t] = 1; - else - inData[r][t] = 0; + if (r == 0 && t == 0) { + inData[r].write(T_in(1)); + inDataArr[r][t] = 1; + } else { + inData[r].write(T_in(0)); + inDataArr[r][t] = 0; + } } } - for (int t = 0; t < 4; ++t) { + for (int t = 0; t < 1; ++t) { // Added Dummy loop iterations // to make II measurable in cosim fft_top(inData, outData); @@ -37,14 +42,16 @@ int main(int argc, char** argv) { int errs = 0; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (outData[r][t].real() != 1 || outData[r][t].imag() != 0) errs++; + T_out tmp = outData[r].read(); + outDataArr[r][t] = tmp; + if (tmp.real() != 1 || tmp.imag() != 0) errs++; } } std::cout << "===============================================================" << std::endl; std::cout << "--Input Impulse:" << std::endl; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - std::cout << inData[r][t] << std::endl; + std::cout << inDataArr[r][t] << std::endl; } } std::cout << "===============================================================" << std::endl; @@ -53,7 +60,7 @@ int main(int argc, char** argv) { std::cout << "--Output Step fuction:" << std::endl; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - std::cout << outData[r][t] << std::endl; + std::cout << outDataArr[r][t] << std::endl; } } std::cout << "===============================================================" << std::endl; diff --git a/dsp/L1/examples/1Dfloat_impluse/src/top_module.cpp b/dsp/L1/examples/1Dfloat_impluse/src/top_module.cpp index 420f62d45f..e7333c81e7 100644 --- a/dsp/L1/examples/1Dfloat_impluse/src/top_module.cpp +++ b/dsp/L1/examples/1Dfloat_impluse/src/top_module.cpp @@ -17,6 +17,6 @@ //================================== End Lic ================================================= #include "top_module.hpp" #include "data_path.hpp" -void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]) { +void fft_top(hls::stream p_inData[SSR], hls::stream p_outData[SSR]) { xf::dsp::fft::fft(p_inData, p_outData); } diff --git a/dsp/L1/examples/1Dfloat_impluse/src/top_module.hpp b/dsp/L1/examples/1Dfloat_impluse/src/top_module.hpp index 3aa6880f7e..098ed61d89 100644 --- a/dsp/L1/examples/1Dfloat_impluse/src/top_module.hpp +++ b/dsp/L1/examples/1Dfloat_impluse/src/top_module.hpp @@ -18,4 +18,4 @@ #include "data_path.hpp" #include -void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]); +void fft_top(hls::stream p_inData[SSR], hls::stream p_outData[SSR]); diff --git a/dsp/L1/include/hw/vitis_fft/fixed/vitis_fft/hls_ssr_fft.hpp b/dsp/L1/include/hw/vitis_fft/fixed/vitis_fft/hls_ssr_fft.hpp index 378fbce88e..1fd99e22a1 100644 --- a/dsp/L1/include/hw/vitis_fft/fixed/vitis_fft/hls_ssr_fft.hpp +++ b/dsp/L1/include/hw/vitis_fft/fixed/vitis_fft/hls_ssr_fft.hpp @@ -3281,9 +3281,14 @@ void stream2Array(hls::stream strmIn[t_R], T_out arrayOut[t_R][t_L / t_R] } } template -void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr_fft_param_struct::R], - typename FFTIOTypes::T_outType - p_fftOutData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr_fft_param_struct::R]) { +void fft(hls::stream fftInStrm[ssr_fft_param_struct::R], + hls::stream::T_castedType>::T_FFTOutType> + fftOutStrm[ssr_fft_param_struct::R]) { enum { FIFO_SIZE = ssr_fft_param_struct::N / ssr_fft_param_struct::R }; //#pragma HLS INLINE //#pragma HLS DATAFLOW disable_start_propagation @@ -3310,13 +3315,6 @@ void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr assert((t_R) == (ssrFFTPow<2, ssrFFTLog2::val>::val)); // radix should be power of 2 always assert((t_L) == (ssrFFTPow<2, ssrFFTLog2::val>::val)); // Length of FFt should be power of 2 always #endif - hls::stream fftInStrm[t_R]; -#pragma HLS stream variable = fftInStrm depth = FIFO_SIZE - hls::stream::T_FFTOutType> - fftOutStrm[t_R]; -#pragma HLS stream variable = fftOutStrm depth = FIFO_SIZE - array2Stream(p_fftInData, fftInStrm); FFTWrapper<(((ssrFFTLog2::val) % (ssrFFTLog2::val)) > 0), (t_L) < ((t_R * t_R)), default_t_instanceID> ssr_fft_wrapper_obj; // The 1st template arguments select : if the FFT is forked , if it is then a different architecture is required @@ -3326,14 +3324,17 @@ void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr tp_output_data_order, T_complexExpTableType, T_fftTwiddleType, T_in, typename FFTOutputTraits::T_FFTOutType>(fftInStrm, fftOutStrm); - stream2Array::T_FFTOutType>(fftOutStrm, p_fftOutData); } template -void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr_fft_param_struct::R], - typename FFTIOTypes::T_outType - p_fftOutData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr_fft_param_struct::R]) { +void fft(hls::stream fftInStrm[ssr_fft_param_struct::R], + hls::stream::T_castedType>::T_FFTOutType> + fftOutStrm[ssr_fft_param_struct::R]) { enum { FIFO_SIZE = ssr_fft_param_struct::N / ssr_fft_param_struct::R }; //#pragma HLS INLINE //#pragma HLS DATAFLOW disable_start_propagation @@ -3359,13 +3360,6 @@ void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr assert((t_R) == (ssrFFTPow<2, ssrFFTLog2::val>::val)); // radix should be power of 2 always assert((t_L) == (ssrFFTPow<2, ssrFFTLog2::val>::val)); // Length of FFt should be power of 2 always #endif - hls::stream fftInStrm[t_R]; -#pragma HLS stream variable = fftInStrm depth = FIFO_SIZE - hls::stream::T_FFTOutType> - fftOutStrm[t_R]; -#pragma HLS stream variable = fftOutStrm depth = FIFO_SIZE - array2Stream(p_fftInData, fftInStrm); FFTWrapper<(((ssrFFTLog2::val) % (ssrFFTLog2::val)) > 0), (t_L) < ((t_R * t_R)), t_instanceID> ssr_fft_wrapper_obj; // The 1st template arguments select : if the FFT is forked , if it is then a different architecture is required @@ -3375,8 +3369,6 @@ void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr tp_output_data_order, T_complexExpTableType, T_fftTwiddleType, T_in, typename FFTOutputTraits::T_FFTOutType>(fftInStrm, fftOutStrm); - stream2Array::T_FFTOutType>(fftOutStrm, p_fftOutData); } template diff --git a/dsp/L1/include/hw/vitis_fft/float/vitis_fft/hls_ssr_fft.hpp b/dsp/L1/include/hw/vitis_fft/float/vitis_fft/hls_ssr_fft.hpp index b88af48d70..2594c10a56 100644 --- a/dsp/L1/include/hw/vitis_fft/float/vitis_fft/hls_ssr_fft.hpp +++ b/dsp/L1/include/hw/vitis_fft/float/vitis_fft/hls_ssr_fft.hpp @@ -3281,9 +3281,14 @@ void stream2Array(hls::stream strmIn[t_R], T_out arrayOut[t_R][t_L / t_R] } } template -void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr_fft_param_struct::R], - typename FFTIOTypes::T_outType - p_fftOutData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr_fft_param_struct::R]) { +void fft(hls::stream fftInStrm[ssr_fft_param_struct::R], + hls::stream::T_castedType>::T_FFTOutType> + fftOutStrm[ssr_fft_param_struct::R]) { enum { FIFO_SIZE = ssr_fft_param_struct::N / ssr_fft_param_struct::R }; //#pragma HLS INLINE //#pragma HLS DATAFLOW disable_start_propagation @@ -3310,13 +3315,6 @@ void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr assert((t_R) == (ssrFFTPow<2, ssrFFTLog2::val>::val)); // radix should be power of 2 always assert((t_L) == (ssrFFTPow<2, ssrFFTLog2::val>::val)); // Length of FFt should be power of 2 always #endif - hls::stream fftInStrm[t_R]; -#pragma HLS stream variable = fftInStrm depth = FIFO_SIZE - hls::stream::T_FFTOutType> - fftOutStrm[t_R]; -#pragma HLS stream variable = fftOutStrm depth = FIFO_SIZE - array2Stream(p_fftInData, fftInStrm); FFTWrapper<(((ssrFFTLog2::val) % (ssrFFTLog2::val)) > 0), (t_L) < ((t_R * t_R)), default_t_instanceID> ssr_fft_wrapper_obj; // The 1st template arguments select : if the FFT is forked , if it is then a different architecture is required @@ -3326,14 +3324,17 @@ void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr tp_output_data_order, T_complexExpTableType, T_fftTwiddleType, T_in, typename FFTOutputTraits::T_FFTOutType>(fftInStrm, fftOutStrm); - stream2Array::T_FFTOutType>(fftOutStrm, p_fftOutData); } template -void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr_fft_param_struct::R], - typename FFTIOTypes::T_outType - p_fftOutData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr_fft_param_struct::R]) { +void fft(hls::stream fftInStrm[ssr_fft_param_struct::R], + hls::stream::T_castedType>::T_FFTOutType> + fftOutStrm[ssr_fft_param_struct::R]) { enum { FIFO_SIZE = ssr_fft_param_struct::N / ssr_fft_param_struct::R }; //#pragma HLS INLINE //#pragma HLS DATAFLOW disable_start_propagation @@ -3359,13 +3360,6 @@ void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr assert((t_R) == (ssrFFTPow<2, ssrFFTLog2::val>::val)); // radix should be power of 2 always assert((t_L) == (ssrFFTPow<2, ssrFFTLog2::val>::val)); // Length of FFt should be power of 2 always #endif - hls::stream fftInStrm[t_R]; -#pragma HLS stream variable = fftInStrm depth = FIFO_SIZE - hls::stream::T_FFTOutType> - fftOutStrm[t_R]; -#pragma HLS stream variable = fftOutStrm depth = FIFO_SIZE - array2Stream(p_fftInData, fftInStrm); FFTWrapper<(((ssrFFTLog2::val) % (ssrFFTLog2::val)) > 0), (t_L) < ((t_R * t_R)), t_instanceID> ssr_fft_wrapper_obj; // The 1st template arguments select : if the FFT is forked , if it is then a different architecture is required @@ -3375,8 +3369,6 @@ void fft(T_in p_fftInData[ssr_fft_param_struct::R][ssr_fft_param_struct::N / ssr tp_output_data_order, T_complexExpTableType, T_fftTwiddleType, T_in, typename FFTOutputTraits::T_FFTOutType>(fftInStrm, fftOutStrm); - stream2Array::T_FFTOutType>(fftOutStrm, p_fftOutData); } template diff --git a/dsp/L1/tests/common/utils/dsp_utilities.hpp b/dsp/L1/tests/common/utils/dsp_utilities.hpp index 524f2f5545..153220ec4d 100644 --- a/dsp/L1/tests/common/utils/dsp_utilities.hpp +++ b/dsp/L1/tests/common/utils/dsp_utilities.hpp @@ -54,6 +54,7 @@ double snr(float signal[DIM1][DIM2], float noisy_signal[DIM1][DIM2]) { return snr; } + template double snr(std::complex signal[DIM1][DIM2], std::complex noisy_signal[DIM1][DIM2]) { // SNR = 10 log10 ( mean(singal^2)/ mean(noise^2) ) @@ -90,6 +91,7 @@ double snr(std::complex signal[DIM1][DIM2], std::complex noisy_sig return snr; } + template void cast_to_double(std::complex inData[DIM1][DIM2], std::complex outData[DIM1][DIM2]) { for (int i = 0; i < DIM1; ++i) { @@ -114,4 +116,13 @@ void cast_to_double(std::complex inData[DIM1][DIM2], std::complex outD } } +template +void convert2Array(hls::stream
strm[R], DT arr[R][L / R]) { + for (int i = 0; i < (L / R); i++) { + for (int j = 0; j < R; j++) { + arr[j][i] = strm[j].read(); + } + } +} + #endif // DSP_UTILITIES_H_ diff --git a/dsp/L1/tests/common_float/utils/dsp_utilities.hpp b/dsp/L1/tests/common_float/utils/dsp_utilities.hpp index 42573152d3..6270751611 100644 --- a/dsp/L1/tests/common_float/utils/dsp_utilities.hpp +++ b/dsp/L1/tests/common_float/utils/dsp_utilities.hpp @@ -114,4 +114,13 @@ void cast_to_double(complex_wrapper inData[DIM1][DIM2], complex_wrapper +void convert2Array(hls::stream
strm[R], DT arr[R][L / R]) { + for (int i = 0; i < (L / R); i++) { + for (int j = 0; j < R; j++) { + arr[j][i] = strm[j].read(); + } + } +} + #endif // DSP_UTILITIES_H_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/Makefile deleted file mode 100644 index 961e9a7c7c..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/description.json deleted file mode 100644 index 292a49e7fa..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate16_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 300 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/run_hls.tcl deleted file mode 100755 index 02b9628fde..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r16_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/Makefile deleted file mode 100644 index 990c8a276d..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_l128.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/description.json deleted file mode 100644 index fac54db84f..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate16_Length128", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_l128", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L128.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L128.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/run_hls.tcl deleted file mode 100755 index 3869bb386d..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r16_l128.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L128.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L128.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/Makefile deleted file mode 100644 index d660303bc7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_256.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/description.json deleted file mode 100644 index 090b387c19..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate16_Length256", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_256", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L256.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L256.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/run_hls.tcl deleted file mode 100755 index 53463223c2..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r16_256.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L256.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L256.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/Makefile deleted file mode 100644 index 1b1e328768..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_l32.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/description.json deleted file mode 100644 index d066497c0c..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate16_Length32", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_l32", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L32.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L32.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/fft_size.hpp deleted file mode 100644 index a9065a80d2..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (32) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l4096/src/main.cpp index fe179b40d7..c49bce8988 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l4096/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l4096/src/main.cpp @@ -25,13 +25,12 @@ #include "utils/dsp_utilities.hpp" #include "utils/sorting.hpp" -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { #pragma HLS TOP xf::dsp::fft::fft(inD, outD); } -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top_c(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { xf::dsp::fft::fft(inD, outD); } @@ -42,8 +41,9 @@ int main(int argc, char** argv) { * complex ssr fft call * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream > din[SSR_FFT_R]; + hls::stream > dout_temp[SSR_FFT_R]; + std::complex dout_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -52,8 +52,9 @@ int main(int argc, char** argv) { * complex ssr fft call that will synthesize to RTL for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix[SSR_FFT_R]; + hls::stream dout_fix_temp[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -62,8 +63,9 @@ int main(int argc, char** argv) { * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix_c[SSR_FFT_R]; + hls::stream dout_fix_c_temp[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_c_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -110,9 +112,9 @@ int main(int argc, char** argv) { // verification for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; + din[j].write(din_file[i * (SSR_FFT_R) + j]); + din_fix[j].write(din_file[i * (SSR_FFT_R) + j]); + din_fix_c[j].write(din_file[i * (SSR_FFT_R) + j]); golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; } } @@ -134,14 +136,16 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); + convert2Array(dout_temp, dout_temp_arr); + fftOutputReorderSimulationModelOnly(dout_temp_arr, dout); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL * for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); + convert2Array(dout_fix_temp, dout_fix_temp_arr); + fftOutputReorderSimulationModelOnly(dout_fix_temp_arr, dout_fix); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ @@ -151,7 +155,8 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); + convert2Array(dout_fix_c_temp, dout_fix_c_temp_arr); + fftOutputReorderSimulationModelOnly(dout_fix_c_temp_arr, dout_fix_c); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/Makefile deleted file mode 100644 index aff1891974..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_l64.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/description.json deleted file mode 100644 index 61454eb59e..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate16_Length64", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_l64", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L64.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L64.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/run_hls.tcl deleted file mode 100755 index dc624ef269..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r16_l64.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L64.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L64.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/fft_size.hpp deleted file mode 100644 index 18584b5732..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (64) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/Makefile deleted file mode 100644 index b18e30999b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r2_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/description.json deleted file mode 100644 index b273d730a7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate2_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r2_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/run_hls.tcl deleted file mode 100755 index 66443a2b1c..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r2_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/fft_size.hpp deleted file mode 100644 index 9c74670d71..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 2 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/DEBUG_CONSTANTS.hpp index 29656bf495..a748fac7b4 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/DEBUG_CONSTANTS.hpp +++ b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/DEBUG_CONSTANTS.hpp @@ -22,7 +22,7 @@ * NO_DATA_FRAMES_TO_SIMULATE : is number of times * FFT is simulated. *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 +#define NO_DATA_FRAMES_TO_SIMULATE 1 /********************************************************************* * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/main.cpp index fe179b40d7..c49bce8988 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/main.cpp @@ -25,13 +25,12 @@ #include "utils/dsp_utilities.hpp" #include "utils/sorting.hpp" -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { #pragma HLS TOP xf::dsp::fft::fft(inD, outD); } -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top_c(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { xf::dsp::fft::fft(inD, outD); } @@ -42,8 +41,9 @@ int main(int argc, char** argv) { * complex ssr fft call * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream > din[SSR_FFT_R]; + hls::stream > dout_temp[SSR_FFT_R]; + std::complex dout_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -52,8 +52,9 @@ int main(int argc, char** argv) { * complex ssr fft call that will synthesize to RTL for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix[SSR_FFT_R]; + hls::stream dout_fix_temp[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -62,8 +63,9 @@ int main(int argc, char** argv) { * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix_c[SSR_FFT_R]; + hls::stream dout_fix_c_temp[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_c_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -110,9 +112,9 @@ int main(int argc, char** argv) { // verification for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; + din[j].write(din_file[i * (SSR_FFT_R) + j]); + din_fix[j].write(din_file[i * (SSR_FFT_R) + j]); + din_fix_c[j].write(din_file[i * (SSR_FFT_R) + j]); golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; } } @@ -134,14 +136,16 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); + convert2Array(dout_temp, dout_temp_arr); + fftOutputReorderSimulationModelOnly(dout_temp_arr, dout); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL * for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); + convert2Array(dout_fix_temp, dout_fix_temp_arr); + fftOutputReorderSimulationModelOnly(dout_fix_temp_arr, dout_fix); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ @@ -151,7 +155,8 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); + convert2Array(dout_fix_c_temp, dout_fix_c_temp_arr); + fftOutputReorderSimulationModelOnly(dout_fix_c_temp_arr, dout_fix_c); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/Makefile deleted file mode 100644 index 60dd72dc9a..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r4_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/description.json deleted file mode 100644 index 98d47ced7e..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate4_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r4_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/run_hls.tcl deleted file mode 100755 index 2bc3c589bc..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r4_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/fft_size.hpp deleted file mode 100644 index 5d74c52b3f..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/Makefile deleted file mode 100644 index 4f8589e011..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r4_l16.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/description.json deleted file mode 100644 index d6708476f5..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate4_Length16", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r4_l16", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L16.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L16.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/run_hls.tcl deleted file mode 100755 index a957b65db4..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r4_l16.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L16.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L16.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/fft_size.hpp deleted file mode 100644 index c6d070c190..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (16) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/Makefile deleted file mode 100644 index f2cc15c046..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r4_l32.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/description.json deleted file mode 100644 index 546e0737a1..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate4_Length32", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r4_l32", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L32.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L32.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/run_hls.tcl deleted file mode 100755 index 8f6dbeb479..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r4_l32.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L32.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L32.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/fft_size.hpp deleted file mode 100644 index 505a77597e..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (32) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/Makefile deleted file mode 100644 index 6c3a43d6de..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r4_l4096.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/description.json deleted file mode 100644 index 1912f95b81..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate4_Length4096", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r4_l4096", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L4096.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L4096.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/run_hls.tcl deleted file mode 100755 index 864ceda404..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r4_l4096.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L4096.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L4096.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/fft_size.hpp deleted file mode 100644 index f502f3986b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (4096) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/Makefile deleted file mode 100644 index 6835cf8771..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/description.json deleted file mode 100644 index 1da30d6fa6..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate8_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/run_hls.tcl deleted file mode 100755 index 5dcd0ab2eb..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/fft_size.hpp deleted file mode 100644 index 70751d3cf9..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/Makefile deleted file mode 100644 index 62e40f09b3..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l128.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/description.json deleted file mode 100644 index 0052f3d523..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate8_Length128", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l128", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L128.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L128.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/run_hls.tcl deleted file mode 100755 index 1ea51d799c..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l128.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L128.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L128.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/fft_size.hpp deleted file mode 100644 index 47af0fa204..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (128) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/Makefile deleted file mode 100644 index 6f16d9fcc5..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l4096.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/description.json deleted file mode 100644 index 6c9b1d4fb6..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate8_Length4096", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l4096", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L4096.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L4096.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/run_hls.tcl deleted file mode 100755 index 992469584e..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l4096.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L4096.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L4096.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/fft_size.hpp deleted file mode 100644 index 2e08218717..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (4096) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/Makefile deleted file mode 100644 index 4d86356543..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l512.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/description.json deleted file mode 100644 index f1c7e951b0..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate8_Length512", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l512", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L512.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L512.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/run_hls.tcl deleted file mode 100755 index f3d1c325d6..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l512.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L512.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L512.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/fft_size.hpp deleted file mode 100644 index 158524fe2e..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (512) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/Makefile deleted file mode 100644 index 7efe589575..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l64.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/description.json deleted file mode 100644 index 8945ba3856..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Fixed Rate8_Length64", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l64", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_dro_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L64.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L64.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/run_hls.tcl deleted file mode 100755 index f53e1600c7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l64.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_dro_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L64.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L64.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/fft_size.hpp deleted file mode 100644 index 72c3c3df91..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (64) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index c5b200f5dd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/main.cpp deleted file mode 100644 index fe179b40d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/Makefile deleted file mode 100644 index 79e4a1a851..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/description.json deleted file mode 100644 index 135d7da503..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate16_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 300 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/fft_size.hpp deleted file mode 100644 index 24a888bed4..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/Makefile deleted file mode 100644 index 4b093d3ca0..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_l128.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/description.json deleted file mode 100644 index f3dc8f0556..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate16_Length128", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_l128", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L128.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L128.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/run_hls.tcl deleted file mode 100755 index 738494c52a..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r16_l128.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L128.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L128.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/fft_size.hpp deleted file mode 100644 index 965578a579..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (128) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/Makefile deleted file mode 100644 index 216a4b9d46..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_256.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/description.json deleted file mode 100644 index 89572009c8..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate16_Length256", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_256", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L256.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L256.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/run_hls.tcl deleted file mode 100755 index b721efba88..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r16_256.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L256.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L256.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/fft_size.hpp deleted file mode 100644 index a5d67680c3..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (256) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/Makefile deleted file mode 100644 index cb3fad40f2..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_l32.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/description.json deleted file mode 100644 index f63e15d100..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate16_Length32", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_l32", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L32.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L32.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/run_hls.tcl deleted file mode 100755 index dc43488da0..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r16_l32.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L32.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L32.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/fft_size.hpp deleted file mode 100644 index a9065a80d2..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (32) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l4096/src/main.cpp index 50e3fe30ca..d75673674c 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l4096/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l4096/src/main.cpp @@ -25,13 +25,12 @@ #include "utils/dsp_utilities.hpp" #include "utils/sorting.hpp" -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { #pragma HLS TOP xf::dsp::fft::fft(inD, outD); } -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top_c(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { xf::dsp::fft::fft(inD, outD); } @@ -42,8 +41,9 @@ int main(int argc, char** argv) { * complex ssr fft call * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream > din[SSR_FFT_R]; + hls::stream > dout[SSR_FFT_R]; + std::complex dout_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -51,8 +51,9 @@ int main(int argc, char** argv) { * complex ssr fft call that will synthesize to RTL for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix[SSR_FFT_R]; + hls::stream dout_fix[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -60,8 +61,9 @@ int main(int argc, char** argv) { * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix_c[SSR_FFT_R]; + hls::stream dout_fix_c[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_c_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus @@ -107,9 +109,9 @@ int main(int argc, char** argv) { // verification for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; + din[j].write(din_file[i * (SSR_FFT_R) + j]); + din_fix[j].write(din_file[i * (SSR_FFT_R) + j]); + din_fix_c[j].write(din_file[i * (SSR_FFT_R) + j]); golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; } } @@ -131,12 +133,14 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft(din, dout); + convert2Array(dout, dout_arr); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL * for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top(din_fix, dout_fix); + convert2Array(dout_fix, dout_fix_arr); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ @@ -146,13 +150,14 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top_c(din_fix_c, dout_fix_c); + convert2Array(dout_fix_c, dout_fix_c_arr); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Verify if the ssr fft double precision model is functionally correct by comparing its output with // double precision Octave model output, it functionally verifies SSR FFT model independent of the // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); + double snrDBs_ssr_vs_octave = snr(golden_output, dout_arr); print_phase_header(); std::cout << get_section_header() << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; @@ -174,7 +179,7 @@ int main(int argc, char** argv) { p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification + p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_arr[a2][a1]; /// convert it to one day array for verification } } @@ -215,7 +220,7 @@ int main(int argc, char** argv) { // double precision Octave model output, It verifies if the data-path choice is good enough // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); + cast_to_double(dout_fix_arr, fix_fft_out); double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); print_phase_header(); @@ -235,7 +240,7 @@ int main(int argc, char** argv) { std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast + p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix_arr[a2][a1]; // convert to 1d array and also cast } } @@ -268,7 +273,7 @@ int main(int argc, char** argv) { print_phase_header(); std::cout << get_section_header() << "Verification Messages\n"; std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); + double snrDBs_fix_point_vs_floating_model = snr(dout_arr, fix_fft_out); std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; print_phase_footer(); @@ -286,11 +291,11 @@ int main(int argc, char** argv) { int rtl_verif_flag = 0; for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { + if ((dout_fix_arr[rad][lt].real() != dout_fix_c_arr[rad][lt].real()) || + (dout_fix_arr[rad][lt].imag() != dout_fix_c_arr[rad][lt].imag())) { rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; + std::cout << "Expected Output : " << dout_fix_c_arr[rad][lt] << "\n"; + std::cout << "RTL Output : " << dout_fix_arr[rad][lt] << "\n"; std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; } } diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/Makefile deleted file mode 100644 index 06934610ae..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_l64.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/description.json deleted file mode 100644 index 1658c3df99..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate16_Length64", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_l64", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L64.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L64.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/run_hls.tcl deleted file mode 100755 index 1876e5d772..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r16_l64.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L64.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L64.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/fft_size.hpp deleted file mode 100644 index 18584b5732..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (64) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/Makefile deleted file mode 100644 index 11284770be..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r2_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/description.json deleted file mode 100644 index f3db4144d7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate2_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r2_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/run_hls.tcl deleted file mode 100755 index 493813293c..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r2_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/fft_size.hpp deleted file mode 100644 index 9c74670d71..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 2 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/DEBUG_CONSTANTS.hpp index 29656bf495..a748fac7b4 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/DEBUG_CONSTANTS.hpp +++ b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/DEBUG_CONSTANTS.hpp @@ -22,7 +22,7 @@ * NO_DATA_FRAMES_TO_SIMULATE : is number of times * FFT is simulated. *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 +#define NO_DATA_FRAMES_TO_SIMULATE 1 /********************************************************************* * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/main.cpp index 50e3fe30ca..d75673674c 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/main.cpp @@ -25,13 +25,12 @@ #include "utils/dsp_utilities.hpp" #include "utils/sorting.hpp" -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { #pragma HLS TOP xf::dsp::fft::fft(inD, outD); } -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top_c(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { xf::dsp::fft::fft(inD, outD); } @@ -42,8 +41,9 @@ int main(int argc, char** argv) { * complex ssr fft call * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream > din[SSR_FFT_R]; + hls::stream > dout[SSR_FFT_R]; + std::complex dout_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -51,8 +51,9 @@ int main(int argc, char** argv) { * complex ssr fft call that will synthesize to RTL for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix[SSR_FFT_R]; + hls::stream dout_fix[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -60,8 +61,9 @@ int main(int argc, char** argv) { * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix_c[SSR_FFT_R]; + hls::stream dout_fix_c[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_c_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus @@ -107,9 +109,9 @@ int main(int argc, char** argv) { // verification for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; + din[j].write(din_file[i * (SSR_FFT_R) + j]); + din_fix[j].write(din_file[i * (SSR_FFT_R) + j]); + din_fix_c[j].write(din_file[i * (SSR_FFT_R) + j]); golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; } } @@ -131,12 +133,14 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft(din, dout); + convert2Array(dout, dout_arr); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL * for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top(din_fix, dout_fix); + convert2Array(dout_fix, dout_fix_arr); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ @@ -146,13 +150,14 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top_c(din_fix_c, dout_fix_c); + convert2Array(dout_fix_c, dout_fix_c_arr); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Verify if the ssr fft double precision model is functionally correct by comparing its output with // double precision Octave model output, it functionally verifies SSR FFT model independent of the // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); + double snrDBs_ssr_vs_octave = snr(golden_output, dout_arr); print_phase_header(); std::cout << get_section_header() << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; @@ -174,7 +179,7 @@ int main(int argc, char** argv) { p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification + p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_arr[a2][a1]; /// convert it to one day array for verification } } @@ -215,7 +220,7 @@ int main(int argc, char** argv) { // double precision Octave model output, It verifies if the data-path choice is good enough // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); + cast_to_double(dout_fix_arr, fix_fft_out); double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); print_phase_header(); @@ -235,7 +240,7 @@ int main(int argc, char** argv) { std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast + p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix_arr[a2][a1]; // convert to 1d array and also cast } } @@ -268,7 +273,7 @@ int main(int argc, char** argv) { print_phase_header(); std::cout << get_section_header() << "Verification Messages\n"; std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); + double snrDBs_fix_point_vs_floating_model = snr(dout_arr, fix_fft_out); std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; print_phase_footer(); @@ -286,11 +291,11 @@ int main(int argc, char** argv) { int rtl_verif_flag = 0; for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { + if ((dout_fix_arr[rad][lt].real() != dout_fix_c_arr[rad][lt].real()) || + (dout_fix_arr[rad][lt].imag() != dout_fix_c_arr[rad][lt].imag())) { rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; + std::cout << "Expected Output : " << dout_fix_c_arr[rad][lt] << "\n"; + std::cout << "RTL Output : " << dout_fix_arr[rad][lt] << "\n"; std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; } } diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/Makefile deleted file mode 100644 index 4a966a0655..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r4_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/description.json deleted file mode 100644 index f3cf6818c7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate4_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r4_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/run_hls.tcl deleted file mode 100755 index dc7d3c43c7..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r4_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/fft_size.hpp deleted file mode 100644 index 5d74c52b3f..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/description.json deleted file mode 100644 index 4ebdd452b5..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate4_Length16", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r4_l16", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L16.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L16.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/run_hls.tcl deleted file mode 100755 index c55087ce86..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r4_l16.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L16.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L16.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/fft_size.hpp deleted file mode 100644 index c6d070c190..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (16) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/description.json deleted file mode 100644 index 377adc0f79..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate4_Length32", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r4_l32", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L32.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L32.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/run_hls.tcl deleted file mode 100755 index f6dabea32c..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r4_l32.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L32.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L32.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/fft_size.hpp deleted file mode 100644 index 505a77597e..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (32) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/Makefile deleted file mode 100644 index 74842b7894..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r4_l4096.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/description.json deleted file mode 100644 index b5d3c2b0fc..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/description.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate4_Length4096", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r4_l4096", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L4096.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L4096.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/run_hls.tcl deleted file mode 100755 index dded4700d5..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r4_l4096.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L4096.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L4096.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/fft_size.hpp deleted file mode 100644 index f502f3986b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (4096) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/Makefile deleted file mode 100644 index 615bb79413..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/description.json deleted file mode 100644 index 3bb25dc42a..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/description.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate8_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/run_hls.tcl deleted file mode 100755 index 4d47550ae4..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/fft_size.hpp deleted file mode 100644 index 70751d3cf9..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/Makefile deleted file mode 100644 index 52df32cc3f..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l128.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/description.json deleted file mode 100644 index c7ce569abd..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/description.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate8_Length128", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l128", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L128.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L128.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/run_hls.tcl deleted file mode 100755 index ae7f7d5a4e..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l128.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L128.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L128.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/fft_size.hpp deleted file mode 100644 index 47af0fa204..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (128) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/Makefile deleted file mode 100644 index e43bae5aaf..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l4096.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/description.json deleted file mode 100644 index a343556d74..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/description.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate8_Length4096", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l4096", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L4096.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L4096.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/run_hls.tcl deleted file mode 100755 index 81e2e09684..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l4096.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L4096.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L4096.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/fft_size.hpp deleted file mode 100644 index 2e08218717..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (4096) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/Makefile b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/Makefile deleted file mode 100644 index 3da91447d2..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l512.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/description.json deleted file mode 100644 index 3fb156a426..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate8_Length512", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l512", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L512.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L512.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/run_hls.tcl deleted file mode 100755 index 30c5700a66..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l512.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L512.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L512.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/fft_size.hpp deleted file mode 100644 index 158524fe2e..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (512) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/description.json b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/description.json deleted file mode 100644 index 090d19cce5..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Fixed Rate8_Length64", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l64", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L64.verif", - "${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L64.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/run_hls.tcl b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/run_hls.tcl deleted file mode 100755 index 93057e512a..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l64.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L64.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L64.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/fft_size.hpp deleted file mode 100644 index 72c3c3df91..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (64) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 2c9aca3b8b..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef ap_fixed T_INNER_SSR_FFT_IN; -typedef ap_fixed T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef std::complex > T_SSR_FFT_IN; -typedef std::complex > T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/main.cpp deleted file mode 100644 index 50e3fe30ca..0000000000 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/main.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - std::complex din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - std::complex dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - std::complex din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - std::complex golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - std::complex golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - std::complex - p_fftOutDataTemp[SSR_FFT_L]; // 1-D array used for conversion of fft_top output from 2-D 1-D - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - std::complex fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT fixed point model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT fixed point vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT fixed point output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing SSR FFT fixed point model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT fixed vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed point model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ FIXED POINT model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model FAILED." - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() << "Bit-True verification of RTL vs. synthesized C++ fixed model PASEED." - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Fixed Point Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/main.cpp b/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/main.cpp index 0692e9c971..8382d361e6 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/main.cpp @@ -22,14 +22,14 @@ #define NUM_TEST 1 int main(int argc, char** argv) { - T_in inData[SSR][FFT_LEN / SSR]; - T_out outData[SSR][FFT_LEN / SSR]; + hls::stream inData[SSR]; + hls::stream outData[SSR]; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { if (r == 0 && t == 0) - inData[r][t] = 1; + inData[r].write(T_in(1)); else - inData[r][t] = 0; + inData[r].write(T_in(0)); } } for (int t = 0; t < NUM_TEST; ++t) { @@ -40,7 +40,8 @@ int main(int argc, char** argv) { int errs = 0; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (outData[r][t].real() != 1 || outData[r][t].imag() != 0) errs++; + T_out tmp = outData[r].read(); + if (tmp.real() != 1 || tmp.imag() != 0) errs++; } } return errs; diff --git a/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/top_module.cpp b/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/top_module.cpp index 42abae8eb0..92916265b6 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/top_module.cpp +++ b/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/top_module.cpp @@ -18,6 +18,6 @@ #include "top_module.hpp" #include "data_path.hpp" -void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]) { +void fft_top(hls::stream p_inData[SSR], hls::stream p_outData[SSR]) { xf::dsp::fft::fft(p_inData, p_outData); } diff --git a/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/top_module.hpp b/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/top_module.hpp index 263932efcc..a4444d1fb6 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/top_module.hpp +++ b/dsp/L1/tests/hw/1dfft/fixed/impulse_test/src/top_module.hpp @@ -19,4 +19,4 @@ #include "data_path.hpp" #include -void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]); +void fft_top(hls::stream p_inData[SSR], hls::stream p_outData[SSR]); diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/Makefile deleted file mode 100644 index 961e9a7c7c..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/description.json deleted file mode 100644 index db5b73e092..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/description.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate16_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/run_hls.tcl deleted file mode 100755 index 1f0855aa8a..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r16_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/fft_size.hpp deleted file mode 100644 index 24a888bed4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l1024/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/Makefile deleted file mode 100644 index 990c8a276d..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_l128.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/description.json deleted file mode 100644 index e0a969bae6..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/description.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate16_Length128", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_l128", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L128.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L128.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/run_hls.tcl deleted file mode 100755 index c77c3b86c4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r16_l128.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L128.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L128.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/fft_size.hpp deleted file mode 100644 index 965578a579..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (128) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l128/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/Makefile deleted file mode 100644 index f1db4be5f7..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_l256.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/description.json deleted file mode 100644 index 3ba9ecc242..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate16_Length256", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_l256", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L256.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L256.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 40960, - "hls_csim": 10240, - "hls_cosim": 40960, - "hls_vivado_impl": 40960, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/run_hls.tcl deleted file mode 100755 index 1bc8f4690a..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r16_l256.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L256.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L256.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/fft_size.hpp deleted file mode 100644 index a5d67680c3..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (256) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/Makefile deleted file mode 100644 index 1b1e328768..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_l32.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/description.json deleted file mode 100644 index 9d386f5fea..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate16_Length32", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_l32", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L32.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L32.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 40960, - "hls_csim": 10240, - "hls_cosim": 40960, - "hls_vivado_impl": 40960, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/run_hls.tcl deleted file mode 100755 index 684d24e419..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r16_l32.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L32.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L32.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/fft_size.hpp deleted file mode 100644 index a9065a80d2..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (32) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l32/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l4096/src/main.cpp index b096cd5309..7e13cf36d3 100644 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l4096/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l4096/src/main.cpp @@ -25,13 +25,12 @@ #include "utils/dsp_utilities.hpp" #include "utils/sorting.hpp" -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { #pragma HLS TOP xf::dsp::fft::fft(inD, outD); } -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top_c(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { xf::dsp::fft::fft(inD, outD); } @@ -42,8 +41,9 @@ int main(int argc, char** argv) { * complex ssr fft call * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din[SSR_FFT_R]; + hls::stream dout_temp[SSR_FFT_R]; + T_ComplexDouble dout_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -52,8 +52,9 @@ int main(int argc, char** argv) { * complex ssr fft call that will synthesize to RTL for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix[SSR_FFT_R]; + hls::stream dout_fix_temp[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -62,8 +63,9 @@ int main(int argc, char** argv) { * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix_c[SSR_FFT_R]; + hls::stream dout_fix_c_temp[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_c_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -110,9 +112,12 @@ int main(int argc, char** argv) { // verification for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; + din[j].write(T_ComplexDouble(din_file[i * (SSR_FFT_R) + j])); + T_SSR_FFT_IN tmp_in; + tmp_in.real() = din_file[i * (SSR_FFT_R) + j].real(); + tmp_in.imag() = din_file[i * (SSR_FFT_R) + j].imag(); + din_fix[j].write(tmp_in); + din_fix_c[j].write(tmp_in); golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; } } @@ -134,14 +139,16 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); + convert2Array(dout_temp, dout_temp_arr); + fftOutputReorderSimulationModelOnly(dout_temp_arr, dout); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL * for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); + convert2Array(dout_fix_temp, dout_fix_temp_arr); + fftOutputReorderSimulationModelOnly(dout_fix_temp_arr, dout_fix); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ @@ -151,7 +158,8 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); + convert2Array(dout_fix_c_temp, dout_fix_c_temp_arr); + fftOutputReorderSimulationModelOnly(dout_fix_c_temp_arr, dout_fix_c); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/Makefile deleted file mode 100644 index aff1891974..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r16_l64.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/description.json deleted file mode 100644 index 83d855b567..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate16_Length64", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r16_l64", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L64.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L64.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 20480, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/run_hls.tcl deleted file mode 100755 index 552c1750ce..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r16_l64.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L64.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L64.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/fft_size.hpp deleted file mode 100644 index 18584b5732..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (64) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l64/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/Makefile deleted file mode 100644 index b18e30999b..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r2_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/description.json deleted file mode 100644 index fe9cc9826e..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate2_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r2_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/run_hls.tcl deleted file mode 100755 index cd2239a677..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r2_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/fft_size.hpp deleted file mode 100644 index 0a04366a8a..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L 1024 -#define SSR_FFT_R 2 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l1024/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/DEBUG_CONSTANTS.hpp index 29656bf495..a748fac7b4 100644 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/DEBUG_CONSTANTS.hpp +++ b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/DEBUG_CONSTANTS.hpp @@ -22,7 +22,7 @@ * NO_DATA_FRAMES_TO_SIMULATE : is number of times * FFT is simulated. *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 +#define NO_DATA_FRAMES_TO_SIMULATE 1 /********************************************************************* * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/main.cpp index b096cd5309..7e13cf36d3 100644 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r2_l16/src/main.cpp @@ -25,13 +25,12 @@ #include "utils/dsp_utilities.hpp" #include "utils/sorting.hpp" -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { #pragma HLS TOP xf::dsp::fft::fft(inD, outD); } -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top_c(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { xf::dsp::fft::fft(inD, outD); } @@ -42,8 +41,9 @@ int main(int argc, char** argv) { * complex ssr fft call * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din[SSR_FFT_R]; + hls::stream dout_temp[SSR_FFT_R]; + T_ComplexDouble dout_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -52,8 +52,9 @@ int main(int argc, char** argv) { * complex ssr fft call that will synthesize to RTL for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix[SSR_FFT_R]; + hls::stream dout_fix_temp[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -62,8 +63,9 @@ int main(int argc, char** argv) { * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix_c[SSR_FFT_R]; + hls::stream dout_fix_c_temp[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_c_temp_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -110,9 +112,12 @@ int main(int argc, char** argv) { // verification for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; + din[j].write(T_ComplexDouble(din_file[i * (SSR_FFT_R) + j])); + T_SSR_FFT_IN tmp_in; + tmp_in.real() = din_file[i * (SSR_FFT_R) + j].real(); + tmp_in.imag() = din_file[i * (SSR_FFT_R) + j].imag(); + din_fix[j].write(tmp_in); + din_fix_c[j].write(tmp_in); golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; } } @@ -134,14 +139,16 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); + convert2Array(dout_temp, dout_temp_arr); + fftOutputReorderSimulationModelOnly(dout_temp_arr, dout); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL * for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); + convert2Array(dout_fix_temp, dout_fix_temp_arr); + fftOutputReorderSimulationModelOnly(dout_fix_temp_arr, dout_fix); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ @@ -151,7 +158,8 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); + convert2Array(dout_fix_c_temp, dout_fix_c_temp_arr); + fftOutputReorderSimulationModelOnly(dout_fix_c_temp_arr, dout_fix_c); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/Makefile deleted file mode 100644 index 60dd72dc9a..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r4_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/description.json deleted file mode 100644 index ba5fa09630..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate4_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r4_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/run_hls.tcl deleted file mode 100755 index 7cc81f9ea7..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r4_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/fft_size.hpp deleted file mode 100644 index 5d74c52b3f..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l1024/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/Makefile deleted file mode 100644 index 4f8589e011..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r4_l16.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/description.json deleted file mode 100644 index ed3cbfd733..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate4_Length16", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r4_l16", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L16.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L16.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/run_hls.tcl deleted file mode 100755 index 9bd35a68e7..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r4_l16.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L16.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L16.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/fft_size.hpp deleted file mode 100644 index c6d070c190..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (16) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l16/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/Makefile deleted file mode 100644 index f2cc15c046..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r4_l32.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/description.json deleted file mode 100644 index e6d084cb9a..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate4_Length32", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r4_l32", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L32.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L32.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/run_hls.tcl deleted file mode 100755 index 921e10d9b2..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r4_l32.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L32.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L32.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/fft_size.hpp deleted file mode 100644 index 505a77597e..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (32) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l32/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/Makefile deleted file mode 100644 index 6c3a43d6de..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r4_l4096.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/description.json deleted file mode 100644 index 47f752a754..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate4_Length4096", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r4_l4096", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L4096.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L4096.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/run_hls.tcl deleted file mode 100755 index f2185ce57e..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r4_l4096.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L4096.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L4096.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/fft_size.hpp deleted file mode 100644 index f502f3986b..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (4096) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r4_l4096/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/Makefile deleted file mode 100644 index 6835cf8771..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/description.json deleted file mode 100644 index 548cd30909..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate8_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 40960, - "hls_csim": 10240, - "hls_cosim": 40960, - "hls_vivado_impl": 40960, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/run_hls.tcl deleted file mode 100755 index 13b362c4c5..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/fft_size.hpp deleted file mode 100644 index 70751d3cf9..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l1024/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/Makefile deleted file mode 100644 index 62e40f09b3..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l128.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/description.json deleted file mode 100644 index 326f539b9c..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate8_Length128", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l128", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L128.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L128.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/run_hls.tcl deleted file mode 100755 index 8029fb98fd..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l128.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L128.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L128.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/fft_size.hpp deleted file mode 100644 index 47af0fa204..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (128) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l128/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/Makefile deleted file mode 100644 index 6f16d9fcc5..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l4096.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/description.json deleted file mode 100644 index f522f6418b..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate8_Length4096", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l4096", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L4096.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L4096.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 20480, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/run_hls.tcl deleted file mode 100755 index 7c230de045..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l4096.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L4096.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L4096.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/fft_size.hpp deleted file mode 100644 index 2e08218717..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (4096) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l4096/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/Makefile deleted file mode 100644 index 4d86356543..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l512.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/description.json deleted file mode 100644 index d9c8f0d4bf..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate8_Length512", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l512", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L512.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L512.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/run_hls.tcl deleted file mode 100755 index fd8820d293..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l512.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L512.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L512.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/fft_size.hpp deleted file mode 100644 index 158524fe2e..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (512) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l512/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/Makefile deleted file mode 100644 index 7efe589575..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_dro_reg_test_r8_l64.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/description.json deleted file mode 100644 index 73643a7c53..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Digital Reversed Order Float Rate8_Length64", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_dro_reg_test_r8_l64", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L64.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L64.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/run_hls.tcl deleted file mode 100755 index 2bf8aaecad..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_dro_reg_test_r8_l64.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L64.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L64.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/fft_size.hpp deleted file mode 100644 index 72c3c3df91..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (64) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 726fab6787..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_DIGIT_REVERSED_TRANSPOSED; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/main.cpp deleted file mode 100644 index b096cd5309..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r8_l64/src/main.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c_temp[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout_temp); - fftOutputReorderSimulationModelOnly(dout_temp, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix_temp); - fftOutputReorderSimulationModelOnly(dout_fix_temp, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c_temp); - fftOutputReorderSimulationModelOnly(dout_fix_c_temp, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/Makefile deleted file mode 100644 index 79e4a1a851..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/description.json deleted file mode 100644 index fb2a173414..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/description.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate16_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 300 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/run_hls.tcl deleted file mode 100755 index 55f823e37c..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r16_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/fft_size.hpp deleted file mode 100644 index 24a888bed4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/Makefile deleted file mode 100644 index 4b093d3ca0..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_l128.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/description.json deleted file mode 100644 index 68946d03b9..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/description.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate16_Length128", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_l128", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L128.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L128.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/run_hls.tcl deleted file mode 100755 index f4e06e87ff..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r16_l128.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L128.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L128.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/fft_size.hpp deleted file mode 100644 index 965578a579..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (128) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l128/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/Makefile deleted file mode 100644 index e0018fcdab..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_l256.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/description.json deleted file mode 100644 index bff75d1e21..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/description.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate16_Length256", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_l256", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L256.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L256.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/run_hls.tcl deleted file mode 100755 index 9ce850a5d1..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r16_l256.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L256.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L256.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/fft_size.hpp deleted file mode 100644 index a5d67680c3..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (256) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l256/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/Makefile deleted file mode 100644 index cb3fad40f2..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_l32.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/description.json deleted file mode 100644 index bab3601177..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate16_Length32", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_l32", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L32.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L32.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 40960, - "hls_csim": 10240, - "hls_cosim": 40960, - "hls_vivado_impl": 40960, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/run_hls.tcl deleted file mode 100755 index 0a0c9d6b0e..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r16_l32.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L32.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L32.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/fft_size.hpp deleted file mode 100644 index a9065a80d2..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (32) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l32/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l4096/src/main.cpp index 4af670aaec..b6b90b91b4 100644 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l4096/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l4096/src/main.cpp @@ -25,13 +25,12 @@ #include "utils/dsp_utilities.hpp" #include "utils/sorting.hpp" -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { #pragma HLS TOP xf::dsp::fft::fft(inD, outD); } -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top_c(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { xf::dsp::fft::fft(inD, outD); } @@ -42,8 +41,9 @@ int main(int argc, char** argv) { * complex ssr fft call * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din[SSR_FFT_R]; + hls::stream dout[SSR_FFT_R]; + T_ComplexDouble dout_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -51,8 +51,9 @@ int main(int argc, char** argv) { * complex ssr fft call that will synthesize to RTL for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix[SSR_FFT_R]; + hls::stream dout_fix[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -60,8 +61,9 @@ int main(int argc, char** argv) { * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix_c[SSR_FFT_R]; + hls::stream dout_fix_c[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_c_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus @@ -107,9 +109,12 @@ int main(int argc, char** argv) { // verification for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; + din[j].write(T_ComplexDouble(din_file[i * (SSR_FFT_R) + j])); + T_SSR_FFT_IN tmp_in; + tmp_in.real() = din_file[i * (SSR_FFT_R) + j].real(); + tmp_in.imag() = din_file[i * (SSR_FFT_R) + j].imag(); + din_fix[j].write(tmp_in); + din_fix_c[j].write(tmp_in); golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; } } @@ -131,12 +136,14 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft(din, dout); + convert2Array(dout, dout_arr); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL * for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top(din_fix, dout_fix); + convert2Array(dout_fix, dout_fix_arr); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ @@ -146,13 +153,14 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top_c(din_fix_c, dout_fix_c); + convert2Array(dout_fix_c, dout_fix_c_arr); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Verify if the ssr fft double precision model is functionally correct by comparing its output with // double precision Octave model output, it functionally verifies SSR FFT model independent of the // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); + double snrDBs_ssr_vs_octave = snr(golden_output, dout_arr); print_phase_header(); std::cout << get_section_header() << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; @@ -174,7 +182,7 @@ int main(int argc, char** argv) { T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification + p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_arr[a2][a1]; /// convert it to one day array for verification } } @@ -215,7 +223,7 @@ int main(int argc, char** argv) { // double precision Octave model output, It verifies if the data-path choice is good enough // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); + cast_to_double(dout_fix_arr, fix_fft_out); double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); print_phase_header(); @@ -236,7 +244,7 @@ int main(int argc, char** argv) { << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast + p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix_arr[a2][a1]; // convert to 1d array and also cast } } @@ -270,7 +278,7 @@ int main(int argc, char** argv) { std::cout << get_section_header() << "Verification Messages\n"; std::cout << get_section_header() << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); + double snrDBs_fix_point_vs_floating_model = snr(dout_arr, fix_fft_out); std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; print_phase_footer(); @@ -288,11 +296,11 @@ int main(int argc, char** argv) { int rtl_verif_flag = 0; for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { + if ((dout_fix_arr[rad][lt].real() != dout_fix_c_arr[rad][lt].real()) || + (dout_fix_arr[rad][lt].imag() != dout_fix_c_arr[rad][lt].imag())) { rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; + std::cout << "Expected Output : " << dout_fix_c_arr[rad][lt] << "\n"; + std::cout << "RTL Output : " << dout_fix_arr[rad][lt] << "\n"; std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; } } diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/Makefile deleted file mode 100644 index 06934610ae..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r16_l64.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/description.json deleted file mode 100644 index bb8c881f89..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate16_Length64", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r16_l64", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L64.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L64.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 40960, - "hls_csim": 10240, - "hls_cosim": 40960, - "hls_vivado_impl": 40960, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/run_hls.tcl deleted file mode 100755 index 41b31bc336..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r16_l64.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L64.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L64.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/fft_size.hpp deleted file mode 100644 index 18584b5732..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (64) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l64/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/Makefile deleted file mode 100644 index 11284770be..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r2_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/description.json deleted file mode 100644 index cbb421f372..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate2_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r2_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/run_hls.tcl deleted file mode 100755 index 394a6a6221..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r2_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/fft_size.hpp deleted file mode 100644 index 9c74670d71..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 2 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l1024/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/DEBUG_CONSTANTS.hpp index 29656bf495..a748fac7b4 100644 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/DEBUG_CONSTANTS.hpp +++ b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/DEBUG_CONSTANTS.hpp @@ -22,7 +22,7 @@ * NO_DATA_FRAMES_TO_SIMULATE : is number of times * FFT is simulated. *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 +#define NO_DATA_FRAMES_TO_SIMULATE 1 /********************************************************************* * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/main.cpp index 4af670aaec..b6b90b91b4 100644 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r2_l16/src/main.cpp @@ -25,13 +25,12 @@ #include "utils/dsp_utilities.hpp" #include "utils/sorting.hpp" -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { #pragma HLS TOP xf::dsp::fft::fft(inD, outD); } -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { +void fft_top_c(hls::stream inD[SSR_FFT_R], hls::stream outD[SSR_FFT_R]) { xf::dsp::fft::fft(inD, outD); } @@ -42,8 +41,9 @@ int main(int argc, char** argv) { * complex ssr fft call * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din[SSR_FFT_R]; + hls::stream dout[SSR_FFT_R]; + T_ComplexDouble dout_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -51,8 +51,9 @@ int main(int argc, char** argv) { * complex ssr fft call that will synthesize to RTL for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix[SSR_FFT_R]; + hls::stream dout_fix[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -60,8 +61,9 @@ int main(int argc, char** argv) { * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; + hls::stream din_fix_c[SSR_FFT_R]; + hls::stream dout_fix_c[SSR_FFT_R]; + T_SSR_FFT_OUT dout_fix_c_arr[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus @@ -107,9 +109,12 @@ int main(int argc, char** argv) { // verification for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; + din[j].write(T_ComplexDouble(din_file[i * (SSR_FFT_R) + j])); + T_SSR_FFT_IN tmp_in; + tmp_in.real() = din_file[i * (SSR_FFT_R) + j].real(); + tmp_in.imag() = din_file[i * (SSR_FFT_R) + j].imag(); + din_fix[j].write(tmp_in); + din_fix_c[j].write(tmp_in); golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; } } @@ -131,12 +136,14 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft(din, dout); + convert2Array(dout, dout_arr); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL * for implementation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top(din_fix, dout_fix); + convert2Array(dout_fix, dout_fix_arr); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ @@ -146,13 +153,14 @@ int main(int argc, char** argv) { * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ fft_top_c(din_fix_c, dout_fix_c); + convert2Array(dout_fix_c, dout_fix_c_arr); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Verify if the ssr fft double precision model is functionally correct by comparing its output with // double precision Octave model output, it functionally verifies SSR FFT model independent of the // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); + double snrDBs_ssr_vs_octave = snr(golden_output, dout_arr); print_phase_header(); std::cout << get_section_header() << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; @@ -174,7 +182,7 @@ int main(int argc, char** argv) { T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification + p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_arr[a2][a1]; /// convert it to one day array for verification } } @@ -215,7 +223,7 @@ int main(int argc, char** argv) { // double precision Octave model output, It verifies if the data-path choice is good enough // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); + cast_to_double(dout_fix_arr, fix_fft_out); double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); print_phase_header(); @@ -236,7 +244,7 @@ int main(int argc, char** argv) { << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast + p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix_arr[a2][a1]; // convert to 1d array and also cast } } @@ -270,7 +278,7 @@ int main(int argc, char** argv) { std::cout << get_section_header() << "Verification Messages\n"; std::cout << get_section_header() << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); + double snrDBs_fix_point_vs_floating_model = snr(dout_arr, fix_fft_out); std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; print_phase_footer(); @@ -288,11 +296,11 @@ int main(int argc, char** argv) { int rtl_verif_flag = 0; for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { + if ((dout_fix_arr[rad][lt].real() != dout_fix_c_arr[rad][lt].real()) || + (dout_fix_arr[rad][lt].imag() != dout_fix_c_arr[rad][lt].imag())) { rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; + std::cout << "Expected Output : " << dout_fix_c_arr[rad][lt] << "\n"; + std::cout << "RTL Output : " << dout_fix_arr[rad][lt] << "\n"; std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; } } diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/Makefile deleted file mode 100644 index 4a966a0655..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r4_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/description.json deleted file mode 100644 index 731c7cae69..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate4_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r4_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/run_hls.tcl deleted file mode 100755 index b7ee1a1bcd..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r4_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/fft_size.hpp deleted file mode 100644 index 5d74c52b3f..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l1024/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/Makefile deleted file mode 100644 index a6115a1db1..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r4_l16.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/fft_size.hpp deleted file mode 100644 index c6d070c190..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (16) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l16/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/Makefile deleted file mode 100644 index 3b623af8da..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r4_l32.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/description.json deleted file mode 100644 index be3836e5e1..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate4_Length32", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r4_l32", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L32.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L32.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/run_hls.tcl deleted file mode 100755 index c2ac5da7b3..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r4_l32.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L32.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L32.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/fft_size.hpp deleted file mode 100644 index 505a77597e..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (32) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/Makefile deleted file mode 100644 index 74842b7894..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r4_l4096.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/description.json deleted file mode 100644 index 461c573315..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate4_Length4096", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r4_l4096", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L4096.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L4096.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/run_hls.tcl deleted file mode 100755 index 0da97ebbeb..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r4_l4096.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L4096.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L4096.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/fft_size.hpp deleted file mode 100644 index f502f3986b..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (4096) -#define SSR_FFT_R 4 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l4096/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/Makefile deleted file mode 100644 index 615bb79413..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l1024.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/description.json deleted file mode 100644 index 26a2c4f079..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate8_Length1024", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l1024", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 40960, - "hls_csim": 10240, - "hls_cosim": 40960, - "hls_vivado_impl": 40960, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/run_hls.tcl deleted file mode 100755 index 343f0e1af3..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l1024.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/fft_size.hpp deleted file mode 100644 index 70751d3cf9..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (1024) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/main.cpp deleted file mode 100644 index 71cd321c24..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l1024/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - //#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/Makefile deleted file mode 100644 index 52df32cc3f..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l128.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/description.json deleted file mode 100644 index a281e6e123..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate8_Length128", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l128", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L128.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L128.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/run_hls.tcl deleted file mode 100755 index 566d95d873..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/run_hls.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l128.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L128.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L128.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP -config_compile -disable_auto_rewind - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/fft_size.hpp deleted file mode 100644 index 47af0fa204..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (128) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l128/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/Makefile deleted file mode 100644 index e43bae5aaf..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l4096.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/description.json deleted file mode 100644 index b1aa388dd2..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate8_Length4096", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l4096", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L4096.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L4096.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 20480, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/run_hls.tcl deleted file mode 100755 index 1eea3c3d0a..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l4096.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L4096.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L4096.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index a748fac7b4..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 1 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/fft_size.hpp deleted file mode 100644 index 2e08218717..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (4096) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l4096/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/Makefile deleted file mode 100644 index 3da91447d2..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l512.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/description.json deleted file mode 100644 index f90a6167b2..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate8_Length512", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l512", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L512.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L512.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 40960, - "hls_csim": 10240, - "hls_cosim": 40960, - "hls_vivado_impl": 40960, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/run_hls.tcl deleted file mode 100755 index 4b5256b529..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l512.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L512.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L512.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/fft_size.hpp deleted file mode 100644 index 158524fe2e..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (512) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l512/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/Makefile b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/Makefile deleted file mode 100644 index df2a6cb184..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) -XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L1/*}') - -# MK_INC_BEGIN hls_common.mk - -.PHONY: help - -help:: - @echo "" - @echo "Makefile Usage:" - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 DEVICE= PLATFORM_REPO_PATHS=" - @echo " Command to run the selected tasks for specified device." - @echo "" - @echo " Valid tasks are CSIM, CSYNTH, COSIM, VIVADO_SYN, VIVADO_IMPL" - @echo "" - @echo " DEVICE is case-insensitive and support awk regex." - @echo " For example, \`make run DEVICE='u200.*xdma' COSIM=1\`" - @echo " It can also be an absolute path to platform file." - @echo "" - @echo " PLATFORM_REPO_PATHS variable is used to specify the paths in which the platform files will be" - @echo " searched for." - @echo "" - @echo " make run CSIM=1 CSYNTH=1 COSIM=1 XPART=" - @echo " Alternatively, the FPGA part can be speficied via XPART." - @echo " For example, \`make run XPART='xcu200-fsgd2104-2-e' COSIM=1\`" - @echo " When XPART is set, DEVICE will be ignored." - @echo "" - @echo " make clean " - @echo " Command to remove the generated files." - @echo "" - -# MK_INC_END hls_common.mk - -# MK_INC_BEGIN vivado.mk - -.PHONY: check_vivado -check_vivado: -ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) - @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false -endif - -export PATH := $(XILINX_VIVADO)/bin:$(PATH) - -# MK_INC_END vivado.mk - -DEVICE ?= u200 - -# MK_INC_BEGIN vitis_set_part.mk - -# MK_INC_BEGIN vitis.mk - -.PHONY: check_vpp -check_vpp: -ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) - @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false -endif - -.PHONY: check_xrt -check_xrt: -ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) - @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false -endif - -export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) - -ifeq (,$(LD_LIBRARY_PATH)) -LD_LIBRARY_PATH := $(XILINX_XRT)/lib -else -LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) -endif -ifneq (,$(wildcard $(XILINX_VITIS)/bin/ldlibpath.sh)) -export LD_LIBRARY_PATH := $(shell $(XILINX_VITIS)/bin/ldlibpath.sh $(XILINX_VITIS)/lib/lnx64.o):$(LD_LIBRARY_PATH) -endif - -# MK_INC_END vitis.mk - -.PHONY: check_part - -ifeq (,$(XPART)) -# MK_INC_BEGIN vitis_set_platform.mk - -ifneq (,$(wildcard $(DEVICE))) -# Use DEVICE as a file path -XPLATFORM := $(DEVICE) -else -# Use DEVICE as a file name pattern -DEVICE_L := $(shell echo $(DEVICE) | tr A-Z a-z) -# 1. search paths specified by variable -ifneq (,$(PLATFORM_REPO_PATHS)) -# 1.1 as exact name -XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE_L)/$(DEVICE_L).xpfm))) -# 1.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 1.2 -endif # 1 -# 2. search Vitis installation -ifeq (,$(XPLATFORM)) -# 2.1 as exact name -XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 2.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 2.2 -endif # 2 -# 3. search default locations -ifeq (,$(XPLATFORM)) -# 3.1 as exact name -XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE_L)/$(DEVICE_L).xpfm)) -# 3.2 as a pattern -ifeq (,$(XPLATFORM)) -XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) -XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE_L)/'))) -endif # 3.2 -endif # 3 -endif - -define MSG_PLATFORM -No platform matched pattern '$(DEVICE)'. -Available platforms are: $(XPLATFORMS) -To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. -endef -export MSG_PLATFORM - -define MSG_DEVICE -More than one platform matched: $(XPLATFORM) -Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. -endef -export MSG_DEVICE - -.PHONY: check_platform -check_platform: -ifeq (,$(XPLATFORM)) - @echo "$${MSG_PLATFORM}" && false -endif -ifneq (,$(word 2,$(XPLATFORM))) - @echo "$${MSG_DEVICE}" && false -endif - -XDEVICE := $(basename $(notdir $(firstword $(XPLATFORM)))) - -# MK_INC_END vitis_set_platform.mk -ifeq (1, $(words $(XPLATFORM))) -# Query the part name of device -ifneq (,$(wildcard $(XILINX_VITIS)/bin/platforminfo)) -override XPART := $(shell $(XILINX_VITIS)/bin/platforminfo --json="hardwarePlatform.devices[0].fpgaPart" --platform $(firstword $(XPLATFORM)) | sed 's/^[^:]*://g' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/-\+/-/g') -endif -endif -check_part: check_platform check_vpp -ifeq (,$(XPART)) - @echo "XPART is not set and cannot be inferred. Please run \`make help\` for usage info." && false -endif -else # XPART -check_part: - @echo "XPART is directly set to $(XPART)" -endif # XPART - -# MK_INC_END vitis_set_part.mk - -# MK_INC_BEGIN hls_test_rules.mk - - -.PHONY: run setup runhls clean cleanall check - -# Alias to run, for legacy test script -check: run - -CSIM ?= 0 -CSYNTH ?= 0 -COSIM ?= 0 -VIVADO_SYN ?= 0 -VIVADO_IMPL ?= 0 -QOR_CHECK ?= 0 - -# at least RTL synthesis before check QoR -ifeq (1,$(QOR_CHECK)) -ifeq (0,$(VIVADO_IMPL)) -override VIVADO_SYN := 1 -endif -endif - -# need synthesis before cosim or vivado -ifeq (1,$(VIVADO_IMPL)) -override CSYNTH := 1 -endif - -ifeq (1,$(VIVADO_SYN)) -override CSYNTH := 1 -endif - -ifeq (1,$(COSIM)) -override CSYNTH := 1 -endif - -# From testbench.data_recipe of description.json -data: - @true - -run: data setup runhls - -setup: | check_part - @rm -f ./settings.tcl - @if [ -n "$$CLKP" ]; then echo 'set CLKP $(CLKP)' >> ./settings.tcl ; fi - @echo 'set XPART $(XPART)' >> ./settings.tcl - @echo 'set CSIM $(CSIM)' >> ./settings.tcl - @echo 'set CSYNTH $(CSYNTH)' >> ./settings.tcl - @echo 'set COSIM $(COSIM)' >> ./settings.tcl - @echo 'set VIVADO_SYN $(VIVADO_SYN)' >> ./settings.tcl - @echo 'set VIVADO_IMPL $(VIVADO_IMPL)' >> ./settings.tcl - @echo 'set XF_PROJ_ROOT "$(XF_PROJ_ROOT)"' >> ./settings.tcl - @echo 'set CUR_DIR "$(CUR_DIR)"' >> ./settings.tcl - @echo "Configured: settings.tcl" - @echo "----" - @cat ./settings.tcl - @echo "----" - -HLS ?= vitis_hls -runhls: data setup | check_vivado check_vpp - $(HLS) -f run_hls.tcl; - -clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r8_l64.prj - -# Used by Jenkins test -cleanall: clean - -# MK_INC_END hls_test_rules.mk \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/description.json b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/description.json deleted file mode 100644 index b42923a966..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/description.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Xilinx SSR FFT Float Rate8_Length64", - "description": "HLS case", - "flow": "hls", - "platform_whitelist": [ - "u200", - "aws-vu9p-f1", - "vck190" - ], - "platform_blacklist": [], - "part_whitelist": [], - "part_blacklist": [], - "project": "prj_ssr_fft_reg_test_r8_l64", - "solution": "solution1", - "clock": "3.3", - "topfunction": "fft_top", - "top": { - "source": [ - "src/main.cpp", - "src/hls_ssr_fft_data_path.hpp", - "src/DEBUG_CONSTANTS.hpp" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" - }, - "testbench": { - "source": [ - "src/main.cpp", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L64.verif", - "${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L64.verif" - ], - "cflags": "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float", - "ldflags": "", - "argv": {}, - "stdmath": false - }, - "testinfo": { - "disable": false, - "jobs": [ - { - "index": 0, - "dependency": [], - "env": "", - "cmd": "", - "max_memory_MB": { - "hls_vivado_syn": 16384, - "hls_csim": 10240, - "hls_cosim": 16384, - "hls_vivado_impl": 16384, - "hls_csynth": 10240 - }, - "max_time_min": { - "hls_vivado_syn": 470, - "hls_csim": 60, - "hls_cosim": 470, - "hls_vivado_impl": 470, - "hls_csynth": 60 - } - } - ], - "targets": [ - "hls_csim", - "hls_csynth", - "hls_cosim", - "hls_vivado_syn", - "hls_vivado_impl" - ], - "category": "canary" - } -} \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/run_hls.tcl b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/run_hls.tcl deleted file mode 100755 index 480795f55b..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/run_hls.tcl +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2019-2020 Xilinx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -source settings.tcl - -set PROJ "prj_ssr_fft_reg_test_r8_l64.prj" -set SOLN "solution1" - -if {![info exists CLKP]} { - set CLKP 3.3 -} - -open_project -reset $PROJ - -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftStimulusIn_L64.verif ${XF_PROJ_ROOT}/L1/tests/common_float/verif/fftGoldenOut_L64.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/float -I${XF_PROJ_ROOT}/L1/tests/common_float" -set_top fft_top - -open_solution -reset $SOLN - - - - -set_part $XPART -create_clock -period $CLKP - -if {$CSIM == 1} { - csim_design -} - -if {$CSYNTH == 1} { - csynth_design -} - -if {$COSIM == 1} { - cosim_design -} - -if {$VIVADO_SYN == 1} { - export_design -flow syn -rtl verilog -} - -if {$VIVADO_IMPL == 1} { - export_design -flow impl -rtl verilog -} - -exit \ No newline at end of file diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/DEBUG_CONSTANTS.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/DEBUG_CONSTANTS.hpp deleted file mode 100644 index 29656bf495..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/DEBUG_CONSTANTS.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : DEBUG_CONSTANTS.hpp -#ifndef DEBUG_CONSTANTS_H_ -#define DEBUG_CONSTANTS_H_ - -/********************************************************************* - * NO_DATA_FRAMES_TO_SIMULATE : is number of times - * FFT is simulated. - *********************************************************************/ -#define NO_DATA_FRAMES_TO_SIMULATE 5 - -/********************************************************************* - * MAX_PERCENT_ERROR_IN_SAMPLE is the maximum allowed error in percent - * when comparing with golden output if sample differ by less than - * MAX_PERCENT_ERROR_IN_SAMPLE it is not counted as error - *********************************************************************/ -#define MAX_PERCENT_ERROR_IN_SAMPLE 10 - -/********************************************************************* - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR is %tage of total errors - * allowed in any simulation(per frame) to pass if the errors in any - * frame (number of mismatches) are larger than - * MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, the simulation fails. - * ******************************************************************/ -#define MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR 5 - -#define CHECK_COVEARAGE \ - std::cout << "\n\n\n\nCovered;;;;;;;;\n" << __FILE__ << "Line:" << __LINE__ << "<<\n\n\n"; \ - exit(1) - -#endif // DEBUG_CONSTANTS_H diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/fft_size.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/fft_size.hpp deleted file mode 100644 index 72c3c3df91..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/fft_size.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (64) -#define SSR_FFT_R 8 -#endif //__FFT_SIZE_H__ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/hls_ssr_fft_data_path.hpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/hls_ssr_fft_data_path.hpp deleted file mode 100644 index 294c57b903..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/hls_ssr_fft_data_path.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -// File Name : hls_ssr_fft_data_path.hpp -#ifndef HLS_SSR_FFT_DATA_PATH_ -#define HLS_SSR_FFT_DATA_PATH_ -#include -#include "vt_fft.hpp" -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Inlcude file that declares FFT Radix or SSR factor and length for the test - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#include "fft_size.hpp" -using namespace xf::dsp::fft; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Set appropriate bit-width for the storage of sine/cosine or exponential tables and also define input bit widths - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -#define SSR_FFT_IN_WL 27 -#define SSR_FFT_IN_IL 10 -#define SSR_FFT_TW_WL 18 -#define SSR_FFT_TW_IL 2 - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double type that is used for creating a reference floating point model which is used for verification and - *calculating fixed point model SNR in DBs. - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef double T_innerDB; -typedef double T_innerDBOut; - -typedef float T_INNER_SSR_FFT_IN; -typedef float T_INNER_SSR_FFT_OUT; -typedef float T_INNER_SSR_TWIDDLE_TABLE; -typedef T_INNER_SSR_TWIDDLE_TABLE T_INNER_SSR_EXP_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define ap_fixed complex type for input samples and the complex sin/cosine table storage - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_SSR_FFT_IN; -typedef complex_wrapper T_SSR_TWIDDLE_TABLE; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define double precision complex types - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -typedef complex_wrapper T_ComplexDouble; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a SSR FFT parameter structure that extends a predefine structure with default values, redefine only the - *members - *whose default values are to be changes , the structure which is extended here is called ssr_fft_default_params which - *defines default values - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -struct ssr_fft_params : ssr_fft_default_params { - static const int N = SSR_FFT_L; - static const int R = SSR_FFT_R; - - /****************************** - * Allowed scaling modes : - * - SSR_FFT_NO_SCALING - * - SSR_FFT_GROW_TO_MAX_WIDTH - * -SSR_FFT_SCALE - * - ******************************/ - static const scaling_mode_enum scaling_mode = SSR_FFT_GROW_TO_MAX_WIDTH; - - // sine/cosine storage resolution - static const int twiddle_table_word_length = SSR_FFT_TW_WL; - static const int twiddle_table_intger_part_length = SSR_FFT_TW_IL; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - - /****************************** - * The default instance ID - * needs to be unique for - * each instance if multiple - * instance of the SSR FFT are - * used in single design - ******************************/ - static const int default_t_instanceID = 0; -}; - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Define a type for output storage which is predefined in a structure ssr_fft_output_type : this structure returns - *proper type provided the constant parameter structure as defined above and the SSR FFT input type also defined - *above - *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ -typedef xf::dsp::fft::ssr_fft_output_type::t_ssr_fft_out T_SSR_FFT_OUT; - -#endif // HLS_SSR_FFT_DATA_PATH_ diff --git a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/main.cpp deleted file mode 100644 index 4af670aaec..0000000000 --- a/dsp/L1/tests/hw/1dfft/float/fft_1d_snr/testsfft_natural_order/ssr_fft_r8_l64/src/main.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2019 Xilinx, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ -//================================== End Lic ================================================= -#include "DEBUG_CONSTANTS.hpp" -#include -#include -#include -#include "hls_ssr_fft_data_path.hpp" -#include "utils/spu.hpp" -#include "utils/mVerificationUtlityFunctions.hpp" -#include "utils/suf.hpp" -#include "utils/dsp_utilities.hpp" -#include "utils/sorting.hpp" - -void fft_top(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { -#pragma HLS TOP - xf::dsp::fft::fft(inD, outD); -} - -void fft_top_c(T_SSR_FFT_IN inD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R], - T_SSR_FFT_OUT outD[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]) { - xf::dsp::fft::fft(inD, outD); -} - -#ifndef __SYNTHESIS__ -int main(int argc, char** argv) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din and dout define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_ComplexDouble din[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_ComplexDouble dout[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix and dout_fix define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that will synthesize to RTL for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * din_fix_c and dout_fix_c define 2-dimensional arrays for the storage of input and output complex samples for - * complex ssr fft call that is NOT SYNTHESIZED creates a bit true output for comparison after COSIM - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - T_SSR_FFT_IN din_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - T_SSR_FFT_OUT dout_fix_c[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - /// dine_file 1-Dimensional array that will be used to store stimulus input data read from the file, stimulus - // is created using octave scripts. - T_ComplexDouble din_file[SSR_FFT_L]; - - // golden_output_file is 1-D array that is used to read GOLDEN OUTPUT test vectors for functional verification - T_ComplexDouble golden_output_file[SSR_FFT_L]; - - // The output from the golden_output_file is transformed and stored in 2-D array depending on the choice of radix - // and the length and stored in array golden_output that is finall used for verification function calls - T_ComplexDouble golden_output[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - - std::string root_path = ""; // Define root path where the input stimulus files are stored - std::string export_root_path = ""; // Define root path where output log files will be stored - - std::ofstream logStreamBB; - std::string blockBoxFilename = root_path + "ssr_fft_verification_log.log"; - logStreamBB.open(blockBoxFilename.c_str(), std::fstream::out); - std::string inputStimulusDataVerifFileName; - std::stringstream strStream; - strStream << root_path << "fftStimulusIn_L" << SSR_FFT_L << ".verif"; - inputStimulusDataVerifFileName = strStream.str(); - std::cout << "The Stimulus file with Path : " << inputStimulusDataVerifFileName << "\n"; - std::stringstream strStream1; - std::string goldenOutputDataVerifFileName; - strStream1 << root_path << "fftGoldenOut_L" << SSR_FFT_L << ".verif"; - goldenOutputDataVerifFileName = strStream1.str(); - strStream1.str(""); - strStream1 << root_path << "output_data_R" << SSR_FFT_R << "_L" << SSR_FFT_L << ".verif"; - std::string RecInOutFileName; - RecInOutFileName = strStream1.str(); - std::ofstream logStream; - std::string verifLogFileName = root_path + "hls_fft_verification_log.vsum"; - std::string exportDataFile1 = export_root_path + "file1.data"; - // Read input stimulus from the file - readComplexArrayFromFile(logStreamBB, "din_file", inputStimulusDataVerifFileName, din_file, SSR_FFT_L); - // Read GOLDEN OUTPUT vector for comparison - readComplexArrayFromFile(logStreamBB, "golden_output_file", goldenOutputDataVerifFileName, - golden_output_file, SSR_FFT_L); - - // This loop will transform 1-D data read from the file in 2-D for passing to ssr fft function calls and - // verification - for (int i = 0; i < SSR_FFT_L / SSR_FFT_R; i++) { - for (int j = 0; j < SSR_FFT_R; j++) { - din[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix[j][i] = din_file[i * (SSR_FFT_R) + j]; - din_fix_c[j][i] = din_file[i * (SSR_FFT_R) + j]; - golden_output[j][i] = golden_output_file[i * (SSR_FFT_R) + j]; - } - } - - /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * F - * F - * T - * **CALLS** - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - for (int no_ffts = 0; no_ffts < NO_DATA_FRAMES_TO_SIMULATE; no_ffts++) { - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex double type : Reference model call to calculate FLOATING POINT fft that - * will be used for verifying the implementation and then for comparison with FIXED POINT model to calculate - * the SNR - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft(din, dout); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This the actual model that will be synthesized, to generate RTL - * for implementation - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top(din_fix, dout_fix); - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * CAll SSR FFT with complex ap_fixed type : This function wraps the same C++ model that is wrapped in for - * synthesis, this function is not synthesized it is only used to compare the final RTL ouput and the C++ - * output during cosimulation for verification. The comparison done with this output has no SIGNIFICANE when - * the csim/ c++ simulation is run. But during RTL/cosim the output of this model will be used to compare - * RTL model output and the c++ output ( Bit true verification of RTL model vs. C++ model) - * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - fft_top_c(din_fix_c, dout_fix_c); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft double precision model is functionally correct by comparing its output with - // double precision Octave model output, it functionally verifies SSR FFT model independent of the - // fact that if fixed point data-path bit-widths are appropriate in case of fixed point ssr fft - double snrDBs_ssr_vs_octave = snr(golden_output, dout); - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT double precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT double precision vs. Octave double precision): " - << " " << snrDBs_ssr_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft double precision model output with golden reference Octave model to verify the - // functionality of ssr fft in general, exculding fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT double precision output with golden Octave model output: \n"; - - // 1-D array used for conversion of fft_top output from 2-D 1-D - T_ComplexDouble p_fftOutDataTemp[SSR_FFT_L]; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout[a2][a1]; /// convert it to one day array for verification - } - } - - int vf3; - VerificationResults verifResultsFFTvsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // error given in % - vf3 = verifResultsFFTvsOctave.m_statusFlag; - exportArrayToFile(p_fftOutDataTemp, - RecInOutFileName); // export FIXED POINT fft ouput to file - if (vf3 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - - } else { - std::cout << get_section_header() - << "Verification of SSR FFT double precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - std::cout << get_section_header() - << "The SNR (SSR FFT vs. Octave/Matlab ): " << verifResultsFFTvsOctave.m_snr << std::endl; - print_phase_footer(); - ///////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * Cast complex to complex for comparison with reference double output - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Verify if the ssr fft FIXED point model is functionally correct by comparing its output with - // double precision Octave model output, It verifies if the data-path choice is good enough - // like the scaling mode, input, output and twiddle bit-width are sufficient for given ssr fft - T_ComplexDouble fix_fft_out[SSR_FFT_R][SSR_FFT_L / SSR_FFT_R]; - cast_to_double(dout_fix, fix_fft_out); - double snrDBs_ssr_fix_vs_octave = snr(golden_output, fix_fft_out); - - print_phase_header(); - std::cout << get_section_header() - << "Comparing C++ SSR FFT Single Precision model vs. Octave double precision model:\n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "The SNR ( SSR FFT Single Precision vs. Octave double precision): " - << " " << snrDBs_ssr_fix_vs_octave << " db \n"; - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft fixed point model output against golden reference Octave model to verify the - // functionality of ssr fft with fixed point data-path effects - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision output with golden Octave model output: \n"; - for (int a1 = 0; a1 < (SSR_FFT_L / SSR_FFT_R); a1++) { - for (int a2 = 0; a2 < SSR_FFT_R; a2++) { - p_fftOutDataTemp[a1 * SSR_FFT_R + a2] = dout_fix[a2][a1]; // convert to 1d array and also cast - } - } - - int vf4; - VerificationResults verifResultsFixVsOctave; - verifResultsFixVsOctave = verifyArrayOutput_with_snr( - logStream, "GOLDEN OUTPUT", goldenOutputDataVerifFileName, p_fftOutDataTemp, MAX_PERCENT_ERROR_IN_SAMPLE, - MAX_ALLOWED_PERCENTAGE_OF_SAMPLES_IN_ERROR, SSR_FFT_L); // 50,5 - vf4 = verifResultsFixVsOctave.m_statusFlag; - if (vf4 != 0) { - print_error_header(); - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : FAILED" - << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - return 1; - } else { - std::cout << get_section_header() - << "Verification of SSR FFT Single Precision output vs. Octave double precision output : PASSED" - << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // Compare SSR fft DOUBLE precision model with SSR FFT fixed point model to verify the closeness - // of fixed point data-path with double precision SSR FFT model. - print_phase_header(); - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() - << "Comparing SSR FFT Single Precision model with SSR FFT double precision model: \n"; - double snrDBs_fix_point_vs_floating_model = snr(dout, fix_fft_out); - std::cout << "The SNR( SSR FFT Single Precision vs. SSR FFT double precision) is :" - << " " << snrDBs_fix_point_vs_floating_model << " db \n\n"; - print_phase_footer(); - /////////////////////////////////////////////////////////////////////////////////////////////////// - - print_phase_header(); - std::cout << "----------------------------------------------------------------------\n"; - std::cout << "These messages aree useful for -----COSIM-----only \notherwise it compares C++ model with itself \n"; - std::cout << get_section_header() << "Verification Messages\n"; - std::cout << get_section_header() << "Comparing RTL model output with C++ fixed Single Precision model. \n"; - std::cout << "------------------COSIM Relevant Verification Messages----------------\n"; - std::cout << "Comparing RTL output with C++ Single Precision model, BIT-TRUE Model Verification \n"; - std::cout << "----------------------------------------------------------------------\n"; - - int rtl_verif_flag = 0; - for (int lt = 0; lt < SSR_FFT_L / SSR_FFT_R; lt++) { - for (int rad = 0; rad < SSR_FFT_R; rad++) { - if ((dout_fix[rad][lt].real() != dout_fix_c[rad][lt].real()) || - (dout_fix[rad][lt].imag() != dout_fix_c[rad][lt].imag())) { - rtl_verif_flag++; - std::cout << "Expected Output : " << dout_fix_c[rad][lt] << "\n"; - std::cout << "RTL Output : " << dout_fix[rad][lt] << "\n"; - std::cout << "Indices : l:r" << lt << ": " << rad << std::endl; - } - } - } - if (rtl_verif_flag != 0) { - print_error_header(); - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model FAILED." << std::endl; - std::cout << "Exiting ..." << std::endl; - print_error_footer(); - std::cout << "No. of Errors: " << rtl_verif_flag << "\n"; - return 1; - } else { - std::cout << get_section_header() - << "Bit-True verification of RTL vs. synthesized C++ Single Precision model PASEED." << std::endl; - std::cout << "VERIFIED.....\n" << std::endl; - } - print_phase_footer(); - - print_phase_header(); - - if ((vf3 | vf4 | rtl_verif_flag) == 0) { - std::cout << "OVERL ALL Simulation was SUCCESSFULL Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R - << std::endl; - std::cout << "SNR Double precision Model : " << snrDBs_ssr_vs_octave << " dbs" << std::endl; - std::cout << "SNR Single Precision Model : " << snrDBs_ssr_fix_vs_octave << " dbs" << std::endl; - - } else { - std::cout << "OVERL ALL Simulation has FAILED Done with L=" << SSR_FFT_L << " R=" << SSR_FFT_R << std::endl; - } - - print_phase_footer(); - return (vf3 | vf4 | rtl_verif_flag); -} -#endif diff --git a/dsp/L1/tests/hw/1dfft/float/impulse_test/src/main.cpp b/dsp/L1/tests/hw/1dfft/float/impulse_test/src/main.cpp index 5008c96eb6..489edfb971 100644 --- a/dsp/L1/tests/hw/1dfft/float/impulse_test/src/main.cpp +++ b/dsp/L1/tests/hw/1dfft/float/impulse_test/src/main.cpp @@ -21,14 +21,14 @@ #define NUM_TEST 1 int main(int argc, char** argv) { - T_in inData[SSR][FFT_LEN / SSR]; - T_out outData[SSR][FFT_LEN / SSR]; + hls::stream inData[SSR]; + hls::stream outData[SSR]; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { if (r == 0 && t == 0) - inData[r][t] = 1; + inData[r].write(T_in(1)); else - inData[r][t] = 0; + inData[r].write(T_in(0)); } } for (int t = 0; t < NUM_TEST; ++t) { @@ -39,7 +39,8 @@ int main(int argc, char** argv) { int errs = 0; for (int r = 0; r < SSR; ++r) { for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (outData[r][t].real() != 1 || outData[r][t].imag() != 0) errs++; + T_out tmp = outData[r].read(); + if (tmp.real() != 1 || tmp.imag() != 0) errs++; } } return errs; diff --git a/dsp/L1/tests/hw/1dfft/float/impulse_test/src/top_module.cpp b/dsp/L1/tests/hw/1dfft/float/impulse_test/src/top_module.cpp index 420f62d45f..e7333c81e7 100644 --- a/dsp/L1/tests/hw/1dfft/float/impulse_test/src/top_module.cpp +++ b/dsp/L1/tests/hw/1dfft/float/impulse_test/src/top_module.cpp @@ -17,6 +17,6 @@ //================================== End Lic ================================================= #include "top_module.hpp" #include "data_path.hpp" -void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]) { +void fft_top(hls::stream p_inData[SSR], hls::stream p_outData[SSR]) { xf::dsp::fft::fft(p_inData, p_outData); } diff --git a/dsp/L1/tests/hw/1dfft/float/impulse_test/src/top_module.hpp b/dsp/L1/tests/hw/1dfft/float/impulse_test/src/top_module.hpp index 3aa6880f7e..098ed61d89 100644 --- a/dsp/L1/tests/hw/1dfft/float/impulse_test/src/top_module.hpp +++ b/dsp/L1/tests/hw/1dfft/float/impulse_test/src/top_module.hpp @@ -18,4 +18,4 @@ #include "data_path.hpp" #include -void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]); +void fft_top(hls::stream p_inData[SSR], hls::stream p_outData[SSR]); diff --git a/dsp/docs/src/csv_data_files/L2/fft_benchmark.csv b/dsp/docs/src/csv_data_files/L2/fft_benchmark.csv index 59c1fe8535..b85d80f8fe 100644 --- a/dsp/docs/src/csv_data_files/L2/fft_benchmark.csv +++ b/dsp/docs/src/csv_data_files/L2/fft_benchmark.csv @@ -1,83 +1,87 @@ Library Element,DATA_TYPE,TWIDDLE_TYPE,POINT_SIZE,FFT_NIFFT,CASC_LEN,DYN_PT_SIZE,WINDOW_VSIZE,API_IO,PARALLEL_POWER,cycleCountAvg,throughputAvg,initiationInterval,throughputInitIntAvg,NUM_BANKS,NUM_ME,DATA_MEMORY,PROGRAM_MEMORY fft_ifft_dit_1ch,cfloat,cfloat,1024,1,1,1,1024,0,0,2390,428 MSa/s,2983,343 MSa/s,13,1,55864,9190 -fft_ifft_dit_1ch,cint32,cint16,1024,1,4,1,1024,0,0,492,2081 MSa/s,2080,492 MSa/s,38,4,127008,24 1 24 1 2894 24 3 24 3 2990 25 1 25 1 6556 25 3 25 3 3550 -fft_ifft_dit_1ch,cint32,cint16,1024,1,3,1,1024,0,0,700,1462 MSa/s,2076,493 MSa/s,31,3,101928,24 2 24 2 9500 25 0 25 0 2894 25 2 25 2 2990 -fft_ifft_dit_1ch,cint32,cint16,1024,1,2,1,1024,0,0,700,1462 MSa/s,2071,494 MSa/s,22,2,76848,24 1 24 1 3974 25 0 25 0 9500 +fft_ifft_dit_1ch,cint32,cint16,1024,1,3,1,1024,0,0,700,1462 MSa/s,2076,493 MSa/s,31,3,101928,9500 2894 2990 +fft_ifft_dit_1ch,cint32,cint16,1024,1,2,1,1024,0,0,700,1462 MSa/s,2071,494 MSa/s,22,2,76848,3974 9500 fft_ifft_dit_1ch,cint32,cint16,1024,1,1,1,1024,0,0,1054,971 MSa/s,2070,494 MSa/s,13,1,51768,12928 fft_ifft_dit_1ch,cint32,cint16,1024,1,1,0,1024,0,0,1782,574 MSa/s,2071,494 MSa/s,9,1,51640,5010 fft_ifft_dit_1ch,cint16,cint16,64,1,1,1,64,0,0,488,131 MSa/s,532,120 MSa/s,8,1,11832,7660 fft_ifft_dit_1ch,cint16,cint16,64,1,1,0,64,0,0,203,315 MSa/s,245,261 MSa/s,8,1,11704,3100 -fft_ifft_dit_1ch,cint32,cint16,1024,1,5,1,1024,0,0,427,2398 MSa/s,2085,491 MSa/s,49,5,152088,24 2 24 2 2862 24 4 24 4 2990 25 0 25 0 3622 25 2 25 2 3598 25 4 25 4 3550 fft_ifft_dit_1ch,cint16,cint16,512,1,1,0,512,0,0,933,548 MSa/s,978,523 MSa/s,9,1,25528,4722 +fft_ifft_dit_1ch,cint16,cint16,512,0,1,0,512,0,0,933,548 MSa/s,978,523 MSa/s,9,1,25528,4722 fft_ifft_dit_1ch,cint16,cint16,32,0,1,1,32,0,0,349,91 MSa/s,393,81 MSa/s,8,1,11320,7460 fft_ifft_dit_1ch,cint16,cint16,32,0,1,0,32,0,0,130,246 MSa/s,167,191 MSa/s,8,1,11192,2310 fft_ifft_dit_1ch,cint16,cint16,256,1,1,0,256,0,0,469,545 MSa/s,512,500 MSa/s,8,1,16824,4322 -fft_ifft_dit_1ch,cint16,cint16,256,1,3,1,256,0,0,344,744 MSa/s,641,399 MSa/s,15,3,42536,24 0 24 0 6732 24 1 24 1 3006 25 0 25 0 2910 -fft_ifft_dit_1ch,cint16,cint16,256,1,3,0,256,0,0,299,856 MSa/s,526,486 MSa/s,15,3,42280,24 0 24 0 2898 24 1 24 1 2082 25 0 25 0 1954 -fft_ifft_dit_1ch,cint16,cint16,256,1,2,1,256,0,0,347,737 MSa/s,596,429 MSa/s,11,2,29744,24 0 24 0 4006 25 0 25 0 6732 -fft_ifft_dit_1ch,cint16,cint16,256,1,2,0,256,0,0,250,1024 MSa/s,440,581 MSa/s,14,2,29552,24 0 24 0 2754 25 0 25 0 2898 -fft_ifft_dit_1ch,cint16,cint16,512,0,1,0,512,0,0,933,548 MSa/s,978,523 MSa/s,9,1,25528,4722 +fft_ifft_dit_1ch,cint16,cint16,256,1,3,1,256,0,0,344,744 MSa/s,641,399 MSa/s,15,3,42536,6732 3006 2910 +fft_ifft_dit_1ch,cint16,cint16,256,1,3,0,256,0,0,299,856 MSa/s,526,486 MSa/s,15,3,42280,2898 2082 1954 +fft_ifft_dit_1ch,cint16,cint16,256,1,2,1,256,0,0,347,737 MSa/s,596,429 MSa/s,11,2,29744,4006 6732 +fft_ifft_dit_1ch,cint16,cint16,256,1,2,0,256,0,0,250,1024 MSa/s,440,581 MSa/s,14,2,29552,2754 2898 +fft_ifft_dit_1ch,cint16,cint16,256,1,1,1,256,0,0,577,443 MSa/s,679,377 MSa/s,8,1,16952,10862 +fft_ifft_dit_1ch,cint16,cint16,256,1,1,0,256,0,0,469,545 MSa/s,567,451 MSa/s,8,1,16824,4322 +fft_ifft_dit_1ch,cint32,cint16,1024,1,4,1,1024,0,0,492,2081 MSa/s,2080,492 MSa/s,38,4,127008,2894 2990 6556 3550 +fft_ifft_dit_1ch,cint32,cint16,1024,1,5,1,1024,0,0,427,2398 MSa/s,2085,491 MSa/s,49,5,152088,2862 2990 3622 3598 3550 fft_ifft_dit_1ch,cint32,cint16,128,1,1,0,1024,0,0,2207,463 MSa/s,2268,451 MSa/s,7,1,42424,4098 -fft_ifft_dit_1ch,cint32,cint16,128,1,2,0,1024,0,0,1219,840 MSa/s,2076,493 MSa/s,12,2,67440,24 0 24 0 2624 25 0 25 0 2958 -fft_ifft_dit_1ch,cint32,cint16,128,1,1,0,128,0,0,282,453 MSa/s,320,400 MSa/s,7,1,13752,3858 -fft_ifft_dit_1ch,cint32,cint16,64,1,2,0,1024,0,0,2114,484 MSa/s,2185,468 MSa/s,12,2,67440,24 0 24 0 2602 25 0 25 0 1890 +fft_ifft_dit_1ch,cint32,cint16,128,1,2,0,1024,0,0,1219,840 MSa/s,2076,493 MSa/s,12,2,67440,2624 2958 +fft_ifft_dit_1ch,cint32,cint16,64,1,2,0,1024,0,0,2114,484 MSa/s,2185,468 MSa/s,12,2,67440,2602 1890 fft_ifft_dit_1ch,cint32,cint16,64,1,1,0,1024,0,0,3000,341 MSa/s,3060,334 MSa/s,7,1,42424,3118 -fft_ifft_dit_1ch,cint32,cint16,512,1,2,0,1024,0,0,1115,918 MSa/s,2072,494 MSa/s,14,2,71024,24 0 24 0 2990 25 0 25 0 3350 +fft_ifft_dit_1ch,cint32,cint16,512,1,2,0,1024,0,0,1115,918 MSa/s,2072,494 MSa/s,14,2,71024,2990 3350 fft_ifft_dit_1ch,cint32,cint16,512,1,1,0,1024,0,0,1895,540 MSa/s,2073,493 MSa/s,8,1,46008,4802 fft_ifft_dit_1ch,cint32,cint16,512,1,1,1,512,0,0,733,698 MSa/s,1069,478 MSa/s,8,1,29752,12976 fft_ifft_dit_1ch,cint32,cint16,512,1,1,0,512,0,0,936,547 MSa/s,1040,492 MSa/s,8,1,29624,4626 fft_ifft_dit_1ch,cint32,cint16,32,1,1,1,32,0,0,320,100 MSa/s,364,87 MSa/s,7,1,10808,7280 fft_ifft_dit_1ch,cint32,cint16,32,1,1,0,32,0,0,139,230 MSa/s,176,181 MSa/s,7,1,10680,2358 -fft_ifft_dit_1ch,cint32,cint16,32,1,2,0,1024,0,0,3008,340 MSa/s,3078,332 MSa/s,12,2,67440,24 0 24 0 2172 25 0 25 0 1680 -fft_ifft_dit_1ch,cint32,cint16,32,1,1,0,1024,0,0,4069,251 MSa/s,4129,248 MSa/s,7,1,42424,2524 +fft_ifft_dit_1ch,cint16,cint16,256,0,1,0,256,0,0,469,545 MSa/s,512,500 MSa/s,8,1,16824,4322 +fft_ifft_dit_1ch,cint32,cint16,32,1,2,0,1024,0,0,3008,340 MSa/s,3078,332 MSa/s,12,2,67440,2172 1680 fft_ifft_dit_1ch,cint32,cint16,256,1,1,1,256,0,0,548,467 MSa/s,600,426 MSa/s,7,1,19000,10160 fft_ifft_dit_1ch,cint32,cint16,256,1,1,0,256,0,0,465,550 MSa/s,524,488 MSa/s,7,1,18872,4306 -fft_ifft_dit_1ch,cint32,cint16,256,1,2,0,1024,0,0,963,1063 MSa/s,2072,494 MSa/s,12,2,68464,24 0 24 0 3058 25 0 25 0 2974 +fft_ifft_dit_1ch,cint32,cint16,256,1,2,0,1024,0,0,963,1063 MSa/s,2072,494 MSa/s,12,2,68464,3058 2974 fft_ifft_dit_1ch,cint32,cint16,256,1,1,0,1024,0,0,1871,547 MSa/s,2073,493 MSa/s,7,1,43448,4512 fft_ifft_dit_1ch,cint32,cint16,16,1,1,0,16,0,0,79,202 MSa/s,114,140 MSa/s,7,1,10168,1778 fft_ifft_dit_1ch,cint32,cint16,16,1,1,0,1024,0,0,3993,256 MSa/s,4054,252 MSa/s,7,1,42424,2230 fft_ifft_dit_1ch,cint32,cint16,128,1,1,1,128,0,0,487,262 MSa/s,532,240 MSa/s,7,1,13880,10160 -fft_ifft_dit_1ch,cint16,cint16,256,1,1,1,256,0,0,577,443 MSa/s,679,377 MSa/s,8,1,16952,10862 -fft_ifft_dit_1ch,cint16,cint16,256,1,1,0,256,0,0,469,545 MSa/s,567,451 MSa/s,8,1,16824,4322 -fft_ifft_dit_1ch,cint16,cint16,256,0,1,0,256,0,0,469,545 MSa/s,512,500 MSa/s,8,1,16824,4322 +fft_ifft_dit_1ch,cint32,cint16,128,1,1,0,128,0,0,282,453 MSa/s,320,400 MSa/s,7,1,13752,3858 +fft_ifft_dit_1ch,cint32,cint16,32,1,1,0,1024,0,0,4069,251 MSa/s,4129,248 MSa/s,7,1,42424,2524 fft_ifft_dit_1ch,cint16,cint16,2048,1,1,0,2048,0,0,3913,523 MSa/s,3974,515 MSa/s,13,1,79288,5490 -fft_ifft_dit_1ch,cfloat,cfloat,32,1,1,0,32,0,0,213,150 MSa/s,255,125 MSa/s,7,1,10680,3268 -fft_ifft_dit_1ch,cfloat,cfloat,32,1,1,0,1024,0,0,6297,162 MSa/s,6358,161 MSa/s,7,1,42424,3538 -fft_ifft_dit_1ch,cfloat,cfloat,256,1,3,1,256,0,0,564,453 MSa/s,1076,237 MSa/s,15,3,44584,24 0 24 0 5738 24 1 24 1 3796 25 0 25 0 3562 -fft_ifft_dit_1ch,cfloat,cfloat,256,1,3,0,256,0,0,633,404 MSa/s,1070,239 MSa/s,14,3,44328,24 0 24 0 3160 24 1 24 1 2296 25 0 25 0 2028 -fft_ifft_dit_1ch,cfloat,cfloat,256,1,2,1,256,0,0,652,392 MSa/s,1065,240 MSa/s,10,2,31792,24 0 24 0 4916 25 0 25 0 5738 -fft_ifft_dit_1ch,cfloat,cfloat,256,1,2,0,256,0,0,802,319 MSa/s,1155,221 MSa/s,10,2,31600,24 0 24 0 3160 25 0 25 0 3020 -fft_ifft_dit_1ch,cfloat,cfloat,256,1,2,0,1024,0,0,2935,348 MSa/s,3021,338 MSa/s,12,2,68464,24 0 24 0 3278 25 0 25 0 3248 +fft_ifft_dit_1ch,cint16,cint16,2048,0,1,0,2048,0,0,3913,523 MSa/s,3974,515 MSa/s,13,1,79288,5490 +fft_ifft_dit_1ch,cint16,cint16,16,1,1,0,16,0,0,81,197 MSa/s,117,136 MSa/s,8,1,10936,1796 +fft_ifft_dit_1ch,cfloat,cfloat,256,1,3,1,256,0,0,564,453 MSa/s,1076,237 MSa/s,15,3,44584,5738 3796 3562 +fft_ifft_dit_1ch,cfloat,cfloat,256,1,3,0,256,0,0,633,404 MSa/s,1070,239 MSa/s,14,3,44328,3160 2296 2028 +fft_ifft_dit_1ch,cfloat,cfloat,256,1,2,1,256,0,0,652,392 MSa/s,1065,240 MSa/s,10,2,31792,4916 5738 +fft_ifft_dit_1ch,cfloat,cfloat,256,1,2,0,256,0,0,802,319 MSa/s,1155,221 MSa/s,10,2,31600,3160 3020 +fft_ifft_dit_1ch,cfloat,cfloat,256,1,2,0,1024,0,0,2935,348 MSa/s,3021,338 MSa/s,12,2,68464,3278 3248 fft_ifft_dit_1ch,cfloat,cfloat,256,1,1,1,256,0,0,976,262 MSa/s,1142,224 MSa/s,7,1,19000,7862 +fft_ifft_dit_1ch,cfloat,cfloat,256,1,1,1,256,0,0,976,262 MSa/s,1024,250 MSa/s,7,1,19000,7862 fft_ifft_dit_1ch,cfloat,cfloat,256,1,1,0,256,0,0,1306,196 MSa/s,1469,174 MSa/s,7,1,18872,4684 -fft_ifft_dit_1ch,cfloat,cfloat,256,1,1,0,1024,0,0,5225,195 MSa/s,5286,193 MSa/s,7,1,43448,4956 +fft_ifft_dit_1ch,cfloat,cfloat,32,1,1,0,1024,0,0,6297,162 MSa/s,6358,161 MSa/s,7,1,42424,3538 +fft_ifft_dit_1ch,cfloat,cfloat,256,1,1,0,256,0,0,1306,196 MSa/s,1351,189 MSa/s,7,1,18872,4684 fft_ifft_dit_1ch,cfloat,cfloat,16,1,1,0,16,0,0,126,126 MSa/s,168,95 MSa/s,7,1,10168,2344 -fft_ifft_dit_1ch,cfloat,cfloat,128,1,3,1,128,0,0,392,326 MSa/s,754,169 MSa/s,14,3,35368,24 0 24 0 5146 24 1 24 1 3796 25 0 25 0 3562 -fft_ifft_dit_1ch,cfloat,cfloat,128,1,3,0,128,0,0,286,447 MSa/s,571,224 MSa/s,14,3,35112,24 0 24 0 2720 24 1 24 1 2296 25 0 25 0 2028 -fft_ifft_dit_1ch,cfloat,cfloat,128,1,2,1,128,0,0,489,261 MSa/s,771,166 MSa/s,12,2,24624,24 0 24 0 5850 25 0 25 0 4250 -fft_ifft_dit_1ch,cfloat,cfloat,128,1,2,0,128,0,0,371,345 MSa/s,590,216 MSa/s,10,2,24432,24 0 24 0 3144 25 0 25 0 2580 +fft_ifft_dit_1ch,cfloat,cfloat,128,1,3,1,128,0,0,392,326 MSa/s,754,169 MSa/s,14,3,35368,5146 3796 3562 +fft_ifft_dit_1ch,cfloat,cfloat,128,1,3,0,128,0,0,286,447 MSa/s,571,224 MSa/s,14,3,35112,2720 2296 2028 +fft_ifft_dit_1ch,cfloat,cfloat,128,1,2,1,128,0,0,489,261 MSa/s,771,166 MSa/s,12,2,24624,5850 4250 +fft_ifft_dit_1ch,cfloat,cfloat,128,1,2,0,128,0,0,371,345 MSa/s,590,216 MSa/s,10,2,24432,3144 2580 fft_ifft_dit_1ch,cfloat,cfloat,128,1,1,1,128,0,0,770,166 MSa/s,872,146 MSa/s,7,1,13880,7158 +fft_ifft_dit_1ch,cfloat,cfloat,128,1,1,1,128,0,0,721,177 MSa/s,766,167 MSa/s,7,1,13880,7158 fft_ifft_dit_1ch,cfloat,cfloat,128,1,1,0,128,0,0,647,197 MSa/s,746,171 MSa/s,7,1,13752,4204 -fft_ifft_dit_1ch,cfloat,cfloat,32,1,1,1,32,0,0,529,60 MSa/s,573,55 MSa/s,7,1,10808,5600 +fft_ifft_dit_1ch,cfloat,cfloat,256,1,1,0,1024,0,0,5225,195 MSa/s,5286,193 MSa/s,7,1,43448,4956 fft_ifft_dit_1ch,cint32,cint16,64,1,1,0,64,0,0,193,331 MSa/s,231,277 MSa/s,7,1,11704,2972 -fft_ifft_dit_1ch,cfloat,cfloat,32,1,2,0,1024,0,0,3774,271 MSa/s,3863,265 MSa/s,12,2,67440,24 0 24 0 2650 25 0 25 0 2250 -fft_ifft_dit_1ch,cfloat,cfloat,512,1,1,0,512,0,0,2735,187 MSa/s,2786,183 MSa/s,8,1,31160,5068 -fft_ifft_dit_1ch,cint16,cint16,2048,0,1,0,2048,0,0,3913,523 MSa/s,3974,515 MSa/s,13,1,79288,5490 -fft_ifft_dit_1ch,cint16,cint16,16,1,1,0,16,0,0,81,197 MSa/s,117,136 MSa/s,8,1,10936,1796 -fft_ifft_dit_1ch,cint16,cint16,128,1,3,1,128,0,0,274,467 MSa/s,496,258 MSa/s,15,3,34344,24 0 24 0 6716 24 1 24 1 3006 25 0 25 0 2910 -fft_ifft_dit_1ch,cint16,cint16,128,1,3,0,128,0,0,159,805 MSa/s,335,382 MSa/s,15,3,34088,24 0 24 0 2498 24 1 24 1 2082 25 0 25 0 1954 -fft_ifft_dit_1ch,cint16,cint16,128,1,2,1,128,0,0,280,457 MSa/s,475,269 MSa/s,13,2,23600,24 0 24 0 6716 25 0 25 0 4006 -fft_ifft_dit_1ch,cint16,cint16,128,1,2,0,128,0,0,161,795 MSa/s,300,426 MSa/s,12,2,23408,24 0 24 0 2754 25 0 25 0 2498 +fft_ifft_dit_1ch,cfloat,cfloat,32,1,1,0,32,0,0,213,150 MSa/s,255,125 MSa/s,7,1,10680,3268 +fft_ifft_dit_1ch,cfloat,cfloat,32,1,2,0,1024,0,0,3774,271 MSa/s,3863,265 MSa/s,12,2,67440,2650 2250 +fft_ifft_dit_1ch,cint16,cint16,128,1,3,1,128,0,0,274,467 MSa/s,496,258 MSa/s,15,3,34344,6716 3006 2910 +fft_ifft_dit_1ch,cint16,cint16,128,1,3,0,128,0,0,159,805 MSa/s,335,382 MSa/s,15,3,34088,2498 2082 1954 +fft_ifft_dit_1ch,cint16,cint16,128,1,2,1,128,0,0,280,457 MSa/s,475,269 MSa/s,13,2,23600,6716 4006 +fft_ifft_dit_1ch,cint16,cint16,128,1,2,0,128,0,0,161,795 MSa/s,300,426 MSa/s,12,2,23408,2754 2498 fft_ifft_dit_1ch,cint16,cint16,128,1,1,1,128,0,0,498,257 MSa/s,568,225 MSa/s,8,1,12856,10532 fft_ifft_dit_1ch,cint16,cint16,128,1,1,0,128,0,0,291,439 MSa/s,354,361 MSa/s,8,1,12728,3938 -fft_ifft_dit_1ch,cint16,cint16,128,1,1,0,128,1,1,205,624 MSa/s,590,242 MSa/s,14,4,38624,23 0 23 0 3558 24 0 24 0 2134 25 0 25 0 3542 26 0 26 0 2134 +fft_ifft_dit_1ch,cint16,cint16,128,1,1,0,128,0,0,291,439 MSa/s,329,389 MSa/s,8,1,12728,3938 +fft_ifft_dit_1ch,cint16,cint16,128,1,1,0,128,1,1,205,624 MSa/s,592,241 MSa/s,14,4,38624,3618 2210 3618 2210 +fft_ifft_dit_1ch,cfloat,cfloat,32,1,1,1,32,0,0,529,60 MSa/s,573,55 MSa/s,7,1,10808,5600 fft_ifft_dit_1ch,cint16,cint16,128,0,1,0,128,0,0,291,439 MSa/s,329,389 MSa/s,8,1,12728,3938 -fft_ifft_dit_1ch,cint16,cint16,1024,1,1,0,1024,0,0,1790,572 MSa/s,1842,555 MSa/s,10,1,43448,5122 fft_ifft_dit_1ch,cint16,cint16,1024,0,1,0,1024,0,0,1790,572 MSa/s,1842,555 MSa/s,10,1,43448,5122 -fft_ifft_dit_1ch,cfloat,cfloat,64,1,2,0,1024,0,0,3011,340 MSa/s,3101,330 MSa/s,12,2,67440,24 0 24 0 2814 25 0 25 0 2778 +fft_ifft_dit_1ch,cfloat,cfloat,64,1,2,0,1024,0,0,3011,340 MSa/s,3099,330 MSa/s,12,2,67440,2814 2762 fft_ifft_dit_1ch,cfloat,cfloat,64,1,1,1,64,0,0,581,110 MSa/s,625,102 MSa/s,7,1,11832,6416 fft_ifft_dit_1ch,cfloat,cfloat,64,1,1,0,64,0,0,347,184 MSa/s,389,164 MSa/s,7,1,11704,3836 fft_ifft_dit_1ch,cfloat,cfloat,64,1,1,0,1024,0,0,5453,187 MSa/s,5514,185 MSa/s,7,1,42424,4132 -fft_ifft_dit_1ch,cfloat,cfloat,512,1,2,0,1024,0,0,2804,365 MSa/s,2894,353 MSa/s,14,2,72560,24 0 24 0 3264 25 0 25 0 3724 +fft_ifft_dit_1ch,cfloat,cfloat,512,1,2,0,1024,0,0,2804,365 MSa/s,2894,353 MSa/s,14,2,72560,3264 3724 +fft_ifft_dit_1ch,cfloat,cfloat,512,1,1,0,512,0,0,2735,187 MSa/s,2786,183 MSa/s,8,1,31160,5068 fft_ifft_dit_1ch,cfloat,cfloat,512,1,1,0,1024,0,0,5495,186 MSa/s,5556,184 MSa/s,8,1,47544,5464 +fft_ifft_dit_1ch,cint16,cint16,1024,1,1,0,1024,0,0,1790,572 MSa/s,1842,555 MSa/s,10,1,43448,5122 fft_ifft_dit_1ch,cint32,cint16,64,1,1,1,64,0,0,442,144 MSa/s,486,131 MSa/s,7,1,11832,7216 diff --git a/dsp/docs/src/user_guide/L1.rst b/dsp/docs/src/user_guide/L1.rst index 82c15ce20c..2f161022bd 100755 --- a/dsp/docs/src/user_guide/L1.rst +++ b/dsp/docs/src/user_guide/L1.rst @@ -283,7 +283,7 @@ The Vitis 1-D SSR FFT L1 module can be used in a C++ HLS design by: 4- Define fft parameter structure say call it ``params_fix`` by extending ``ssr_fft_default_params`` like :ref:`Defining 1-D SSR FFT Parameter Structure ` -5- call ``fft(input_array,output_array)`` +5- call ``fft(input_stream,output_stream)`` The following section gives usage examples and explains some other interface level details for use in C++ based HLS design. @@ -329,7 +329,7 @@ To use the 1-D SSR FFT L1 module: // IID: is a constant giving instance ID -where inD and outD are 2-dimensional complex arrays of ap_fixed, float or double type, +where inD and outD are 1-dimensional hls::stream of complex of ap_fixed, float or double type, synthesis and simulation use is already explained in the previous table. The I/O arrays can be declared as follows: @@ -352,7 +352,7 @@ The Vitis 1-D SSR FFT L1 module can be used in a C++ HLS design by: 4- Define fft parameter structure lets say call it ``params_float`` by extending ``ssr_fft_default_params`` like :ref:`Defining 1-D SSR FFT Parameter Structure ` -5- call ``fft(input_array,output_array)`` +5- call ``fft(input_stream,output_stream)`` The following section gives usage examples and explains some other interface level details for use in C++ based HLS design. @@ -394,7 +394,7 @@ To use the 1-D SSR FFT L1 module: // IID: is a constant giving instance ID -where inD and outD are 2-dimensional complex arrays of ap_fixed, float or double type, +where inD and outD are 1-dimensional hls::stream complex of ap_fixed, float or double type, synthesis and simulation use is already explained in the previous table. The I/O arrays can be declared as follows: @@ -423,9 +423,9 @@ For float types the output type calculation will return the same type as input. I_TYPE inD[SSR_FFT_R][SSR_FFT_L/SSR_FFT_R]; O_TYPE outD[SSR_FFT_R][SSR_FFT_L/SSR_FFT_R]; -1-D SSR FFT Input Array Reading and Writing Considerations +1-D SSR FFT Input Stream Reading and Writing Considerations ---------------------------------------------------------- -After synthesis, 1-D SSR FFT HLS IP maps to a processing block with buffer interface at both the input +After synthesis, 1-D SSR FFT HLS IP maps to a processing block with stream interface at both the input and output. If user requires a streaming 1-D SSR FFT block with FIFO interface at both the input and output, as shown in the following figure: @@ -435,24 +435,6 @@ If user requires a streaming 1-D SSR FFT block with FIFO interface at both the i :width: 40% :align: center -They should skip the wrapper **fft** with the buffer-to-stream transformation blocks named array2Stream and stream2Array, -and directly call the **innerFFT** function in **FFTWrapper** struct. -If input and output arrays are declared as the following: - -.. code-block:: cpp - - I_TYPE inD[R][L/R]; - O_TYPE outD[R][L/R]; - -The dimensions with size L/R will be mapped to time and dimension with size R mapped to one -stream which is R-wide. This mapping places some constraints on how these arrays can be read -and written to by consumers and producers while writing C++ design using 1-D SSR FFT. These -constraints stem from the physical mapping of array dimensions to time and parallel wide-accesses. - -All of these constraints will be well handled by **array2Stream** and **stream2Array** blocks, -user could ignore those details by calling the wrapper with buffer interface instead of the internal streaming block **innerFFT**. -If the streaming block is required, the read and write on **innerFFT** can be performed as follows: - 1. Declares the input and output streams explicitly with corresponding stream depth: .. code-block:: cpp @@ -485,33 +467,14 @@ If the streaming block is required, the read and write on **innerFFT** can be pe 3. If the 1-D SSR FFT IP is facing another HLS IP in the input chain or output chain, the inner loop doing reading and writing should be unrolled. -1-D SSR FFT Usage in Dataflow Region, Streaming/Non-Streaming Connections -------------------------------------------------------------------------- +1-D SSR FFT Usage in Dataflow Region Streaming +------------------------------------------------ 1-D SSR FFT internally relies heavily on HLS dataflow optimization. The potential use case for 1-D SSR FFT could interconnect with an SSR FFT input or output in two ways: -• Streaming Connection -• Non-Streaming Connections - Streaming Connection ^^^^^^^^^^^^^^^^^^^^ -In the case of a streaming connection at the input, the scenario should look as follows: - -.. code-block:: cpp - - #pragma HLS DATAFLOW - in_dummy_proc (..., fft_in); - innerFFT(fft_in, fft_out); - out_dummy_proc(fft_out, ....) - ... - ... - ... - -The constraint for input producer is that it should produce an array of stream. The constraint for output consumers is that it should consume an array of stream. These constraints are also described in previous sections. - -Non-Streaming Connection -^^^^^^^^^^^^^^^^^^^^^^^^ -The current version of the 1-D SSR FFT naturally support non-streaming connection at the output and input. +The current version of the 1-D SSR FFT naturally support streaming connection at the output and input. .. code-block:: cpp @@ -522,254 +485,6 @@ The current version of the 1-D SSR FFT naturally support non-streaming connectio fft(inD, outD); // IID: is a constant giving instance ID -1-D FFT Examples -========================= -The following sections provides brief details of examples provided for 1-D SSR FFT. - -1-D Fixed Point SSR FFT Example ----------------------------------------------------------- -The example below follows the sequence of steps described in previous sections to do a transform on impulse signal. The listing give below ``data_path.hpp`` describes the datapath, by defining size, SSR, data-path bit-widths, scaling mode, out order etc. It also includes top level library interface header ``vt_fft.hpp`` which gives to ``fft`` function defined in namespace ``xf::dsp::fft`` - - -.. code-block:: cpp - - - #ifndef _DATA_PATH_H_ - #define _DATA_PATH_H_ - #include - #include - #include "vt_fft.hpp" - using namespace xf::dsp::fft; - - // Define FFT Size and Super Sample Rate - #define FFT_LEN 16 - #define SSR 4 - // Define fixed point input/output bit-widths - #define IN_WL 16 - #define IN_IL 2 - #define TW_WL 16 - #define TW_IL 2 - - //Define FFT instane ID, every instance created should have unique ID - #define IID 0 - - typedef std::complex > T_in; - - /* Define parameter structure for SSR FFT that defines - * holds , size, SSR, scaling mode, output order sin/cos - * bit resoulation for storage*/ - struct fftParams : ssr_fft_default_params { - static const int N = FFT_LEN; - static const int R = SSR; - static const scaling_mode_enum scaling_mode = SSR_FFT_NO_SCALING; - static const fft_output_order_enum output_data_order = SSR_FFT_NATURAL; - static const int twiddle_table_word_length = TW_WL; - static const int twiddle_table_intger_part_length = TW_IL; - }; - // Using type traits calculate the output type given FFT param struct - // and the input type - typedef ssr_fft_output_type::t_ssr_fft_out T_out; - - #endif // _DATA_PATH_H_ - -The listing ``top_module.hpp`` and ``top_module.cpp`` declare and define top level module. The top level function here is very simple it only wraps the core SSR FFT function call in a top level wrapper called ``fft_top`` - -.. code-block:: cpp - - #include "data_path.hpp" - #include - - void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]); - -.. code-block:: cpp - - #include "top_module.hpp" - #include "data_path.hpp" - - void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]) { - xf::dsp::fft::fft(p_inData, p_outData); - } - -The listing below gives main funtion that generates impulse data for SSR FFT input in a 2-dimensional array which is SSRx(Size/SRR) and feeds it to top level which produces a 2-dimensional output array of same dimensions. The impulse input produces a step which is verified and test declared as passed. - -.. code-block:: cpp - - #include "top_module.hpp" - #include - - int main(int argc, char** argv) { - T_in inData[SSR][FFT_LEN / SSR]; - T_out outData[SSR][FFT_LEN / SSR]; - for (int r = 0; r < SSR; ++r) { - for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (r == 0 && t == 0) - inData[r][t] = 1; - else - inData[r][t] = 0; - } - } - for (int t = 0; t < 4; ++t) { - // Added Dummy loop iterations - // to make II measurable in cosim - fft_top(inData, outData); - } - int errs = 0; - for (int r = 0; r < SSR; ++r) { - for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (outData[r][t].real() != 1 || outData[r][t].imag() != 0) errs++; - } - } - std::cout << "===============================================================" << std::endl; - std::cout << "--Input Impulse:" << std::endl; - for (int r = 0; r < SSR; ++r) { - for (int t = 0; t < FFT_LEN / SSR; ++t) { - std::cout << inData[r][t] << std::endl; - } - } - std::cout << "===============================================================" << std::endl; - - std::cout << "===============================================================" << std::endl; - std::cout << "--Output Step fuction:" << std::endl; - for (int r = 0; r < SSR; ++r) { - for (int t = 0; t < FFT_LEN / SSR; ++t) { - std::cout << outData[r][t] << std::endl; - } - } - std::cout << "===============================================================" << std::endl; - - return errs; - } - -Compiling and Building Example HLS Project -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Before compiling and running the example it is required to setup the path to HLS compiler which can be done as follows: -change the setting of environment variable **TA_PATH** to point to the installation path of your Vitis, and run following command to set up the environment. - -.. code-block:: bash - - export XILINX_VITIS=${TA_PATH}/Vitis/2021.1 - export XILINX_VIVADO=${TA_PATH}/Vivado/2021.1 - source ${XILINX_VIVADO}/settings64.sh - -The example discussed above is also provided as an example and available at the following path : ``REPO_PATH/dsp/L1/examples/1Dfix_impluse`` it can be simulated, synthesized or co-simulated as follows: -Simply go to the directory ``REPO_PATH/dsp/L1/examples/1Dfix_impluse`` and simulate, build and co-simulate project using : ``make run XPART='xcu200-fsgd2104-2-e' CSIM=1 CSYNTH=1 COSIM=1`` you can choose the part number as required and by settting CSIM/CSYNTH/COSIM=0 choose what to build and run with make target. - - - -1-D Floating Point SSR FFT Example ----------------------------------------------------------- -The use of floating point SSR FFT is very similar to fixed point SSR FFT the following listing ``data_path.hpp`` gives parameter struct -which is simple as compared to fixed point since data-path constants scaling type, input bit-widths etc are not required for floatig point case. -It essentially requires declaration of Size and SSR factor and output data order by default is set to natural order, if required it can be changed to digital reversed transposed. - -.. code-block:: cpp - - #ifndef _DATA_PATH_H_ - #define _DATA_PATH_H_ - - #include - #include - #include "vt_fft.hpp" - using namespace xf::dsp::fft; - - // Define FFT Size and Super Sample Rate - #define FFT_LEN 16 - #define SSR 4 - - typedef complex_wrapper T_in; - #define IID 0 - - // Define parameter structure for SSR FFT - struct fftParams : ssr_fft_default_params { - static const int N = FFT_LEN; - static const int R = SSR; - }; - - // typedef ssr_fft_output_type::t_ssr_fft_out T_out; - typedef T_in T_out; - - #endif // _DATA_PATH_H_ - -The following two listings ``top_moduel.hpp`` and ``top_module.cpp`` give top level module decleration and definition only. - -.. code-block:: cpp - - #include "data_path.hpp" - #include - - void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]); - -.. code-block:: cpp - - #include "top_module.hpp" - #include "data_path.hpp" - - void fft_top(T_in p_inData[SSR][FFT_LEN / SSR], T_out p_outData[SSR][FFT_LEN / SSR]) { - xf::dsp::fft::fft(p_inData, p_outData); - } - -The listing below ``main.cpp`` gives main function which creates an impulse input and verfies if the correct output is produced. The only significant change w.r.t to fixed point is the data type declaration and the param struct otherwise this example is very the same like the use of fixed point SSR FFT. - -.. code-block:: cpp - - #include "top_module.hpp" - #include - int main(int argc, char** argv) { - T_in inData[SSR][FFT_LEN / SSR]; - T_out outData[SSR][FFT_LEN / SSR]; - for (int r = 0; r < SSR; ++r) { - for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (r == 0 && t == 0) - inData[r][t] = 1; - else - inData[r][t] = 0; - } - } - for (int t = 0; t < 4; ++t) { - // Added Dummy loop iterations - // to make II measurable in cosim - fft_top(inData, outData); - } - int errs = 0; - for (int r = 0; r < SSR; ++r) { - for (int t = 0; t < FFT_LEN / SSR; ++t) { - if (outData[r][t].real() != 1 || outData[r][t].imag() != 0) errs++; - } - } - std::cout << "===============================================================" << std::endl; - std::cout << "--Input Impulse:" << std::endl; - for (int r = 0; r < SSR; ++r) { - for (int t = 0; t < FFT_LEN / SSR; ++t) { - std::cout << inData[r][t] << std::endl; - } - } - std::cout << "===============================================================" << std::endl; - - std::cout << "===============================================================" << std::endl; - std::cout << "--Output Step fuction:" << std::endl; - for (int r = 0; r < SSR; ++r) { - for (int t = 0; t < FFT_LEN / SSR; ++t) { - std::cout << outData[r][t] << std::endl; - } - } - std::cout << "===============================================================" << std::endl; - - return errs; - } - -Compiling and Building Example HLS Project -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Before compiling and running the example it is required to setup the path to HLS compiler which can be done as follows: -change the setting of environment variable **TA_PATH** to point to the installation path of your Vitis, and run following command to set up the environment. - -.. code-block:: bash - - export XILINX_VITIS=${TA_PATH}/Vitis/2021.1 - export XILINX_VIVADO=${TA_PATH}/Vivado/2021.1 - source ${XILINX_VIVADO}/settings64.sh - -The example discussed above is also provided as an example and available at the following path : ``REPO_PATH/dsp/L1/examples/1Dfloat_impluse`` it can be simulated, synthesized or co-simulated as follows: -Simply go to the directory ``REPO_PATH/dsp/L1/examples/1Dfloat_impluse`` and simulate, build and co-simulate project using : ``make run XPART='xcu200-fsgd2104-2-e' CSIM=1 CSYNTH=1 COSIM=1`` you can choose the part number as required and by settting CSIM/CSYNTH/COSIM=0 choose what to build and run with make target 1-D SSR FFT Tests ---------------------------------------------------------- diff --git a/graph/Jenkinsfile b/graph/Jenkinsfile index 16d8f77cca..3be6ce8eba 100644 --- a/graph/Jenkinsfile +++ b/graph/Jenkinsfile @@ -1,4 +1,4 @@ @Library('pipeline-library')_ -VitisLibPipeline (branch: 'next', libname: 'xf_graph', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', - upstream_dependencies: 'xf_utils_hw,next,../utils; xf_database,next,../database; xf_fintech,next,../quantitative_finance', - email: 'shengl@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_stable_latest') +VitisLibPipeline (branch: 'master', libname: 'xf_graph', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', + upstream_dependencies: 'xf_utils_hw,master,../utils; xf_database,master,../database; xf_fintech,master,../quantitative_finance', + email: 'shengl@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_released') diff --git a/graph/L2/benchmarks/louvain_fast/Makefile b/graph/L2/benchmarks/louvain_fast/Makefile index 398d1d3eaf..f451dfaa14 100644 --- a/graph/L2/benchmarks/louvain_fast/Makefile +++ b/graph/L2/benchmarks/louvain_fast/Makefile @@ -55,8 +55,12 @@ endif # #################### Checking if DEVICE in whitelist ############################ ifneq ($(findstring u50, $(DEVICE)), u50) +ifneq ($(findstring u280, $(DEVICE)), u280) +ifneq ($(findstring u55c, $(DEVICE)), u55c) $(warning [WARNING]: This project has not been tested for $(DEVICE). It may or may not work.) endif +endif +endif # ######################## Setting up Project Variables ################################# MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) @@ -119,22 +123,22 @@ endif # ######################### Host compiler global settings ############################ CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++11 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -pthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE -CXXFLAGS += -fmessage-length=0 -O3 -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD +LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE +CXXFLAGS += -fmessage-length=0 -O3 -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD -B/usr/lib/x86_64-linux-gnu CXXFLAGS += -I$(CUR_DIR)/src/ ifeq ($(HOST_ARCH), x86) LDFLAGS += -L$(XILINX_HLS)/lnx64/tools/fpo_v7_0 -Wl,--as-needed -lgmp -lmpfr -lIp_floating_point_v7_0_bitacc_cmodel endif -ifneq (,$(shell echo $(XPLATFORM) | awk '/u50/')) -CXXFLAGS += -D USE_HBM +ifneq (,$(shell echo $(XPLATFORM) | awk '/u55c/')) +CXXFLAGS += -D USE_U55C endif # ################### Setting package and image directory ####################### EXE_NAME := host.exe EXE_FILE := $(BUILD_DIR)/$(EXE_NAME) -HOST_ARGS := -x $(BUILD_DIR)/kernel_louvain.xclbin -f 3 -c -m 10 -prun $(CUR_DIR)/data/example-wt.txt +HOST_ARGS := -x $(BUILD_DIR)/kernel_louvain.xclbin -f 3 -c -m 10000 $(CUR_DIR)/data/example-wt.txt -prun LIBRARY_PATH =$(LD_LIBRARY_PATH):$(XILINX_XRT)/lib # ##################### Kernel compiler global settings ########################## @@ -142,7 +146,15 @@ VPP_FLAGS += -t $(TARGET) --platform $(XPLATFORM) --save-temps --optimize 2 VPP_FLAGS += --hls.jobs 8 VPP_LDFLAGS += --vivado.synth.jobs 8 --vivado.impl.jobs 8 ifneq (,$(shell echo $(XPLATFORM) | awk '/u50/')) -VPP_FLAGS += --config $(CUR_DIR)/conn_u50_u280.cfg +VPP_FLAGS += --config $(CUR_DIR)/conn_u50_u280.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=$(CUR_DIR)/postSysLink.tcl +endif + +ifneq (,$(shell echo $(XPLATFORM) | awk '/u280/')) +VPP_FLAGS += --config $(CUR_DIR)/conn_u50_u280.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=$(CUR_DIR)/postSysLink.tcl +endif + +ifneq (,$(shell echo $(XPLATFORM) | awk '/u55c/')) +VPP_FLAGS += --config $(CUR_DIR)/conn_u55c.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=$(CUR_DIR)/postSysLink.tcl endif VPP_FLAGS += -I$(XFLIB_DIR)/L2/include @@ -156,8 +168,8 @@ VPP_FLAGS += -I$(XFLIB_DIR)/../utils/L1/include VPP_FLAGS += -I$(XFLIB_DIR)/L2/benchmarks/louvain_fast/kernel kernel_louvain_VPP_FLAGS += -D KERNEL_NAME=kernel_louvain -kernel_louvain_VPP_FLAGS += --hls.clock 300000000:kernel_louvain -VPP_LDFLAGS_kernel_louvain += --kernel_frequency 300 +kernel_louvain_VPP_FLAGS += --hls.clock 250000000:kernel_louvain +VPP_LDFLAGS_kernel_louvain += --kernel_frequency 250 # Kernel args diff --git a/graph/L2/benchmarks/louvain_fast/conn_u50_u280.cfg b/graph/L2/benchmarks/louvain_fast/conn_u50_u280.cfg index d74678fb78..df61ca1fd3 100644 --- a/graph/L2/benchmarks/louvain_fast/conn_u50_u280.cfg +++ b/graph/L2/benchmarks/louvain_fast/conn_u50_u280.cfg @@ -2,20 +2,26 @@ sp=kernel_louvain.m_axi_gmem0:HBM[4] sp=kernel_louvain.m_axi_gmem1:HBM[0:1] sp=kernel_louvain.m_axi_gmem2:HBM[2:3] -sp=kernel_louvain.m_axi_gmem3:HBM[6] -sp=kernel_louvain.m_axi_gmem4:HBM[8] -sp=kernel_louvain.m_axi_gmem5:HBM[10] -sp=kernel_louvain.m_axi_gmem6:HBM[12] -sp=kernel_louvain.m_axi_gmem7:HBM[14] -sp=kernel_louvain.m_axi_gmem8:HBM[16] -sp=kernel_louvain.m_axi_gmem9:HBM[18] -sp=kernel_louvain.m_axi_gmem10:HBM[20] -sp=kernel_louvain.m_axi_gmem11:HBM[22] -sp=kernel_louvain.m_axi_gmem12:HBM[24] -sp=kernel_louvain.m_axi_gmem13:HBM[26] -sp=kernel_louvain.m_axi_gmem14:HBM[27] -sp=kernel_louvain.m_axi_gmem15:HBM[28:29] -sp=kernel_louvain.m_axi_gmem16:HBM[7] -sp=kernel_louvain.m_axi_gmem17:HBM[9] +sp=kernel_louvain.m_axi_gmem3:HBM[5:6] +sp=kernel_louvain.m_axi_gmem4:HBM[5:6] +sp=kernel_louvain.m_axi_gmem5:HBM[7] +sp=kernel_louvain.m_axi_gmem6:HBM[8] +sp=kernel_louvain.m_axi_gmem7:HBM[9] +sp=kernel_louvain.m_axi_gmem8:HBM[10] +sp=kernel_louvain.m_axi_gmem9:HBM[11] +sp=kernel_louvain.m_axi_gmem10:HBM[12] +sp=kernel_louvain.m_axi_gmem11:HBM[13] +sp=kernel_louvain.m_axi_gmem12:HBM[14] +sp=kernel_louvain.m_axi_gmem13:HBM[15] +sp=kernel_louvain.m_axi_gmem14:HBM[4] +sp=kernel_louvain.m_axi_gmem15:HBM[0:1] slr=kernel_louvain:SLR0 nk=kernel_louvain:1:kernel_louvain +[vivado] +prop=run.impl_1.STEPS.OPT_DESIGN.ARGS.DIRECTIVE=Explore +prop=run.impl_1.STEPS.PLACE_DESIGN.ARGS.DIRECTIVE=ExtraNetDelay_low +prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.IS_ENABLED=true +prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.ARGS.DIRECTIVE=AggressiveExplore +prop=run.impl_1.STEPS.ROUTE_DESIGN.ARGS.DIRECTIVE=NoTimingRelaxation +prop=run.impl_1.{STEPS.ROUTE_DESIGN.ARGS.MORE OPTIONS}={-tns_cleanup} +prop=run.impl_1.STEPS.POST_ROUTE_PHYS_OPT_DESIGN.IS_ENABLED=true diff --git a/graph/L2/benchmarks/louvain_fast/conn_u55c.cfg b/graph/L2/benchmarks/louvain_fast/conn_u55c.cfg new file mode 100644 index 0000000000..3c2784aaaa --- /dev/null +++ b/graph/L2/benchmarks/louvain_fast/conn_u55c.cfg @@ -0,0 +1,43 @@ +[connectivity] +sp=kernel_louvain_0.m_axi_gmem0:HBM[4] +sp=kernel_louvain_0.m_axi_gmem1:HBM[0:1] +sp=kernel_louvain_0.m_axi_gmem2:HBM[2:3] +sp=kernel_louvain_0.m_axi_gmem3:HBM[5:6] +sp=kernel_louvain_0.m_axi_gmem4:HBM[5:6] +sp=kernel_louvain_0.m_axi_gmem5:HBM[7] +sp=kernel_louvain_0.m_axi_gmem6:HBM[8] +sp=kernel_louvain_0.m_axi_gmem7:HBM[9] +sp=kernel_louvain_0.m_axi_gmem8:HBM[10] +sp=kernel_louvain_0.m_axi_gmem9:HBM[11] +sp=kernel_louvain_0.m_axi_gmem10:HBM[12] +sp=kernel_louvain_0.m_axi_gmem11:HBM[13] +sp=kernel_louvain_0.m_axi_gmem12:HBM[14] +sp=kernel_louvain_0.m_axi_gmem13:HBM[15] +sp=kernel_louvain_0.m_axi_gmem14:HBM[4] +sp=kernel_louvain_0.m_axi_gmem15:HBM[0:1] + +sp=kernel_louvain_1.m_axi_gmem0:HBM[20] +sp=kernel_louvain_1.m_axi_gmem1:HBM[16:17] +sp=kernel_louvain_1.m_axi_gmem2:HBM[18:19] +sp=kernel_louvain_1.m_axi_gmem3:HBM[21:22] +sp=kernel_louvain_1.m_axi_gmem4:HBM[21:22] +sp=kernel_louvain_1.m_axi_gmem5:HBM[23] +sp=kernel_louvain_1.m_axi_gmem6:HBM[24] +sp=kernel_louvain_1.m_axi_gmem7:HBM[25] +sp=kernel_louvain_1.m_axi_gmem8:HBM[26] +sp=kernel_louvain_1.m_axi_gmem9:HBM[27] +sp=kernel_louvain_1.m_axi_gmem10:HBM[28] +sp=kernel_louvain_1.m_axi_gmem11:HBM[29] +sp=kernel_louvain_1.m_axi_gmem12:HBM[30] +sp=kernel_louvain_1.m_axi_gmem13:HBM[31] +sp=kernel_louvain_1.m_axi_gmem14:HBM[20] +sp=kernel_louvain_1.m_axi_gmem15:HBM[16:17] +nk=kernel_louvain:2:kernel_louvain_0.kernel_louvain_1 +[vivado] +prop=run.impl_1.STEPS.OPT_DESIGN.ARGS.DIRECTIVE=Explore +prop=run.impl_1.STEPS.PLACE_DESIGN.ARGS.DIRECTIVE=ExtraNetDelay_low +prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.IS_ENABLED=true +prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.ARGS.DIRECTIVE=AggressiveExplore +prop=run.impl_1.STEPS.ROUTE_DESIGN.ARGS.DIRECTIVE=NoTimingRelaxation +prop=run.impl_1.{STEPS.ROUTE_DESIGN.ARGS.MORE OPTIONS}={-tns_cleanup} +prop=run.impl_1.STEPS.POST_ROUTE_PHYS_OPT_DESIGN.IS_ENABLED=true diff --git a/graph/L2/benchmarks/louvain_fast/description.json b/graph/L2/benchmarks/louvain_fast/description.json index 2109c838f1..3cae59c9ec 100644 --- a/graph/L2/benchmarks/louvain_fast/description.json +++ b/graph/L2/benchmarks/louvain_fast/description.json @@ -4,24 +4,44 @@ "description": "The Louvain method for community detection is a method to extract communities from large networks created by Blondel from the University of Louvain (the source of this method's name). The method is a greedy optimization method that appears to run in time O(n cdot log n), if n is the number of nodes in the network", "flow": "vitis", "platform_whitelist": [ - "u50" + "u50", + "u280", + "u55c" ], "platform_blacklist": [ "zc" ], "platform_properties": { "u50": { + "v++": { + "compiler": { + "cflags": [ + "--config PROJECT/conn_u50_u280.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=PROJECT/postSysLink.tcl" + ] + } + } + }, + "u280": { + "v++": { + "compiler": { + "cflags": [ + "--config PROJECT/conn_u50_u280.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=PROJECT/postSysLink.tcl" + ] + } + } + }, + "u55c": { "host": { "compiler": { "symbols": [ - "USE_HBM" + "USE_U55C" ] } }, "v++": { "compiler": { "cflags": [ - "--config PROJECT/conn_u50_u280.cfg" + "--config PROJECT/conn_u55c.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=PROJECT/postSysLink.tcl" ] } } @@ -32,16 +52,16 @@ ], "launch": [ { - "cmd_args": " -x BUILD/kernel_louvain.xclbin -f 3 -c -m 10 -prun PROJECT/data/example-wt.txt", + "cmd_args": " -x BUILD/kernel_louvain.xclbin -f 3 -c -m 10000 PROJECT/data/example-wt.txt -prun", "name": "generic launch for all flows", "ld_library_path": [ - "$(LD_LIBRARY_PATH)", - "$(XILINX_XRT)/lib" - ] + "$(LD_LIBRARY_PATH)", + "$(XILINX_XRT)/lib" + ] } ], "host": { - "host_exe": "host.exe", + "host_exe": "host.exe", "linker": { "options": "-lgomp" }, @@ -75,7 +95,7 @@ "LIB_DIR/../utils/L1/include", "LIB_DIR/ext/xcl2" ], - "options": "-O3 -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD" + "options": "-O3 -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD -B/usr/lib/x86_64-linux-gnu" } }, "v++": { @@ -93,7 +113,7 @@ "accelerators": [ { "location": "LIB_DIR/L2/benchmarks/louvain_fast/kernel/kernel_louvain.cpp", - "frequency": 300.0, + "frequency": 250.0, "clflags": " -D KERNEL_NAME=kernel_louvain", "name": "kernel_louvain", "num_compute_units": 1, @@ -116,70 +136,62 @@ }, { "name": "m_axi_gmem3", - "memory": "HBM[6]" + "memory": "HBM[5:6]" }, { "name": "m_axi_gmem4", - "memory": "HBM[8]" + "memory": "HBM[5:6]" }, { "name": "m_axi_gmem5", - "memory": "HBM[10]" + "memory": "HBM[7]" }, { "name": "m_axi_gmem6", - "memory": "HBM[12]" + "memory": "HBM[8]" }, { "name": "m_axi_gmem7", - "memory": "HBM[14]" + "memory": "HBM[9]" }, { "name": "m_axi_gmem8", - "memory": "HBM[16]" + "memory": "HBM[10]" }, { "name": "m_axi_gmem9", - "memory": "HBM[18]" + "memory": "HBM[11]" }, { "name": "m_axi_gmem10", - "memory": "HBM[20]" + "memory": "HBM[12]" }, { "name": "m_axi_gmem11", - "memory": "HBM[22]" + "memory": "HBM[13]" }, { "name": "m_axi_gmem12", - "memory": "HBM[24]" + "memory": "HBM[14]" }, { "name": "m_axi_gmem13", - "memory": "HBM[26]" + "memory": "HBM[15]" }, { "name": "m_axi_gmem14", - "memory": "HBM[27]" + "memory": "HBM[4]" }, { "name": "m_axi_gmem15", - "memory": "HBM[28:29]" - }, - { - "name": "m_axi_gmem16", - "memory": "HBM[7]" - }, - { - "name": "m_axi_gmem17", - "memory": "HBM[9]" + "memory": "HBM[0:1]" } ] } ] } ], - "frequency": 300.0, + "frequency": 250.0, "name": "kernel_louvain" } ], diff --git a/graph/L2/benchmarks/louvain_fast/host/driverForGraphClustering.cpp b/graph/L2/benchmarks/louvain_fast/host/driverForGraphClustering.cpp index 789ae01ddb..3285bd553a 100644 --- a/graph/L2/benchmarks/louvain_fast/host/driverForGraphClustering.cpp +++ b/graph/L2/benchmarks/louvain_fast/host/driverForGraphClustering.cpp @@ -68,51 +68,51 @@ int xai_close(xaiHandle xaiInstance) { return 0; } -int xai_louvain_main(int argc, char** argv) { - std::cout << "called xai_louvain_main, argc: " << argc << "argv 1: " << argv[1] << std::flush; - //Parse Input parameters: - double opts_C_thresh; //Threshold with coloring on - long opts_minGraphSize; //Min |V| to enable coloring - double opts_threshold; //Value of threshold - int opts_ftype; //File type - char opts_inFile[4096]; - bool opts_coloring; - bool opts_output; - bool opts_VF; - char opts_xclbinPath[4096]; - - host_ParserParameters(argc, argv, - opts_C_thresh, //double opts_C_thresh; //Threshold with coloring on - opts_minGraphSize,//long opts_minGraphSize; //Min |V| to enable coloring - opts_threshold, //double opts_threshold; //Value of threshold - opts_ftype, //int opts_ftype; //File type - opts_inFile, //char opts_inFile[4096]; - opts_coloring, //bool opts_coloring; - opts_output, //bool opts_output; - opts_VF, //bool opts_VF; - opts_xclbinPath); - int numThreads = NUMTHREAD; // using fixed number of thread instead of omp_get_num_threads(); - //Parse the graphNew in Matrix Market format - graphNew* G = host_PrepareGraph( opts_ftype, opts_inFile, opts_VF); - //Datastructures to store clustering information - long NV_begin = G->numVertices; - long *C_orig = (long *) malloc (NV_begin * sizeof(long)); assert(C_orig != 0); - #pragma omp parallel for - for (long i=0; inumVertices; +// long *C_orig = (long *) malloc (NV_begin * sizeof(long)); assert(C_orig != 0); +// #pragma omp parallel for +// for (long i=0; i +#include #include "xilinxlouvain.hpp" #include "ParLV.h" //tmp include #include "ctrlLV.h" //tmp include @@ -22,11 +23,18 @@ #include "louvainPhase.h" #include "defs.h" #include "xcl2.hpp" +//#include +//#include #include "string.h" #include "ap_int.h" #include "utils.hpp" #include "xf_utils_sw/logger.hpp" /////////////////////////////////////////////////////////////////////////////////////////////////////////// +// There are 3 flows in this codes +// 1. no ghost flow, for the no partition, no ghost test, designed for 20.2 kernels, rarely used +// 2. support the partition and ghost flow, designed for 20.2 kernels +// 3. support the partition and ghost flow, designed for the kernel after 21.2, faster than the origin kernels (_par +// _prune) void PrintReport_MultiPhase(bool opts_coloring, long opts_minGraphSize, double opts_threshold, @@ -171,20 +179,6 @@ void PhaseLoop_UpdatingC_org(int phase, long NV, long NV_G, long* C, long* C_ori } } -void inline PhaseLoop_Kernel_Enable(cl::Kernel& kernel_louvain, - cl::CommandQueue& q, - std::vector& ob_in, - std::vector& ob_out, - std::vector >& kernel_evt0, - std::vector >& kernel_evt1) { - kernel_evt0[0].resize(1); - kernel_evt1[0].resize(1); - - q.enqueueMigrateMemObjects(ob_in, 0, nullptr, kernel_evt0[0].data()); // 0 : migrate from host to dev - q.enqueueTask(kernel_louvain, &kernel_evt0[0], kernel_evt1[0].data()); - q.enqueueMigrateMemObjects(ob_out, 1, &kernel_evt1[0], nullptr); // 1 : migrate from dev to host - q.finish(); -} long* CreateM(long NV_new, long NV_orig, long* C_orig, long* M_orig) { long* M = (long*)malloc(NV_new * sizeof(long)); assert(M); @@ -195,32 +189,114 @@ long* CreateM(long NV_new, long NV_orig, long* C_orig, long* M_orig) { return M; } -double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, - GLV* pglv_iter, - int numThreads, - double opts_threshold, - bool opts_coloring, - // modified: - bool& nonColor, - int& phase, - int& totItr, - long& numClusters, - double& totTimeBuildingPhase) { +// There are 3 flows in this codes +// 1. no ghost flow, for the no partition, no ghost test, designed for 20.2 kernels, rarely used +// 2. support the partition and ghost flow, designed for 20.2 kernels +// 3. support the partition and ghost flow, designed for the kernel after 21.2, faster than the origin kernels (_par +// _prune) +bool PhaseLoop_CommPostProcessing(long NV, + int numThreads, + double opts_threshold, + bool opts_coloring, + double prevMod, + double currMod, + // modified: + graphNew*& G, + long*& C, + long*& C_orig, + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase) { + double time1 = 0; + time1 = omp_get_wtime(); + graphNew* Gnew; + numClusters = renumberClustersContiguously(C, G->numVertices); + printf("Number of unique clusters: %ld\n", numClusters); + PhaseLoop_UpdatingC_org(phase, NV, G->numVertices, C, C_orig); + + if ((phase > MAX_NUM_PHASE) || (totItr > MAX_NUM_TOTITR)) { + return 1; // Break if too many phases or iterations + } else { + if ((currMod - prevMod) > opts_threshold) { + Gnew = (graphNew*)malloc(sizeof(graphNew)); + assert(Gnew != 0); + double tmpTime = buildNextLevelGraphOpt(G, Gnew, C, numClusters, numThreads); + // totTimeBuildingPhase += tmpTime; + // Free up the previous graphNew + free(G->edgeListPtrs); + free(G->edgeList); + free(G); + G = Gnew; // Swap the pointers + G->edgeListPtrs = Gnew->edgeListPtrs; + G->edgeList = Gnew->edgeList; + // Free up the previous cluster & create new one of a different size + free(C); + C = (long*)malloc(numClusters * sizeof(long)); + assert(C != 0); +#pragma omp parallel for + for (long i = 0; i < numClusters; i++) { + C[i] = -1; + } + phase++; // Increment phase number + } else { // when !((opts_coloring == 1) && (G->numVertices > opts_minGraphSize) && (nonColor == false)) + if ((opts_coloring) && (nonColor == false)) { + nonColor = true; // Run at least one loop of non-coloring routine + } else { + return true; // Modularity gain is not enough. Exit. + } + } + } + time1 = omp_get_wtime() - time1; + totTimeBuildingPhase += time1; + return false; +} + +double PhaseLoop_CommPostProcessing(GLV* pglv_orig, + GLV* pglv_iter, + int numThreads, + double opts_threshold, + bool opts_coloring, + // modified: + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase, + double& time_renum, + double& time_C, + double& time_M, + double& time_buid, + double& time_set) { double time1 = 0; time1 = omp_get_wtime(); + time_renum = time1; graphNew* Gnew; - numClusters = renumberClustersContiguously_ghost(pglv_iter->C, pglv_iter->G->numVertices, pglv_iter->NVl); + // numClusters = renumberClustersContiguously(pglv_iter->C, pglv_iter->G->numVertices); printf("Number of unique clusters: %ld\n", numClusters); + time_renum = omp_get_wtime() - time_renum; + + time_C = omp_get_wtime(); PhaseLoop_UpdatingC_org(phase, pglv_orig->NV, pglv_iter->NV, pglv_iter->C, pglv_orig->C); + time_C = omp_get_wtime() - time_C; - long* M_new = CreateM(numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M); + time_M = 0; // omp_get_wtime(); + // long* M_new = CreateM( numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M ); + // time_M = omp_get_wtime() - time_M; Gnew = (graphNew*)malloc(sizeof(graphNew)); assert(Gnew != 0); double tmpTime = buildNextLevelGraphOpt(pglv_iter->G, Gnew, pglv_iter->C, numClusters, numThreads); totTimeBuildingPhase += tmpTime; - pglv_iter->SetByOhterG(Gnew, M_new); + time_buid = tmpTime; + + time_set = omp_get_wtime(); + pglv_iter->SetByOhterG(Gnew); //, M_new); + time_set = omp_get_wtime() - time_set; + time1 = omp_get_wtime() - time1; + return time1; } @@ -270,110 +346,6 @@ double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, return time1; } -double PhaseLoop_CommPostProcessing(GLV* pglv_orig, - GLV* pglv_iter, - int numThreads, - double opts_threshold, - bool opts_coloring, - // modified: - bool& nonColor, - int& phase, - int& totItr, - long& numClusters, - double& totTimeBuildingPhase, - double& time_renum, - double& time_C, - double& time_M, - double& time_buid, - double& time_set) { - double time1 = 0; - time1 = omp_get_wtime(); - time_renum = time1; - graphNew* Gnew; - // numClusters = renumberClustersContiguously(pglv_iter->C, pglv_iter->G->numVertices); - printf("Number of unique clusters: %ld\n", numClusters); - time_renum = omp_get_wtime() - time_renum; - - time_C = omp_get_wtime(); - PhaseLoop_UpdatingC_org(phase, pglv_orig->NV, pglv_iter->NV, pglv_iter->C, pglv_orig->C); - time_C = omp_get_wtime() - time_C; - - time_M = 0; // omp_get_wtime(); - // long* M_new = CreateM( numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M ); - // time_M = omp_get_wtime() - time_M; - - Gnew = (graphNew*)malloc(sizeof(graphNew)); - assert(Gnew != 0); - double tmpTime = buildNextLevelGraphOpt(pglv_iter->G, Gnew, pglv_iter->C, numClusters, numThreads); - totTimeBuildingPhase += tmpTime; - time_buid = tmpTime; - - time_set = omp_get_wtime(); - pglv_iter->SetByOhterG(Gnew); //, M_new); - time_set = omp_get_wtime() - time_set; - - time1 = omp_get_wtime() - time1; - - return time1; -} -bool PhaseLoop_CommPostProcessing(long NV, - int numThreads, - double opts_threshold, - bool opts_coloring, - double prevMod, - double currMod, - // modified: - graphNew*& G, - long*& C, - long*& C_orig, - bool& nonColor, - int& phase, - int& totItr, - long& numClusters, - double& totTimeBuildingPhase) { - double time1 = 0; - time1 = omp_get_wtime(); - graphNew* Gnew; - numClusters = renumberClustersContiguously(C, G->numVertices); - printf("Number of unique clusters: %ld\n", numClusters); - PhaseLoop_UpdatingC_org(phase, NV, G->numVertices, C, C_orig); - - if ((phase > MAX_NUM_PHASE) || (totItr > MAX_NUM_TOTITR)) { - return 1; // Break if too many phases or iterations - } else { - if ((currMod - prevMod) > opts_threshold) { - Gnew = (graphNew*)malloc(sizeof(graphNew)); - assert(Gnew != 0); - double tmpTime = buildNextLevelGraphOpt(G, Gnew, C, numClusters, numThreads); - // totTimeBuildingPhase += tmpTime; - // Free up the previous graphNew - free(G->edgeListPtrs); - free(G->edgeList); - free(G); - G = Gnew; // Swap the pointers - G->edgeListPtrs = Gnew->edgeListPtrs; - G->edgeList = Gnew->edgeList; - // Free up the previous cluster & create new one of a different size - free(C); - C = (long*)malloc(numClusters * sizeof(long)); - assert(C != 0); -#pragma omp parallel for - for (long i = 0; i < numClusters; i++) { - C[i] = -1; - } - phase++; // Increment phase number - } else { // when !((opts_coloring == 1) && (G->numVertices > opts_minGraphSize) && (nonColor == false)) - if ((opts_coloring) && (nonColor == false)) { - nonColor = true; // Run at least one loop of non-coloring routine - } else { - return true; // Modularity gain is not enough. Exit. - } - } - } - time1 = omp_get_wtime() - time1; - totTimeBuildingPhase += time1; - return false; -} void inline PhaseLoop_MapHostBuff(long NV, long NE_mem_1, @@ -482,257 +454,7 @@ void UsingFPGA_MapHostClBuff( PhaseLoop_MapClBuff(NV, NE_mem_1, NE_mem_2, mext_in, context, buff_cl); } -int PhaseLoop_UsingCPU(double opts_threshold, - int numThreads, - double& currMod, - graphNew*& G, - long*& C, - long*& C_orig, - int& totItr, - bool& nonColor, - double& totTimeClustering) { - double tmpTime; - int tmpItr = 0; - currMod = parallelLouvianMethod(G, C, numThreads, currMod, opts_threshold, &tmpTime, &tmpItr); - totTimeClustering += tmpTime; - totItr += tmpItr; - nonColor = true; - return 0; -} -void PhaseLoop_UsingFPGA_1_KernelSetup(bool isLargeEdge, - cl::Kernel& kernel_louvain, - std::vector& ob_in, - std::vector& ob_out, - KMemorys_clBuff& buff_cl) { - // Data transfer from host buffer to device buffer - ob_in.push_back(buff_cl.db_config0); - ob_in.push_back(buff_cl.db_config1); - ob_in.push_back(buff_cl.db_offsets); - ob_in.push_back(buff_cl.db_indices); - if (isLargeEdge) ob_in.push_back(buff_cl.db_indices2); - ob_in.push_back(buff_cl.db_weights); - if (isLargeEdge) ob_in.push_back(buff_cl.db_weights2); - ob_in.push_back(buff_cl.db_cidCurr); - ob_in.push_back(buff_cl.db_cidSizePrev); - ob_in.push_back(buff_cl.db_cidSizeUpdate); - ob_in.push_back(buff_cl.db_cidSizeCurr); - ob_in.push_back(buff_cl.db_totPrev); - ob_in.push_back(buff_cl.db_totUpdate); - ob_in.push_back(buff_cl.db_totCurr); - ob_in.push_back(buff_cl.db_cWeight); - ob_in.push_back(buff_cl.db_colorAxi); - ob_in.push_back(buff_cl.db_colorInx); - ob_out.push_back(buff_cl.db_config0); - ob_out.push_back(buff_cl.db_config1); - ob_out.push_back(buff_cl.db_cidPrev); - - kernel_louvain.setArg(0, buff_cl.db_config0); // config0 - kernel_louvain.setArg(1, buff_cl.db_config1); // config1 - kernel_louvain.setArg(2, buff_cl.db_offsets); // offsets - kernel_louvain.setArg(3, buff_cl.db_indices); // indices - kernel_louvain.setArg(4, buff_cl.db_weights); // weights - kernel_louvain.setArg(5, buff_cl.db_colorAxi); // colorAxi - kernel_louvain.setArg(6, buff_cl.db_colorInx); // colorInx - kernel_louvain.setArg(7, buff_cl.db_cidPrev); // cidPrev - kernel_louvain.setArg(8, buff_cl.db_cidSizePrev); // cidSizePrev - kernel_louvain.setArg(9, buff_cl.db_totPrev); // totPrev - kernel_louvain.setArg(10, buff_cl.db_cidCurr); // cidCurr - kernel_louvain.setArg(11, buff_cl.db_cidSizeCurr); // cidSizeCurr - kernel_louvain.setArg(12, buff_cl.db_totCurr); // totCurr - kernel_louvain.setArg(13, buff_cl.db_cidSizeUpdate); // cUpdate - kernel_louvain.setArg(14, buff_cl.db_totUpdate); // totCurr - kernel_louvain.setArg(15, buff_cl.db_cWeight); // cWeight - std::cout << "INFO: Finish kernel setup" << std::endl; -} - -void PhaseLoop_UsingFPGA_2_DataWriteTo(cl::CommandQueue& q, - std::vector >& kernel_evt0, - std::vector& ob_in) { /* 0 : migrate from host to dev */ - q.enqueueMigrateMemObjects(ob_in, 0, nullptr, kernel_evt0[0].data()); -} - -void PhaseLoop_UsingFPGA_3_KernelRun(cl::CommandQueue& q, - std::vector >& kernel_evt0, - std::vector >& kernel_evt1, - cl::Kernel& kernel_louvain) { - q.enqueueTask(kernel_louvain, &kernel_evt0[0], kernel_evt1[0].data()); -} - -void PhaseLoop_UsingFPGA_4_DataReadBack(cl::CommandQueue& q, - std::vector >& kernel_evt1, - std::vector& ob_out) { /* kernel_evt1 : migrate from dev to host*/ - q.enqueueMigrateMemObjects(ob_out, 1, &kernel_evt1[0], nullptr); -} - -void PhaseLoop_UsingFPGA_5_KernelFinish(cl::CommandQueue& q) { - q.finish(); -} -void PhaseLoop_UsingFPGA_Post(long vertexNum, - int num_runsFPGA, - KMemorys_host& buff_host, - struct timeval& tstartE2E, - struct timeval& tendE2E, - std::vector >& kernel_evt1, - // output - long* C, - int& totItr, - double& currMod, - int& totTimeE2E) { - // updating - totItr += buff_host.config0[2]; - currMod = buff_host.config1[1]; - for (int i = 0; i < vertexNum; i++) { - C[i] = (long)buff_host.cidPrev[i]; - } - unsigned long timeStart, timeEnd; - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); - int exec_timeE2E = diff(&tendE2E, &tstartE2E); - totTimeE2E += exec_timeE2E; - // showing - unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish kernel execution" << std::endl; - std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish E2E execution" << std::endl; - // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" - printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, - exec_timeE2E, buff_host.config0[2], currMod); - std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" - << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; - std::cout << "-------------------------------------------------------" << std::endl; -} - -void PhaseLoop_UsingFPGA_Post_par(long vertexNum, - int num_runsFPGA, - KMemorys_host& buff_host, - struct timeval& tstartE2E, - struct timeval& tendE2E, - std::vector >& kernel_evt1, - // output - long* C, - int& totItr, - double& currMod, - int& totTimeE2E) { - // updating - totItr += buff_host.config0[2]; - currMod = buff_host.config1[1]; - for (int i = 0; i < vertexNum; i++) { - C[i] = (long)buff_host.cidPrev[i]; - } - unsigned long timeStart, timeEnd; - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); - int exec_timeE2E = diff(&tendE2E, &tstartE2E); - totTimeE2E += exec_timeE2E; - // showing - unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish kernel execution" << std::endl; - std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish E2E execution" << std::endl; - // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" - printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, - exec_timeE2E, buff_host.config0[2], currMod); - std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" - << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; - std::cout << "-------------------------------------------------------" << std::endl; -} - -void PhaseLoop_UsingFPGA_Prep(graphNew* G, - double opts_C_thresh, - double currMod, - int numThreads, - // Updated variables - double& totTimeColoring, - int* colors, - KMemorys_host& buff_host) { - int edgeNum; - int numColors = Phaseloop_UsingFPGA_InitColorBuff(G, colors, numThreads, totTimeColoring); - double time1 = 0; - time1 = omp_get_wtime(); - assert(numColors < COLORS); - long vertexNum = G->numVertices; - long* vtxPtr = G->edgeListPtrs; - edge* vtxInd = G->edgeList; - long NE = G->numEdges; - long NEx2 = NE << 1; - long NE1 = NEx2 < (1 << 26) ? NEx2 : (1 << 26); // 256MB/sizeof(int/float)=64M - - long cnt_e = 0; - for (int i = 0; i < vertexNum + 1; i++) { - buff_host.offsets[i] = (int)vtxPtr[i]; - } - edgeNum = buff_host.offsets[vertexNum]; - for (int i = 0; i < vertexNum; i++) { - int adj1 = vtxPtr[i]; - int adj2 = vtxPtr[i + 1]; - for (int j = adj1; j < adj2; j++) { - if (cnt_e < NE1) { - buff_host.indices[j] = (int)vtxInd[j].tail; - buff_host.weights[j] = vtxInd[j].weight; - } else { - buff_host.indices2[j - NE1] = (int)vtxInd[j].tail; - buff_host.weights2[j - NE1] = vtxInd[j].weight; - } - cnt_e++; - } - } - for (int i = 0; i < vertexNum; i++) { - buff_host.colorAxi[i] = colors[i]; - } - buff_host.config0[0] = vertexNum; - buff_host.config0[1] = numColors; - buff_host.config0[2] = 0; - buff_host.config0[3] = edgeNum; - buff_host.config1[0] = opts_C_thresh; - buff_host.config1[1] = currMod; - time1 = omp_get_wtime() - time1; -} - -void PhaseLoop_UsingFPGA(long NV, - double opts_C_thresh, - bool opts_coloring, - double opts_threshold, - int numThreads, - double& currMod, - graphNew*& G, - long*& C, - long*& C_orig, - int& totItr, - KMemorys_host& buff_host, - KMemorys_clBuff& buff_cl, - cl::Kernel& kernel_louvain, - cl::CommandQueue& q, - int& num_runsFPGA, - int*& colors, - int& totTimeE2E, - double& totTimeColoring) { - long vertexNum = G->numVertices; - bool isLargeEdge = G->numEdges > (1 << 25); - num_runsFPGA++; - struct timeval tstartE2E, tendE2E; - std::vector ob_in; - std::vector ob_out; - std::vector > kernel_evt0(1); - std::vector > kernel_evt1(1); - kernel_evt0[0].resize(1); - kernel_evt1[0].resize(1); - - PhaseLoop_UsingFPGA_Prep(G, opts_C_thresh, currMod, numThreads, totTimeColoring, colors, buff_host); - gettimeofday(&tstartE2E, 0); - PhaseLoop_UsingFPGA_1_KernelSetup(isLargeEdge, kernel_louvain, ob_in, ob_out, buff_cl); - PhaseLoop_UsingFPGA_2_DataWriteTo(q, kernel_evt0, ob_in); - PhaseLoop_UsingFPGA_3_KernelRun(q, kernel_evt0, kernel_evt1, kernel_louvain); - PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); - PhaseLoop_UsingFPGA_5_KernelFinish(q); - gettimeofday(&tendE2E, 0); - PhaseLoop_UsingFPGA_Post(vertexNum, num_runsFPGA, buff_host, tstartE2E, tendE2E, kernel_evt1, C, totItr, currMod, - totTimeE2E); -} - +// prune void inline PhaseLoop_MapHostBuff_prune(long NV, long NE_mem_1, long NE_mem_2, @@ -743,8 +465,8 @@ void inline PhaseLoop_MapHostBuff_prune(long NV, buff_host.config1 = aligned_alloc(4); buff_host.offsets = aligned_alloc(NV + 1); buff_host.indices = aligned_alloc(NE_mem_1); - buff_host.offsetsdup = aligned_alloc(NV + 1); // - buff_host.indicesdup = aligned_alloc(NE_mem_1); // + // buff_host.offsetsdup = aligned_alloc(NV + 1); // + // buff_host.indicesdup = aligned_alloc(NE_mem_1); // buff_host.weights = aligned_alloc(NE_mem_1); buff_host.flag = aligned_alloc >(NV); buff_host.flagUpdate = aligned_alloc >(NV); @@ -769,15 +491,15 @@ void inline PhaseLoop_MapHostBuff_prune(long NV, ap_uint* axi_offsets = reinterpret_cast*>(buff_host.offsets); ap_uint* axi_indices = reinterpret_cast*>(buff_host.indices); - ap_uint* axi_offsetsdup = reinterpret_cast*>(buff_host.offsetsdup); - ap_uint* axi_indicesdup = reinterpret_cast*>(buff_host.indicesdup); + // ap_uint* axi_offsetsdup = reinterpret_cast*>(buff_host.offsetsdup); + // ap_uint* axi_indicesdup = reinterpret_cast*>(buff_host.indicesdup); ap_uint* axi_weights = reinterpret_cast*>(buff_host.weights); ap_uint* axi_indices2; ap_uint* axi_indicesdup2; ap_uint* axi_weights2; if (NE_mem_2 > 0) { axi_indices2 = reinterpret_cast*>(buff_host.indices2); - axi_indicesdup2 = reinterpret_cast*>(buff_host.indicesdup2); + // axi_indicesdup2 = reinterpret_cast*>(buff_host.indicesdup2); axi_weights2 = reinterpret_cast*>(buff_host.weights2); } ap_uint* axi_cidPrev = reinterpret_cast*>(buff_host.cidPrev); @@ -804,27 +526,20 @@ void inline PhaseLoop_MapHostBuff_prune(long NV, mext_in[3 + 18] = {(unsigned int)(1) | XCL_MEM_TOPOLOGY, axi_indices2, 0}; mext_in[4 + 18] = {(unsigned int)(3) | XCL_MEM_TOPOLOGY, axi_weights2, 0}; } - mext_in[5] = {(unsigned int)(6) | XCL_MEM_TOPOLOGY, axi_colorAxi, 0}; - mext_in[6] = {(unsigned int)(8) | XCL_MEM_TOPOLOGY, axi_colorInx, 0}; - mext_in[7] = {(unsigned int)(10) | XCL_MEM_TOPOLOGY, axi_cidPrev, 0}; - mext_in[8] = {(unsigned int)(12) | XCL_MEM_TOPOLOGY, axi_cidSizePrev, 0}; - mext_in[9] = {(unsigned int)(14) | XCL_MEM_TOPOLOGY, axi_totPrev, 0}; - mext_in[10] = {(unsigned int)(16) | XCL_MEM_TOPOLOGY, axi_cidCurr, 0}; - mext_in[11] = {(unsigned int)(18) | XCL_MEM_TOPOLOGY, axi_cidSizeCurr, 0}; - mext_in[12] = {(unsigned int)(20) | XCL_MEM_TOPOLOGY, axi_totCurr, 0}; - mext_in[13] = {(unsigned int)(22) | XCL_MEM_TOPOLOGY, axi_cidSizeUpdate, 0}; - mext_in[14] = {(unsigned int)(24) | XCL_MEM_TOPOLOGY, axi_totUpdate, 0}; - mext_in[15] = {(unsigned int)(26) | XCL_MEM_TOPOLOGY, axi_cWeight, 0}; - - mext_in[16] = {(unsigned int)(27) | XCL_MEM_TOPOLOGY, axi_offsetsdup, 0}; - // mext_in[17] = {(unsigned int)(28) | XCL_MEM_TOPOLOGY, axi_indicesdup, 0}; - mext_in[17] = {(unsigned int)(28) | XCL_MEM_TOPOLOGY, axi_indicesdup, 0}; //| (unsigned int)(29) - if (NE_mem_2 > 0) { - mext_in[20] = {(unsigned int)(29) | XCL_MEM_TOPOLOGY, axi_indicesdup2, 0}; - } - - mext_in[18] = {(unsigned int)(7) | XCL_MEM_TOPOLOGY, axi_flag, 0}; - mext_in[19] = {(unsigned int)(9) | XCL_MEM_TOPOLOGY, axi_flagUpdate, 0}; + mext_in[5] = {(unsigned int)(5) | XCL_MEM_TOPOLOGY, axi_colorAxi, 0}; + mext_in[6] = {(unsigned int)(6) | XCL_MEM_TOPOLOGY, axi_colorInx, 0}; + mext_in[7] = {(unsigned int)(7) | XCL_MEM_TOPOLOGY, axi_cidPrev, 0}; + mext_in[8] = {(unsigned int)(8) | XCL_MEM_TOPOLOGY, axi_cidSizePrev, 0}; + mext_in[9] = {(unsigned int)(9) | XCL_MEM_TOPOLOGY, axi_totPrev, 0}; + mext_in[10] = {(unsigned int)(10) | XCL_MEM_TOPOLOGY, axi_cidCurr, 0}; + mext_in[11] = {(unsigned int)(11) | XCL_MEM_TOPOLOGY, axi_cidSizeCurr, 0}; + mext_in[12] = {(unsigned int)(12) | XCL_MEM_TOPOLOGY, axi_totCurr, 0}; + mext_in[13] = {(unsigned int)(13) | XCL_MEM_TOPOLOGY, axi_cidSizeUpdate, 0}; + mext_in[14] = {(unsigned int)(14) | XCL_MEM_TOPOLOGY, axi_totUpdate, 0}; + mext_in[15] = {(unsigned int)(15) | XCL_MEM_TOPOLOGY, axi_cWeight, 0}; + + mext_in[18] = {(unsigned int)(5) | XCL_MEM_TOPOLOGY, axi_flag, 0}; + mext_in[19] = {(unsigned int)(5) | XCL_MEM_TOPOLOGY, axi_flagUpdate, 0}; } void inline PhaseLoop_MapClBuff_prune(long NV, long NE_mem_1, @@ -858,14 +573,14 @@ void inline PhaseLoop_MapClBuff_prune(long NV, buff_cl.db_totUpdate = cl::Buffer(context, flag_RW, sizeof(float) * (NV), &mext_in[14]); buff_cl.db_cWeight = cl::Buffer(context, flag_RW, sizeof(float) * (NV), &mext_in[15]); - buff_cl.db_offsetsdup = cl::Buffer(context, flag_RD, sizeof(int) * (NV + 1), &mext_in[16]); - buff_cl.db_indicesdup = cl::Buffer(context, flag_RD, sizeof(int) * (NE_mem_1), &mext_in[17]); + // buff_cl.db_offsetsdup = cl::Buffer(context, flag_RD, sizeof(int) * (NV + 1), &mext_in[16]); + // buff_cl.db_indicesdup = cl::Buffer(context, flag_RD, sizeof(int) * (NE_mem_1), &mext_in[17]); buff_cl.db_flag = cl::Buffer(context, flag_RW, sizeof(ap_uint<8>) * (NV), &mext_in[18]); buff_cl.db_flagUpdate = cl::Buffer(context, flag_RW, sizeof(ap_uint<8>) * (NV), &mext_in[19]); // printf("INFO: sizeof(ap_uint<8>) = %d", sizeof(ap_uint<8>) ); - if (NE_mem_2 != 0) buff_cl.db_indicesdup2 = cl::Buffer(context, flag_RD, sizeof(int) * (NE_mem_2), &mext_in[20]); + // if (NE_mem_2 != 0) buff_cl.db_indicesdup2 = cl::Buffer(context, flag_RD, sizeof(int) * (NE_mem_2), &mext_in[20]); } void UsingFPGA_MapHostClBuff_prune(long NV, long NE_mem_1, @@ -877,96 +592,61 @@ void UsingFPGA_MapHostClBuff_prune(long NV, PhaseLoop_MapHostBuff_prune(NV, NE_mem_1, NE_mem_2, mext_in, context, buff_host); PhaseLoop_MapClBuff_prune(NV, NE_mem_1, NE_mem_2, mext_in, context, buff_cl); } -void PhaseLoop_UsingFPGA_1_KernelSetup_prune(bool isLargeEdge, - cl::Kernel& kernel_louvain, - std::vector& ob_in, - std::vector& ob_out, - KMemorys_clBuff_prune& buff_cl) { - // Data transfer from host buffer to device buffer - ob_in.push_back(buff_cl.db_config0); - ob_in.push_back(buff_cl.db_config1); - ob_in.push_back(buff_cl.db_offsets); - ob_in.push_back(buff_cl.db_indices); - if (isLargeEdge) ob_in.push_back(buff_cl.db_indices2); - ob_in.push_back(buff_cl.db_weights); - if (isLargeEdge) ob_in.push_back(buff_cl.db_weights2); - ob_in.push_back(buff_cl.db_cidCurr); - ob_in.push_back(buff_cl.db_cidSizePrev); - ob_in.push_back(buff_cl.db_cidSizeUpdate); - ob_in.push_back(buff_cl.db_cidSizeCurr); - ob_in.push_back(buff_cl.db_totPrev); - ob_in.push_back(buff_cl.db_totUpdate); - ob_in.push_back(buff_cl.db_totCurr); - ob_in.push_back(buff_cl.db_cWeight); - ob_in.push_back(buff_cl.db_colorAxi); - ob_in.push_back(buff_cl.db_colorInx); - ob_in.push_back(buff_cl.db_cidPrev); - ob_in.push_back(buff_cl.db_offsetsdup); - ob_in.push_back(buff_cl.db_indicesdup); - if (isLargeEdge) ob_in.push_back(buff_cl.db_indicesdup2); - ob_in.push_back(buff_cl.db_flag); - ob_in.push_back(buff_cl.db_flagUpdate); - - ob_out.push_back(buff_cl.db_config0); - ob_out.push_back(buff_cl.db_config1); - ob_out.push_back(buff_cl.db_cidPrev); - kernel_louvain.setArg(0, buff_cl.db_config0); // config0 - kernel_louvain.setArg(1, buff_cl.db_config1); // config1 - kernel_louvain.setArg(2, buff_cl.db_offsets); // offsets - kernel_louvain.setArg(3, buff_cl.db_indices); // indices - kernel_louvain.setArg(4, buff_cl.db_weights); // weights - kernel_louvain.setArg(5, buff_cl.db_colorAxi); // colorAxi - kernel_louvain.setArg(6, buff_cl.db_colorInx); // colorInx - kernel_louvain.setArg(7, buff_cl.db_cidPrev); // cidPrev - kernel_louvain.setArg(8, buff_cl.db_cidSizePrev); // cidSizePrev - kernel_louvain.setArg(9, buff_cl.db_totPrev); // totPrev - kernel_louvain.setArg(10, buff_cl.db_cidCurr); // cidCurr - kernel_louvain.setArg(11, buff_cl.db_cidSizeCurr); // cidSizeCurr - kernel_louvain.setArg(12, buff_cl.db_totCurr); // totCurr - kernel_louvain.setArg(13, buff_cl.db_cidSizeUpdate); // cUpdate - kernel_louvain.setArg(14, buff_cl.db_totUpdate); // totCurr - kernel_louvain.setArg(15, buff_cl.db_cWeight); // cWeight - kernel_louvain.setArg(16, buff_cl.db_offsetsdup); // offsets - kernel_louvain.setArg(17, buff_cl.db_indicesdup); // indices - kernel_louvain.setArg(18, buff_cl.db_flag); // offsets - kernel_louvain.setArg(19, buff_cl.db_flagUpdate); // indices - std::cout << "INFO: Finish kernel setup" << std::endl; -} +//////////////////////////////////////////////////////////////////////////////////////////////////////////// -void PhaseLoop_UsingFPGA_Post_par_prune(long vertexNum, - int num_runsFPGA, - KMemorys_host_prune& buff_host, - struct timeval& tstartE2E, - struct timeval& tendE2E, - std::vector >& kernel_evt1, - // output - long* C, - int& totItr, - double& currMod, - int& totTimeE2E) { - // updating - totItr += buff_host.config0[2]; - currMod = buff_host.config1[1]; +double PhaseLoop_UsingFPGA_Prep_Init_buff_host(int numColors, + graphNew* G, + long* M, + double opts_C_thresh, + double currMod, + // Updated variables + int* colors, + KMemorys_host& buff_host) { + int edgeNum; + double time1 = omp_get_wtime(); + assert(numColors < COLORS); + long vertexNum = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + long NE = G->numEdges; + long NEx2 = NE << 1; + long NE1 = NEx2 < (MAXNV) ? NEx2 : (MAXNV); // 256MB/sizeof(int/float)=64M + + long cnt_e = 0; + for (int i = 0; i < vertexNum + 1; i++) { + buff_host.offsets[i] = (int)vtxPtr[i]; + if (i != vertexNum) { + if (M[i] < 0) buff_host.offsets[i] = (int)(0x80000000 | (unsigned int)vtxPtr[i]); + } else + buff_host.offsets[i] = (int)(vtxPtr[i]); + } + edgeNum = buff_host.offsets[vertexNum]; for (int i = 0; i < vertexNum; i++) { - C[i] = (long)buff_host.cidPrev[i]; + int adj1 = vtxPtr[i]; + int adj2 = vtxPtr[i + 1]; + for (int j = adj1; j < adj2; j++) { + if (cnt_e < NE1) { + buff_host.indices[j] = (int)vtxInd[j].tail; + buff_host.weights[j] = vtxInd[j].weight; + } else { + buff_host.indices2[j - NE1] = (int)vtxInd[j].tail; + buff_host.weights2[j - NE1] = vtxInd[j].weight; + } + cnt_e++; + } } - unsigned long timeStart, timeEnd; - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); - int exec_timeE2E = diff(&tendE2E, &tstartE2E); - totTimeE2E += exec_timeE2E; - // showing - unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish kernel execution" << std::endl; - std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish E2E execution" << std::endl; - std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" - << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" - << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; - std::cout << "-------------------------------------------------------" << std::endl; + for (int i = 0; i < vertexNum; i++) { + buff_host.colorAxi[i] = colors[i]; + } + buff_host.config0[0] = vertexNum; + buff_host.config0[1] = numColors; + buff_host.config0[2] = 0; + buff_host.config0[3] = edgeNum; + buff_host.config1[0] = opts_C_thresh; + buff_host.config1[1] = currMod; + time1 = omp_get_wtime() - time1; + return time1; } double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, @@ -986,7 +666,7 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, edge* vtxInd = G->edgeList; long NE = G->numEdges; long NEx2 = NE << 1; - long NE1 = NEx2 < (1 << 26) ? NEx2 : (1 << 26); // 256MB/sizeof(int/float)=64M + long NE1 = NEx2 < (MAXNV) ? NEx2 : (MAXNV); // 256MB/sizeof(int/float)=64M long cnt_e = 0; @@ -999,7 +679,7 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, } else { buff_host.offsets[i] = (int)(vtxPtr[i]); } - buff_host.offsetsdup[i] = buff_host.offsets[i]; // zyl + // buff_host.offsetsdup[i] = buff_host.offsets[i]; // zyl } edgeNum = buff_host.offsets[vertexNum]; @@ -1011,11 +691,11 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, for (int j = adj1; j < adj2; j++) { if (cnt_e < NE1) { buff_host.indices[j] = (int)vtxInd[j].tail; - buff_host.indicesdup[j] = (int)vtxInd[j].tail; + // buff_host.indicesdup[j] = (int)vtxInd[j].tail; buff_host.weights[j] = vtxInd[j].weight; } else { buff_host.indices2[j - NE1] = (int)vtxInd[j].tail; - buff_host.indicesdup2[j - NE1] = (int)vtxInd[j].tail; + // buff_host.indicesdup2[j - NE1] = (int)vtxInd[j].tail; buff_host.weights2[j - NE1] = vtxInd[j].weight; } cnt_e++; @@ -1037,285 +717,172 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, return time1; } -//////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void runLouvainWithFPGA(graphNew* G, // Input graphNew, undirectioned - long* C_orig, // Output - char* opts_xclbinPath, - bool opts_coloring, - long opts_minGraphSize, - double opts_threshold, - double opts_C_thresh, - int numThreads) { - long NV = G->numVertices; - long NE_org = G->numEdges; - long numClusters; - /* Check graphNew size, limited by hardware features */ - assert(NV < MAXNV); - assert(NE_org < MAXNE); - - /* For coloring */ - int* colors; - if (opts_coloring) { - colors = (int*)malloc(G->numVertices * sizeof(int)); - assert(colors != 0); - } - - /* To build new hierarchical graphNews*/ - long* C = (long*)malloc(NV * sizeof(long)); - assert(C != 0); -#pragma omp parallel for - for (long i = 0; i < NV; i++) { - C[i] = -1; - } - - /*******************************/ - /* FPGA-related data structures*/ - /*******************************/ - /* platform related operations */ - std::vector devices = xcl::get_xil_devices(); - cl::Device device = devices[0]; - cl::Context context(device); - std::string devName = device.getInfo(); - printf("INFO: Found Device=%s\n", devName.c_str()); - cl::Program::Binaries xclBins = xcl::import_binary_file(opts_xclbinPath); - devices.resize(1); - cl::Program program(context, devices, xclBins); - cl::Kernel kernel_louvain(program, "kernel_louvain"); - printf("INFO: kernel has been created\n"); - cl::CommandQueue q(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); - /* Memories mapping */ - KMemorys_host buff_host; - KMemorys_clBuff buff_cl; - long NE_mem = NE_org * 2; // number for real edge to be stored in memory - long NE_mem_1 = NE_mem < (1 << 26) ? NE_mem : (1 << 26); - long NE_mem_2 = NE_mem - NE_mem_1; - UsingFPGA_MapHostClBuff(NV, NE_mem_1, NE_mem_2, context, buff_host, buff_cl); - - /*******************************/ - /* Loop for phase(s) */ - /*******************************/ - double totTimeClustering = 0; // time accumulator for clustering by CPU - double totTimeBuildingPhase = 0; // time accumulator for Building new graphNew for next phase by CPU - double totTimeColoring = 0; // time accumulator for coloring - double prevMod = -1; // Last-phase modularity - double currMod = -1; // Current modularity - int phase = 1; // Total phase counter - int totTimeE2E = 0; // FPGA E2E time accumulator - int num_runsFPGA = 0; // FPGA calling times counter - int totItr = 0; // Total iteration counter - bool nonColor = false; // Make sure that at least one phase with lower opts_threshold runs - bool isItrStop = false; - while (!isItrStop) { - printf("===============================\n"); - printf("Phase %d\n", phase); - printf("===============================\n"); - prevMod = currMod; - bool isUsingFPGA = ((opts_coloring) && (G->numVertices > opts_minGraphSize) && (nonColor == false)); - - if (isUsingFPGA) { - PhaseLoop_UsingFPGA(NV, opts_C_thresh, opts_coloring, opts_threshold, numThreads, currMod, G, C, C_orig, - totItr, buff_host, buff_cl, kernel_louvain, q, /*kernel's parameter*/ - num_runsFPGA, colors, totTimeE2E, totTimeColoring); - } else { - PhaseLoop_UsingCPU(opts_threshold, numThreads, currMod, G, C, C_orig, totItr, nonColor, totTimeClustering); - } - /* General post-processing for both FPGA and CPU */ - isItrStop = PhaseLoop_CommPostProcessing(NV, numThreads, opts_threshold, opts_coloring, prevMod, currMod, G, C, - C_orig, nonColor, phase, totItr, numClusters, totTimeBuildingPhase); - } // End of while(1) = End of Louvain - - /* Print information*/ - printf("********************************************\n"); - printf("********* Compact Summary *************\n"); - printf("********************************************\n"); - printf("Number of threads : %d\n", numThreads); - printf("Total number of phases : %d\n", phase); - printf("Total number of iterations : %d\n", totItr); - printf("Final number of clusters : %ld\n", numClusters); - printf("Final modularity : %lf\n", prevMod); - printf("Total time for clustering : %lf\n", totTimeClustering); - printf("Total time for building phases : %lf\n", totTimeBuildingPhase); - printf("Total E2E time(s) : %lf\n", (1.0 * totTimeE2E * 1e-6)); - if (opts_coloring) { - printf("Total time for coloring : %lf\n", totTimeColoring); - } - printf("********************************************\n"); - printf("TOTAL TIME : %lf\n", - ((1.0 * totTimeE2E * 1e-6) + totTimeClustering + totTimeBuildingPhase + totTimeColoring)); - printf("********************************************\n"); - - /* Clean up memories */ - free(C); - if (G != 0) { - free(G->edgeListPtrs); - free(G->edgeList); - free(G); - } - if (opts_coloring) { - if (colors != 0) free(colors); - } - buff_host.freeMem(); -} // End of runMultiPhaseLouvainAlgorithm() - -void runLouvainWithFPGA_demo(graphNew* G, - long* C_orig, - char* opts_xclbinPath, - bool opts_coloring, - long opts_minGraphSize, - double opts_threshold, - double opts_C_thresh, - int numThreads) { - long NV = G->numVertices; - long NE_org = G->numEdges; - long numClusters; - assert(NV < MAXNV); - assert(NE_org < MAXNE); - - int* colors; - if (opts_coloring) { - colors = (int*)malloc(G->numVertices * sizeof(int)); - assert(colors != 0); - } - long* C = (long*)malloc(NV * sizeof(long)); - assert(C != 0); -#pragma omp parallel for - for (long i = 0; i < NV; i++) { - C[i] = -1; - } - - std::vector devices = xcl::get_xil_devices(); - cl::Device device = devices[0]; - cl::Context context(device); - std::string devName = device.getInfo(); - printf("INFO: Found Device=%s\n", devName.c_str()); - cl::Program::Binaries xclBins = xcl::import_binary_file(opts_xclbinPath); - devices.resize(1); - cl::Program program(context, devices, xclBins); - cl::Kernel kernel_louvain(program, "kernel_louvain"); - printf("INFO: kernel has been created\n"); - cl::CommandQueue q(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); - - KMemorys_host buff_host; - KMemorys_clBuff buff_cl; - long NE_mem = NE_org * 2; // number for real edge to be stored in memory - long NE_mem_1 = NE_mem < (MAXNV) ? NE_mem : (MAXNV); - long NE_mem_2 = NE_mem - NE_mem_1; - UsingFPGA_MapHostClBuff(NV, NE_mem_1, NE_mem_2, context, buff_host, buff_cl); - - double totTimeClustering = 0; // time accumulator for clustering by CPU - double totTimeBuildingPhase = 0; // time accumulator for Building new graphNew for next phase by CPU - double totTimeColoring = 0; // time accumulator for coloring - double prevMod = -1; // Last-phase modularity - double currMod = -1; // Current modularity - int phase = 1; // Total phase counter - int totTimeE2E = 0; // FPGA E2E time accumulator - int num_runsFPGA = 0; // FPGA calling times counter - int totItr = 0; // Total iteration counter - bool nonColor = false; // Make sure that at least one phase with lower opts_threshold runs - bool isItrStop = false; - while (!isItrStop) { - printf("===============================\n"); - printf("Phase %d\n", phase); - printf("===============================\n"); - prevMod = currMod; - bool isUsingFPGA = ((opts_coloring) && (G->numVertices > opts_minGraphSize) && (nonColor == false)); - - if (isUsingFPGA) { - long vertexNum = G->numVertices; - bool isLargeEdge = G->numEdges > (MAXNV / 2); - num_runsFPGA++; - struct timeval tstartE2E, tendE2E; - std::vector ob_in; - std::vector ob_out; - std::vector > kernel_evt0(1); - std::vector > kernel_evt1(1); - kernel_evt0[0].resize(1); - kernel_evt1[0].resize(1); - - PhaseLoop_UsingFPGA_Prep(G, opts_C_thresh, currMod, numThreads, totTimeColoring, colors, buff_host); +int PhaseLoop_UsingCPU(double opts_threshold, + int numThreads, + double& currMod, + graphNew*& G, + long*& C, + long*& C_orig, + int& totItr, + bool& nonColor, + double& totTimeClustering) { + double tmpTime; + int tmpItr = 0; + currMod = parallelLouvianMethod(G, C, numThreads, currMod, opts_threshold, &tmpTime, &tmpItr); + totTimeClustering += tmpTime; + totItr += tmpItr; + nonColor = true; + return 0; +} +void PhaseLoop_UsingFPGA_1_KernelSetup(bool isLargeEdge, + cl::Kernel& kernel_louvain, + std::vector& ob_in, + std::vector& ob_out, + KMemorys_clBuff& buff_cl) { + // Data transfer from host buffer to device buffer + ob_in.push_back(buff_cl.db_config0); + ob_in.push_back(buff_cl.db_config1); + ob_in.push_back(buff_cl.db_offsets); + ob_in.push_back(buff_cl.db_indices); + if (isLargeEdge) ob_in.push_back(buff_cl.db_indices2); + ob_in.push_back(buff_cl.db_weights); + if (isLargeEdge) ob_in.push_back(buff_cl.db_weights2); + ob_in.push_back(buff_cl.db_cidCurr); + ob_in.push_back(buff_cl.db_cidSizePrev); + ob_in.push_back(buff_cl.db_cidSizeUpdate); + ob_in.push_back(buff_cl.db_cidSizeCurr); + ob_in.push_back(buff_cl.db_totPrev); + ob_in.push_back(buff_cl.db_totUpdate); + ob_in.push_back(buff_cl.db_totCurr); + ob_in.push_back(buff_cl.db_cWeight); + ob_in.push_back(buff_cl.db_colorAxi); + ob_in.push_back(buff_cl.db_colorInx); + ob_out.push_back(buff_cl.db_config0); + ob_out.push_back(buff_cl.db_config1); + ob_out.push_back(buff_cl.db_cidPrev); - gettimeofday(&tstartE2E, 0); - { /* 5-Step flow for using FPGA */ - PhaseLoop_UsingFPGA_1_KernelSetup(isLargeEdge, kernel_louvain, ob_in, ob_out, buff_cl); + kernel_louvain.setArg(0, buff_cl.db_config0); // config0 + kernel_louvain.setArg(1, buff_cl.db_config1); // config1 + kernel_louvain.setArg(2, buff_cl.db_offsets); // offsets + kernel_louvain.setArg(3, buff_cl.db_indices); // indices + kernel_louvain.setArg(4, buff_cl.db_weights); // weights + kernel_louvain.setArg(5, buff_cl.db_colorAxi); // colorAxi + kernel_louvain.setArg(6, buff_cl.db_colorInx); // colorInx + kernel_louvain.setArg(7, buff_cl.db_cidPrev); // cidPrev + kernel_louvain.setArg(8, buff_cl.db_cidSizePrev); // cidSizePrev + kernel_louvain.setArg(9, buff_cl.db_totPrev); // totPrev + kernel_louvain.setArg(10, buff_cl.db_cidCurr); // cidCurr + kernel_louvain.setArg(11, buff_cl.db_cidSizeCurr); // cidSizeCurr + kernel_louvain.setArg(12, buff_cl.db_totCurr); // totCurr + kernel_louvain.setArg(13, buff_cl.db_cidSizeUpdate); // cUpdate + kernel_louvain.setArg(14, buff_cl.db_totUpdate); // totCurr + kernel_louvain.setArg(15, buff_cl.db_cWeight); // cWeight + std::cout << "INFO: Finish kernel setup" << std::endl; +} - PhaseLoop_UsingFPGA_2_DataWriteTo(q, kernel_evt0, ob_in); +void PhaseLoop_UsingFPGA_1_KernelSetup_prune(bool isLargeEdge, + cl::Kernel& kernel_louvain, + std::vector& ob_in, + std::vector& ob_out, + KMemorys_clBuff_prune& buff_cl) { + // Data transfer from host buffer to device buffer + ob_in.push_back(buff_cl.db_config0); + ob_in.push_back(buff_cl.db_config1); + ob_in.push_back(buff_cl.db_offsets); + ob_in.push_back(buff_cl.db_indices); + if (isLargeEdge) ob_in.push_back(buff_cl.db_indices2); + ob_in.push_back(buff_cl.db_weights); + if (isLargeEdge) ob_in.push_back(buff_cl.db_weights2); + ob_in.push_back(buff_cl.db_cidCurr); + ob_in.push_back(buff_cl.db_cidSizePrev); + ob_in.push_back(buff_cl.db_cidSizeUpdate); + ob_in.push_back(buff_cl.db_cidSizeCurr); + ob_in.push_back(buff_cl.db_totPrev); + ob_in.push_back(buff_cl.db_totUpdate); + ob_in.push_back(buff_cl.db_totCurr); + ob_in.push_back(buff_cl.db_cWeight); + ob_in.push_back(buff_cl.db_colorAxi); + ob_in.push_back(buff_cl.db_colorInx); + ob_in.push_back(buff_cl.db_cidPrev); + // ob_in.push_back(buff_cl.db_offsetsdup); + // ob_in.push_back(buff_cl.db_indicesdup); + // if (isLargeEdge) ob_in.push_back(buff_cl.db_indicesdup2); + ob_in.push_back(buff_cl.db_flag); + ob_in.push_back(buff_cl.db_flagUpdate); - PhaseLoop_UsingFPGA_3_KernelRun(q, kernel_evt0, kernel_evt1, kernel_louvain); + ob_out.push_back(buff_cl.db_config0); + ob_out.push_back(buff_cl.db_config1); + ob_out.push_back(buff_cl.db_cidPrev); - PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); + kernel_louvain.setArg(0, buff_cl.db_config0); // config0 + kernel_louvain.setArg(1, buff_cl.db_config1); // config1 + kernel_louvain.setArg(2, buff_cl.db_offsets); // offsets + kernel_louvain.setArg(3, buff_cl.db_indices); // indices + kernel_louvain.setArg(4, buff_cl.db_weights); // weights + kernel_louvain.setArg(5, buff_cl.db_colorAxi); // colorAxi + kernel_louvain.setArg(6, buff_cl.db_colorInx); // colorInx + kernel_louvain.setArg(7, buff_cl.db_cidPrev); // cidPrev + kernel_louvain.setArg(8, buff_cl.db_cidSizePrev); // cidSizePrev + kernel_louvain.setArg(9, buff_cl.db_totPrev); // totPrev + kernel_louvain.setArg(10, buff_cl.db_cidCurr); // cidCurr + kernel_louvain.setArg(11, buff_cl.db_cidSizeCurr); // cidSizeCurr + kernel_louvain.setArg(12, buff_cl.db_totCurr); // totCurr + kernel_louvain.setArg(13, buff_cl.db_cidSizeUpdate); // cUpdate + kernel_louvain.setArg(14, buff_cl.db_totUpdate); // totCurr + kernel_louvain.setArg(15, buff_cl.db_cWeight); // cWeight + kernel_louvain.setArg(16, buff_cl.db_offsets); // offsets + kernel_louvain.setArg(17, buff_cl.db_indices); // indices + kernel_louvain.setArg(18, buff_cl.db_flag); // offsets + kernel_louvain.setArg(19, buff_cl.db_flagUpdate); // indices + std::cout << "INFO: Finish kernel setup" << std::endl; +} - PhaseLoop_UsingFPGA_5_KernelFinish(q); - } - gettimeofday(&tendE2E, 0); +void PhaseLoop_UsingFPGA_2_DataWriteTo(cl::CommandQueue& q, + std::vector >& kernel_evt0, + std::vector& ob_in) { /* 0 : migrate from host to dev */ + q.enqueueMigrateMemObjects(ob_in, 0, nullptr, kernel_evt0[0].data()); +} - PhaseLoop_UsingFPGA_Post(vertexNum, num_runsFPGA, buff_host, tstartE2E, tendE2E, kernel_evt1, C, totItr, - currMod, totTimeE2E); - } else { - PhaseLoop_UsingCPU(opts_threshold, numThreads, currMod, G, C, C_orig, totItr, nonColor, totTimeClustering); - } - isItrStop = PhaseLoop_CommPostProcessing(NV, numThreads, opts_threshold, opts_coloring, prevMod, currMod, G, C, - C_orig, nonColor, phase, totItr, numClusters, totTimeBuildingPhase); - } +void PhaseLoop_UsingFPGA_3_KernelRun(cl::CommandQueue& q, + std::vector >& kernel_evt0, + std::vector >& kernel_evt1, + cl::Kernel& kernel_louvain) { + q.enqueueTask(kernel_louvain, &kernel_evt0[0], kernel_evt1[0].data()); +} - printf("********************************************\n"); - printf("********* Compact Summary *************\n"); - printf("********************************************\n"); - printf("Number of threads : %d\tm=%d \t thhd=%lf \t thhd_c=%lf\n", numThreads, opts_minGraphSize, - opts_threshold, opts_C_thresh); - printf("Total number of phases : %d\n", phase); - printf("Total number of iterations : %d\n", totItr); - printf("Final number of clusters : %ld\n", numClusters); - printf("Final modularity : %lf\n", prevMod); - printf("Total time for clustering : %lf\n", totTimeClustering); - printf("Total time for building phases : %lf\n", totTimeBuildingPhase); - printf("Total E2E time(s) : %lf\n", (1.0 * totTimeE2E * 1e-6)); - if (opts_coloring) { - printf("Total time for coloring : %lf\n", totTimeColoring); - } - printf("********************************************\n"); - printf("TOTAL TIME : %lf\n", - ((1.0 * totTimeE2E * 1e-6) + totTimeClustering + totTimeBuildingPhase + totTimeColoring)); - printf("********************************************\n"); +void PhaseLoop_UsingFPGA_4_DataReadBack(cl::CommandQueue& q, + std::vector >& kernel_evt1, + std::vector& ob_out) { /* kernel_evt1 : migrate from dev to host*/ + q.enqueueMigrateMemObjects(ob_out, 1, &kernel_evt1[0], nullptr); +} - /* Clean up memories */ - free(C); - if (G != 0) { - free(G->edgeListPtrs); - free(G->edgeList); - free(G); - } - if (opts_coloring) { - if (colors != 0) free(colors); - } - buff_host.freeMem(); -} // End of runMultiPhaseLouvainAlgorithm() +void PhaseLoop_UsingFPGA_5_KernelFinish(cl::CommandQueue& q) { + q.finish(); +} -double PhaseLoop_UsingFPGA_Prep_Init_buff_host(int numColors, - graphNew* G, - long* M, - double opts_C_thresh, - double currMod, - // Updated variables - int* colors, - KMemorys_host& buff_host) { +void PhaseLoop_UsingFPGA_Prep(graphNew* G, + double opts_C_thresh, + double currMod, + int numThreads, + // Updated variables + double& totTimeColoring, + int* colors, + KMemorys_host& buff_host) { int edgeNum; - double time1 = omp_get_wtime(); + int numColors = Phaseloop_UsingFPGA_InitColorBuff(G, colors, numThreads, totTimeColoring); + double time1 = 0; + time1 = omp_get_wtime(); assert(numColors < COLORS); long vertexNum = G->numVertices; long* vtxPtr = G->edgeListPtrs; edge* vtxInd = G->edgeList; long NE = G->numEdges; long NEx2 = NE << 1; - long NE1 = NEx2 < (1 << 26) ? NEx2 : (1 << 26); // 256MB/sizeof(int/float)=64M + long NE1 = NEx2 < (MAXNV) ? NEx2 : (MAXNV); // 256MB/sizeof(int/float)=64M long cnt_e = 0; for (int i = 0; i < vertexNum + 1; i++) { buff_host.offsets[i] = (int)vtxPtr[i]; - if (i != vertexNum) { - if (M[i] < 0) buff_host.offsets[i] = (int)(0x80000000 | (unsigned int)vtxPtr[i]); - } else - buff_host.offsets[i] = (int)(vtxPtr[i]); } edgeNum = buff_host.offsets[vertexNum]; for (int i = 0; i < vertexNum; i++) { @@ -1333,36 +900,126 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host(int numColors, } } for (int i = 0; i < vertexNum; i++) { - buff_host.colorAxi[i] = colors[i]; + buff_host.colorAxi[i] = colors[i]; + } + buff_host.config0[0] = vertexNum; + buff_host.config0[1] = numColors; + buff_host.config0[2] = 0; + buff_host.config0[3] = edgeNum; + buff_host.config1[0] = opts_C_thresh; + buff_host.config1[1] = currMod; + time1 = omp_get_wtime() - time1; +} + +void PhaseLoop_UsingFPGA_Post(long vertexNum, + int num_runsFPGA, + KMemorys_host& buff_host, + struct timeval& tstartE2E, + struct timeval& tendE2E, + std::vector >& kernel_evt1, + // output + long* C, + int& totItr, + double& currMod, + int& totTimeE2E) { + // updating + totItr += buff_host.config0[2]; + currMod = buff_host.config1[1]; + for (int i = 0; i < vertexNum; i++) { + C[i] = (long)buff_host.cidPrev[i]; + } + unsigned long timeStart, timeEnd; + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); + int exec_timeE2E = diff(&tendE2E, &tstartE2E); + totTimeE2E += exec_timeE2E; + // showing + unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish kernel execution" << std::endl; + std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish E2E execution" << std::endl; + // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" + printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, + exec_timeE2E, buff_host.config0[2], currMod); + std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" + << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; + std::cout << "-------------------------------------------------------" << std::endl; +} + +void PhaseLoop_UsingFPGA_Post_par(long vertexNum, + int num_runsFPGA, + KMemorys_host& buff_host, + struct timeval& tstartE2E, + struct timeval& tendE2E, + std::vector >& kernel_evt1, + // output + long* C, + int& totItr, + double& currMod, + int& totTimeE2E) { + // updating + totItr += buff_host.config0[2]; + currMod = buff_host.config1[1]; + for (int i = 0; i < vertexNum; i++) { + C[i] = (long)buff_host.cidPrev[i]; } - buff_host.config0[0] = vertexNum; - buff_host.config0[1] = numColors; - buff_host.config0[2] = 0; - buff_host.config0[3] = edgeNum; - buff_host.config1[0] = opts_C_thresh; - buff_host.config1[1] = currMod; - time1 = omp_get_wtime() - time1; - return time1; + unsigned long timeStart, timeEnd; + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); + int exec_timeE2E = diff(&tendE2E, &tstartE2E); + totTimeE2E += exec_timeE2E; + // showing + unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish kernel execution" << std::endl; + std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish E2E execution" << std::endl; + // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" + printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, + exec_timeE2E, buff_host.config0[2], currMod); + std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" + << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; + std::cout << "-------------------------------------------------------" << std::endl; } -double PhaseLoop_UsingFPGA_Prep_Read_buff_host(long vertexNum, - KMemorys_host& buff_host, - int phase, - int eachItrs[MAX_NUM_PHASE], - // output - long* C, - int& totItr, - double& currMod) { - double time1 = omp_get_wtime(); + +void PhaseLoop_UsingFPGA_Post_par_prune(long vertexNum, + int num_runsFPGA, + KMemorys_host_prune& buff_host, + struct timeval& tstartE2E, + struct timeval& tendE2E, + std::vector >& kernel_evt1, + // output + long* C, + int& totItr, + double& currMod, + int& totTimeE2E) { // updating - eachItrs[phase - 1] = buff_host.config0[2]; totItr += buff_host.config0[2]; currMod = buff_host.config1[1]; for (int i = 0; i < vertexNum; i++) { C[i] = (long)buff_host.cidPrev[i]; } - time1 = omp_get_wtime() - time1; - return time1; + unsigned long timeStart, timeEnd; + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); + int exec_timeE2E = diff(&tendE2E, &tstartE2E); + totTimeE2E += exec_timeE2E; + // showing + unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish kernel execution" << std::endl; + std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish E2E execution" << std::endl; + std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" + << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" + << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; + std::cout << "-------------------------------------------------------" << std::endl; } + double PhaseLoop_UsingFPGA_Prep_Read_buff_host(long vertexNum, KMemorys_host& buff_host, int& eachItrs, @@ -1406,35 +1063,8 @@ double PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune(long vertexNum, unsigned long diff2(const struct timeval* newTime, const struct timeval* oldTime) { return (newTime->tv_sec - oldTime->tv_sec) * 1000000 + (newTime->tv_usec - oldTime->tv_usec); } -void PhaseLoop_UsingFPGA_Post_par_noRead(double* p_eachTimeE2E, - int num_runsFPGA, - int num_iter, - struct timeval& tstartE2E, - struct timeval& tendE2E, - // std::vector > &kernel_evt1, - double currMod, - int& totTimeE2E) { - // unsigned long timeStart, timeEnd; - // kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - // kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); - int exec_timeE2E = diff2(&tendE2E, &tstartE2E); - totTimeE2E += exec_timeE2E; - // showing - // unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish kernel execution" << std::endl; - // std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish E2E execution" << std::endl; - // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" - printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, - exec_timeE2E, num_iter, currMod); - // std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 - // << " us\n" - std::cout << "INFO: The iterations is: " << num_iter << "\n"; - std::cout << "-------------------------------------------------------" << std::endl; - *p_eachTimeE2E = (1.0 * exec_timeE2E * 1e-6); -} + +/////////////////////////////////////////////////////////// double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, GLV* pglv_iter, int numThreads, @@ -1781,6 +1411,63 @@ void runLouvainWithFPGA_demo_par_core_prune(bool hasGhost, std::vector devices = xcl::get_xil_devices(); int d_num = devices.size(); + + // select device id with multi board + cl_uint platformID = 0; + cl_platform_id* platforms = NULL; + char vendor_name[128] = {0}; + cl_uint num_platforms = 0; + cl_int err2 = clGetPlatformIDs(0, NULL, &num_platforms); + if (CL_SUCCESS != err2) { + std::cout << "INFO: get platform failed" << std::endl; + } + platforms = (cl_platform_id*)malloc(sizeof(cl_platform_id) * num_platforms); + if (NULL == platforms) { + std::cout << "INFO: allocate platform failed" << std::endl; + } + err2 = clGetPlatformIDs(num_platforms, platforms, NULL); + if (CL_SUCCESS != err2) { + std::cout << "INFO: get platform failed" << std::endl; + } + for (cl_uint ui = 0; ui < num_platforms; ++ui) { + err2 = clGetPlatformInfo(platforms[ui], CL_PLATFORM_VENDOR, 128 * sizeof(char), vendor_name, NULL); + if (CL_SUCCESS != err2) { + std::cout << "INFO: get platform failed" << std::endl; + } else if (!std::strcmp(vendor_name, "Xilinx")) { + platformID = ui; + } + } + + uint32_t totalXilinxDevices = devices.size(); + uint32_t totalSupportedDevices_ = 0; + cl_device_id* c_devices = (cl_device_id*)malloc(sizeof(cl_device_id) * totalXilinxDevices); + clGetDeviceIDs(platforms[platformID], CL_DEVICE_TYPE_ALL, totalXilinxDevices, c_devices, NULL); + size_t valueSize; + char* value; + std::vector supportedDeviceNames_; // Supported device names + int XF_GRAPH_L3_MAX_DEVICES_PER_NODE = 4; + uint32_t supportedDeviceIds_[XF_GRAPH_L3_MAX_DEVICES_PER_NODE]; + const std::string token = "xilinx_u55c_gen3x16_xdma_base_2"; + supportedDeviceNames_.push_back(token); + + for (uint32_t i = 0; i < totalXilinxDevices; ++i) { + // print device name + clGetDeviceInfo(c_devices[i], CL_DEVICE_NAME, 0, NULL, &valueSize); + value = new char[valueSize]; + clGetDeviceInfo(c_devices[i], CL_DEVICE_NAME, valueSize, value, NULL); + if (std::find(supportedDeviceNames_.begin(), supportedDeviceNames_.end(), value) != + supportedDeviceNames_.end()) { + std::cout << "INFO: Found requested device: " << value << " ID=" << i << std::endl; + supportedDeviceIds_[totalSupportedDevices_++] = i; // save curret supported supported devices + } else { + std::cout << "INFO: Skipped non-requested device: " << value << " ID=" << i << std::endl; + } + delete[] value; + } + std::cout << "INFO: Total matching devices: " << totalSupportedDevices_ << std::endl; + id_dev = supportedDeviceIds_[0]; + // end the id + if (id_dev >= d_num) { printf("\033[1;31;40mERROR\033[0m: id_dev(%d) >= d_num(%d)\n", id_dev, d_num); return; @@ -1951,6 +1638,142 @@ void runLouvainWithFPGA_demo_par_core_prune(bool hasGhost, timePostPost - timePostPost_feature); // eachTimePhase } // End of runM +// top level +void runLouvainWithFPGA_demo(graphNew* G, + long* C_orig, + char* opts_xclbinPath, + bool opts_coloring, + long opts_minGraphSize, + double opts_threshold, + double opts_C_thresh, + int numThreads) { + long NV = G->numVertices; + long NE_org = G->numEdges; + long numClusters; + assert(NV < MAXNV); + assert(NE_org < MAXNE); + + int* colors; + if (opts_coloring) { + colors = (int*)malloc(G->numVertices * sizeof(int)); + assert(colors != 0); + } + long* C = (long*)malloc(NV * sizeof(long)); + assert(C != 0); +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + C[i] = -1; + } + + std::vector devices = xcl::get_xil_devices(); + int dev_id = 0; + + cl::Device device = devices[dev_id]; + cl::Context context(device); + std::string devName = device.getInfo(); + printf("INFO: Found Device=%s\n", devName.c_str()); + cl::Program::Binaries xclBins = xcl::import_binary_file(opts_xclbinPath); + devices.resize(1); + cl::Program program(context, devices, xclBins); + cl::Kernel kernel_louvain(program, "kernel_louvain"); + printf("INFO: kernel has been created\n"); + cl::CommandQueue q(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); + + KMemorys_host buff_host; + KMemorys_clBuff buff_cl; + long NE_mem = NE_org * 2; // number for real edge to be stored in memory + long NE_mem_1 = NE_mem < (MAXNV) ? NE_mem : (MAXNV); + long NE_mem_2 = NE_mem - NE_mem_1; + UsingFPGA_MapHostClBuff(NV, NE_mem_1, NE_mem_2, context, buff_host, buff_cl); + + double totTimeClustering = 0; // time accumulator for clustering by CPU + double totTimeBuildingPhase = 0; // time accumulator for Building new graphNew for next phase by CPU + double totTimeColoring = 0; // time accumulator for coloring + double prevMod = -1; // Last-phase modularity + double currMod = -1; // Current modularity + int phase = 1; // Total phase counter + int totTimeE2E = 0; // FPGA E2E time accumulator + int num_runsFPGA = 0; // FPGA calling times counter + int totItr = 0; // Total iteration counter + bool nonColor = false; // Make sure that at least one phase with lower opts_threshold runs + bool isItrStop = false; + while (!isItrStop) { + printf("===============================\n"); + printf("Phase %d\n", phase); + printf("===============================\n"); + prevMod = currMod; + bool isUsingFPGA = ((opts_coloring) && (G->numVertices > opts_minGraphSize) && (nonColor == false)); + + if (isUsingFPGA) { + long vertexNum = G->numVertices; + bool isLargeEdge = G->numEdges > (MAXNV / 2); + num_runsFPGA++; + struct timeval tstartE2E, tendE2E; + std::vector ob_in; + std::vector ob_out; + std::vector > kernel_evt0(1); + std::vector > kernel_evt1(1); + kernel_evt0[0].resize(1); + kernel_evt1[0].resize(1); + + PhaseLoop_UsingFPGA_Prep(G, opts_C_thresh, currMod, numThreads, totTimeColoring, colors, buff_host); + + gettimeofday(&tstartE2E, 0); + { /* 5-Step flow for using FPGA */ + PhaseLoop_UsingFPGA_1_KernelSetup(isLargeEdge, kernel_louvain, ob_in, ob_out, buff_cl); + + PhaseLoop_UsingFPGA_2_DataWriteTo(q, kernel_evt0, ob_in); + + PhaseLoop_UsingFPGA_3_KernelRun(q, kernel_evt0, kernel_evt1, kernel_louvain); + + PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); + + PhaseLoop_UsingFPGA_5_KernelFinish(q); + } + gettimeofday(&tendE2E, 0); + + PhaseLoop_UsingFPGA_Post(vertexNum, num_runsFPGA, buff_host, tstartE2E, tendE2E, kernel_evt1, C, totItr, + currMod, totTimeE2E); + } else { + PhaseLoop_UsingCPU(opts_threshold, numThreads, currMod, G, C, C_orig, totItr, nonColor, totTimeClustering); + } + isItrStop = PhaseLoop_CommPostProcessing(NV, numThreads, opts_threshold, opts_coloring, prevMod, currMod, G, C, + C_orig, nonColor, phase, totItr, numClusters, totTimeBuildingPhase); + } + + printf("********************************************\n"); + printf("********* Compact Summary *************\n"); + printf("********************************************\n"); + printf("Number of threads : %d\tm=%d \t thhd=%lf \t thhd_c=%lf\n", numThreads, opts_minGraphSize, + opts_threshold, opts_C_thresh); + printf("Total number of phases : %d\n", phase); + printf("Total number of iterations : %d\n", totItr); + printf("Final number of clusters : %ld\n", numClusters); + printf("Final modularity : %lf\n", prevMod); + printf("Total time for clustering : %lf\n", totTimeClustering); + printf("Total time for building phases : %lf\n", totTimeBuildingPhase); + printf("Total E2E time(s) : %lf\n", (1.0 * totTimeE2E * 1e-6)); + if (opts_coloring) { + printf("Total time for coloring : %lf\n", totTimeColoring); + } + printf("********************************************\n"); + printf("TOTAL TIME : %lf\n", + ((1.0 * totTimeE2E * 1e-6) + totTimeClustering + totTimeBuildingPhase + totTimeColoring)); + printf("********************************************\n"); + + /* Clean up memories */ + free(C); + if (G != 0) { + free(G->edgeListPtrs); + free(G->edgeList); + free(G); + } + if (opts_coloring) { + if (colors != 0) free(colors); + } + buff_host.freeMem(); +} // End of runMultiPhaseLouvainAlgorithm() + GLV* LouvainGLV_general(bool hasGhost, int mode_flow, int id_dev, @@ -2011,3 +1834,260 @@ void LouvainGLV_general_batch_thread(bool hasGhost, timeLv[p] = omp_get_wtime() - time1; } } + +// debug // clean code +// void inline PhaseLoop_Kernel_Enable(cl::Kernel& kernel_louvain, +// cl::CommandQueue& q, +// std::vector& ob_in, +// std::vector& ob_out, +// std::vector >& kernel_evt0, +// std::vector >& kernel_evt1) { +// kernel_evt0[0].resize(1); +// kernel_evt1[0].resize(1); + +// q.enqueueMigrateMemObjects(ob_in, 0, nullptr, kernel_evt0[0].data()); // 0 : migrate from host to dev +// q.enqueueTask(kernel_louvain, &kernel_evt0[0], kernel_evt1[0].data()); +// q.enqueueMigrateMemObjects(ob_out, 1, &kernel_evt1[0], nullptr); // 1 : migrate from dev to host +// q.finish(); +// } + +// void PhaseLoop_UsingFPGA_Post_par_noRead(double* p_eachTimeE2E, +// int num_runsFPGA, +// int num_iter, +// struct timeval& tstartE2E, +// struct timeval& tendE2E, +// // std::vector > &kernel_evt1, +// double currMod, +// int& totTimeE2E) { +// // unsigned long timeStart, timeEnd; +// // kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); +// // kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); +// int exec_timeE2E = diff2(&tendE2E, &tstartE2E); +// totTimeE2E += exec_timeE2E; +// // showing +// // unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; +// std::cout << "-------------------------------------------------------" << std::endl; +// std::cout << "INFO: Finish kernel execution" << std::endl; +// // std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; +// std::cout << "-------------------------------------------------------" << std::endl; +// std::cout << "INFO: Finish E2E execution" << std::endl; +// // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" +// printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, +// exec_timeE2E, num_iter, currMod); +// // std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 +// // << " us\n" +// std::cout << "INFO: The iterations is: " << num_iter << "\n"; +// std::cout << "-------------------------------------------------------" << std::endl; +// *p_eachTimeE2E = (1.0 * exec_timeE2E * 1e-6); +// } + +// double PhaseLoop_UsingFPGA_Prep_Read_buff_host(long vertexNum, +// KMemorys_host& buff_host, +// int phase, +// int eachItrs[MAX_NUM_PHASE], +// // output +// long* C, +// int& totItr, +// double& currMod) { +// double time1 = omp_get_wtime(); +// // updating +// eachItrs[phase - 1] = buff_host.config0[2]; +// totItr += buff_host.config0[2]; +// currMod = buff_host.config1[1]; +// for (int i = 0; i < vertexNum; i++) { +// C[i] = (long)buff_host.cidPrev[i]; +// } +// time1 = omp_get_wtime() - time1; +// return time1; +// } + +// void PhaseLoop_UsingFPGA(long NV, +// double opts_C_thresh, +// bool opts_coloring, +// double opts_threshold, +// int numThreads, +// double& currMod, +// graphNew*& G, +// long*& C, +// long*& C_orig, +// int& totItr, +// KMemorys_host& buff_host, +// KMemorys_clBuff& buff_cl, +// cl::Kernel& kernel_louvain, +// cl::CommandQueue& q, +// int& num_runsFPGA, +// int*& colors, +// int& totTimeE2E, +// double& totTimeColoring) { +// long vertexNum = G->numVertices; +// bool isLargeEdge = G->numEdges > (1 << 25); +// num_runsFPGA++; +// struct timeval tstartE2E, tendE2E; +// std::vector ob_in; +// std::vector ob_out; +// std::vector > kernel_evt0(1); +// std::vector > kernel_evt1(1); +// kernel_evt0[0].resize(1); +// kernel_evt1[0].resize(1); + +// PhaseLoop_UsingFPGA_Prep(G, opts_C_thresh, currMod, numThreads, totTimeColoring, colors, buff_host); +// gettimeofday(&tstartE2E, 0); +// PhaseLoop_UsingFPGA_1_KernelSetup(isLargeEdge, kernel_louvain, ob_in, ob_out, buff_cl); +// PhaseLoop_UsingFPGA_2_DataWriteTo(q, kernel_evt0, ob_in); +// PhaseLoop_UsingFPGA_3_KernelRun(q, kernel_evt0, kernel_evt1, kernel_louvain); +// PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); +// PhaseLoop_UsingFPGA_5_KernelFinish(q); +// gettimeofday(&tendE2E, 0); +// PhaseLoop_UsingFPGA_Post(vertexNum, num_runsFPGA, buff_host, tstartE2E, tendE2E, kernel_evt1, C, totItr, currMod, +// totTimeE2E); +// } + +// double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, +// GLV* pglv_iter, +// int numThreads, +// double opts_threshold, +// bool opts_coloring, +// // modified: +// bool& nonColor, +// int& phase, +// int& totItr, +// long& numClusters, +// double& totTimeBuildingPhase) { +// double time1 = 0; +// time1 = omp_get_wtime(); +// graphNew* Gnew; +// numClusters = renumberClustersContiguously_ghost(pglv_iter->C, pglv_iter->G->numVertices, pglv_iter->NVl); +// printf("Number of unique clusters: %ld\n", numClusters); +// PhaseLoop_UpdatingC_org(phase, pglv_orig->NV, pglv_iter->NV, pglv_iter->C, pglv_orig->C); + +// long* M_new = CreateM(numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M); + +// Gnew = (graphNew*)malloc(sizeof(graphNew)); +// assert(Gnew != 0); +// double tmpTime = buildNextLevelGraphOpt(pglv_iter->G, Gnew, pglv_iter->C, numClusters, numThreads); +// totTimeBuildingPhase += tmpTime; +// pglv_iter->SetByOhterG(Gnew, M_new); +// time1 = omp_get_wtime() - time1; +// return time1; +// } + +// void runLouvainWithFPGA(graphNew* G, // Input graphNew, undirectioned +// long* C_orig, // Output +// char* opts_xclbinPath, +// bool opts_coloring, +// long opts_minGraphSize, +// double opts_threshold, +// double opts_C_thresh, +// int numThreads) { +// long NV = G->numVertices; +// long NE_org = G->numEdges; +// long numClusters; +// /* Check graphNew size, limited by hardware features */ +// assert(NV < MAXNV); +// assert(NE_org < MAXNE); + +// /* For coloring */ +// int* colors; +// if (opts_coloring) { +// colors = (int*)malloc(G->numVertices * sizeof(int)); +// assert(colors != 0); +// } + +// /* To build new hierarchical graphNews*/ +// long* C = (long*)malloc(NV * sizeof(long)); +// assert(C != 0); +// #pragma omp parallel for +// for (long i = 0; i < NV; i++) { +// C[i] = -1; +// } + +// /*******************************/ +// /* FPGA-related data structures*/ +// /*******************************/ +// /* platform related operations */ +// std::vector devices = xcl::get_xil_devices(); +// cl::Device device = devices[0]; +// cl::Context context(device); +// std::string devName = device.getInfo(); +// printf("INFO: Found Device=%s\n", devName.c_str()); +// cl::Program::Binaries xclBins = xcl::import_binary_file(opts_xclbinPath); +// devices.resize(1); +// cl::Program program(context, devices, xclBins); +// cl::Kernel kernel_louvain(program, "kernel_louvain"); +// printf("INFO: kernel has been created\n"); +// cl::CommandQueue q(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); +// /* Memories mapping */ +// KMemorys_host buff_host; +// KMemorys_clBuff buff_cl; +// long NE_mem = NE_org * 2; // number for real edge to be stored in memory +// long NE_mem_1 = NE_mem < (MAXNV) ? NE_mem : (MAXNV); +// long NE_mem_2 = NE_mem - NE_mem_1; +// UsingFPGA_MapHostClBuff(NV, NE_mem_1, NE_mem_2, context, buff_host, buff_cl); + +// /*******************************/ +// /* Loop for phase(s) */ +// /*******************************/ +// double totTimeClustering = 0; // time accumulator for clustering by CPU +// double totTimeBuildingPhase = 0; // time accumulator for Building new graphNew for next phase by CPU +// double totTimeColoring = 0; // time accumulator for coloring +// double prevMod = -1; // Last-phase modularity +// double currMod = -1; // Current modularity +// int phase = 1; // Total phase counter +// int totTimeE2E = 0; // FPGA E2E time accumulator +// int num_runsFPGA = 0; // FPGA calling times counter +// int totItr = 0; // Total iteration counter +// bool nonColor = false; // Make sure that at least one phase with lower opts_threshold runs +// bool isItrStop = false; +// while (!isItrStop) { +// printf("===============================\n"); +// printf("Phase %d\n", phase); +// printf("===============================\n"); +// prevMod = currMod; +// bool isUsingFPGA = ((opts_coloring) && (G->numVertices > opts_minGraphSize) && (nonColor == false)); + +// if (isUsingFPGA) { +// PhaseLoop_UsingFPGA(NV, opts_C_thresh, opts_coloring, opts_threshold, numThreads, currMod, G, C, C_orig, +// totItr, buff_host, buff_cl, kernel_louvain, q, /*kernel's parameter*/ +// num_runsFPGA, colors, totTimeE2E, totTimeColoring); +// } else { +// PhaseLoop_UsingCPU(opts_threshold, numThreads, currMod, G, C, C_orig, totItr, nonColor, +// totTimeClustering); +// } +// /* General post-processing for both FPGA and CPU */ +// isItrStop = PhaseLoop_CommPostProcessing(NV, numThreads, opts_threshold, opts_coloring, prevMod, currMod, G, +// C, +// C_orig, nonColor, phase, totItr, numClusters, totTimeBuildingPhase); +// } // End of while(1) = End of Louvain + +// /* Print information*/ +// printf("********************************************\n"); +// printf("********* Compact Summary *************\n"); +// printf("********************************************\n"); +// printf("Number of threads : %d\n", numThreads); +// printf("Total number of phases : %d\n", phase); +// printf("Total number of iterations : %d\n", totItr); +// printf("Final number of clusters : %ld\n", numClusters); +// printf("Final modularity : %lf\n", prevMod); +// printf("Total time for clustering : %lf\n", totTimeClustering); +// printf("Total time for building phases : %lf\n", totTimeBuildingPhase); +// printf("Total E2E time(s) : %lf\n", (1.0 * totTimeE2E * 1e-6)); +// if (opts_coloring) { +// printf("Total time for coloring : %lf\n", totTimeColoring); +// } +// printf("********************************************\n"); +// printf("TOTAL TIME : %lf\n", +// ((1.0 * totTimeE2E * 1e-6) + totTimeClustering + totTimeBuildingPhase + totTimeColoring)); +// printf("********************************************\n"); + +// /* Clean up memories */ +// free(C); +// if (G != 0) { +// free(G->edgeListPtrs); +// free(G->edgeList); +// free(G); +// } +// if (opts_coloring) { +// if (colors != 0) free(colors); +// } +// buff_host.freeMem(); +// } // End of runMultiPhaseLouvainAlgorithm() diff --git a/graph/L2/benchmarks/louvain_fast/host/partition/test.cpp b/graph/L2/benchmarks/louvain_fast/host/partition/test.cpp index 6c4f498a05..1de9714e46 100644 --- a/graph/L2/benchmarks/louvain_fast/host/partition/test.cpp +++ b/graph/L2/benchmarks/louvain_fast/host/partition/test.cpp @@ -58,7 +58,7 @@ int host_ParserParameters(int argc, int has_numThread = general_findPara(argc, argv, "-thread"); int has_num_par = general_findPara(argc, argv, "-num_par"); int has_gh_par = general_findPara(argc, argv, "-gh_par"); - int has_flow_prune = general_findPara(argc, argv, "-prun"); + int has_flow_prune = general_findPara(argc, argv, "-prun") || general_findPara(argc, argv, "-fast"); if (has_opts_C_thresh != -1) { rec[has_opts_C_thresh] = true; @@ -233,29 +233,8 @@ int LvTest_main_par(int argc, char** argv) { int num_par; int gh_par; bool usingPrune = false; - int numThreads; /*= GetNumThreadsForOpMP(argc, argv); - - - if( general_findPara(argc, argv, "-prun")!=-1 || general_findPara(argc, argv, "-lvprun")!=-1|| - general_findPara(argc, argv, "-fast")!=-1) - { - usingPrune=true; - argc--; - } - host_ParserParameters( - argc, - argv, - opts_C_thresh, //double opts_C_thresh; //Threshold with coloring on - opts_minGraphSize,//long opts_minGraphSize; //Min |V| to enable coloring - opts_threshold, //double opts_threshold; //Value of threshold - opts_ftype, //int opts_ftype; //File type - opts_inFile, //char opts_inFile[4096]; - opts_coloring, //bool opts_coloring; - opts_output, //bool opts_output; - opts_VF, //bool opts_VF; - opts_xclbinPath); + int numThreads; - */ host_ParserParameters(argc, argv, opts_C_thresh, // double opts_C_thresh; //Threshold with coloring on opts_minGraphSize, // long opts_minGraphSize; //Min |V| to enable coloring @@ -273,12 +252,6 @@ int LvTest_main_par(int argc, char** argv) { long NV_begin = pglv_src->G->numVertices; long* C_orig = pglv_src->C; //= (long *) malloc (NV_begin * sizeof(long)); assert(C_orig != 0); - /* #pragma omp parallel for - for (long i=0; i* flagUpdate) { DWEIGHT constant_recip = 0; #pragma HLS INTERFACE m_axi offset = slave bundle = gmem0 port = config0 latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = 4 + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = 6 #pragma HLS INTERFACE m_axi offset = slave bundle = gmem0 port = config1 latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = 4 + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = 4 #pragma HLS INTERFACE m_axi offset = slave bundle = gmem0 port = offsets latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem1 port = indices latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthEdge + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthEdge #pragma HLS INTERFACE m_axi offset = slave bundle = gmem2 port = weights latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthEdge + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthEdge #pragma HLS INTERFACE m_axi offset = slave bundle = gmem3 port = colorAxi latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 16 max_write_burst_length = 16 depth = depthVertex -#pragma HLS INTERFACE m_axi offset = slave bundle = gmem4 port = colorInx latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex +#pragma HLS INTERFACE m_axi offset = slave bundle = gmem3 port = colorInx latency = 32 num_read_outstanding = \ + 64 max_read_burst_length = 16 num_write_outstanding = 16 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem5 port = cidPrev latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem6 port = cidSizePrev latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem7 port = totPrev latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem8 port = cidCurr latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem9 port = cidSizeCurr latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem10 port = totCurr latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem11 port = cidSizeUpdate latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem12 port = totUpdate latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem13 port = cWeight latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem14 port = offsetsDup latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem15 port = indicesDup latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthEdge + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthEdge -#pragma HLS INTERFACE m_axi offset = slave bundle = gmem16 port = flag latency = 32 num_read_outstanding = \ - 32 max_read_burst_length = 2 num_write_outstanding = 32 max_write_burst_length = 2 depth = depthVertex +//#pragma HLS INTERFACE m_axi offset = slave bundle = gmem16 port = flag latency = 32 num_read_outstanding = \ +// 64 max_read_burst_length = 2 num_write_outstanding = 32 max_write_burst_length = 2 depth = depthVertex -#pragma HLS INTERFACE m_axi offset = slave bundle = gmem17 port = flagUpdate latency = 32 num_read_outstanding = \ - 32 max_read_burst_length = 2 num_write_outstanding = 32 max_write_burst_length = 2 depth = depthVertex +//#pragma HLS INTERFACE m_axi offset = slave bundle = gmem17 port = flagUpdate latency = 32 num_read_outstanding = \ +// 64 max_read_burst_length = 2 num_write_outstanding = 32 max_write_burst_length = 2 depth = depthVertex + +#pragma HLS INTERFACE m_axi offset = slave bundle = gmem4 port = flag latency = 32 num_read_outstanding = \ + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex + +#pragma HLS INTERFACE m_axi offset = slave bundle = gmem4 port = flagUpdate latency = 32 num_read_outstanding = \ + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE s_axilite port = config0 bundle = control #pragma HLS INTERFACE s_axilite port = config1 bundle = control diff --git a/graph/L2/benchmarks/louvain_fast/postSysLink.tcl b/graph/L2/benchmarks/louvain_fast/postSysLink.tcl new file mode 100644 index 0000000000..2dc2f67034 --- /dev/null +++ b/graph/L2/benchmarks/louvain_fast/postSysLink.tcl @@ -0,0 +1 @@ +set_property -dict [list CONFIG.ECC_EN {false} CONFIG.ECC_SCRUB_EN {false}] [get_bd_cells hmss_0] diff --git a/graph/L2/include/hw/louvain_samecolor.hpp b/graph/L2/include/hw/louvain_samecolor.hpp index 2768aee88e..54be1211fb 100644 --- a/graph/L2/include/hw/louvain_samecolor.hpp +++ b/graph/L2/include/hw/louvain_samecolor.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2020 Xilinx, Inc. + * Copyright 2021 Xilinx, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +/** + * @file dut.h + * + * @brief This file contains top function of test case. + */ #ifndef _LOUVAIN_SAMECOLOR_H_ #define _LOUVAIN_SAMECOLOR_H_ @@ -43,13 +47,13 @@ namespace xf { namespace graph { template -void _new_bus(bool use_push_flag, - ap_uint* flag, - int coloradj1, - int coloradj2, - ap_uint* colorInx, - ap_uint* offset, - hls::stream >& str_GetVout) { +void SameColor_GetV(bool use_push_flag, + ap_uint* flag, + int coloradj1, + int coloradj2, + ap_uint* colorInx, + ap_uint* offset, + hls::stream >& str_GetVout) { StrmBus_M out_v; ap_uint<96> dinout; @@ -158,6 +162,8 @@ void SameColor_GetFlag3(hls::stream& str_pushV, ap_uint* offset, if (pushV >= 0) { adj1 = AxiRead<8, 5>(offset, pushV); // axi_offset.rdi(v); adj2 = AxiRead<8, 5>(offset, pushV + 1); + adj1 = 0x7fffffff & adj1; + adj2 = 0x7fffffff & adj2; e_dgr = adj2 - adj1; out_v.vod.set(pushV, adj1, e_dgr); out_v.vod.get(dinout); @@ -231,6 +237,11 @@ void SameColor_GetE(ap_uint* index, if ((d + 0) == e_dgr) { str_GetVout.read(dinout); u_vod.vod.get(dinout, v, off, e_dgr); + if (e_dgr <= 0 && (off > 0)) { + e_dgr = 0; // when off!=0 & dgr<=0 reset + d = 0; + continue; + } u_vd_ew.vd.set(dinout, v, e_dgr); str_GetEout.write(dinout); d = 0; @@ -469,6 +480,8 @@ void SameColor_GetBest_Update_Gain_step1(short scl, ap_uint<128> dinout; ap_uint<160> dout; + bool readnew = false; + GetKins_e = false; d = 0; numComm = 0; @@ -571,6 +584,151 @@ void SameColor_GetBest_Update_Gain_step1(short scl, str_GainUpdate.write(vf); } +template +void SameColor_GetBest_Update_Gain_step_II1(short scl, + hls::stream >& str_Aggout, + DF_W_T constant_recip, + ap_uint* totPrev, + // output + // hls::stream >& done, + // hls::stream >& doneupdate, + hls::stream& str_GainUpdate, + hls::stream >& str_Gainout) { + double constant = (1.0 / constant_recip); + long long constant_i = (long long)constant; + int scl_2 = 10; + + AxiMap axi_totPrev(totPrev); + // AxiMap axi_commWeight(commWeight); + StrmBus_S vf; + + DF_WI_T constant_i_scl = ToInt(constant, 0); + DF_V_T v, vCid, target, best_comm; + DF_W_T selfloop, ki, ei_u, a_u, best_gain; + DF_WI_T selfloop_i, ki_i, ei_u_i, a_u_i; + DF_WI_T best_gain_i; + DF_D_T degree, numComm, d; + DF_W_T kinCk_0_; + DF_V_T Ck_0; + bool GetKins_e; + StrmBus_L vcdn, kisf, ckkin; + StrmBus_M vcn, m_ki; + StrmBus_XL vcnki, cgain, vcnki_tmp; + ap_uint<128> dinout; + ap_uint<160> dout; + + bool readnew = false; + GetKins_e = false; + d = 0; + numComm = 0; +GET_BEST: + while (GetKins_e == false) { +#pragma HLS LOOP_TRIPCOUNT MIN = 1 MAX = 1000000 + +#pragma HLS PIPELINE II = 1 +#pragma HLS DEPENDENCE variable = totPrev inter false + if (d == numComm && !readnew) { + str_Aggout.read(dinout); + vcdn.vcdn.set(dinout); + vcdn.vcdn.get(v, vCid, degree, numComm); + if (degree < 0) numComm = -1; + vcn.vcn.set(v, vCid, numComm); + vcnki.vcnk.set(v, vCid, numComm, 0.0); + GetKins_e = degree < 0; + + if (GetKins_e == false) { + readnew = true; + } + } else if (readnew) { + if (GetKins_e == false) { + str_Aggout.read(dinout); + kisf.kisf.set(dinout); + selfloop = degree > 0 ? kisf.kisf.self : 0; + ki = degree > 0 ? kisf.kisf.ki : 0; + vcnki.vcnk.ki = degree > 0 ? kisf.kisf.ki : 0; + d = 0; + ki_i = ToInt(ki, scl_2); +#ifndef __SYNTHESIS__ +#ifdef _DEBUG_GAIN + printf("GAIN: v=%d\t, vCid=%d\t, degree=%d\t, numComm=%d\t, ki=%f\t, selfloop=%f\t \n", v, vCid, degree, + numComm, ki, selfloop); +#endif +#endif + } + vcnki.vcnk.get(dout); + vcnki_tmp.vcnk.set(dout); + str_Gainout.write(dout); + readnew = false; + } else if (GetKins_e == false) + if (degree > 0) { + if (d == 0) { + str_Aggout.read(dinout); + ckkin.n_ckk.set(dinout); + kinCk_0_ = ckkin.n_ckk.kin; + Ck_0 = ckkin.n_ckk.ck; + best_gain = 0; + best_comm = vCid; + // commWeight[v] = kinCk_0_; + vf.vf.set(v, (float)kinCk_0_); + str_GainUpdate.write(vf); + // axi_commWeight.wr(v, (float)kinCk_0_); + ei_u = kinCk_0_ - selfloop; + // a_u = totPrev[vCid]-ki; + a_u = axi_totPrev.rdf(vCid) - ki; + best_gain_i = 0; + ei_u_i = ToInt(ei_u, scl_2 * 2); + a_u_i = ToInt(a_u, scl_2); + d = 1; + cgain.cgi.set(vCid, best_gain_i); + cgain.cgi.get(dout); + str_Gainout.write(dout); +#ifndef __SYNTHESIS__ +#ifdef _DEBUG_GAIN + printf("GAIN: vCid=%d\t, best_gain_i%x\t \n", vCid, best_gain_i); +#endif +#endif + } else if (d < numComm) { + str_Aggout.read(dinout); + ckkin.n_ckk.set(dinout); + DF_V_T eCid = ckkin.n_ckk.ck; + DF_W_T ei_v = ckkin.n_ckk.kin; + // DF_W_T a_v = totPrev[eCid]; + DF_W_T a_v = axi_totPrev.rdf(eCid); + ; + DF_W_T diff_e = (ei_v - ei_u); + DF_W_T diff_a = (a_v - a_u); + DF_W_T v_pos = diff_e * constant; + DF_W_T v_neg = diff_a * ki; + DF_W_T curr_gain_org = v_pos - v_neg; + DF_WI_T ei_v_i = ToInt(ei_v, scl_2 * 2); + DF_WI_T a_v_i = ToInt(a_v, scl_2); + DF_WI_T diff_e_i = (ei_v_i - ei_u_i); + DF_WI_T diff_a_i = (a_v_i - a_u_i); + DF_WI_T v_pos_i = diff_e_i * constant_i_scl; + DF_WI_T v_neg_i = diff_a_i * ki_i; + DF_WI_T curr_gain_i = v_pos_i - v_neg_i; + DF_W_T curr_gain = (curr_gain_i >> (scl_2 * 2)); + cgain.cgi.set(eCid, curr_gain_i); + cgain.cgi.get(dout); + str_Gainout.write(dout); +#ifndef __SYNTHESIS__ +#ifdef _DEBUG_GAIN + printf("GAIN: d=%d\t, eCid=%d\t, curr_gain_i%x\t \n", d, eCid, curr_gain_i); +#endif +#endif + d++; + } + } + } + + vcnki.vcnk.get(dout); + vcnki_tmp.vcnk.set(dout); + str_Gainout.write(dout); + + vf.vf.set(-1, -1); + str_GainUpdate.write(vf); +} + template void SameColor_GetBest_Update_TOT_Csize_hash3(short scl, int& moves, @@ -991,7 +1149,7 @@ void SameColor_dataflow(int numVertex, hls::stream > str_GetVout("str_GetVout"); #pragma HLS RESOURCE variable = str_GetVout core = FIFO_SRL #pragma HLS STREAM variable = str_GetVout depth = 256 - _new_bus(use_push_flag, flag, coloradj1, coloradj2, colorInx, offset, str_GetVout); + SameColor_GetV(use_push_flag, flag, coloradj1, coloradj2, colorInx, offset, str_GetVout); hls::stream > str_GetEout("str_GetEout"); #pragma HLS RESOURCE variable = str_GetEout core = FIFO_LUTRAM @@ -1015,8 +1173,8 @@ void SameColor_dataflow(int numVertex, #pragma HLS RESOURCE variable = str_Gainout_update core = FIFO_LUTRAM #pragma HLS STREAM variable = str_Gainout_update depth = 256 // SameColor_GetBest_Update_Gain_bus3(scl, str_Aggout, constant_recip, totPrev, commWeight, str_Gainout); - SameColor_GetBest_Update_Gain_step1(scl, str_Aggout, constant_recip, totPrev, str_Gainout_update, - str_Gainout); + SameColor_GetBest_Update_Gain_step_II1(scl, str_Aggout, constant_recip, totPrev, str_Gainout_update, + str_Gainout); SameColor_GetBest_Update_Gain_step2(commWeight, str_Gainout_update); hls::stream str_Cidout("str_Cidout"); diff --git a/graph/L2/include/hw/louvain_samecolor_hash_agg.hpp b/graph/L2/include/hw/louvain_samecolor_hash_agg.hpp index 129caa1101..4a16cc05c8 100644 --- a/graph/L2/include/hw/louvain_samecolor_hash_agg.hpp +++ b/graph/L2/include/hw/louvain_samecolor_hash_agg.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2020 Xilinx, Inc. + * Copyright 2021 Xilinx, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -381,6 +381,13 @@ template void SameColor_GetKins_HashAgg_big(short scl, hls::stream >& str_GetCout, hls::stream >& str_Aggout) { +#ifndef __SYNTHESIS__ + CkKins* ckkins = (CkKins*)malloc((1 << LG2_W_HASHADDR) * sizeof(CkKins)); + CkKins* ckkins_s = (CkKins*)malloc((1 << LG2_W_HASHADDR) * sizeof(CkKins)); + ValAddr* valAdd = (ValAddr*)malloc((1 << LG2_W_HASHADDR) * sizeof(ValAddr)); + + ap_uint<1 << LG2_W_MEMPORT>* mem_used = (ap_uint<1 << LG2_W_MEMPORT>*)malloc((1 << (LG2_W_HASHADDR - LG2_W_MEMPORT)) * sizeof(ap_uint<1 << LG2_W_MEMPORT>)); +#else CkKins ckkins[1 << LG2_W_HASHADDR]; #pragma HLS RESOURCE variable = ckkins core = RAM_T2P_URAM CkKins ckkins_s[1 << LG2_W_HASHADDR]; @@ -389,6 +396,7 @@ void SameColor_GetKins_HashAgg_big(short scl, #pragma HLS RESOURCE variable = valAdd core = RAM_T2P_URAM ap_uint<1 << LG2_W_MEMPORT> mem_used[1 << (LG2_W_HASHADDR - LG2_W_MEMPORT)]; #pragma HLS RESOURCE variable = mem_used core = RAM_T2P_URAM +#endif HashAgg myHash(ckkins, valAdd, mem_used); ScanAgg myScan(ckkins_s); @@ -568,6 +576,72 @@ static void SameColor_GetKins_hash_dispatch(int th_2, } } +static void SameColor_GetKins_hash_dispatch4(int th_2, + // input + hls::stream >& str_GetCout, + // output + hls::stream >& str_GetCout0, + hls::stream >& str_GetCout1, + hls::stream >& str_GetCout3, + hls::stream >& str_GetCout4, + hls::stream >& str_GetCout2) { + ap_uint<2> select_0 = 0; + short pre_degree_0; + short pre_degree_1; + short pre_degree_2; + short pre_degree_3; + bool e_GetC = false; + DF_V_T v; + DF_V_T vCid; + DF_D_T degree; + DF_W_T deg_w; + DF_V_T edge; + DF_V_T eCid; + StrmBus_L cout; + ap_uint<128> dinout; + +GET_KIN_DISPATCH: + while (e_GetC == false) { + str_GetCout.read(dinout); + cout.vcde.get(dinout, v, vCid, degree, e_GetC); + if (e_GetC == false) { + if (degree < th_2) { + if (select_0 == 0) { + str_GetCout0.write(dinout); + dispatch_send_ewc(degree, str_GetCout, str_GetCout0); + select_0 = 1; + pre_degree_0 = degree; + } else if (select_0 == 1) { + str_GetCout1.write(dinout); + dispatch_send_ewc(degree, str_GetCout, str_GetCout1); + select_0 = 2; // zyl + pre_degree_1 = degree; + } else if (select_0 == 2) { + str_GetCout3.write(dinout); + dispatch_send_ewc(degree, str_GetCout, str_GetCout3); + select_0 = 3; // zyl + pre_degree_2 = degree; + } else if (select_0 == 3) { + str_GetCout4.write(dinout); + dispatch_send_ewc(degree, str_GetCout, str_GetCout4); + select_0 = 0; // zyl + pre_degree_3 = degree; + } + } else { + str_GetCout2.write(dinout); + dispatch_send_ewc(degree, str_GetCout, str_GetCout2); + } + } else { + cout.vcde.set(0, 0, 0, true); + str_GetCout0.write(dinout); + str_GetCout1.write(dinout); + str_GetCout3.write(dinout); + str_GetCout4.write(dinout); + str_GetCout2.write(dinout); + } + } +} + static bool Collector_bus_vcde_ewc(hls::stream >& str_Aggout1, hls::stream >& str_Aggout) { #pragma HLS INLINE StrmBus_L vcdn; @@ -631,9 +705,115 @@ static void SameColor_GetKins_hash_Collector( str_Aggout.write(dinout); } +static void SameColor_GetKins_hash_Collector( + // input + hls::stream >& str_Aggout0, + hls::stream >& str_Aggout1, + hls::stream >& str_Aggout3, + hls::stream >& str_Aggout4, + + hls::stream >& str_Aggout2, + // output + // hls::stream >& done, + hls::stream >& str_Aggout) { + ap_uint<128> dinout; + ap_uint<3> selected = 0; + bool e_0 = false; + bool e_1 = false; + bool e_3 = false; + bool e_4 = false; + bool e_2 = false; + bool e01234 = e_0 & e_1 & e_2 & e_3 & e_4; + while (e01234 == false) { + if (selected == 0) { + if (!str_Aggout0.empty()) e_0 = Collector_bus_vcde_ewc(str_Aggout0, str_Aggout); + if (!str_Aggout1.empty()) e_1 = Collector_bus_vcde_ewc(str_Aggout1, str_Aggout); + if (!str_Aggout3.empty()) e_3 = Collector_bus_vcde_ewc(str_Aggout3, str_Aggout); + if (!str_Aggout4.empty()) e_4 = Collector_bus_vcde_ewc(str_Aggout4, str_Aggout); + if (!str_Aggout2.empty()) e_2 = Collector_bus_vcde_ewc(str_Aggout2, str_Aggout); + selected = 1; + } else if (selected == 1) { + if (!str_Aggout1.empty()) e_1 = Collector_bus_vcde_ewc(str_Aggout1, str_Aggout); + if (!str_Aggout3.empty()) e_3 = Collector_bus_vcde_ewc(str_Aggout3, str_Aggout); + if (!str_Aggout4.empty()) e_4 = Collector_bus_vcde_ewc(str_Aggout4, str_Aggout); + if (!str_Aggout2.empty()) e_2 = Collector_bus_vcde_ewc(str_Aggout2, str_Aggout); + if (!str_Aggout0.empty()) e_0 = Collector_bus_vcde_ewc(str_Aggout0, str_Aggout); + selected = 2; + } else if (selected == 2) { + if (!str_Aggout3.empty()) e_3 = Collector_bus_vcde_ewc(str_Aggout3, str_Aggout); + if (!str_Aggout4.empty()) e_4 = Collector_bus_vcde_ewc(str_Aggout4, str_Aggout); + if (!str_Aggout2.empty()) e_2 = Collector_bus_vcde_ewc(str_Aggout2, str_Aggout); + if (!str_Aggout0.empty()) e_0 = Collector_bus_vcde_ewc(str_Aggout0, str_Aggout); + if (!str_Aggout1.empty()) e_1 = Collector_bus_vcde_ewc(str_Aggout1, str_Aggout); + selected = 3; + } else if (selected == 3) { + if (!str_Aggout4.empty()) e_4 = Collector_bus_vcde_ewc(str_Aggout4, str_Aggout); + if (!str_Aggout2.empty()) e_2 = Collector_bus_vcde_ewc(str_Aggout2, str_Aggout); + if (!str_Aggout0.empty()) e_0 = Collector_bus_vcde_ewc(str_Aggout0, str_Aggout); + if (!str_Aggout1.empty()) e_1 = Collector_bus_vcde_ewc(str_Aggout1, str_Aggout); + if (!str_Aggout3.empty()) e_3 = Collector_bus_vcde_ewc(str_Aggout3, str_Aggout); + selected = 4; + } else { + if (!str_Aggout2.empty()) e_2 = Collector_bus_vcde_ewc(str_Aggout2, str_Aggout); + if (!str_Aggout0.empty()) e_0 = Collector_bus_vcde_ewc(str_Aggout0, str_Aggout); + if (!str_Aggout1.empty()) e_1 = Collector_bus_vcde_ewc(str_Aggout1, str_Aggout); + if (!str_Aggout3.empty()) e_3 = Collector_bus_vcde_ewc(str_Aggout3, str_Aggout); + if (!str_Aggout4.empty()) e_4 = Collector_bus_vcde_ewc(str_Aggout4, str_Aggout); + selected = 0; + } + e01234 = e_0 & e_1 & e_2 & e_3 & e_4; + } + StrmBus_L bus_out; + bus_out.vcdn.set(0, 0, -2, -2); + bus_out.vcdn.get(dinout); + str_Aggout.write(dinout); + // done.write(true); +} + +// static void SameColor_GetKins_hash_top(short scl, +// // input +// hls::stream >& str_GetCout, +// hls::stream >& str_Aggout) { +//#pragma HLS DATAFLOW +// // +// hls::stream > str_GetCout0("str_GetCout0"); +//#pragma HLS RESOURCE variable = str_GetCout0 core = FIFO_LUTRAM +//#pragma HLS STREAM variable = str_GetCout0 depth = 128 +// hls::stream > str_GetCout1("str_GetCout1"); +//#pragma HLS RESOURCE variable = str_GetCout1 core = FIFO_LUTRAM +//#pragma HLS STREAM variable = str_GetCout1 depth = 128 +// hls::stream > str_GetCout2("str_GetCout2"); +//#pragma HLS RESOURCE variable = str_GetCout2 core = FIFO_LUTRAM +//#pragma HLS STREAM variable = str_GetCout2 depth = 128 +// SameColor_GetKins_hash_dispatch(63, +// // input +// str_GetCout, str_GetCout0, str_GetCout1, str_GetCout2); +// +// hls::stream > str_GetAggout0("str_GetAggout0"); +//#pragma HLS RESOURCE variable = str_GetAggout0 core = FIFO_LUTRAM +//#pragma HLS STREAM variable = str_GetAggout0 depth = 128 +// SameColor_GetKins_HashAgg_small(scl, str_GetCout0, str_GetAggout0); +// +// hls::stream > str_GetAggout1("str_GetAggout1"); +//#pragma HLS RESOURCE variable = str_GetAggout1 core = FIFO_LUTRAM +//#pragma HLS STREAM variable = str_GetAggout1 depth = 128 +// +// SameColor_GetKins_HashAgg_small(scl, str_GetCout1, str_GetAggout1); +// +// hls::stream > str_GetAggout2("str_GetAggout2"); +//#pragma HLS RESOURCE variable = str_GetAggout2 core = FIFO_LUTRAM +//#pragma HLS STREAM variable = str_GetAggout2 depth = 128 +// const int LG2_NUM_HASH = 17; +// const int LG2_BITS_MEM = 10; +// SameColor_GetKins_HashAgg_big(scl, str_GetCout2, str_GetAggout2); +// +// SameColor_GetKins_hash_Collector(str_GetAggout0, str_GetAggout1, str_GetAggout2, str_Aggout); +//} + static void SameColor_GetKins_hash_top(short scl, // input hls::stream >& str_GetCout, + // hls::stream >& done, hls::stream >& str_Aggout) { #pragma HLS DATAFLOW // @@ -643,12 +823,20 @@ static void SameColor_GetKins_hash_top(short scl, hls::stream > str_GetCout1("str_GetCout1"); #pragma HLS RESOURCE variable = str_GetCout1 core = FIFO_LUTRAM #pragma HLS STREAM variable = str_GetCout1 depth = 128 + + hls::stream > str_GetCout3("str_GetCout1"); +#pragma HLS RESOURCE variable = str_GetCout3 core = FIFO_LUTRAM +#pragma HLS STREAM variable = str_GetCout3 depth = 128 + hls::stream > str_GetCout4("str_GetCout1"); +#pragma HLS RESOURCE variable = str_GetCout4 core = FIFO_LUTRAM +#pragma HLS STREAM variable = str_GetCout4 depth = 128 + hls::stream > str_GetCout2("str_GetCout2"); #pragma HLS RESOURCE variable = str_GetCout2 core = FIFO_LUTRAM #pragma HLS STREAM variable = str_GetCout2 depth = 128 - SameColor_GetKins_hash_dispatch(63, - // input - str_GetCout, str_GetCout0, str_GetCout1, str_GetCout2); + SameColor_GetKins_hash_dispatch4(63, + // input + str_GetCout, str_GetCout0, str_GetCout1, str_GetCout3, str_GetCout4, str_GetCout2); hls::stream > str_GetAggout0("str_GetAggout0"); #pragma HLS RESOURCE variable = str_GetAggout0 core = FIFO_LUTRAM @@ -661,6 +849,18 @@ static void SameColor_GetKins_hash_top(short scl, SameColor_GetKins_HashAgg_small(scl, str_GetCout1, str_GetAggout1); + hls::stream > str_GetAggout3("str_GetAggout3"); +#pragma HLS RESOURCE variable = str_GetAggout3 core = FIFO_LUTRAM +#pragma HLS STREAM variable = str_GetAggout3 depth = 128 + + SameColor_GetKins_HashAgg_small(scl, str_GetCout3, str_GetAggout3); + + hls::stream > str_GetAggout4("str_GetAggout4"); +#pragma HLS RESOURCE variable = str_GetAggout4 core = FIFO_LUTRAM +#pragma HLS STREAM variable = str_GetAggout4 depth = 128 + + SameColor_GetKins_HashAgg_small(scl, str_GetCout4, str_GetAggout4); + hls::stream > str_GetAggout2("str_GetAggout2"); #pragma HLS RESOURCE variable = str_GetAggout2 core = FIFO_LUTRAM #pragma HLS STREAM variable = str_GetAggout2 depth = 128 @@ -668,9 +868,9 @@ static void SameColor_GetKins_hash_top(short scl, const int LG2_BITS_MEM = 10; SameColor_GetKins_HashAgg_big(scl, str_GetCout2, str_GetAggout2); - SameColor_GetKins_hash_Collector(str_GetAggout0, str_GetAggout1, str_GetAggout2, str_Aggout); + SameColor_GetKins_hash_Collector(str_GetAggout0, str_GetAggout1, str_GetAggout3, str_GetAggout4, str_GetAggout2, + str_Aggout); // done } - } // graph } // xf #endif diff --git a/graph/L2/include/hw/xilinxlouvain.hpp b/graph/L2/include/hw/xilinxlouvain.hpp index a5568a8ffc..d8616e0dd2 100644 --- a/graph/L2/include/hw/xilinxlouvain.hpp +++ b/graph/L2/include/hw/xilinxlouvain.hpp @@ -38,8 +38,13 @@ using namespace std; #define CSRWIDTHS (256) #define COLORWIDTHS (32) #define NUM (DWIDTHS / 32) +#ifndef USE_U55C #define MAXNV (1 << 26) #define MAXNE (1 << 27) +#else +#define MAXNV (1 << 27) +#define MAXNE (1 << 28) +#endif #define VERTEXS (MAXNV / NUM) #define EDGES (MAXNE / NUM) #define DEGREES (1 << 17) diff --git a/graph/L2/tests/louvain_fast/Makefile b/graph/L2/tests/louvain_fast/Makefile index 72a98d59ab..022b0f57aa 100644 --- a/graph/L2/tests/louvain_fast/Makefile +++ b/graph/L2/tests/louvain_fast/Makefile @@ -55,8 +55,12 @@ endif # #################### Checking if DEVICE in whitelist ############################ ifneq ($(findstring u50, $(DEVICE)), u50) +ifneq ($(findstring u280, $(DEVICE)), u280) +ifneq ($(findstring u55c, $(DEVICE)), u55c) $(warning [WARNING]: This project has not been tested for $(DEVICE). It may or may not work.) endif +endif +endif # ######################## Setting up Project Variables ################################# MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) @@ -119,22 +123,22 @@ endif # ######################### Host compiler global settings ############################ CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++11 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -pthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE -CXXFLAGS += -fmessage-length=0 -O3 -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD +LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE +CXXFLAGS += -fmessage-length=0 -O3 -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD -B/usr/lib/x86_64-linux-gnu CXXFLAGS += -I$(CUR_DIR)/src/ ifeq ($(HOST_ARCH), x86) LDFLAGS += -L$(XILINX_HLS)/lnx64/tools/fpo_v7_0 -Wl,--as-needed -lgmp -lmpfr -lIp_floating_point_v7_0_bitacc_cmodel endif -ifneq (,$(shell echo $(XPLATFORM) | awk '/u50/')) -CXXFLAGS += -D USE_HBM +ifneq (,$(shell echo $(XPLATFORM) | awk '/u55c/')) +CXXFLAGS += -D USE_U55C endif # ################### Setting package and image directory ####################### EXE_NAME := host.exe EXE_FILE := $(BUILD_DIR)/$(EXE_NAME) -HOST_ARGS := -x $(BUILD_DIR)/kernel_louvain.xclbin -f 3 -c -m 10000 -prun $(CUR_DIR)/data/example-wt.txt +HOST_ARGS := -x $(BUILD_DIR)/kernel_louvain.xclbin -f 3 -c -m 10000 $(CUR_DIR)/data/example-wt.txt -prun LIBRARY_PATH =$(LD_LIBRARY_PATH):$(XILINX_XRT)/lib # ##################### Kernel compiler global settings ########################## @@ -142,7 +146,15 @@ VPP_FLAGS += -t $(TARGET) --platform $(XPLATFORM) --save-temps --optimize 2 VPP_FLAGS += --hls.jobs 8 VPP_LDFLAGS += --vivado.synth.jobs 8 --vivado.impl.jobs 8 ifneq (,$(shell echo $(XPLATFORM) | awk '/u50/')) -VPP_FLAGS += --config $(CUR_DIR)/conn_u50_u280.cfg +VPP_FLAGS += --config $(CUR_DIR)/conn_u50_u280.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=$(CUR_DIR)/postSysLink.tcl +endif + +ifneq (,$(shell echo $(XPLATFORM) | awk '/u280/')) +VPP_FLAGS += --config $(CUR_DIR)/conn_u50_u280.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=$(CUR_DIR)/postSysLink.tcl +endif + +ifneq (,$(shell echo $(XPLATFORM) | awk '/u55c/')) +VPP_FLAGS += --config $(CUR_DIR)/conn_u55c.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=$(CUR_DIR)/postSysLink.tcl endif VPP_FLAGS += -I$(XFLIB_DIR)/L2/include @@ -156,8 +168,8 @@ VPP_FLAGS += -I$(XFLIB_DIR)/../utils/L1/include VPP_FLAGS += -I$(XFLIB_DIR)/L2/tests/louvain_fast/kernel kernel_louvain_VPP_FLAGS += -D KERNEL_NAME=kernel_louvain -kernel_louvain_VPP_FLAGS += --hls.clock 300000000:kernel_louvain -VPP_LDFLAGS_kernel_louvain += --kernel_frequency 300 +kernel_louvain_VPP_FLAGS += --hls.clock 250000000:kernel_louvain +VPP_LDFLAGS_kernel_louvain += --kernel_frequency 250 # Kernel args diff --git a/graph/L2/tests/louvain_fast/conn_u50_u280.cfg b/graph/L2/tests/louvain_fast/conn_u50_u280.cfg index d74678fb78..df61ca1fd3 100644 --- a/graph/L2/tests/louvain_fast/conn_u50_u280.cfg +++ b/graph/L2/tests/louvain_fast/conn_u50_u280.cfg @@ -2,20 +2,26 @@ sp=kernel_louvain.m_axi_gmem0:HBM[4] sp=kernel_louvain.m_axi_gmem1:HBM[0:1] sp=kernel_louvain.m_axi_gmem2:HBM[2:3] -sp=kernel_louvain.m_axi_gmem3:HBM[6] -sp=kernel_louvain.m_axi_gmem4:HBM[8] -sp=kernel_louvain.m_axi_gmem5:HBM[10] -sp=kernel_louvain.m_axi_gmem6:HBM[12] -sp=kernel_louvain.m_axi_gmem7:HBM[14] -sp=kernel_louvain.m_axi_gmem8:HBM[16] -sp=kernel_louvain.m_axi_gmem9:HBM[18] -sp=kernel_louvain.m_axi_gmem10:HBM[20] -sp=kernel_louvain.m_axi_gmem11:HBM[22] -sp=kernel_louvain.m_axi_gmem12:HBM[24] -sp=kernel_louvain.m_axi_gmem13:HBM[26] -sp=kernel_louvain.m_axi_gmem14:HBM[27] -sp=kernel_louvain.m_axi_gmem15:HBM[28:29] -sp=kernel_louvain.m_axi_gmem16:HBM[7] -sp=kernel_louvain.m_axi_gmem17:HBM[9] +sp=kernel_louvain.m_axi_gmem3:HBM[5:6] +sp=kernel_louvain.m_axi_gmem4:HBM[5:6] +sp=kernel_louvain.m_axi_gmem5:HBM[7] +sp=kernel_louvain.m_axi_gmem6:HBM[8] +sp=kernel_louvain.m_axi_gmem7:HBM[9] +sp=kernel_louvain.m_axi_gmem8:HBM[10] +sp=kernel_louvain.m_axi_gmem9:HBM[11] +sp=kernel_louvain.m_axi_gmem10:HBM[12] +sp=kernel_louvain.m_axi_gmem11:HBM[13] +sp=kernel_louvain.m_axi_gmem12:HBM[14] +sp=kernel_louvain.m_axi_gmem13:HBM[15] +sp=kernel_louvain.m_axi_gmem14:HBM[4] +sp=kernel_louvain.m_axi_gmem15:HBM[0:1] slr=kernel_louvain:SLR0 nk=kernel_louvain:1:kernel_louvain +[vivado] +prop=run.impl_1.STEPS.OPT_DESIGN.ARGS.DIRECTIVE=Explore +prop=run.impl_1.STEPS.PLACE_DESIGN.ARGS.DIRECTIVE=ExtraNetDelay_low +prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.IS_ENABLED=true +prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.ARGS.DIRECTIVE=AggressiveExplore +prop=run.impl_1.STEPS.ROUTE_DESIGN.ARGS.DIRECTIVE=NoTimingRelaxation +prop=run.impl_1.{STEPS.ROUTE_DESIGN.ARGS.MORE OPTIONS}={-tns_cleanup} +prop=run.impl_1.STEPS.POST_ROUTE_PHYS_OPT_DESIGN.IS_ENABLED=true diff --git a/graph/L2/tests/louvain_fast/conn_u55c.cfg b/graph/L2/tests/louvain_fast/conn_u55c.cfg new file mode 100644 index 0000000000..3c2784aaaa --- /dev/null +++ b/graph/L2/tests/louvain_fast/conn_u55c.cfg @@ -0,0 +1,43 @@ +[connectivity] +sp=kernel_louvain_0.m_axi_gmem0:HBM[4] +sp=kernel_louvain_0.m_axi_gmem1:HBM[0:1] +sp=kernel_louvain_0.m_axi_gmem2:HBM[2:3] +sp=kernel_louvain_0.m_axi_gmem3:HBM[5:6] +sp=kernel_louvain_0.m_axi_gmem4:HBM[5:6] +sp=kernel_louvain_0.m_axi_gmem5:HBM[7] +sp=kernel_louvain_0.m_axi_gmem6:HBM[8] +sp=kernel_louvain_0.m_axi_gmem7:HBM[9] +sp=kernel_louvain_0.m_axi_gmem8:HBM[10] +sp=kernel_louvain_0.m_axi_gmem9:HBM[11] +sp=kernel_louvain_0.m_axi_gmem10:HBM[12] +sp=kernel_louvain_0.m_axi_gmem11:HBM[13] +sp=kernel_louvain_0.m_axi_gmem12:HBM[14] +sp=kernel_louvain_0.m_axi_gmem13:HBM[15] +sp=kernel_louvain_0.m_axi_gmem14:HBM[4] +sp=kernel_louvain_0.m_axi_gmem15:HBM[0:1] + +sp=kernel_louvain_1.m_axi_gmem0:HBM[20] +sp=kernel_louvain_1.m_axi_gmem1:HBM[16:17] +sp=kernel_louvain_1.m_axi_gmem2:HBM[18:19] +sp=kernel_louvain_1.m_axi_gmem3:HBM[21:22] +sp=kernel_louvain_1.m_axi_gmem4:HBM[21:22] +sp=kernel_louvain_1.m_axi_gmem5:HBM[23] +sp=kernel_louvain_1.m_axi_gmem6:HBM[24] +sp=kernel_louvain_1.m_axi_gmem7:HBM[25] +sp=kernel_louvain_1.m_axi_gmem8:HBM[26] +sp=kernel_louvain_1.m_axi_gmem9:HBM[27] +sp=kernel_louvain_1.m_axi_gmem10:HBM[28] +sp=kernel_louvain_1.m_axi_gmem11:HBM[29] +sp=kernel_louvain_1.m_axi_gmem12:HBM[30] +sp=kernel_louvain_1.m_axi_gmem13:HBM[31] +sp=kernel_louvain_1.m_axi_gmem14:HBM[20] +sp=kernel_louvain_1.m_axi_gmem15:HBM[16:17] +nk=kernel_louvain:2:kernel_louvain_0.kernel_louvain_1 +[vivado] +prop=run.impl_1.STEPS.OPT_DESIGN.ARGS.DIRECTIVE=Explore +prop=run.impl_1.STEPS.PLACE_DESIGN.ARGS.DIRECTIVE=ExtraNetDelay_low +prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.IS_ENABLED=true +prop=run.impl_1.STEPS.PHYS_OPT_DESIGN.ARGS.DIRECTIVE=AggressiveExplore +prop=run.impl_1.STEPS.ROUTE_DESIGN.ARGS.DIRECTIVE=NoTimingRelaxation +prop=run.impl_1.{STEPS.ROUTE_DESIGN.ARGS.MORE OPTIONS}={-tns_cleanup} +prop=run.impl_1.STEPS.POST_ROUTE_PHYS_OPT_DESIGN.IS_ENABLED=true diff --git a/graph/L2/tests/louvain_fast/description.json b/graph/L2/tests/louvain_fast/description.json index 0015a4a578..3bf7d75511 100644 --- a/graph/L2/tests/louvain_fast/description.json +++ b/graph/L2/tests/louvain_fast/description.json @@ -4,24 +4,44 @@ "description": "The Louvain method for community detection is a method to extract communities from large networks created by Blondel from the University of Louvain (the source of this method's name). The method is a greedy optimization method that appears to run in time O(n cdot log n), if n is the number of nodes in the network", "flow": "vitis", "platform_whitelist": [ - "u50" + "u50", + "u280", + "u55c" ], "platform_blacklist": [ "zc" ], "platform_properties": { "u50": { + "v++": { + "compiler": { + "cflags": [ + "--config PROJECT/conn_u50_u280.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=PROJECT/postSysLink.tcl" + ] + } + } + }, + "u280": { + "v++": { + "compiler": { + "cflags": [ + "--config PROJECT/conn_u50_u280.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=PROJECT/postSysLink.tcl" + ] + } + } + }, + "u55c": { "host": { "compiler": { "symbols": [ - "USE_HBM" + "USE_U55C" ] } }, "v++": { "compiler": { "cflags": [ - "--config PROJECT/conn_u50_u280.cfg" + "--config PROJECT/conn_u55c.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=PROJECT/postSysLink.tcl" ] } } @@ -32,7 +52,7 @@ ], "launch": [ { - "cmd_args": " -x BUILD/kernel_louvain.xclbin -f 3 -c -m 10000 -prun PROJECT/data/example-wt.txt", + "cmd_args": " -x BUILD/kernel_louvain.xclbin -f 3 -c -m 10000 PROJECT/data/example-wt.txt -prun", "name": "generic launch for all flows", "ld_library_path": [ "$(LD_LIBRARY_PATH)", @@ -75,7 +95,7 @@ "LIB_DIR/../utils/L1/include", "LIB_DIR/ext/xcl2" ], - "options": "-O3 -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD" + "options": "-O3 -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD -B/usr/lib/x86_64-linux-gnu" } }, "v++": { @@ -93,7 +113,7 @@ "accelerators": [ { "location": "LIB_DIR/L2/tests/louvain_fast/kernel/kernel_louvain.cpp", - "frequency": 300.0, + "frequency": 250.0, "clflags": " -D KERNEL_NAME=kernel_louvain", "name": "kernel_louvain", "num_compute_units": 1, @@ -116,70 +136,62 @@ }, { "name": "m_axi_gmem3", - "memory": "HBM[6]" + "memory": "HBM[5:6]" }, { "name": "m_axi_gmem4", - "memory": "HBM[8]" + "memory": "HBM[5:6]" }, { "name": "m_axi_gmem5", - "memory": "HBM[10]" + "memory": "HBM[7]" }, { "name": "m_axi_gmem6", - "memory": "HBM[12]" + "memory": "HBM[8]" }, { "name": "m_axi_gmem7", - "memory": "HBM[14]" + "memory": "HBM[9]" }, { "name": "m_axi_gmem8", - "memory": "HBM[16]" + "memory": "HBM[10]" }, { "name": "m_axi_gmem9", - "memory": "HBM[18]" + "memory": "HBM[11]" }, { "name": "m_axi_gmem10", - "memory": "HBM[20]" + "memory": "HBM[12]" }, { "name": "m_axi_gmem11", - "memory": "HBM[22]" + "memory": "HBM[13]" }, { "name": "m_axi_gmem12", - "memory": "HBM[24]" + "memory": "HBM[14]" }, { "name": "m_axi_gmem13", - "memory": "HBM[26]" + "memory": "HBM[15]" }, { "name": "m_axi_gmem14", - "memory": "HBM[27]" + "memory": "HBM[4]" }, { "name": "m_axi_gmem15", - "memory": "HBM[28:29]" - }, - { - "name": "m_axi_gmem16", - "memory": "HBM[7]" - }, - { - "name": "m_axi_gmem17", - "memory": "HBM[9]" + "memory": "HBM[0:1]" } ] } ] } ], - "frequency": 300.0, + "frequency": 250.0, "name": "kernel_louvain" } ], diff --git a/graph/L2/tests/louvain_fast/host/driverForGraphClustering.cpp b/graph/L2/tests/louvain_fast/host/driverForGraphClustering.cpp index 789ae01ddb..3285bd553a 100644 --- a/graph/L2/tests/louvain_fast/host/driverForGraphClustering.cpp +++ b/graph/L2/tests/louvain_fast/host/driverForGraphClustering.cpp @@ -68,51 +68,51 @@ int xai_close(xaiHandle xaiInstance) { return 0; } -int xai_louvain_main(int argc, char** argv) { - std::cout << "called xai_louvain_main, argc: " << argc << "argv 1: " << argv[1] << std::flush; - //Parse Input parameters: - double opts_C_thresh; //Threshold with coloring on - long opts_minGraphSize; //Min |V| to enable coloring - double opts_threshold; //Value of threshold - int opts_ftype; //File type - char opts_inFile[4096]; - bool opts_coloring; - bool opts_output; - bool opts_VF; - char opts_xclbinPath[4096]; - - host_ParserParameters(argc, argv, - opts_C_thresh, //double opts_C_thresh; //Threshold with coloring on - opts_minGraphSize,//long opts_minGraphSize; //Min |V| to enable coloring - opts_threshold, //double opts_threshold; //Value of threshold - opts_ftype, //int opts_ftype; //File type - opts_inFile, //char opts_inFile[4096]; - opts_coloring, //bool opts_coloring; - opts_output, //bool opts_output; - opts_VF, //bool opts_VF; - opts_xclbinPath); - int numThreads = NUMTHREAD; // using fixed number of thread instead of omp_get_num_threads(); - //Parse the graphNew in Matrix Market format - graphNew* G = host_PrepareGraph( opts_ftype, opts_inFile, opts_VF); - //Datastructures to store clustering information - long NV_begin = G->numVertices; - long *C_orig = (long *) malloc (NV_begin * sizeof(long)); assert(C_orig != 0); - #pragma omp parallel for - for (long i=0; inumVertices; +// long *C_orig = (long *) malloc (NV_begin * sizeof(long)); assert(C_orig != 0); +// #pragma omp parallel for +// for (long i=0; i +#include #include "xilinxlouvain.hpp" #include "ParLV.h" //tmp include #include "ctrlLV.h" //tmp include @@ -22,11 +23,18 @@ #include "louvainPhase.h" #include "defs.h" #include "xcl2.hpp" +//#include +//#include #include "string.h" #include "ap_int.h" #include "utils.hpp" #include "xf_utils_sw/logger.hpp" /////////////////////////////////////////////////////////////////////////////////////////////////////////// +// There are 3 flows in this codes +// 1. no ghost flow, for the no partition, no ghost test, designed for 20.2 kernels, rarely used +// 2. support the partition and ghost flow, designed for 20.2 kernels +// 3. support the partition and ghost flow, designed for the kernel after 21.2, faster than the origin kernels (_par +// _prune) void PrintReport_MultiPhase(bool opts_coloring, long opts_minGraphSize, double opts_threshold, @@ -171,20 +179,6 @@ void PhaseLoop_UpdatingC_org(int phase, long NV, long NV_G, long* C, long* C_ori } } -void inline PhaseLoop_Kernel_Enable(cl::Kernel& kernel_louvain, - cl::CommandQueue& q, - std::vector& ob_in, - std::vector& ob_out, - std::vector >& kernel_evt0, - std::vector >& kernel_evt1) { - kernel_evt0[0].resize(1); - kernel_evt1[0].resize(1); - - q.enqueueMigrateMemObjects(ob_in, 0, nullptr, kernel_evt0[0].data()); // 0 : migrate from host to dev - q.enqueueTask(kernel_louvain, &kernel_evt0[0], kernel_evt1[0].data()); - q.enqueueMigrateMemObjects(ob_out, 1, &kernel_evt1[0], nullptr); // 1 : migrate from dev to host - q.finish(); -} long* CreateM(long NV_new, long NV_orig, long* C_orig, long* M_orig) { long* M = (long*)malloc(NV_new * sizeof(long)); assert(M); @@ -195,32 +189,114 @@ long* CreateM(long NV_new, long NV_orig, long* C_orig, long* M_orig) { return M; } -double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, - GLV* pglv_iter, - int numThreads, - double opts_threshold, - bool opts_coloring, - // modified: - bool& nonColor, - int& phase, - int& totItr, - long& numClusters, - double& totTimeBuildingPhase) { +// There are 3 flows in this codes +// 1. no ghost flow, for the no partition, no ghost test, designed for 20.2 kernels, rarely used +// 2. support the partition and ghost flow, designed for 20.2 kernels +// 3. support the partition and ghost flow, designed for the kernel after 21.2, faster than the origin kernels (_par +// _prune) +bool PhaseLoop_CommPostProcessing(long NV, + int numThreads, + double opts_threshold, + bool opts_coloring, + double prevMod, + double currMod, + // modified: + graphNew*& G, + long*& C, + long*& C_orig, + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase) { + double time1 = 0; + time1 = omp_get_wtime(); + graphNew* Gnew; + numClusters = renumberClustersContiguously(C, G->numVertices); + printf("Number of unique clusters: %ld\n", numClusters); + PhaseLoop_UpdatingC_org(phase, NV, G->numVertices, C, C_orig); + + if ((phase > MAX_NUM_PHASE) || (totItr > MAX_NUM_TOTITR)) { + return 1; // Break if too many phases or iterations + } else { + if ((currMod - prevMod) > opts_threshold) { + Gnew = (graphNew*)malloc(sizeof(graphNew)); + assert(Gnew != 0); + double tmpTime = buildNextLevelGraphOpt(G, Gnew, C, numClusters, numThreads); + // totTimeBuildingPhase += tmpTime; + // Free up the previous graphNew + free(G->edgeListPtrs); + free(G->edgeList); + free(G); + G = Gnew; // Swap the pointers + G->edgeListPtrs = Gnew->edgeListPtrs; + G->edgeList = Gnew->edgeList; + // Free up the previous cluster & create new one of a different size + free(C); + C = (long*)malloc(numClusters * sizeof(long)); + assert(C != 0); +#pragma omp parallel for + for (long i = 0; i < numClusters; i++) { + C[i] = -1; + } + phase++; // Increment phase number + } else { // when !((opts_coloring == 1) && (G->numVertices > opts_minGraphSize) && (nonColor == false)) + if ((opts_coloring) && (nonColor == false)) { + nonColor = true; // Run at least one loop of non-coloring routine + } else { + return true; // Modularity gain is not enough. Exit. + } + } + } + time1 = omp_get_wtime() - time1; + totTimeBuildingPhase += time1; + return false; +} + +double PhaseLoop_CommPostProcessing(GLV* pglv_orig, + GLV* pglv_iter, + int numThreads, + double opts_threshold, + bool opts_coloring, + // modified: + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase, + double& time_renum, + double& time_C, + double& time_M, + double& time_buid, + double& time_set) { double time1 = 0; time1 = omp_get_wtime(); + time_renum = time1; graphNew* Gnew; - numClusters = renumberClustersContiguously_ghost(pglv_iter->C, pglv_iter->G->numVertices, pglv_iter->NVl); + // numClusters = renumberClustersContiguously(pglv_iter->C, pglv_iter->G->numVertices); printf("Number of unique clusters: %ld\n", numClusters); + time_renum = omp_get_wtime() - time_renum; + + time_C = omp_get_wtime(); PhaseLoop_UpdatingC_org(phase, pglv_orig->NV, pglv_iter->NV, pglv_iter->C, pglv_orig->C); + time_C = omp_get_wtime() - time_C; - long* M_new = CreateM(numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M); + time_M = 0; // omp_get_wtime(); + // long* M_new = CreateM( numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M ); + // time_M = omp_get_wtime() - time_M; Gnew = (graphNew*)malloc(sizeof(graphNew)); assert(Gnew != 0); double tmpTime = buildNextLevelGraphOpt(pglv_iter->G, Gnew, pglv_iter->C, numClusters, numThreads); totTimeBuildingPhase += tmpTime; - pglv_iter->SetByOhterG(Gnew, M_new); + time_buid = tmpTime; + + time_set = omp_get_wtime(); + pglv_iter->SetByOhterG(Gnew); //, M_new); + time_set = omp_get_wtime() - time_set; + time1 = omp_get_wtime() - time1; + return time1; } @@ -270,110 +346,6 @@ double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, return time1; } -double PhaseLoop_CommPostProcessing(GLV* pglv_orig, - GLV* pglv_iter, - int numThreads, - double opts_threshold, - bool opts_coloring, - // modified: - bool& nonColor, - int& phase, - int& totItr, - long& numClusters, - double& totTimeBuildingPhase, - double& time_renum, - double& time_C, - double& time_M, - double& time_buid, - double& time_set) { - double time1 = 0; - time1 = omp_get_wtime(); - time_renum = time1; - graphNew* Gnew; - // numClusters = renumberClustersContiguously(pglv_iter->C, pglv_iter->G->numVertices); - printf("Number of unique clusters: %ld\n", numClusters); - time_renum = omp_get_wtime() - time_renum; - - time_C = omp_get_wtime(); - PhaseLoop_UpdatingC_org(phase, pglv_orig->NV, pglv_iter->NV, pglv_iter->C, pglv_orig->C); - time_C = omp_get_wtime() - time_C; - - time_M = 0; // omp_get_wtime(); - // long* M_new = CreateM( numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M ); - // time_M = omp_get_wtime() - time_M; - - Gnew = (graphNew*)malloc(sizeof(graphNew)); - assert(Gnew != 0); - double tmpTime = buildNextLevelGraphOpt(pglv_iter->G, Gnew, pglv_iter->C, numClusters, numThreads); - totTimeBuildingPhase += tmpTime; - time_buid = tmpTime; - - time_set = omp_get_wtime(); - pglv_iter->SetByOhterG(Gnew); //, M_new); - time_set = omp_get_wtime() - time_set; - - time1 = omp_get_wtime() - time1; - - return time1; -} -bool PhaseLoop_CommPostProcessing(long NV, - int numThreads, - double opts_threshold, - bool opts_coloring, - double prevMod, - double currMod, - // modified: - graphNew*& G, - long*& C, - long*& C_orig, - bool& nonColor, - int& phase, - int& totItr, - long& numClusters, - double& totTimeBuildingPhase) { - double time1 = 0; - time1 = omp_get_wtime(); - graphNew* Gnew; - numClusters = renumberClustersContiguously(C, G->numVertices); - printf("Number of unique clusters: %ld\n", numClusters); - PhaseLoop_UpdatingC_org(phase, NV, G->numVertices, C, C_orig); - - if ((phase > MAX_NUM_PHASE) || (totItr > MAX_NUM_TOTITR)) { - return 1; // Break if too many phases or iterations - } else { - if ((currMod - prevMod) > opts_threshold) { - Gnew = (graphNew*)malloc(sizeof(graphNew)); - assert(Gnew != 0); - double tmpTime = buildNextLevelGraphOpt(G, Gnew, C, numClusters, numThreads); - // totTimeBuildingPhase += tmpTime; - // Free up the previous graphNew - free(G->edgeListPtrs); - free(G->edgeList); - free(G); - G = Gnew; // Swap the pointers - G->edgeListPtrs = Gnew->edgeListPtrs; - G->edgeList = Gnew->edgeList; - // Free up the previous cluster & create new one of a different size - free(C); - C = (long*)malloc(numClusters * sizeof(long)); - assert(C != 0); -#pragma omp parallel for - for (long i = 0; i < numClusters; i++) { - C[i] = -1; - } - phase++; // Increment phase number - } else { // when !((opts_coloring == 1) && (G->numVertices > opts_minGraphSize) && (nonColor == false)) - if ((opts_coloring) && (nonColor == false)) { - nonColor = true; // Run at least one loop of non-coloring routine - } else { - return true; // Modularity gain is not enough. Exit. - } - } - } - time1 = omp_get_wtime() - time1; - totTimeBuildingPhase += time1; - return false; -} void inline PhaseLoop_MapHostBuff(long NV, long NE_mem_1, @@ -482,257 +454,7 @@ void UsingFPGA_MapHostClBuff( PhaseLoop_MapClBuff(NV, NE_mem_1, NE_mem_2, mext_in, context, buff_cl); } -int PhaseLoop_UsingCPU(double opts_threshold, - int numThreads, - double& currMod, - graphNew*& G, - long*& C, - long*& C_orig, - int& totItr, - bool& nonColor, - double& totTimeClustering) { - double tmpTime; - int tmpItr = 0; - currMod = parallelLouvianMethod(G, C, numThreads, currMod, opts_threshold, &tmpTime, &tmpItr); - totTimeClustering += tmpTime; - totItr += tmpItr; - nonColor = true; - return 0; -} -void PhaseLoop_UsingFPGA_1_KernelSetup(bool isLargeEdge, - cl::Kernel& kernel_louvain, - std::vector& ob_in, - std::vector& ob_out, - KMemorys_clBuff& buff_cl) { - // Data transfer from host buffer to device buffer - ob_in.push_back(buff_cl.db_config0); - ob_in.push_back(buff_cl.db_config1); - ob_in.push_back(buff_cl.db_offsets); - ob_in.push_back(buff_cl.db_indices); - if (isLargeEdge) ob_in.push_back(buff_cl.db_indices2); - ob_in.push_back(buff_cl.db_weights); - if (isLargeEdge) ob_in.push_back(buff_cl.db_weights2); - ob_in.push_back(buff_cl.db_cidCurr); - ob_in.push_back(buff_cl.db_cidSizePrev); - ob_in.push_back(buff_cl.db_cidSizeUpdate); - ob_in.push_back(buff_cl.db_cidSizeCurr); - ob_in.push_back(buff_cl.db_totPrev); - ob_in.push_back(buff_cl.db_totUpdate); - ob_in.push_back(buff_cl.db_totCurr); - ob_in.push_back(buff_cl.db_cWeight); - ob_in.push_back(buff_cl.db_colorAxi); - ob_in.push_back(buff_cl.db_colorInx); - ob_out.push_back(buff_cl.db_config0); - ob_out.push_back(buff_cl.db_config1); - ob_out.push_back(buff_cl.db_cidPrev); - - kernel_louvain.setArg(0, buff_cl.db_config0); // config0 - kernel_louvain.setArg(1, buff_cl.db_config1); // config1 - kernel_louvain.setArg(2, buff_cl.db_offsets); // offsets - kernel_louvain.setArg(3, buff_cl.db_indices); // indices - kernel_louvain.setArg(4, buff_cl.db_weights); // weights - kernel_louvain.setArg(5, buff_cl.db_colorAxi); // colorAxi - kernel_louvain.setArg(6, buff_cl.db_colorInx); // colorInx - kernel_louvain.setArg(7, buff_cl.db_cidPrev); // cidPrev - kernel_louvain.setArg(8, buff_cl.db_cidSizePrev); // cidSizePrev - kernel_louvain.setArg(9, buff_cl.db_totPrev); // totPrev - kernel_louvain.setArg(10, buff_cl.db_cidCurr); // cidCurr - kernel_louvain.setArg(11, buff_cl.db_cidSizeCurr); // cidSizeCurr - kernel_louvain.setArg(12, buff_cl.db_totCurr); // totCurr - kernel_louvain.setArg(13, buff_cl.db_cidSizeUpdate); // cUpdate - kernel_louvain.setArg(14, buff_cl.db_totUpdate); // totCurr - kernel_louvain.setArg(15, buff_cl.db_cWeight); // cWeight - std::cout << "INFO: Finish kernel setup" << std::endl; -} - -void PhaseLoop_UsingFPGA_2_DataWriteTo(cl::CommandQueue& q, - std::vector >& kernel_evt0, - std::vector& ob_in) { /* 0 : migrate from host to dev */ - q.enqueueMigrateMemObjects(ob_in, 0, nullptr, kernel_evt0[0].data()); -} - -void PhaseLoop_UsingFPGA_3_KernelRun(cl::CommandQueue& q, - std::vector >& kernel_evt0, - std::vector >& kernel_evt1, - cl::Kernel& kernel_louvain) { - q.enqueueTask(kernel_louvain, &kernel_evt0[0], kernel_evt1[0].data()); -} - -void PhaseLoop_UsingFPGA_4_DataReadBack(cl::CommandQueue& q, - std::vector >& kernel_evt1, - std::vector& ob_out) { /* kernel_evt1 : migrate from dev to host*/ - q.enqueueMigrateMemObjects(ob_out, 1, &kernel_evt1[0], nullptr); -} - -void PhaseLoop_UsingFPGA_5_KernelFinish(cl::CommandQueue& q) { - q.finish(); -} -void PhaseLoop_UsingFPGA_Post(long vertexNum, - int num_runsFPGA, - KMemorys_host& buff_host, - struct timeval& tstartE2E, - struct timeval& tendE2E, - std::vector >& kernel_evt1, - // output - long* C, - int& totItr, - double& currMod, - int& totTimeE2E) { - // updating - totItr += buff_host.config0[2]; - currMod = buff_host.config1[1]; - for (int i = 0; i < vertexNum; i++) { - C[i] = (long)buff_host.cidPrev[i]; - } - unsigned long timeStart, timeEnd; - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); - int exec_timeE2E = diff(&tendE2E, &tstartE2E); - totTimeE2E += exec_timeE2E; - // showing - unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish kernel execution" << std::endl; - std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish E2E execution" << std::endl; - // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" - printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, - exec_timeE2E, buff_host.config0[2], currMod); - std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" - << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; - std::cout << "-------------------------------------------------------" << std::endl; -} - -void PhaseLoop_UsingFPGA_Post_par(long vertexNum, - int num_runsFPGA, - KMemorys_host& buff_host, - struct timeval& tstartE2E, - struct timeval& tendE2E, - std::vector >& kernel_evt1, - // output - long* C, - int& totItr, - double& currMod, - int& totTimeE2E) { - // updating - totItr += buff_host.config0[2]; - currMod = buff_host.config1[1]; - for (int i = 0; i < vertexNum; i++) { - C[i] = (long)buff_host.cidPrev[i]; - } - unsigned long timeStart, timeEnd; - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); - int exec_timeE2E = diff(&tendE2E, &tstartE2E); - totTimeE2E += exec_timeE2E; - // showing - unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish kernel execution" << std::endl; - std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish E2E execution" << std::endl; - // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" - printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, - exec_timeE2E, buff_host.config0[2], currMod); - std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" - << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; - std::cout << "-------------------------------------------------------" << std::endl; -} - -void PhaseLoop_UsingFPGA_Prep(graphNew* G, - double opts_C_thresh, - double currMod, - int numThreads, - // Updated variables - double& totTimeColoring, - int* colors, - KMemorys_host& buff_host) { - int edgeNum; - int numColors = Phaseloop_UsingFPGA_InitColorBuff(G, colors, numThreads, totTimeColoring); - double time1 = 0; - time1 = omp_get_wtime(); - assert(numColors < COLORS); - long vertexNum = G->numVertices; - long* vtxPtr = G->edgeListPtrs; - edge* vtxInd = G->edgeList; - long NE = G->numEdges; - long NEx2 = NE << 1; - long NE1 = NEx2 < (1 << 26) ? NEx2 : (1 << 26); // 256MB/sizeof(int/float)=64M - - long cnt_e = 0; - for (int i = 0; i < vertexNum + 1; i++) { - buff_host.offsets[i] = (int)vtxPtr[i]; - } - edgeNum = buff_host.offsets[vertexNum]; - for (int i = 0; i < vertexNum; i++) { - int adj1 = vtxPtr[i]; - int adj2 = vtxPtr[i + 1]; - for (int j = adj1; j < adj2; j++) { - if (cnt_e < NE1) { - buff_host.indices[j] = (int)vtxInd[j].tail; - buff_host.weights[j] = vtxInd[j].weight; - } else { - buff_host.indices2[j - NE1] = (int)vtxInd[j].tail; - buff_host.weights2[j - NE1] = vtxInd[j].weight; - } - cnt_e++; - } - } - for (int i = 0; i < vertexNum; i++) { - buff_host.colorAxi[i] = colors[i]; - } - buff_host.config0[0] = vertexNum; - buff_host.config0[1] = numColors; - buff_host.config0[2] = 0; - buff_host.config0[3] = edgeNum; - buff_host.config1[0] = opts_C_thresh; - buff_host.config1[1] = currMod; - time1 = omp_get_wtime() - time1; -} - -void PhaseLoop_UsingFPGA(long NV, - double opts_C_thresh, - bool opts_coloring, - double opts_threshold, - int numThreads, - double& currMod, - graphNew*& G, - long*& C, - long*& C_orig, - int& totItr, - KMemorys_host& buff_host, - KMemorys_clBuff& buff_cl, - cl::Kernel& kernel_louvain, - cl::CommandQueue& q, - int& num_runsFPGA, - int*& colors, - int& totTimeE2E, - double& totTimeColoring) { - long vertexNum = G->numVertices; - bool isLargeEdge = G->numEdges > (1 << 25); - num_runsFPGA++; - struct timeval tstartE2E, tendE2E; - std::vector ob_in; - std::vector ob_out; - std::vector > kernel_evt0(1); - std::vector > kernel_evt1(1); - kernel_evt0[0].resize(1); - kernel_evt1[0].resize(1); - - PhaseLoop_UsingFPGA_Prep(G, opts_C_thresh, currMod, numThreads, totTimeColoring, colors, buff_host); - gettimeofday(&tstartE2E, 0); - PhaseLoop_UsingFPGA_1_KernelSetup(isLargeEdge, kernel_louvain, ob_in, ob_out, buff_cl); - PhaseLoop_UsingFPGA_2_DataWriteTo(q, kernel_evt0, ob_in); - PhaseLoop_UsingFPGA_3_KernelRun(q, kernel_evt0, kernel_evt1, kernel_louvain); - PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); - PhaseLoop_UsingFPGA_5_KernelFinish(q); - gettimeofday(&tendE2E, 0); - PhaseLoop_UsingFPGA_Post(vertexNum, num_runsFPGA, buff_host, tstartE2E, tendE2E, kernel_evt1, C, totItr, currMod, - totTimeE2E); -} - +// prune void inline PhaseLoop_MapHostBuff_prune(long NV, long NE_mem_1, long NE_mem_2, @@ -743,8 +465,8 @@ void inline PhaseLoop_MapHostBuff_prune(long NV, buff_host.config1 = aligned_alloc(4); buff_host.offsets = aligned_alloc(NV + 1); buff_host.indices = aligned_alloc(NE_mem_1); - buff_host.offsetsdup = aligned_alloc(NV + 1); // - buff_host.indicesdup = aligned_alloc(NE_mem_1); // + // buff_host.offsetsdup = aligned_alloc(NV + 1); // + // buff_host.indicesdup = aligned_alloc(NE_mem_1); // buff_host.weights = aligned_alloc(NE_mem_1); buff_host.flag = aligned_alloc >(NV); buff_host.flagUpdate = aligned_alloc >(NV); @@ -769,15 +491,15 @@ void inline PhaseLoop_MapHostBuff_prune(long NV, ap_uint* axi_offsets = reinterpret_cast*>(buff_host.offsets); ap_uint* axi_indices = reinterpret_cast*>(buff_host.indices); - ap_uint* axi_offsetsdup = reinterpret_cast*>(buff_host.offsetsdup); - ap_uint* axi_indicesdup = reinterpret_cast*>(buff_host.indicesdup); + // ap_uint* axi_offsetsdup = reinterpret_cast*>(buff_host.offsetsdup); + // ap_uint* axi_indicesdup = reinterpret_cast*>(buff_host.indicesdup); ap_uint* axi_weights = reinterpret_cast*>(buff_host.weights); ap_uint* axi_indices2; ap_uint* axi_indicesdup2; ap_uint* axi_weights2; if (NE_mem_2 > 0) { axi_indices2 = reinterpret_cast*>(buff_host.indices2); - axi_indicesdup2 = reinterpret_cast*>(buff_host.indicesdup2); + // axi_indicesdup2 = reinterpret_cast*>(buff_host.indicesdup2); axi_weights2 = reinterpret_cast*>(buff_host.weights2); } ap_uint* axi_cidPrev = reinterpret_cast*>(buff_host.cidPrev); @@ -804,27 +526,20 @@ void inline PhaseLoop_MapHostBuff_prune(long NV, mext_in[3 + 18] = {(unsigned int)(1) | XCL_MEM_TOPOLOGY, axi_indices2, 0}; mext_in[4 + 18] = {(unsigned int)(3) | XCL_MEM_TOPOLOGY, axi_weights2, 0}; } - mext_in[5] = {(unsigned int)(6) | XCL_MEM_TOPOLOGY, axi_colorAxi, 0}; - mext_in[6] = {(unsigned int)(8) | XCL_MEM_TOPOLOGY, axi_colorInx, 0}; - mext_in[7] = {(unsigned int)(10) | XCL_MEM_TOPOLOGY, axi_cidPrev, 0}; - mext_in[8] = {(unsigned int)(12) | XCL_MEM_TOPOLOGY, axi_cidSizePrev, 0}; - mext_in[9] = {(unsigned int)(14) | XCL_MEM_TOPOLOGY, axi_totPrev, 0}; - mext_in[10] = {(unsigned int)(16) | XCL_MEM_TOPOLOGY, axi_cidCurr, 0}; - mext_in[11] = {(unsigned int)(18) | XCL_MEM_TOPOLOGY, axi_cidSizeCurr, 0}; - mext_in[12] = {(unsigned int)(20) | XCL_MEM_TOPOLOGY, axi_totCurr, 0}; - mext_in[13] = {(unsigned int)(22) | XCL_MEM_TOPOLOGY, axi_cidSizeUpdate, 0}; - mext_in[14] = {(unsigned int)(24) | XCL_MEM_TOPOLOGY, axi_totUpdate, 0}; - mext_in[15] = {(unsigned int)(26) | XCL_MEM_TOPOLOGY, axi_cWeight, 0}; - - mext_in[16] = {(unsigned int)(27) | XCL_MEM_TOPOLOGY, axi_offsetsdup, 0}; - // mext_in[17] = {(unsigned int)(28) | XCL_MEM_TOPOLOGY, axi_indicesdup, 0}; - mext_in[17] = {(unsigned int)(28) | XCL_MEM_TOPOLOGY, axi_indicesdup, 0}; //| (unsigned int)(29) - if (NE_mem_2 > 0) { - mext_in[20] = {(unsigned int)(29) | XCL_MEM_TOPOLOGY, axi_indicesdup2, 0}; - } - - mext_in[18] = {(unsigned int)(7) | XCL_MEM_TOPOLOGY, axi_flag, 0}; - mext_in[19] = {(unsigned int)(9) | XCL_MEM_TOPOLOGY, axi_flagUpdate, 0}; + mext_in[5] = {(unsigned int)(5) | XCL_MEM_TOPOLOGY, axi_colorAxi, 0}; + mext_in[6] = {(unsigned int)(6) | XCL_MEM_TOPOLOGY, axi_colorInx, 0}; + mext_in[7] = {(unsigned int)(7) | XCL_MEM_TOPOLOGY, axi_cidPrev, 0}; + mext_in[8] = {(unsigned int)(8) | XCL_MEM_TOPOLOGY, axi_cidSizePrev, 0}; + mext_in[9] = {(unsigned int)(9) | XCL_MEM_TOPOLOGY, axi_totPrev, 0}; + mext_in[10] = {(unsigned int)(10) | XCL_MEM_TOPOLOGY, axi_cidCurr, 0}; + mext_in[11] = {(unsigned int)(11) | XCL_MEM_TOPOLOGY, axi_cidSizeCurr, 0}; + mext_in[12] = {(unsigned int)(12) | XCL_MEM_TOPOLOGY, axi_totCurr, 0}; + mext_in[13] = {(unsigned int)(13) | XCL_MEM_TOPOLOGY, axi_cidSizeUpdate, 0}; + mext_in[14] = {(unsigned int)(14) | XCL_MEM_TOPOLOGY, axi_totUpdate, 0}; + mext_in[15] = {(unsigned int)(15) | XCL_MEM_TOPOLOGY, axi_cWeight, 0}; + + mext_in[18] = {(unsigned int)(5) | XCL_MEM_TOPOLOGY, axi_flag, 0}; + mext_in[19] = {(unsigned int)(5) | XCL_MEM_TOPOLOGY, axi_flagUpdate, 0}; } void inline PhaseLoop_MapClBuff_prune(long NV, long NE_mem_1, @@ -858,14 +573,14 @@ void inline PhaseLoop_MapClBuff_prune(long NV, buff_cl.db_totUpdate = cl::Buffer(context, flag_RW, sizeof(float) * (NV), &mext_in[14]); buff_cl.db_cWeight = cl::Buffer(context, flag_RW, sizeof(float) * (NV), &mext_in[15]); - buff_cl.db_offsetsdup = cl::Buffer(context, flag_RD, sizeof(int) * (NV + 1), &mext_in[16]); - buff_cl.db_indicesdup = cl::Buffer(context, flag_RD, sizeof(int) * (NE_mem_1), &mext_in[17]); + // buff_cl.db_offsetsdup = cl::Buffer(context, flag_RD, sizeof(int) * (NV + 1), &mext_in[16]); + // buff_cl.db_indicesdup = cl::Buffer(context, flag_RD, sizeof(int) * (NE_mem_1), &mext_in[17]); buff_cl.db_flag = cl::Buffer(context, flag_RW, sizeof(ap_uint<8>) * (NV), &mext_in[18]); buff_cl.db_flagUpdate = cl::Buffer(context, flag_RW, sizeof(ap_uint<8>) * (NV), &mext_in[19]); // printf("INFO: sizeof(ap_uint<8>) = %d", sizeof(ap_uint<8>) ); - if (NE_mem_2 != 0) buff_cl.db_indicesdup2 = cl::Buffer(context, flag_RD, sizeof(int) * (NE_mem_2), &mext_in[20]); + // if (NE_mem_2 != 0) buff_cl.db_indicesdup2 = cl::Buffer(context, flag_RD, sizeof(int) * (NE_mem_2), &mext_in[20]); } void UsingFPGA_MapHostClBuff_prune(long NV, long NE_mem_1, @@ -877,96 +592,61 @@ void UsingFPGA_MapHostClBuff_prune(long NV, PhaseLoop_MapHostBuff_prune(NV, NE_mem_1, NE_mem_2, mext_in, context, buff_host); PhaseLoop_MapClBuff_prune(NV, NE_mem_1, NE_mem_2, mext_in, context, buff_cl); } -void PhaseLoop_UsingFPGA_1_KernelSetup_prune(bool isLargeEdge, - cl::Kernel& kernel_louvain, - std::vector& ob_in, - std::vector& ob_out, - KMemorys_clBuff_prune& buff_cl) { - // Data transfer from host buffer to device buffer - ob_in.push_back(buff_cl.db_config0); - ob_in.push_back(buff_cl.db_config1); - ob_in.push_back(buff_cl.db_offsets); - ob_in.push_back(buff_cl.db_indices); - if (isLargeEdge) ob_in.push_back(buff_cl.db_indices2); - ob_in.push_back(buff_cl.db_weights); - if (isLargeEdge) ob_in.push_back(buff_cl.db_weights2); - ob_in.push_back(buff_cl.db_cidCurr); - ob_in.push_back(buff_cl.db_cidSizePrev); - ob_in.push_back(buff_cl.db_cidSizeUpdate); - ob_in.push_back(buff_cl.db_cidSizeCurr); - ob_in.push_back(buff_cl.db_totPrev); - ob_in.push_back(buff_cl.db_totUpdate); - ob_in.push_back(buff_cl.db_totCurr); - ob_in.push_back(buff_cl.db_cWeight); - ob_in.push_back(buff_cl.db_colorAxi); - ob_in.push_back(buff_cl.db_colorInx); - ob_in.push_back(buff_cl.db_cidPrev); - ob_in.push_back(buff_cl.db_offsetsdup); - ob_in.push_back(buff_cl.db_indicesdup); - if (isLargeEdge) ob_in.push_back(buff_cl.db_indicesdup2); - ob_in.push_back(buff_cl.db_flag); - ob_in.push_back(buff_cl.db_flagUpdate); - - ob_out.push_back(buff_cl.db_config0); - ob_out.push_back(buff_cl.db_config1); - ob_out.push_back(buff_cl.db_cidPrev); - kernel_louvain.setArg(0, buff_cl.db_config0); // config0 - kernel_louvain.setArg(1, buff_cl.db_config1); // config1 - kernel_louvain.setArg(2, buff_cl.db_offsets); // offsets - kernel_louvain.setArg(3, buff_cl.db_indices); // indices - kernel_louvain.setArg(4, buff_cl.db_weights); // weights - kernel_louvain.setArg(5, buff_cl.db_colorAxi); // colorAxi - kernel_louvain.setArg(6, buff_cl.db_colorInx); // colorInx - kernel_louvain.setArg(7, buff_cl.db_cidPrev); // cidPrev - kernel_louvain.setArg(8, buff_cl.db_cidSizePrev); // cidSizePrev - kernel_louvain.setArg(9, buff_cl.db_totPrev); // totPrev - kernel_louvain.setArg(10, buff_cl.db_cidCurr); // cidCurr - kernel_louvain.setArg(11, buff_cl.db_cidSizeCurr); // cidSizeCurr - kernel_louvain.setArg(12, buff_cl.db_totCurr); // totCurr - kernel_louvain.setArg(13, buff_cl.db_cidSizeUpdate); // cUpdate - kernel_louvain.setArg(14, buff_cl.db_totUpdate); // totCurr - kernel_louvain.setArg(15, buff_cl.db_cWeight); // cWeight - kernel_louvain.setArg(16, buff_cl.db_offsetsdup); // offsets - kernel_louvain.setArg(17, buff_cl.db_indicesdup); // indices - kernel_louvain.setArg(18, buff_cl.db_flag); // offsets - kernel_louvain.setArg(19, buff_cl.db_flagUpdate); // indices - std::cout << "INFO: Finish kernel setup" << std::endl; -} +//////////////////////////////////////////////////////////////////////////////////////////////////////////// -void PhaseLoop_UsingFPGA_Post_par_prune(long vertexNum, - int num_runsFPGA, - KMemorys_host_prune& buff_host, - struct timeval& tstartE2E, - struct timeval& tendE2E, - std::vector >& kernel_evt1, - // output - long* C, - int& totItr, - double& currMod, - int& totTimeE2E) { - // updating - totItr += buff_host.config0[2]; - currMod = buff_host.config1[1]; +double PhaseLoop_UsingFPGA_Prep_Init_buff_host(int numColors, + graphNew* G, + long* M, + double opts_C_thresh, + double currMod, + // Updated variables + int* colors, + KMemorys_host& buff_host) { + int edgeNum; + double time1 = omp_get_wtime(); + assert(numColors < COLORS); + long vertexNum = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + long NE = G->numEdges; + long NEx2 = NE << 1; + long NE1 = NEx2 < (MAXNV) ? NEx2 : (MAXNV); // 256MB/sizeof(int/float)=64M + + long cnt_e = 0; + for (int i = 0; i < vertexNum + 1; i++) { + buff_host.offsets[i] = (int)vtxPtr[i]; + if (i != vertexNum) { + if (M[i] < 0) buff_host.offsets[i] = (int)(0x80000000 | (unsigned int)vtxPtr[i]); + } else + buff_host.offsets[i] = (int)(vtxPtr[i]); + } + edgeNum = buff_host.offsets[vertexNum]; for (int i = 0; i < vertexNum; i++) { - C[i] = (long)buff_host.cidPrev[i]; + int adj1 = vtxPtr[i]; + int adj2 = vtxPtr[i + 1]; + for (int j = adj1; j < adj2; j++) { + if (cnt_e < NE1) { + buff_host.indices[j] = (int)vtxInd[j].tail; + buff_host.weights[j] = vtxInd[j].weight; + } else { + buff_host.indices2[j - NE1] = (int)vtxInd[j].tail; + buff_host.weights2[j - NE1] = vtxInd[j].weight; + } + cnt_e++; + } } - unsigned long timeStart, timeEnd; - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); - int exec_timeE2E = diff(&tendE2E, &tstartE2E); - totTimeE2E += exec_timeE2E; - // showing - unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish kernel execution" << std::endl; - std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish E2E execution" << std::endl; - std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" - << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" - << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; - std::cout << "-------------------------------------------------------" << std::endl; + for (int i = 0; i < vertexNum; i++) { + buff_host.colorAxi[i] = colors[i]; + } + buff_host.config0[0] = vertexNum; + buff_host.config0[1] = numColors; + buff_host.config0[2] = 0; + buff_host.config0[3] = edgeNum; + buff_host.config1[0] = opts_C_thresh; + buff_host.config1[1] = currMod; + time1 = omp_get_wtime() - time1; + return time1; } double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, @@ -986,7 +666,7 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, edge* vtxInd = G->edgeList; long NE = G->numEdges; long NEx2 = NE << 1; - long NE1 = NEx2 < (1 << 26) ? NEx2 : (1 << 26); // 256MB/sizeof(int/float)=64M + long NE1 = NEx2 < (MAXNV) ? NEx2 : (MAXNV); // 256MB/sizeof(int/float)=64M long cnt_e = 0; @@ -999,7 +679,7 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, } else { buff_host.offsets[i] = (int)(vtxPtr[i]); } - buff_host.offsetsdup[i] = buff_host.offsets[i]; // zyl + // buff_host.offsetsdup[i] = buff_host.offsets[i]; // zyl } edgeNum = buff_host.offsets[vertexNum]; @@ -1011,11 +691,11 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, for (int j = adj1; j < adj2; j++) { if (cnt_e < NE1) { buff_host.indices[j] = (int)vtxInd[j].tail; - buff_host.indicesdup[j] = (int)vtxInd[j].tail; + // buff_host.indicesdup[j] = (int)vtxInd[j].tail; buff_host.weights[j] = vtxInd[j].weight; } else { buff_host.indices2[j - NE1] = (int)vtxInd[j].tail; - buff_host.indicesdup2[j - NE1] = (int)vtxInd[j].tail; + // buff_host.indicesdup2[j - NE1] = (int)vtxInd[j].tail; buff_host.weights2[j - NE1] = vtxInd[j].weight; } cnt_e++; @@ -1037,285 +717,172 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, return time1; } -//////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void runLouvainWithFPGA(graphNew* G, // Input graphNew, undirectioned - long* C_orig, // Output - char* opts_xclbinPath, - bool opts_coloring, - long opts_minGraphSize, - double opts_threshold, - double opts_C_thresh, - int numThreads) { - long NV = G->numVertices; - long NE_org = G->numEdges; - long numClusters; - /* Check graphNew size, limited by hardware features */ - assert(NV < MAXNV); - assert(NE_org < MAXNE); - - /* For coloring */ - int* colors; - if (opts_coloring) { - colors = (int*)malloc(G->numVertices * sizeof(int)); - assert(colors != 0); - } - - /* To build new hierarchical graphNews*/ - long* C = (long*)malloc(NV * sizeof(long)); - assert(C != 0); -#pragma omp parallel for - for (long i = 0; i < NV; i++) { - C[i] = -1; - } - - /*******************************/ - /* FPGA-related data structures*/ - /*******************************/ - /* platform related operations */ - std::vector devices = xcl::get_xil_devices(); - cl::Device device = devices[0]; - cl::Context context(device); - std::string devName = device.getInfo(); - printf("INFO: Found Device=%s\n", devName.c_str()); - cl::Program::Binaries xclBins = xcl::import_binary_file(opts_xclbinPath); - devices.resize(1); - cl::Program program(context, devices, xclBins); - cl::Kernel kernel_louvain(program, "kernel_louvain"); - printf("INFO: kernel has been created\n"); - cl::CommandQueue q(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); - /* Memories mapping */ - KMemorys_host buff_host; - KMemorys_clBuff buff_cl; - long NE_mem = NE_org * 2; // number for real edge to be stored in memory - long NE_mem_1 = NE_mem < (1 << 26) ? NE_mem : (1 << 26); - long NE_mem_2 = NE_mem - NE_mem_1; - UsingFPGA_MapHostClBuff(NV, NE_mem_1, NE_mem_2, context, buff_host, buff_cl); - - /*******************************/ - /* Loop for phase(s) */ - /*******************************/ - double totTimeClustering = 0; // time accumulator for clustering by CPU - double totTimeBuildingPhase = 0; // time accumulator for Building new graphNew for next phase by CPU - double totTimeColoring = 0; // time accumulator for coloring - double prevMod = -1; // Last-phase modularity - double currMod = -1; // Current modularity - int phase = 1; // Total phase counter - int totTimeE2E = 0; // FPGA E2E time accumulator - int num_runsFPGA = 0; // FPGA calling times counter - int totItr = 0; // Total iteration counter - bool nonColor = false; // Make sure that at least one phase with lower opts_threshold runs - bool isItrStop = false; - while (!isItrStop) { - printf("===============================\n"); - printf("Phase %d\n", phase); - printf("===============================\n"); - prevMod = currMod; - bool isUsingFPGA = ((opts_coloring) && (G->numVertices > opts_minGraphSize) && (nonColor == false)); - - if (isUsingFPGA) { - PhaseLoop_UsingFPGA(NV, opts_C_thresh, opts_coloring, opts_threshold, numThreads, currMod, G, C, C_orig, - totItr, buff_host, buff_cl, kernel_louvain, q, /*kernel's parameter*/ - num_runsFPGA, colors, totTimeE2E, totTimeColoring); - } else { - PhaseLoop_UsingCPU(opts_threshold, numThreads, currMod, G, C, C_orig, totItr, nonColor, totTimeClustering); - } - /* General post-processing for both FPGA and CPU */ - isItrStop = PhaseLoop_CommPostProcessing(NV, numThreads, opts_threshold, opts_coloring, prevMod, currMod, G, C, - C_orig, nonColor, phase, totItr, numClusters, totTimeBuildingPhase); - } // End of while(1) = End of Louvain - - /* Print information*/ - printf("********************************************\n"); - printf("********* Compact Summary *************\n"); - printf("********************************************\n"); - printf("Number of threads : %d\n", numThreads); - printf("Total number of phases : %d\n", phase); - printf("Total number of iterations : %d\n", totItr); - printf("Final number of clusters : %ld\n", numClusters); - printf("Final modularity : %lf\n", prevMod); - printf("Total time for clustering : %lf\n", totTimeClustering); - printf("Total time for building phases : %lf\n", totTimeBuildingPhase); - printf("Total E2E time(s) : %lf\n", (1.0 * totTimeE2E * 1e-6)); - if (opts_coloring) { - printf("Total time for coloring : %lf\n", totTimeColoring); - } - printf("********************************************\n"); - printf("TOTAL TIME : %lf\n", - ((1.0 * totTimeE2E * 1e-6) + totTimeClustering + totTimeBuildingPhase + totTimeColoring)); - printf("********************************************\n"); - - /* Clean up memories */ - free(C); - if (G != 0) { - free(G->edgeListPtrs); - free(G->edgeList); - free(G); - } - if (opts_coloring) { - if (colors != 0) free(colors); - } - buff_host.freeMem(); -} // End of runMultiPhaseLouvainAlgorithm() - -void runLouvainWithFPGA_demo(graphNew* G, - long* C_orig, - char* opts_xclbinPath, - bool opts_coloring, - long opts_minGraphSize, - double opts_threshold, - double opts_C_thresh, - int numThreads) { - long NV = G->numVertices; - long NE_org = G->numEdges; - long numClusters; - assert(NV < MAXNV); - assert(NE_org < MAXNE); - - int* colors; - if (opts_coloring) { - colors = (int*)malloc(G->numVertices * sizeof(int)); - assert(colors != 0); - } - long* C = (long*)malloc(NV * sizeof(long)); - assert(C != 0); -#pragma omp parallel for - for (long i = 0; i < NV; i++) { - C[i] = -1; - } - - std::vector devices = xcl::get_xil_devices(); - cl::Device device = devices[0]; - cl::Context context(device); - std::string devName = device.getInfo(); - printf("INFO: Found Device=%s\n", devName.c_str()); - cl::Program::Binaries xclBins = xcl::import_binary_file(opts_xclbinPath); - devices.resize(1); - cl::Program program(context, devices, xclBins); - cl::Kernel kernel_louvain(program, "kernel_louvain"); - printf("INFO: kernel has been created\n"); - cl::CommandQueue q(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); - - KMemorys_host buff_host; - KMemorys_clBuff buff_cl; - long NE_mem = NE_org * 2; // number for real edge to be stored in memory - long NE_mem_1 = NE_mem < (MAXNV) ? NE_mem : (MAXNV); - long NE_mem_2 = NE_mem - NE_mem_1; - UsingFPGA_MapHostClBuff(NV, NE_mem_1, NE_mem_2, context, buff_host, buff_cl); - - double totTimeClustering = 0; // time accumulator for clustering by CPU - double totTimeBuildingPhase = 0; // time accumulator for Building new graphNew for next phase by CPU - double totTimeColoring = 0; // time accumulator for coloring - double prevMod = -1; // Last-phase modularity - double currMod = -1; // Current modularity - int phase = 1; // Total phase counter - int totTimeE2E = 0; // FPGA E2E time accumulator - int num_runsFPGA = 0; // FPGA calling times counter - int totItr = 0; // Total iteration counter - bool nonColor = false; // Make sure that at least one phase with lower opts_threshold runs - bool isItrStop = false; - while (!isItrStop) { - printf("===============================\n"); - printf("Phase %d\n", phase); - printf("===============================\n"); - prevMod = currMod; - bool isUsingFPGA = ((opts_coloring) && (G->numVertices > opts_minGraphSize) && (nonColor == false)); - - if (isUsingFPGA) { - long vertexNum = G->numVertices; - bool isLargeEdge = G->numEdges > (MAXNV / 2); - num_runsFPGA++; - struct timeval tstartE2E, tendE2E; - std::vector ob_in; - std::vector ob_out; - std::vector > kernel_evt0(1); - std::vector > kernel_evt1(1); - kernel_evt0[0].resize(1); - kernel_evt1[0].resize(1); - - PhaseLoop_UsingFPGA_Prep(G, opts_C_thresh, currMod, numThreads, totTimeColoring, colors, buff_host); +int PhaseLoop_UsingCPU(double opts_threshold, + int numThreads, + double& currMod, + graphNew*& G, + long*& C, + long*& C_orig, + int& totItr, + bool& nonColor, + double& totTimeClustering) { + double tmpTime; + int tmpItr = 0; + currMod = parallelLouvianMethod(G, C, numThreads, currMod, opts_threshold, &tmpTime, &tmpItr); + totTimeClustering += tmpTime; + totItr += tmpItr; + nonColor = true; + return 0; +} +void PhaseLoop_UsingFPGA_1_KernelSetup(bool isLargeEdge, + cl::Kernel& kernel_louvain, + std::vector& ob_in, + std::vector& ob_out, + KMemorys_clBuff& buff_cl) { + // Data transfer from host buffer to device buffer + ob_in.push_back(buff_cl.db_config0); + ob_in.push_back(buff_cl.db_config1); + ob_in.push_back(buff_cl.db_offsets); + ob_in.push_back(buff_cl.db_indices); + if (isLargeEdge) ob_in.push_back(buff_cl.db_indices2); + ob_in.push_back(buff_cl.db_weights); + if (isLargeEdge) ob_in.push_back(buff_cl.db_weights2); + ob_in.push_back(buff_cl.db_cidCurr); + ob_in.push_back(buff_cl.db_cidSizePrev); + ob_in.push_back(buff_cl.db_cidSizeUpdate); + ob_in.push_back(buff_cl.db_cidSizeCurr); + ob_in.push_back(buff_cl.db_totPrev); + ob_in.push_back(buff_cl.db_totUpdate); + ob_in.push_back(buff_cl.db_totCurr); + ob_in.push_back(buff_cl.db_cWeight); + ob_in.push_back(buff_cl.db_colorAxi); + ob_in.push_back(buff_cl.db_colorInx); + ob_out.push_back(buff_cl.db_config0); + ob_out.push_back(buff_cl.db_config1); + ob_out.push_back(buff_cl.db_cidPrev); - gettimeofday(&tstartE2E, 0); - { /* 5-Step flow for using FPGA */ - PhaseLoop_UsingFPGA_1_KernelSetup(isLargeEdge, kernel_louvain, ob_in, ob_out, buff_cl); + kernel_louvain.setArg(0, buff_cl.db_config0); // config0 + kernel_louvain.setArg(1, buff_cl.db_config1); // config1 + kernel_louvain.setArg(2, buff_cl.db_offsets); // offsets + kernel_louvain.setArg(3, buff_cl.db_indices); // indices + kernel_louvain.setArg(4, buff_cl.db_weights); // weights + kernel_louvain.setArg(5, buff_cl.db_colorAxi); // colorAxi + kernel_louvain.setArg(6, buff_cl.db_colorInx); // colorInx + kernel_louvain.setArg(7, buff_cl.db_cidPrev); // cidPrev + kernel_louvain.setArg(8, buff_cl.db_cidSizePrev); // cidSizePrev + kernel_louvain.setArg(9, buff_cl.db_totPrev); // totPrev + kernel_louvain.setArg(10, buff_cl.db_cidCurr); // cidCurr + kernel_louvain.setArg(11, buff_cl.db_cidSizeCurr); // cidSizeCurr + kernel_louvain.setArg(12, buff_cl.db_totCurr); // totCurr + kernel_louvain.setArg(13, buff_cl.db_cidSizeUpdate); // cUpdate + kernel_louvain.setArg(14, buff_cl.db_totUpdate); // totCurr + kernel_louvain.setArg(15, buff_cl.db_cWeight); // cWeight + std::cout << "INFO: Finish kernel setup" << std::endl; +} - PhaseLoop_UsingFPGA_2_DataWriteTo(q, kernel_evt0, ob_in); +void PhaseLoop_UsingFPGA_1_KernelSetup_prune(bool isLargeEdge, + cl::Kernel& kernel_louvain, + std::vector& ob_in, + std::vector& ob_out, + KMemorys_clBuff_prune& buff_cl) { + // Data transfer from host buffer to device buffer + ob_in.push_back(buff_cl.db_config0); + ob_in.push_back(buff_cl.db_config1); + ob_in.push_back(buff_cl.db_offsets); + ob_in.push_back(buff_cl.db_indices); + if (isLargeEdge) ob_in.push_back(buff_cl.db_indices2); + ob_in.push_back(buff_cl.db_weights); + if (isLargeEdge) ob_in.push_back(buff_cl.db_weights2); + ob_in.push_back(buff_cl.db_cidCurr); + ob_in.push_back(buff_cl.db_cidSizePrev); + ob_in.push_back(buff_cl.db_cidSizeUpdate); + ob_in.push_back(buff_cl.db_cidSizeCurr); + ob_in.push_back(buff_cl.db_totPrev); + ob_in.push_back(buff_cl.db_totUpdate); + ob_in.push_back(buff_cl.db_totCurr); + ob_in.push_back(buff_cl.db_cWeight); + ob_in.push_back(buff_cl.db_colorAxi); + ob_in.push_back(buff_cl.db_colorInx); + ob_in.push_back(buff_cl.db_cidPrev); + // ob_in.push_back(buff_cl.db_offsetsdup); + // ob_in.push_back(buff_cl.db_indicesdup); + // if (isLargeEdge) ob_in.push_back(buff_cl.db_indicesdup2); + ob_in.push_back(buff_cl.db_flag); + ob_in.push_back(buff_cl.db_flagUpdate); - PhaseLoop_UsingFPGA_3_KernelRun(q, kernel_evt0, kernel_evt1, kernel_louvain); + ob_out.push_back(buff_cl.db_config0); + ob_out.push_back(buff_cl.db_config1); + ob_out.push_back(buff_cl.db_cidPrev); - PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); + kernel_louvain.setArg(0, buff_cl.db_config0); // config0 + kernel_louvain.setArg(1, buff_cl.db_config1); // config1 + kernel_louvain.setArg(2, buff_cl.db_offsets); // offsets + kernel_louvain.setArg(3, buff_cl.db_indices); // indices + kernel_louvain.setArg(4, buff_cl.db_weights); // weights + kernel_louvain.setArg(5, buff_cl.db_colorAxi); // colorAxi + kernel_louvain.setArg(6, buff_cl.db_colorInx); // colorInx + kernel_louvain.setArg(7, buff_cl.db_cidPrev); // cidPrev + kernel_louvain.setArg(8, buff_cl.db_cidSizePrev); // cidSizePrev + kernel_louvain.setArg(9, buff_cl.db_totPrev); // totPrev + kernel_louvain.setArg(10, buff_cl.db_cidCurr); // cidCurr + kernel_louvain.setArg(11, buff_cl.db_cidSizeCurr); // cidSizeCurr + kernel_louvain.setArg(12, buff_cl.db_totCurr); // totCurr + kernel_louvain.setArg(13, buff_cl.db_cidSizeUpdate); // cUpdate + kernel_louvain.setArg(14, buff_cl.db_totUpdate); // totCurr + kernel_louvain.setArg(15, buff_cl.db_cWeight); // cWeight + kernel_louvain.setArg(16, buff_cl.db_offsets); // offsets + kernel_louvain.setArg(17, buff_cl.db_indices); // indices + kernel_louvain.setArg(18, buff_cl.db_flag); // offsets + kernel_louvain.setArg(19, buff_cl.db_flagUpdate); // indices + std::cout << "INFO: Finish kernel setup" << std::endl; +} - PhaseLoop_UsingFPGA_5_KernelFinish(q); - } - gettimeofday(&tendE2E, 0); +void PhaseLoop_UsingFPGA_2_DataWriteTo(cl::CommandQueue& q, + std::vector >& kernel_evt0, + std::vector& ob_in) { /* 0 : migrate from host to dev */ + q.enqueueMigrateMemObjects(ob_in, 0, nullptr, kernel_evt0[0].data()); +} - PhaseLoop_UsingFPGA_Post(vertexNum, num_runsFPGA, buff_host, tstartE2E, tendE2E, kernel_evt1, C, totItr, - currMod, totTimeE2E); - } else { - PhaseLoop_UsingCPU(opts_threshold, numThreads, currMod, G, C, C_orig, totItr, nonColor, totTimeClustering); - } - isItrStop = PhaseLoop_CommPostProcessing(NV, numThreads, opts_threshold, opts_coloring, prevMod, currMod, G, C, - C_orig, nonColor, phase, totItr, numClusters, totTimeBuildingPhase); - } +void PhaseLoop_UsingFPGA_3_KernelRun(cl::CommandQueue& q, + std::vector >& kernel_evt0, + std::vector >& kernel_evt1, + cl::Kernel& kernel_louvain) { + q.enqueueTask(kernel_louvain, &kernel_evt0[0], kernel_evt1[0].data()); +} - printf("********************************************\n"); - printf("********* Compact Summary *************\n"); - printf("********************************************\n"); - printf("Number of threads : %d\tm=%d \t thhd=%lf \t thhd_c=%lf\n", numThreads, opts_minGraphSize, - opts_threshold, opts_C_thresh); - printf("Total number of phases : %d\n", phase); - printf("Total number of iterations : %d\n", totItr); - printf("Final number of clusters : %ld\n", numClusters); - printf("Final modularity : %lf\n", prevMod); - printf("Total time for clustering : %lf\n", totTimeClustering); - printf("Total time for building phases : %lf\n", totTimeBuildingPhase); - printf("Total E2E time(s) : %lf\n", (1.0 * totTimeE2E * 1e-6)); - if (opts_coloring) { - printf("Total time for coloring : %lf\n", totTimeColoring); - } - printf("********************************************\n"); - printf("TOTAL TIME : %lf\n", - ((1.0 * totTimeE2E * 1e-6) + totTimeClustering + totTimeBuildingPhase + totTimeColoring)); - printf("********************************************\n"); +void PhaseLoop_UsingFPGA_4_DataReadBack(cl::CommandQueue& q, + std::vector >& kernel_evt1, + std::vector& ob_out) { /* kernel_evt1 : migrate from dev to host*/ + q.enqueueMigrateMemObjects(ob_out, 1, &kernel_evt1[0], nullptr); +} - /* Clean up memories */ - free(C); - if (G != 0) { - free(G->edgeListPtrs); - free(G->edgeList); - free(G); - } - if (opts_coloring) { - if (colors != 0) free(colors); - } - buff_host.freeMem(); -} // End of runMultiPhaseLouvainAlgorithm() +void PhaseLoop_UsingFPGA_5_KernelFinish(cl::CommandQueue& q) { + q.finish(); +} -double PhaseLoop_UsingFPGA_Prep_Init_buff_host(int numColors, - graphNew* G, - long* M, - double opts_C_thresh, - double currMod, - // Updated variables - int* colors, - KMemorys_host& buff_host) { +void PhaseLoop_UsingFPGA_Prep(graphNew* G, + double opts_C_thresh, + double currMod, + int numThreads, + // Updated variables + double& totTimeColoring, + int* colors, + KMemorys_host& buff_host) { int edgeNum; - double time1 = omp_get_wtime(); + int numColors = Phaseloop_UsingFPGA_InitColorBuff(G, colors, numThreads, totTimeColoring); + double time1 = 0; + time1 = omp_get_wtime(); assert(numColors < COLORS); long vertexNum = G->numVertices; long* vtxPtr = G->edgeListPtrs; edge* vtxInd = G->edgeList; long NE = G->numEdges; long NEx2 = NE << 1; - long NE1 = NEx2 < (1 << 26) ? NEx2 : (1 << 26); // 256MB/sizeof(int/float)=64M + long NE1 = NEx2 < (MAXNV) ? NEx2 : (MAXNV); // 256MB/sizeof(int/float)=64M long cnt_e = 0; for (int i = 0; i < vertexNum + 1; i++) { buff_host.offsets[i] = (int)vtxPtr[i]; - if (i != vertexNum) { - if (M[i] < 0) buff_host.offsets[i] = (int)(0x80000000 | (unsigned int)vtxPtr[i]); - } else - buff_host.offsets[i] = (int)(vtxPtr[i]); } edgeNum = buff_host.offsets[vertexNum]; for (int i = 0; i < vertexNum; i++) { @@ -1333,36 +900,126 @@ double PhaseLoop_UsingFPGA_Prep_Init_buff_host(int numColors, } } for (int i = 0; i < vertexNum; i++) { - buff_host.colorAxi[i] = colors[i]; + buff_host.colorAxi[i] = colors[i]; + } + buff_host.config0[0] = vertexNum; + buff_host.config0[1] = numColors; + buff_host.config0[2] = 0; + buff_host.config0[3] = edgeNum; + buff_host.config1[0] = opts_C_thresh; + buff_host.config1[1] = currMod; + time1 = omp_get_wtime() - time1; +} + +void PhaseLoop_UsingFPGA_Post(long vertexNum, + int num_runsFPGA, + KMemorys_host& buff_host, + struct timeval& tstartE2E, + struct timeval& tendE2E, + std::vector >& kernel_evt1, + // output + long* C, + int& totItr, + double& currMod, + int& totTimeE2E) { + // updating + totItr += buff_host.config0[2]; + currMod = buff_host.config1[1]; + for (int i = 0; i < vertexNum; i++) { + C[i] = (long)buff_host.cidPrev[i]; + } + unsigned long timeStart, timeEnd; + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); + int exec_timeE2E = diff(&tendE2E, &tstartE2E); + totTimeE2E += exec_timeE2E; + // showing + unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish kernel execution" << std::endl; + std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish E2E execution" << std::endl; + // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" + printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, + exec_timeE2E, buff_host.config0[2], currMod); + std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" + << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; + std::cout << "-------------------------------------------------------" << std::endl; +} + +void PhaseLoop_UsingFPGA_Post_par(long vertexNum, + int num_runsFPGA, + KMemorys_host& buff_host, + struct timeval& tstartE2E, + struct timeval& tendE2E, + std::vector >& kernel_evt1, + // output + long* C, + int& totItr, + double& currMod, + int& totTimeE2E) { + // updating + totItr += buff_host.config0[2]; + currMod = buff_host.config1[1]; + for (int i = 0; i < vertexNum; i++) { + C[i] = (long)buff_host.cidPrev[i]; } - buff_host.config0[0] = vertexNum; - buff_host.config0[1] = numColors; - buff_host.config0[2] = 0; - buff_host.config0[3] = edgeNum; - buff_host.config1[0] = opts_C_thresh; - buff_host.config1[1] = currMod; - time1 = omp_get_wtime() - time1; - return time1; + unsigned long timeStart, timeEnd; + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); + int exec_timeE2E = diff(&tendE2E, &tstartE2E); + totTimeE2E += exec_timeE2E; + // showing + unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish kernel execution" << std::endl; + std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish E2E execution" << std::endl; + // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" + printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, + exec_timeE2E, buff_host.config0[2], currMod); + std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" + << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; + std::cout << "-------------------------------------------------------" << std::endl; } -double PhaseLoop_UsingFPGA_Prep_Read_buff_host(long vertexNum, - KMemorys_host& buff_host, - int phase, - int eachItrs[MAX_NUM_PHASE], - // output - long* C, - int& totItr, - double& currMod) { - double time1 = omp_get_wtime(); + +void PhaseLoop_UsingFPGA_Post_par_prune(long vertexNum, + int num_runsFPGA, + KMemorys_host_prune& buff_host, + struct timeval& tstartE2E, + struct timeval& tendE2E, + std::vector >& kernel_evt1, + // output + long* C, + int& totItr, + double& currMod, + int& totTimeE2E) { // updating - eachItrs[phase - 1] = buff_host.config0[2]; totItr += buff_host.config0[2]; currMod = buff_host.config1[1]; for (int i = 0; i < vertexNum; i++) { C[i] = (long)buff_host.cidPrev[i]; } - time1 = omp_get_wtime() - time1; - return time1; + unsigned long timeStart, timeEnd; + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); + kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); + int exec_timeE2E = diff(&tendE2E, &tstartE2E); + totTimeE2E += exec_timeE2E; + // showing + unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish kernel execution" << std::endl; + std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; + std::cout << "-------------------------------------------------------" << std::endl; + std::cout << "INFO: Finish E2E execution" << std::endl; + std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" + << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 << " us\n" + << "INFO: The iterations is: " << buff_host.config0[2] << "\n"; + std::cout << "-------------------------------------------------------" << std::endl; } + double PhaseLoop_UsingFPGA_Prep_Read_buff_host(long vertexNum, KMemorys_host& buff_host, int& eachItrs, @@ -1406,35 +1063,8 @@ double PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune(long vertexNum, unsigned long diff2(const struct timeval* newTime, const struct timeval* oldTime) { return (newTime->tv_sec - oldTime->tv_sec) * 1000000 + (newTime->tv_usec - oldTime->tv_usec); } -void PhaseLoop_UsingFPGA_Post_par_noRead(double* p_eachTimeE2E, - int num_runsFPGA, - int num_iter, - struct timeval& tstartE2E, - struct timeval& tendE2E, - // std::vector > &kernel_evt1, - double currMod, - int& totTimeE2E) { - // unsigned long timeStart, timeEnd; - // kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); - // kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); - int exec_timeE2E = diff2(&tendE2E, &tstartE2E); - totTimeE2E += exec_timeE2E; - // showing - // unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish kernel execution" << std::endl; - // std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; - std::cout << "-------------------------------------------------------" << std::endl; - std::cout << "INFO: Finish E2E execution" << std::endl; - // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" - printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, - exec_timeE2E, num_iter, currMod); - // std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 - // << " us\n" - std::cout << "INFO: The iterations is: " << num_iter << "\n"; - std::cout << "-------------------------------------------------------" << std::endl; - *p_eachTimeE2E = (1.0 * exec_timeE2E * 1e-6); -} + +/////////////////////////////////////////////////////////// double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, GLV* pglv_iter, int numThreads, @@ -1781,6 +1411,63 @@ void runLouvainWithFPGA_demo_par_core_prune(bool hasGhost, std::vector devices = xcl::get_xil_devices(); int d_num = devices.size(); + + // select device id with multi board + cl_uint platformID = 0; + cl_platform_id* platforms = NULL; + char vendor_name[128] = {0}; + cl_uint num_platforms = 0; + cl_int err2 = clGetPlatformIDs(0, NULL, &num_platforms); + if (CL_SUCCESS != err2) { + std::cout << "INFO: get platform failed" << std::endl; + } + platforms = (cl_platform_id*)malloc(sizeof(cl_platform_id) * num_platforms); + if (NULL == platforms) { + std::cout << "INFO: allocate platform failed" << std::endl; + } + err2 = clGetPlatformIDs(num_platforms, platforms, NULL); + if (CL_SUCCESS != err2) { + std::cout << "INFO: get platform failed" << std::endl; + } + for (cl_uint ui = 0; ui < num_platforms; ++ui) { + err2 = clGetPlatformInfo(platforms[ui], CL_PLATFORM_VENDOR, 128 * sizeof(char), vendor_name, NULL); + if (CL_SUCCESS != err2) { + std::cout << "INFO: get platform failed" << std::endl; + } else if (!std::strcmp(vendor_name, "Xilinx")) { + platformID = ui; + } + } + + uint32_t totalXilinxDevices = devices.size(); + uint32_t totalSupportedDevices_ = 0; + cl_device_id* c_devices = (cl_device_id*)malloc(sizeof(cl_device_id) * totalXilinxDevices); + clGetDeviceIDs(platforms[platformID], CL_DEVICE_TYPE_ALL, totalXilinxDevices, c_devices, NULL); + size_t valueSize; + char* value; + std::vector supportedDeviceNames_; // Supported device names + int XF_GRAPH_L3_MAX_DEVICES_PER_NODE = 4; + uint32_t supportedDeviceIds_[XF_GRAPH_L3_MAX_DEVICES_PER_NODE]; + const std::string token = "xilinx_u55c_gen3x16_xdma_base_2"; + supportedDeviceNames_.push_back(token); + + for (uint32_t i = 0; i < totalXilinxDevices; ++i) { + // print device name + clGetDeviceInfo(c_devices[i], CL_DEVICE_NAME, 0, NULL, &valueSize); + value = new char[valueSize]; + clGetDeviceInfo(c_devices[i], CL_DEVICE_NAME, valueSize, value, NULL); + if (std::find(supportedDeviceNames_.begin(), supportedDeviceNames_.end(), value) != + supportedDeviceNames_.end()) { + std::cout << "INFO: Found requested device: " << value << " ID=" << i << std::endl; + supportedDeviceIds_[totalSupportedDevices_++] = i; // save curret supported supported devices + } else { + std::cout << "INFO: Skipped non-requested device: " << value << " ID=" << i << std::endl; + } + delete[] value; + } + std::cout << "INFO: Total matching devices: " << totalSupportedDevices_ << std::endl; + id_dev = supportedDeviceIds_[0]; + // end the id + if (id_dev >= d_num) { printf("\033[1;31;40mERROR\033[0m: id_dev(%d) >= d_num(%d)\n", id_dev, d_num); return; @@ -1951,6 +1638,142 @@ void runLouvainWithFPGA_demo_par_core_prune(bool hasGhost, timePostPost - timePostPost_feature); // eachTimePhase } // End of runM +// top level +void runLouvainWithFPGA_demo(graphNew* G, + long* C_orig, + char* opts_xclbinPath, + bool opts_coloring, + long opts_minGraphSize, + double opts_threshold, + double opts_C_thresh, + int numThreads) { + long NV = G->numVertices; + long NE_org = G->numEdges; + long numClusters; + assert(NV < MAXNV); + assert(NE_org < MAXNE); + + int* colors; + if (opts_coloring) { + colors = (int*)malloc(G->numVertices * sizeof(int)); + assert(colors != 0); + } + long* C = (long*)malloc(NV * sizeof(long)); + assert(C != 0); +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + C[i] = -1; + } + + std::vector devices = xcl::get_xil_devices(); + int dev_id = 0; + + cl::Device device = devices[dev_id]; + cl::Context context(device); + std::string devName = device.getInfo(); + printf("INFO: Found Device=%s\n", devName.c_str()); + cl::Program::Binaries xclBins = xcl::import_binary_file(opts_xclbinPath); + devices.resize(1); + cl::Program program(context, devices, xclBins); + cl::Kernel kernel_louvain(program, "kernel_louvain"); + printf("INFO: kernel has been created\n"); + cl::CommandQueue q(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); + + KMemorys_host buff_host; + KMemorys_clBuff buff_cl; + long NE_mem = NE_org * 2; // number for real edge to be stored in memory + long NE_mem_1 = NE_mem < (MAXNV) ? NE_mem : (MAXNV); + long NE_mem_2 = NE_mem - NE_mem_1; + UsingFPGA_MapHostClBuff(NV, NE_mem_1, NE_mem_2, context, buff_host, buff_cl); + + double totTimeClustering = 0; // time accumulator for clustering by CPU + double totTimeBuildingPhase = 0; // time accumulator for Building new graphNew for next phase by CPU + double totTimeColoring = 0; // time accumulator for coloring + double prevMod = -1; // Last-phase modularity + double currMod = -1; // Current modularity + int phase = 1; // Total phase counter + int totTimeE2E = 0; // FPGA E2E time accumulator + int num_runsFPGA = 0; // FPGA calling times counter + int totItr = 0; // Total iteration counter + bool nonColor = false; // Make sure that at least one phase with lower opts_threshold runs + bool isItrStop = false; + while (!isItrStop) { + printf("===============================\n"); + printf("Phase %d\n", phase); + printf("===============================\n"); + prevMod = currMod; + bool isUsingFPGA = ((opts_coloring) && (G->numVertices > opts_minGraphSize) && (nonColor == false)); + + if (isUsingFPGA) { + long vertexNum = G->numVertices; + bool isLargeEdge = G->numEdges > (MAXNV / 2); + num_runsFPGA++; + struct timeval tstartE2E, tendE2E; + std::vector ob_in; + std::vector ob_out; + std::vector > kernel_evt0(1); + std::vector > kernel_evt1(1); + kernel_evt0[0].resize(1); + kernel_evt1[0].resize(1); + + PhaseLoop_UsingFPGA_Prep(G, opts_C_thresh, currMod, numThreads, totTimeColoring, colors, buff_host); + + gettimeofday(&tstartE2E, 0); + { /* 5-Step flow for using FPGA */ + PhaseLoop_UsingFPGA_1_KernelSetup(isLargeEdge, kernel_louvain, ob_in, ob_out, buff_cl); + + PhaseLoop_UsingFPGA_2_DataWriteTo(q, kernel_evt0, ob_in); + + PhaseLoop_UsingFPGA_3_KernelRun(q, kernel_evt0, kernel_evt1, kernel_louvain); + + PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); + + PhaseLoop_UsingFPGA_5_KernelFinish(q); + } + gettimeofday(&tendE2E, 0); + + PhaseLoop_UsingFPGA_Post(vertexNum, num_runsFPGA, buff_host, tstartE2E, tendE2E, kernel_evt1, C, totItr, + currMod, totTimeE2E); + } else { + PhaseLoop_UsingCPU(opts_threshold, numThreads, currMod, G, C, C_orig, totItr, nonColor, totTimeClustering); + } + isItrStop = PhaseLoop_CommPostProcessing(NV, numThreads, opts_threshold, opts_coloring, prevMod, currMod, G, C, + C_orig, nonColor, phase, totItr, numClusters, totTimeBuildingPhase); + } + + printf("********************************************\n"); + printf("********* Compact Summary *************\n"); + printf("********************************************\n"); + printf("Number of threads : %d\tm=%d \t thhd=%lf \t thhd_c=%lf\n", numThreads, opts_minGraphSize, + opts_threshold, opts_C_thresh); + printf("Total number of phases : %d\n", phase); + printf("Total number of iterations : %d\n", totItr); + printf("Final number of clusters : %ld\n", numClusters); + printf("Final modularity : %lf\n", prevMod); + printf("Total time for clustering : %lf\n", totTimeClustering); + printf("Total time for building phases : %lf\n", totTimeBuildingPhase); + printf("Total E2E time(s) : %lf\n", (1.0 * totTimeE2E * 1e-6)); + if (opts_coloring) { + printf("Total time for coloring : %lf\n", totTimeColoring); + } + printf("********************************************\n"); + printf("TOTAL TIME : %lf\n", + ((1.0 * totTimeE2E * 1e-6) + totTimeClustering + totTimeBuildingPhase + totTimeColoring)); + printf("********************************************\n"); + + /* Clean up memories */ + free(C); + if (G != 0) { + free(G->edgeListPtrs); + free(G->edgeList); + free(G); + } + if (opts_coloring) { + if (colors != 0) free(colors); + } + buff_host.freeMem(); +} // End of runMultiPhaseLouvainAlgorithm() + GLV* LouvainGLV_general(bool hasGhost, int mode_flow, int id_dev, @@ -2011,3 +1834,260 @@ void LouvainGLV_general_batch_thread(bool hasGhost, timeLv[p] = omp_get_wtime() - time1; } } + +// debug // clean code +// void inline PhaseLoop_Kernel_Enable(cl::Kernel& kernel_louvain, +// cl::CommandQueue& q, +// std::vector& ob_in, +// std::vector& ob_out, +// std::vector >& kernel_evt0, +// std::vector >& kernel_evt1) { +// kernel_evt0[0].resize(1); +// kernel_evt1[0].resize(1); + +// q.enqueueMigrateMemObjects(ob_in, 0, nullptr, kernel_evt0[0].data()); // 0 : migrate from host to dev +// q.enqueueTask(kernel_louvain, &kernel_evt0[0], kernel_evt1[0].data()); +// q.enqueueMigrateMemObjects(ob_out, 1, &kernel_evt1[0], nullptr); // 1 : migrate from dev to host +// q.finish(); +// } + +// void PhaseLoop_UsingFPGA_Post_par_noRead(double* p_eachTimeE2E, +// int num_runsFPGA, +// int num_iter, +// struct timeval& tstartE2E, +// struct timeval& tendE2E, +// // std::vector > &kernel_evt1, +// double currMod, +// int& totTimeE2E) { +// // unsigned long timeStart, timeEnd; +// // kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_START, &timeStart); +// // kernel_evt1[0][0].getProfilingInfo(CL_PROFILING_COMMAND_END, &timeEnd); +// int exec_timeE2E = diff2(&tendE2E, &tstartE2E); +// totTimeE2E += exec_timeE2E; +// // showing +// // unsigned long exec_time0 = (timeEnd - timeStart) / 1000.0; +// std::cout << "-------------------------------------------------------" << std::endl; +// std::cout << "INFO: Finish kernel execution" << std::endl; +// // std::cout << "INFO: Average execution per run: " << exec_time0 << " us\n"; +// std::cout << "-------------------------------------------------------" << std::endl; +// std::cout << "INFO: Finish E2E execution" << std::endl; +// // std::cout << "INFO: FPGA execution time of " << num_runsFPGA << " runs:" << exec_timeE2E << " us\n" +// printf("INFO: FPGA execution time of %1d runs:%9d us Iteration times = %2d currMod=%f\n", num_runsFPGA, +// exec_timeE2E, num_iter, currMod); +// // std::cout << "INFO: Average execution per run: " << exec_timeE2E - exec_time0 * num_runsFPGA + exec_time0 +// // << " us\n" +// std::cout << "INFO: The iterations is: " << num_iter << "\n"; +// std::cout << "-------------------------------------------------------" << std::endl; +// *p_eachTimeE2E = (1.0 * exec_timeE2E * 1e-6); +// } + +// double PhaseLoop_UsingFPGA_Prep_Read_buff_host(long vertexNum, +// KMemorys_host& buff_host, +// int phase, +// int eachItrs[MAX_NUM_PHASE], +// // output +// long* C, +// int& totItr, +// double& currMod) { +// double time1 = omp_get_wtime(); +// // updating +// eachItrs[phase - 1] = buff_host.config0[2]; +// totItr += buff_host.config0[2]; +// currMod = buff_host.config1[1]; +// for (int i = 0; i < vertexNum; i++) { +// C[i] = (long)buff_host.cidPrev[i]; +// } +// time1 = omp_get_wtime() - time1; +// return time1; +// } + +// void PhaseLoop_UsingFPGA(long NV, +// double opts_C_thresh, +// bool opts_coloring, +// double opts_threshold, +// int numThreads, +// double& currMod, +// graphNew*& G, +// long*& C, +// long*& C_orig, +// int& totItr, +// KMemorys_host& buff_host, +// KMemorys_clBuff& buff_cl, +// cl::Kernel& kernel_louvain, +// cl::CommandQueue& q, +// int& num_runsFPGA, +// int*& colors, +// int& totTimeE2E, +// double& totTimeColoring) { +// long vertexNum = G->numVertices; +// bool isLargeEdge = G->numEdges > (1 << 25); +// num_runsFPGA++; +// struct timeval tstartE2E, tendE2E; +// std::vector ob_in; +// std::vector ob_out; +// std::vector > kernel_evt0(1); +// std::vector > kernel_evt1(1); +// kernel_evt0[0].resize(1); +// kernel_evt1[0].resize(1); + +// PhaseLoop_UsingFPGA_Prep(G, opts_C_thresh, currMod, numThreads, totTimeColoring, colors, buff_host); +// gettimeofday(&tstartE2E, 0); +// PhaseLoop_UsingFPGA_1_KernelSetup(isLargeEdge, kernel_louvain, ob_in, ob_out, buff_cl); +// PhaseLoop_UsingFPGA_2_DataWriteTo(q, kernel_evt0, ob_in); +// PhaseLoop_UsingFPGA_3_KernelRun(q, kernel_evt0, kernel_evt1, kernel_louvain); +// PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); +// PhaseLoop_UsingFPGA_5_KernelFinish(q); +// gettimeofday(&tendE2E, 0); +// PhaseLoop_UsingFPGA_Post(vertexNum, num_runsFPGA, buff_host, tstartE2E, tendE2E, kernel_evt1, C, totItr, currMod, +// totTimeE2E); +// } + +// double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, +// GLV* pglv_iter, +// int numThreads, +// double opts_threshold, +// bool opts_coloring, +// // modified: +// bool& nonColor, +// int& phase, +// int& totItr, +// long& numClusters, +// double& totTimeBuildingPhase) { +// double time1 = 0; +// time1 = omp_get_wtime(); +// graphNew* Gnew; +// numClusters = renumberClustersContiguously_ghost(pglv_iter->C, pglv_iter->G->numVertices, pglv_iter->NVl); +// printf("Number of unique clusters: %ld\n", numClusters); +// PhaseLoop_UpdatingC_org(phase, pglv_orig->NV, pglv_iter->NV, pglv_iter->C, pglv_orig->C); + +// long* M_new = CreateM(numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M); + +// Gnew = (graphNew*)malloc(sizeof(graphNew)); +// assert(Gnew != 0); +// double tmpTime = buildNextLevelGraphOpt(pglv_iter->G, Gnew, pglv_iter->C, numClusters, numThreads); +// totTimeBuildingPhase += tmpTime; +// pglv_iter->SetByOhterG(Gnew, M_new); +// time1 = omp_get_wtime() - time1; +// return time1; +// } + +// void runLouvainWithFPGA(graphNew* G, // Input graphNew, undirectioned +// long* C_orig, // Output +// char* opts_xclbinPath, +// bool opts_coloring, +// long opts_minGraphSize, +// double opts_threshold, +// double opts_C_thresh, +// int numThreads) { +// long NV = G->numVertices; +// long NE_org = G->numEdges; +// long numClusters; +// /* Check graphNew size, limited by hardware features */ +// assert(NV < MAXNV); +// assert(NE_org < MAXNE); + +// /* For coloring */ +// int* colors; +// if (opts_coloring) { +// colors = (int*)malloc(G->numVertices * sizeof(int)); +// assert(colors != 0); +// } + +// /* To build new hierarchical graphNews*/ +// long* C = (long*)malloc(NV * sizeof(long)); +// assert(C != 0); +// #pragma omp parallel for +// for (long i = 0; i < NV; i++) { +// C[i] = -1; +// } + +// /*******************************/ +// /* FPGA-related data structures*/ +// /*******************************/ +// /* platform related operations */ +// std::vector devices = xcl::get_xil_devices(); +// cl::Device device = devices[0]; +// cl::Context context(device); +// std::string devName = device.getInfo(); +// printf("INFO: Found Device=%s\n", devName.c_str()); +// cl::Program::Binaries xclBins = xcl::import_binary_file(opts_xclbinPath); +// devices.resize(1); +// cl::Program program(context, devices, xclBins); +// cl::Kernel kernel_louvain(program, "kernel_louvain"); +// printf("INFO: kernel has been created\n"); +// cl::CommandQueue q(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); +// /* Memories mapping */ +// KMemorys_host buff_host; +// KMemorys_clBuff buff_cl; +// long NE_mem = NE_org * 2; // number for real edge to be stored in memory +// long NE_mem_1 = NE_mem < (MAXNV) ? NE_mem : (MAXNV); +// long NE_mem_2 = NE_mem - NE_mem_1; +// UsingFPGA_MapHostClBuff(NV, NE_mem_1, NE_mem_2, context, buff_host, buff_cl); + +// /*******************************/ +// /* Loop for phase(s) */ +// /*******************************/ +// double totTimeClustering = 0; // time accumulator for clustering by CPU +// double totTimeBuildingPhase = 0; // time accumulator for Building new graphNew for next phase by CPU +// double totTimeColoring = 0; // time accumulator for coloring +// double prevMod = -1; // Last-phase modularity +// double currMod = -1; // Current modularity +// int phase = 1; // Total phase counter +// int totTimeE2E = 0; // FPGA E2E time accumulator +// int num_runsFPGA = 0; // FPGA calling times counter +// int totItr = 0; // Total iteration counter +// bool nonColor = false; // Make sure that at least one phase with lower opts_threshold runs +// bool isItrStop = false; +// while (!isItrStop) { +// printf("===============================\n"); +// printf("Phase %d\n", phase); +// printf("===============================\n"); +// prevMod = currMod; +// bool isUsingFPGA = ((opts_coloring) && (G->numVertices > opts_minGraphSize) && (nonColor == false)); + +// if (isUsingFPGA) { +// PhaseLoop_UsingFPGA(NV, opts_C_thresh, opts_coloring, opts_threshold, numThreads, currMod, G, C, C_orig, +// totItr, buff_host, buff_cl, kernel_louvain, q, /*kernel's parameter*/ +// num_runsFPGA, colors, totTimeE2E, totTimeColoring); +// } else { +// PhaseLoop_UsingCPU(opts_threshold, numThreads, currMod, G, C, C_orig, totItr, nonColor, +// totTimeClustering); +// } +// /* General post-processing for both FPGA and CPU */ +// isItrStop = PhaseLoop_CommPostProcessing(NV, numThreads, opts_threshold, opts_coloring, prevMod, currMod, G, +// C, +// C_orig, nonColor, phase, totItr, numClusters, totTimeBuildingPhase); +// } // End of while(1) = End of Louvain + +// /* Print information*/ +// printf("********************************************\n"); +// printf("********* Compact Summary *************\n"); +// printf("********************************************\n"); +// printf("Number of threads : %d\n", numThreads); +// printf("Total number of phases : %d\n", phase); +// printf("Total number of iterations : %d\n", totItr); +// printf("Final number of clusters : %ld\n", numClusters); +// printf("Final modularity : %lf\n", prevMod); +// printf("Total time for clustering : %lf\n", totTimeClustering); +// printf("Total time for building phases : %lf\n", totTimeBuildingPhase); +// printf("Total E2E time(s) : %lf\n", (1.0 * totTimeE2E * 1e-6)); +// if (opts_coloring) { +// printf("Total time for coloring : %lf\n", totTimeColoring); +// } +// printf("********************************************\n"); +// printf("TOTAL TIME : %lf\n", +// ((1.0 * totTimeE2E * 1e-6) + totTimeClustering + totTimeBuildingPhase + totTimeColoring)); +// printf("********************************************\n"); + +// /* Clean up memories */ +// free(C); +// if (G != 0) { +// free(G->edgeListPtrs); +// free(G->edgeList); +// free(G); +// } +// if (opts_coloring) { +// if (colors != 0) free(colors); +// } +// buff_host.freeMem(); +// } // End of runMultiPhaseLouvainAlgorithm() diff --git a/graph/L2/tests/louvain_fast/host/partition/test.cpp b/graph/L2/tests/louvain_fast/host/partition/test.cpp index 6c4f498a05..1de9714e46 100644 --- a/graph/L2/tests/louvain_fast/host/partition/test.cpp +++ b/graph/L2/tests/louvain_fast/host/partition/test.cpp @@ -58,7 +58,7 @@ int host_ParserParameters(int argc, int has_numThread = general_findPara(argc, argv, "-thread"); int has_num_par = general_findPara(argc, argv, "-num_par"); int has_gh_par = general_findPara(argc, argv, "-gh_par"); - int has_flow_prune = general_findPara(argc, argv, "-prun"); + int has_flow_prune = general_findPara(argc, argv, "-prun") || general_findPara(argc, argv, "-fast"); if (has_opts_C_thresh != -1) { rec[has_opts_C_thresh] = true; @@ -233,29 +233,8 @@ int LvTest_main_par(int argc, char** argv) { int num_par; int gh_par; bool usingPrune = false; - int numThreads; /*= GetNumThreadsForOpMP(argc, argv); - - - if( general_findPara(argc, argv, "-prun")!=-1 || general_findPara(argc, argv, "-lvprun")!=-1|| - general_findPara(argc, argv, "-fast")!=-1) - { - usingPrune=true; - argc--; - } - host_ParserParameters( - argc, - argv, - opts_C_thresh, //double opts_C_thresh; //Threshold with coloring on - opts_minGraphSize,//long opts_minGraphSize; //Min |V| to enable coloring - opts_threshold, //double opts_threshold; //Value of threshold - opts_ftype, //int opts_ftype; //File type - opts_inFile, //char opts_inFile[4096]; - opts_coloring, //bool opts_coloring; - opts_output, //bool opts_output; - opts_VF, //bool opts_VF; - opts_xclbinPath); + int numThreads; - */ host_ParserParameters(argc, argv, opts_C_thresh, // double opts_C_thresh; //Threshold with coloring on opts_minGraphSize, // long opts_minGraphSize; //Min |V| to enable coloring @@ -273,12 +252,6 @@ int LvTest_main_par(int argc, char** argv) { long NV_begin = pglv_src->G->numVertices; long* C_orig = pglv_src->C; //= (long *) malloc (NV_begin * sizeof(long)); assert(C_orig != 0); - /* #pragma omp parallel for - for (long i=0; i* flagUpdate) { DWEIGHT constant_recip = 0; #pragma HLS INTERFACE m_axi offset = slave bundle = gmem0 port = config0 latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = 4 + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = 6 #pragma HLS INTERFACE m_axi offset = slave bundle = gmem0 port = config1 latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = 4 + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = 4 #pragma HLS INTERFACE m_axi offset = slave bundle = gmem0 port = offsets latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem1 port = indices latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthEdge + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthEdge #pragma HLS INTERFACE m_axi offset = slave bundle = gmem2 port = weights latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthEdge + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthEdge #pragma HLS INTERFACE m_axi offset = slave bundle = gmem3 port = colorAxi latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 16 max_write_burst_length = 16 depth = depthVertex -#pragma HLS INTERFACE m_axi offset = slave bundle = gmem4 port = colorInx latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex +#pragma HLS INTERFACE m_axi offset = slave bundle = gmem3 port = colorInx latency = 32 num_read_outstanding = \ + 64 max_read_burst_length = 16 num_write_outstanding = 16 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem5 port = cidPrev latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem6 port = cidSizePrev latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem7 port = totPrev latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem8 port = cidCurr latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem9 port = cidSizeCurr latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem10 port = totCurr latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem11 port = cidSizeUpdate latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem12 port = totUpdate latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem13 port = cWeight latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 32 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem14 port = offsetsDup latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthVertex + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthVertex #pragma HLS INTERFACE m_axi offset = slave bundle = gmem15 port = indicesDup latency = 32 num_read_outstanding = \ - 64 max_read_burst_length = 64 num_write_outstanding = 64 max_write_burst_length = 32 depth = depthEdge + 64 max_read_burst_length = 16 num_write_outstanding = 1 max_write_burst_length = 2 depth = depthEdge -#pragma HLS INTERFACE m_axi offset = slave bundle = gmem16 port = flag latency = 32 num_read_outstanding = \ - 32 max_read_burst_length = 2 num_write_outstanding = 32 max_write_burst_length = 2 depth = depthVertex +//#pragma HLS INTERFACE m_axi offset = slave bundle = gmem16 port = flag latency = 32 num_read_outstanding = \ +// 64 max_read_burst_length = 2 num_write_outstanding = 32 max_write_burst_length = 2 depth = depthVertex -#pragma HLS INTERFACE m_axi offset = slave bundle = gmem17 port = flagUpdate latency = 32 num_read_outstanding = \ - 32 max_read_burst_length = 2 num_write_outstanding = 32 max_write_burst_length = 2 depth = depthVertex +//#pragma HLS INTERFACE m_axi offset = slave bundle = gmem17 port = flagUpdate latency = 32 num_read_outstanding = \ +// 64 max_read_burst_length = 2 num_write_outstanding = 32 max_write_burst_length = 2 depth = depthVertex + +#pragma HLS INTERFACE m_axi offset = slave bundle = gmem4 port = flag latency = 32 num_read_outstanding = \ + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex + +#pragma HLS INTERFACE m_axi offset = slave bundle = gmem4 port = flagUpdate latency = 32 num_read_outstanding = \ + 64 max_read_burst_length = 16 num_write_outstanding = 32 max_write_burst_length = 16 depth = depthVertex #pragma HLS INTERFACE s_axilite port = config0 bundle = control #pragma HLS INTERFACE s_axilite port = config1 bundle = control diff --git a/graph/L2/tests/louvain_fast/postSysLink.tcl b/graph/L2/tests/louvain_fast/postSysLink.tcl new file mode 100644 index 0000000000..2dc2f67034 --- /dev/null +++ b/graph/L2/tests/louvain_fast/postSysLink.tcl @@ -0,0 +1 @@ +set_property -dict [list CONFIG.ECC_EN {false} CONFIG.ECC_SCRUB_EN {false}] [get_bd_cells hmss_0] diff --git a/graph/L3/graphPartition/grappolo/include/RngStream.h b/graph/L3/graphPartition/grappolo/include/RngStream.h new file mode 100755 index 0000000000..fc7ec481ea --- /dev/null +++ b/graph/L3/graphPartition/grappolo/include/RngStream.h @@ -0,0 +1,91 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#ifndef RNGSTREAM_H +#define RNGSTREAM_H + +#include + +class RngStream { + public: + RngStream(const char* name = ""); + + static bool SetPackageSeed(const unsigned long seed[6]); + + void ResetStartStream(); + + void ResetStartSubstream(); + + void ResetNextSubstream(); + + void SetAntithetic(bool a); + + void IncreasedPrecis(bool incp); + + bool SetSeed(const unsigned long seed[6]); + + void AdvanceState(long e, long c); + + void GetState(unsigned long seed[6]) const; + + void WriteState() const; + + void WriteStateFull() const; + + double RandU01(); + + int RandInt(int i, int j); + + private: + double Cg[6], Bg[6], Ig[6]; + + bool anti, incPrec; + + std::string name; + + static double nextSeed[6]; + + double U01(); + + double U01d(); +}; + +#endif diff --git a/graph/L3/graphPartition/grappolo/include/defs.h b/graph/L3/graphPartition/grappolo/include/defs.h new file mode 100755 index 0000000000..9f3ad6d288 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/include/defs.h @@ -0,0 +1,174 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#ifndef _DEFS_H +#define _DEFS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //For getopts() +#include "xilinxlouvain.h" +#include "ParLV.h" +//#include "ctrlLV.h" + +#define MilanRealMax HUGE_VAL // +INFINITY +#define MilanRealMin -MilanRealMax // -INFINITY + +#ifdef PRINTINFO +#define PRINT_DETAILED_STATS_ +#endif + +typedef struct comm { + long size; + long degree; +} Comm; + +struct clustering_parameters { + const char* inFile; // Input file + int ftype; // File type + + const char* xclbin; // xclbin file + + bool strongScaling; // Enable strong scaling + bool output; // Printout the clustering data + bool VF; // Vertex following turned on + bool coloring; // If coloring is turned on + + double C_thresh; // Threshold with coloring on + long minGraphSize; // Min |V| to enable coloring + double threshold; // Value of threshold + + clustering_parameters(); + void usage(); + bool parse(int argc, char* argv[]); +}; + +/////////////////// FUNCTION CALLS //////////////////// +void displayGraphCharacteristics(graphNew* G); +void displayGraph(graphNew* G); +void displayGraphEdgeList(graphNew* G); +void displayGraphEdgeList(graphNew* G, FILE* out); +// Graph Clustering (Community detection) +double parallelLouvianMethod( + graphNew* G, long* C, int nThreads, double Lower, double thresh, double* totTime, int* numItr); +double algoLouvainWithDistOneColoring(graphNew* G, + long* C, + int nThreads, + int* color, + int numColor, + double Lower, + double thresh, + double* totTime, + int* numItr); +void runMultiPhaseLouvainAlgorithm( + graphNew* G, long* C_orig, int coloring, long minGraphSize, double threshold, double C_threshold, int numThreads); + +// void runLouvainWithFPGA(graphNew *G, long *C_orig, char *xclbinName, bool coloring, long minGraphSize, +// double threshold, double C_threshold, int numThreads); + +//*** Clustering Utility Functions ***// +// Distance-1 Coloring +int algoDistanceOneVertexColoring(graphNew* G, int* vtxColor, int nThreads, double* totTime); +int algoDistanceOneVertexColoringOpt(graphNew* G, int* vtxColor, int nThreads, double* totTime); + +// Other +inline void Visit(long v, long myCommunity, short* Visited, long* Volts, long* vtxPtr, edge* vtxInd, long* C); +long buildCommunityBasedOnVoltages(graphNew* G, long* Volts, long* C, long* Cvolts); +void buildNextLevelGraph(graphNew* Gin, graphNew* Gout, long* C, long numUniqueClusters); +long renumberClustersContiguously(long* C, long size); +double buildNextLevelGraphOpt(graphNew* Gin, graphNew* Gout, long* C, long numUniqueClusters, int nThreads); +// Vertex following functions: +long vertexFollowing(graphNew* G, long* C); +double buildNewGraphVF(graphNew* Gin, graphNew* Gout, long* C, long numUniqueClusters); + +//*** Utility Functions ***// +void duplicateGivenGraph(graphNew* Gin, graphNew* Gout); +void writeEdgeListToFile(graphNew* G, FILE* out); + +// Random Number Generation: +void generateRandomNumbers(double* RandVec, long size); + +void displayGraph(graphNew* G); +void displayGraphCharacteristics(graphNew* G); +graphNew* convertDirected2Undirected(graphNew* G); + +void segregateEdgesBasedOnVoltages(graphNew* G, long* Volts); +void writeGraphPajekFormat(graphNew* G, char* filename); +void writeGraphPajekFormatWithNodeVolts(graphNew* G, long* Cvolts, char* filename); +void writeGraphBinaryFormat(graphNew* G, char* filename); // Binary (each edge once) +void writeGraphMetisSimpleFormat(graphNew* G, char* filename); // Metis format; no weights + +// File parsers: +void parse_Dimacs9FormatDirectedNewD(graphNew* G, char* fileName); +long removeEdges(long NV, long NE, edge* edgeList); +void SortNodeEdgesByIndex2(long NV, edge* list1, edge* list2, long* ptrs); +void SortEdgesUndirected2(long NV, long NE, edge* list1, edge* list2, long* ptrs); + +void loadMetisFileFormat(graphNew* G, const char* filename); // Metis (DIMACS#10) +void parse_MatrixMarket(graphNew* G, char* fileName); // Matrix-Market +void parse_MatrixMarket_Sym_AsGraph(graphNew* G, char* fileName); + +void parse_Dimacs1Format(graphNew* G, char* fileName); // DIMACS#1 Challenge format +void parse_Dimacs9FormatDirectedNewD(graphNew* G, char* fileName); // DIMACS#9 Challenge format +void parse_PajekFormat(graphNew* G, char* fileName); // Pajek format (each edge stored only once +void parse_PajekFormatUndirected(graphNew* G, char* fileName); +void parse_DoulbedEdgeList(graphNew* G, char* fileName); + +void parse_EdgeListBinary(graphNew* G, char* fileName); // Binary: Each edge stored only once +void parse_SNAP(graphNew* G, char* fileName); + +// For reading power grid data +long* parse_MultiKvPowerGridGraph(graphNew* G, char* fileName); // Four-column format + +// Graph partitioning with Metis: +void MetisGraphPartitioner(graphNew* G, long* VertexPartitioning, int numParts); + +#endif diff --git a/graph/L3/graphPartition/grappolo/include/utilityClusteringFunctions.h b/graph/L3/graphPartition/grappolo/include/utilityClusteringFunctions.h new file mode 100755 index 0000000000..51b0af5f8e --- /dev/null +++ b/graph/L3/graphPartition/grappolo/include/utilityClusteringFunctions.h @@ -0,0 +1,66 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "defs.h" + +using namespace std; + +void sumVertexDegree(edge* vtxInd, long* vtxPtr, long* vDegree, long NV, Comm* cInfo); + +double calConstantForSecondTerm(long* vDegree, long NV); + +void initCommAss(long* pastCommAss, long* currCommAss, long NV); + +long buildLocalMapCounter(long adj1, + long adj2, + map& clusterLocalMap, + vector& Counter, + edge* vtxInd, + long* currCommAss, + long me); + +long max(map& clusterLocalMap, + vector& Counter, + long selfLoop, + Comm* cInfo, + long degree, + long sc, + double constant); diff --git a/graph/L3/graphPartition/grappolo/include/utilityStringTokenizer.hpp b/graph/L3/graphPartition/grappolo/include/utilityStringTokenizer.hpp new file mode 100755 index 0000000000..57a4f4c8df --- /dev/null +++ b/graph/L3/graphPartition/grappolo/include/utilityStringTokenizer.hpp @@ -0,0 +1,365 @@ +/* Author: Arijit Tarafdar < aritar@gmail.com > */ +/* Used with permission by the author */ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#ifndef _string_Tokenizer_ +#define _string_Tokenizer_ + +// I/O +#include +#include +#include +#include + +using namespace std; + +class StringTokenizer { + private: + string DelimiterString; + string InputString; + string TokenString; + + public: + long CountTokens(); // ***Public Function No. 1*** + long CountTokens(char*); // ***Public Function No. 2*** + + string GetDelimiterString() const; // ***Public Function No. 3*** + string GetFirstToken(); // ***Public Function No. 4*** + string GetInputString() const; // ***Public Function No. 5*** + string GetLastToken(); // ***Public Function No. 6*** + string GetNextToken(); // ***Public Function No. 7*** + string GetNextToken(char*); // ***Public Function No. 8*** + string GetToken(long); // ***Public Function No. 9*** + + long HasMoreTokens(); // ***Public Function No. 10*** + long HasMoreTokens(char*); // ***Public Function No. 11*** + + long SetInputString(char*); // ***Public Function No. 12*** + long SetDelimiterString(char*); // ***Public Function No. 13*** + + StringTokenizer(); // ***Public Function No. 14*** + StringTokenizer(char*); // ***Public Function No. 15*** + StringTokenizer(char*, char*); // ***Public Function No. 16*** + StringTokenizer(string, char*); // ***Public Function No. 17*** + StringTokenizer(string, string); // ***Public Function No. 18*** + ~StringTokenizer(); // ***Public Function No. 19*** +}; +/* ------------------------------------------------------------------------- */ + +long StringTokenizer::CountTokens() { + long TokenCounter = 1; + + long DelimiterPosition; + + long LastPosition; + + long TokenStringLength = TokenString.size(); + long DelimiterStringLength = DelimiterString.size(); + + string DelimiterSubString; + + if (TokenStringLength == 0) { + return (0); + } + + if (DelimiterStringLength == 0) { + return (1); + } + + DelimiterPosition = 0; + LastPosition = 0; + + while (1) { + DelimiterPosition = TokenString.find(DelimiterString, DelimiterPosition); + + if (DelimiterPosition == 0) { + DelimiterPosition += DelimiterStringLength; + + continue; + } + + if ((DelimiterPosition < 0) || (DelimiterPosition == TokenStringLength)) { + return (TokenCounter); + } + + if (DelimiterStringLength != (DelimiterPosition - LastPosition)) { + // cout<<"Delimiter Position = "< +#include +#include +#include +#include +#include + +#define XCL_BANK(n) (((unsigned int)(n)) | XCL_MEM_TOPOLOGY) +#define XCL_BANK0 XCL_BANK(0) +#define XCL_BANK1 XCL_BANK(1) +#define XCL_BANK2 XCL_BANK(2) + +#define XCL_BANK4 XCL_BANK(4) +#define XCL_BANK5 XCL_BANK(5) +#define XCL_BANK6 XCL_BANK(6) +#define XCL_BANK7 XCL_BANK(7) +#define XCL_BANK8 XCL_BANK(8) +#define XCL_BANK9 XCL_BANK(9) +#define XCL_BANK10 XCL_BANK(10) +#define XCL_BANK11 XCL_BANK(11) +#define XCL_BANK12 XCL_BANK(12) +#define XCL_BANK13 XCL_BANK(13) +#define XCL_BANK14 XCL_BANK(14) +#define XCL_BANK15 XCL_BANK(15) +#define XCL_BANK16 XCL_BANK(16) +#define XCL_BANK17 XCL_BANK(17) +#define XCL_BANK18 XCL_BANK(18) +#define XCL_BANK19 XCL_BANK(19) +#define XCL_BANK20 XCL_BANK(20) +#define XCL_BANK21 XCL_BANK(21) +#define XCL_BANK22 XCL_BANK(22) +#define XCL_BANK23 XCL_BANK(23) +#define XCL_BANK24 XCL_BANK(24) +#define XCL_BANK25 XCL_BANK(25) +#define XCL_BANK26 XCL_BANK(26) +#define XCL_BANK27 XCL_BANK(27) +#define XCL_BANK28 XCL_BANK(28) +#define XCL_BANK29 XCL_BANK(29) +#define XCL_BANK30 XCL_BANK(30) +#define XCL_BANK31 XCL_BANK(31) + +template +T* aligned_alloc(std::size_t num) { + void* ptr = nullptr; + if (posix_memalign(&ptr, 4096, num * sizeof(T))) { + throw std::bad_alloc(); + } + return reinterpret_cast(ptr); +} +// Compute time difference +unsigned long diff(const struct timeval* newTime, const struct timeval* oldTime) { + return (newTime->tv_sec - oldTime->tv_sec) * 1000000 + (newTime->tv_usec - oldTime->tv_usec); +} +#endif diff --git a/graph/L3/graphPartition/grappolo/src/RngStream.cpp b/graph/L3/graphPartition/grappolo/src/RngStream.cpp new file mode 100755 index 0000000000..68b0336375 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/RngStream.cpp @@ -0,0 +1,432 @@ +/***********************************************************************\ + * + * File: RngStream.cpp for multiple streams of Random Numbers + * Language: C++ (ISO 1998) + * Copyright: Pierre L'Ecuyer, University of Montreal + * Notice: This code can be used freely for personal, academic, + * or non-commercial purposes. For commercial purposes, + * please contact P. L'Ecuyer at: lecuyer@iro.umontreal.ca + * Date: 14 August 2001 + * +\***********************************************************************/ + +/***********************************************************************\ + * + * P. L'Ecuyer, ``Good Parameter Sets for Combined Multiple Recursive Random Number Generators'', + Operations Research, 47, 1 (1999), 159--164. + + + * P. L'Ecuyer, R. Simard, E. J. Chen, and W. D. Kelton, + ``An Objected-Oriented Random-Number Package with Many Long Streams and Substreams'', + Operations Research, 50, 6 (2002), 1073--1075 + + \***************************************************************************************/ + +#include "RngStream.h" +#include +#include +using namespace std; + +namespace { +const double m1 = 4294967087.0; +const double m2 = 4294944443.0; +const double norm = 1.0 / (m1 + 1.0); +const double a12 = 1403580.0; +const double a13n = 810728.0; +const double a21 = 527612.0; +const double a23n = 1370589.0; +const double two17 = 131072.0; +const double two53 = 9007199254740992.0; +const double fact = 5.9604644775390625e-8; /* 1 / 2^24 */ + +// The following are the transition matrices of the two MRG components +// (in matrix form), raised to the powers -1, 1, 2^76, and 2^127, resp. + +const double InvA1[3][3] = { // Inverse of A1p0 + {184888585.0, 0.0, 1945170933.0}, + {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}}; + +const double InvA2[3][3] = { // Inverse of A2p0 + {0.0, 360363334.0, 4225571728.0}, + {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}}; + +const double A1p0[3][3] = {{0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {-810728.0, 1403580.0, 0.0}}; + +const double A2p0[3][3] = {{0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {-1370589.0, 0.0, 527612.0}}; + +const double A1p76[3][3] = {{82758667.0, 1871391091.0, 4127413238.0}, + {3672831523.0, 69195019.0, 1871391091.0}, + {3672091415.0, 3528743235.0, 69195019.0}}; + +const double A2p76[3][3] = {{1511326704.0, 3759209742.0, 1610795712.0}, + {4292754251.0, 1511326704.0, 3889917532.0}, + {3859662829.0, 4292754251.0, 3708466080.0}}; + +const double A1p127[3][3] = {{2427906178.0, 3580155704.0, 949770784.0}, + {226153695.0, 1230515664.0, 3580155704.0}, + {1988835001.0, 986791581.0, 1230515664.0}}; + +const double A2p127[3][3] = {{1464411153.0, 277697599.0, 1610723613.0}, + {32183930.0, 1464411153.0, 1022607788.0}, + {2824425944.0, 32183930.0, 2093834863.0}}; + +//------------------------------------------------------------------------- +// Return (a*s + c) MOD m; a, s, c and m must be < 2^35 +// +double MultModM(double a, double s, double c, double m) { + double v; + long a1; + + v = a * s + c; + + if (v >= two53 || v <= -two53) { + a1 = static_cast(a / two17); + a -= a1 * two17; + v = a1 * s; + a1 = static_cast(v / m); + v -= a1 * m; + v = v * two17 + a * s + c; + } + + a1 = static_cast(v / m); + /* in case v < 0)*/ + if ((v -= a1 * m) < 0.0) + return v += m; + else + return v; +} + +//------------------------------------------------------------------------- +// Compute the vector v = A*s MOD m. Assume that -m < s[i] < m. +// Works also when v = s. +// +void MatVecModM(const double A[3][3], const double s[3], double v[3], double m) { + int i; + double x[3]; // Necessary if v = s + + for (i = 0; i < 3; ++i) { + x[i] = MultModM(A[i][0], s[0], 0.0, m); + x[i] = MultModM(A[i][1], s[1], x[i], m); + x[i] = MultModM(A[i][2], s[2], x[i], m); + } + for (i = 0; i < 3; ++i) v[i] = x[i]; +} + +//------------------------------------------------------------------------- +// Compute the matrix C = A*B MOD m. Assume that -m < s[i] < m. +// Note: works also if A = C or B = C or A = B = C. +// +void MatMatModM(const double A[3][3], const double B[3][3], double C[3][3], double m) { + int i, j; + double V[3], W[3][3]; + + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) V[j] = B[j][i]; + MatVecModM(A, V, V, m); + for (j = 0; j < 3; ++j) W[j][i] = V[j]; + } + for (i = 0; i < 3; ++i) + for (j = 0; j < 3; ++j) C[i][j] = W[i][j]; +} + +//------------------------------------------------------------------------- +// Compute the matrix B = (A^(2^e) Mod m); works also if A = B. +// +void MatTwoPowModM(const double A[3][3], double B[3][3], double m, long e) { + int i, j; + + /* initialize: B = A */ + if (A != B) { + for (i = 0; i < 3; ++i) + for (j = 0; j < 3; ++j) B[i][j] = A[i][j]; + } + /* Compute B = A^(2^e) mod m */ + for (i = 0; i < e; i++) MatMatModM(B, B, B, m); +} + +//------------------------------------------------------------------------- +// Compute the matrix B = (A^n Mod m); works even if A = B. +// +void MatPowModM(const double A[3][3], double B[3][3], double m, long n) { + int i, j; + double W[3][3]; + + /* initialize: W = A; B = I */ + for (i = 0; i < 3; ++i) + for (j = 0; j < 3; ++j) { + W[i][j] = A[i][j]; + B[i][j] = 0.0; + } + for (j = 0; j < 3; ++j) B[j][j] = 1.0; + + /* Compute B = A^n mod m using the binary decomposition of n */ + while (n > 0) { + if (n % 2) MatMatModM(W, B, B, m); + MatMatModM(W, W, W, m); + n /= 2; + } +} + +//------------------------------------------------------------------------- +// Check that the seeds are legitimate values. Returns 0 if legal seeds, +// -1 otherwise. +// +int CheckSeed(const unsigned long seed[6]) { + int i; + + for (i = 0; i < 3; ++i) { + if (seed[i] >= m1) { + cerr << "****************************************\n" + << "ERROR: Seed[" << i << "] >= 4294967087, Seed is not set." + << "\n****************************************\n\n"; + return (-1); + } + } + for (i = 3; i < 6; ++i) { + if (seed[i] >= m2) { + cerr << "*****************************************\n" + << "ERROR: Seed[" << i << "] >= 4294944443, Seed is not set." + << "\n*****************************************\n\n"; + return (-1); + } + } + if (seed[0] == 0 && seed[1] == 0 && seed[2] == 0) { + cerr << "****************************\n" + << "ERROR: First 3 seeds = 0.\n" + << "****************************\n\n"; + return (-1); + } + if (seed[3] == 0 && seed[4] == 0 && seed[5] == 0) { + cerr << "****************************\n" + << "ERROR: Last 3 seeds = 0.\n" + << "****************************\n\n"; + return (-1); + } + + return 0; +} + +} // end of anonymous namespace + +//------------------------------------------------------------------------- +// Generate the next random number. +// +double RngStream::U01() { + long k; + double p1, p2, u; + + /* Component 1 */ + p1 = a12 * Cg[1] - a13n * Cg[0]; + k = static_cast(p1 / m1); + p1 -= k * m1; + if (p1 < 0.0) p1 += m1; + Cg[0] = Cg[1]; + Cg[1] = Cg[2]; + Cg[2] = p1; + + /* Component 2 */ + p2 = a21 * Cg[5] - a23n * Cg[3]; + k = static_cast(p2 / m2); + p2 -= k * m2; + if (p2 < 0.0) p2 += m2; + Cg[3] = Cg[4]; + Cg[4] = Cg[5]; + Cg[5] = p2; + + /* Combination */ + u = ((p1 > p2) ? (p1 - p2) * norm : (p1 - p2 + m1) * norm); + + return (anti == false) ? u : (1 - u); +} + +//------------------------------------------------------------------------- +// Generate the next random number with extended (53 bits) precision. +// +double RngStream::U01d() { + double u; + u = U01(); + if (anti) { + // Don't forget that U01() returns 1 - u in the antithetic case + u += (U01() - 1.0) * fact; + return (u < 0.0) ? u + 1.0 : u; + } else { + u += U01() * fact; + return (u < 1.0) ? u : (u - 1.0); + } +} + +//************************************************************************* +// Public members of the class start here + +//------------------------------------------------------------------------- +// The default seed of the package; will be the seed of the first +// declared RngStream, unless SetPackageSeed is called. +// +double RngStream::nextSeed[6] = {12345.0, 12345.0, 12345.0, 12345.0, 12345.0, 12345.0}; + +//------------------------------------------------------------------------- +// constructor +// +RngStream::RngStream(const char* s) : name(s) { + anti = false; + incPrec = false; + + /* Information on a stream. The arrays {Cg, Bg, Ig} contain the current + state of the stream, the starting state of the current SubStream, and the + starting state of the stream. This stream generates antithetic variates + if anti = true. It also generates numbers with extended precision (53 + bits if machine follows IEEE 754 standard) if incPrec = true. nextSeed + will be the seed of the next declared RngStream. */ + + for (int i = 0; i < 6; ++i) { + Bg[i] = Cg[i] = Ig[i] = nextSeed[i]; + } + + MatVecModM(A1p127, nextSeed, nextSeed, m1); + MatVecModM(A2p127, &nextSeed[3], &nextSeed[3], m2); +} + +//------------------------------------------------------------------------- +// Reset Stream to beginning of Stream. +// +void RngStream::ResetStartStream() { + for (int i = 0; i < 6; ++i) Cg[i] = Bg[i] = Ig[i]; +} + +//------------------------------------------------------------------------- +// Reset Stream to beginning of SubStream. +// +void RngStream::ResetStartSubstream() { + for (int i = 0; i < 6; ++i) Cg[i] = Bg[i]; +} + +//------------------------------------------------------------------------- +// Reset Stream to NextSubStream. +// +void RngStream::ResetNextSubstream() { + MatVecModM(A1p76, Bg, Bg, m1); + MatVecModM(A2p76, &Bg[3], &Bg[3], m2); + for (int i = 0; i < 6; ++i) Cg[i] = Bg[i]; +} + +//------------------------------------------------------------------------- +bool RngStream::SetPackageSeed(const unsigned long seed[6]) { + if (CheckSeed(seed)) return false; // FAILURE + for (int i = 0; i < 6; ++i) nextSeed[i] = seed[i]; + return true; // SUCCESS +} + +//------------------------------------------------------------------------- +bool RngStream::SetSeed(const unsigned long seed[6]) { + if (CheckSeed(seed)) return false; // FAILURE + for (int i = 0; i < 6; ++i) Cg[i] = Bg[i] = Ig[i] = seed[i]; + return true; // SUCCESS +} + +//------------------------------------------------------------------------- +// if e > 0, let n = 2^e + c; +// if e < 0, let n = -2^(-e) + c; +// if e = 0, let n = c. +// Jump n steps forward if n > 0, backwards if n < 0. +// +void RngStream::AdvanceState(long e, long c) { + double B1[3][3], C1[3][3], B2[3][3], C2[3][3]; + + if (e > 0) { + MatTwoPowModM(A1p0, B1, m1, e); + MatTwoPowModM(A2p0, B2, m2, e); + } else if (e < 0) { + MatTwoPowModM(InvA1, B1, m1, -e); + MatTwoPowModM(InvA2, B2, m2, -e); + } + + if (c >= 0) { + MatPowModM(A1p0, C1, m1, c); + MatPowModM(A2p0, C2, m2, c); + } else { + MatPowModM(InvA1, C1, m1, -c); + MatPowModM(InvA2, C2, m2, -c); + } + + if (e) { + MatMatModM(B1, C1, C1, m1); + MatMatModM(B2, C2, C2, m2); + } + + MatVecModM(C1, Cg, Cg, m1); + MatVecModM(C2, &Cg[3], &Cg[3], m2); +} + +//------------------------------------------------------------------------- +void RngStream::GetState(unsigned long seed[6]) const { + for (int i = 0; i < 6; ++i) seed[i] = static_cast(Cg[i]); +} + +//------------------------------------------------------------------------- +void RngStream::WriteState() const { + cout << "The current state of the Rngstream"; + if (name.size() > 0) cout << " " << name; + cout << ":\n Cg = { "; + + for (int i = 0; i < 5; i++) { + cout << static_cast(Cg[i]) << ", "; + } + cout << static_cast(Cg[5]) << " }\n\n"; +} + +//------------------------------------------------------------------------- +void RngStream::WriteStateFull() const { + int i; + + cout << "The RngStream"; + if (name.size() > 0) cout << " " << name; + cout << ":\n anti = " << (anti ? "true" : "false") << "\n"; + cout << " incPrec = " << (incPrec ? "true" : "false") << "\n"; + + cout << " Ig = { "; + for (i = 0; i < 5; i++) { + cout << static_cast(Ig[i]) << ", "; + } + cout << static_cast(Ig[5]) << " }\n"; + + cout << " Bg = { "; + for (i = 0; i < 5; i++) { + cout << static_cast(Bg[i]) << ", "; + } + cout << static_cast(Bg[5]) << " }\n"; + + cout << " Cg = { "; + for (i = 0; i < 5; i++) { + cout << static_cast(Cg[i]) << ", "; + } + cout << static_cast(Cg[5]) << " }\n\n"; +} + +//------------------------------------------------------------------------- +void RngStream::IncreasedPrecis(bool incp) { + incPrec = incp; +} + +//------------------------------------------------------------------------- +void RngStream::SetAntithetic(bool a) { + anti = a; +} + +//------------------------------------------------------------------------- +// Generate the next random number. +// +double RngStream::RandU01() { + if (incPrec) + return U01d(); + else + return U01(); +} + +//------------------------------------------------------------------------- +// Generate the next random integer. +// +int RngStream::RandInt(int low, int high) { + return low + static_cast((high - low + 1.0) * RandU01()); +}; diff --git a/graph/L3/graphPartition/grappolo/src/buildNextPhase.cpp b/graph/L3/graphPartition/grappolo/src/buildNextPhase.cpp new file mode 100755 index 0000000000..ada16e7699 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/buildNextPhase.cpp @@ -0,0 +1,535 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "defs.h" + +using namespace std; + +// WARNING: Will overwrite the old cluster vector +// Returns the number of unique clusters +long renumberClustersContiguously(long* C, long size) { +#ifdef PRINT_DETAILED_STATS_ + printf("Within renumberClustersContiguously()\n"); +#endif + double time1 = omp_get_wtime(); + // Count the number of unique communities and internal edges + map clusterLocalMap; // Map each neighbor's cluster to a local number + map::iterator storedAlready; + long numUniqueClusters = 0; + + // Do this loop in serial + // Will overwrite the old cluster id with the new cluster id + for (long i = 0; i < size; i++) { + assert(C[i] < size); + if (C[i] >= 0) { // Only if it is a valid number + storedAlready = clusterLocalMap.find(C[i]); // Check if it already exists + if (storedAlready != clusterLocalMap.end()) { // Already exists + C[i] = storedAlready->second; // Renumber the cluster id + } else { + clusterLocalMap[C[i]] = numUniqueClusters; // Does not exist, add to the map + C[i] = numUniqueClusters; // Renumber the cluster id + numUniqueClusters++; // Increment the number + } + } // End of if() + } // End of for(i) + time1 = omp_get_wtime() - time1; +#ifdef PRINT_DETAILED_STATS_ + printf("Time to renumber clusters: %lf\n", time1); +#endif + + return numUniqueClusters; // Return the number of unique cluster ids +} // End of renumberClustersContiguously() + +long renumberClustersContiguously_ghost(long *C, long size, long NV_l) { +#ifdef PRINT_DETAILED_STATS_ + printf("Within renumberClustersContiguously_ghost()\n"); +#endif + double time1 = omp_get_wtime(); + //Count the number of unique communities and internal edges + map clusterLocalMap; //Map each neighbor's cluster to a local number + map::iterator storedAlready; + long numUniqueClusters = 0; + + //Do this loop in serial + //Will overwrite the old cluster id with the new cluster id + for(long i=0; i= 0 && C[i]second; //Renumber the cluster id + } else { + clusterLocalMap[C[i]] = numUniqueClusters; //Does not exist, add to the map + C[i] = numUniqueClusters; //Renumber the cluster id + numUniqueClusters++; //Increment the number + } + }//End of if() + }//End of for(i) + for(long i=0; i= 0 && C[i]>=NV_l ) { //Only if it is a valid number and GHOST node + storedAlready = clusterLocalMap.find(C[i]); //Check if it already exists + if( storedAlready != clusterLocalMap.end() ) { //Already exists + C[i] = storedAlready->second; //Renumber the cluster id + } else { + clusterLocalMap[C[i]] = numUniqueClusters; //Does not exist, add to the map + C[i] = numUniqueClusters; //Renumber the cluster id + numUniqueClusters++; //Increment the number + } + }//End of if() + }//End of for(i) + time1 = omp_get_wtime() - time1; +#ifdef PRINT_DETAILED_STATS_ + printf("Time to renumber clusters: %lf for size %ld to size %d \n", time1, size, numUniqueClusters); +#endif + + return numUniqueClusters; //Return the number of unique cluster ids +}//End of renumberClustersContiguously_ghost() + +// WARNING: Will assume that the cluster id have been renumbered contiguously +// Return the total time for building the next level of graph +double buildNextLevelGraphOpt(graphNew* Gin, graphNew* Gout, long* C, long numUniqueClusters, int nThreads) { +#ifdef PRINT_DETAILED_STATS_ + printf("Within buildNextLevelGraphOpt(): # of unique clusters= %ld\n", numUniqueClusters); +#endif +/* if (nThreads < 1) + omp_set_num_threads(1); + else + omp_set_num_threads(nThreads);*/ + int nT; +#pragma omp parallel + { nT = omp_get_num_threads(); } + if (nThreads < 1) + omp_set_num_threads(1); + else if(nTnumVertices; + // long NE_in = Gin->numEdges;//-Wunused-variable + long* vtxPtrIn = Gin->edgeListPtrs; + edge* vtxIndIn = Gin->edgeList; + + time1 = omp_get_wtime(); + // Pointers into the output graph structure + long NV_out = numUniqueClusters; + long NE_out = 0; + long* vtxPtrOut = (long*)malloc((NV_out + 1) * sizeof(long)); + assert(vtxPtrOut != 0); + vtxPtrOut[0] = 0; // First location is always a zero + /* Step 1 : Regroup the node into cluster node */ + map** cluPtrIn = (map**)malloc(numUniqueClusters * sizeof(map*)); + assert(cluPtrIn != 0); + +#pragma omp parallel for + for (long i = 0; i < numUniqueClusters; i++) { + cluPtrIn[i] = new map(); + (*(cluPtrIn[i]))[i] = 0; // Add for a self loop with zero weight + } +#pragma omp parallel for + for (long i = 1; i <= NV_out; i++) vtxPtrOut[i] = 1; // Count self-loops for every vertex + + // Create an array of locks for each cluster + omp_lock_t* nlocks = (omp_lock_t*)malloc(numUniqueClusters * sizeof(omp_lock_t)); + assert(nlocks != 0); +#pragma omp parallel for + for (long i = 0; i < numUniqueClusters; i++) { + omp_init_lock(&nlocks[i]); // Initialize locks + } + time2 = omp_get_wtime(); + TotTime += (time2 - time1); +#ifdef PRINT_DETAILED_STATS_ + printf("Time to initialize: %3.3lf\n", time2 - time1); +#endif + time1 = omp_get_wtime(); +#pragma omp parallel for + for (long i = 0; i < NV_in; i++) { + long adj1 = vtxPtrIn[i]; + long adj2 = vtxPtrIn[i + 1]; + map::iterator localIterator; + assert(C[i] < numUniqueClusters); + // Now look for all the neighbors of this cluster + for (long j = adj1; j < adj2; j++) { + long tail = vtxIndIn[j].tail; + assert(C[tail] < numUniqueClusters); + // Add the edge from one endpoint + if (C[i] >= C[tail]) { + omp_set_lock(&nlocks[C[i]]); // Locking the cluster + + localIterator = cluPtrIn[C[i]]->find(C[tail]); // Check if it exists + if (localIterator != cluPtrIn[C[i]]->end()) { // Already exists + //(*(cluPtrIn[C[i]]))[C[tail]] += (long)vtxIndIn[j].weight; + localIterator->second += (long)vtxIndIn[j].weight; + } else { + (*(cluPtrIn[C[i]]))[C[tail]] = (long)vtxIndIn[j].weight; // Add edge i-->j + __sync_fetch_and_add(&vtxPtrOut[C[i] + 1], 1); + if (C[i] > C[tail]) { + __sync_fetch_and_add(&NE_out, 1); // Keep track of non-self #edges + __sync_fetch_and_add(&vtxPtrOut[C[tail] + 1], 1); // Count edge + // j-->i + } + } + + omp_unset_lock(&nlocks[C[i]]); // Unlocking the cluster + } // End of if + } // End of for(j) + } // End of for(i) + // Prefix sum: + for (long i = 0; i < NV_out; i++) { + vtxPtrOut[i + 1] += vtxPtrOut[i]; + } + + time2 = omp_get_wtime(); + TotTime += (time2 - time1); +// printf("These should match: %ld == %ld\n",(2*NE_out + NV_out), +// vtxPtrOut[NV_out]); +#ifdef PRINT_DETAILED_STATS_ + printf("Time to count edges: %3.3lf\n", time2 - time1); +#endif + assert(vtxPtrOut[NV_out] == (NE_out * 2 + NV_out)); // Sanity check + + time1 = omp_get_wtime(); + // Step 3 : build the edge list: + long numEdges = vtxPtrOut[NV_out]; + long realEdges = numEdges - NE_out; // Self-loops appear once, others appear twice + edge* vtxIndOut = (edge*)malloc(numEdges * sizeof(edge)); + assert(vtxIndOut != 0); + long* Added = (long*)malloc(NV_out * sizeof(long)); // Keep track of what got added + assert(Added != 0); + +#pragma omp parallel for + for (long i = 0; i < NV_out; i++) { + Added[i] = 0; + } +// Now add the edges in no particular order +#pragma omp parallel for + for (long i = 0; i < NV_out; i++) { + long Where; + map::iterator localIterator = cluPtrIn[i]->begin(); + // Now go through the other edges: + while (localIterator != cluPtrIn[i]->end()) { + Where = vtxPtrOut[i] + __sync_fetch_and_add(&Added[i], 1); + vtxIndOut[Where].head = i; // Head + vtxIndOut[Where].tail = localIterator->first; // Tail + vtxIndOut[Where].weight = localIterator->second; // Weight + if (i != localIterator->first) { + Where = vtxPtrOut[localIterator->first] + __sync_fetch_and_add(&Added[localIterator->first], 1); + vtxIndOut[Where].head = localIterator->first; + vtxIndOut[Where].tail = i; // Tail + vtxIndOut[Where].weight = localIterator->second; // Weight + } + localIterator++; + } + } // End of for(i) + time2 = omp_get_wtime(); + TotTime += (time2 - time1); +#ifdef PRINT_DETAILED_STATS_ + printf("Time to build the graph: %3.3lf\n", time2 - time1); + printf("Total time: %3.3lf\n", TotTime); +#endif +#ifdef PRINT_TERSE_STATS_ + printf("Total time to build next phase: %3.3lf\n", TotTime); +#endif + // Set the pointers + Gout->numVertices = NV_out; + Gout->sVertices = NV_out; + // Note: Self-loops are represented ONCE, but others appear TWICE + Gout->numEdges = realEdges; // Add self loops to the #edges + Gout->edgeListPtrs = vtxPtrOut; + Gout->edgeList = vtxIndOut; + + // Clean up + free(Added); +#pragma omp parallel for + for (long i = 0; i < numUniqueClusters; i++) delete cluPtrIn[i]; + free(cluPtrIn); + +#pragma omp parallel for + for (long i = 0; i < numUniqueClusters; i++) { + omp_destroy_lock(&nlocks[i]); + } + free(nlocks); + + return TotTime; +} // End of buildNextLevelGraph2() + +// WARNING: Will assume that the cluster ids have been renumbered contiguously +void buildNextLevelGraph(graphNew* Gin, graphNew* Gout, long* C, long numUniqueClusters) { +#ifdef PRINT_DETAILED_STATS_ + printf("Within buildNextLevelGraph() with numUC:%ld\n", numUniqueClusters); +#endif + // double time1, time2, time3, time4; //For timing purposes + // //-Wunused-variable + // double total = 0, totItr = 0;//-Wunused-variable + + // Pointers into the input graph structure: + long NV_in = Gin->numVertices; + // long NE_in = Gin->numEdges;//-Wunused-variable + long* vtxPtrIn = Gin->edgeListPtrs; + edge* vtxIndIn = Gin->edgeList; + + long vecSize = (numUniqueClusters * (numUniqueClusters + 1)) / 2; + long* tmpCounter = (long*)malloc(vecSize * sizeof(long)); + assert(tmpCounter != 0); + +/////STEP-1: Count the number of internal edges and cut edges (edges between two +/// clusters): +/////Stored in a lower triangular matrix (complete matrix). Size of matrix = +///|#of clusters| +///// The diagonal entries in the matrix store the number of internal edges of a +/// cluster +///// Off-diagonal entries are from i-->j iff i>j +#pragma omp parallel for + for (long i = 0; i < vecSize; i++) tmpCounter[i] = 0; + +#pragma omp parallel for + for (long i = 0; i < NV_in; i++) { + long adj1 = vtxPtrIn[i]; + long adj2 = vtxPtrIn[i + 1]; + for (long j = adj1; j < adj2; j++) { + long tail = vtxIndIn[j].tail; + assert((C[i] < numUniqueClusters) && (C[tail] < numUniqueClusters)); + if (C[i] == C[tail]) { // Internal edge + long location = (C[i] * (C[i] + 1)) / 2 + C[i]; // Diagonal element + __sync_fetch_and_add(&tmpCounter[location], vtxIndIn[j].weight); + } else { + // One store it one way: if C[i] > C[tail] + if (C[i] > C[tail]) { + long location = (C[i] * (C[i] + 1)) / 2 + C[tail]; + __sync_fetch_and_add(&tmpCounter[location], vtxIndIn[j].weight); + } // End of if + } // End of else + } // End of for(j) + } // End of for(i) + + /////STEP-2: Build the graph data structure: + long NV_out = numUniqueClusters; + long NE_out = 0; + long* vtxPtrOut = (long*)malloc((NV_out + 1) * sizeof(long)); + assert(vtxPtrOut != 0); + vtxPtrOut[0] = 0; // First location is always a zero +#pragma omp parallel for + for (long i = 1; i <= NV_out; i++) vtxPtrOut[i] = 1; // Count self loops + +// Count the number of edges: +#pragma omp parallel for + for (long i = 0; i < NV_out; i++) { + long location = (i * (i + 1)) / 2; // Starting location for i + for (long j = 0; j < i; j++) { + if (i == j) continue; // Self-loops have already been counted + if (tmpCounter[location + j] > 0) { + __sync_fetch_and_add(&vtxPtrOut[i + 1], 1); // Add edge i-->j (leave the zeroth location as-is + __sync_fetch_and_add(&vtxPtrOut[j + 1], 1); // Add edge j-->i + __sync_fetch_and_add(&NE_out, 1); // Keep track of #edges + } + } // End of for(j) + } // End of for(i) + + // Prefix sum: + for (long i = 0; i < NV_out; i++) { + vtxPtrOut[i + 1] += vtxPtrOut[i]; + } + // printf("End Structure %ld %ld vs %ld\n",NE_out, NV_out, vtxPtrOut[NV_out]); + assert(vtxPtrOut[NV_out] == (NE_out * 2 + NV_out)); // Sanity check + + // Now build the edge list: + long numEdges = NE_out * 2 + NV_out; // Self-loops appear once, others appear twice + edge* vtxIndOut = (edge*)malloc(numEdges * sizeof(edge)); + long* Added = (long*)malloc(NV_out * sizeof(long)); // Keep track of what got added +#pragma omp parallel for + for (long i = 0; i < NV_out; i++) Added[i] = 0; + +// Now add the edges: NOT IN SORTED ORDER +#pragma omp parallel for + for (long i = 0; i < NV_out; i++) { + long location = (i * (i + 1)) / 2; // Starting location for i + // Add the self-loop: i-i + long Where = vtxPtrOut[i] + __sync_fetch_and_add(&Added[i], 1); + + vtxIndOut[Where].head = i; + vtxIndOut[Where].tail = i; + if (tmpCounter[location + i] == 0) { + // tmpCounter[location+i] = tmpCounter[location+i]/2; + // printf("Crap Modify this\n"); + } + vtxIndOut[Where].weight = tmpCounter[location + i]; + // Now go through the other edges: + for (long j = 0; j < i; j++) { + if (tmpCounter[location + j] > 0) { + Where = vtxPtrOut[i] + __sync_fetch_and_add(&Added[i], 1); + vtxIndOut[Where].head = i; // Head + vtxIndOut[Where].tail = j; // Tail + vtxIndOut[Where].weight = tmpCounter[location + j]; // Weight + + Where = vtxPtrOut[j] + __sync_fetch_and_add(&Added[j], 1); + vtxIndOut[Where].head = j; // Head + vtxIndOut[Where].tail = i; // Tail + vtxIndOut[Where].weight = tmpCounter[location + j]; // Weight + } // End of if + } // End of for(j) + } // End of for(i) + + // Set the pointers + Gout->numVertices = NV_out; + Gout->sVertices = NV_out; + // Note: Self-loops are represented ONCE, but others appear TWICE + Gout->numEdges = NE_out + NV_out; // Add self loops to the #edges + Gout->edgeListPtrs = vtxPtrOut; + Gout->edgeList = vtxIndOut; + + // Clean up + free(Added); + free(tmpCounter); + + // printf("End of rebuild\n"); + +} // End of buildNextLevelGraph + +// This code is for finding communities in power grids based on +// voltage levels of nodes. All nodes in a connected components with +// the same voltage belong to a community: Complexity is O(|E|) +long buildCommunityBasedOnVoltages(graphNew* G, long* Volts, long* C, long* Cvolts) { + /* Graph data structure */ + long NV = G->numVertices; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + printf("|V|=%ld, |E|=%ld\n", NV, NE); + + short* Visited = (short*)malloc(NV * sizeof(short)); + for (long i = 0; i < NV; i++) { + C[i] = -1; + Visited[i] = 0; + } + long myCommunity = 0; + bool found = false; // Make sure that a community with no vertices does not exist + for (long v = 0; v < NV; v++) { + if (Visited[v] > 0) // Already visited + continue; + // Find the community of this vertex + C[v] = myCommunity; + assert(Volts[v] > 0); + Cvolts[myCommunity] = Volts[v]; // Store the voltage of that community + Visited[v] = 1; + found = true; // At least one vertex exists in this community + Visit(v, myCommunity, Visited, Volts, vtxPtr, vtxInd, C); // Find others + if (found) { + myCommunity++; // Increment to next community + found = false; + printf("Starting a new community...\n"); + } + } + free(Visited); + return myCommunity; +} + +// Recursive call for finding neighbors +inline void Visit(long v, long myCommunity, short* Visited, long* Volts, long* vtxPtr, edge* vtxInd, long* C) { + printf("Visit(%ld)\n", v); + long adj1 = vtxPtr[v]; // Begining + long adj2 = vtxPtr[v + 1]; // End + for (long i = adj1; i < adj2; i++) { + long w = vtxInd[i].tail; + if (Visited[w] != 0) { // Already visited? + continue; + } + if (Volts[v] == Volts[w]) { // belong to the same community + C[w] = myCommunity; // Set the community + Visited[w] = 1; // Mark as visited + Visit(w, myCommunity, Visited, Volts, vtxPtr, vtxInd, C); // Find others recursively + } + } // End of for(i) +} // End of Visit + +void segregateEdgesBasedOnVoltages(graphNew* G, long* Volts) { + /* Graph data structure */ + long NV = G->numVertices; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + printf("|V|=%ld, |E|=%ld\n", NV, NE); + + // Count the number of unique communities and internal edges + map voltsMap; // Map each neighbor's cluster to a local number + map::iterator storedAlready; + + // voltsMap[0] = 0; + // long numUniqueVolts = 1; + + long numUniqueVolts = 0; + // Do this loop in serial + // Will overwrite the old cluster id with the new cluster id + for (long i = 0; i < NV; i++) { + storedAlready = voltsMap.find(Volts[i]); // Check if it already exists + if (storedAlready == voltsMap.end()) { // Does not exist, add to the map + voltsMap[Volts[i]] = numUniqueVolts; + numUniqueVolts++; + } + } // End of for(i) + + printf("Number of unique voltage levels: %ld\n", numUniqueVolts); + printf("Printing edges of a given voltage: \n"); + storedAlready = voltsMap.begin(); + do { + long myVolt = storedAlready->first; + printf("All edges with both end-points of Volt: %ld\n", myVolt); + for (long v = 0; v < NV; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + for (long j = adj1; j < adj2; j++) { + long w = vtxInd[j].tail; + if ((Volts[v] == myVolt) && (Volts[w] == myVolt)) { + // printf("%ld %ld %ld %ld\n", v+1, w+1, Volts[v], Volts[w]); + printf("%ld %ld %ld\n", v + 1, w + 1, Volts[v]); + } + } // End of for(j) + } // End of for(v) + printf("\n***************************\n"); + storedAlready++; // Go to the next cluster + } while (storedAlready != voltsMap.end()); +} // End of segregateEdgesBasedOnVoltages() diff --git a/graph/L3/graphPartition/grappolo/src/coloringDistanceOne.cpp b/graph/L3/graphPartition/grappolo/src/coloringDistanceOne.cpp new file mode 100755 index 0000000000..7ae7bef277 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/coloringDistanceOne.cpp @@ -0,0 +1,455 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "defs.h" + +#define MaxDegree 4096 // Increase if number of colors is larger; decrease if memory is not + // enough + +////////////////////////////////////////////////////////////////////////////////////// +////////////////////////// DISTANCE ONE COLORING +////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// +// Return the number of colors used (zero is a valid color) +int algoDistanceOneVertexColoringOpt(graphNew* G, int* vtxColor, int nThreads, double* totTime) { +#ifdef PRINT_DETAILED_STATS_ + printf("Within algoDistanceOneVertexColoringOpt()\n"); +#endif + if (nThreads < 1) + omp_set_num_threads(1); // default to one thread + else + omp_set_num_threads(nThreads); + int nT; +#pragma omp parallel + { nT = omp_get_num_threads(); } +#ifdef PRINT_DETAILED_STATS_ + printf("Actual number of threads: %d (requested: %d)\n", nT, nThreads); +#endif + + double time1 = 0, time2 = 0, totalTime = 0; + // Get the iterators for the graph: + long NVer = G->numVertices; + long NEdge = G->numEdges; + long* verPtr = G->edgeListPtrs; // Vertex Pointer: pointers to endV + edge* verInd = G->edgeList; // Vertex Index: destination id of an edge (src -> dest) +#ifdef PRINT_DETAILED_STATS_ + printf("Vertices: %ld Edges: %ld\n", NVer, NEdge); +#endif + + // Build a vector of random numbers + double* randValues = (double*)malloc(NVer * sizeof(double)); + assert(randValues != 0); + generateRandomNumbers(randValues, NVer); + + long* Q = (long*)malloc(NVer * sizeof(long)); + assert(Q != 0); + long* Qtmp = (long*)malloc(NVer * sizeof(long)); + assert(Qtmp != 0); + long* Qswap; + if ((Q == NULL) || (Qtmp == NULL)) { + printf("Not enough memory to allocate for the two queues \n"); + exit(1); + } + long QTail = 0; // Tail of the queue + long QtmpTail = 0; // Tail of the queue (implicitly will represent the size) + +#pragma omp parallel for + for (long i = 0; i < NVer; i++) { + Q[i] = i; // Natural order + Qtmp[i] = -1; // Empty queue + } + QTail = NVer; // Queue all vertices + ///////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////// START THE WHILE LOOP + ////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + long nConflicts = 0; // Number of conflicts + int nLoops = 0; // Number of rounds of conflict resolution + +#ifdef PRINT_DETAILED_STATS_ + printf("Results from parallel coloring:\n"); + printf("***********************************************\n"); +#endif + do { +///////////////////////////////////////// PART 1 +/////////////////////////////////////////// +// Color the vertices in parallel - do not worry about conflicts +#ifdef PRINT_DETAILED_STATS_ + printf("** Iteration : %d \n", nLoops); +#endif + time1 = omp_get_wtime(); +#pragma omp parallel for + for (long Qi = 0; Qi < QTail; Qi++) { + long v = Q[Qi]; // Q.pop_front(); + + long adj1 = verPtr[v]; + long adj2 = verPtr[v + 1]; + // long myDegree = verPtr[v+1] - verPtr[v];//-Wunused-variable + bool* Mark = (bool*)malloc(MaxDegree * sizeof(bool)); + assert(Mark != 0); + for (long i = 0; i < MaxDegree; i++) Mark[i] = false; + + int maxColor = -1; + int adjColor = -1; + // Browse the adjacency set of vertex v + for (long k = adj1; k < adj2; k++) { + if (v == verInd[k].tail) // Self-loops + continue; + adjColor = vtxColor[verInd[k].tail]; + if (adjColor >= 0) { + assert(adjColor < MaxDegree); + Mark[adjColor] = true; + // Find the largest color in the neighborhood + if (adjColor > maxColor) maxColor = adjColor; + } + } // End of for loop to traverse adjacency of v + int myColor; + for (myColor = 0; myColor <= maxColor; myColor++) { + if (Mark[myColor] == false) break; + } + if (myColor == maxColor) myColor++; /* no available color with # less than cmax */ + vtxColor[v] = myColor; // Color the vertex + + free(Mark); + } // End of outer for loop: for each vertex + time1 = omp_get_wtime() - time1; + totalTime += time1; +#ifdef PRINT_DETAILED_STATS_ + printf("Time taken for Coloring: %lf sec.\n", time1); +#endif + ///////////////////////////////////////// PART 2 + /////////////////////////////////////////// + // Detect Conflicts: + // printf("Phase 2: Detect Conflicts, add to queue\n"); + // Add the conflicting vertices into a Q: + // Conflicts are resolved by changing the color of only one of the + // two conflicting vertices, based on their random values + time2 = omp_get_wtime(); +#pragma omp parallel for + for (long Qi = 0; Qi < QTail; Qi++) { + long v = Q[Qi]; // Q.pop_front(); + long adj1 = verPtr[v]; + long adj2 = verPtr[v + 1]; + // Browse the adjacency set of vertex v + for (long k = adj1; k < adj2; k++) { + if (v == verInd[k].tail) // Self-loops + continue; + if (vtxColor[v] == vtxColor[verInd[k].tail]) { + if ((randValues[v] < randValues[verInd[k].tail]) || + ((randValues[v] == randValues[verInd[k].tail]) && (v < verInd[k].tail))) { + long whereInQ = __sync_fetch_and_add(&QtmpTail, 1); + Qtmp[whereInQ] = v; // Add to the queue + vtxColor[v] = -1; // Will prevent v from being in conflict in another pairing + break; + } + } // End of if( vtxColor[v] == vtxColor[verInd[k]] ) + } // End of inner for loop: w in adj(v) + } // End of outer for loop: for each vertex + time2 = omp_get_wtime() - time2; + totalTime += time2; + nConflicts += QtmpTail; + nLoops++; +#ifdef PRINT_DETAILED_STATS_ + printf("Num conflicts : %ld \n", QtmpTail); + printf("Time for detection : %lf sec\n", time2); +#endif + // Swap the two queues: + Qswap = Q; + Q = Qtmp; // Q now points to the second vector + Qtmp = Qswap; + QTail = QtmpTail; // Number of elements + QtmpTail = 0; // Symbolic emptying of the second queue + } while (QTail > 0); + // Check the number of colors used + int nColors = -1; + for (long v = 0; v < NVer; v++) + if (vtxColor[v] > nColors) nColors = vtxColor[v]; +#ifdef PRINT_DETAILED_STATS_ + printf("***********************************************\n"); + printf("Total number of colors used: %d \n", nColors); + printf("Number of conflicts overall: %ld \n", nConflicts); + printf("Number of rounds : %d \n", nLoops); + printf("Total Time : %lf sec\n", totalTime); + printf("***********************************************\n"); +#endif + *totTime = totalTime; + //////////////////////////// + //////////////////////////////////////////////////////////////// + ///////////////////////////////// VERIFY THE COLORS + //////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + // Verify Results and Cleanup + int myConflicts = 0; +#pragma omp parallel for + for (long v = 0; v < NVer; v++) { + long adj1 = verPtr[v]; + long adj2 = verPtr[v + 1]; + // Browse the adjacency set of vertex v + for (long k = adj1; k < adj2; k++) { + if (v == verInd[k].tail) // Self-loops + continue; + if (vtxColor[v] == vtxColor[verInd[k].tail]) { + __sync_fetch_and_add(&myConflicts, 1); // increment the counter + } + } // End of inner for loop: w in adj(v) + } // End of outer for loop: for each vertex + myConflicts = myConflicts / 2; // Have counted each conflict twice +#ifdef PRINT_DETAILED_STATS_ + if (myConflicts > 0) + printf( + "Check - WARNING: Number of conflicts detected after resolution: %d " + "\n\n", + myConflicts); + else + printf("Check - SUCCESS: No conflicts exist\n\n"); +#endif + // Clean Up: + free(Q); + free(Qtmp); + free(randValues); + + return nColors; // Return the number of colors used +} + +////////////////////////////////////////////////////////////////////////////////////// +////////////////////////// DISTANCE ONE COLORING +////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// +// Return the number of colors used (zero is a valid color) +int algoDistanceOneVertexColoring(graphNew* G, int* vtxColor, int nThreads, double* totTime) { + printf("Within algoDistanceOneVertexColoring()\n"); + if (nThreads < 1) + omp_set_num_threads(1); // default to one thread + else + omp_set_num_threads(nThreads); + int nT; +#pragma omp parallel + { nT = omp_get_num_threads(); } + printf("Actual number of threads: %d (requested: %d)\n", nT, nThreads); + + double time1 = 0, time2 = 0, totalTime = 0; + // Get the iterators for the graph: + long NVer = G->numVertices; + // long NS = G->sVertices;////-Wunused-variable + // long NT = NVer - NS;//-Wunused-variable + long NEdge = G->numEdges; + long* verPtr = G->edgeListPtrs; // Vertex Pointer: pointers to endV + edge* verInd = G->edgeList; // Vertex Index: destination id of an edge (src -> dest) + printf("Vertices: %ld Edges: %ld\n", NVer, NEdge); + + // const int MaxDegree = 4096; //Increase if number of colors is larger + + // Build a vector of random numbers + double* randValues = (double*)malloc(NVer * sizeof(double)); + if (randValues == NULL) { + printf("Not enough memory to allocate for random numbers \n"); + exit(1); + } + generateRandomNumbers(randValues, NVer); + + // The Queue Data Structure for the storing the vertices + // the need to be colored/recolored + // Have two queues - read from one, write into another + // at the end, swap the two. + long* Q = (long*)malloc(NVer * sizeof(long)); + long* Qtmp = (long*)malloc(NVer * sizeof(long)); + long* Qswap; + if ((Q == NULL) || (Qtmp == NULL)) { + printf("Not enough memory to allocate for the two queues \n"); + exit(1); + } + long QTail = 0; // Tail of the queue + long QtmpTail = 0; // Tail of the queue (implicitly will represent the size) + +#pragma omp parallel for + for (long i = 0; i < NVer; i++) { + Q[i] = i; // Natural order + Qtmp[i] = -1; // Empty queue + } + QTail = NVer; // Queue all vertices + ///////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////// START THE WHILE LOOP + ////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + long nConflicts = 0; // Number of conflicts + int nLoops = 0; // Number of rounds of conflict resolution + int* Mark = (int*)malloc(MaxDegree * NVer * sizeof(int)); + if (Mark == NULL) { + printf("Not enough memory to allocate for Mark \n"); + exit(1); + } +#pragma omp parallel for + for (long i = 0; i < MaxDegree * NVer; i++) Mark[i] = -1; + + printf("Results from parallel coloring:\n"); + printf("***********************************************\n"); + do { + ///////////////////////////////////////// PART 1 + /////////////////////////////////////////// + // Color the vertices in parallel - do not worry about conflicts + printf("** Iteration : %d \n", nLoops); + time1 = omp_get_wtime(); +#pragma omp parallel for + for (long Qi = 0; Qi < QTail; Qi++) { + long v = Q[Qi]; // Q.pop_front(); + long StartIndex = v * MaxDegree; // Location in Mark + if (nLoops > 0) // Skip the first time around + for (long i = StartIndex; i < (StartIndex + MaxDegree); i++) Mark[i] = -1; + long adj1 = verPtr[v]; + long adj2 = verPtr[v + 1]; + int maxColor = -1; + int adjColor = -1; + // Browse the adjacency set of vertex v + for (long k = adj1; k < adj2; k++) { + // if ( v == verInd[k] ) //Skip self-loops + // continue; + adjColor = vtxColor[verInd[k].tail]; + if (adjColor >= 0) { + Mark[StartIndex + adjColor] = v; + // Find the largest color in the neighborhood + if (adjColor > maxColor) maxColor = adjColor; + } + } // End of for loop to traverse adjacency of v + int myColor; + for (myColor = 0; myColor <= maxColor; myColor++) { + if (Mark[StartIndex + myColor] != v) break; + } + if (myColor == maxColor) myColor++; /* no available color with # less than cmax */ + vtxColor[v] = myColor; // Color the vertex + } // End of outer for loop: for each vertex + time1 = omp_get_wtime() - time1; + totalTime += time1; + printf("Time taken for Coloring: %lf sec.\n", time1); + + ///////////////////////////////////////// PART 2 + /////////////////////////////////////////// + // Detect Conflicts: + // printf("Phase 2: Detect Conflicts, add to queue\n"); + // Add the conflicting vertices into a Q: + // Conflicts are resolved by changing the color of only one of the + // two conflicting vertices, based on their random values + time2 = omp_get_wtime(); +#pragma omp parallel for + for (long Qi = 0; Qi < QTail; Qi++) { + long v = Q[Qi]; // Q.pop_front(); + long adj1 = verPtr[v]; + long adj2 = verPtr[v + 1]; + // Browse the adjacency set of vertex v + for (long k = adj1; k < adj2; k++) { + // if ( v == verInd[k] ) //Self-loops + // continue; + if (vtxColor[v] == vtxColor[verInd[k].tail]) { + // Q.push_back(v or w) + if ((randValues[v] < randValues[verInd[k].tail]) || + ((randValues[v] == randValues[verInd[k].tail]) && (v < verInd[k].tail))) { + long whereInQ = __sync_fetch_and_add(&QtmpTail, 1); + Qtmp[whereInQ] = v; // Add to the queue + vtxColor[v] = -1; // Will prevent v from being in conflict in another pairing + break; + } + } // End of if( vtxColor[v] == vtxColor[verInd[k]] ) + } // End of inner for loop: w in adj(v) + } // End of outer for loop: for each vertex + time2 = omp_get_wtime() - time2; + totalTime += time2; + nConflicts += QtmpTail; + nLoops++; + printf("Conflicts : %ld \n", QtmpTail); + printf("Time for detection : %lf sec\n", time2); + // Swap the two queues: + Qswap = Q; + Q = Qtmp; // Q now points to the second vector + Qtmp = Qswap; + QTail = QtmpTail; // Number of elements + QtmpTail = 0; // Symbolic emptying of the second queue + } while (QTail > 0); + // Check the number of colors used + int nColors = -1; + for (long v = 0; v < NVer; v++) + if (vtxColor[v] > nColors) nColors = vtxColor[v]; + printf("***********************************************\n"); + printf("Total number of colors used: %d \n", nColors); + printf("Number of conflicts overall: %ld \n", nConflicts); + printf("Number of rounds : %d \n", nLoops); + printf("Total Time : %lf sec\n", totalTime); + printf("***********************************************\n"); + + *totTime = totalTime; + ///////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////// VERIFY THE COLORS + //////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + // Verify Results and Cleanup + int myConflicts = 0; +#pragma omp parallel for + for (long v = 0; v < NVer; v++) { + long adj1 = verPtr[v]; + long adj2 = verPtr[v + 1]; + // Browse the adjacency set of vertex v + for (long k = adj1; k < adj2; k++) { + if (v == verInd[k].tail) // Self-loops + continue; + if (vtxColor[v] == vtxColor[verInd[k].tail]) { + //#pragma omp atomic + // printf("Conflict: color[%ld]=%d AND color[%ld]=%d\n", v, vtxColor[v], + // verInd[k].tail, vtxColor[ verInd[k].tail]); + __sync_fetch_and_add(&myConflicts, 1); // increment the counter + } + } // End of inner for loop: w in adj(v) + } // End of outer for loop: for each vertex + myConflicts = myConflicts / 2; // Have counted each conflict twice +#ifdef PRINT_DETAILED_STATS_ + if (myConflicts > 0) + printf( + "Check - WARNING: Number of conflicts detected after resolution: %d " + "\n\n", + myConflicts); + else + printf("Check - SUCCESS: No conflicts exist\n\n"); +#endif + // Clean Up: + free(Q); + free(Qtmp); + free(Mark); + free(randValues); + + return nColors; // Return the number of colors used +} diff --git a/graph/L3/graphPartition/grappolo/src/driverForGraphClustering.cpp b/graph/L3/graphPartition/grappolo/src/driverForGraphClustering.cpp new file mode 100755 index 0000000000..216f81158a --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/driverForGraphClustering.cpp @@ -0,0 +1,119 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "defs.h" +#include "xilinxlouvain.h" + +int host_ParserParameters(int argc, + char** argv, + double& opts_C_thresh, //; //Threshold with coloring on + long& opts_minGraphSize, //; //Min |V| to enable coloring + double& opts_threshold, //; //Value of threshold + int& opts_ftype, //; //File type + char opts_inFile[4096], //; + bool& opts_coloring, // + bool& opts_output, //; + bool& opts_VF, //; + char opts_xclbinPath[4096]) { + // step1: parser parameters: xclbinPath, coloring, int fType , + // opts.minGraphSize, opts.threshold + // step2: prepare graphNew: parser files and undirection + // Parse Input parameters: + clustering_parameters opts; + if (!opts.parse(argc, argv)) { + return -1; + } + opts_C_thresh = opts.C_thresh; + opts_minGraphSize = opts.minGraphSize; + opts_threshold = opts.threshold; + opts_ftype = opts.ftype; // File type + opts_output = opts.output; + opts_coloring = opts.coloring; + opts_VF = opts.VF; + strcpy(opts_inFile, (char*)opts.inFile); + strcpy(opts_xclbinPath, (char*)opts.xclbin); + return 0; +} + +graphNew* host_PrepareGraph(int opts_ftype, char opts_inFile[4096], bool opts_VF) { + graphNew* G = (graphNew*)malloc(sizeof(graphNew)); + if (opts_ftype == 1) + parse_MatrixMarket_Sym_AsGraph(G, opts_inFile); + else if (opts_ftype == 2) + parse_Dimacs9FormatDirectedNewD(G, opts_inFile); + else if (opts_ftype == 3) + parse_PajekFormat(G, opts_inFile); + else if (opts_ftype == 4) + parse_PajekFormatUndirected(G, opts_inFile); + else if (opts_ftype == 5) + loadMetisFileFormat(G, opts_inFile); + else if (opts_ftype == 6) + parse_DoulbedEdgeList(G, opts_inFile); + else if (opts_ftype == 7) + parse_EdgeListBinary(G, opts_inFile); + else + parse_SNAP(G, opts_inFile); + displayGraphCharacteristics(G); + /* Vertex Following option */ + if (opts_VF) { + printf("Vertex following is enabled.\n"); + long numVtxToFix = 0; // Default zero + long* C = (long*)malloc(G->numVertices * sizeof(long)); + assert(C != 0); + numVtxToFix = vertexFollowing(G, C); // Find vertices that follow other vertices + if (numVtxToFix > 0) { // Need to fix things: build a new graphNew + printf("Graph will be modified -- %ld vertices need to be fixed.\n", numVtxToFix); + graphNew* Gnew = (graphNew*)malloc(sizeof(graphNew)); + long numClusters = renumberClustersContiguously(C, G->numVertices); + buildNewGraphVF(G, Gnew, C, numClusters); + // Get rid of the old graphNew and store the new graphNew + free(G->edgeListPtrs); + free(G->edgeList); + free(G); + G = Gnew; + } + free(C); // Free up memory + printf("Graph after modifications:\n"); + displayGraphCharacteristics(G); + } // End of if( VF == 1 ) + return G; +} + diff --git a/graph/L3/graphPartition/grappolo/src/louvainMultiPhaseRun.cpp b/graph/L3/graphPartition/grappolo/src/louvainMultiPhaseRun.cpp new file mode 100644 index 0000000000..03b604c7c1 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/louvainMultiPhaseRun.cpp @@ -0,0 +1,305 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "defs.h" +#include "xilinxlouvain.h" +#include "xcl2.hpp" + +using namespace std; +// WARNING: This will overwrite the original graphNew data structure to +// minimize memory footprint +// Return: C_orig will hold the cluster ids for vertices in the original graphNew +// Assume C_orig is initialized appropriately +// WARNING: Graph G will be destroyed at the end of this routine + + +void inline PhaseLoop_UpdatingC_org(int phase, long NV, long NV_G, long* C, long* C_orig) { + if (phase == 1) { +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + C_orig[i] = C[i]; // After the first phase + } + } else { +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + assert(C_orig[i] < NV_G); + if (C_orig[i] >= 0) C_orig[i] = C[C_orig[i]]; // Each cluster in a previous phase becomes a vertex + } + } + printf("Done updating C_orig\n"); +} + +/* +double PhaseLoop_UsingFPGA_Prep_Init_buff_host(int numColors, + graphNew* G, + long* M, + double opts_C_thresh, + double* currMod, + // Updated variables + int* colors, + KMemorys_host* buff_host) { + int edgeNum; + double time1 = omp_get_wtime(); + assert(numColors < COLORS); + long vertexNum = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + long NE = G->numEdges; + long NEx2 = NE << 1; + long NE1 = NEx2 < (1 << 26) ? NEx2 : (1 << 26); // 256MB/sizeof(int/float)=64M + + long cnt_e = 0; + for (int i = 0; i < vertexNum + 1; i++) { + buff_host[0].offsets[i] = (int)vtxPtr[i]; + if (i != vertexNum) { + if (M[i] < 0) buff_host[0].offsets[i] = (int)(0x80000000 | (unsigned int)vtxPtr[i]); + } else + buff_host[0].offsets[i] = (int)(vtxPtr[i]); + } + edgeNum = buff_host[0].offsets[vertexNum]; + for (int i = 0; i < vertexNum; i++) { + int adj1 = vtxPtr[i]; + int adj2 = vtxPtr[i + 1]; + for (int j = adj1; j < adj2; j++) { + if (cnt_e < NE1) { + buff_host[0].indices[j] = (int)vtxInd[j].tail; + buff_host[0].weights[j] = vtxInd[j].weight; + } else { + buff_host[0].indices2[j - NE1] = (int)vtxInd[j].tail; + buff_host[0].weights2[j - NE1] = vtxInd[j].weight; + } + cnt_e++; + } + } + for (int i = 0; i < vertexNum; i++) { + buff_host[0].colorAxi[i] = colors[i]; + } + buff_host[0].config0[0] = vertexNum; + buff_host[0].config0[1] = numColors; + buff_host[0].config0[2] = 0; + buff_host[0].config0[3] = edgeNum; + buff_host[0].config1[0] = opts_C_thresh; + buff_host[0].config1[1] = currMod[0]; + time1 = omp_get_wtime() - time1; + return time1; +} +*/ +// double PhaseLoop_UsingFPGA_Prep_Read_buff_host(long vertexNum, +// KMemorys_host* buff_host, +// int* eachItrs, +// // output +// long* C, +// int* eachItr, +// double* currMod) { +// double time1 = omp_get_wtime(); +// // updating +// eachItrs[0] = buff_host[0].config0[2]; +// eachItr[0] = buff_host[0].config0[2]; +// currMod[0] = buff_host[0].config1[1]; +// for (int i = 0; i < vertexNum; i++) { +// C[i] = (long)buff_host[0].cidPrev[i]; +// } +// time1 = omp_get_wtime() - time1; +// return time1; +// } +/* +long* CreateM(long NV_new, long NV_orig, long* C_orig, long* M_orig) { + long* M = (long*)malloc(NV_new * sizeof(long)); + assert(M); + memset(M, 0, NV_new * sizeof(long)); + for (int i = 0; i < NV_orig; i++) { + if (M_orig[i] < 0) M[C_orig[i]] = M_orig[i]; + } + return M; +} + +double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, + GLV* pglv_iter, + int numThreads, + double opts_threshold, + bool opts_coloring, + // modified: + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase, + double& time_renum, + double& time_C, + double& time_M, + double& time_buid, + double& time_set) { + double time1 = 0; + time1 = omp_get_wtime(); + time_renum = time1; + graphNew* Gnew; + numClusters = renumberClustersContiguously_ghost(pglv_iter->C, pglv_iter->G->numVertices, pglv_iter->NVl); + printf("Number of unique clusters: %ld\n", numClusters); + time_renum = omp_get_wtime() - time_renum; + + time_C = omp_get_wtime(); + PhaseLoop_UpdatingC_org(phase, pglv_orig->NV, pglv_iter->NV, pglv_iter->C, pglv_orig->C); + time_C = omp_get_wtime() - time_C; + + time_M = omp_get_wtime(); + long* M_new = CreateM(numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M); + time_M = omp_get_wtime() - time_M; + + Gnew = (graphNew*)malloc(sizeof(graphNew)); + assert(Gnew != 0); + double tmpTime = buildNextLevelGraphOpt(pglv_iter->G, Gnew, pglv_iter->C, numClusters, numThreads); + totTimeBuildingPhase += tmpTime; + time_buid = tmpTime; + + time_set = omp_get_wtime(); + pglv_iter->SetByOhterG(Gnew, M_new); + time_set = omp_get_wtime() - time_set; + + time1 = omp_get_wtime() - time1; + + return time1; +} +*/ + +/* +double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(//DAIS + int numColors, + graphNew* G, + long* M, + double opts_C_thresh, + double* currMod, + //Updated variables + int* colors, + KMemorys_host_prune *buff_host) +{ + + int edgeNum; + double time1 = omp_get_wtime(); + assert(numColors < COLORS); + long vertexNum = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + long NE = G->numEdges; + long NEx2 = NE<<1; + long NE1 = NEx2< (1<<26)? NEx2 : (1<<26);//256MB/sizeof(int/float)=64M + + long cnt_e=0; + for (int i = 0; i < vertexNum + 1; i++) { + buff_host[0].offsets[i] = (int)vtxPtr[i]; + if(i!=vertexNum){ + if(M[i]<0) + buff_host[0].offsets[i] = (int) (0x80000000 |(unsigned int)vtxPtr[i]); + }else + buff_host[0].offsets[i] = (int) ( vtxPtr[i]); + } + edgeNum = buff_host[0].offsets[vertexNum]; + for (int i = 0; i < vertexNum + 1; i++) { + buff_host[0].offsets[i] = (int)vtxPtr[i]; + buff_host[0].offsetsdup[i] = buff_host[0].offsets[i];// + if(i!=vertexNum){ + if(M[i]<0) + buff_host[0].offsets[i] = (int) (0x80000000 |(unsigned int)vtxPtr[i]); + }else + buff_host[0].offsets[i] = (int) ( vtxPtr[i]); + } + edgeNum = buff_host[0].offsets[vertexNum]; + std::cout << "INFO: for test 1" << std::endl; + for (int i = 0; i < vertexNum; i++) { + int adj1 = vtxPtr[i]; + int adj2 = vtxPtr[i + 1]; + buff_host[0].flag[i] = 0;// + buff_host[0].flagUpdate[i] = 0;// + for (int j = adj1; j < adj2; j++) { + if(cnt_enumVertices; + // long NS = G->sVertices;//-Wunused-variable + // long NE = G->numEdges;//-Wunused-variable + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + + /* Variables for computing modularity */ + // long totalEdgeWeightTwice;//-Wunused-variable + double constantForSecondTerm; + double prevMod = -1; + double currMod = -1; + // double thresMod = 0.000001; + double thresMod = thresh; // Input parameter + int numItrs = 0; + + /********************** Initialization **************************/ + time1 = omp_get_wtime(); + // Store the degree of all vertices + long* vDegree = (long*)malloc(NV * sizeof(long)); + assert(vDegree != 0); + // Community info. (ai and size) + Comm* cInfo = (Comm*)malloc(NV * sizeof(Comm)); + assert(cInfo != 0); + // use for updating Community + Comm* cUpdate = (Comm*)malloc(NV * sizeof(Comm)); + assert(cUpdate != 0); + // use for Modularity calculation (eii) + long* clusterWeightInternal = (long*)malloc(NV * sizeof(long)); + assert(clusterWeightInternal != 0); + + sumVertexDegree(vtxInd, vtxPtr, vDegree, NV, cInfo); // Sum up the vertex degree + + /*** Compute the total edge weight (2m) and 1/2m ***/ + constantForSecondTerm = calConstantForSecondTerm(vDegree, NV); // 1 over sum of the degree + + // Community assignments: + // Store previous iteration's community assignment + long* pastCommAss = (long*)malloc(NV * sizeof(long)); + assert(pastCommAss != 0); + // Store current community assignment + long* currCommAss = (long*)malloc(NV * sizeof(long)); + assert(currCommAss != 0); + // Store the target of community assignment + long* targetCommAss = (long*)malloc(NV * sizeof(long)); + assert(targetCommAss != 0); + + // Initialize each vertex to its own cluster + initCommAss(pastCommAss, currCommAss, NV); + + time2 = omp_get_wtime(); + printf("Time to initialize: %3.3lf\n", time2 - time1); + +#ifdef PRINT_DETAILED_STATS_ + printf( + "=====================================================================" + "===================================\n"); + printf( + "Itr E_xx A_x2 Curr-Mod Time-1(s) " + " Time-2(s) T/Itr(s)\n"); + printf( + "=====================================================================" + "===================================\n"); +#endif +#ifdef PRINT_TERSE_STATS_ + printf("=====================================================\n"); + printf("Itr Curr-Mod T/Itr(s) T-Cumulative\n"); + printf("=====================================================\n"); +#endif + // Start maximizing modularity + while (true) { + numItrs++; + time1 = omp_get_wtime(); +/* Re-initialize datastructures */ +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + clusterWeightInternal[i] = 0; + cUpdate[i].degree = 0; + cUpdate[i].size = 0; + } + +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + long adj1 = vtxPtr[i]; + long adj2 = vtxPtr[i + 1]; + long selfLoop = 0; + // Build a datastructure to hold the cluster structure of its neighbors + map clusterLocalMap; // Map each neighbor's cluster to a local number + map::iterator storedAlready; + vector Counter; // Number of edges in each unique cluster + // Add v's current cluster: + if (adj1 != adj2) { + clusterLocalMap[currCommAss[i]] = 0; + Counter.push_back(0); // Initialize the counter to ZERO (no edges incident yet) + // Find unique cluster ids and #of edges incident (eicj) to them + selfLoop = buildLocalMapCounter(adj1, adj2, clusterLocalMap, Counter, vtxInd, currCommAss, i); + // Update delta Q calculation + clusterWeightInternal[i] += (long)Counter[0]; //(e_ix) + // Calculate the max + targetCommAss[i] = + max(clusterLocalMap, Counter, selfLoop, cInfo, vDegree[i], currCommAss[i], constantForSecondTerm); + // assert((targetCommAss[i] >= 0)&&(targetCommAss[i] < NV)); + } else { + targetCommAss[i] = -1; + } + + // Update + if (targetCommAss[i] != currCommAss[i] && targetCommAss[i] != -1) { + __sync_fetch_and_add(&cUpdate[targetCommAss[i]].degree, vDegree[i]); + __sync_fetch_and_add(&cUpdate[targetCommAss[i]].size, 1); + __sync_fetch_and_sub(&cUpdate[currCommAss[i]].degree, vDegree[i]); + __sync_fetch_and_sub(&cUpdate[currCommAss[i]].size, 1); + } // End of If() + clusterLocalMap.clear(); + Counter.clear(); + } // End of for(i) + time2 = omp_get_wtime(); + + time3 = omp_get_wtime(); + double e_xx = 0; + double a2_x = 0; + +#pragma omp parallel for reduction(+ : e_xx) reduction(+ : a2_x) + for (long i = 0; i < NV; i++) { + e_xx += clusterWeightInternal[i]; + a2_x += (cInfo[i].degree) * (cInfo[i].degree); + } + time4 = omp_get_wtime(); + + currMod = (e_xx * (double)constantForSecondTerm) - + (a2_x * (double)constantForSecondTerm * (double)constantForSecondTerm); + totItr = (time2 - time1) + (time4 - time3); + total += totItr; +#ifdef PRINT_DETAILED_STATS_ + printf("%d \t %g \t %g \t %lf \t %3.3lf \t %3.3lf \t %3.3lf\n", numItrs, e_xx, a2_x, currMod, (time2 - time1), + (time4 - time3), totItr); +#endif +#ifdef PRINT_TERSE_STATS_ + printf("%d \t %lf \t %3.3lf \t %3.3lf\n", numItrs, currMod, totItr, total); +#endif + + // Break if modularity gain is not sufficient + if ((currMod - prevMod) < thresMod) { + break; + } + + // Else update information for the next iteration + prevMod = currMod; + if (prevMod < Lower) prevMod = Lower; +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + cInfo[i].size += cUpdate[i].size; + cInfo[i].degree += cUpdate[i].degree; + } + + // Do pointer swaps to reuse memory: + long* tmp; + tmp = pastCommAss; + pastCommAss = currCommAss; // Previous holds the current + currCommAss = targetCommAss; // Current holds the chosen assignment + targetCommAss = tmp; // Reuse the vector + + } // End of while(true) + *totTime = total; // Return back the total time for clustering + *numItr = numItrs; + +#ifdef PRINT_DETAILED_STATS_ + printf( + "=====================================================================" + "===================================\n"); + printf("Total time for %d iterations is: %lf\n", numItrs, total); + printf( + "=====================================================================" + "===================================\n"); +#endif +#ifdef PRINT_TERSE_STATS_ + printf( + "=====================================================================" + "===================================\n"); + printf("Total time for %d iterations is: %lf\n", numItrs, total); + printf( + "=====================================================================" + "===================================\n"); +#endif + +// Store back the community assignments in the input variable: +// Note: No matter when the while loop exits, we are interested in the previous +// assignment +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + C[i] = pastCommAss[i]; + } + // Cleanup + free(pastCommAss); + free(currCommAss); + free(targetCommAss); + free(vDegree); + free(cInfo); + free(cUpdate); + free(clusterWeightInternal); + + return prevMod; +} diff --git a/graph/L3/graphPartition/grappolo/src/parallelLouvainWithColoring.cpp b/graph/L3/graphPartition/grappolo/src/parallelLouvainWithColoring.cpp new file mode 100755 index 0000000000..7e46ef28f4 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/parallelLouvainWithColoring.cpp @@ -0,0 +1,309 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "defs.h" +#include "utilityClusteringFunctions.h" + +using namespace std; + +double algoLouvainWithDistOneColoring(graphNew* G, + long* C, + int nThreads, + int* color, + int numColor, + double Lower, + double thresh, + double* totTime, + int* numItr) { +#ifdef PRINT_DETAILED_STATS_ + printf("Within algoLouvainWithDistOneColoring()\n"); +#endif + if (nThreads < 1) + omp_set_num_threads(1); + else + omp_set_num_threads(nThreads); +#ifdef PRINT_DETAILED_STATS_ + int nT; +#pragma omp parallel + { nT = omp_get_num_threads(); } + printf("Actual number of threads: %d (requested: %d)\n", nT, nThreads); +#endif + + double time1, time2, time3, time4; // For timing purposes + double total = 0, totItr = 0; + /* Indexs are vertex */ + long* pastCommAss; // Store previous iteration's community assignment + long* currCommAss; // Store current community assignment + // long* targetCommAss; //Store the target of community assignment + long* vDegree; // Store each vertex's degree + long* clusterWeightInternal; // use for Modularity calculation (eii) + + /* Indexs are community */ + Comm* cInfo; // Community info. (ai and size) + Comm* cUpdate; // use for updating Community + + /* Book keeping variables */ + long NV = G->numVertices; + // long NS = G->sVertices;//-Wunused-variable + // long NE = G->numEdges;//-Wunused-variable + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + + /* Modularity Needed variables */ + // long totalEdgeWeightTwice;//-Wunused-variable + double constantForSecondTerm; + double prevMod = Lower; + double currMod = -1; + double thresMod = thresh; + int numItrs = 0; + + /********************** Initialization **************************/ + time1 = omp_get_wtime(); + vDegree = (long*)malloc(NV * sizeof(long)); + assert(vDegree != 0); + cInfo = (Comm*)malloc(NV * sizeof(Comm)); + assert(cInfo != 0); + cUpdate = (Comm*)malloc(NV * sizeof(Comm)); + assert(cUpdate != 0); + + sumVertexDegree(vtxInd, vtxPtr, vDegree, NV, cInfo); // Sum up the vertex degree + /*** Compute the total edge weight (2m) and 1/2m ***/ + constantForSecondTerm = calConstantForSecondTerm(vDegree, NV); // 1 over sum of the degree + + pastCommAss = (long*)malloc(NV * sizeof(long)); + assert(pastCommAss != 0); + // Community provided as input: + currCommAss = C; + assert(currCommAss != 0); + + /*** Assign each vertex to its own Community ***/ + initCommAss(pastCommAss, currCommAss, NV); + + clusterWeightInternal = (long*)malloc(NV * sizeof(long)); + assert(clusterWeightInternal != 0); + + /*** Create a CSR-like datastructure for vertex-colors ***/ + long* colorPtr = (long*)malloc((numColor + 1) * sizeof(long)); + long* colorIndex = (long*)malloc(NV * sizeof(long)); + long* colorAdded = (long*)malloc(numColor * sizeof(long)); + assert(colorPtr != 0); + assert(colorIndex != 0); + assert(colorAdded != 0); +// Initialization +#pragma omp parallel for + for (long i = 0; i < numColor; i++) { + colorPtr[i] = 0; + colorAdded[i] = 0; + } + colorPtr[numColor] = 0; +// Count the size of each color +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + __sync_fetch_and_add(&colorPtr[(long)color[i] + 1], 1); + } + // Prefix sum: + for (long i = 0; i < numColor; i++) { + colorPtr[i + 1] += colorPtr[i]; + } +// Group vertices with the same color in particular order +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + long tc = (long)color[i]; + long Where = colorPtr[tc] + __sync_fetch_and_add(&(colorAdded[tc]), 1); + colorIndex[Where] = i; + } + time2 = omp_get_wtime(); + printf("Time to initialize: %3.3lf\n", time2 - time1); +#ifdef PRINT_DETAILED_STATS_ + printf( + "=====================================================================" + "===================================\n"); + printf( + "Itr E_xx A_x2 Curr-Mod Time-1(s) " + " Time-2(s) T/Itr(s)\n"); + printf( + "=====================================================================" + "===================================\n"); +#endif +#ifdef PRINT_TERSE_STATS_ + printf("=====================================================\n"); + printf("Itr Curr-Mod T/Itr(s) T-Cumulative\n"); + printf("=====================================================\n"); +#endif + while (true) { + numItrs++; + + time1 = omp_get_wtime(); + for (long ci = 0; ci < numColor; ci++) // Begin of color loop + { +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + clusterWeightInternal[i] = 0; // Initialize to zero + cUpdate[i].degree = 0; + cUpdate[i].size = 0; + } + long coloradj1 = colorPtr[ci]; + long coloradj2 = colorPtr[ci + 1]; + +#pragma omp parallel for + for (long K = coloradj1; K < coloradj2; K++) { + long i = colorIndex[K]; + long localTarget = -1; + long adj1 = vtxPtr[i]; + long adj2 = vtxPtr[i + 1]; + long selfLoop = 0; + // Build a datastructure to hold the cluster structure of its neighbors: + map clusterLocalMap; // Map each neighbor's cluster to a local number + map::iterator storedAlready; + vector Counter; // Number of edges to each unique cluster + + if (adj1 != adj2) { + // Add v's current cluster: + clusterLocalMap[currCommAss[i]] = 0; + Counter.push_back(0); // Initialize the counter to ZERO (no edges incident yet) + // Find unique cluster ids and #of edges incident (eicj) to them + selfLoop = buildLocalMapCounter(adj1, adj2, clusterLocalMap, Counter, vtxInd, currCommAss, i); + // Calculate the max + localTarget = max(clusterLocalMap, Counter, selfLoop, cInfo, vDegree[i], currCommAss[i], + constantForSecondTerm); + } else { + localTarget = -1; + } + // Update prepare + if (localTarget != currCommAss[i] && localTarget != -1) { + __sync_fetch_and_add(&cUpdate[localTarget].degree, vDegree[i]); + __sync_fetch_and_add(&cUpdate[localTarget].size, 1); + __sync_fetch_and_sub(&cUpdate[currCommAss[i]].degree, vDegree[i]); + __sync_fetch_and_sub(&cUpdate[currCommAss[i]].size, 1); + } // End of If() + currCommAss[i] = localTarget; + clusterLocalMap.clear(); + } // End of for(i) + +// UPDATE +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + cInfo[i].size += cUpdate[i].size; + cInfo[i].degree += cUpdate[i].degree; + } + } // End of Color loop + time2 = omp_get_wtime(); + + time3 = omp_get_wtime(); + double e_xx = 0; + double a2_x = 0; + +// CALCULATE MOD +#pragma omp parallel for // Parallelize on each vertex + for (long i = 0; i < NV; i++) { + clusterWeightInternal[i] = 0; + } +#pragma omp parallel for // Parallelize on each vertex + for (long i = 0; i < NV; i++) { + long adj1 = vtxPtr[i]; + long adj2 = vtxPtr[i + 1]; + for (long j = adj1; j < adj2; j++) { + if (currCommAss[vtxInd[j].tail] == currCommAss[i]) { + clusterWeightInternal[i] += (long)vtxInd[j].weight; + } + } + } + +#pragma omp parallel for reduction(+ : e_xx) reduction(+ : a2_x) + for (long i = 0; i < NV; i++) { + e_xx += clusterWeightInternal[i]; + a2_x += (cInfo[i].degree) * (cInfo[i].degree); + } + time4 = omp_get_wtime(); + + currMod = + e_xx * (double)constantForSecondTerm - a2_x * (double)constantForSecondTerm * (double)constantForSecondTerm; + + totItr = (time2 - time1) + (time4 - time3); + total += totItr; + +#ifdef PRINT_DETAILED_STATS_ + printf("%d \t %g \t %g \t %lf \t %3.3lf \t %3.3lf \t %3.3lf\n", numItrs, e_xx, a2_x, currMod, (time2 - time1), + (time4 - time3), totItr); +#endif +#ifdef PRINT_TERSE_STATS_ + printf("%d \t %lf \t %3.3lf \t %3.3lf\n", numItrs, currMod, totItr, total); +#endif + if ((currMod - prevMod) < thresMod) { + break; + } + + prevMod = currMod; + } // End of while(true) + *totTime = total; // Return back the total time + *numItr = numItrs; + +#ifdef PRINT_DETAILED_STATS_ + printf( + "=====================================================================" + "===================================\n"); + printf("Total time for %d iterations is: %lf\n", numItrs, total); + printf( + "=====================================================================" + "===================================\n"); +#endif +#ifdef PRINT_TERSE_STATS_ + printf( + "=====================================================================" + "===================================\n"); + printf("Total time for %d iterations is: %lf\n", numItrs, total); + printf( + "=====================================================================" + "===================================\n"); +#endif + // Cleanup: + free(vDegree); + free(cInfo); + free(cUpdate); + free(clusterWeightInternal); + free(colorPtr); + free(colorIndex); + free(colorAdded); + free(pastCommAss); + + return prevMod; + +} // End of algoLouvainWithDistOneColoring() diff --git a/graph/L3/graphPartition/grappolo/src/parseInputFiles.cpp b/graph/L3/graphPartition/grappolo/src/parseInputFiles.cpp new file mode 100755 index 0000000000..8fe10bc337 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/parseInputFiles.cpp @@ -0,0 +1,1957 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "defs.h" +#include "utilityStringTokenizer.hpp" + +/* Remove self- and duplicate edges. */ +/* For each node, we store its non-duplicate edges as a linked list */ +long removeEdges(long NV, long NE, edge* edgeList) +{ +#ifndef NDEBUG + std::cout << "DEBUG: removeEdges NV=" << NV << " NE=" << NE << std::endl; +#endif + long NGE = 0; + long* head = (long*)malloc(NV * sizeof(long)); /* head of linked list points to an edge */ + long* next = (long*)malloc(NE * sizeof(long)); /* ptr to next edge in linked list */ + + /* Initialize linked lists */ + for (long i = 0; i < NV; i++) head[i] = -1; + for (long i = 0; i < NE; i++) next[i] = -2; + + for (long i = 0; i < NE; i++) { + long sv = edgeList[i].head; + long ev = edgeList[i].tail; + if (sv == ev) continue; /* self edge */ + long* ptr = head + sv; /* start at head of list for this key */ + while (1) { + long edgeId = *ptr; + if (edgeId == -1) { /* at the end of the list */ + edgeId = *ptr; /* lock ptr */ + if (edgeId == -1) { /* if still end of list */ + // long newId = NGE;//unused variable + NGE++; /* increment number of good edges */ + // edgeList[i].id = newId; /* set id of edge */ + next[i] = -1; /* insert edge in linked list */ + *ptr = i; + break; + } + *ptr = edgeId; + } else if (edgeList[edgeId].tail == ev) + break; /* duplicate edge */ + else + ptr = next + edgeId; + } + } + /* Move good edges to front of edgeList */ + /* While edge i is a bad edge, swap with last edge in list */ + for (long i = 0; i < NGE; i++) { + while (next[i] == -2) { + long k = NE - 1; + NE--; + edgeList[i] = edgeList[k]; + next[i] = next[k]; + } + } + printf("About to free memory\n"); + free(head); + free(next); + //printf("Exiting removeEdges()\n"); + return NGE; +} // End of removeEdges() + + +/* Since graphNew is undirected, sort each edge head --> tail AND tail --> head */ +void SortEdgesUndirected(long NV, long NE, edge* list1, edge* list2, long* ptrs) { + for (long i = 0; i < NV + 2; i++) ptrs[i] = 0; + ptrs += 2; + + /* Histogram key values */ + for (long i = 0; i < NE; i++) { + ptrs[list1[i].head]++; + ptrs[list1[i].tail]++; + } + /* Compute start index of each bucket */ + for (long i = 1; i < NV; i++) ptrs[i] += ptrs[i - 1]; + ptrs--; + + /* Move edges into its bucket's segment */ + for (long i = 0; i < NE; i++) { + long head = list1[i].head; + long index = ptrs[head]++; + // list2[index].id = list1[i].id; + list2[index].head = list1[i].head; + list2[index].tail = list1[i].tail; + list2[index].weight = list1[i].weight; + + long tail = list1[i].tail; + index = ptrs[tail]++; + // list2[index].id = list1[i].id; + list2[index].head = list1[i].tail; + list2[index].tail = list1[i].head; + list2[index].weight = list1[i].weight; + } +} // End of SortEdgesUndirected2() + +/* Sort each node's neighbors by tail from smallest to largest. */ +void SortNodeEdgesByIndex(long NV, edge* list1, edge* list2, long* ptrs) { + for (long i = 0; i < NV; i++) { + edge* edges1 = list1 + ptrs[i]; + edge* edges2 = list2 + ptrs[i]; + long size = ptrs[i + 1] - ptrs[i]; + + /* Merge Sort */ + for (long skip = 2; skip < 2 * size; skip *= 2) { + for (long sect = 0; sect < size; sect += skip) { + long j = sect; + long l = sect; + long half_skip = skip / 2; + long k = sect + half_skip; + + long j_limit = (j + half_skip < size) ? j + half_skip : size; + long k_limit = (k + half_skip < size) ? k + half_skip : size; + + while ((j < j_limit) && (k < k_limit)) { + if (edges1[j].tail < edges1[k].tail) { + edges2[l] = edges1[j]; + j++; + l++; + } else { + edges2[l] = edges1[k]; + k++; + l++; + } + } + while (j < j_limit) { + edges2[l] = edges1[j]; + j++; + l++; + } + while (k < k_limit) { + edges2[l] = edges1[k]; + k++; + l++; + } + } + edge* tmp = edges1; + edges1 = edges2; + edges2 = tmp; + } + // result is in list2, so move to list1 + if (edges1 == list2 + ptrs[i]) + for (long j = ptrs[i]; j < ptrs[i + 1]; j++) list1[j] = list2[j]; + } +} // End of SortNodeEdgesByIndex2() + +// Parse files in Metis format: +void loadMetisFileFormat(graphNew* G, const char* filename) { + long i, j, value, neighbor, mNVer = 0, mNEdge = 0; + double edgeWeight; //, vertexWeight;//-Wunused-but-set-variable + string oneLine, myDelimiter(" "); // Delimiter is a blank space + ifstream fin; + char comment; + + fin.open(filename); + if (!fin) { + cerr << "Within Function: loadMetisFileFormat() \n"; + cerr << "Could not open the file.. \n"; + exit(1); + } + do { // Ignore the comment lines + getline(fin, oneLine); + comment = oneLine[0]; + } while (comment == '%'); + + StringTokenizer* ST = new StringTokenizer(oneLine, myDelimiter); + if (ST->HasMoreTokens()) mNVer = atol(ST->GetNextToken().c_str()); // Number of Vertices + if (ST->HasMoreTokens()) mNEdge = atol(ST->GetNextToken().c_str()); // Number of Edges + if (ST->HasMoreTokens()) + value = atol(ST->GetNextToken().c_str()); // Indication of the weights + else + value = 0; + delete ST; +#ifdef PRINT_CF_DEBUG_INFO_ + cout << "N Ver: " << mNVer << " N Edge: " << mNEdge << " value: " << value << " \n"; +#endif + + long* mVerPtr = (long*)malloc((mNVer + 1) * sizeof(long)); // The Pointer + edge* mEdgeList = (edge*)malloc((mNEdge * 2) * sizeof(edge)); // The Indices + assert(mVerPtr != 0); + assert(mEdgeList != 0); +// printf("hi\n"); +#pragma omp parallel for + for (long i = 0; i <= mNVer; i++) { + mVerPtr[i] = 0; + } +#pragma omp parallel for + for (long i = 0; i < (2 * mNEdge); i++) { + mEdgeList[i].tail = -1; + mEdgeList[i].weight = 0; + } + + // Read the rest of the file: + long PtrPos = 0, IndPos = 0, cumulative = 0; + mVerPtr[PtrPos] = cumulative; + PtrPos++; + // printf("hi %d\n",value); + switch (value) { + case 0: // No Weights +#ifdef PRINT_CF_DEBUG_INFO_ + cout << "Graph Type: No Weights. \n"; +#endif + + for (i = 0; i < mNVer; i++) { + if (fin.eof()) { + cout << " Error reading the Metis input File \n"; + cout << " Reached Abrupt End \n"; + exit(1); + } + j = 0; + getline(fin, oneLine); + StringTokenizer* ST = new StringTokenizer(oneLine, myDelimiter); +#ifdef PRINT_CF_DEBUG_INFO_ + cout << "\n" << i << ": "; +#endif + while (ST->HasMoreTokens()) { + neighbor = (atol(ST->GetNextToken().c_str()) - 1); // Zero-based index +#ifdef PRINT_CF_DEBUG_INFO_ + cout << neighbor << " "; +#endif + j++; + mEdgeList[IndPos].head = i; + mEdgeList[IndPos].tail = neighbor; // IndPos++; + mEdgeList[IndPos].weight = 1; + IndPos++; + } + delete ST; // Clear the buffer + cumulative += j; + mVerPtr[PtrPos] = cumulative; + PtrPos++; // Add to the Pointer Vector + } + break; + case 1: // Only Edge weights +#ifdef PRINT_CF_DEBUG_INFO_ + cout << "Graph Type: Only Edge Weights. \n"; +#endif + + for (i = 0; i < mNVer; i++) { + if (fin.eof()) { + cerr << "Within Function: loadMetisFileFormat() \n"; + cerr << " Error reading the Metis input File \n"; + cerr << " Reached Abrupt End \n"; + exit(1); + } + j = 0; + getline(fin, oneLine); + StringTokenizer* ST = new StringTokenizer(oneLine, myDelimiter); + while (ST->HasMoreTokens()) { + neighbor = (atol(ST->GetNextToken().c_str()) - 1); // Zero-based index + mEdgeList[IndPos].tail = neighbor; + IndPos++; + edgeWeight = atof(ST->GetNextToken().c_str()); + mEdgeList[IndPos].weight = (long)edgeWeight; // Type casting + j++; + } + delete ST; // Clear the buffer + cumulative += j; + mVerPtr[PtrPos] = cumulative; + PtrPos++; // Add to the Pointer Vector + } + break; + case 10: // Only Vertex Weights +#ifdef PRINT_CF_DEBUG_INFO_ + cout << "Graph Type: Only Vertex Weights. \n"; + cout << "Will ignore vertex weights.\n"; +#endif + + for (i = 0; i < mNVer; i++) { + if (fin.eof()) { + cout << " Error reading the Metis input File \n"; + cout << " Reached Abrupt End \n"; + exit(1); + } + j = 0; + getline(fin, oneLine); + StringTokenizer* ST = new StringTokenizer(oneLine, myDelimiter); + // vertexWeight = atof( ST->GetNextToken().c_str() ); + // //-Wunused-but-set-variable + while (ST->HasMoreTokens()) { + neighbor = (atol(ST->GetNextToken().c_str()) - 1); // Zero-based index +#ifdef PRINT_CF_DEBUG_INFO_ + cout << "Neighbors: " << neighbor << " \t"; +#endif + j++; + mEdgeList[IndPos].tail = neighbor; + IndPos++; + mEdgeList[IndPos].weight = 1; + } + delete ST; // Clear the buffer + cumulative += j; + mVerPtr[PtrPos] = cumulative; + PtrPos++; // Add to the Pointer Vector + } + break; + case 11: // Both Edge and Vertex Weights: +#ifdef PRINT_CF_DEBUG_INFO_ + cout << "Graph Type: Both Edge and Vertex Weights. \n"; +#endif + cout << "Will ignore vertex weights.\n"; + + for (i = 0; i < mNVer; i++) { + if (fin.eof()) { + cerr << "Within Function: loadMetisFileFormat() \n"; + cerr << " Error reading the Metis input File \n"; + cerr << " Reached Abrupt End \n"; + exit(1); + } + j = 0; + getline(fin, oneLine); + StringTokenizer* ST = new StringTokenizer(oneLine, myDelimiter); + // vertexWeight = atof( ST->GetNextToken().c_str() ); //Vertex + // weight////-Wunused-but-set-variable + while (ST->HasMoreTokens()) { + neighbor = (atol(ST->GetNextToken().c_str()) - 1); // Zero-based index + mEdgeList[IndPos].tail = neighbor; + IndPos++; + edgeWeight = atof(ST->GetNextToken().c_str()); + mEdgeList[IndPos].weight = (long)edgeWeight; // Type casting + j++; + } + delete ST; // Clear the buffer + cumulative += j; + mVerPtr[PtrPos] = cumulative; + PtrPos++; // Add to the Pointer Vector + } + break; + } // End of switch(value) + fin.close(); + G->numVertices = mNVer; + G->sVertices = mNVer; + G->numEdges = mNEdge; // This is what the code expects + G->edgeListPtrs = mVerPtr; // Vertex Pointer + G->edgeList = mEdgeList; + +} // End of loadMetisFileFormat() + +/*-------------------------------------------------------* + * This function reads a MATRIX MARKET file and builds the graphNew + *-------------------------------------------------------*/ +void parse_MatrixMarket(graphNew* G, char* fileName) { + printf("Parsing a Matrix Market File...\n"); + int nthreads; +#pragma omp parallel + { nthreads = omp_get_num_threads(); } + printf("parse_MatrixMarket: Number of threads: %d\n", nthreads); + + double time1, time2; + FILE* file = fopen(fileName, "r"); + if (file == NULL) { + printf("Cannot open the input file: %s\n", fileName); + exit(1); + } + + /* ----- Read File in Matrix Market Format ------ */ + // Parse the first line: + char line[1024]; + fgets(line, 1024, file); + char LS1[25], LS2[25], LS3[25], LS4[25], LS5[25]; + if (sscanf(line, "%s %s %s %s %s", LS1, LS2, LS3, LS4, LS5) != 5) { + printf("parse_MatrixMarket(): bad file format - 01"); + exit(1); + } + printf("%s %s %s %s %s\n", LS1, LS2, LS3, LS4, LS5); + if (strcmp(LS1, "%%MatrixMarket") != 0) { + printf("Error: The first line should start with %%MatrixMarket word \n"); + exit(1); + } + if (!(strcmp(LS2, "matrix") == 0 || strcmp(LS2, "Matrix") == 0 || strcmp(LS2, "MATRIX") == 0)) { + printf("Error: The Object should be matrix or Matrix or MATRIX \n"); + exit(1); + } + if (!(strcmp(LS3, "coordinate") == 0 || strcmp(LS3, "Coordinate") == 0 || strcmp(LS3, "COORDINATE") == 0)) { + printf( + "Error: The Object should be coordinate or Coordinate or COORDINATE " + "\n"); + exit(1); + } + // int isComplex = 0; //-Wunused-but-set-variable + if (strcmp(LS4, "complex") == 0 || strcmp(LS4, "Complex") == 0 || strcmp(LS4, "COMPLEX") == 0) { + // isComplex = 1;//-Wunused-but-set-variable + printf("Warning: Will only read the real part. \n"); + } + int isPattern = 0; + if (strcmp(LS4, "pattern") == 0 || strcmp(LS4, "Pattern") == 0 || strcmp(LS4, "PATTERN") == 0) { + isPattern = 1; + printf("Note: Matrix type is Pattern. Will set all weights to 1.\n"); + // exit(1); + } + int isSymmetric = 0, isGeneral = 0; + if (strcmp(LS5, "general") == 0 || strcmp(LS5, "General") == 0 || strcmp(LS5, "GENERAL") == 0) + isGeneral = 1; + else { + if (strcmp(LS5, "symmetric") == 0 || strcmp(LS5, "Symmetric") == 0 || strcmp(LS5, "SYMMETRIC") == 0) { + isSymmetric = 1; + printf( + "Note: Matrix type is Symmetric: Converting it into General type. " + "\n"); + } + } + if ((isGeneral == 0) && (isSymmetric == 0)) { + printf("Warning: Matrix type should be General or Symmetric. \n"); + exit(1); + } + + /* Parse all comments starting with '%' symbol */ + do { + fgets(line, 1024, file); + } while (line[0] == '%'); + + /* Read the matrix parameters */ + long NS = 0, NT = 0, NV = 0; + long NE = 0; + if (sscanf(line, "%ld %ld %ld", &NS, &NT, &NE) != 3) { + printf("parse_MatrixMarket(): bad file format - 02"); + exit(1); + } + NV = NS + NT; + printf("|S|= %ld, |T|= %ld, |E|= %ld \n", NS, NT, NE); + + /*---------------------------------------------------------------------*/ + /* Read edge list */ + /* S vertices: 0 to NS-1 */ + /* T vertices: NS to NS+NT-1 */ + /*---------------------------------------------------------------------*/ + // Allocate for Edge Pointer and keep track of degree for each vertex + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); +#pragma omp parallel for + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + + edge* edgeListTmp; // Read the data in a temporary list + long newNNZ = 0; // New edges because of symmetric matrices + long Si, Ti; + double weight = 1; + if (isSymmetric == 1) { + printf("Matrix is of type: Symmetric Real or Complex\n"); + printf("Weights will be converted to positive numbers.\n"); + edgeListTmp = (edge*)malloc(2 * NE * sizeof(edge)); + for (long i = 0; i < NE; i++) { + if (isPattern == 1) + fscanf(file, "%ld %ld", &Si, &Ti); + else + fscanf(file, "%ld %ld %lf", &Si, &Ti, &weight); + Si--; + Ti--; // One-based indexing + assert((Si >= 0) && (Si < NV)); + assert((Ti >= 0) && (Ti < NV)); + weight = fabs(weight); // Make it positive : Leave it as is + if (Si == Ti) { + edgeListTmp[i].head = Si; // The S index + edgeListTmp[i].tail = NS + Ti; // The T index + edgeListTmp[i].weight = weight; // The value + edgeListPtr[Si + 1]++; + edgeListPtr[NS + Ti + 1]++; + } else { // an off diagonal element: Also store the upper part + // LOWER PART: + edgeListTmp[i].head = Si; // The S index + edgeListTmp[i].tail = NS + Ti; // The T index + edgeListTmp[i].weight = weight; // The value + edgeListPtr[Si + 1]++; + edgeListPtr[NS + Ti + 1]++; + // UPPER PART: + edgeListTmp[NE + newNNZ].head = Ti; // The S index + edgeListTmp[NE + newNNZ].tail = NS + Si; // The T index + edgeListTmp[NE + newNNZ].weight = weight; // The value + newNNZ++; // Increment the number of edges + edgeListPtr[Ti + 1]++; + edgeListPtr[NS + Si + 1]++; + } + } + } // End of Symmetric + /////// General Real or Complex /////// + else { + printf("Matrix is of type: Unsymmetric Real or Complex\n"); + printf("Weights will be converted to positive numbers.\n"); + edgeListTmp = (edge*)malloc(NE * sizeof(edge)); + for (long i = 0; i < NE; i++) { + if (isPattern == 1) + fscanf(file, "%ld %ld", &Si, &Ti); + else + fscanf(file, "%ld %ld %lf", &Si, &Ti, &weight); + // printf("(%d, %d) %lf\n",Si, Ti, weight); + Si--; + Ti--; // One-based indexing + assert((Si >= 0) && (Si < NV)); + assert((Ti >= 0) && (Ti < NV)); + weight = fabs(weight); // Make it positive : Leave it as is + edgeListTmp[i].head = Si; // The S index + edgeListTmp[i].tail = NS + Ti; // The T index + edgeListTmp[i].weight = weight; // The value + edgeListPtr[Si + 1]++; + edgeListPtr[NS + Ti + 1]++; + } + } // End of Real or Complex + fclose(file); // Close the file + printf("Done reading from file.\n"); + + if (isSymmetric) { + printf("Modified the number of edges from %ld ", NE); + NE += newNNZ; //#NNZ might change + printf("to %ld \n", NE); + } + + //////Build the EdgeListPtr Array: Cumulative addition + time1 = omp_get_wtime(); + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + time2 = omp_get_wtime(); + printf("Done cumulative addition for edgeListPtrs: %9.6lf sec.\n", time2 - time1); + printf("Sanity Check: 2|E| = %ld, edgeListPtr[NV]= %ld\n", NE * 2, edgeListPtr[NV]); + + /*---------------------------------------------------------------------*/ + /* Allocate memory for G & Build it */ + /*---------------------------------------------------------------------*/ + time1 = omp_get_wtime(); + edge* edgeList = (edge*)malloc(2 * NE * sizeof(edge)); // Every edge stored twice + assert(edgeList != 0); + // Keep track of how many edges have been added for a vertex: + long* added = (long*)malloc(NV * sizeof(long)); + assert(added != 0); +#pragma omp parallel for + for (long i = 0; i < NV; i++) added[i] = 0; + time2 = omp_get_wtime(); + printf("Time for allocating memory for marks and edgeList = %lf\n", time2 - time1); + + time1 = omp_get_wtime(); + + printf("About to build edgeList...\n"); +// Build the edgeList from edgeListTmp: +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + long head = edgeListTmp[i].head; + long tail = edgeListTmp[i].tail; + double weight = edgeListTmp[i].weight; + + long Where = edgeListPtr[head] + __sync_fetch_and_add(&added[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + // Now add the counter-edge: + Where = edgeListPtr[tail] + __sync_fetch_and_add(&added[tail], 1); + edgeList[Where].head = tail; + edgeList[Where].tail = head; + edgeList[Where].weight = weight; + } + time2 = omp_get_wtime(); + printf("Time for building edgeList = %lf\n", time2 - time1); + + G->sVertices = NS; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + free(edgeListTmp); + free(added); +} + +/*-------------------------------------------------------* + * This function reads a MATRIX MARKET file and build the graphNew + * graphNew is nonbipartite: each diagonal entry is a vertex, and + * each non-diagonal entry becomes an edge. Assume structural and + * numerical symmetry. + *-------------------------------------------------------*/ +void parse_MatrixMarket_Sym_AsGraph(graphNew* G, char* fileName) { + printf("Parsing a Matrix Market File as a general graphNew...\n"); + int nthreads = 0; +#pragma omp parallel + { nthreads = omp_get_num_threads(); } + printf("parse_MatrixMarket: Number of threads: %d\n ", nthreads); + + double time1, time2; + FILE* file = fopen(fileName, "r"); + if (file == NULL) { + printf("Cannot open the input file: %s\n", fileName); + exit(1); + } + /* ----- Read File in Matrix Market Format ------ */ + // Parse the first line: + char line[1024]; + fgets(line, 1024, file); + char LS1[25], LS2[25], LS3[25], LS4[25], LS5[25]; + if (sscanf(line, "%s %s %s %s %s", LS1, LS2, LS3, LS4, LS5) != 5) { + printf("parse_MatrixMarket(): bad file format - 01"); + exit(1); + } + printf("%s %s %s %s %s\n", LS1, LS2, LS3, LS4, LS5); + if (strcmp(LS1, "%%MatrixMarket") != 0) { + printf("Error: The first line should start with %%MatrixMarket word \n"); + exit(1); + } + if (!(strcmp(LS2, "matrix") == 0 || strcmp(LS2, "Matrix") == 0 || strcmp(LS2, "MATRIX") == 0)) { + printf("Error: The Object should be matrix or Matrix or MATRIX \n"); + exit(1); + } + if (!(strcmp(LS3, "coordinate") == 0 || strcmp(LS3, "Coordinate") == 0 || strcmp(LS3, "COORDINATE") == 0)) { + printf( + "Error: The Object should be coordinate or Coordinate or COORDINATE " + "\n"); + exit(1); + } + // int isComplex = 0;//-Wunused-but-set-variable + if (strcmp(LS4, "complex") == 0 || strcmp(LS4, "Complex") == 0 || strcmp(LS4, "COMPLEX") == 0) { + // isComplex = 1;//-Wunused-but-set-variable + printf("Warning: Will only read the real part. \n"); + } + int isPattern = 0; + if (strcmp(LS4, "pattern") == 0 || strcmp(LS4, "Pattern") == 0 || strcmp(LS4, "PATTERN") == 0) { + isPattern = 1; + printf("Note: Matrix type is Pattern. Will set all weights to 1.\n"); + // exit(1); + } + int isSymmetric = 0; //, isGeneral = 0;//-Wunused-but-set-variable + if (strcmp(LS5, "general") == 0 || strcmp(LS5, "General") == 0 || strcmp(LS5, "GENERAL") == 0) + ; // isGeneral = 1;//-Wunused-but-set-variable + else { + if (strcmp(LS5, "symmetric") == 0 || strcmp(LS5, "Symmetric") == 0 || strcmp(LS5, "SYMMETRIC") == 0) { + isSymmetric = 1; + printf( + "Note: Matrix type is Symmetric: Converting it into General type. " + "\n"); + } + } + if (isSymmetric == 0) { + printf("Warning: Matrix type should be Symmetric for this routine. \n"); + exit(1); + } + + /* Parse all comments starting with '%' symbol */ + do { + fgets(line, 1024, file); + } while (line[0] == '%'); + + /* Read the matrix parameters */ + long NS = 0, NT = 0, NV = 0; + long NE = 0; + if (sscanf(line, "%ld %ld %ld", &NS, &NT, &NE) != 3) { + printf("parse_MatrixMarket(): bad file format - 02"); + exit(1); + } + NV = NS; + printf("|S|= %ld, |T|= %ld, |E|= %ld \n", NS, NT, NE); + + /*---------------------------------------------------------------------*/ + /* Read edge list */ + /* S vertices: 0 to NS-1 */ + /* T vertices: NS to NS+NT-1 */ + /*---------------------------------------------------------------------*/ + // Allocate for Edge Pointer and keep track of degree for each vertex + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); +#pragma omp parallel for + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + + edge* edgeListTmp; // Read the data in a temporary list + long newNNZ = 0; // New edges because of symmetric matrices + long Si, Ti; + double weight = 1; + printf("Matrix is of type: Symmetric Real or Complex\n"); + printf("Weights will be converted to positive numbers.\n"); + edgeListTmp = (edge*)malloc(2 * NE * sizeof(edge)); + for (long i = 0; i < NE; i++) { + if (isPattern == 1) + fscanf(file, "%ld %ld", &Si, &Ti); + else + fscanf(file, "%ld %ld %lf", &Si, &Ti, &weight); + Si--; + Ti--; // One-based indexing + assert((Si >= 0) && (Si < NV)); + assert((Ti >= 0) && (Ti < NV)); + weight = fabs(weight); // Make it positive : Leave it as is + if (Si == Ti) { + // Do nothing... + } else { // an off diagonal element: store the edge + // LOWER PART: + edgeListTmp[newNNZ].head = Si; // The S index + edgeListTmp[newNNZ].tail = Ti; // The T index + edgeListTmp[newNNZ].weight = weight; // The value + edgeListPtr[Si + 1]++; + edgeListPtr[Ti + 1]++; + newNNZ++; + } // End of Else + } // End of for loop + fclose(file); // Close the file + // newNNZ = newNNZ / 2; + printf("Done reading from file.\n"); + printf("Modified the number of edges from %ld ", NE); + NE = newNNZ; //#NNZ might change + printf("to %ld \n", NE); + + //////Build the EdgeListPtr Array: Cumulative addition + time1 = omp_get_wtime(); + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + time2 = omp_get_wtime(); + printf("Done cumulative addition for edgeListPtrs: %9.6lf sec.\n", time2 - time1); + printf("Sanity Check: 2|E| = %ld, edgeListPtr[NV]= %ld\n", NE * 2, edgeListPtr[NV]); + + /*---------------------------------------------------------------------*/ + /* Allocate memory for G & Build it */ + /*---------------------------------------------------------------------*/ + time1 = omp_get_wtime(); + edge* edgeList = (edge*)malloc(2 * NE * sizeof(edge)); // Every edge stored twice + assert(edgeList != 0); + // Keep track of how many edges have been added for a vertex: + long* Counter = (long*)malloc(NV * sizeof(long)); + assert(Counter != 0); +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + Counter[i] = 0; + } + time2 = omp_get_wtime(); + printf("Time for allocating memory for edgeList = %lf\n", time2 - time1); + printf("About to build edgeList...\n"); + + time1 = omp_get_wtime(); +// Build the edgeList from edgeListTmp: +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + long head = edgeListTmp[i].head; + long tail = edgeListTmp[i].tail; + double weight = edgeListTmp[i].weight; + + long Where = edgeListPtr[head] + __sync_fetch_and_add(&Counter[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + // Now add the edge the other way: + Where = edgeListPtr[tail] + __sync_fetch_and_add(&Counter[tail], 1); + edgeList[Where].head = tail; + edgeList[Where].tail = head; + edgeList[Where].weight = weight; + } + time2 = omp_get_wtime(); + printf("Time for building edgeList = %lf\n", time2 - time1); + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + free(edgeListTmp); + free(Counter); + +} // End of parse_MatrixMarket_Sym_AsGraph() + +/* +------------------------------------------------------------------------- +INPUT FORMAT FOR WMATCH: +------------------------------------------------------------------------- + Graph I/O is performed by a generic graphNew library package, + so some of the fields are ignored by the "wmatch" code (but + you must include dummy fields in the input). + + There are three types of lines: the first line, vertex lines, + and edge lines. The fields in each line type are as follows. + + First line-> size edges U + size: integer giving number of vertices + edges: integer giving number of edges + U: character ``U'' or ``u'' specifying an undirected graphNew + + Vertex lines-> degree vlabel xcoord ycoord + degree: edge degree of the vertex + vlabel: vertex label (ignored--vertices are referred to by index) + xcoord: integer x-coordinate location (ignored) + ycoord: integer y-coordinate location (ignored) + + *****Each vertex line is followed immediately by the lines + for all its adjacent edges (thus each edge appears twice, + once for each vertex).****** + + Edge lines-> adjacent weight + adjacent: index (not vlabel) of the adjacent vertex + weight: integer edge weight +------------------------------------------------------------------------- +*/ +void parse_Dimacs1Format(graphNew* G, char* fileName) { + printf("Parsing a DIMACS-1 formatted file as a general graphNew...\n"); + int nthreads = 0; +#pragma omp parallel + { nthreads = omp_get_num_threads(); } + printf("parse_Dimacs1Format: Number of threads: %d\n ", nthreads); + + double time1, time2; + FILE* file = fopen(fileName, "r"); + if (file == NULL) { + printf("Cannot open the input file: %s\n", fileName); + exit(1); + } + /* ----- Read File in Matrix Market Format ------ */ + /* Read the matrix parameters */ + long NV = 0, NE = 0; + char line[1024], LS1[25]; + fgets(line, 1024, file); + // Parse the first line: + if (sscanf(line, "%ld %ld %s", &NV, &NE, LS1) != 3) { + printf("parse_Dimacs1(): bad file format - 01"); + exit(1); + } + assert((LS1[0] == 'U') || (LS1[0] == 'u')); // graphNew is undirected + // NE = NE / 2; //Each edge is stored twice, but counted only once, in the + // file + printf("|V|= %ld, |E|= %ld \n", NV, NE); + + /*---------------------------------------------------------------------*/ + /* Read edge list */ + /* S vertices: 0 to NS-1 */ + /* T vertices: NS to NS+NT-1 */ + /*---------------------------------------------------------------------*/ + // Allocate for Edge Pointer and keep track of degree for each vertex + time1 = omp_get_wtime(); + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); + assert(edgeListPtr != NULL); + edge* edgeList = (edge*)malloc(2 * NE * sizeof(edge)); // Every edge stored twice + assert(edgeList != NULL); + time2 = omp_get_wtime(); + printf("Time for allocating memory for storing graphNew = %lf\n", time2 - time1); +#pragma omp parallel for + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + + long Degree, Ti; + // double weight = 1;//-Wunused-variable + int Twt = 0, label, xCoord, yCoord; + long nE = 0; + printf("Weights will be converted to positive integers.\n"); + + time1 = omp_get_wtime(); + for (long i = 0; i < NV; i++) { + // Vertex lines: degree vlabel xcoord ycoord + fscanf(file, "%ld %d %d %d", &Degree, &label, &xCoord, &yCoord); + edgeListPtr[i + 1] = Degree; + for (long j = 0; j < Degree; j++) { + fscanf(file, "%ld %d", &Ti, &Twt); + assert((Ti > 0) && (Ti < NV)); + edgeList[nE].head = i; // The S index + edgeList[nE].tail = Ti - 1; // The T index: One-based indexing + edgeList[nE].weight = fabs((double)Twt); // Make it positive and cast to Double + nE++; + } // End of inner for loop + } // End of outer for loop + fclose(file); // Close the file + time2 = omp_get_wtime(); + printf("Done reading from file: nE= %ld. Time= %lf\n", nE, time2 - time1); + assert(NE == nE / 2); + + //////Build the EdgeListPtr Array: Cumulative addition + time1 = omp_get_wtime(); + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + time2 = omp_get_wtime(); + printf("Done cumulative addition for edgeListPtrs: %9.6lf sec.\n", time2 - time1); + printf("Sanity Check: 2|E| = %ld, edgeListPtr[NV]= %ld\n", NE * 2, edgeListPtr[NV]); + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + +} // End of parse_Dimacs1Format() + +/* ****************************************** */ +// Loading Functions: +/* NOTE: Indices are ZERO-based, i.e. G(0,0) is the first element, + while the indices stored in the file are ONE-based. +Details: +* A graphNew contains n nodes and m arcs +* Nodes are identified by integers 1...* Graphs can be interpreted as directed +or undirected, depending on the problem being studied +* Graphs can have parallel arcs and self-loops +* Arc weights are signed integers + +** c : This is a comment +** p sp n m : Unique problem line: sp is for shortest path - no meaning for us +** a U V W : a=arc, U, V, W are the I-J-V format for an edge + +* Assumption: Graphs are DIRECTED ==> Each edge is stored ONLY ONCE. +* (If Undirected, then edge is stored TWICE) +*/ +void parse_Dimacs9FormatDirectedNewD(graphNew* G, char* fileName) { + printf("Parsing a DIMACS-9 formatted file as a general graphNew...\n"); + printf( + "WARNING: Assumes that the graphNew is directed -- an edge is stored " + "only once.\n"); + printf( + " : Graph will be stored as undirected, each edge appears " + "twice.\n"); + int nthreads = 0; +#pragma omp parallel + { nthreads = omp_get_num_threads(); } + printf("parse_Dimacs9FormatDirectedNewD: Number of threads: %d\n ", nthreads); + + double time1, time2; + FILE* file = fopen(fileName, "r"); + if (file == NULL) { + printf("Cannot open the input file: %s\n", fileName); + exit(1); + } + char line[1024], LS1[25], LS2[25]; + // Ignore the Comment lines starting with "c" + do { + fgets(line, 1024, file); + } while (line[0] == 'c'); + // Expecting a problem line here: p sp n m + long NV = 0, NE = 0; + // Parse the problem line: + if (line[0] == 'p') { + if (sscanf(line, "%s %s %ld %ld", LS1, LS2, &NV, &NE) != 4) { + printf("parse_Dimacs9(): bad file format - 01"); + exit(1); + } + } else { + printf("parse_Dimacs9(): bad file format, expecting a line starting with p\n"); + printf("%s\n", line); + exit(1); + } + printf("|V|= %ld, |E|= %ld \n", NV, NE); + printf("Weights will be converted to positive numbers.\n"); + /*---------------------------------------------------------------------*/ + /* Read edge list: a U V W */ + /*---------------------------------------------------------------------*/ + edge* tmpEdgeList = (edge*)malloc(NE * sizeof(edge)); // Every edge stored ONCE + assert(tmpEdgeList != NULL); + long Si, Ti; + double Twt; + time1 = omp_get_wtime(); + for (long i = 0; i < NE; i++) { + // Vertex lines: degree vlabel xcoord ycoord + fscanf(file, "%s %ld %ld %lf", LS1, &Si, &Ti, &Twt); + assert((Si > 0) && (Si <= NV)); + assert((Ti > 0) && (Ti <= NV)); + tmpEdgeList[i].head = Si - 1; // The S index + tmpEdgeList[i].tail = Ti - 1; // The T index: One-based indexing + tmpEdgeList[i].weight = fabs((double)Twt); // Make it positive and cast to Double + } // End of outer for loop + fclose(file); // Close the file + time2 = omp_get_wtime(); + printf("Done reading from file: NE= %ld. Time= %lf\n", NE, time2 - time1); + + // Remove duplicate entries: + /* long NewEdges = removeEdges(NV, NE, tmpEdgeList); + if (NewEdges < NE) { + printf("Number of duplicate entries detected: %ld\n", NE-NewEdges); + NE = NewEdges; //Only look at clean edges + } else { + printf("No dubplicates found.\n"); + }*/ + /////////// + time1 = omp_get_wtime(); + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); + assert(edgeListPtr != NULL); + edge* edgeList = (edge*)malloc(2 * NE * sizeof(edge)); // Every edge stored twice + assert(edgeList != NULL); + time2 = omp_get_wtime(); + printf("Time for allocating memory for storing graphNew = %lf\n", time2 - time1); +#pragma omp parallel for + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + + //////Build the EdgeListPtr Array: Cumulative addition + time1 = omp_get_wtime(); +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + __sync_fetch_and_add(&edgeListPtr[tmpEdgeList[i].head + 1], 1); // Leave 0th position intact + __sync_fetch_and_add(&edgeListPtr[tmpEdgeList[i].tail + 1], 1); + } + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + time2 = omp_get_wtime(); + printf("Done cumulative addition for edgeListPtrs: %9.6lf sec.\n", time2 - time1); + printf("Sanity Check: 2|E| = %ld, edgeListPtr[NV]= %ld\n", NE * 2, edgeListPtr[NV]); + printf("*********** (%ld)\n", NV); + + printf("About to build edgeList...\n"); + time1 = omp_get_wtime(); + // Keep track of how many edges have been added for a vertex: + long* added = (long*)malloc(NV * sizeof(long)); + assert(added != NULL); +#pragma omp parallel for + for (long i = 0; i < NV; i++) added[i] = 0; + +// Build the edgeList from edgeListTmp: +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + long head = tmpEdgeList[i].head; + long tail = tmpEdgeList[i].tail; + double weight = tmpEdgeList[i].weight; + + long Where = edgeListPtr[head] + __sync_fetch_and_add(&added[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + // Now add the counter-edge: + Where = edgeListPtr[tail] + __sync_fetch_and_add(&added[tail], 1); + edgeList[Where].head = tail; + edgeList[Where].tail = head; + edgeList[Where].weight = weight; + } + time2 = omp_get_wtime(); + printf("Time for building edgeList = %lf\n", time2 - time1); + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + // Clean up + free(tmpEdgeList); + free(added); + +} // End of parse_Dimacs9FormatDirectedNewD() + +/*-------------------------------------------------------* + * This function reads a Pajek file and builds the graphNew + *-------------------------------------------------------*/ +void parse_PajekFormat(graphNew* G, char* fileName) +{ + printf("INFO: Parsing Pajek file %s...\n", fileName); + int nthreads; +#pragma omp parallel + { + nthreads = NUMTHREAD; // omp_get_num_threads(); + } + printf("parse_Pajek: Number of threads: %d\n", nthreads); + + double time1, time2; + FILE* file = fopen(fileName, "r"); + if (file == NULL) { + printf("ERROR: Cannot open the input file: %s\n", fileName); + exit(1); + } + // Parse the first line: + char line[1024]; + fgets(line, 1024, file); + char LS1[25], LS2[25]; + long NV = 0, ED = 0, NE = 0; + if (sscanf(line, "%s %s", LS1, LS2) != 2) { + printf("parse_Pajek(): bad file format - 01"); + exit(1); + } + // printf("(%s) --- (%s) \n", LS1, LS2); + if (strcmp(LS1, "*Vertices") != 0) { + printf("ERROR: The first line should start with *Vertices word \n"); + exit(1); + } + NV = atol(LS2); + printf("|V|= %ld \n", NV); + /* Ignore all the vertex lines */ + // for (long i=0; i <= NV; i++) { + fgets(line, 1024, file); + //} + if (sscanf(line, "%s %s", LS1, LS2) != 2) { + printf("parse_Pajek(): bad file format - 02"); + exit(1); + } + if (strcmp(LS1, "*Edges") != 0) { + printf("Error: The next line should start with *Edges word \n"); + exit(1); + } + + ED = atol(LS2); + printf("|E|= %ld \n", ED); + /*---------------------------------------------------------------------*/ + /* Read edge list */ + /* (i , j, value ) 1-based index */ + /*---------------------------------------------------------------------*/ + edge* edgeListTmp; // Read the data in a temporary list + long Si, Ti; + double weight = 1; + long edgeEstimate = ED; // NV * 2; //25% density -- not valid for large graphNews + edgeListTmp = (edge*)malloc(edgeEstimate * sizeof(edge)); + assert(edgeListTmp != 0); + + printf("Parsing edges -- with weights\n"); + + while (fscanf(file, "%ld %ld %lf", &Si, &Ti, &weight) != EOF) { + // while (fscanf(file, "%ld %ld", &Si, &Ti) != EOF) { + if (NE >= edgeEstimate) { + printf("Temporary buffer is not enough. \n"); + exit(1); + } + // printf("%ld -- %ld -- %lf\n", Si, Ti, weight); + Si--; + Ti--; // One-based indexing + assert((Si >= 0) && (Si < NV)); + assert((Ti >= 0) && (Ti < NV)); + // if(Si%99999 == 0) + // printf("%ld -- %ld\n", Si, Ti); + if (Si == Ti) // Ignore self-loops + continue; + // weight = fabs(weight); //Make it positive : Leave it as is + // weight = 1.0; //Make it positive : Leave it as is + edgeListTmp[NE].head = Si; // The S index + edgeListTmp[NE].tail = Ti; // The T index + edgeListTmp[NE].weight = weight; // The value + NE++; + } + fclose(file); // Close the file + printf("Done reading from file.\n"); + printf("|V|= %ld, |E|= %ld \n", NV, NE); + + // Remove duplicate entries: + long NewEdges = removeEdges(NV, NE, edgeListTmp); + if (NewEdges < NE) { + printf("Number of duplicate entries detected: %ld\n", NE - NewEdges); + NE = NewEdges; // Only look at clean edges + } + + // Allocate for Edge Pointer and keep track of degree for each vertex + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); +#pragma omp parallel for + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + __sync_fetch_and_add(&edgeListPtr[edgeListTmp[i].head + 1], 1); // Plus one to take care of the zeroth location + __sync_fetch_and_add(&edgeListPtr[edgeListTmp[i].tail + 1], 1); + } + + //////Build the EdgeListPtr Array: Cumulative addition + time1 = omp_get_wtime(); + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + time2 = omp_get_wtime(); + printf("Done cumulative addition for edgeListPtrs: %9.6lf sec.\n", time2 - time1); + printf("Sanity Check: 2|E| = %ld, edgeListPtr[NV]= %ld\n", NE * 2, edgeListPtr[NV]); + + /*---------------------------------------------------------------------*/ + /* Allocate memory for G & Build it */ + /*---------------------------------------------------------------------*/ + printf("About to allocate memory for graphNew data structures\n"); + time1 = omp_get_wtime(); + edge* edgeList = (edge*)malloc((2 * NE) * sizeof(edge)); // Every edge stored twice + assert(edgeList != 0); + // Keep track of how many edges have been added for a vertex: + long* added = (long*)malloc(NV * sizeof(long)); + assert(added != 0); +#pragma omp parallel for + for (long i = 0; i < NV; i++) added[i] = 0; + time2 = omp_get_wtime(); + printf("Time for allocating memory for edgeList = %lf\n", time2 - time1); + + time1 = omp_get_wtime(); + + printf("About to build edgeList...\n"); +// Build the edgeList from edgeListTmp: +//Multi-threading will lead to a very small difference in the results of each sub_graph +//when the partition algorithm uses bfs in low bandwidth partition method +#ifndef _SINGLE_THREAD_ +#pragma omp parallel for +#endif + for (long i = 0; i < NE; i++) { + long head = edgeListTmp[i].head; + long tail = edgeListTmp[i].tail; + double weight = edgeListTmp[i].weight; + + long Where = edgeListPtr[head] + __sync_fetch_and_add(&added[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + // added[head]++; + // Now add the counter-edge: + Where = edgeListPtr[tail] + __sync_fetch_and_add(&added[tail], 1); + edgeList[Where].head = tail; + edgeList[Where].tail = head; + edgeList[Where].weight = weight; + // added[tail]++; + } + time2 = omp_get_wtime(); + printf("Time for building edgeList = %lf\n", time2 - time1); + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + free(edgeListTmp); + free(added); +} + +/*-------------------------------------------------------* + * This function reads a Pajek file and builds the graphNew + *-------------------------------------------------------*/ +// Assume every edge is stored twice: +void parse_PajekFormatUndirected(graphNew* G, char* fileName) { + printf("Parsing a Pajek File *** Undirected ***...\n"); + int nthreads; +#pragma omp parallel + { nthreads = omp_get_num_threads(); } + printf("parse_Pajek_undirected: Number of threads: %d\n", nthreads); + + double time1, time2; + FILE* file = fopen(fileName, "r"); + if (file == NULL) { + printf("Cannot open the input file: %s\n", fileName); + exit(1); + } + // Parse the first line: + char line[1024]; + fgets(line, 1024, file); + char LS1[25], LS2[25]; + long NV = 0, NE = 0; + if (sscanf(line, "%s %s", LS1, LS2) != 2) { + printf("parse_Pajek(): bad file format - 01"); + exit(1); + } + // printf("(%s) --- (%s) \n", LS1, LS2); + if (strcmp(LS1, "*Vertices") != 0) { + printf("Error: The first line should start with *Vertices word \n"); + exit(1); + } + NV = atol(LS2); + printf("|V|= %ld \n", NV); + /* Ignore all the vertex lines */ + for (long i = 0; i <= NV; i++) { + fgets(line, 1024, file); + } + printf("Done parsing through vertex lines\n"); + if (sscanf(line, "%s", LS1) != 1) { + printf("parse_Pajek(): bad file format - 02"); + exit(1); + } + if (strcmp(LS1, "*Edges") != 0) { + printf("Error: The next line should start with *Edges word \n"); + exit(1); + } + printf("About to read edges -- no weights\n"); + /*---------------------------------------------------------------------*/ + /* Read edge list */ + /* (i , j, value ) 1-based index */ + /*---------------------------------------------------------------------*/ + + edge* edgeListTmp; // Read the data in a temporary list + long Si, Ti; + double weight = 1; + long edgeEstimate = NV * NV / 8; // 12.5% density -- not valid for dense + // graphNews + edgeListTmp = (edge*)malloc(edgeEstimate * sizeof(edge)); + + // while (fscanf(file, "%ld %ld %lf", &Si, &Ti, &weight) != EOF) { + while (fscanf(file, "%ld %ld ", &Si, &Ti) != EOF) { + Si--; + Ti--; // One-based indexing + assert((Si >= 0) && (Si < NV)); + assert((Ti >= 0) && (Ti < NV)); + if (Si == Ti) // Ignore self-loops + continue; + // weight = fabs(weight); //Make it positive : Leave it as is + weight = 1.0; // Make it positive : Leave it as is + edgeListTmp[NE].head = Si; // The S index + edgeListTmp[NE].tail = Ti; // The T index + edgeListTmp[NE].weight = weight; // The value + NE++; + } + fclose(file); // Close the file + printf("Done reading from file.\n"); + printf("|V|= %ld, |E|= %ld \n", NV, NE); + + // Remove duplicate entries: + /* + long NewEdges = removeEdges(NV, NE, edgeListTmp); + if (NewEdges < NE) { + printf("Number of duplicate entries detected: %ld\n", NE-NewEdges); + NE = NewEdges; //Only look at clean edges + } else + printf("No duplicates were found\n"); + */ + + // Allocate for Edge Pointer and keep track of degree for each vertex + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); + assert(edgeListPtr != 0); + +#pragma omp parallel for + for (long i = 0; i <= NV; i++) { + edgeListPtr[i] = 0; // For first touch purposes + } +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + __sync_fetch_and_add(&edgeListPtr[edgeListTmp[i].head + 1], 1); // Plus one to take care of the zeroth location + //__sync_fetch_and_add(&edgeListPtr[edgeListTmp[i].tail + 1], 1); //No need + } + + //////Build the EdgeListPtr Array: Cumulative addition + time1 = omp_get_wtime(); + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + time2 = omp_get_wtime(); + printf("Done cumulative addition for edgeListPtrs: %9.6lf sec.\n", time2 - time1); + printf("Sanity Check: |E| = %ld, edgeListPtr[NV]= %ld\n", NE, edgeListPtr[NV]); + /*---------------------------------------------------------------------*/ + /* Allocate memory for G & Build it */ + /*---------------------------------------------------------------------*/ + time1 = omp_get_wtime(); + printf("Size of edge: %ld and size of NE*edge= %ld\n", sizeof(edge), NE * sizeof(edge)); + edge* edgeList = (edge*)malloc(NE * sizeof(edge)); // Every edge stored twice + assert(edgeList != 0); + // Keep track of how many edges have been added for a vertex: + long* added = (long*)malloc(NV * sizeof(long)); + assert(added != 0); +#pragma omp parallel for + for (long i = 0; i < NV; i++) added[i] = 0; + + time2 = omp_get_wtime(); + printf("Time for allocating memory for edgeList = %lf\n", time2 - time1); + + time1 = omp_get_wtime(); + + printf("About to build edgeList...\n"); +// Build the edgeList from edgeListTmp: +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + long head = edgeListTmp[i].head; + long tail = edgeListTmp[i].tail; + double weight = edgeListTmp[i].weight; + + long Where = edgeListPtr[head] + __sync_fetch_and_add(&added[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + } + time2 = omp_get_wtime(); + printf("Time for building edgeList = %lf\n", time2 - time1); + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE / 2; // Each edge had been presented twice + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + free(edgeListTmp); + free(added); +} + +/*-------------------------------------------------------* + * This function reads a Ppower grid file and builds the graphNew + * First line: <#nodes> <#edges> + * + * Indices are one-based numbers + *-------------------------------------------------------*/ +long* parse_MultiKvPowerGridGraph(graphNew* G, char* fileName) { + printf("Parsing a multi-KV power grid graphNew...\n"); + + double time1, time2; + FILE* file = fopen(fileName, "r"); + if (file == NULL) { + printf("Cannot open the input file: %s\n", fileName); + exit(1); + } + // Parse the first line: + char line[1024]; + fgets(line, 1024, file); + char LS1[25], LS2[25]; + long NV = 0, NE = 0; + if (sscanf(line, "%s %s", LS1, LS2) != 2) { + printf("parse_Pajek(): bad file format - 01"); + exit(1); + } + NV = atol(LS1); + NE = atol(LS2); + NE = NE; // Each edge is stored only once + printf("|V|= %ld, |E|= %ld \n", NV, NE); + /*---------------------------------------------------------------------*/ + /* Read edge list */ + /* (i , j, value, value ) 1-based index */ + /*---------------------------------------------------------------------*/ + long Si, Ti, SiV, TiV; + edge* edgeListTmp = (edge*)malloc(NE * sizeof(edge)); + assert(edgeListTmp != 0); + long* Volts = (long*)malloc(NV * sizeof(long)); + assert(Volts != 0); + for (long i = 0; i < NV; i++) Volts[i] = -1; + long tmpNE = 0; + + double tSiV, tTiV; + while (fscanf(file, "%ld %ld %lf %lf", &Si, &Ti, &tSiV, &tTiV) != EOF) { + // printf("(%ld, %ld) (%ld %ld)\n",Si, Ti, SiV, TiV); + Si--; + Ti--; // One-based indexing + assert((Si >= 0) && (Si < NV)); + assert((Ti >= 0) && (Ti < NV)); + if (Si == Ti) // Ignore self-loops + continue; + // if (Ti < Si) //Each edge is stored twice; so ignore the flip part. + // continue; + SiV = (long)tSiV; // assert(SiV > 0); + TiV = (long)tTiV; // assert(TiV > 0); + edgeListTmp[tmpNE].head = Si; // The S index + edgeListTmp[tmpNE].tail = Ti; // The T index + + if (Volts[Si] == -1) Volts[Si] = SiV; // Volts will get rewritten; correctness assumed. + if (Volts[Ti] == -1) Volts[Ti] = TiV; + if (SiV == TiV) + edgeListTmp[tmpNE].weight = 1; // The value + else + edgeListTmp[tmpNE].weight = 0; // The value + tmpNE++; + } + fclose(file); // Close the file + printf("Done reading from file. (Edge-lines read = %ld)\n", tmpNE); + + // Volts not set correctly -- could be isolated vertices + for (long i = 0; i < NV; i++) { + if (Volts[i] <= 0) { + printf("*** Voltage[%ld] = %ld\n", i, Volts[i]); + Volts[i] = 4000; // Some meaningless number + } + } // End of for(i) + + // Remove duplicate entries: + /* + long NewEdges = removeEdges(NV, tmpNE, edgeListTmp); + if (NewEdges < tmpNE) { + printf("Number of duplicate entries detected: %ld\n", NE-NewEdges); + tmpNE = NewEdges; //Only look at clean edges + } + NE = tmpNE; + */ + + // Allocate for Edge Pointer and keep track of degree for each vertex + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); + + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + + for (long i = 0; i < NE; i++) { + edgeListPtr[edgeListTmp[i].head + 1]++; // Plus one to take care of the zeroth location + edgeListPtr[edgeListTmp[i].tail + 1]++; + } + + //////Build the EdgeListPtr Array: Cumulative addition + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + printf("Sanity Check: 2|E| = %ld, edgeListPtr[NV]= %ld\n", NE * 2, edgeListPtr[NV]); + assert(NE * 2 == edgeListPtr[NV]); + + /*---------------------------------------------------------------------*/ + /* Allocate memory for G & Build it */ + /*---------------------------------------------------------------------*/ + printf("About to allocate memory for graphNew data structures\n"); + time1 = omp_get_wtime(); + edge* edgeList = (edge*)malloc((2 * NE) * sizeof(edge)); // Every edge stored twice + assert(edgeList != 0); + // Keep track of how many edges have been added for a vertex: + long* added = (long*)malloc(NV * sizeof(long)); + assert(added != 0); +#pragma omp parallel for + for (long i = 0; i < NV; i++) added[i] = 0; + time2 = omp_get_wtime(); + printf("Time for allocating memory for edgeList = %lf\n", time2 - time1); + + // Build the edgeList from edgeListTmp: + printf("About to build edgeList...\n"); + time1 = omp_get_wtime(); +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + long head = edgeListTmp[i].head; + long tail = edgeListTmp[i].tail; + double weight = edgeListTmp[i].weight; + + long Where = edgeListPtr[head] + __sync_fetch_and_add(&added[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + // Now add the same edge from the other direction: + Where = edgeListPtr[tail] + __sync_fetch_and_add(&added[tail], 1); + edgeList[Where].head = tail; + edgeList[Where].tail = head; + edgeList[Where].weight = weight; + } + time2 = omp_get_wtime(); + printf("Time for building edgeList = %lf\n", time2 - time1); + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + free(edgeListTmp); + free(added); + + return Volts; +} + +void parse_DoulbedEdgeList(graphNew* G, char* fileName) { + printf("Parsing a DoulbedEdgeList formatted file as a general graphNew...\n"); + printf( + "WARNING: Assumes that the graphNew is undirected -- an edge is stored " + "twince.\n"); + int nthreads = 0; + +#pragma omp parallel + { nthreads = omp_get_num_threads(); } + printf("parse_Dimacs9FormatDirectedNewD: Number of threads: %d\n ", nthreads); + + double time1, time2; + FILE* file = fopen(fileName, "r"); + if (file == NULL) { + printf("Cannot open the input file: %s\n", fileName); + exit(1); + } + + long NV = 2361670, NE = 191402826; + + printf("|V|= %ld, |E|= %ld \n", NV, NE); + printf("Weights will be converted to positive numbers.\n"); + /*---------------------------------------------------------------------*/ + /* Read edge list: a U V W */ + /*---------------------------------------------------------------------*/ + edge* tmpEdgeList = (edge*)malloc(NE * sizeof(edge)); // Every edge stored ONCE + assert(tmpEdgeList != NULL); + long Si, Ti; + // double Twt;//-Wunused-variable + time1 = omp_get_wtime(); + for (long i = 0; i < NE; i++) { + fscanf(file, "%ld %ld", &Si, &Ti); + assert((Si >= 0) && (Si < NV)); + assert((Ti >= 0) && (Ti < NV)); + tmpEdgeList[i].head = Si; // The S index + tmpEdgeList[i].tail = Ti; // The T index: Zero-based indexing + tmpEdgeList[i].weight = 1; // Make it positive and cast to Double + } // End of outer for loop + fclose(file); // Close the file + time2 = omp_get_wtime(); + printf("Done reading from file: NE= %ld. Time= %lf\n", NE, time2 - time1); + + /////////// + time1 = omp_get_wtime(); + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); + assert(edgeListPtr != NULL); + edge* edgeList = (edge*)malloc(NE * sizeof(edge)); // Every edge stored twice + assert(edgeList != NULL); + time2 = omp_get_wtime(); + printf("Time for allocating memory for storing graphNew = %lf\n", time2 - time1); + +#pragma omp parallel for + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + + //////Build the EdgeListPtr Array: Cumulative addition + time1 = omp_get_wtime(); +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + __sync_fetch_and_add(&edgeListPtr[tmpEdgeList[i].head + 1], 1); // Leave 0th position intact + } + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + time2 = omp_get_wtime(); + printf("Done cumulative addition for edgeListPtrs: %9.6lf sec.\n", time2 - time1); + printf("Sanity Check: |E| = %ld, edgeListPtr[NV]= %ld\n", NE, edgeListPtr[NV]); + printf("*********** (%ld)\n", NV); + + // time1 = omp_get_wtime(); + // Keep track of how many edges have been added for a vertex: + printf("About to allocate for added vector: %ld\n", NV); + long* added = (long*)malloc(NV * sizeof(long)); + printf("Done allocating memory fors added vector\n"); + assert(added != NULL); +#pragma omp parallel for + for (long i = 0; i < NV; i++) added[i] = 0; + + printf("About to build edgeList...\n"); +// Build the edgeList from edgeListTmp: +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + long head = tmpEdgeList[i].head; + long tail = tmpEdgeList[i].tail; + double weight = tmpEdgeList[i].weight; + + long Where = edgeListPtr[head] + __sync_fetch_and_add(&added[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + } + // time2 = omp_get_wtime(); + printf("Time for building edgeList = %lf\n", time2 - time1); + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE / 2; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + // Clean up + free(tmpEdgeList); + free(added); + +} // End of parse_Dimacs9FormatDirectedNewD() + +// Binary File Parser: +// Format: Zero-based indices; Every edge stored "TWICE" +// Line 1: #Vertices #Edges +// Line 2: +void parse_EdgeListBinary(graphNew* G, char* fileName) { + printf("Parsing a file in binary format...\n"); + printf( + "WARNING: Assumes that the graphNew is undirected -- every edge is " + "stored twice.\n"); + int nthreads = 0; + +#pragma omp parallel + { nthreads = omp_get_num_threads(); } + printf("parse_Dimacs9FormatDirectedNewD: Number of threads: %d\n ", nthreads); + + double time1, time2; + + std::ifstream ifs; + ifs.open(fileName, std::ifstream::in | std::ifstream::binary); + if (!ifs) { + std::cerr << "Error opening binary format file: " << fileName << std::endl; + exit(EXIT_FAILURE); + } + + long NV, NE; + // Parse line-1: #Vertices #Edges + ifs.read(reinterpret_cast(&NV), sizeof(NV)); + ifs.read(reinterpret_cast(&NE), sizeof(NE)); + + std::cout << "Loading " << fileName << ", |V|: " << NV << ", |E|: " << NE << std::endl; + printf("Weights not stored in the file. All edge weights are set to one.\n"); + /*---------------------------------------------------------------------*/ + /* Read edge list: U V */ + /*---------------------------------------------------------------------*/ + edge* tmpEdgeList = (edge*)malloc(2 * NE * sizeof(edge)); // Every edge stored TWICE + assert(tmpEdgeList != NULL); + + // Read the entire edge list in one shot: + time1 = omp_get_wtime(); + // int64_t *edgeListRaw = new int64_t[2*NE]; assert(edgeListRaw != 0); + long* edgeListRaw = new long[4 * NE]; + assert(edgeListRaw != 0); + // ifs.read(reinterpret_cast(edgeListRaw), sizeof(int64_t) * (2*NE)); + ifs.read(reinterpret_cast(edgeListRaw), sizeof(long) * (4 * NE)); + // Need 2*NE because each edge has two numbers (vertex-1, vertex-2) + ifs.close(); // Close the file + time2 = omp_get_wtime(); + printf("Done reading from file: NE= %ld. Time= %lf\n", NE, time2 - time1); + + // Now parse through the list for edges: + printf("Parsing edges: \n"); + time1 = omp_get_wtime(); + for (long i = 0; i < 2 * NE; i++) { + tmpEdgeList[i].head = edgeListRaw[2 * i]; // each edge has two numbers + tmpEdgeList[i].tail = edgeListRaw[(2 * i) + 1]; + // printf("(%ld, %ld)", tmpEdgeList[i].head, tmpEdgeList[i].tail); + assert(tmpEdgeList[i].head >= 0 && tmpEdgeList[i].head < NV); + assert(tmpEdgeList[i].tail >= 0 && tmpEdgeList[i].tail < NV); + tmpEdgeList[i].weight = 1; // Default value of one + } + delete[] edgeListRaw; + time2 = omp_get_wtime(); + printf("Time for parse through edgelist = %lf\n", time2 - time1); + + /////////// + time1 = omp_get_wtime(); + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); + assert(edgeListPtr != NULL); + edge* edgeList = (edge*)malloc(2 * NE * sizeof(edge)); // Every edge stored twice + assert(edgeList != NULL); + long* added = (long*)malloc(NV * sizeof(long)); + assert(added != NULL); + time2 = omp_get_wtime(); + printf("Time for allocating memory for storing graphNew = %lf\n", time2 - time1); + +#pragma omp parallel for + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + + //////Build the EdgeListPtr Array: Cumulative addition + time1 = omp_get_wtime(); +#pragma omp parallel for + for (long i = 0; i < 2 * NE; i++) { + __sync_fetch_and_add(&edgeListPtr[tmpEdgeList[i].head + 1], 1); // Leave 0th position intact + } + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + time2 = omp_get_wtime(); + printf("Done cumulative addition for edgeListPtrs: %9.6lf sec.\n", time2 - time1); + printf("Sanity Check: |E| = %ld, edgeListPtr[NV]= %ld\n", 2 * NE, edgeListPtr[NV]); + printf("*********** (%ld)\n", NV); + + time1 = omp_get_wtime(); +// Keep track of how many edges have been added for a vertex: +#pragma omp parallel for + for (long i = 0; i < NV; i++) added[i] = 0; + + printf("About to build edgeList...\n"); +// Build the edgeList from edgeListTmp: +#pragma omp parallel for + for (long i = 0; i < 2 * NE; i++) { + long head = tmpEdgeList[i].head; + long tail = tmpEdgeList[i].tail; + double weight = tmpEdgeList[i].weight; + // Add edge head --> tail + long Where = edgeListPtr[head] + __sync_fetch_and_add(&added[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + } + time2 = omp_get_wtime(); + printf("Time for building edgeList = %lf\n", time2 - time1); + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + // Clean up + free(tmpEdgeList); + free(added); + + // displayGraph(G); +} // End of parse_Dimacs9FormatDirectedNewD() + +/* ****************************************** */ +// Loading Functions: +/* NOTE: Indices are ZERO-based, i.e. G(0,0) is the first element, + while the indices stored in the file are ONE-based. +Details: +* A graphNew contains n nodes and m arcs +* Nodes are identified by integers 1...* Graphs can be interpreted as directed +or undirected, depending on the problem being studied +* Graphs can have parallel arcs and self-loops +* Arc weights are signed integers + +** #... : This is a comment +** # Nodes: 65608366 Edges: 1806067135 +** U V : U = from; V = to -- is an edge + +* Assumption: Each edge is stored ONLY ONCE. +*/ +void parse_SNAP(graphNew* G, char* fileName) { + printf("Parsing a SNAP formatted file as a general graphNew...\n"); + printf( + "WARNING: Assumes that the graphNew is directed -- an edge is stored " + "only once.\n"); + printf( + " : Graph will be stored as undirected, each edge appears " + "twice.\n"); + int nthreads = 0; +#pragma omp parallel + { nthreads = omp_get_num_threads(); } + printf("parse_Dimacs9FormatDirectedNewD: Number of threads: %d\n ", nthreads); + + long NV = 0, NE = 0; + string oneLine, myDelimiter(" "), myDelimiter2("\t"), oneWord; // Delimiter is a blank space + // ifstream fin; + char comment; + + double time1, time2; + /* + FILE *file = fopen(fileName, "r"); + if (file == NULL) { + printf("Cannot open the input file: %s\n",fileName); + exit(1); + } + */ + ifstream fin; + fin.open(fileName); + if (!fin) { + cerr << "Within Function: loadMetisFileFormat() \n"; + cerr << "Could not open the file.. \n"; + exit(1); + } + + do { // Parse the comment lines for problem size + getline(fin, oneLine); + cout << "Read line: " << oneLine << endl; + comment = oneLine[0]; + if (comment == '#') { // Check if this line has problem sizes + StringTokenizer* ST = new StringTokenizer(oneLine, myDelimiter); + if (ST->HasMoreTokens()) oneWord = ST->GetNextToken(); // Ignore # + if (ST->HasMoreTokens()) oneWord = ST->GetNextToken(); // Ignore # + if (oneWord == "Nodes:") { + //# Nodes: 65608366 Edges: 1806067135 + NV = atol(ST->GetNextToken().c_str()); // Number of Vertices + oneWord = ST->GetNextToken(); // Ignore Edges: + NE = atol(ST->GetNextToken().c_str()); // Number of Edges + } + delete ST; + } + } while (comment == '#'); + + printf("|V|= %ld, |E|= %ld \n", NV, NE); + printf("Weight of 1 will be assigned to each edge.\n"); + cout << oneLine << endl; + /*---------------------------------------------------------------------*/ + /* Read edge list: a U V W */ + /*---------------------------------------------------------------------*/ + edge* tmpEdgeList = (edge*)malloc(NE * sizeof(edge)); // Every edge stored ONCE + assert(tmpEdgeList != NULL); + long Si, Ti; + + map clusterLocalMap; // Map each neighbor's cluster to a local number + map::iterator storedAlready; + long numUniqueVertices = 0; + + // Parse the first edge already read from the file and stored in oneLine + + long i = 0; + do { + StringTokenizer* ST = new StringTokenizer(oneLine, myDelimiter2); + if (ST->HasMoreTokens()) Si = atol(ST->GetNextToken().c_str()); + if (ST->HasMoreTokens()) Ti = atol(ST->GetNextToken().c_str()); + delete ST; + + storedAlready = clusterLocalMap.find(Si); // Check if it already exists + if (storedAlready != clusterLocalMap.end()) { // Already exists + Si = storedAlready->second; // Renumber the cluster id + } else { + clusterLocalMap[Si] = numUniqueVertices; // Does not exist, add to the map + Si = numUniqueVertices; // Renumber the vertex id + numUniqueVertices++; // Increment the number + } + + storedAlready = clusterLocalMap.find(Ti); // Check if it already exists + if (storedAlready != clusterLocalMap.end()) { // Already exists + Ti = storedAlready->second; // Renumber the cluster id + } else { + clusterLocalMap[Ti] = numUniqueVertices; // Does not exist, add to the map + Ti = numUniqueVertices; // Renumber the vertex id + numUniqueVertices++; // Increment the number + } + tmpEdgeList[i].head = Si; // The S index + tmpEdgeList[i].tail = Ti; // The T index: One-based indexing + tmpEdgeList[i].weight = 1; // default weight of one + // cout<<" Adding edge ("<sVertices = NV; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + // Clean up + free(tmpEdgeList); + free(added); + +} // End of parse_Dimacs9FormatDirectedNewD() diff --git a/graph/L3/graphPartition/grappolo/src/parseInputParameters.cpp b/graph/L3/graphPartition/grappolo/src/parseInputParameters.cpp new file mode 100755 index 0000000000..eb8dff8997 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/parseInputParameters.cpp @@ -0,0 +1,192 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "defs.h" + +using namespace std; + +clustering_parameters::clustering_parameters() + : ftype(1), + strongScaling(false), + output(false), + VF(false), + coloring(false), + C_thresh(0.0001), + minGraphSize(100000), + threshold(0.000001) {} + +void clustering_parameters::usage() { + cout << "********************************************************************" + "*******************" + << endl; + cout << "Basic usage: Driver FileName\n"; + cout << "********************************************************************" + "*******************" + << endl; + cout << "Input Options: \n"; + cout << "********************************************************************" + "*******************" + << endl; + cout << "File-type : -f <1-8> -- default=7" << endl; + cout << "File-Type : (1) Matrix-Market (2) DIMACS#9 (3) Pajek (each edge " + "once) (4) Pajek (twice) \n"; + cout << " : (5) Metis (DIMACS#10) (6) Simple edge list twice (7) " + "Binary format (8) SNAP\n"; + cout << "--------------------------------------------------------------------" + "------------------" + << endl; + cout << "Strong scaling : -s -- default=false" << endl; + cout << "VF : -v -- default=false" << endl; + cout << "Output : -o -- default=false" << endl; + cout << "Coloring : -c -- default=false" << endl; + cout << "--------------------------------------------------------------------" + "------------------" + << endl; + cout << "Min-size : -m -- default=100000" << endl; + cout << "C-threshold : -d -- default=0.01" << endl; + cout << "Threshold : -t -- default=0.000001" << endl; + cout << "********************************************************************" + "*******************" + << endl; +} // end of usage() + +bool clustering_parameters::parse(int argc, char* argv[]) { + static const char* opt_string = "x:csvof:t:d:m:"; + int opt = getopt(argc, argv, opt_string); + while (opt != -1) { + switch (opt) { + case 'x': + xclbin = optarg; + break; + case 'c': + coloring = true; + break; + case 's': + strongScaling = true; + break; + case 'v': + VF = true; + break; + case 'o': + output = true; + break; + + case 'f': + ftype = atoi(optarg); + if ((ftype > 8) || (ftype < 0)) { + cout << "ftype must be an integer between 1 to 6" << endl; + return false; + } + break; + + case 't': + threshold = atof(optarg); + if (threshold < 0.0) { + cout << "Threshold must be non-negative" << endl; + return false; + } + break; + + case 'd': + C_thresh = atof(optarg); + if (C_thresh < 0.0) { + cout << "Threshold must be non-negative" << endl; + return false; + } + break; + + case 'm': + minGraphSize = atol(optarg); + if (minGraphSize < 0) { + cout << "minGraphSize must be non-negative" << endl; + return false; + } + break; + + default: + cerr << "unknown argument" << endl; + return false; + } + opt = getopt(argc, argv, opt_string); + } + + if (argc - optind != 1) { + cout << "Problem name not specified. Exiting." << endl; + usage(); + return false; + } else { + inFile = argv[optind]; + } + +#ifdef PRINT_DETAILED_STATS_ + cout << "********************************************" << endl; + cout << "Input Parameters: \n"; + cout << "********************************************" << endl; +#ifndef HLS_TEST + cout << "Xclbin File: " << xclbin << endl; +#endif + cout << "Input File: " << inFile << endl; + cout << "File type : " << ftype << endl; + cout << "Threshold : " << threshold << endl; + cout << "C-threshold: " << C_thresh << endl; + cout << "Min-size : " << minGraphSize << endl; + cout << "--------------------------------------------" << endl; + if (coloring) + cout << "Coloring : TRUE" << endl; + else + cout << "Coloring : FALSE" << endl; + if (strongScaling) + cout << "Strong scaling : TRUE" << endl; + else + cout << "Strong scaling : FALSE" << endl; + if (VF) + cout << "VF : TRUE" << endl; + else + cout << "VF : FALSE" << endl; + if (output) + cout << "Output : TRUE" << endl; + else + cout << "Output : FALSE" << endl; + cout << "********************************************" << endl; +#endif + + return true; +} diff --git a/graph/L3/graphPartition/grappolo/src/utilityClusteringFunctions.cpp b/graph/L3/graphPartition/grappolo/src/utilityClusteringFunctions.cpp new file mode 100755 index 0000000000..d5377a13d0 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/utilityClusteringFunctions.cpp @@ -0,0 +1,151 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "utilityClusteringFunctions.h" + +using namespace std; + +void sumVertexDegree(edge* vtxInd, long* vtxPtr, long* vDegree, long NV, Comm* cInfo) { +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + long adj1 = vtxPtr[i]; // Begining + long adj2 = vtxPtr[i + 1]; // End + long totalWt = 0; + for (long j = adj1; j < adj2; j++) { + totalWt += (long)vtxInd[j].weight; + } + vDegree[i] = totalWt; // Degree of each node + cInfo[i].degree = totalWt; // Initialize the community + cInfo[i].size = 1; + } +} // End of sumVertexDegree() + +double calConstantForSecondTerm(long* vDegree, long NV) { + long totalEdgeWeightTwice = 0; +#pragma omp parallel + { + long localWeight = 0; +#pragma omp for + for (long i = 0; i < NV; i++) { + localWeight += vDegree[i]; + } +#pragma omp critical + { + totalEdgeWeightTwice += localWeight; // Update the global weight + } + } // End of parallel region + + return 1 / (double)totalEdgeWeightTwice; +} // End of calConstantForSecondTerm() + +void initCommAss(long* pastCommAss, long* currCommAss, long NV) { +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + pastCommAss[i] = i; // Initialize each vertex to its cluster + currCommAss[i] = i; + } +} // End of initCommAss() + +long buildLocalMapCounter(long adj1, + long adj2, + map& clusterLocalMap, + vector& Counter, + edge* vtxInd, + long* currCommAss, + long me) { + map::iterator storedAlready; + long numUniqueClusters = 1; + long selfLoop = 0; + for (long j = adj1; j < adj2; j++) { + if (vtxInd[j].tail == me) { // SelfLoop need to be recorded + selfLoop += (long)vtxInd[j].weight; + } + + storedAlready = clusterLocalMap.find(currCommAss[vtxInd[j].tail]); // Check if it already exists + if (storedAlready != clusterLocalMap.end()) { // Already exists + Counter[storedAlready->second] += vtxInd[j].weight; // Increment the counter with weight + } else { + clusterLocalMap[currCommAss[vtxInd[j].tail]] = numUniqueClusters; // Does not exist, add to the map + Counter.push_back(vtxInd[j].weight); // Initialize the count + numUniqueClusters++; + } + } // End of for(j) + + return selfLoop; +} // End of buildLocalMapCounter() + +long max(map& clusterLocalMap, + vector& Counter, + long selfLoop, + Comm* cInfo, + long degree, + long sc, + double constant) { + map::iterator storedAlready; + long maxIndex = sc; // Assign the initial value as self community + double curGain = 0; + double maxGain = 0; + double eix = Counter[0] - selfLoop; + double ax = cInfo[sc].degree - degree; + double eiy = 0; + double ay = 0; + + storedAlready = clusterLocalMap.begin(); + do { + if (sc != storedAlready->first) { + ay = cInfo[storedAlready->first].degree; // degree of cluster y + eiy = Counter[storedAlready->second]; // Total edges incident on cluster y + curGain = 2 * (eiy - eix) - 2 * degree * (ay - ax) * constant; + + if ((curGain > maxGain) || ((curGain == maxGain) && (curGain != 0) && (storedAlready->first < maxIndex))) { + maxGain = curGain; + maxIndex = storedAlready->first; + } + } + storedAlready++; // Go to the next cluster + } while (storedAlready != clusterLocalMap.end()); + + if (cInfo[maxIndex].size == 1 && cInfo[sc].size == 1 && maxIndex > sc) { // Swap protection + maxIndex = sc; + } + + return maxIndex; +} // End max() diff --git a/graph/L3/graphPartition/grappolo/src/utilityFunctions.cpp b/graph/L3/graphPartition/grappolo/src/utilityFunctions.cpp new file mode 100755 index 0000000000..11749080c5 --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/utilityFunctions.cpp @@ -0,0 +1,185 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "RngStream.h" +#include "defs.h" + +using namespace std; + +void generateRandomNumbers(double* RandVec, long size) { + int nT; +#pragma omp parallel + { nT = omp_get_num_threads(); } +#ifdef PRINT_DETAILED_STATS_ + printf("Within generateRandomNumbers() -- Number of threads: %d\n", nT); +#endif + // Initialize parallel pseudo-random number generator + unsigned long seed[6] = {1, 2, 3, 4, 5, 6}; + RngStream::SetPackageSeed(seed); + RngStream RngArray[nT]; // array of RngStream Objects + + long block = size / nT; +#ifdef PRINT_DETAILED_STATS_ + cout << "Each thread will add " << block << " edges\n"; +#endif +// Each thread will generate m/nT edges each +// double start = omp_get_wtime();// unused variable ‘start’ +#pragma omp parallel + { + int myRank = omp_get_thread_num(); +#pragma omp for schedule(static) + for (long i = 0; i < size; i++) { + RandVec[i] = RngArray[myRank].RandU01(); + } + } // End of parallel region +} // End of generateRandomNumbers() + +void displayGraphCharacteristics(graphNew* G) { + printf("Within displayGraphCharacteristics()\n"); + long sum = 0, sum_sq = 0; + double average, avg_sq, variance, std_dev; + long maxDegree = 0; + long isolated = 0; + long degreeOne = 0; + long NS = G->sVertices; + long NV = G->numVertices; + long NT = NV - NS; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + long tNV = NV; // Number of vertices + + if ((NS == 0) || (NS == NV)) { // Nonbiparite graphNew + for (long i = 0; i < NV; i++) { + long degree = vtxPtr[i + 1] - vtxPtr[i]; + sum_sq += degree * degree; + sum += degree; + if (degree > maxDegree) maxDegree = degree; + if (degree == 0) isolated++; + if (degree == 1) degreeOne++; + } + average = (double)sum / tNV; + avg_sq = (double)sum_sq / tNV; + variance = avg_sq - (average * average); + std_dev = sqrt(variance); + + printf("*******************************************\n"); + printf("General Graph: Characteristics :\n"); + printf("*******************************************\n"); + printf("Number of vertices : %ld\n", NV); + printf("Number of edges : %ld\n", NE); + printf("Maximum out-degree is: %ld\n", maxDegree); + printf("Average out-degree is: %lf\n", average); + printf("Expected value of X^2: %lf\n", avg_sq); + printf("Variance is : %lf\n", variance); + printf("Standard deviation : %lf\n", std_dev); + printf("Isolated vertices : %ld (%3.2lf%%)\n", isolated, ((double)isolated / tNV) * 100); + printf("Degree-one vertices : %ld (%3.2lf%%)\n", degreeOne, ((double)degreeOne / tNV) * 100); + printf("Density : %lf%%\n", ((double)NE / (NV * NV)) * 100); + printf("*******************************************\n"); + + } // End of nonbipartite graphNew + else { // Bipartite graphNew + + // Compute characterisitcs from S side: + for (long i = 0; i < NS; i++) { + long degree = vtxPtr[i + 1] - vtxPtr[i]; + sum_sq += degree * degree; + sum += degree; + if (degree > maxDegree) maxDegree = degree; + if (degree == 0) isolated++; + if (degree == 1) degreeOne++; + } + average = (double)sum / NS; + avg_sq = (double)sum_sq / NS; + variance = avg_sq - (average * average); + std_dev = sqrt(variance); + + printf("*******************************************\n"); + printf("Bipartite Graph: Characteristics of S:\n"); + printf("*******************************************\n"); + printf("Number of S vertices : %ld\n", NS); + printf("Number of T vertices : %ld\n", NT); + printf("Number of edges : %ld\n", NE); + printf("Maximum out-degree is: %ld\n", maxDegree); + printf("Average out-degree is: %lf\n", average); + printf("Expected value of X^2: %lf\n", avg_sq); + printf("Variance is : %lf\n", variance); + printf("Standard deviation : %lf\n", std_dev); + printf("Isolated (S)vertices : %ld (%3.2lf%%)\n", isolated, ((double)isolated / NS) * 100); + printf("Degree-one vertices : %ld (%3.2lf%%)\n", degreeOne, ((double)degreeOne / tNV) * 100); + printf("Density : %lf%%\n", ((double)NE / (NS * NS)) * 100); + printf("*******************************************\n"); + + sum = 0; + sum_sq = 0; + maxDegree = 0; + isolated = 0; + // Compute characterisitcs from T side: + for (long i = NS; i < NV; i++) { + long degree = vtxPtr[i + 1] - vtxPtr[i]; + sum_sq += degree * degree; + sum += degree; + if (degree > maxDegree) maxDegree = degree; + if (degree == 0) isolated++; + if (degree == 1) degreeOne++; + } + + average = (double)sum / NT; + avg_sq = (double)sum_sq / NT; + variance = avg_sq - (average * average); + std_dev = sqrt(variance); + + printf("Bipartite Graph: Characteristics of T:\n"); + printf("*******************************************\n"); + printf("Number of T vertices : %ld\n", NT); + printf("Number of S vertices : %ld\n", NS); + printf("Number of edges : %ld\n", NE); + printf("Maximum out-degree is: %ld\n", maxDegree); + printf("Average out-degree is: %lf\n", average); + printf("Expected value of X^2: %lf\n", avg_sq); + printf("Variance is : %lf\n", variance); + printf("Standard deviation : %lf\n", std_dev); + printf("Isolated (T)vertices : %ld (%3.2lf%%)\n", isolated, ((double)isolated / NT) * 100); + printf("Degree-one vertices : %ld (%3.2lf%%)\n", degreeOne, ((double)degreeOne / tNV) * 100); + printf("Density : %lf%%\n", ((double)NE / (NT * NT)) * 100); + printf("*******************************************\n"); + } // End of bipartite graphNew +} diff --git a/graph/L3/graphPartition/grappolo/src/vertexFollowing.cpp b/graph/L3/graphPartition/grappolo/src/vertexFollowing.cpp new file mode 100755 index 0000000000..22ebbc033d --- /dev/null +++ b/graph/L3/graphPartition/grappolo/src/vertexFollowing.cpp @@ -0,0 +1,253 @@ +// *********************************************************************** +// +// Grappolo: A C++ library for graph clustering +// Mahantesh Halappanavar (hala@pnnl.gov) +// Pacific Northwest National Laboratory +// +// *********************************************************************** +// +// Copyright (2014) Battelle Memorial Institute +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ************************************************************************ + +#include "defs.h" + +using namespace std; + +long vertexFollowing(graphNew* G, long* C) { + long NV = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + long numNode = 0; + double time1 = omp_get_wtime(); +// Initialize the Communities +#pragma omp parallel for // Parallelize on the outer most loop + for (long i = 0; i < NV; i++) { + C[i] = i; // Initialize each vertex to its own cluster + } + +// Remove Isolated and degree-one vertices +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + long adj1 = vtxPtr[i]; + long adj2 = vtxPtr[i + 1]; + if (adj1 == adj2) { // Isolated vertex + __sync_fetch_and_add(&numNode, 1); + C[i] = -1; + } else { + if ((adj2 - adj1) == 1) { // Degree one + // Check if the tail has degree greater than one: + long tail = vtxInd[adj1].tail; + long adj11 = vtxPtr[tail]; + long adj12 = vtxPtr[tail + 1]; + if (((adj12 - adj11) > 1) || (i > tail)) { // Degree of tail greater than one + __sync_fetch_and_add(&numNode, 1); + C[i] = tail; + } // else don't do anything + } // End of if(degree one) + } // End of else + } // End of for(i) + + time1 = omp_get_wtime() - time1; +#ifdef PRINT_DETAILED_STATS_ + printf("Time to determine number of vertices (numNode) to fix: %lf\n", time1); +#endif + return numNode; // These are nodes that need to be removed +} // End of vertexFollowing() + +// WARNING: Will assume that the cluster id have been renumbered contiguously +// Return the total time for building the next level of graphNew +// This will not add any self-loops +double buildNewGraphVF(graphNew* Gin, graphNew* Gout, long* C, long numUniqueClusters) { +#ifdef PRINT_DETAILED_STATS_ + int nT; +#pragma omp parallel + { nT = omp_get_num_threads(); } + printf("Within buildNewGraphVF(): # of unique clusters= %ld\n", numUniqueClusters); + printf("Actual number of threads: %d \n", nT); +#endif + + double time1, time2, TotTime = 0; // For timing purposes + // double total = 0, totItr = 0; //-Wunused-variable + // Pointers into the input graphNew structure: + long NV_in = Gin->numVertices; + // long NE_in = Gin->numEdges;//-Wunused-variable + long* vtxPtrIn = Gin->edgeListPtrs; + edge* vtxIndIn = Gin->edgeList; + + time1 = omp_get_wtime(); + // Pointers into the output graphNew structure + long NV_out = numUniqueClusters; + long NE_self = 0; // Not all vertices get self-loops + long NE_out = 0; // Cross edges + long* vtxPtrOut = (long*)malloc((NV_out + 1) * sizeof(long)); + assert(vtxPtrOut != 0); + vtxPtrOut[0] = 0; // First location is always a zero + /* Step 1 : Regroup the node into cluster node */ + map** cluPtrIn = (map**)malloc(numUniqueClusters * sizeof(map*)); + assert(cluPtrIn != 0); + +#pragma omp parallel for + for (long i = 0; i < numUniqueClusters; i++) { + cluPtrIn[i] = new map(); + // Do not add self-loops + //(*(cluPtrIn[i]))[i] = 0; //Add for a self loop with zero weight + } +#pragma omp parallel for + for (long i = 1; i <= NV_out; i++) vtxPtrOut[i] = 0; + + // Create an array of locks for each cluster + omp_lock_t* nlocks = (omp_lock_t*)malloc(numUniqueClusters * sizeof(omp_lock_t)); + assert(nlocks != 0); +#pragma omp parallel for + for (long i = 0; i < numUniqueClusters; i++) { + omp_init_lock(&nlocks[i]); // Initialize locks + } + time2 = omp_get_wtime(); + TotTime += (time2 - time1); +#ifdef PRINT_DETAILED_STATS_ + printf("Time to initialize: %3.3lf\n", time2 - time1); +#endif + time1 = omp_get_wtime(); +#pragma omp parallel for + for (long i = 0; i < NV_in; i++) { + if ((C[i] < 0) || (C[i] > numUniqueClusters)) continue; // Not a valid cluster id + long adj1 = vtxPtrIn[i]; + long adj2 = vtxPtrIn[i + 1]; + map::iterator localIterator; + assert(C[i] < numUniqueClusters); + // Now look for all the neighbors of this cluster + for (long j = adj1; j < adj2; j++) { + long tail = vtxIndIn[j].tail; + assert(C[tail] < numUniqueClusters); + // Add the edge from one endpoint + if (C[i] >= C[tail]) { + omp_set_lock(&nlocks[C[i]]); // Locking the cluster + + localIterator = cluPtrIn[C[i]]->find(C[tail]); // Check if it exists + if (localIterator != cluPtrIn[C[i]]->end()) { // Already exists + localIterator->second += (long)vtxIndIn[j].weight; + } else { + (*(cluPtrIn[C[i]]))[C[tail]] = (long)vtxIndIn[j].weight; // Self-edge + __sync_fetch_and_add(&vtxPtrOut[C[i] + 1], 1); + if (C[i] == C[tail]) __sync_fetch_and_add(&NE_self, 1); // Keep track of self #edges + if (C[i] > C[tail]) { + __sync_fetch_and_add(&NE_out, 1); // Keep track of non-self #edges + __sync_fetch_and_add(&vtxPtrOut[C[tail] + 1], 1); // Count edge + // j-->i + } + } + + omp_unset_lock(&nlocks[C[i]]); // Unlocking the cluster + } // End of if + } // End of for(j) + } // End of for(i) + // Prefix sum: + for (long i = 0; i < NV_out; i++) { + vtxPtrOut[i + 1] += vtxPtrOut[i]; + } + + time2 = omp_get_wtime(); + TotTime += (time2 - time1); + printf("NE_out= %ld NE_self= %ld\n", NE_out, NE_self); + printf("These should match: %ld == %ld\n", (2 * NE_out + NE_self), vtxPtrOut[NV_out]); + std::cout << "123456" << std::endl; +#ifdef PRINT_DETAILED_STATS_ + printf("Time to count edges: %3.3lf\n", time2 - time1); +#endif + assert(vtxPtrOut[NV_out] == (NE_out * 2 + NE_self)); // Sanity check + + time1 = omp_get_wtime(); + // Step 3 : build the edge list: + long numEdges = vtxPtrOut[NV_out]; + long realEdges = NE_out + NE_self; // Self-loops appear once, others appear twice + edge* vtxIndOut = (edge*)malloc(numEdges * sizeof(edge)); + assert(vtxIndOut != 0); + long* Added = (long*)malloc(NV_out * sizeof(long)); // Keep track of what got added + assert(Added != 0); + +#pragma omp parallel for + for (long i = 0; i < NV_out; i++) { + Added[i] = 0; + } +// Now add the edges in no particular order +#pragma omp parallel for + for (long i = 0; i < NV_out; i++) { + long Where; + map::iterator localIterator = cluPtrIn[i]->begin(); + // Now go through the other edges: + while (localIterator != cluPtrIn[i]->end()) { + Where = vtxPtrOut[i] + __sync_fetch_and_add(&Added[i], 1); + vtxIndOut[Where].head = i; // Head + vtxIndOut[Where].tail = localIterator->first; // Tail + vtxIndOut[Where].weight = localIterator->second; // Weight + if (i != localIterator->first) { + Where = vtxPtrOut[localIterator->first] + __sync_fetch_and_add(&Added[localIterator->first], 1); + vtxIndOut[Where].head = localIterator->first; + vtxIndOut[Where].tail = i; // Tail + vtxIndOut[Where].weight = localIterator->second; // Weight + // printf("%d\n",localIterator->first); + } + localIterator++; + } + } // End of for(i) + time2 = omp_get_wtime(); + TotTime += (time2 - time1); +#ifdef PRINT_DETAILED_STATS_ + printf("Time to build the graphNew: %3.3lf\n", time2 - time1); + printf("Total time: %3.3lf\n", TotTime); +#endif +#ifdef PRINT_TERSE_STATS_ + printf("Total time to build next phase: %3.3lf\n", TotTime); +#endif + // Set the pointers + Gout->numVertices = NV_out; + Gout->sVertices = NV_out; + // Note: Self-loops are represented ONCE, but others appear TWICE + Gout->numEdges = realEdges; // Add self loops to the #edges + Gout->edgeListPtrs = vtxPtrOut; + Gout->edgeList = vtxIndOut; + + // Clean up + free(Added); +#pragma omp parallel for + for (long i = 0; i < numUniqueClusters; i++) delete cluPtrIn[i]; + free(cluPtrIn); + +#pragma omp parallel for + for (long i = 0; i < numUniqueClusters; i++) { + omp_destroy_lock(&nlocks[i]); + } + free(nlocks); + + return TotTime; +} // End of buildNextLevelGraph2() diff --git a/graph/L3/graphPartition/louvainPartition/ParLV.cpp b/graph/L3/graphPartition/louvainPartition/ParLV.cpp new file mode 100644 index 0000000000..66108b43d4 --- /dev/null +++ b/graph/L3/graphPartition/louvainPartition/ParLV.cpp @@ -0,0 +1,2373 @@ +/* + * Copyright 2019-2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +#include +#include +#include + +#include "defs.h" +#include "ParLV.h" +#include "partitionLouvain.hpp" + +// set default global max values for U50 +long glb_MAXNV = (1ul << 26); +long glb_MAXNE = (1 << 27); +long glb_MAXNV_M = (1 << 27); + +using namespace std; + +// time functions + +typedef std::chrono::time_point TimePointType; + +double getTime() { + TimePointType t1 = chrono::high_resolution_clock::now(); + chrono::duration l_durationSec = chrono::duration(t1.time_since_epoch()); + return l_durationSec.count(); +} + +// time functions end + +// load/send GLV through data files +int SaveGLVBin(char* name, GLV* glv) { + assert(name); + assert(glv); + graphNew* g = glv->G; + long nv = g->numVertices; + long ne = g->numEdges; + long ne_undir = g->edgeListPtrs[nv]; + long nc = glv->NC; + double Q = glv->Q; + long nvl = glv->NVl; + long nelg = glv->NElg; + FILE* fp = fopen(name, "wb"); + if (fp == NULL) { + printf("ERROR: SaveGLVBin failed to open %s \n", name); + return -1; + } + fwrite(&headGLVBin, sizeof(long), 1, fp); + fwrite(&nv, sizeof(long), 1, fp); + fwrite(&ne, sizeof(long), 1, fp); + fwrite(&ne_undir, sizeof(long), 1, fp); + fwrite(&nc, sizeof(long), 1, fp); + fwrite(&Q, sizeof(double), 1, fp); + fwrite(&nvl, sizeof(long), 1, fp); + fwrite(&nelg, sizeof(long), 1, fp); + fwrite(g->edgeListPtrs, sizeof(long), nv + 1, fp); + fwrite(g->edgeList, sizeof(edge), ne_undir, fp); + fwrite(glv->M, sizeof(long), nv, fp); + fwrite(glv->C, sizeof(long), nv, fp); + fclose(fp); +#ifdef PRINTINFO + printf("INFO: SaveGLVBin %s Successfully nv=%ld ne=%ld undir ne=%ld nc=%ld Q=%lf \n", name, nv, ne, ne_undir, nc, + Q); +#endif + + return 0; +} + +long UseInt(long nv, long* src, FILE* fp) { + int* tmp = (int*)malloc(sizeof(int) * nv); + for (int i = 0; i < nv; i++) tmp[i] = src[i]; + long ret = fwrite(tmp, sizeof(int), nv, fp); + free(tmp); + + return ret; +} + +int SaveGLVBin(char* name, GLV* glv, bool useInt) { +#ifndef NDEBUG + std::cout << "DEBUG:" << __FUNCTION__ << " name=" << name << std::endl; +#endif + assert(name); + assert(glv); + graphNew* g = glv->G; + long nv = g->numVertices; + long ne = g->numEdges; + long ne_undir = g->edgeListPtrs[nv]; + long nc = glv->NC; + double Q = glv->Q; + long nvl = glv->NVl; + long nelg = glv->NElg; + FILE* fp = fopen(name, "wb"); + if (fp == NULL) { + printf("ERROR: SaveGLVBin failed to open %s \n", name); + return -1; + } + fwrite(&headGLVBin, sizeof(long), 1, fp); + fwrite(&nv, sizeof(long), 1, fp); + fwrite(&ne, sizeof(long), 1, fp); + fwrite(&ne_undir, sizeof(long), 1, fp); + fwrite(&nc, sizeof(long), 1, fp); + fwrite(&Q, sizeof(double), 1, fp); + fwrite(&nvl, sizeof(long), 1, fp); + fwrite(&nelg, sizeof(long), 1, fp); + fwrite(g->edgeListPtrs, sizeof(long), nv + 1, fp); + fwrite(g->edgeList, sizeof(edge), ne_undir, fp); + fwrite(glv->M, sizeof(long), nv, fp); + fwrite(glv->C, sizeof(long), nv, fp); + fclose(fp); +#ifdef PRINTINFO + printf("INFO: SaveGLVBin %s Successfully nv=%ld ne=%ld undir ne=%ld nc=%ld Q=%lf \n", name, nv, ne, ne_undir, nc, + Q); +#endif + return 0; +} +int SaveGLVBin_OnlyC(char* name, GLV* glv, bool useInt) { + assert(name); + assert(glv); + graphNew* g = glv->G; + long nv = g->numVertices; + long nc = glv->NC; + double Q = glv->Q; + long nvl = glv->NVl; + long nelg = glv->NElg; + FILE* fp = fopen(name, "wb"); + if (fp == NULL) { + printf("ERROR: SaveGLVBin_OnlyC failed for open %s \n", name); + return -1; + } + fwrite(&headGLVBin, sizeof(long), 1, fp); + fwrite(&nv, sizeof(long), 1, fp); + fwrite(&nc, sizeof(long), 1, fp); + fwrite(&Q, sizeof(double), 1, fp); + fwrite(&nvl, sizeof(long), 1, fp); + fwrite(&nelg, sizeof(long), 1, fp); + if (useInt) { + int* tmp = (int*)malloc(sizeof(int) * nv); + for (int i = 0; i < nv; i++) tmp[i] = glv->C[i]; + fwrite(tmp, sizeof(int), nv, fp); + free(tmp); + } else + fwrite(glv->C, sizeof(long), nv, fp); + fclose(fp); +#ifdef PRINTINFO + printf("INFO: SaveGLVBin_OnlyC %s nv=%ld nc=%ld Q=%lf Successfully \n", name, nv, nc, Q); +#endif + return 0; +} +int SaveGLVBin_OnlyC(char* name, GLV* glv) { + assert(name); + assert(glv); + graphNew* g = glv->G; + long nv = g->numVertices; + long nc = glv->NC; + double Q = glv->Q; + long nvl = glv->NVl; + long nelg = glv->NElg; + FILE* fp = fopen(name, "wb"); + if (fp == NULL) { + printf("ERROR: SaveGLVBin_OnlyC failed for open %s \n", name); + return -1; + } + fwrite(&headGLVBin, sizeof(long), 1, fp); + fwrite(&nv, sizeof(long), 1, fp); + fwrite(&nc, sizeof(long), 1, fp); + fwrite(&Q, sizeof(double), 1, fp); + fwrite(&nvl, sizeof(long), 1, fp); + fwrite(&nelg, sizeof(long), 1, fp); + fwrite(glv->C, sizeof(long), nv, fp); + fclose(fp); +#ifdef PRINTINFO + printf("INFO: SaveGLVBin_OnlyC %s nv=%ld nc=%ld Q=%lf Successfully \n", name, nv, nc, Q); +#endif + return 0; +} + +int SaveGLVBinBatch(GLV* glv[], int num_par, const char* path, bool useInt) { + assert(glv); + assert(num_par < MAX_PARTITION); + int ret = 0; + for (int i = 0; i < num_par; i++) { + char pathName[1024]; + if (strlen(path)) { + strcpy(pathName, path); + strcat(pathName, "/"); + } else + strcpy(pathName, "./"); + strcat(pathName, glv[i]->name); + ret += SaveGLVBin(pathName, glv[i], useInt); + } + return ret; +} + +int SaveGLVBinBatch_OnlyC(GLV* glv[], int num_par, const char* path) { + assert(glv); + assert(num_par < MAX_PARTITION); + int ret = 0; + for (int i = 0; i < num_par; i++) { + char pathName[1024]; + if (strlen(path)) { + strcpy(pathName, path); + strcat(pathName, "/"); + } else + strcpy(pathName, "./"); + strcat(pathName, glv[i]->name); + ret += SaveGLVBin_OnlyC(pathName, glv[i]); + } + return ret; +} + +// functions for printing info or read command lines +int general_findPara(int argc, char** argv, const char* para) { + for (int i = 1; i < argc; i++) { + if (0 == strcmp(argv[i], para)) return i; + } + return -1; +} +void ParameterError(const char* msg) { + printf("\033[1;31;40mPARAMETER ERROR\033[0m: %s \n", msg); + exit(1); +} + +int host_ParserParameters(int argc, + char** argv, + double& opts_C_thresh, // Threshold with coloring on + long& opts_minGraphSize, // Min |V| to enable coloring + double& opts_threshold, // Value of threshold + int& opts_ftype, // File type + char opts_inFile[4096], // + bool& opts_coloring, // + bool& opts_output, // + std::string& opts_outputFile, + bool& opts_VF, //; + std::string& xclbinFile, // Full path including filename to the xclbin files to be loaded + std::string& deviceNames, // Target device names + int& numThread, + int& numPars, + // bool& BFS_partition, + int& gh_par, + int& kernelMode, + int& numDevices, + int& mode_zmq, + char* path_zmq, + bool& useCmd, + int& mode_alveo, + char* nameProj, + std::string& nameMetaFile, + int& numPureWorker, + char* nameWorkers[128], + int& nodeID, + int& numNodes, + int& max_num_level, + int& max_num_iter) { + const int max_parameter = 100; + bool rec[max_parameter]; + for (int i = 1; i < argc; i++) rec[i] = false; + int has_opts_C_thresh = general_findPara(argc, argv, "-d"); + int has_opts_minGraphSize = general_findPara(argc, argv, "-m"); + int has_opts_threshold = general_findPara(argc, argv, "-t"); + int has_opts_ftype = general_findPara(argc, argv, "-f"); + int has_opts_inFile; //= general_findPara(argc, argv, "-thread"); + int has_opts_coloring = general_findPara(argc, argv, "-c"); + int has_opts_output = general_findPara(argc, argv, "-o"); + int has_opts_VF = general_findPara(argc, argv, "-v"); + int hasXclbinPath = general_findPara(argc, argv, "-x"); + int hasDeviceNames = general_findPara(argc, argv, "-devices"); + int has_numThread = general_findPara(argc, argv, "-thread"); + int hasNumPars = general_findPara(argc, argv, "-num_pars"); + int has_gh_par = general_findPara(argc, argv, "-par_prune"); + int hasKernelMode = general_findPara(argc, argv, "-kernel_mode"); + int hasNumDevices = general_findPara(argc, argv, "-num_devices"); + int hasNumCu = general_findPara(argc, argv, "-num_cu"); + int has_driver = general_findPara(argc, argv, "-driver"); + int has_worker = general_findPara(argc, argv, "-worker"); + int has_driverAlone = general_findPara(argc, argv, "-driverAlone"); + int has_workerAlone = general_findPara(argc, argv, "-workerAlone"); + int has_cmd = general_findPara(argc, argv, "-cmd"); + int hasNumNodes = general_findPara(argc, argv, "-num_nodes"); + int has_max_num_level = general_findPara(argc, argv, "-num_level"); + int has_max_num_iter = general_findPara(argc, argv, "-num_iter"); + + if (general_findPara(argc, argv, "-create_alveo_partitions") != -1) { + mode_alveo = ALVEOAPI_PARTITION; + // BFS_partition = false; + int indx = general_findPara(argc, argv, "-name"); + if (argc > indx && indx != -1) strcpy(nameProj, argv[indx + 1]); + } else if (general_findPara(argc, argv, "-create_alveo_BFS_partitions") != -1) { + mode_alveo = ALVEOAPI_PARTITION_BFS; + // BFS_partition = true; + int indx = general_findPara(argc, argv, "-name"); + if (argc > indx && indx != -1) strcpy(nameProj, argv[indx + 1]); + } else if (general_findPara(argc, argv, "-load_alveo_partitions") != -1) { + int indx = general_findPara(argc, argv, "-load_alveo_partitions") + 1; + mode_alveo = ALVEOAPI_LOAD; + if (argc > indx) + nameMetaFile = argv[indx]; + else { + printf("\033[1;31;40mPARAMETER ERROR\033[0m: -load_alveo_partitions \n"); + return -1; + } + if (general_findPara(argc, argv, "-setwkr") == -1) { + numPureWorker = 0; + } else { //[-setwkr [] ] + int indx2 = general_findPara(argc, argv, "-setwkr") + 1; + if (argc <= indx2) ParameterError("-setwkr [] ]"); + numPureWorker = atoi(argv[indx2++]); + if (argc < indx2 + numPureWorker) ParameterError("-setwkr [] ]"); + for (int i = 0; i < numPureWorker; i++) { + nameWorkers[i] = argv[indx2 + i]; + } + } + + if ((has_driverAlone == -1) && (has_workerAlone == -1)) { + mode_zmq = ZMQ_NONE; + } else { + if (has_driverAlone != -1) { + mode_zmq = ZMQ_DRIVER; + } else { + mode_zmq = ZMQ_WORKER; + if (argc > has_workerAlone + 1) + nodeID = atoi(argv[has_workerAlone + 1]); + else { + printf( + "\033[1;31;40mPARAMETER ERROR\033[0m: -load_alveo_partitions -worker " + "\033[1;31;40m\033[0m missed \n"); + exit(1); + } + } + } + } else if (general_findPara(argc, argv, "-louvain_modularity_alveo") != -1) + mode_alveo = ALVEOAPI_RUN; + else + mode_alveo = ALVEOAPI_NONE; + + if (has_cmd != -1) + useCmd = true; + else + useCmd = false; + + if (mode_alveo == ALVEOAPI_NONE) { + if ((has_driver == -1) && (has_worker == -1)) { + mode_zmq = ZMQ_NONE; + } else { + if (has_driver != -1) { + mode_zmq = ZMQ_DRIVER; + if (argc > has_driver + 1) + strcpy(path_zmq, argv[has_driver + 1]); + else + strcpy(path_zmq, "./"); + } else { + mode_zmq = ZMQ_WORKER; + if (argc > has_worker + 1) + strcpy(path_zmq, argv[has_driver + 1]); + else + strcpy(path_zmq, "./"); + } + } + } + + if (has_opts_C_thresh != -1 && has_opts_C_thresh < (argc - 1)) { + rec[has_opts_C_thresh] = true; + rec[has_opts_C_thresh + 1] = true; + opts_C_thresh = atof(argv[has_opts_C_thresh + 1]); + } else + opts_C_thresh = 0.0002; +#ifdef PRINTINFO + printf("PARAMETER opts_C_thresh = %f\n", opts_C_thresh); +#endif + if (has_opts_minGraphSize != -1 && has_opts_minGraphSize < (argc - 1)) { + rec[has_opts_minGraphSize] = true; + rec[has_opts_minGraphSize + 1] = true; + opts_minGraphSize = atoi(argv[has_opts_minGraphSize + 1]); + } else + opts_minGraphSize = 10; +#ifdef PRINTINFO + printf("PARAMETER has_opts_minGraphSize= %ld\n", opts_minGraphSize); +#endif + if (has_opts_threshold != -1 && has_opts_threshold < (argc - 1)) { + rec[has_opts_threshold] = true; + rec[has_opts_threshold + 1] = true; + opts_threshold = atof(argv[has_opts_threshold + 1]); + } else + opts_threshold = 0.000001; +#ifdef PRINTINFO + printf("PARAMETER opts_C_thresh= %f\n", opts_C_thresh); +#endif + if (has_opts_ftype != -1 && has_opts_ftype < (argc - 1)) { + rec[has_opts_ftype] = true; + rec[has_opts_ftype + 1] = true; + opts_ftype = atof(argv[has_opts_ftype + 1]); + } else + opts_ftype = 3; +#ifdef PRINTINFO + printf("PARAMETER opts_ftype = %i\n", opts_ftype); +#endif + if (has_opts_coloring != -1) { + rec[has_opts_coloring] = true; + opts_coloring = true; + } +#ifdef PRINTINFO + printf("PARAMETER opts_coloring = %d\n", opts_coloring); +#endif + opts_output = false; + if (has_opts_VF != -1) { + rec[has_opts_VF] = true; + opts_VF = true; + } +#ifdef PRINTINFO + printf("PARAMETER opts_VF = %d\n", opts_VF); +#endif + + if (hasXclbinPath != -1 && hasXclbinPath < (argc - 1)) { + rec[hasXclbinPath] = true; + rec[hasXclbinPath + 1] = true; + xclbinFile = argv[hasXclbinPath + 1]; + } + + if (hasDeviceNames != -1 && hasDeviceNames < (argc - 1)) { + rec[hasDeviceNames] = true; + rec[hasDeviceNames + 1] = true; + deviceNames = argv[hasDeviceNames + 1]; +#ifndef NDEBUG + std::cout << "INFO: deviceNames=" << deviceNames << std::endl; +#endif + } else { + deviceNames = "xilinx_u50_gen3x16_xdma_201920_3"; +#ifdef PRINTINFO + printf("Using defalut device xilinx_u50_gen3x16_xdma_201920_3, because of the missing deviceNames.\n"); +#endif + } + + if (has_numThread != -1 && has_numThread < (argc - 1)) { + rec[has_numThread] = true; + rec[has_numThread + 1] = true; + numThread = atoi(argv[has_numThread + 1]); + } else + numThread = 16; + + if (hasNumPars != -1 && hasNumPars < (argc - 1)) { + rec[hasNumPars] = true; + rec[hasNumPars + 1] = true; + numPars = atoi(argv[hasNumPars + 1]); + } else + numPars = 2; + + if (hasNumDevices != -1 && hasNumDevices < (argc - 1)) { + rec[hasNumDevices] = true; + rec[hasNumDevices + 1] = true; + numDevices = atoi(argv[hasNumDevices + 1]); + } else + numDevices = 1; + + int numCu = 1; + if (hasNumCu != -1 && hasNumCu < (argc - 1)) { + rec[hasNumCu] = true; + rec[hasNumCu + 1] = true; + numCu = atoi(argv[hasNumCu + 1]); +#ifdef PRINTINFO + printf("PARAMETER numCu = %i\n", numCu); +#endif + } else + numCu = 1; + + if (has_gh_par != -1 && has_gh_par < (argc - 1)) { + rec[has_gh_par] = true; + rec[has_gh_par + 1] = true; + gh_par = atoi(argv[has_gh_par + 1]); + } else + gh_par = 1; + +// Kernel mode handling +#ifdef PRINTINFO + printf("PARAMETER gh_par = %i\n", gh_par); +#endif + if (hasKernelMode != -1 && hasKernelMode < (argc - 1)) { + rec[hasNumDevices] = true; + rec[hasNumDevices + 1] = true; + kernelMode = atoi(argv[hasKernelMode + 1]); + } else + kernelMode = 1; + +#ifndef NDEBUG + printf("PARAMETER kernelMode=%d\n", kernelMode); +#endif + if (has_opts_output != -1 && has_opts_output < (argc - 1)) { + opts_output = true; + rec[has_opts_output] = true; + rec[has_opts_output + 1] = true; + + opts_outputFile = argv[has_opts_output + 1]; + } + + if (hasNumNodes != -1 && hasNumNodes < (argc - 1)) { + rec[hasNumNodes] = true; + rec[hasNumNodes + 1] = true; + numNodes = atoi(argv[hasNumNodes + 1]); + } else + numNodes = 1; + + if (has_max_num_level != -1 && has_max_num_level < (argc - 1)) { + rec[has_max_num_level] = true; + rec[has_max_num_level + 1] = true; + max_num_level = atoi(argv[has_max_num_level + 1]); + } else + max_num_level = MAX_NUM_PHASE; +#ifdef PRINTINFO + printf("PARAMETER max_num_level = %i\n", max_num_level); +#endif + + if (has_max_num_iter != -1 && has_max_num_iter < (argc - 1)) { + rec[has_max_num_iter] = true; + rec[has_max_num_iter + 1] = true; + max_num_iter = atoi(argv[has_max_num_iter + 1]); + } else + max_num_iter = MAX_NUM_TOTITR; +#ifdef PRINTINFO + printf("PARAMETER max_num_iter = %i\n", max_num_iter); +#endif + + if (mode_alveo == ALVEOAPI_LOAD) return 0; // No need to set input matrix file if + + for (int i = 1; i < argc; i++) { + // printf("i= %d rec[i]=%d\n", i , rec[i]); + if (rec[i] == false) { + has_opts_inFile = i; + strcpy(opts_inFile, argv[has_opts_inFile]); +#ifdef PRINTINFO + printf("PARAMETER opts_inFile = %s\n", opts_inFile); +#endif + FILE* file = fopen(opts_inFile, "r"); + if (file == NULL) { + printf("\033[1;31;40mPARAMETER ERROR\033[0m: Cannot open the batch file: %s\n", opts_inFile); + exit(1); + } else + fclose(file); + break; + } else { + if (i == argc - 1) { + printf("\033[1;31;40mPARAMETER ERROR\033[0m: opts_inFile NOT set!!!\n"); + exit(1); + } + } + } +#ifndef NDEBUG + std::cout << "DEBUG: host_ParserParameters " + << "\n numPars=" << numPars << "\n numNodes=" << numNodes << std::endl; +#endif + return 0; +} + +ToolOptions::ToolOptions(int argcIn, char** argvIn) { + argc = argcIn; + argv = argvIn; + host_ParserParameters(argc, argv, opts_C_thresh, opts_minGraphSize, threshold, opts_ftype, opts_inFile, + opts_coloring, opts_output, outputFile, opts_VF, xclbinFile, deviceNames, numThreads, numPars, + gh_par, kernelMode, numDevices, modeZmq, path_zmq, useCmd, mode_alveo, nameProj, alveoProject, + numPureWorker, nameWorkers, nodeId, numNodes, max_level, max_iter); +} + +void PrintTimeRpt(GLV* glv, int num_dev, bool isHead) { + int num_phase = 6; + if (isHead) { + printf("=========="); + printf("=========="); + for (int d = 0; d < num_dev; d++) { + printf("==Dev_%-2d==", d); + } + printf("="); + + for (int phs = 0; phs < num_phase; phs++) printf("==phase%-2d=", phs); + } else { + for (int d = 0; d < (num_dev + num_phase); d++) printf("----------"); + } + printf("\n"); + + for (int d = 0; d < num_dev; d++) { + // 1: Get E2E time on the device + glv->times.totTimeE2E_DEV[d] = 0; + for (int i = 0; i < glv->times.phase; i++) + if (glv->times.deviceID[i] == d) glv->times.totTimeE2E_DEV[d] += glv->times.eachTimeE2E[i]; + // 2-1: Print left column + if (d == 0) { + if (glv->times.parNo == -1) + printf("Final Louv "); + else + printf("Par:%2d ", glv->times.parNo); + } else + printf(" "); + printf("Dev_%-2d: ", d); + // 2-2: + for (int i = 0; i < num_dev; i++) { + if (i == d) { + printf(" %3.4f ", glv->times.totTimeE2E_DEV[d]); + } else + printf(" "); + } + printf(" = "); + // 2-3 + for (int i = 0; i < glv->times.phase; i++) { + if (glv->times.deviceID[i] != d) + printf(" "); + else + printf(" + %2.3f ", glv->times.eachTimeE2E[i]); + } + printf("\n"); + } +} + +void PrintTimeRpt(ParLV& parlv, int num_dev) { + printf( + "===============\033[1;35;40mE2E time Matrix for each partition's very phases on each device " + "\033[0m====================\n"); + double totTimeOnDev[num_dev]; + for (int d = 0; d < num_dev; d++) totTimeOnDev[d] = 0; + for (int p = 0; p < parlv.num_par; p++) { + PrintTimeRpt(parlv.par_src[p], num_dev, p == 0); + for (int d = 0; d < num_dev; d++) { + totTimeOnDev[d] += parlv.par_src[p]->times.totTimeE2E_DEV[d]; + } + } + printf("--------------------------------------------------------------------------------\n"); + // printf("Total Par time : ", num_dev);//? + for (int d = 0; d < num_dev; d++) printf(" %3.4f ", totTimeOnDev[d]); + printf("\n"); + // printf("============================================================\n"); + PrintTimeRpt(parlv.plv_merged, num_dev, false); + printf("====================================================================================================\n"); +} + +void PrintRptParameters(double opts_C_thresh, // Threshold with coloring on + long opts_minGraphSize, // Min |V| to enable coloring + double opts_threshold, // Value of threshold + int opts_ftype, // File type + char* opts_inFile, + bool opts_coloring, + bool opts_output, + char* opts_outputFile, + bool opts_VF, + char* opts_xclbinPath, + int numThreads, + int num_par, + int par_prune, + bool kernelMode, + int devNeed_cmd, + int mode_zmq, + char* path_zmq, + bool useCmd, + int mode_alveo, + xf::graph::L3::Handle::singleOP& op0) { + printf("************************************************************************************************\n"); + printf( + "******************************** \033[1;35;40mParameters Report \033[0m " + "*********************|********************\n"); + printf("************************************************************************************************\n"); + // numDevices + printf( + "FPGA Parameter \033[1;37;40mnumDevices \033[0m: %-8d \t\t\t Default= 1, by " + "command-line: \" \033[1;37;40m-num_devices\033[0m \"", + op0.deviceNeeded); + printf(" or by config.json\n"); + printf( + "FPGA Parameter \033[1;37;40mrequestLoad \033[0m: %-8d \t\t\t Default= 100, by config.json " + " \n", + op0.requestLoad); + printf( + "FPGA Parameter \033[1;37;40moperationName \033[0m: %s \t\t Default=louvainModularity, by config.json " + " \n", + op0.operationName); + printf( + "FPGA Parameter \033[1;37;40mkernelName \033[0m: %s \t\t Default=kernel_louvain, by config.json " + " \n", + op0.kernelName); + if (opts_xclbinPath[0] == 0) + printf( + "FPGA Parameter \033[1;37;40mxclbinFile \033[0m: %s \t by config.json or by \" " + "\033[1;37;40m-x \033[0m\" \n", + op0.xclbinFile); + else + printf( + "FPGA Parameter \033[1;37;40mxclbinFile \033[0m: %s \t by command-line: \" \033[1;37;40m-x " + "\033[0m\" or by config.json \n", + op0.xclbinFile); + printf( + "FPGA Parameter \033[1;37;40mtype of xclbin \033[0m: %d \t\t\t Default= normal , by command-line: " + "\" \033[1;37;40m-fast\033[0m \" \n", + kernelMode); + printf( + "Louv Parameter \033[1;37;40mLouvain_inFile \033[0m: %s \t\t\t Required -f 3 , by command-line: " + "\" \033[1;37;40m\033[0m \" \n", + opts_inFile); + printf( + "Louv Parameter \033[1;37;40mLouvain_Output \033[0m: %s \t\t\t Default= No Out , by command-line: " + "\" \033[1;37;40m-o\033[0m \" \n", + opts_output ? "true" : "false"); + if (opts_output) + printf( + "Louv Parameter \033[1;37;40mhas Output File \033[0m: %s \t\t Default= false, by " + "command-line: \" \033[1;37;40m-o \033[0m \" \n", + opts_outputFile); + printf( + "Louv Parameter \033[1;37;40mCPU numThreads \033[0m: %-8d \t\t\t Default= 16, by command-line: " + "\" \033[1;37;40m-thread \033[0m \" \n", + numThreads); + printf( + "Louv Parameter \033[1;37;40mcoloring thrhd \033[0m: %1.7f \t\t\t Default= 0.0002, by command-line: " + "\" \033[1;37;40m-d \033[0m \" \n", + opts_C_thresh); + printf( + "Louv Parameter \033[1;37;40mparallel thrhd \033[0m: %1.7f \t\t\t Default= 0.000001, by command-line: " + "\" \033[1;37;40m-t \033[0m \" \n", + opts_threshold); + printf( + "Louv Parameter \033[1;37;40mminGraphSize \033[0m: %-8ld \t\t\t Default= 10, by command-line: " + "\" \033[1;37;40m-m \033[0m \" \n", + opts_minGraphSize); + printf( + "Part Parameter \033[1;37;40mNumber of shares\033[0m: %-8d \t\t\t Default= 2, by command-line: " + "\" \033[1;37;40m-num_pars \033[0m \" \n", + num_par); + printf( + "Part Parameter \033[1;37;40mpruning thrhd \033[0m: %-8d \t\t\t Default= 1, by command-line: " + "\" \033[1;37;40m-par_prune\033[0m \" \n", + par_prune); + + printf("************************************************************************************************\n"); +} + +// functions for printing info or read command lines end +void ParLV::Init(int mode) { + st_Partitioned = false; + st_ParLved = false; + st_PreMerged = false; + st_Merged = false; + st_FinalLved = false; + // + st_Merged_ll = false; + st_Merged_gh = false; + isMergeGhost = false; + isOnlyGL = false; + isPrun = true; + th_prun = 1; + plv_src = NULL; + plv_merged = NULL; + plv_final = NULL; + num_par = NV = NVl = NE = NElg = NEll = NEgl = NEgg = NEself = NV_gh = 0; + elist = NULL; + M_v = NULL; + NE_list_all = 0; + NE_list_ll = 0; + NE_list_gl = 0; + NE_list_gg = 0; + NV_list_all = 0; + NV_list_l = 0; + NV_list_g = 0; + num_dev = 1; + kernelMode = mode; + num_server = 1; +} + +void ParLV::Init(int mode, GLV* src, int nump, int numd) { + Init(mode); + plv_src = src; + num_par = nump; + num_dev = numd; + st_Partitioned = true; +} + +void ParLV::Init(int mode, GLV* src, int num_p, int num_d, bool isPrun, int th_prun) { + Init(mode, src, num_p, num_d); + this->isPrun = isPrun; + this->th_prun = th_prun; +} + +ParLV::ParLV() { + Init(MD_FAST); +} + +ParLV::~ParLV() { + num_par = 0; + if (elist) free(elist); + if (M_v) free(M_v); +} + +void ParLV::PrintSelf() { + printf( + "=========================================================[\033[1;35;40m LIST Begin " + "\033[0m]======================================================================================\n"); + printf( + "= Uniq ID ==| Numbers for C / V ( V_ghost ) Edge Number (ghost edges " + ")=================================================================================\n"); + printf( + "=========================================================[\033[1;35;40m Partitioned sub-graphs " + "\033[0m]============================================================================\n"); + + for (int p = 0; p < num_par; p++) + if (st_Partitioned == false) + break; + else + this->par_src[p]->printSimple(); + printf( + "=========================================================[\033[1;35;40m Louvained sub-graphs " + "\033[0m]==================================================================================\n"); + + for (int p = 0; p < num_par; p++) + if (st_ParLved == false) + break; + else + this->par_lved[p]->printSimple(); + + if (st_FinalLved) { + this->plv_src->printSimple(); + printf( + "=========================================================[\033[1;35;40m Merged sub-graphs together " + "\033[0m]============================================================================\n"); + this->plv_merged->printSimple(); + printf( + "=========================================================[\033[1;35;40m Original graph with Updated " + "Communities \033[0m]===============================================================\n"); + this->plv_final->printSimple(); + } else if (st_Merged) { + this->plv_merged->printSimple(); + printf( + "=========================================================[\033[1;35;40m Original graph with Updated " + "Communities \033[0m]===============================================================\n"); + this->plv_src->printSimple(); + } else if (st_PreMerged) { + this->plv_merged->printSimple(); + } + printf( + "==========================================================[\033[1;35;40m LIST END " + "\033[0m]===========================================================================================\n"); +} + +void ParLV::UpdateTimeAll() { + timesPar.timeAll = + +timesPar.timePar_all + timesPar.timeLv_all + timesPar.timePre + timesPar.timeMerge + timesPar.timeFinal; +}; + +int ParLV::partition(GLV* glv_src, int& id_glv, int num, long th_size, int th_maxGhost) { + assert(glv_src); + assert(glv_src->G); + num_par = num; + if (num_par >= MAX_PARTITION) { + printf("\033[1;31;40mERROR\033[0m: exe_LV_SETM wrong number of partition %d which should be small than %d!\n", + num_par, MAX_PARTITION); + return -1; + } + long vsize = glv_src->NV / num_par; + long start = 0; + long end = start + vsize; + off_src[0] = 0; + for (int i = 0; i < num_par; i++) { + if (th_maxGhost > 0) + par_src[i] = stt[i].ParNewGlv_Prun(glv_src->G, start, end, id_glv, th_maxGhost); + else + par_src[i] = stt[i].ParNewGlv(glv_src->G, start, end, id_glv); + // par_list.push_back(pt_par[i]); + start = end; + end = start + vsize; + off_src[i + 1] = start; + } + return 0; +} + +int GetScl(long v) { + int ret = 0; + while (v > 0) { + v = v >> 1; + ret++; + } + return ret; +} + +void ParLV::PreMerge() { + if (st_PreMerged == true) return; + assert(num_par > 0); + // assert(st_ParLved==true); + if (st_ParLved == false) return; + off_lved[0] = off_src[0] = 0; + NV = NVl = NE = NElg = 0; + max_NV = max_NVl = max_NE = max_NElg = 0; + for (int p = 0; p < num_par; p++) { + NV += par_lved[p]->NV; + NVl += par_lved[p]->NVl; + NE += par_lved[p]->NE; + NElg += par_lved[p]->NElg; + max_NV = max_NV > par_lved[p]->NV ? max_NV : par_lved[p]->NV; + max_NVl = max_NVl > par_lved[p]->NVl ? max_NVl : par_lved[p]->NVl; + max_NE = max_NE > par_lved[p]->NE ? max_NE : par_lved[p]->NE; + max_NElg = max_NElg > par_lved[p]->NElg ? max_NElg : par_lved[p]->NElg; + off_lved[p + 1] = NVl; + off_src[p + 1] = off_src[p] + par_src[p]->NVl; + } + scl_NV = GetScl(max_NV); + scl_NE = GetScl(max_NE); + scl_NVl = GetScl(max_NVl); + scl_NElg = GetScl(max_NElg); + NV_gh = CheckGhost(); // + NVl;; + NV = NV_gh + NVl; + elist = (edge*)malloc(sizeof(edge) * (NE)); + M_v = (long*)malloc(sizeof(long) * (NV)); + assert(M_v); + assert(elist); + memset(M_v, 0, sizeof(long) * (NV)); + NE_list_all = 0; + NE_list_ll = 0; + NE_list_gl = 0; + NE_list_gg = 0; + NV_list_all = 0; + NV_list_l = 0; + NV_list_g = 0; + for (int p = 0; p < num_par; p++) { + GLV* G_src = par_src[p]; + for (int v = 0; v < G_src->NVl; v++) { + long base_src = off_src[p]; + long base_lved = off_lved[p]; + long c_src = G_src->C[v]; + long c_mg; + if (c_src < par_lved[p]->NVl) + c_mg = c_src + base_lved; + else + c_mg = p_v_new[p][c_src]; + G_src->C[v] = c_mg; +// M_v[v+base_lved] = c_mg; +#ifdef DBG_PAR_PRINT + printf("DBGPREMG:p=%d v=%d base_src=%d base_lved=%d C1=%d, isLocal%d, c_mg=%d\n", p, v, base_src, + base_lved, G_src->C[v], c_src < par_lved[p]->NVl, c_mg); +#endif + } + } + st_PreMerged = true; +} + +int ParLV::AddGLV(GLV* plv) { + assert(plv); + par_src[num_par] = plv; + num_par++; + return num_par; +} + +long ParLV::FindGhostInLocalC(long me) { + long e_org = -me - 1; + int idx = 0; + // 1. find #p + for (int p = 0; p < num_par; p++) { + if (off_src[p] <= e_org && e_org < off_src[p + 1]) { + idx = p; + break; + } + } + // 2. + long address = e_org - off_src[idx]; + long m_src = par_src[idx]->M[address]; + // assert(m_org == m_src); + long c_src = par_src[idx]->C[address]; + long c_src_m = c_src + off_lved[idx]; +#ifdef PRINTINFO + printf("e_org=%-4ld - %-4ld = address:%-4ld; c_src:%-4ld+off%-4ld=c_src_m%-4ld\n", e_org, off_src[idx], address, + c_src, off_lved[idx], c_src_m); +#endif + return c_src_m; +} + +int ParLV::FindParIdx(long e_org) { + int idx = 0; + // 1. find #p + for (int p = 0; p < num_par; p++) { + if (off_src[p] <= e_org && e_org < off_src[p + 1]) { + idx = p; + break; + } + } + return idx; +} + +int ParLV::FindParIdxByID(int id) { + if (!this->st_Partitioned) return -1; + for (int p = 0; p < num_par; p++) + if (this->par_lved[p]->ID == id) return p; + if (!this->st_ParLved) return -1; + for (int p = 0; p < num_par; p++) + if (this->par_src[p]->ID == id) return p; + return -1; +} + +pair ParLV::FindCM_1hop(int idx, long e_org) { + // 2. + pair ret; + long addr_v = e_org - off_src[idx]; + long c_src_sync = par_src[idx]->C[addr_v]; + long c_lved_new = c_src_sync; // key logic + long m_lved_new = par_lved[idx]->M[c_lved_new]; + ret.first = c_lved_new; + ret.second = m_lved_new; + return ret; +} + +pair ParLV::FindCM_1hop(long e_org) { + // 2. + int idx = FindParIdx(e_org); + pair ret; + long addr_v = e_org - off_src[idx]; + long c_src_sync = par_src[idx]->C[addr_v]; + long c_lved_new = c_src_sync; // key logic + long m_lved_new = par_lved[idx]->M[c_lved_new]; + ret.first = c_lved_new; + ret.second = m_lved_new; + return ret; +} + +long ParLV::FindC_nhop(long m_g) { + assert(m_g < 0); + long m_next = m_g; + int cnt = 0; + + do { + long e_org = -m_next - 1; + int idx = FindParIdx(e_org); + long v_src = e_org - off_src[idx]; // dbg + pair cm = FindCM_1hop(idx, e_org); + long c_lved_new = cm.first; + long m_lved_new = cm.second; + cnt++; + + if (m_lved_new >= 0) + return c_lved_new + off_lved[idx]; + else if (m_lved_new == m_g) { + return m_g; + } else { // m_lved_new<0; + m_next = m_lved_new; + } + + } while (cnt < 2 * num_par); + return m_g; // no local community for the ghost which should be add as a new community +} + +//#define DBG_PAR_PRINT +long FindOldOrAddNew(map& map_v, long& NV, long v) { + map::iterator iter; + int ret; + iter = map_v.find(v); + if (iter == map_v.end()) { + ret = NV++; // add new +#ifdef DBG_PAR_PRINT + printf("DBG_PAR_PRINT, new:%d ", ret); +#endif + } else { + ret = iter->second; // find old +#ifdef DBG_PAR_PRINT + printf("DBG_PAR_PRINT, old:%d ", ret); +#endif + } + return ret; +} + +long ParLV::CheckGhost() { + long NV_gh_new = 0; + for (int p = 0; p < num_par; p++) { + GLV* G_src = par_src[p]; + GLV* G_lved = par_lved[p]; + long* vtxPtr = G_lved->G->edgeListPtrs; + edge* vtxInd = G_lved->G->edgeList; + p_v_new[p] = (long*)malloc(sizeof(long) * (G_lved->NV)); + assert(p_v_new[p]); + for (int v = G_lved->NVl; v < G_lved->NV; v++) { + long mv = G_lved->M[v]; + long v_new = 0; + if (use_bfs) + v_new = FindC_nhop_bfs(mv); // find the bfs-hop subgraph //BFS + else + v_new = FindC_nhop(mv); // find the directly cat subgraph + if (v_new == mv) { + p_v_new[p][v] = FindOldOrAddNew(m_v_gh, NV_gh_new, v_new) + this->NVl; +#ifdef DBG_PAR_PRINT + printf("CheckGhost: p=%-2d v=%-6d mv=%-6d v_new=%-6d NV_gh=%d\n", p, v, mv, p_v_new[p][v], NV_gh_new); +#endif + } else { + p_v_new[p][v] = v_new; +#ifdef DBG_PAR_PRINT + printf("CheckGhost: p=%-2d v=%-6d mv=%-6d v_new=%-6d isNVL%d\n", p, v, mv, v_new, v_new < this->NVl); +#endif + } + } + } + return NV_gh_new; +} + +double ParLV::TimeStar() { + return timesPar.time_star = getTime(); +} +double ParLV::TimeDonePar() { + return timesPar.time_done_par = getTime(); +} +double ParLV::TimeDoneLv() { + return timesPar.time_done_lv = getTime(); +} +double ParLV::TimeDonePre() { + return timesPar.time_done_pre = getTime(); +} +double ParLV::TimeDoneMerge() { + return timesPar.time_done_mg = getTime(); +} +double ParLV::TimeDoneFinal() { + timesPar.time_done_fnl = getTime(); + return timesPar.time_done_fnl; +} + +double ParLV::TimeAll_Done() { + timesPar.timePar_all = timesPar.time_done_par - timesPar.time_star; + timesPar.timeLv_all = timesPar.time_done_lv - timesPar.time_done_par; + timesPar.timePre = timesPar.time_done_pre - timesPar.time_done_lv; + timesPar.timeMerge = timesPar.time_done_mg - timesPar.time_done_pre; + timesPar.timeFinal = timesPar.time_done_fnl - timesPar.time_done_mg; + timesPar.timeAll = timesPar.time_done_fnl - timesPar.time_star; + return timesPar.timeAll; +} + +void ParLV::PrintTime() { + printf("\033[1;37;40mINFO\033[0m: Total time for partition orignal : %lf\n", timesPar.timePar_all); + printf("\033[1;37;40mINFO\033[0m: Total time for partition Louvain subs : %lf\n", timesPar.timeLv_all); + for (int d = 0; d < num_dev; d++) { // for parlv.timeLv_dev[d] + printf("\033[1;37;40m \033[0m: Total time for Louvain on dev-%1d : %lf\t = ", d, + timesPar.timeLv_dev[d]); + for (int p = d; p < num_par; p += num_dev) printf("+ %3.4f ", timesPar.timeLv[p]); + printf("\n"); + } + printf("\033[1;37;40mINFO\033[0m: Total time for partition pre-Merge : %lf\n", timesPar.timePre); + printf("\033[1;37;40mINFO\033[0m: Total time for partition Merge : %lf\n", timesPar.timeMerge); + printf("\033[1;37;40mINFO\033[0m: Total time for partition Final Louvain : %lf\n", timesPar.timeFinal); + printf("\033[1;37;40mINFO\033[0m: Total time for partition All flow : %lf\n", timesPar.timeAll); +} + +void ParLV::PrintTime2() { + // Final number of clusters : 225 + // Final modularity : + printf("\033[1;37;40mINFO\033[0m: Final number of clusters : %ld\n", plv_src->com_list.back().NC); + printf("\033[1;37;40mINFO\033[0m: Final modularity : %lf\n", plv_src->com_list.back().Q); + printf("\033[1;37;40mINFO\033[0m: Total time for partition + Louvain : %lf\n", timesPar.timePar_all); + printf("\033[1;37;40mINFO\033[0m: Total time for partition pre-Merge : %lf\n", timesPar.timePre); + printf("\033[1;37;40mINFO\033[0m: Total time for partition Merge : %lf\n", timesPar.timeMerge); + printf("\033[1;37;40mINFO\033[0m: Total time for partition Final Louvain : %lf\n", timesPar.timeFinal); + printf("\033[1;37;40mINFO\033[0m: Total time for partition All flow : %lf\n", timesPar.timeAll); +} + +void ParLV::CleanTmpGlv() { + for (int p = 0; p < num_par; p++) { + delete (par_src[p]); + delete (par_lved[p]); + } + delete (plv_merged); +} +//////////////////////////////////////////////////////////////////////////////////////////////// + +void sim_getServerPar( + // inputs + graphNew* G, // Looks like a Global Graph but here only access dataset within + long start_vertex, // a range from start_vertex to end_vertex, which is stored locally + long end_vertex, // Here we assume that the vertices of a TigerGraph partition + // stored on a node are continuous + // Outputs + long* offsets_tg, // we can also use �degree� instead of �offsets� + edge* edges_tg, // + long* dgr_tail_tg // degrees for the tail of each edge; + ) { + // printf("DBG_TGPAR: NV=%d NE=%d \n", G->numVertices, G->numEdges); + long* off_glb = G->edgeListPtrs; // in GSQL, maybe �degree� can be much easier. + edge* edges_glb = G->edgeList; + long cnt_e = 0; + long cnt_v = 0; + offsets_tg[0] = off_glb[0 + start_vertex] - off_glb[start_vertex]; // 0; + for (long v_glb = start_vertex; v_glb < end_vertex; v_glb++) { // Scanning nodes within a range + offsets_tg[cnt_v + 1] = off_glb[v_glb + 1] - off_glb[start_vertex]; + long degree = off_glb[v_glb + 1] - off_glb[v_glb]; + for (long e = 0; e < degree; e++) { + edges_tg[cnt_e].head = edges_glb[off_glb[v_glb] + e].head; + edges_tg[cnt_e].tail = edges_glb[off_glb[v_glb] + e].tail; + edges_tg[cnt_e].weight = edges_glb[off_glb[v_glb] + e].weight; + dgr_tail_tg[cnt_e] = off_glb[edges_tg[cnt_e].tail + 1] - off_glb[edges_tg[cnt_e].tail]; + // printf("INFO:edges_tg[cnt_e].tail = %ld,dgr_tail_tg[cnt_e]=%ld\n",edges_tg[cnt_e].tail, + // dgr_tail_tg[cnt_e]); + cnt_e++; + } + cnt_v++; + } +} + +// start bfs partition (lOW_BANGWIDTH_MOTHED) method +#define lOW_BANGWIDTH_METHOD + +#ifdef lOW_BANGWIDTH_METHOD + +struct HopV { + long v; + int hop; +}; +typedef int t_sel; +long FindStartVertexlastround(graphNew* G, t_sel V_selected[], long laststart) { + long NV = G->numVertices; + long* offsets = G->edgeListPtrs; + edge* indices = G->edgeList; + long v_start = -1; + int degree_max = 1; + + // omp is not fast than the directly write coding style + for (long v = laststart; v < NV; v++) { + if (V_selected[v]) continue; + v_start = v; + break; + } + return v_start; +} + +long FindStartVertex(graphNew* G, t_sel V_selected[]) { + long NV = G->numVertices; + long* offsets = G->edgeListPtrs; + edge* indices = G->edgeList; + long v_start = -1; + int degree_max = 1; + + for (long v = 0; v < NV; v++) { + if (V_selected[v]) continue; + long adj1 = offsets[v]; + long adj2 = offsets[v + 1]; + int degree = adj2 - adj1; + if (degree < degree_max) continue; + v_start = v; + degree_max = degree; + } + return v_start; +} + +long BFSPar_AddNeighbors( + graphNew* G, + int p, // + t_sel V_selected[], // inout, for recording whether a vertex is selected + long v, + int hop, + // long* drglist_tg, + // output + edge* elist_par[], + long num_e_dir[], + long num_e_dir_lg[], + long num_v_l[], + long num_v_g[], + map map_v_l[], // std:map for local vertices, will be used for renumbering and creating M + map map_v_g[], // std:map for ghost vertices, will be used for renumbering and creating M + std::queue q_par[], + map map_v_l_scaned[], + int max_hop[]) { + long* offsets = G->edgeListPtrs; + edge* indices = G->edgeList; +#ifdef DEBUGPAR + printf("BFS, v=%ld\n", v); +#endif + long adj1 = offsets[v]; + long adj2 = offsets[v + 1]; + int degree = adj2 - adj1; + bool hasAGhost = false; // th_prun = 1 ,so this flag turn ture just in first ghost add to edge + int e_mindgr = 0; // the min degree of the edge + int e_min = 0; // the min degree of the edge's global ID + long num_e_min = num_e_dir[p]; // the min degree of the edge's sub-graph ID + + for (int d = 0; d < degree; d++) { + map::iterator itr; + bool notSelected = false; + bool isTailLocal = false; + bool isTailGhost = false; + bool BeenScaned = false; + long e = indices[adj1 + d].tail; + + if (V_selected[e] == 0) { + notSelected = true; + V_selected[e] = p + 1; + } // atom action done + + itr = map_v_l[p].find(e); + if (itr != map_v_l[p].end()) isTailLocal = true; + itr = map_v_l_scaned[p].find(e); + if (itr != map_v_l_scaned[p].end()) BeenScaned = true; + itr = map_v_g[p].find(e); + if (itr != map_v_g[p].end()) isTailGhost = true; + if (notSelected) { + map_v_l[p][e] = num_v_l[p]; + num_v_l[p]++; + HopV he; + he.hop = hop + 1; + he.v = e; + q_par[p].push(he); +#ifdef DEBUGPAR + printf("push vertex'e %ld\n", e); +#endif + // if(he.hop>max_hop[p]) + // max_hop[p] = he.hop; + } + // add to edge ghost; + if (BeenScaned) // && v!=e) + continue; + else { + double w = indices[adj1 + d].weight; +#ifdef NO_PRUNING + // if no define the th_maxGhost=1 in the top function:BFS_par_general_4TG, but that is impossible + elist_par[p][num_e_dir[p]].head = v <= e ? v : e; + elist_par[p][num_e_dir[p]].tail = v <= e ? e : v; + elist_par[p][num_e_dir[p]].weight = w; +#ifdef DEBUGPAR + printf("edge (%ld %ld)\n", elist_par[p][num_e_dir[p]].head, elist_par[p][num_e_dir[p]].tail); +#endif + num_e_dir[p]++; + if (!notSelected && !isTailLocal) { + if (!isTailGhost) { // new found ghost + map_v_g[p][e] = num_v_g[p]; + num_v_g[p]++; + num_e_dir_lg[p]++; + } else { + num_e_dir_lg[p]++; + } + } +#else + // so the th_maxGhost=1 and should do the ghost edge pruning by 1 + if (!notSelected && !isTailLocal) { + if (!isTailGhost) { // new found ghost + long drglist_tg = offsets[e + 1] - offsets[e]; + if (!hasAGhost) { // add new edge + elist_par[p][num_e_dir[p]].head = v <= e ? v : e; + elist_par[p][num_e_dir[p]].tail = v <= e ? e : v; + elist_par[p][num_e_dir[p]].weight = w; + num_e_min = num_e_dir[p]; +#ifdef DEBUGPAR + printf("edge (%ld %ld)\n", elist_par[p][num_e_dir[p]].head, elist_par[p][num_e_dir[p]].tail); +#endif + num_e_dir[p]++; + + map_v_g[p][e] = num_v_g[p]; + e_mindgr = drglist_tg; + e_min = e; + num_v_g[p]++; + num_e_dir_lg[p]++; + hasAGhost = true; + } else { // switch the min // because the bfs, this branch access lightly + // printf("b emin=%ld, e=%ld, num_v_g[p]=%d \n",e_min, e,num_v_g[p]); + if (drglist_tg < e_mindgr || (drglist_tg == e_mindgr && e < e_min)) { + map_v_g[p].erase(e_min); + map_v_g[p][e] = num_v_g[p] - 1; + e_mindgr = drglist_tg; + e_min = e; + + elist_par[p][num_e_min].head = v <= e ? v : e; + elist_par[p][num_e_min].tail = v <= e ? e : v; + elist_par[p][num_e_min].weight = w; + } + } + } else { // add new edge + elist_par[p][num_e_dir[p]].head = v <= e ? v : e; + elist_par[p][num_e_dir[p]].tail = v <= e ? e : v; + elist_par[p][num_e_dir[p]].weight = w; +#ifdef DEBUGPAR + printf("edge (%ld %ld)\n", elist_par[p][num_e_dir[p]].head, elist_par[p][num_e_dir[p]].tail); +#endif + num_e_dir[p]++; + } + } else { // add new edge + elist_par[p][num_e_dir[p]].head = v <= e ? v : e; + elist_par[p][num_e_dir[p]].tail = v <= e ? e : v; + elist_par[p][num_e_dir[p]].weight = w; +#ifdef DEBUGPAR + printf("edge (%ld %ld)\n", elist_par[p][num_e_dir[p]].head, elist_par[p][num_e_dir[p]].tail); +#endif + num_e_dir[p]++; + } +#endif + } // add to edge ghost; + } // for eatch e + map_v_l_scaned[p][v] = v; + return 0; +} + +long addGhostAfterPartition( + graphNew* G, + int p, // + t_sel V_selected[], // inout, for recording whether a vertex is selected + long v, + int hop, + // long* drglist_tg, + // output + edge* elist_par[], + long num_e_dir[], + long num_e_dir_lg[], + long num_v_l[], + long num_v_g[], + map map_v_l[], // std:map for local vertices, will be used for renumbering and creating M + map map_v_g[], // std:map for ghost vertices, will be used for renumbering and creating M + std::queue q_par[], + map map_v_l_scaned[], + int max_hop[]) { + long* offsets = G->edgeListPtrs; + edge* indices = G->edgeList; +#ifdef DEBUGPAR + printf(" addghost BFS, v=%ld\n", v); +#endif + long adj1 = offsets[v]; + long adj2 = offsets[v + 1]; + int degree = adj2 - adj1; + bool hasAGhost = false; // th_prun = 1 ,so this flag turn ture just in first ghost add to edge + int e_mindgr = 0; // the min degree of the edge + int e_min = 0; // the min degree of the edge's global ID + long num_e_min = num_e_dir[p]; // the min degree of the edge's sub-graph ID + + for (int d = 0; d < degree; d++) { + map::iterator itr; + bool notSelected = false; + bool isTailLocal = false; + bool isTailGhost = false; + bool BeenScaned = false; + long e = indices[adj1 + d].tail; + + // if(V_selected[e]==0){ + // notSelected = true; + // //V_selected[e] = p+1; + // } //atom action done + + itr = map_v_l[p].find(e); + if (itr != map_v_l[p].end()) isTailLocal = true; + itr = map_v_l_scaned[p].find(e); + if (itr != map_v_l_scaned[p].end()) BeenScaned = true; + itr = map_v_g[p].find(e); + if (itr != map_v_g[p].end()) isTailGhost = true; + // if( notSelected){ + // map_v_l[p][e] = num_v_l[p]; + // num_v_l[p]++; + // HopV he; + // he.hop=hop+1; + // he.v = e; + // q_par[p].push(he); + // } + // add to edge ghost; + if (BeenScaned) // && v!=e) + continue; + else { + double w = indices[adj1 + d].weight; +#ifdef NO_PRUNING + // if no define the th_maxGhost=1 in the top function:BFS_par_general_4TG, but that is impossible + elist_par[p][num_e_dir[p]].head = v <= e ? v : e; + elist_par[p][num_e_dir[p]].tail = v <= e ? e : v; + elist_par[p][num_e_dir[p]].weight = w; +#ifdef DEBUGPAR + printf("edge (%ld %ld)\n", elist_par[p][num_e_dir[p]].head, elist_par[p][num_e_dir[p]].tail); +#endif + num_e_dir[p]++; + if (!notSelected && !isTailLocal) { + if (!isTailGhost) { // new found ghost + map_v_g[p][e] = num_v_g[p]; + num_v_g[p]++; + num_e_dir_lg[p]++; + } else { + num_e_dir_lg[p]++; + } + } +#else + // so the th_maxGhost=1 and should do the ghost edge pruning by 1 + if (!notSelected && !isTailLocal) { + if (!isTailGhost) { // new found ghost + long drglist_tg = offsets[e + 1] - offsets[e]; + if (!hasAGhost) { // add new edge + elist_par[p][num_e_dir[p]].head = v <= e ? v : e; + elist_par[p][num_e_dir[p]].tail = v <= e ? e : v; + elist_par[p][num_e_dir[p]].weight = w; + num_e_min = num_e_dir[p]; +#ifdef DEBUGPAR + printf("edge (%ld %ld)\n", elist_par[p][num_e_dir[p]].head, elist_par[p][num_e_dir[p]].tail); +#endif + num_e_dir[p]++; + + map_v_g[p][e] = num_v_g[p]; + e_mindgr = drglist_tg; + e_min = e; + num_v_g[p]++; + num_e_dir_lg[p]++; + hasAGhost = true; + } else { // switch the min // because the bfs, this branch access lightly + // printf("b emin=%ld, e=%ld, num_v_g[p]=%d \n",e_min, e,num_v_g[p]); + if (drglist_tg < e_mindgr || (drglist_tg == e_mindgr && e < e_min)) { + map_v_g[p].erase(e_min); + map_v_g[p][e] = num_v_g[p] - 1; + e_mindgr = drglist_tg; + e_min = e; + + elist_par[p][num_e_min].head = v <= e ? v : e; + elist_par[p][num_e_min].tail = v <= e ? e : v; + elist_par[p][num_e_min].weight = w; + } + } + } else { // add new edge + elist_par[p][num_e_dir[p]].head = v <= e ? v : e; + elist_par[p][num_e_dir[p]].tail = v <= e ? e : v; + elist_par[p][num_e_dir[p]].weight = w; +#ifdef DEBUGPAR + printf("edge (%ld %ld)\n", elist_par[p][num_e_dir[p]].head, elist_par[p][num_e_dir[p]].tail); +#endif + num_e_dir[p]++; + } + } else { // add new edge + elist_par[p][num_e_dir[p]].head = v <= e ? v : e; + elist_par[p][num_e_dir[p]].tail = v <= e ? e : v; + elist_par[p][num_e_dir[p]].weight = w; +#ifdef DEBUGPAR + printf("edge (%ld %ld)\n", elist_par[p][num_e_dir[p]].head, elist_par[p][num_e_dir[p]].tail); +#endif + num_e_dir[p]++; + } +#endif + } // add to edge ghost; + } // for eatch e + map_v_l_scaned[p][v] = v; + return 0; +} + +bool isHopDone(std::queue& q_par_p, int num_hop_p) { + bool hop_done; + if (!q_par_p.empty()) { + HopV hv = q_par_p.front(); + if (hv.hop == num_hop_p) + hop_done = false; + else + hop_done = true; + } else + hop_done = true; + return hop_done; +} + +void BFSPar_creatingEdgeLists_fixed_prune( + int mode_start, // 0: find vertices with max degrees, 1: vertices at average partition -m 1 + int mode_hop, //"-h 0": just one vertex will be scanned; "-h 1": full hop; "-h 2"(default): full hop with limited + // MAX_PAR_VERTEX + graphNew* G, + int num_par, // which is fixed for convenience, in future num_par maybe modified + t_sel V_selected[], // inout, for recording whether a vertex is selected + // long* drglist_tg,//input, the degree of all the vertext + // output + edge* elist_par[], + long num_e_dir[], + long num_e_dir_lg[], + long num_v_l[], + long num_v_g[], + map map_v_l[], // std:map for local vertices, will be used for renumbering and creating M + map map_v_g[] // std:map for ghost vertices, will be used for renumbering and creating M + ) { + const int MAX_PAR = num_par; + std::queue q_par[MAX_PAR]; + int num_hop[MAX_PAR]; + // long v_start[MAX_PAR]; + map map_v_l_scaned[MAX_PAR]; + + long NV_all = G->numVertices; + long* offsets = G->edgeListPtrs; + edge* indices = G->edgeList; + int idx_par = 0; + +#ifdef DEBUGPAR + for (int e = 0; e < G->numEdges; e++) { + printf("e=%ld, indices[e].tail=%ld, dgr=%ld\n", e, indices[e].tail, drglist_tg[e]); + } +#endif + // find the max vertices of the partition graph by NV/max_par + const long MAX_PAR_VERTEX = (NV_all + MAX_PAR - 1) / MAX_PAR; + + long NE_all = G->numEdges; + /************************************/ + // Step-1: finding num_par start vertices from global G, + // and initializing queues for each partition: q_par[p].push(v_start[p]); + /************************************/ + + for (int p = 0; p < num_par; p++) { + num_v_l[p] = 0; + num_v_g[p] = 0; + num_e_dir[p] = 0; + num_e_dir_lg[p] = 0; + num_hop[p] = 0; + } + // find the first startvertex for partition0 + for (int p = 0; p < 1; p++) { + num_v_l[p] = 0; + + long v_start; + if (mode_start == 0) + v_start = FindStartVertex(G, V_selected); + else + v_start = p * (NV_all / num_par); + V_selected[v_start] = p + 1; // true; + HopV hv_start; + hv_start.hop = 0; + hv_start.v = v_start; + q_par[p].push(hv_start); + map_v_l[p][v_start] = num_v_l[p]; + num_v_l[p]++; + printf("par=%d_push_v_start=%ld, num_v_l[%d]=%ld\n", p, v_start, p, num_v_l[p]); + + num_v_g[p] = 0; + num_e_dir[p] = 0; + num_e_dir_lg[p] = 0; + num_hop[p] = 0; + } + + bool notAllQueuesEmpty = true; + map::iterator itr; + /************************************/ + // Step-2: based on start vertices, doing hop-search: + /************************************/ + int cnt_hop_round = 0; + long num_v_all_l = 0; + long laststart = 0; // for the last round fast sourch + for (int p = 0; p < num_par; p++) { // loop for each partition + bool notQueueEmpty = false; + + // 2-1 growing until MAX_PAR_VERTEX + while (num_v_l[p] < MAX_PAR_VERTEX && notAllQueuesEmpty) { // for hop + notAllQueuesEmpty = (num_v_all_l < NV_all); + + bool hop_done = true; + // 2-1-1. growing many hops + // 2-1-2. if empty, add a new start vertex then continue growing + do { + if (q_par[p].empty()) { + printf("empty_par=%d num_v_all_l=%ld %ld\n", p, num_v_all_l, NV_all); + hop_done = true; + continue; + } + HopV hv = q_par[p].front(); + q_par[p].pop(); + + if (hv.hop > num_hop[p]) num_hop[p] = hv.hop; + + BFSPar_AddNeighbors(G, + p, // + V_selected, // inout, for recording whether a vertex is selected + hv.v, hv.hop, + // output + elist_par, num_e_dir, num_e_dir_lg, num_v_l, num_v_g, + map_v_l, // std:map for local vertices, will be used for renumbering and creating M + map_v_g, // std:map for ghost vertices, will be used for renumbering and creating M + q_par, map_v_l_scaned, num_hop); + notQueueEmpty = !q_par[p].empty(); + // notAllQueuesEmpty|= notQueueEmpty; + + if (num_v_l[p] >= MAX_PAR_VERTEX) { + printf("!!!! break on the max vertex!!!%ld\n", MAX_PAR_VERTEX); + break; + } + if (mode_hop == 1 || mode_hop == 2) + hop_done = isHopDone(q_par[p], num_hop[p]); + else + hop_done = true; // Always true if checking one vertext + } while (!hop_done); + + // printf("limit_v=%d, num_v_all_l=%d, num_v_l[%d] = %d\n", MAX_PAR_VERTEX, num_v_all_l, p , num_v_l[p]); + // printf("queueEMP=%d, notall=%d\n", !notQueueEmpty , notAllQueuesEmpty ); + + if (!notQueueEmpty && notAllQueuesEmpty && (num_v_l[p] < MAX_PAR_VERTEX)) { + // printf("2-1-2. add a new start for the empty par-queue to continue growing the partition graph\n "); + long v_start; + if (mode_start == 0) + if (p < num_par - 1) // to make the last round + v_start = FindStartVertex(G, V_selected); + else { + v_start = FindStartVertexlastround(G, V_selected, laststart); + laststart = v_start; + } + else + v_start = p * (NV_all / num_par); + if (v_start < 0) { + printf(" ----all vertex selected, go to add ghost\n"); + break; + } + V_selected[v_start] = p + 1; // true; + HopV hv_start; + hv_start.hop = 0; + hv_start.v = v_start; + q_par[p].push(hv_start); + map_v_l[p][v_start] = num_v_l[p]; + num_v_l[p]++; + notQueueEmpty = true; + // printf(" ==== Empty case par=%d_push_v_start=%d, num_v_l[%d]=%d\n", p, v_start, p, num_v_l[p]); + } +#ifdef DEBUGPAR + printf("cnt_hop_round=%d, notAllQueuesEmpty = %d\n", cnt_hop_round++, notAllQueuesEmpty); +#endif + } // while one partition + + // 2-2. add all queue vertex to the partition and ghost + while (!q_par[p].empty()) { + HopV hv = q_par[p].front(); + q_par[p].pop(); + + addGhostAfterPartition(G, + p, // + V_selected, // inout, for recording whether a vertex is selected + hv.v, hv.hop, + // output + elist_par, num_e_dir, num_e_dir_lg, num_v_l, num_v_g, + map_v_l, // std:map for local vertices, will be used for renumbering and creating M + map_v_g, // std:map for ghost vertices, will be used for renumbering and creating M + q_par, map_v_l_scaned, num_hop); + } + num_v_all_l += num_v_l[p]; + // printf("add ghost: limit_v=%d, num_v_all_l=%d, num_v_l[%d] = %d, num_hop[p]=%d\n", limit_v, num_v_all_l, p , + // num_v_l[p], num_hop[p] ); + + // 2-3.find the next partition's start vertex + if (p < num_par - 1) { + num_v_l[p + 1] = 0; + long v_start; + + if (mode_start == 0) + v_start = FindStartVertex(G, V_selected); + else + v_start = (p + 1) * (NV_all / num_par); + // assert(v_start>0); + if (v_start < 0) { + // all vertex selected, but not edges + break; + } + V_selected[v_start] = p + 1 + 1; // true; + HopV hv_start; + hv_start.hop = 0; + hv_start.v = v_start; + q_par[p + 1].push(hv_start); + map_v_l[p + 1][v_start] = num_v_l[p + 1]; + num_v_l[p + 1]++; + printf("par=%d, _push_v_start=%ld, num_v_l[%d]=%ld ------------\n", p + 1, v_start, p + 1, num_v_l[p + 1]); + + num_v_g[p + 1] = 0; + num_e_dir[p + 1] = 0; + num_e_dir_lg[p + 1] = 0; + num_hop[p + 1] = 0; + } + } // for all partition +} + +// find the v in the map and renum use the second value of map +bool MapRenumber(map& map_v, long v, long& renum) { + map::iterator storedAlready = map_v.find(v); + if (storedAlready != map_v.end()) { + renum = storedAlready->second; + // printf("renum %ld to %ld\n", v, renum); + return true; + } else { + return false; + } +} + +// step-3: renumbering the head and tail in edge lists +void BFSPar_renumberingEdgeLists( // return: real number of partition + int num_par, + edge* elist_par[], + long num_e_dir[], + long num_e_dir_lg[], + long num_v_l[], + long num_v_g[], + map map_v_l[], // std:map for local vertices, will be used for renumbering and creating M + map map_v_g[], // std:map for ghost vertices, will be used for renumbering and creating M + long* M[]) { +// map_v_l first value is v_global(key), second value is renum (value++) +#pragma omp parallel for + for (int p = 0; p < num_par; p++) { + for (int i = 0; i < num_e_dir[p]; i++) { + edge e = elist_par[p][i]; + long head = e.head; + long tail = e.tail; + long renum_h_l = 0; + long renum_t_l = 0; + long renum_h_g = 0; + long renum_t_g = 0; + bool isIn_h_l = MapRenumber(map_v_l[p], head, renum_h_l); + bool isIn_t_l = MapRenumber(map_v_l[p], tail, renum_t_l); + // bool isIn_h_g = isInMap(map_v_g, head); + // bool isIn_t_g = isInMap(map_v_g, tail); + if (isIn_h_l && isIn_t_l) { // is local + elist_par[p][i].head = renum_h_l; + elist_par[p][i].tail = renum_t_l; + M[p][renum_h_l] = head; + M[p][renum_t_l] = tail; + } else if (isIn_h_l && (!isIn_t_l)) { // tail is ghost + MapRenumber(map_v_g[p], tail, renum_t_g); + // printf("tail %ld, %ld \n",tail, renum_t_g+num_v_l[p]); + elist_par[p][i].head = renum_h_l; + elist_par[p][i].tail = renum_t_g + num_v_l[p]; + M[p][renum_h_l] = head; + M[p][renum_t_g + num_v_l[p]] = (-1) * tail - 1; + } else if (!isIn_h_l && isIn_t_l) { // head is ghost and swap + MapRenumber(map_v_g[p], head, renum_h_g); + // printf("h %ld, %ld \n",head, renum_h_g+num_v_l[p]); + elist_par[p][i].head = renum_h_g + num_v_l[p]; + elist_par[p][i].tail = renum_t_l; + M[p][renum_h_g + num_v_l[p]] = (-1) * head - 1; + M[p][renum_t_l] = tail; + } else { + printf("ERROR: in %s\n", __FUNCTION__); + } + + } // end edgelist per partition + + printf("check edgelist: \n"); + // for(int i = 0; i < num_e_dir[p]; i++){ + // printf("check_par:%3d, \t edge_%d_%d\n", p, elist_par[p][i].head, elist_par[p][i].tail); + //} + + // convert to M + // for(int i=0; i < num_v_l[p]; i++){ + // M[p][map_v_l[p][i]] = i; + // } + + printf("check M: \n"); + // for(int i = 0; i < num_v_l[p]+num_v_g[p]; i++){ + // printf("check_M:%3d, \t M[%d]=%lld\n", p, i, M[p][i]); + //} + + } // end all partition +} + +void BFS_par_general_4TG( + // Input data from TG + long numVertices, + long numEdges, + long* offsets_tg, + edge* edgelist_tg, + long* drglist_tg, // no use in bfs + char* path_prefix, + // no use new + long start_parInGlb, // Start vertex for each partition + long stride_par, // Total local vertex. Number of ghost vertex is not available until partition finish + // + int& id_glv, // ID counter's reference for GLV obejects created. Any integer with any value is OK here; + int th_maxGhost, // Ghost prunning parameter, always be '1'. It can be set by command-lin + int num_par, + GLV* parlv_par_src[MAX_PARTITION]) { + // input + const int mode_start = 0; + const int mode_hop = 2; + graphNew* G = (graphNew*)malloc(sizeof(graphNew)); + G->edgeListPtrs = offsets_tg; + G->edgeList = edgelist_tg; + G->numVertices = numVertices; + G->numEdges = numEdges; + t_sel* V_selected; //, //inout, for recording whether a vertex is selected + // output + edge* elist_par[num_par]; //, + long* tmp_M_v[num_par]; + long num_e_dir[num_par]; // + long num_e_dir_lg[num_par]; //, + long num_v_l[num_par]; //, + long num_v_g[num_par]; //, + map map_v_l[num_par]; //,//std:map for local vertices, will be used for renumbering and creating M + map map_v_g[num_par]; ////std:map for ghost vertices, will be used for renumbering and creating M + for (int p = 0; p < num_par; p++) { + elist_par[p] = (edge*)malloc(sizeof(edge) * (G->numEdges)); + tmp_M_v[p] = (long*)malloc(sizeof(long) * (G->numVertices)); + } + V_selected = (t_sel*)malloc(sizeof(t_sel) * (G->numVertices)); + memset(V_selected, 0, sizeof(t_sel) * (G->numVertices)); + + BFSPar_creatingEdgeLists_fixed_prune( + mode_start, mode_hop, G, num_par, + V_selected, // inout, for recording whether a vertex is selected + // drglist_tg, + // output + elist_par, num_e_dir, num_e_dir_lg, num_v_l, num_v_g, + map_v_l, // std:map for local vertices, will be used for renumbering and creating M + map_v_g // std:map for ghost vertices, will be used for renumbering and creating M + ); + + BFSPar_renumberingEdgeLists(num_par, elist_par, num_e_dir, num_e_dir_lg, num_v_l, num_v_g, map_v_l, map_v_g, + tmp_M_v); + + // 2-3. generate GLV + for (int p = 0; p < num_par; p++) { + // int id_glv = p+1; + graphNew* Gnew = (graphNew*)malloc(sizeof(graphNew)); + GLV* glv = new GLV(id_glv); + printf("par%d num_v = %ld,num_e_dir = %ld \n", p, (num_v_l[p] + num_v_g[p]), num_e_dir[p]); + GetGFromEdge(Gnew, elist_par[p], (num_v_l[p] + num_v_g[p]), num_e_dir[p]); + glv->SetByOhterG(Gnew); + glv->SetM(tmp_M_v[p]); + glv->SetName_par(glv->ID, p, p, p, 0); + + parlv_par_src[p] = glv; + } + + // check + // for(int i=0; inumVertices; i++){ + // printf(" V_selected[%d] = %d \t\n", i, V_selected[i]); + // } + + // connect V_selected with map_v_l+map_v_l to bfs_adjacent + + bfs_selected* bfs_adjacent = (bfs_selected*)malloc(sizeof(bfs_selected) * (G->numVertices)); + for (int p = 0; p < num_par; p++) { + for (map::iterator itr = map_v_l[p].begin(); itr != map_v_l[p].end(); ++itr) { + int v = itr->first; + bfs_adjacent[v].par_idx = V_selected[v] - 1; + bfs_adjacent[v].renum_in_par = itr->second; + } + } + + // check + // for(int v=0; vnumVertices; v++) + // printf(" v= %d, par= %d, renum= %d\n", v, bfs_adjacent[v].par_idx, bfs_adjacent[v].renum_in_par); + // save adjacent + + char tailName[125] = ".bfs.adj"; + char pathName[1024]; + strcpy(pathName, path_prefix); + strcat(pathName, tailName); + // sprintf(fullName, "_proj.bfs.adj\0", wfileName.c_str()); + string fn = pathName; + FILE* f = fopen(fn.c_str(), "wb"); + std::cout << "WARNING: " << fn << " will be opened for binary write." << std::endl; + if (!f) { + std::cerr << "ERROR: " << fn << " cannot be opened for binary write." << std::endl; + } + long nv = G->numVertices; + // fprintf(f, "*Vertices %ld\n", G->numVertices); + // fprintf(f, "v\t par\t renum\t\n"); + // for(int v=0; vnumVertices; v++) + // fprintf(f, " %d\t %d\t %d\t\n", v, bfs_adjacent[v].par_idx, bfs_adjacent[v].renum_in_par); + fwrite(&nv, sizeof(long), 1, f); + fwrite(bfs_adjacent, sizeof(bfs_adjacent), nv, f); + fclose(f); + + free(V_selected); + for (int p = 0; p < num_par; p++) { + free(elist_par[p]); + free(tmp_M_v[p]); + } +} + +pair ParLV::FindCM_1hop_bfs(int idx, long e_org, long addr_v) { + pair ret; + // long addr_v = e_org - off_src[idx]; + long c_src_sync = par_src[idx]->C[addr_v]; + long c_lved_new = c_src_sync; // key logic + long m_lved_new = par_lved[idx]->M[c_lved_new]; + ret.first = c_lved_new; + ret.second = m_lved_new; + return ret; +} + +long ParLV::FindC_nhop_bfs(long m_g) { + assert(m_g < 0); + long m_next = m_g; + int cnt = 0; + + do { + long e_org = -m_next - 1; + int idx = bfs_adjacent[e_org].par_idx; // FindParIdx(e_org); + long addr_v = bfs_adjacent[e_org].renum_in_par; + // dbg + // long v_src = e_org - off_src[idx]; // dbg + // dbg + pair cm = FindCM_1hop_bfs(idx, e_org, addr_v); + long c_lved_new = cm.first; + long m_lved_new = cm.second; + + // debug begin + // printf("DBG:FindC:cnt=%d, m:%-4d --> e_org:%-4d, idx:%-2d, --> v_src:%-4d, c_src&lved:%-4d, m_lved:%-4d --> + // c_new:%d", + // cnt, m_next, e_org, idx, addr_v, c_lved_new, m_lved_new, + // c_lved_new + off_lved[idx]); + // if(m_lved_new>=0) + // printf("-> c_new:%d\n",c_lved_new + off_lved[idx]); + // else + // printf("\n"); + // debug end + + cnt++; + + if (m_lved_new >= 0) + return c_lved_new + off_lved[idx]; + else if (m_lved_new == m_g) { + return m_g; + } else { // m_lved_new<0; + m_next = m_lved_new; + } + + } while (cnt < 2 * num_par); + return m_g; // no local community for the ghost which should be add as a new community +} + +#endif + +// end bfs partition method to get BFS subgraph + +int xai_save_partition_bfs( + // long numVertices, + // long numEdges, + long* offsets_tg, + edge* edgelist_tg, + long* drglist_tg, + long start_vertex, // If a vertex is smaller than star_vertex, it is a ghost + long end_vertex, // If a vertex is larger than end_vertex-1, it is a ghost + char* path_prefix, // For saving the partition files like _xxx.par + // Different server can have different path_prefix + int par_prune, // Can always be set with value '1' + long NV_par_requested, // NV requested per partition + long NV_par_max // 64*1000*1000; + ) { + long NV_server = end_vertex - start_vertex; + long NV_par = (NV_par_requested <= NV_par_max) ? NV_par_requested : NV_par_max; + int num_par = (NV_server + NV_par- 1) / NV_par; + long numEdges = offsets_tg[NV_server]; +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << "\n start_vertex=" << start_vertex << "\n end_vertex=" << end_vertex + << "\n path_prefix=" << path_prefix << "\n NV_par_requested=" << NV_par_requested + << "\n NV_par_max=" << NV_par_max << "\n NV_server=" << NV_server << "\n numEdges=" << numEdges + << "\n NV_par=" << NV_par << "\n num_par=" << num_par << std::endl; +#endif + int status = 0; + + GLV* parlv_par_src[MAX_PARTITION]; + int id_glv = 0; + long average_stride = 0; // NV_par_requested; + long start_vertext_par = 0; // start_vertex; + int p = 0; + // while (start_vertext_par != end_vertex) { + // long NV_par = 0;//(end_vertex - start_vertext_par ) > average_stride ? average_stride: end_vertex - + // start_vertext_par; + + do { + BFS_par_general_4TG( + // Input data from TG + NV_server, // numVertices, + numEdges, offsets_tg, edgelist_tg, drglist_tg, path_prefix, + // Partition parameters + start_vertext_par, // Start vertex for each partition + NV_par, // Total local vertex. Number of ghost vertex is not available until partition finish + id_glv, // ID counter's reference for GLV obejects created. Any integer with any value is OK here; + par_prune, // Ghost prunning parameter, always be '1'. It can be set by command-lin + num_par, + // output + parlv_par_src); + bool deletePar = false; + for (int p = 0; p < num_par; p++) { + long diff_NV = NV_par_max - parlv_par_src[p]->NV; + // std::cout << "DEBUG: after par_general_4TG " + // << "\n NV_par=" << NV_par + // << "\n diff_NV=" << diff_NV + // << "\n parlv_par_src[p]->NV=" << parlv_par_src[p]->NV + // << std::endl; + if (diff_NV < 0) { + deletePar = true; + break; + } + } + for (int p = 0; p < num_par; p++) { + if (deletePar) { + delete (parlv_par_src[p]); + parlv_par_src[p] = NULL; + std::cout << "WARNING: partition NV_par > NV_par_MAX caused num_par++ " << std::endl; + num_par++; + } + } + } while (parlv_par_src[0] == + NULL); // If the partition is too big to load on FPGA, reduce the NV_par until partition is small enough + + for (int p = 0; p < num_par; p++) { + char nm[1024]; + sprintf(nm, "_%03d.par", p); + parlv_par_src[p]->SetName(nm); + char pathName[1024]; + strcpy(pathName, path_prefix); + strcat(pathName, nm); + status = SaveGLVBin(pathName, parlv_par_src[p], false); + if (status < 0) return status; + } + // start_vertext_par += NV_par; + // p++; + //} + std::cout << "INFO: Total number of partitions created: " << num_par << std::endl; + return num_par; +} + +GLV* par_general_4TG(long start_vertexInGlb, + long* offsets_tg, + edge* edgelist_tg, + long* drglist_tg, + long start_parInGlb, + long stride_par, + int& id_glv, + int th_maxGhost) { + SttGPar stt; + GLV* ret = stt.ParNewGlv_Prun(start_vertexInGlb, offsets_tg, edgelist_tg, drglist_tg, start_parInGlb, stride_par, + id_glv, th_maxGhost); + return ret; +} + +int xai_save_partition(long* offsets_tg, + edge* edgelist_tg, + long* drglist_tg, + long start_vertex, // If a vertex is smaller than star_vertex, it is a ghost + long end_vertex, // If a vertex is larger than end_vertex-1, it is a ghost + char* path_prefix, // For saving the partition files like _xxx.par + // Different server can have different path_prefix + int par_prune, // Can always be set with value '1' + long NV_par_requested, // NV requested per partition + long NV_par_max // 64*1000*1000; + ) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << "\n start_vertex=" << start_vertex << "\n end_vertex=" << end_vertex + << "\n path_prefix=" << path_prefix << "\n NV_par_requested=" << NV_par_requested + << "\n NV_par_max=" << NV_par_max << std::endl; +#endif + int status = 0; + + long NV_server = end_vertex - start_vertex; + GLV* parlv_par_src[MAX_PARTITION]; + int id_glv = 0; + long average_stride = NV_par_requested; + long start_vertext_par = start_vertex; + int p = 0; + while (start_vertext_par != end_vertex) { + long NV_par = + (end_vertex - start_vertext_par) > average_stride ? average_stride : end_vertex - start_vertext_par; + + do { + parlv_par_src[p] = par_general_4TG( + // Input data from TG + start_vertex, offsets_tg, edgelist_tg, drglist_tg, + // Partition parameters + start_vertext_par, // Start vertex for each partition + NV_par, // Total local vertex. Number of ghost vertex is not available until partition finish + id_glv, // ID counter's reference for GLV obejects created. Any integer with any value is OK here; + par_prune // Ghost prunning parameter, always be '1'. It can be set by command-lin + ); + long diff_NV = NV_par_max - parlv_par_src[p]->NV; + // std::cout << "DEBUG: after par_general_4TG " + // << "\n NV_par=" << NV_par + // << "\n diff_NV=" << diff_NV + // << "\n parlv_par_src[p]->NV=" << parlv_par_src[p]->NV + // << std::endl; + if (diff_NV < 0) { + NV_par -= diff_NV; + delete (parlv_par_src[p]); + parlv_par_src[p] = NULL; + } + } while ( + parlv_par_src[p] == + NULL); // If the partition is too big to load on FPGA, reduce the NV_par until partition is small enough + char nm[1024]; + sprintf(nm, "_%03d.par", p); + parlv_par_src[p]->SetName(nm); + char pathName[1024]; + strcpy(pathName, path_prefix); + strcat(pathName, nm); + status = SaveGLVBin(pathName, parlv_par_src[p], false); + if (status < 0) return status; + start_vertext_par += NV_par; + p++; + } + std::cout << "INFO: Total number of partitions created: " << p << std::endl; + return p; +} + +void SaveParLV(char* name, ParLV* p_parlv) { + assert(name); + FILE* fp = fopen(name, "wb"); + char* ptr = (char*)p_parlv; + fwrite(ptr, sizeof(ParLVVar), 1, fp); + fclose(fp); +} + +const char* NameNoPath(const char* name) { + assert(name); + int len = strlen(name) - 1; + char c = name[len]; + while ((c != '/' && c != '\\' && c != '\n' && c != 0) && len > 0) { + c = name[--len]; + } + if (len == 0) + return name + len; + else + return name + len + 1; +} + +void PathNoName(char* des, const char* name) { + assert(name); + int len = strlen(name) - 1; + char c = name[len]; + while ((c != '/' && c != '\\' && c != '\n' && c != 0) && len > 0) { + c = name[--len]; + } + for (int i = 0; i < len; i++) des[i] = name[i]; + if (len > 0) + des[len++] = '/'; + else if (len == 0) { + des[len++] = '.'; + des[len++] = '/'; + } + des[len] = '\0'; +} + +int Phaseloop_InitColorBuff(graphNew* G, int* colors, int numThreads, double& totTimeColoring) { +#pragma omp parallel for + for (long i = 0; i < G->numVertices; i++) { + colors[i] = -1; + } + double tmpTime; + int numColors = algoDistanceOneVertexColoringOpt(G, colors, numThreads, &tmpTime) + 1; + totTimeColoring += tmpTime; + return numColors; +} + +long ParLV::MergingPar2_ll() { + // 1.create new edge list; + long num_e_dir = 0; + NEll = 0; + NEself = 0; + // long num_c_g = 0; + for (int p = 0; p < num_par; p++) { + GLV* G_src = par_src[p]; + GLV* G_lved = par_lved[p]; + long* vtxPtr = G_lved->G->edgeListPtrs; + edge* vtxInd = G_lved->G->edgeList; + for (int v = 0; v < G_lved->NVl; v++) { + assert(G_lved->M[v] >= 0); + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + long off_local = off_lved[p]; + long v_new = v + off_local; + long e_new; + p_v_new[p][v] = v_new; + // M_v[v_new] = v_new; + for (int d = 0; d < degree; d++) { + long e = vtxInd[adj1 + d].tail; + long me = G_lved->M[e]; + bool isGhost = me < 0; + if (v < e || isGhost) continue; + e_new = e + off_local; + double w = vtxInd[adj1 + d].weight; + elist[num_e_dir].head = v_new; + elist[num_e_dir].tail = e_new; + elist[num_e_dir].weight = w; + assert(v_new < this->NVl); + assert(e_new < this->NVl); + num_e_dir++; + NEll++; + if (v_new == e_new) NEself++; +#ifdef DBG_PAR_PRINT + printf( + "LOCAL: p=%-2d v=%-8ld mv=%-8ld v_new=%-8ld, e=%-8ld me=%-8ld e_new=%-8ld w=%-3.0f NE=%-8ld " + "NEself=%-8ld NEll=%-8ld \n", + p, v, 0, v_new, e, me, e_new, w, num_e_dir, NEself, NEll); +#endif + // AddEdge(elist, v, e, w, M_v); + } // for d + } // for v + } + st_Merged_ll = true; + return num_e_dir; +} + +long ParLV::MergingPar2_gh() { + long num_e_dir = 0; + + for (int p = 0; p < num_par; p++) { + GLV* G_src = par_src[p]; + GLV* G_lved = par_lved[p]; + long* vtxPtr = G_lved->G->edgeListPtrs; + edge* vtxInd = G_lved->G->edgeList; + + for (int v = G_lved->NVl; v < G_lved->NV; v++) { + long mv = G_lved->M[v]; // should be uniqe in the all sub-graph + assert(mv < 0); + // combination of possible connection: + // 1.1 C(head_gh)==Normal C and tail is local; + // + // 1.2 C(head_gh)==Normal C and tail is head_gh itself; + // + // 1.3.1 C(head_gh)==Normal C,and tail is other ghost in current sub graph and its C is normal + // + // 1.3.2 C(head_gh)==Normal C,and tail is other ghost in current sub graph and its C is other ghost , + // 2 C(head_gh) is other ghost + + long v_new = p_v_new[p][v]; /* + if(v_new <0 ){ + if(isOnlyGL) + continue; + v_new = FindOldOrAddNew(m_v_gh, this->NV_gh, v_new); + v_new += this->NVl;// Allocated a new community for local + }*/ + + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + long off_local = off_lved[p]; + // trace v + + for (int d = 0; d < degree; d++) { + double w = vtxInd[adj1 + d].weight; + long e = vtxInd[adj1 + d].tail; + long me = G_lved->M[e]; + bool isGhost = me < 0; + if (v < e) continue; + long e_new; + if (me >= 0) + e_new = e + off_local; + else if (me == mv) { + // assert (me == mv); + e_new = v_new; + NEself++; + NEgg++; + } else { + e_new = p_v_new[p][e]; + } + elist[NEll + num_e_dir].head = v_new; + elist[NEll + num_e_dir].tail = e_new; + elist[NEll + num_e_dir].weight = w; + // M_v[v_new] = v_new; + num_e_dir++; +#ifdef DBG_PAR_PRINT + printf( + "GHOST: p=%-2d v=%-8ld mv=%-8ld v_new=%-8ld, e=%-8ld me=%-8ld e_new=%-8ld w=%-3.0f NE=%-8ld " + "NEself=%-8ld NEgg=%-8ld \n", + p, v, mv, v_new, e, me, e_new, w, num_e_dir, NEself, NEgg); +#endif + } + // 1 findDesC; + } + } // for sub graph ; + + st_Merged_gh = true; + return num_e_dir; +} + +GLV* ParLV::MergingPar2(int& id_glv) { + long num_e_dir = 0; + // CheckGhost(); + num_e_dir += MergingPar2_ll(); + num_e_dir += MergingPar2_gh(); + NE = num_e_dir; + + graphNew* Gnew = (graphNew*)malloc(sizeof(graphNew)); + // std::cout << "------------" << __FUNCTION__ << " id_glv=" << id_glv << std::endl; + GLV* glv = new GLV(id_glv); + glv->SetName_ParLvMrg(num_par, plv_src->ID); +#ifdef PRINTINFO + printf("\033[1;37;40mINFO: PAR\033[0m: NV( %-8d) = NVl ( %-8d) + NV_gh( %-8d) \n", NV, NVl, NV_gh); + printf( + "\033[1;37;40mINFO: PAR\033[0m: NE( %-8d) = NEll( %-8d) + NElg ( %-8d) + NEgl( %-8d) + NEgg( %-8d) + NEself( " + "%-8d) \n", + NE, NEll, NElg, NEgl, NEgg, NEself); +#endif + GetGFromEdge_selfloop(Gnew, elist, this->NVl + this->NV_gh, num_e_dir); + glv->SetByOhterG(Gnew); + // glv->SetM(M_v); + st_Merged = true; + plv_merged = glv; + return glv; +} diff --git a/graph/L3/graphPartition/louvainPartition/partitionLouvain.cpp b/graph/L3/graphPartition/louvainPartition/partitionLouvain.cpp new file mode 100644 index 0000000000..dc43482c0d --- /dev/null +++ b/graph/L3/graphPartition/louvainPartition/partitionLouvain.cpp @@ -0,0 +1,1634 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WANCUNCUANTIES ONCU CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "defs.h" +#include "partitionLouvain.hpp" +//#include "ctrlLV.h" +//#include "louvainPhase.h" + +#ifdef PRINTINFO +#define PRINTINFO_PARLV +#endif + +void FreeG(graphNew*& G) { + free(G->edgeListPtrs); + free(G->edgeList); + free(G); +} + +void printG_org(graphNew* G) { + long vertexNum = G->numVertices; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + printf("v=%ld\t; e=%ld \n", vertexNum, NE); + for (long v = 0; v < vertexNum; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + long degree = adj2 - adj1; + printf("v=%4ld\t adj1=%4ld, adj2=%4ld, degree=%4ld\t", v, adj1, adj2, degree); + for (int d = 0; d < degree; d++) { + printf(" %4ld\t", vtxInd[adj1 + d].tail); + } + printf("\n"); + } +} + +void printG(graphNew* G, long* C, long* M, long star, long end) { + long NV = G->numVertices; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + printf("v=%ld\t; e=%ld \n", NV, NE); + if (star < 0) star = 0; + if (end > NV) end = NV; + // printf("|==C==|==V==|==M==|=OFF=|=Dgr=|\n"); + for (long v = star; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + long degree = adj2 - adj1; + // printf("c=%4ld : v=%4ld\t adj1=%4ld, adj2=%4ld, degree=%4ld\t",C[v], v, adj1, adj2, degree); + // printf("c=%4ld : v=%4ld\t adj1=%4ld, adj2=%4ld, degree=%4ld\t",C[v], v, adj1, adj2, degree); + // printf("c=%-4d : v=%-4d m=%-4d off=%4d, dgr=%-3d\t",C[v], v, M[v], adj1, degree); + long m = M == NULL ? v : M[v]; + long c = C == NULL ? v : C[v]; + // printf(" c=%-4d, v=%-4d,", c, v, m, adj1, degree); + if (m < 0) + printf(" \033[1;31;40mc=%-5ld v=%-5ld m=%-5ld\033[0m", c, v, m); + else + printf(" c=%-5ld v=%-5ld m=%-5ld", c, v, m); + printf(" o=%-5ld d=%-4ld |", adj1, degree); + for (long d = 0; d < degree; d++) { + //\033[1;31;40mERROR\033[0m + long t = vtxInd[adj1 + d].tail; + double w = vtxInd[adj1 + d].weight; + if (M != NULL && M[t] < 0) + printf("\033[1;31;40m%5ld\033[0m/%1.0f ", t, w); + else + printf("%5ld/%1.0f ", t, w); + } + printf("\n"); + } +} +void printG(graphNew* G, long* C, long* M, long star, long end, bool isCid, bool isDir, ParLV* p_par, int idx) { + long NV = G->numVertices; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + printf("v=%ld\t; e=%ld \n", NV, NE); + if (star < 0) star = 0; + if (end > NV) end = NV; + // printf("|==C==|==V==|==M==|=OFF=|=Dgr=|\n"); + for (long v = star; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + long degree = adj2 - adj1; + long m = M == NULL ? v : M[v]; + long c = C == NULL ? v : C[v]; + long c_final = c + p_par->off_lved[idx]; + // printf(" c=%-4d, v=%-4d,", c, v, m, adj1, degree); + if (m < 0) { + if (p_par->st_PreMerged == true) c_final = p_par->p_v_new[idx][v]; + printf(" \033[1;31;40mc=%-5ld (%-5ld) v=%-5ld m=%-5ld c(m)=%-5ld\033[0m", c, c_final, v, m, + p_par->FindC_nhop(m)); + } else + printf(" c=%-5ld (%-5ld) v=%-5ld m=%-5ld c(m)=%-5ld", c, c_final, v, m, c); + printf(" o=%-5ld d=%-4ld |", adj1, degree); + for (long d = 0; d < degree; d++) { + long t = vtxInd[adj1 + d].tail; + if (isDir) { + if (isCid) { + if (C[v] < C[t]) continue; + } else { + if (v < t) continue; + } + } + double w = vtxInd[adj1 + d].weight; + if (M != NULL && M[t] < 0) + printf("\033[1;31;40m%5ld\033[0m/%1.0f ", (isCid ? C[t] : t), w); + else + printf("%5ld/%1.0f ", (isCid ? C[t] : t), w); + } + printf("\n"); + } +} +void printG(graphNew* G, long* C, long* M, long star, long end, bool isCid, bool isDir) { + long NV = G->numVertices; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + printf("v=%ld\t; e=%ld \n", NV, NE); + if (star < 0) star = 0; + if (end > NV) end = NV; + // printf("|==C==|==V==|==M==|=OFF=|=Dgr=|\n"); + for (long v = star; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + long degree = adj2 - adj1; + long m = M == NULL ? v : M[v]; + long c = C == NULL ? v : C[v]; + + if (m < 0) + printf(" \033[1;31;40mc=%-5ld v=%-5ld m=%-5ld\033[0m", c, v, m); + else + printf(" c=%-5ld v=%-5ld m=%-5ld", c, v, m); + + printf(" o=%-5ld d=%-4ld |", adj1, degree); + for (int d = 0; d < degree; d++) { + long t = vtxInd[adj1 + d].tail; + if (isDir) { + if (isCid) { + if (C[v] < C[t]) continue; + } else { + if (v < t) continue; + } + } + double w = vtxInd[adj1 + d].weight; + if (M != NULL && M[t] < 0) + printf("\033[1;31;40m%5ld\033[0m/%1.0f ", isCid ? C[t] : t, w); + else + printf("%5ld/%1.0f ", isCid ? C[t] : t, w); + } + printf("\n"); + } +} +void printG(char* name, graphNew* G, long* C, long* M, long star, long end) { + FILE* fp = fopen(name, "w"); + if (fp == NULL) return; + long NV = G->numVertices; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + fprintf(fp, "v=%ld\t; e=%ld \n", NV, NE); + if (star < 0) star = 0; + if (end > NV) end = NV; + // printf("|==C==|==V==|==M==|=OFF=|=Dgr=|\n"); + for (long v = star; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + long degree = adj2 - adj1; + // printf("c=%4ld : v=%4ld\t adj1=%4ld, adj2=%4ld, degree=%4ld\t",C[v], v, adj1, adj2, degree); + // printf("c=%4ld : v=%4ld\t adj1=%4ld, adj2=%4ld, degree=%4ld\t",C[v], v, adj1, adj2, degree); + // printf("c=%-4d : v=%-4d m=%-4d off=%4d, dgr=%-3d\t",C[v], v, M[v], adj1, degree); + long m = M == NULL ? v : M[v]; + long c = C == NULL ? v : C[v]; + // printf(" c=%-4d, v=%-4d,", c, v, m, adj1, degree); + if (m < 0) + printf(" \033[1;31;40mc=%-5ld v=%-5ld m=%-5ld\033[0m", c, v, m); + else + printf(" c=%-5ld v=%-5ld m=%-5ld", c, v, m); + if (m < 0) + fprintf(fp, "[c=%-5ld v=%-5ld m=%-5ld]", c, v, m); + else + fprintf(fp, " c=%-5ld v=%-5ld m=%-5ld", c, v, m); + fprintf(fp, " o=%-5ld d=%-4ld |", adj1, degree); + for (long d = 0; d < degree; d++) { + //\033[1;31;40mERROR\033[0m + long t = vtxInd[adj1 + d].tail; + double w = vtxInd[adj1 + d].weight; + if (M != NULL && M[t] < 0) + fprintf(fp, "[%5ld]%1.0f ", t, w); + else + fprintf(fp, "%5ld/%1.0f ", t, w); + if (M != NULL && M[t] < 0) + printf("\033[1;31;40m%5ld\033[0m/%1.0f ", t, w); + else + printf("%5ld/%1.0f ", t, w); + } + fprintf(fp, "\n"); + } + fclose(fp); +} +void printG_NOWeight(graphNew* G, long* C, long* M, long star, long end) { + long NV = G->numVertices; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + printf("v=%ld\t; e=%ld \n", NV, NE); + if (star < 0) star = 0; + if (end > NV) end = NV; + // printf("|==C==|==V==|==M==|=OFF=|=Dgr=|\n"); + for (long v = star; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + long degree = adj2 - adj1; + // printf("c=%4ld : v=%4ld\t adj1=%4ld, adj2=%4ld, degree=%4ld\t",C[v], v, adj1, adj2, degree); + // printf("c=%4ld : v=%4ld\t adj1=%4ld, adj2=%4ld, degree=%4ld\t",C[v], v, adj1, adj2, degree); + // printf("c=%-4d : v=%-4d m=%-4d off=%4d, dgr=%-3d\t",C[v], v, M[v], adj1, degree); + long m = M == NULL ? v : M[v]; + long c = C == NULL ? v : C[v]; + // printf(" c=%-4d, v=%-4d,", c, v, m, adj1, degree); + if (m < 0) + printf(" \033[1;31;40mc=%-5ld v=%-5ld m=%-5ld\033[0m", c, v, m); + else + printf(" c=%-5ld v=%-5ld m=%-5ld", c, v, m); + printf(" o=%-5ld d=%-4ld |", adj1, degree); + for (int d = 0; d < degree; d++) { + //\033[1;31;40mERROR\033[0m + long t = vtxInd[adj1 + d].tail; + if (M != NULL && M[t] < 0) + printf("\033[1;31;40m%5ld\033[0m ", t); + else + printf("%5ld ", t); + } + printf("\n"); + } +} + +void printG_old2(graphNew* G, long* C, long* M, long star, long end) { + long NV = G->numVertices; + long NE = G->numEdges; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + printf("v=%ld\t; e=%ld \n", NV, NE); + if (star < 0) star = 0; + if (end > NV) end = NV; + for (long v = star; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + long degree = adj2 - adj1; + printf("c=%-4ld : v=%-4ld m=%-4ld off=%4ld, dgr=%-3ld\t", C[v], v, M[v], adj1, degree); + for (long d = 0; d < degree; d++) { + printf(" %4ld ", vtxInd[adj1 + d].tail); + } + printf("\n"); + } +} + +void printG(graphNew* G, long* C, long* M) { + long NV = G->numVertices; + printG(G, C, M, 0, NV); +} + +void printG(graphNew* G, long* C) { + long NV = G->numVertices; + printG(G, C, NULL, 0, NV); +} +long CountV(graphNew* G, long star, long end) { + long NV = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + if (star < 0) star = 0; + if (end > NV) end = NV; + map map_all; + map::iterator iter_all; + long cnt = 0; + for (long v = star; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + if (map_all.find(v) == map_all.end()) map_all[cnt] = cnt++; + + for (int d = 0; d < degree; d++) { + long e = vtxInd[adj1 + d].tail; + if (map_all.find(e) == map_all.end()) map_all[cnt] = cnt++; + } // for + } + return cnt; +} + +long CountV(graphNew* G) { + long NV = G->numVertices; + return CountV(G, 0, NV); +} + +long CountVGh(graphNew* G, long star, long end) { + long NV = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + if (star < 0) star = 0; + if (end > NV) end = NV; + map map_all; + map::iterator iter_all; + long cnt = 0; + for (long v = star; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + + // if(map_all.find(v) == map_all.end()) + // map_all[cnt] = cnt++; + + for (int d = 0; d < degree; d++) { + long e = vtxInd[adj1 + d].tail; + if (e < star || e >= end) { + if (map_all.find(e) == map_all.end()) map_all[e] = cnt++; + } + } // for + } + return cnt; +} + +long CountVGh(graphNew* G) { + long NV = G->numVertices; + return CountVGh(G, 0, NV); +} +void CreateSubG(graphNew* G_src, long start, long size, graphNew* G_sub, long* M_sub2src, long* M_sub2ghost) { + long end = start + size; + long NV_s = G_src->numVertices; + long NE_s = G_src->numEdges; + long* off_s = G_src->edgeListPtrs; + edge* edge_s = G_src->edgeList; + + map clusterLocalMap; // Map each neighbor's cluster to a local number + map::iterator storedAlready; + long numUniqueClusters = 0; + + long num_v_par = 0; + long num_e_par = 0; + long v = start; + map map_ghost; + map map_all; + map::iterator iter_ghost; + map::iterator iter_all; + + while (1) { + long adj1 = off_s[v]; + long adj2 = off_s[v + 1]; + int dgr = adj2 - adj1; + iter_all = map_all.find(v); + } + + for (long v = start; v < end; v++) { + long adj1 = off_s[v]; + long adj2 = off_s[v + 1]; + int degree = adj2 - adj1; + for (long e = 0; e < degree; e++) { + long head = edge_s[v + e].head; + long tail = edge_s[v + e].tail; + bool isHeadin = (head >= start) && (head < end); + bool isTailin = (tail >= start) && (tail < end); + bool isEgAllIn = isHeadin && isTailin; + bool isEgAllOut = (!isHeadin) && (!isTailin); + bool isOnlyHeadIn = isHeadin && (!isTailin); + bool isOnlyTailIn = isTailin && (!isHeadin); + long head_m; + long tail_m; + + // Remap the head and tail + if (isEgAllOut) { + continue; + } else { + storedAlready = clusterLocalMap.find(head); + if (storedAlready != clusterLocalMap.end()) { + head_m = storedAlready->second; // Renumber the cluster id + } else { + clusterLocalMap[head] = numUniqueClusters; ////Does not exist, add to the map + head_m = numUniqueClusters; // Renumber the cluster id + numUniqueClusters++; // Increment the number + } + storedAlready = clusterLocalMap.find(tail); + if (storedAlready != clusterLocalMap.end()) { + tail_m = storedAlready->second; // Renumber the cluster id + } else { + clusterLocalMap[tail] = numUniqueClusters; ////Does not exist, add to the map + tail_m = numUniqueClusters; // Renumber the cluster id + numUniqueClusters++; // Increment the number + } + } + edge_s[v + e].head = head_m; + edge_s[v + e].tail = tail_m; + } + } +} + +void CopyG(graphNew* G_scr, graphNew* G_des) { + long NV = G_scr->numVertices; + long NE = G_scr->numEdges; + G_des->numEdges = NE; + G_des->numVertices = NV; + + long* vtxPtr = G_scr->edgeListPtrs; + edge* vtxInd = G_scr->edgeList; + long* vtxPtr2 = G_des->edgeListPtrs; + edge* vtxInd2 = G_des->edgeList; + + for (int v = 0; v < NV; v++) { + long adj1 = vtxPtr[0 + v]; + long adj2 = vtxPtr[0 + v + 1]; + vtxPtr2[v] = adj1 - 0; + vtxPtr2[v + 1] = adj2 - 0; + int degree = adj2 - adj1; + long adj1_des = vtxPtr2[v]; + for (int d = 0; d < degree; d++) { + vtxInd2[adj1_des + d].head = vtxInd[adj1 + d].head; + vtxInd2[adj1_des + d].tail = vtxInd[adj1 + d].tail; + vtxInd2[adj1_des + d].weight = vtxInd[adj1 + d].weight; + } + } +} + +graphNew* CloneGbad(graphNew* G_scr) { + long NV = G_scr->numVertices; + long NE = G_scr->numEdges; + graphNew* G_des = (graphNew*)malloc(sizeof(graphNew)); + G_des->edgeListPtrs = (long*)malloc(sizeof(long) * (NV + 1)); + G_des->edgeList = (edge*)malloc(sizeof(edge) * NE); + CopyG(G_scr, G_des); + return G_des; +} + +void CreatSubG(long head, long end_line, graphNew* G_scr, graphNew* G_des) { + long NV = G_scr->numVertices; + long* vtxPtr = G_scr->edgeListPtrs; + edge* vtxInd = G_scr->edgeList; + long NE = G_scr->numEdges; + G_des->numVertices = G_scr->numVertices; + G_des->numEdges = G_scr->numEdges; + G_des->edgeListPtrs = (long*)malloc(sizeof(long) * (NV + 1)); + long base_edge = vtxPtr[head]; + long size_edge = vtxPtr[head + end_line] - base_edge; + G_des->edgeList = (edge*)malloc(sizeof(edge) * size_edge); + long* vtxPtr2 = G_des->edgeListPtrs; + edge* vtxInd2 = G_des->edgeList; + + for (int v = 0; v < NV; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + if (v >= head && v < (head + end_line)) { + vtxPtr2[v] = adj1 - base_edge; // txPtr[head] + vtxPtr2[v + 1] = adj2 - base_edge; // txPtr[head] + long adj1_des = vtxPtr2[v]; + for (int d = 0; d < degree; d++) { + vtxInd2[adj1_des + d].head = vtxInd[adj1 + d].head; + vtxInd2[adj1_des + d].tail = vtxInd[adj1 + d].tail; + vtxInd2[adj1_des + d].weight = vtxInd[adj1 + d].weight; + } + } else if (v < head) { + vtxPtr2[v] = 0; + vtxPtr2[v + 1] = 0; + } else { + vtxPtr2[v] = size_edge; + vtxPtr2[v + 1] = size_edge; + } + } +} + +graphNew* CloneG(graphNew* G_scr) { + long NV = G_scr->numVertices; + graphNew* G_des = (graphNew*)malloc(sizeof(graphNew)); + CreatSubG(0, NV, G_scr, G_des); + return G_des; +} + +void InitC(long* C, long NV) { + assert(C); + for (int i = 0; i < NV; i++) C[i] = i; +} + +///////////////////////////////////////////////////////////////////////////////////// +/// GLV////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////// + +GLV::GLV(int& id) { + InitVar(); + ID = id; + sprintf(name, "%d", id); + id++; +} + +GLV::~GLV() { + FreeMem(); +} + +void GLV::InitVar() { + G = 0; + C = 0; + M = 0; + colors = 0; + NC = NElg = NVl = 0; + NV = -1; + NE = -1; + numColors = -1; + numThreads = 1; + Q = 0; + times.parNo = -1; // No partition +}; +void GLV::FreeMem() { + if (G) FreeG(G); + if (C) free(C); + if (M) free(M); + if (colors) free(colors); +} +void GLV::CleanCurrentG() { + if (G != 0) { +#ifdef PRINTINFO_PARLV + printf("GLV: Current G is not empty!!!: \n"); + printf("GLV: To be clean G in GLV: "); + printSimple(); + // displayGraphCharacteristics(G); + printf("GLV: FreeMem\n"); +#endif + FreeMem(); +#ifdef PRINTINFO_PARLV + printf("GLV: InitVar\n"); +#endif + InitVar(); + } +} + +void GLV::InitByFile(char* name_file) { + double totTimeColoring; + CleanCurrentG(); + G = host_PrepareGraph(3, name_file, 0); + SyncWithG(); + InitM(); + // displayGraphCharacteristics(G); + printf("INFO: GLV: NV = %ld\t NE = %ld\t numColor = %d \n", NV, NE, numColors); +} +void GLV::InitByOhterG(graphNew* G_orig) { + assert(G_orig); + CleanCurrentG(); + G = CloneG(G_orig); + SyncWithG(); + InitM(); + printf("INFO: GLV: NV = %ld\t NE = %ld\t numColor = %d \n", NV, NE, numColors); +} +void GLV::SetByOhterG(graphNew* G_src) { + assert(G_src); + CleanCurrentG(); + G = G_src; + SyncWithG(); + InitM(); +#ifdef PRINTINFO_PARLV + printf("GLV: NV = %ld\t NE = %ld\t numColor = %d \n", NV, NE, numColors); +#endif +} +void GLV::RstNVlByM() { + NVl = 0; + for (int i = 0; i < NV; i++) + if (M[i] >= 0) NVl++; +} +void GLV::RstNVElg() { + NElg = 0; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + for (long v = 0; v < NV; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + if (M[v] < 0) continue; + for (long k = adj1; k < adj2; k++) { + edge e = vtxInd[k]; + if (M[e.tail] < 0) NElg++; + } + } // for v +} +void GLV::SetByOhterG(graphNew* G_src, long* M_src) { + assert(G_src); + CleanCurrentG(); + G = G_src; + SyncWithG(); + if (M) free(M); + M = M_src; + RstNVlByM(); + RstNVElg(); +#ifdef PRINTINFO_PARLV + printf("GLV: NV = %ld\t NE = %ld\t numColor = %d \n", NV, NE, numColors); +#endif +} + +void GLV::SetM(long* M_src) { + assert(M_src); + assert(G); + NVl = 0; + for (int i = 0; i < NV; i++) { + M[i] = M_src[i]; + if (M[i] >= 0) NVl++; + } + RstNVElg(); +} + +void GLV::SetM() { + assert(G); + for (int i = 0; i < NV; i++) M[i] = i; + NVl = NV; +} + +void GLV::InitM(long* M_src) { + assert(M_src); + assert(G); + NV = G->numVertices; + NE = G->numEdges; + if (M) { + printf("GLV: InitM: M is not empty and will be free and re-allocated.\n"); + free(M); + } + M = (long*)malloc(NV * sizeof(long)); + SetM(M_src); +} + +void GLV::InitM() { + assert(G); + NV = G->numVertices; + NE = G->numEdges; + if (M) { + printf("GLV: InitM: M is not empty and will be free and re-allocated.\n"); + free(M); + } + M = (long*)malloc(NV * sizeof(long)); + SetM(); +} + +void GLV::SetC(long* C_src) { + assert(C_src); + assert(G); + NV = G->numVertices; + NE = G->numEdges; + for (int i = 0; i < NV; i++) C[i] = C_src[i]; +} +void GLV::SetC() { + assert(G); + NV = G->numVertices; + NE = G->numEdges; + for (int i = 0; i < NV; i++) C[i] = i; + NC = NV; +} +void GLV::InitC(long* C_src) { + assert(C_src); + assert(G); + NV = G->numVertices; + NE = G->numEdges; + if (C) { +#ifdef PRINTINFO_PARLV + printf("GLV: InitC: C is not empty and will be free and re-allocated.\n"); +#endif + free(C); + } + C = (long*)malloc(NV * sizeof(long)); + SetC(C_src); +} +void GLV::InitC() { + assert(G); + NV = G->numVertices; + NE = G->numEdges; + if (C) { +#ifdef PRINTINFO_PARLV + printf("GLV: InitC: C is not empty and will be free and re-allocated.\n"); +#endif + free(C); + } + C = (long*)malloc(NV * sizeof(long)); + SetC(); +} +void GLV::ResetColor() { + double totTimeColoring; + numColors = Phaseloop_InitColorBuff(G, colors, numThreads, totTimeColoring); +} +void GLV::ResetC() { + this->com_list.clear(); + InitC(); /* + FeatureLV f1(this); + f1.PrintFeature(); + com_list.push_back(f1);*/ +} +void GLV::SyncWithG() { + double totTimeColoring; + assert(G); + if (NV < G->numVertices) { + if (C) free(C); + C = (long*)malloc(G->numVertices * sizeof(long)); + if (colors) free(colors); + colors = (int*)malloc(G->numVertices * sizeof(int)); + } + NV = G->numVertices; + NE = G->numEdges; + ResetColor(); + ResetC(); +} +void GLV::InitG(graphNew* G_src) { + assert(G_src); + if (G) CleanCurrentG(); + G = CloneG(G_src); + NV = G->numVertices; + NE = G->numEdges; +} +void GLV::SetName(char* nm) { + strcpy(name, nm); +}; +void GLV::InitColor() { + // double totTimeColoring; + assert(G); + NV = G->numVertices; + NE = G->numEdges; + if (colors) free(colors); + colors = (int*)malloc(G->numVertices * sizeof(int)); + ResetColor(); +} +void GLV::print() { + printSimple(); + assert(G); + assert(C); + assert(M); + printG(G, C, M); +} + +void GLV::printSimple() { + // list::iterator iter = com_list.back(); + // list::iterator iter = com_list[com_list.size() - 1]; + // Q = com_list.back().Q; + // long NC = this->NC;//com_list.back().NC; + if (NC == NV) + printf("| GLV ID: %-2d| NC/NV: \033[1;37;40m%8ld\033[0m/", ID, NC); + else + printf("| GLV ID: %-2d| NC/NV: \033[1;31;40m%8ld\033[0m/", ID, NC); + if (NV < (1)) { + if (NV == NVl) + printf(" \033[1;37;40m%-3ld\033[0m(%-3ld/%2d%%)", NV, (NV - NVl), + (int)(100 * (float)(NV - NVl) / (float)NV)); + else + printf(" \033[1;37;40m%-3ld\033[0m(%-3ld/%2d%%)", NV, (NV - NVl), + (int)(100 * (float)(NV - NVl) / (float)NV)); + } else if (NV < (1000000)) { + if (NV == NVl) + printf(" \033[1;37;40m%-6ld\033[0m(%-5ld/%2d%%)", NV, (NV - NVl), + (int)(100 * (float)(NV - NVl) / (float)NV)); + else + printf(" \033[1;37;40m%-6ld\033[0m(%-5ld/%2d%%)", NV, (NV - NVl), + (int)(100 * (float)(NV - NVl) / (float)NV)); + } else { + if (NV == NVl) + printf(" \033[1;37;40m%-6ld\033[0m(%-8ld/%2d%%)", NV, (NV - NVl), + (int)(100 * (float)(NV - NVl) / (float)NV)); + else + printf(" \033[1;37;40m%-6ld\033[0m(%-8ld/%2d%%)", NV, (NV - NVl), + (int)(100 * (float)(NV - NVl) / (float)NV)); + } + if (NE < (1000)) { + if (NElg == 0) + printf(" NE: %9ld(%-9ld/%2d%%)| Colors:%-6d ", NE, NElg, (int)(100 * (float)NElg / (float)NE), numColors); + else + printf(" NE: %9ld(%-9ld/%2d%%)| Colors:%-6d ", NE, NElg, (int)(100 * (float)NElg / (float)NE), numColors); + } else if (NE < (1000000)) { + if (NElg == 0) + printf(" NE: %9ld(%-9ld/%2d%%)| Colors:%-6d ", NE, NElg, (int)(100 * (float)NElg / (float)NE), numColors); + else + printf(" NE: %9ld(%-9ld/%2d%%)| Colors:%-6d ", NE, NElg, (int)(100 * (float)NElg / (float)NE), numColors); + } else { + if (NElg == 0) + printf(" NE: %9ld(%-9ld/%2d%%)| Colors:%-6d ", NE, NElg, (int)(100 * (float)NElg / (float)NE), numColors); + else + printf(" NE: %9ld(%-9ld/%2d%%)| Colors:%-6d ", NE, NElg, (int)(100 * (float)NElg / (float)NE), numColors); + } + if (Q > 0) + printf(" Q: \033[1;32;40m%1.6f\033[0m ", Q); + else + printf(" Q:\033[1;37;40m%2.6f\033[0m ", Q); + printf("| name: %s \n", name); +} + +void GLV::PushFeature(int ph, int iter, double time, bool FPGA) { + FeatureLV f1(this); + f1.No_phase = ph; + f1.Num_iter = iter; + f1.time = time; + f1.isFPGA = FPGA; + this->com_list.push_back(f1); + this->NC = f1.NC; + this->Q = f1.Q; +} + +void GLV::printFeature() { + list::iterator iter = com_list.begin(); + while (iter != com_list.end()) { + (*iter).PrintFeature(); + iter++; + } +} + +void GLV::SetName_par(int ID_par, int ID_src, long start, long end, int th) { + char nm[256]; + sprintf(nm, "ID_%d_ParID_%d_%ld_%ld_th%d", ID_par, ID_src, start, end, th); + this->SetName(nm); +} + +void GLV::SetName_lv(int ID_par, int ID_src) { + char nm[256]; + sprintf(nm, "ID_%d_lv_ID_%d", ID_par, ID_src); + this->SetName(nm); +} + +void GLV::SetName_ParLvMrg(int num_par, int ID_src) { + char nm[256]; + sprintf(nm, "ID_%d_Mrg_lv_Par%d_ID_%d", ID, num_par, ID_src); + this->SetName(nm); +} + +void GLV::SetName_loadg(int ID_curr, char* path) { + char nm[256]; + sprintf(nm, "ID_%d_%s", ID_curr, path); + this->SetName(nm); +} + +void GLV::SetName_cat(int ID_src1, int ID_src2) { + char nm[256]; + sprintf(nm, "ID_%d_cat_ID_%d_ID%d", ID, ID_src1, ID_src2); + this->SetName(nm); +} + +//////////////////////////////////////////////////////////////////////////// +SttGPar::SttGPar(long s, long e) { + assert(e > s); + start = s; + end = e; + num_v = num_e = num_e_dir = num_e_ll_dir = 0; + num_v_l = num_v_g = 0; + num_e_ll = num_e_lg = num_e_gl = num_e_gg = 0; +} + +SttGPar::SttGPar() { + num_v = num_e = num_e_dir = num_e_ll_dir = 0; + num_v_l = num_v_g = 0; + num_e_ll = num_e_lg = num_e_gl = num_e_gg = 0; +} + +void SttGPar::PrintStt() { + printf("**SttGPar::PrintStt BEGIN**\n"); + printf("From %ld to %ld \n", start, end); + num_v_l = end - start; + printf("Total V : %ld\t Total Vl : %ld\t Total Vg: %ld\t Vl/V=%2.2f%% \n", num_v, num_v_l, num_v_g, + (float)num_v_l / (float)num_v * 100.0); + assert(num_e_lg == num_e - num_e_ll); + printf("Total 2E: %ld\t Total ll : %ld\t Total lg: %ld\t ll/E=%2.2f%% \n", num_e, num_e_ll, num_e_lg, + (float)num_e_ll / (float)num_e * 100.0); + printf("Total|E|: %ld\t Total |ll|: %ld\t Total lg: %ld\t |ll|/|E|=%2.2f%% \n", num_e_dir, num_e_ll_dir, num_e_lg, + (float)num_e_ll_dir / (float)num_e_dir * 100.0); + printf("**SttGPar::PrintStt END**\n"); +} + +bool SttGPar::InRange(long v) { + return v >= start && v < end; +} + +void SttGPar::AddEdge(edge* edges, long head, long tail, double weight, long* M_g) { + long head_m = head - start; + long off = end - start; + long tail_m; + map::iterator itr; + num_e++; + // num_e + if (InRange(tail)) { + num_e_ll++; + if (head <= tail) { + tail_m = tail - start; + edges[num_e_dir].head = head_m; + edges[num_e_dir].tail = tail_m; + edges[num_e_dir].weight = weight; + num_e_ll_dir++; + num_e_dir++; + } + } else { + itr = map_v_g.find(tail); + if (itr == map_v_g.end()) { + tail_m = num_v_g + off; + M_g[tail_m] = -tail - 1; // using negtive to indicate it ghost + map_v_g[tail] = num_v_g++; + // printf("NODIR(%ld)\t: lg:<%ld %ld> -> <%ld %ld> \t= %ld + %ld \n", num_e_dir, head, tail, head_m, + // tail_m, num_v_g, off); + } else { + tail_m = itr->second + off; + // printf("NODIR(%ld)\t: lg:<%ld %ld> -> <%ld %ld> \t= %ld + %ld \n", num_e_dir, head, tail, head_m, + // tail_m, itr->second, off); + } + edges[num_e_dir].head = head_m; + edges[num_e_dir].tail = tail_m; + edges[num_e_dir].weight = weight; + num_e_lg++; + num_e_dir++; + } + num_v_l = end - start; + num_v = num_v_l + num_v_g; +} + +long SttGPar::findAt(VGMinDgr& gMinDgr, long tail, long dgr, long num_vg, int th_maxGhost) { + long index = 0; + long low = 0, high; + + if (th_maxGhost == 1) { + if (dgr < gMinDgr.dgrs[0] || (dgr == gMinDgr.dgrs[0] && tail < gMinDgr.tail[0])) + return 0; + else + return -1; + } else if (th_maxGhost > 1) { // th_maxGhost > 1 && num_vg < th_maxGhost + high = num_vg < th_maxGhost ? num_vg - 1 : th_maxGhost - 1; + if (dgr < gMinDgr.dgrs[0] || (dgr == gMinDgr.dgrs[0] && tail < gMinDgr.tail[0])) + return 0; + else { + while (low <= high) { + index = (low + high) / 2; + if (dgr == gMinDgr.dgrs[index] && tail == gMinDgr.tail[index]) + return -1; + else if (dgr < gMinDgr.dgrs[index] || (dgr == gMinDgr.dgrs[index] && tail < gMinDgr.tail[index])) + high = index - 1; + else if (dgr > gMinDgr.dgrs[index] || (dgr == gMinDgr.dgrs[index] && tail > gMinDgr.tail[index])) + low = index + 1; + } + return low; + } + } else + return -1; +} + +void SttGPar::EdgePruning(edge* edges, + long head, + long tail, + double weight, + long* M_g, + VGMinDgr& gMinDgr, + long& num_vg, + long& e_dgr, + int th_maxGhost) { + long head_m = head - start; + long tail_m; + + // num_e + if (InRange(tail)) { + num_e++; + num_e_ll++; + if (head <= tail) { + tail_m = tail - start; + // printf("NODIR(%ld)\t: ll:<%ld %ld> -> <%ld %ld> \t= %ld - %ld \n", num_e_dir, head, tail, head_m, tail_m, + // tail, start); + edges[num_e_dir].head = head_m; + edges[num_e_dir].tail = tail_m; + edges[num_e_dir].weight = weight; + num_e_ll_dir++; + num_e_dir++; + } + } else { + // printf("tail=%ld dgr= %ld \n", tail, e_dgr); + if (num_vg == 0) { + gMinDgr.tail[0] = tail; + gMinDgr.dgrs[0] = e_dgr; + gMinDgr.wght[0] = weight; + } else { + long at = findAt(gMinDgr, tail, e_dgr, num_vg, th_maxGhost); + if (at >= 0 && at < th_maxGhost) { + long where = num_vg < th_maxGhost ? num_vg : (th_maxGhost - 1); + for (int i = where; i > at; i--) { + gMinDgr.tail[i] = gMinDgr.tail[i - 1]; + gMinDgr.dgrs[i] = gMinDgr.dgrs[i - 1]; + gMinDgr.wght[i] = gMinDgr.wght[i - 1]; + } + gMinDgr.tail[at] = tail; + gMinDgr.dgrs[at] = e_dgr; + gMinDgr.wght[at] = weight; + // printf("insert: at= %ld \n", at); + } + } + num_vg++; + } +} + +void SttGPar::CountVPruning(graphNew* G, long st, long ed, int th_maxGhost) { + assert(G); + assert(ed > st); + + start = st; + end = ed; + long NV = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + assert(end <= NV); + long ne = vtxPtr[end] - vtxPtr[start]; + edge* elist = (edge*)malloc(sizeof(edge) * (ne)); + long* M_g = (long*)malloc(sizeof(long) * (NV)); + + // long off = end - start; + + long off = end - start; + for (int i = 0; i < NV; i++) { + M_g[i] = i < off ? i + start : -2; + } + for (long v = start; v < end; v++) { + map::iterator itr; + VGMinDgr gMinDgr; + long num_vg = 0; + long e_dgr = 0; + long head_m = 0, tail_m = 0; + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + for (int d = 0; d < degree; d++) { + long e = vtxInd[adj1 + d].tail; + double w = vtxInd[adj1 + d].weight; + e_dgr = vtxPtr[e + 1] - vtxPtr[e]; + head_m = v - start; + EdgePruning(elist, v, e, w, M_g, gMinDgr, num_vg, e_dgr, th_maxGhost); + } // for + long smallest = num_vg < th_maxGhost ? num_vg : th_maxGhost; + for (int i = 0; i < smallest; i++) { + itr = map_v_g.find(gMinDgr.tail[i]); + if (itr == map_v_g.end()) { + tail_m = num_v_g + off; + M_g[tail_m] = -gMinDgr.tail[i] - 1; + map_v_g[gMinDgr.tail[i]] = num_v_g++; + } else { + tail_m = itr->second + off; + } + elist[num_e_dir].head = head_m; + elist[num_e_dir].tail = tail_m; + elist[num_e_dir].weight = gMinDgr.wght[i]; + num_e_lg++; + num_e_dir++; + num_e++; + printf("vertex= %ld\t nGhost= %ld\t sGhost= %ld\t degree= %ld\t\n", v, num_vg, gMinDgr.tail[i], + gMinDgr.dgrs[i]); + } + } + + num_v_l = end - start; + num_v = num_v_l + num_v_g; + graphNew* Gnew = (graphNew*)malloc(sizeof(graphNew)); + GetGFromEdge(Gnew, elist, num_v, num_e_dir); + // printG(Gnew); + printG(Gnew, M_g); + FreeG(Gnew); + free(elist); + free(M_g); +} + +void SttGPar::CountV(graphNew* G, long st, long ed, edge* elist, long* M_g) { + assert(G); + assert(ed > st); + start = st; + end = ed; + long NV = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + assert(end <= NV); + long ne = vtxPtr[end] - vtxPtr[start]; + elist = (edge*)malloc(sizeof(edge) * (ne)); + M_g = (long*)malloc(sizeof(long) * (NV)); + + // long off = end - start; + + long off = end - start; + for (int i = 0; i < NV; i++) { + M_g[i] = i < off ? i + start : -2; + } + for (long v = start; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + for (int d = 0; d < degree; d++) { + long e = vtxInd[adj1 + d].tail; + double w = vtxInd[adj1 + d].weight; + AddEdge(elist, v, e, w, M_g); + } // for + } + graphNew* Gnew = (graphNew*)malloc(sizeof(graphNew)); + GetGFromEdge(Gnew, elist, num_v, num_e_dir); + // printG(Gnew); + printG(Gnew, M_g); + FreeG(Gnew); + free(elist); + free(M_g); +} + +void SttGPar::CountV(graphNew* G, long st, long ed) { + assert(G); + assert(ed > st); + start = st; + end = ed; + long NV = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + assert(end <= NV); + long ne = vtxPtr[end] - vtxPtr[start]; + edge* elist = (edge*)malloc(sizeof(edge) * (ne)); + long* M_g = (long*)malloc(sizeof(long) * (NV)); + + // long off = end - start; + + long off = end - start; + for (int i = 0; i < NV; i++) { + M_g[i] = i < off ? i + start : -2; + } + for (long v = start; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + for (int d = 0; d < degree; d++) { + long e = vtxInd[adj1 + d].tail; + double w = vtxInd[adj1 + d].weight; + AddEdge(elist, v, e, w, M_g); + } // for + } + graphNew* Gnew = (graphNew*)malloc(sizeof(graphNew)); + GetGFromEdge(Gnew, elist, num_v, num_e_dir); + // printG(Gnew); + printG(Gnew, M_g); + FreeG(Gnew); + free(elist); + free(M_g); +} + +GLV* CloneGlv(GLV* glv_src, int& id_glv) { + assert(glv_src); + GLV* glv = new GLV(id_glv); + glv->InitG(glv_src->G); + glv->InitC(glv_src->C); + glv->InitM(glv_src->M); + glv->InitColor(); + return glv; +} +GLV* GLV::CloneSelf(int& id_glv) { + GLV* glv = new GLV(id_glv); + glv->Q = this->Q; + glv->InitG(G); + glv->InitC(C); + glv->InitM(M); + glv->InitColor(); + return glv; +} +GLV* GLV::CloneSelf_lite(int& id_glv) { + GLV* glv = new GLV(id_glv); + glv->Q = this->Q; + glv->G = this->G; + glv->NV = this->NV; + glv->NC = this->NV; + glv->NE = this->NE; + glv->NVl = this->NVl; + glv->NElg = this->NElg; + glv->InitC(C); + glv->InitM(M); + glv->InitColor(); + return glv; +} +GLV* SttGPar::ParNewGlv(graphNew* G_src, long st, long ed, int& id_glv) { + assert(G_src); + assert(ed > st); + start = st; + end = ed; + long NV = G_src->numVertices; + long* vtxPtr = G_src->edgeListPtrs; + edge* vtxInd = G_src->edgeList; + assert(end <= NV); + + long ne = vtxPtr[end] - vtxPtr[start]; + edge* elist = (edge*)malloc(sizeof(edge) * (ne)); + long* M_v = (long*)malloc(sizeof(long) * (NV)); // address by v + + long off = end - start; + for (int i = 0; i < NV; i++) { + M_v[i] = i < off ? i + start : -2; + } + + for (long v = start; v < end; v++) { + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + for (int d = 0; d < degree; d++) { + long e = vtxInd[adj1 + d].tail; + double w = vtxInd[adj1 + d].weight; + AddEdge(elist, v, e, w, M_v); + } // for + } + graphNew* Gnew = (graphNew*)malloc(sizeof(graphNew)); + GLV* glv = new GLV(id_glv); + + GetGFromEdge(Gnew, elist, num_v, num_e_dir); + glv->SetByOhterG(Gnew); + glv->SetM(M_v); + // printG(Gnew); + // FreeG(Gnew); + free(elist); + free(M_v); + glv->NVl = ed - st; + glv->RstNVElg(); + return glv; +} + +GLV* SttGPar::ParNewGlv_Prun(graphNew* G, long st, long ed, int& id_glv, int th_maxGhost) { + start = st; + end = ed; + long NV = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + assert(end <= NV); + long ne = vtxPtr[end] - vtxPtr[start]; + edge* elist = (edge*)malloc(sizeof(edge) * (ne)); + long* M_v = (long*)malloc(sizeof(long) * (NV)); + + // long off = end - start; + + long off = end - start; + for (int i = 0; i < NV; i++) { + M_v[i] = i < off ? i + start : -2; + } + for (long v = start; v < end; v++) { + map::iterator itr; + VGMinDgr gMinDgr; + long num_vg = 0; + long e_dgr = 0; + long head_m = 0, tail_m = 0; + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + for (int d = 0; d < degree; d++) { + long e = vtxInd[adj1 + d].tail; + double w = vtxInd[adj1 + d].weight; + e_dgr = vtxPtr[e + 1] - vtxPtr[e]; + head_m = v - start; + EdgePruning(elist, v, e, w, M_v, gMinDgr, num_vg, e_dgr, th_maxGhost); + } // for + long smallest = num_vg < th_maxGhost ? num_vg : th_maxGhost; + for (int i = 0; i < smallest; i++) { + itr = map_v_g.find(gMinDgr.tail[i]); + if (itr == map_v_g.end()) { + tail_m = num_v_g + off; + M_v[tail_m] = -gMinDgr.tail[i] - 1; + map_v_g[gMinDgr.tail[i]] = num_v_g++; + } else { + tail_m = itr->second + off; + } + elist[num_e_dir].head = head_m; + elist[num_e_dir].tail = tail_m; + elist[num_e_dir].weight = gMinDgr.wght[i]; + num_e_lg++; + num_e_dir++; + num_e++; + // printf("vertex= %ld\t nGhost= %ld\t sGhost= %ld\t degree= %ld\t\n", v, num_vg, gMinDgr.tail[i], + // gMinDgr.dgrs[i]); + } + } + num_v_l = end - start; + num_v = num_v_l + num_v_g; + graphNew* Gnew = (graphNew*)malloc(sizeof(graphNew)); + GLV* glv = new GLV(id_glv); + + GetGFromEdge(Gnew, elist, num_v, num_e_dir); + glv->SetByOhterG(Gnew); + glv->SetM(M_v); + // printG(Gnew); + // FreeG(Gnew); + free(elist); + free(M_v); + return glv; +} + +GLV* SttGPar::ParNewGlv_Prun(long start_tg, + long* offsets_tg, + edge* edgelist_tg, + long* dgrlist_tg, + long start_par, + long size_par, + int& id_glv, + int th_maxGhost) { + /*std::cout << "\nDEBUG: ParNewGlv_Prun " + << "\n size_par=" << size_par + << "\n id_glv=" << id_glv + << std::endl;*/ + start = start_par; // global ID of first local vertex (vertex in the partition) + long ed_par = start_par + size_par; // 1 + global ID of last local vertex + end = ed_par; + long NV_par_local = end - start; // number of local vertices + long NE_par = + offsets_tg[end - start_tg] - offsets_tg[start - start_tg]; // number of edges connected to local vertices + edge* elist = (edge*)malloc(sizeof(edge) * (NE_par)); // output partition edge list with local vertex IDs + + // Array of local IDs for all local vertices followed by encoded global IDs of ghost nodes for the current + // partition. The array size is the sum of the number of local nodes plus the number of edges to cover the + // worst-case scenario that every edge connects to a different ghost node. + const unsigned long M_v_size = NV_par_local + NE_par; + long* M_v = (long*)malloc(sizeof(long) * (M_v_size)); + + // long off = end - start; + + // Initialize M_v with all local vertices and set all possible ghost vertices to a dummy value + // std::cout << "DEBUG: M_v_size = " << M_v_size << std::endl; + for (int i = 0; i < M_v_size; i++) { + M_v[i] = i < NV_par_local ? i + start : -2; + } + long cnt_e_input = offsets_tg[start_par - start_tg]; // index of current edge (used for dgrlist_tg) + + // Iterate through all local vertices of the partition, building the output edgelist + for (long v = start; v < end; v++) { + map::iterator itr; + VGMinDgr gMinDgr; // list of ghost vertices for the current local vertex sorted from smallest degree to largest + long num_vg = 0; // number of ghost vertices for the current local vertex + long head_m = 0, tail_m = 0; // locally (to the partition) renumbered vertices of the current edge + long adj1 = offsets_tg[v - start_tg]; // index of first edge of current vertex + long adj2 = offsets_tg[v + 1 - start_tg]; // 1 + index of last edge of current vertex + int degree = adj2 - adj1; // number of edges of current vertex + + // Add each edge of v to elist (if tail is local) or gMinDgr (if tail is a ghost) + for (int d = 0; d < degree; d++) { + long e = edgelist_tg[adj1 + d].tail; + double w = edgelist_tg[adj1 + d].weight; + long e_dgr2 = dgrlist_tg[cnt_e_input]; + head_m = v - start; + EdgePruning(elist, v, e, w, M_v, gMinDgr, num_vg, e_dgr2, th_maxGhost); + cnt_e_input++; + } + + // Add edges for ghost nodes collected in gMinDgr, limited to th_maxGhost edges + long smallest = num_vg < th_maxGhost ? num_vg : th_maxGhost; + for (int i = 0; i < smallest; i++) { + itr = map_v_g.find(gMinDgr.tail[i]); + if (itr == map_v_g.end()) { + tail_m = num_v_g + NV_par_local; // next free slot in M_v + M_v[tail_m] = -gMinDgr.tail[i] - 1; // Save encoded global ID of ghost node in M_v + map_v_g[gMinDgr.tail[i]] = num_v_g++; // Maps from ghost global ID to slot in M_v + } else { + tail_m = itr->second + NV_par_local; // Reuse ghost node already seen + } + elist[num_e_dir].head = head_m; + elist[num_e_dir].tail = tail_m; + elist[num_e_dir].weight = gMinDgr.wght[i]; + num_e_lg++; + num_e_dir++; + num_e++; + // printf("DBG_PAR:vertex= %ld\t nGhost= %ld\t sGhost= %ld\t degree= %ld\t\n", v, num_vg, gMinDgr.tail[i], + // gMinDgr.dgrs[i]); + } + } + + // Convert the new edgelist and M_v into a GLV. The offset list is inferred from the edgelist. + + num_v_l = end - start; + num_v = num_v_l + num_v_g; + graphNew* Gnew = (graphNew*)malloc(sizeof(graphNew)); + GLV* glv = new GLV(id_glv); + + GetGFromEdge(Gnew, elist, num_v, num_e_dir); + glv->SetByOhterG(Gnew); + glv->SetM(M_v); + + free(elist); + free(M_v); + return glv; +} + +void SttGPar::CountV(graphNew* G, edge* elist, long* M_g) { + long NV = G->numVertices; + return CountV(G, 0, NV, elist, M_g); +} +void SttGPar::CountV(graphNew* G) { + long NV = G->numVertices; + return CountV(G, 0, NV); +} + +void GetGFromEdge(graphNew* G, edge* edgeListTmp, long num_v, long num_e_dir) { + // Parse the first line: + long NV = num_v, ED = num_e_dir * 2, NE = num_e_dir; + + printf("|V|= %ld, |E|= %ld \n", NV, NE); + + // Remove duplicate entries: + // Allocate for Edge Pointer and keep track of degree for each vertex + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); +#pragma omp parallel for + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + __sync_fetch_and_add(&edgeListPtr[edgeListTmp[i].head + 1], 1); // Plus one to take care of the zeroth location + __sync_fetch_and_add(&edgeListPtr[edgeListTmp[i].tail + 1], 1); + } + + // Build the EdgeListPtr Array: Cumulative addition + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } + // The last element of Cumulative will hold the total number of characters + printf("DEBUG: Sanity Check: 2|E| = %ld, edgeListPtr[NV]= %ld\n", NE * 2, edgeListPtr[NV]); + + edge* edgeList = (edge*)malloc((2 * NE) * sizeof(edge)); // Every edge stored twice + assert(edgeList != 0); + // Keep track of how many edges have been added for a vertex: + long* added = (long*)malloc(NV * sizeof(long)); + assert(added != 0); +#pragma omp parallel for + for (long i = 0; i < NV; i++) added[i] = 0; + + // Build the edgeList from edgeListTmp: + //#pragma omp parallel for + for (long i = 0; i < NE; i++) { + long head = edgeListTmp[i].head; + long tail = edgeListTmp[i].tail; + double weight = edgeListTmp[i].weight; + + long Where = edgeListPtr[head] + __sync_fetch_and_add(&added[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + // added[head]++; + // Now add the counter-edge: + Where = edgeListPtr[tail] + __sync_fetch_and_add(&added[tail], 1); + edgeList[Where].head = tail; + edgeList[Where].tail = head; + edgeList[Where].weight = weight; + // added[tail]++; + } + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + // free(edgeListTmp); + free(added); +} + +long GetGFromEdge_selfloop(graphNew* G, edge* edgeListTmp, long num_v, long num_e_dir) { + long NV = num_v, ED = num_e_dir * 2, NE = num_e_dir; +// Remove duplicate entries: +/* long NewEdges = removeEdges(NV, NE, edgeListTmp); + if (NewEdges < NE) { + printf("GetGFromEdge_selfloop: Number of duplicate entries detected: %ld\n", NE-NewEdges); + NE = NewEdges; //Only look at clean edges + }*/ +#ifdef PRINTINFO_PARLV + printf("|V|= %ld, |E|= %ld \n", NV, NE); +#endif + + long* edgeListPtr = (long*)malloc((NV + 1) * sizeof(long)); +#pragma omp parallel for + for (long i = 0; i <= NV; i++) edgeListPtr[i] = 0; // For first touch purposes + +#pragma omp parallel for + for (long i = 0; i < NE; i++) { + __sync_fetch_and_add(&edgeListPtr[edgeListTmp[i].head + 1], 1); // Plus one to take care of the zeroth location + if (edgeListTmp[i].head != edgeListTmp[i].tail) __sync_fetch_and_add(&edgeListPtr[edgeListTmp[i].tail + 1], 1); + } + //////Build the EdgeListPtr Array: Cumulative addition + for (long i = 0; i < NV; i++) { + edgeListPtr[i + 1] += edgeListPtr[i]; // Prefix Sum: + } +// The last element of Cumulative will hold the total number of characters +#ifdef PRINTINFO_PARLV + printf("Sanity Check: 2|E| = %ld, edgeListPtr[NV]= %ld GetGFromEdge_selfloop\n", NE * 2, edgeListPtr[NV]); +#endif + // printf("About to allocate memory for graph data structures\n"); + edge* edgeList = (edge*)malloc((2 * NE) * sizeof(edge)); // Every edge stored twice + assert(edgeList != 0); + // Keep track of how many edges have been added for a vertex: + long* added = (long*)malloc(NV * sizeof(long)); + assert(added != 0); +#pragma omp parallel for + for (long i = 0; i < NV; i++) added[i] = 0; + + // printf("About to build edgeList...\n"); + // Build the edgeList from edgeListTmp: + //#pragma omp parallel for + for (long i = 0; i < NE; i++) { + long head = edgeListTmp[i].head; + long tail = edgeListTmp[i].tail; + double weight = edgeListTmp[i].weight; + + long Where = edgeListPtr[head] + __sync_fetch_and_add(&added[head], 1); + edgeList[Where].head = head; + edgeList[Where].tail = tail; + edgeList[Where].weight = weight; + // added[head]++; + // Now add the counter-edge: + // printf("GetGFromEdge_selfloop e=%-6d head=%-6d tail=%-6d w=%-4.0f where(%d)=%d + added[head](%d) \n",i, head, + // tail, weight, Where, edgeListPtr[head], added[head]); + if (head != tail) { + Where = edgeListPtr[tail] + __sync_fetch_and_add(&added[tail], 1); + edgeList[Where].head = tail; + edgeList[Where].tail = head; + edgeList[Where].weight = weight; + } + // added[tail]++; + } + + G->sVertices = NV; + G->numVertices = NV; + G->numEdges = NE; + G->edgeListPtrs = edgeListPtr; + G->edgeList = edgeList; + + // free(edgeListTmp); + free(added); + return NE; +} +////////////////////////////////////////////////////////////////// +double FeatureLV::ComputeQ(GLV* glv) { + assert(glv->G); + NV = glv->G->numVertices; + NE = glv->G->numEdges; + long* vtxPtr = glv->G->edgeListPtrs; + edge* vtxInd = glv->G->edgeList; + long* tot_m = (long*)malloc(sizeof(long) * NV); + for (int v = 0; v < NV; v++) tot_m[v] = 0; + m = 0; + for (int v = 0; v < NV; v++) { + long cid = glv->C[v]; + long adj1 = vtxPtr[v]; + long adj2 = vtxPtr[v + 1]; + int degree = adj2 - adj1; + for (int d = 0; d < degree; d++) { + long e = vtxInd[adj1 + d].tail; + double w = vtxInd[adj1 + d].weight; + long cide = glv->C[e]; + m += w; + tot_m[cide] += w; + if (cide == cid) totalIn += w; + } + } + NC = 0; + for (int v = 0; v < NV; v++) { + totalTot += tot_m[v] * tot_m[v]; + if (tot_m[v]) NC++; + } + Q = totalIn / m - totalTot / (m * m); + free(tot_m); + glv->Q = Q; + return Q; +} +double FeatureLV::ComputeQ2(GLV* glv) { + assert(glv->G); + NV = glv->G->numVertices; + NE = glv->G->numEdges; + long* vtxPtr = glv->G->edgeListPtrs; + edge* vtxInd = glv->G->edgeList; + long* tot_m = (long*)malloc(sizeof(long) * NV); + for (int v = 0; v < NV; v++) tot_m[v] = 0; + m = 0; + for (int e = 0; e < NE; e++) { + long head = vtxInd[e].head; + long tail = vtxInd[e].tail; + double w = vtxInd[e].weight; + long cid = glv->C[head]; + long cide = glv->C[tail]; + m += w; + tot_m[cide] += w; + if (cide == cid) totalIn += w; + } + NC = 0; + for (int v = 0; v < NV; v++) { + totalTot += tot_m[v] * tot_m[v]; + if (tot_m[v]) NC++; + } + Q = totalIn / m - totalTot / (m * m); + free(tot_m); + return Q; +} +void FeatureLV::PrintFeature() { + printf("NC=%-8ld NV=%-8ld NE=%-8ld ", NC, NV, NE); + printf("Q=%-2.6f m=%-8.1f totalTot=%-14.1f totalIn=%-8.1f ", Q, m, totalTot, totalIn); + printf("No_phase=%-2d Num_iter=%-2d time=%-8.1f %s \n", No_phase, Num_iter, time, + isFPGA == true ? "FPGA" : "CPU"); +} +FeatureLV::FeatureLV(GLV* glv) { + init(); + ComputeQ(glv); +} +void FeatureLV::init() { + NV = NE = 0; + totalTot = totalIn = m = 0; + Q = -1; + NC = 0; + No_phase = Num_iter = 0; + time = 0; + isFPGA = true; +} +FeatureLV::FeatureLV() { + init(); +} // FeatureLV() + +////////////////////////////////////////////////////////////////////////////////////////// +int glb_cnt_glv = 0; +GLV* CreateByFile_general(char* inFile, int& id_glv) { + assert(inFile); + FILE* fp = fopen(inFile, "r"); + if (fp == NULL) { + printf("\033[1;31;40mERROR\033[0m: L3 can't open input file %s\n", inFile); + return NULL; + } else + fclose(fp); + GLV* glv_src = new GLV(id_glv); + glv_src->InitByFile(inFile); + return glv_src; +} + +GLV* CreateByFile_general(char* inFile) { + assert(inFile); + FILE* fp = fopen(inFile, "r"); + if (fp == NULL) { + printf("\033[1;31;40mERROR\033[0m: L3 can't open input file %s\n", inFile); + return NULL; + } else + fclose(fp); + GLV* glv_src = new GLV(glb_cnt_glv); + glv_src->InitByFile(inFile); + return glv_src; +} diff --git a/graph/L3/graphPartition/louvainPartition/xilinxlouvain.cpp b/graph/L3/graphPartition/louvainPartition/xilinxlouvain.cpp new file mode 100644 index 0000000000..fc4f576c4c --- /dev/null +++ b/graph/L3/graphPartition/louvainPartition/xilinxlouvain.cpp @@ -0,0 +1,515 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WANCUNCUANTIES ONCU CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xilinxlouvain.h" +#include "ParLV.h" +#include "op_louvainmodularity.hpp" +//#include "ctrlLV.h" +#include +#include +#include +#include +#include +#include + +namespace { + +using namespace xilinx_apps::louvainmod; + +// Max number of vertices that fit on one Alveo card +long NV_par_max = 64 * 1000 * 1000; +// Only use 80% NV_max to save 20% space for ghosts +long NV_par_max_margin = NV_par_max * 8 / 10; + +// Keeps all state for a partition run +// +class PartitionRun { + public: + const Options& globalOpts_; + // const ComputedSettings &settings_; + LouvainPar::PartitionOptions partOpts_; + bool isVerbose_ = false; + ParLV parlv_; + std::string projName_; + std::string projPath_; + std::vector parInServer_; // number of partitions for each server + std::string inputFileName_ = "no-file"; // file name for the source file for the graph, or a dummy string if no file + const int numServers = 1; + + PartitionRun(const Options& globalOpts, // const ComputedSettings &settings, + const LouvainPar::PartitionOptions& partOpts) + : globalOpts_(globalOpts), partOpts_(partOpts), isVerbose_(globalOpts.verbose) { + int kernelMode = globalOpts.kernelMode; + + if (kernelMode < 2 || kernelMode > 4) { + std::ostringstream oss; + oss << "Invalid kernelMode value " << kernelMode << ". The supported values are 2, 3 and 4."; + throw Exception(oss.str()); + } + + parlv_.Init(kernelMode, nullptr, partOpts.numPars, globalOpts.numDevices, true, partOpts.par_prune); + parlv_.num_par = partOpts.numPars; + parlv_.th_prun = partOpts.par_prune; + parlv_.num_server = numServers; + parlv_.use_bfs = partOpts.BFS_partition; + + if (globalOpts.nameProj.empty()) { + std::ostringstream oss1; + oss1 << "ERROR: Alveo project name is empty"; + throw Exception(oss1.str()); + } + //////////////////////////// Set the name for partition project//////////////////////////// + char path_proj[1024]; + char name_proj[256]; + std::strcpy(name_proj, NameNoPath(globalOpts.nameProj)); + PathNoName(path_proj, globalOpts.nameProj); + projName_ = name_proj; + projPath_ = path_proj; + +#ifdef PRINTINFO + printf("\033[1;37;40mINFO\033[0m:Partition Project: path = %s name = %s\n", path_proj, name_proj); +#endif + + parlv_.timesPar.timePar_all = getTime(); + parlv_.timesPar.timePar_save = 0.0; // Initialize in case we end up not writing to a file + } + + ~PartitionRun() {} + + void setFileName(const char* inFileName) { inputFileName_ = inFileName; } + + int addPartitionData(const LouvainPar::PartitionData& partitionData) { + // Determine the prefix string for each partition (.par) file + // For compatibility, when num_server is 1, no 'srv' surfix used + char pathName_proj_svr[1024]; + int serverNum = (partitionData.nodeId >= 0) ? partitionData.nodeId : globalOpts_.nodeId; + // Assign partitions to the current node. + // Node 0 (aka driver) gets the last partitions. + // All other nodes gets numPartitions/numNode partitions. + // Below is an example of partition assignment for 10 partitions on a 3-node cluster + // node 1 (aka worker 1): par_svr0_000.par par_svr0_001.par par_svr0_002.par + // node 2 (aka worker 2): par_svr1_000.par par_svr1_001.par par_svr1_002.par + // node 0 (aka driver) : par_svr2_000.par par_svr2_001.par par_svr2_002.par par_svr2_003.par + // if (globalOpts_.partitionNameMode == PartitionNameMode::Server + // || (globalOpts_.partitionNameMode == PartitionNameMode::Server && settings_.numServers > 1)) + // { + // int serverIndexAssigned = (serverNum == 0) ? (settings_.numServers-1) : (settings_.serverIndex-1); + // std::sprintf(pathName_proj_svr, "%s_svr%d", globalOpts_.nameProj.c_str(), serverIndexAssigned); + // } + // else + std::strcpy(pathName_proj_svr, globalOpts_.nameProj); // louvain_partitions_000.par + + // User requested NV per partition + long NV_par_requested = partitionData.NV_par_requested; + // No supplied desired partition size: calculate it + if (NV_par_requested == 0) { + int totalNumDevices = numServers * globalOpts_.numDevices; + + // Assume that we want one partition per Alveo card unless overridden by num_par or isWholeGraph option + int numPartitionsThisServer = (partitionData.isWholeGraph) ? totalNumDevices : globalOpts_.numDevices; + + // If num_par specifies more partitions than we have total number of devices in the cluster, + // create num_par devices instead. This feature is for testing partitioning of smaller graphs, + // but can also be used to pre-calculate the partitions for graphs that are so large that each + // Alveo card needs to process more than its maximum number of vertices. + if (partOpts_.numPars > totalNumDevices) { + // If we're in whole-graph mode, we'll create numPars partitions for this "server partition" + if (partitionData.isWholeGraph) numPartitionsThisServer = partOpts_.numPars; + + // Not whole-graph mode: this server partition represents a fraction of the total number of alveo + // partitions desired. Calculate the number of alveo partitions for this server partition by + // dividing the desired total number of alveo partitions (numPars) by the total number of server + // partitions expected, distributing any remainder among the servers. + else { + // Distribute partitions evenly among servers + numPartitionsThisServer = partOpts_.numPars / numServers; + + // Distribute the L leftover partitions (where L = servers % partitions) among the first + // L servers + int extraPartitions = partOpts_.numPars % numServers; + if (extraPartitions > serverNum) ++numPartitionsThisServer; + } + } + + // Determine the number of vertices for each partition on this server, which is the lesser of + // (a) 80% Alveo card capacity and (b) the number of vertices for this server divided by the number of + // partitions on this server. + NV_par_requested = NV_par_max_margin; + const long numVerticesThisServer = partitionData.end_vertex - partitionData.start_vertex; + const long numPartitionVertices = + (numVerticesThisServer + numPartitionsThisServer - 1) / numPartitionsThisServer; + if (numPartitionVertices < NV_par_requested) NV_par_requested = numPartitionVertices; + + std::cout << "INFO: automatically computed NV_par_requested=" << NV_par_requested << std::endl; + } else if (NV_par_requested > NV_par_max_margin) { + // making sure NV_par_requested is within NV_par_max_margin + NV_par_requested = NV_par_max_margin; + std::cout << "INFO: NV_par_requested is adjusted to NV_par_max_margin " << NV_par_requested << std::endl; + } else { + std::cout << "INFO: NV_par_requested is set to " << NV_par_requested << std::endl; + } + + int numPartitionsCreated = 0; + if (!partOpts_.BFS_partition) { + numPartitionsCreated = xai_save_partition( + const_cast(partitionData.offsets_tg), const_cast(partitionData.edgelist_tg), + const_cast(partitionData.drglist_tg), partitionData.start_vertex, partitionData.end_vertex, + pathName_proj_svr, // num_server==1? /louvain_partitions_ : louvain_partitions_svr + partOpts_.par_prune, // always be '1' + NV_par_requested, // Allow to partition small graphs not bigger than FPGA limitation + NV_par_max); + } else { + numPartitionsCreated = xai_save_partition_bfs( + const_cast(partitionData.offsets_tg), const_cast(partitionData.edgelist_tg), + const_cast(partitionData.drglist_tg), partitionData.start_vertex, partitionData.end_vertex, + pathName_proj_svr, // num_server==1? /louvain_partitions_ : louvain_partitions_svr + partOpts_.par_prune, // always be '1' + NV_par_requested, // Allow to partition small graphs not bigger than FPGA limitation + NV_par_max); + } + + if (numPartitionsCreated < 0) { + std::ostringstream oss; + oss << "ERROR: Failed to create Alveo partition #" << parInServer_.size() << " for server partition " + << "start_vertex=" << partitionData.start_vertex << ", end_vertex=" << partitionData.end_vertex << "."; + throw Exception(oss.str()); + } + parInServer_.push_back(numPartitionsCreated); + return numPartitionsCreated; + } + + void finishPartitioning(int numAlveoPartitions[]) { + parlv_.st_Partitioned = true; + parlv_.timesPar.timePar_all = getTime() - parlv_.timesPar.timePar_all; + + //////////////////////////// save .par file for loading ////////////////// + // Format: -create_alveo_partitions -num_pars -par_prune -name + char* meta = (char*)malloc(4096); + char pathName_tmp[1024]; + int numPartitions = 0; + int numServers = 1;//(globalOpts_.partitionNameMode == PartitionNameMode::Flat) ? 1 : numServers; + for (int i = 0; i < numServers; i++) numPartitions += numAlveoPartitions[i]; + + std::sprintf(pathName_tmp, "%s%s.par.proj", projPath_.c_str(), projName_.c_str()); + if (parlv_.use_bfs) + std::sprintf( + meta, "-create_alveo_BFS_partitions %s -num_pars %d -par_prune %d -name %s -time_par %f -time_save %f ", + inputFileName_.c_str(), numPartitions, partOpts_.par_prune, globalOpts_.nameProj.c_str(), + parlv_.timesPar.timePar_all, parlv_.timesPar.timePar_save); + else + std::sprintf(meta, + "-create_alveo_partitions %s -num_pars %d -par_prune %d -name %s -time_par %f -time_save %f ", + inputFileName_.c_str(), numPartitions, partOpts_.par_prune, globalOpts_.nameProj.c_str(), + parlv_.timesPar.timePar_all, parlv_.timesPar.timePar_save); + parlv_.num_par = numPartitions; + // adding: -server_par ... + // example: -server_par 3 1 1 1 + char tmp_str[128]; + std::sprintf(tmp_str, "-server_par %d ", numServers); + std::strcat(meta, tmp_str); + for (int i_svr = 0, end = numServers; i_svr < end; i_svr++) { + std::sprintf(tmp_str, "%d ", numAlveoPartitions[i_svr]); + std::strcat(meta, tmp_str); + } + std::strcat(meta, "\n"); + + FILE* fp = fopen(pathName_tmp, "w"); + fwrite(meta, sizeof(char), strlen(meta), fp); + fclose(fp); + printf("INFO: Partition project metadata saved in file %s\n", pathName_tmp); + printf("INFO: Metadata in file is: %s\n", meta); + std::sprintf(pathName_tmp, "%s%s.par.parlv", projPath_.c_str(), projName_.c_str()); + SaveParLV(pathName_tmp, &parlv_); + std::sprintf(pathName_tmp, "%s%s.par.src", projPath_.c_str(), projName_.c_str()); + GLVHead dummyGlvHead; + dummyGlvHead.NV = (parlv_.plv_src == nullptr) ? partOpts_.totalNumVertices : parlv_.plv_src->NV; + if (dummyGlvHead.NV < 1) + throw Exception( + "ERROR: Number of vertices appears not to be set." + " Ensure that your graph source file has at least one vertex or that you have set" + " PartitionOptions::totalNumVertices."); + SaveHead(pathName_tmp, &dummyGlvHead); + + if (isVerbose_) { + std::cout + << "************************************************************************************************" + << std::endl; + std::cout + << "*********************** Louvain Partition Summary *******************************************" + << std::endl; + std::cout + << "************************************************************************************************" + << std::endl; + std::cout << "Number of servers : " << numServers << std::endl; + std::cout << "Output Alveo partition project : " << globalOpts_.nameProj << std::endl; + std::cout << "Number of partitions created : " << parlv_.num_par << std::endl; + std::cout << "Time for partitioning the graph : " + << (parlv_.timesPar.timePar_all + parlv_.timesPar.timePar_save) << std::endl; + std::cout << " partitioning + saving \n" << std::endl; + std::cout << " Time for partition : " << parlv_.timesPar.timePar_all << std::endl; + std::cout << " Time for saving : " << parlv_.timesPar.timePar_save << std::endl; + std::cout + << "************************************************************************************************" + << std::endl; + } + } +}; + +} // anonymous namespace + +//##################################################################################################################### + +namespace xilinx_apps { +namespace louvainmod { + +// Values determined from the global options +// +struct ComputedSettings { + std::vector hostIps; + int numServers = 1; + int modeZmq = ZMQ_NONE; + int numPureWorker = 0; + int serverIndex = -1; // this is the index of hostIp in hostIpAddresses. It's used + // to construct partition file name, sets driver/worker mode + // Start with -1 to indicate it's not assigned. + std::vector nameWorkers; + + ComputedSettings(const Options& options) { + const std::string delimiters(" "); + const std::string hostIpStr = options.clusterIpAddresses; + const std::string hostIpAddress = options.hostIpAddress; + /*modeZmq = (options.nodeId == 0) ? ZMQ_DRIVER : ZMQ_WORKER; + int idx = 0; + for (int i = hostIpStr.find_first_not_of(delimiters, 0); i != std::string::npos; + i = hostIpStr.find_first_not_of(delimiters, i)) + { + auto tokenEnd = hostIpStr.find_first_of(delimiters, i); + if (tokenEnd == std::string::npos) + tokenEnd = hostIpStr.size(); + const std::string token = hostIpStr.substr(i, tokenEnd - i); + hostIps.push_back(token); + if (hostIpAddress == token) + serverIndex = idx; + + if ((serverIndex == 0) && (idx > 0)) // The first IP in the list is the driver. Others are workers. + nameWorkers.push_back(std::string("tcp://" + token + ":5555")); + idx++; + i = tokenEnd; + } + + numServers = hostIps.size(); + numPureWorker = nameWorkers.size(); + modeZmq = (serverIndex == 0) ? ZMQ_DRIVER : ZMQ_WORKER; + */ + modeZmq = ZMQ_DRIVER; +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << " serverIndex=" << serverIndex << std::endl; +#endif + } +}; + +//##################################################################################################################### +class LouvainModImpl { + public: + Options options_; // copy of options passed to LouvainPar constructor + ComputedSettings settings_; + std::unique_ptr partitionRun_; // the active or most recent partition run + // void loadComputeUnitsToFPGAs(); + // bool computeUnitsLoaded; + LouvainModImpl(const Options& options) : options_(options), settings_(options) {} +}; + +//##################################################################################################################### +// +// LouvainPar Members +// +#ifndef LouvainPar + +void LouvainPar::partitionDataFile(const char* fileName, const PartitionOptions& partOptions) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << "\n fileName=" << fileName << std::endl; +#endif + assert(fileName); + int id_glv = 0; + GLV* glv_src = CreateByFile_general(const_cast(fileName), id_glv); // Louvain code not const correct + if (glv_src == NULL) throw Exception("Unable to read data file"); // TODO: better error message + const long NV = glv_src->NV; + + startPartitioning(partOptions); + pImpl_->partitionRun_->setFileName(fileName); + ParLV& parlv = pImpl_->partitionRun_->parlv_; + parlv.plv_src = glv_src; + + //////////////////////////// partition //////////////////////////// + // numServers is computed based on clusterIpAddresses fields from toolOptions + const int num_server = pImpl_->partitionRun_->numServers; + std::vector start_vertex(num_server); + std::vector end_vertex(num_server); + std::vector vInServer(num_server); + for (int i_svr = 0; i_svr < num_server; i_svr++) { + start_vertex[i_svr] = i_svr * (NV / num_server); + if (i_svr != num_server - 1) + end_vertex[i_svr] = start_vertex[i_svr] + NV / num_server; + else + end_vertex[i_svr] = NV; + vInServer[i_svr] = end_vertex[i_svr] - start_vertex[i_svr]; + } + + int num_partition = partOptions.numPars; + int start_par[MAX_PARTITION]; // eg. {0, 3, 6} when par_num == 9 + int end_par[MAX_PARTITION]; // eg. {3, 6, 9} when par_num == 9 + int numParsInServer[MAX_PARTITION]; // eg. {3, 3, 3} when par_num == 9 and num_server==3 + for (int i_svr = 0; i_svr < num_server; i_svr++) { + start_par[i_svr] = i_svr * (num_partition / num_server); + if (i_svr != num_server - 1) + end_par[i_svr] = start_par[i_svr] + (num_partition / num_server); + else + end_par[i_svr] = num_partition - 1; + numParsInServer[i_svr] = end_par[i_svr] - start_par[i_svr]; + } + + long* offsets_glb = glv_src->G->edgeListPtrs; + num_partition = 0; + + for (int i_svr = 0; i_svr < num_server; i_svr++) { + long* offsets_tg = (long*)malloc(sizeof(long) * (vInServer[i_svr] + 1)); + edge* edgelist_tg = + (edge*)malloc(sizeof(edge) * (offsets_glb[end_vertex[i_svr]] - offsets_glb[start_vertex[i_svr]])); + long* drglist_tg = + (long*)malloc(sizeof(long) * (offsets_glb[end_vertex[i_svr]] - offsets_glb[start_vertex[i_svr]])); + + sim_getServerPar( // This function should be repleased by GSQL + glv_src->G, start_vertex[i_svr], end_vertex[i_svr], offsets_tg, edgelist_tg, drglist_tg); +#ifndef NDEBUG + std::cout << "DEBUG: server id=" << i_svr << "\n start_vertex=" << start_vertex[i_svr] + << "\n end_vertex=" << end_vertex[i_svr] << "\n NV_tg=" << vInServer[i_svr] + << "\n start_par=" << start_par[i_svr] << "\n parInServer=" << numParsInServer[i_svr] + << "\n pathName=" << fileName << std::endl; +#endif + + long NV_par_requested = 0; + if (partOptions.numPars > 1) + NV_par_requested = + (NV + partOptions.numPars - 1) / partOptions.numPars; // allow to partition small graph with -par_num + + LouvainPar::PartitionData partitionData; + partitionData.offsets_tg = offsets_tg; + partitionData.edgelist_tg = edgelist_tg; + partitionData.drglist_tg = drglist_tg; + partitionData.start_vertex = start_vertex[i_svr]; + partitionData.end_vertex = end_vertex[i_svr]; + partitionData.NV_par_requested = NV_par_requested; + partitionData.nodeId = i_svr; + numParsInServer[i_svr] = addPartitionData(partitionData); + + num_partition += numParsInServer[i_svr]; + free(offsets_tg); + free(edgelist_tg); + free(drglist_tg); + } + + finishPartitioning(numParsInServer); +} + +void LouvainPar::startPartitioning(const PartitionOptions& partOpts) { + pImpl_->partitionRun_.reset(new PartitionRun(pImpl_->options_, partOpts)); +} + +int LouvainPar::addPartitionData(const PartitionData& partitionData) { + return pImpl_->partitionRun_->addPartitionData(partitionData); +} + +void LouvainPar::finishPartitioning(int numAlveoPartitions[]) { + pImpl_->partitionRun_->finishPartitioning(numAlveoPartitions); +} + +#endif // Louvain Partition + +//##################################################################################################################### +// +// LouvainRun Members +// +#ifndef LouvainRun + +void LouvainRun::setAlveoProject(const char* alveoProject) { + pImpl_->options_.alveoProject = alveoProject; +} + +void LouvainRun::loadAlveo() {} +void LouvainRun::computeLouvain(const ComputeOptions& computeOpts) {} + +float LouvainRun::loadAlveoAndComputeLouvain(const ComputeOptions& computeOpts) { + float finalQ; + char* nameWorkers[128]; + +#ifndef NDEBUG + std::cout << "DEBUG: " << __FILE__ << "::" << __FUNCTION__ << "\n xclbinPath=" << pImpl_->options_.xclbinPath + << "\n alveoProject=" << pImpl_->options_.alveoProject + << "\n deviceNames=" << pImpl_->options_.deviceNames << "\n nodeId=" << pImpl_->options_.nodeId + << "\n modeZmq=" << pImpl_->settings_.modeZmq + << "\n numPureWorker=" << pImpl_->settings_.numPureWorker; +#endif + + int i = 0; + for (auto it = pImpl_->settings_.nameWorkers.begin(); it != pImpl_->settings_.nameWorkers.end(); ++it) { + nameWorkers[i++] = (char*)it->c_str(); + std::cout << "\n nameWorker " << i << "=" << nameWorkers[i - 1]; + } + std::cout << std::endl; + + finalQ = ::loadAlveoAndComputeLouvain( + (char*)(pImpl_->options_.xclbinPath.c_str()), pImpl_->options_.kernelMode, pImpl_->options_.numDevices, + pImpl_->options_.deviceNames, (char*)(pImpl_->options_.alveoProject.c_str()), pImpl_->settings_.modeZmq, + pImpl_->settings_.numPureWorker, nameWorkers, pImpl_->options_.nodeId, (char*)(computeOpts.outputFile.c_str()), + computeOpts.max_iter, computeOpts.max_level, computeOpts.tolerance, computeOpts.intermediateResult, + pImpl_->options_.verbose, computeOpts.final_Q, computeOpts.all_Q); +//,computeOpts.BFS_partition); + +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << " finalQ=" << finalQ << std::endl; +#endif + return finalQ; +} + +#endif + +//##################################################################################################################### +// +// LouvainModImpl Members +// +// void LouvainModImpl::loadComputeUnitsToFPGAs() + +} // namespace louvainmod +} // namespace xilinx_apps + +//##################################################################################################################### + +// +// Shared Library Entry Points +// + +extern "C" { + +xilinx_apps::louvainmod::LouvainModImpl* xilinx_louvainmod_createImpl(const xilinx_apps::louvainmod::Options& options) { + return new xilinx_apps::louvainmod::LouvainModImpl(options); +} + +void xilinx_louvainmod_destroyImpl(xilinx_apps::louvainmod::LouvainModImpl* pImpl) { + delete pImpl; +} + +} // extern "C" diff --git a/graph/L3/include/ParLV.h b/graph/L3/include/ParLV.h new file mode 100644 index 0000000000..fc1026b805 --- /dev/null +++ b/graph/L3/include/ParLV.h @@ -0,0 +1,274 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WANCUNCUANTIES ONCU CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _PARLV_H_ +#define _PARLV_H_ +#include "string.h" +#include "stdio.h" +#include "stdlib.h" +#include "xilinxlouvain.h" +//#include "app_common.h" +#include "xilinxlouvainInternal.h" +#include "partitionLouvain.hpp" +#include "xf_graph_L3.hpp" +//#include "zmq.h" +#define MAX_PARTITION (512) +#define MAX_DEVICE (64) +#define MAX_SERVER (64) + +enum MOKD_PHASEFLOW { MD_CLASSIC = 0, MD_NORMAL, MD_FAST }; + +const long headGLVBin = 0xffff5555ffff5555; + +struct TimePartition { + double time_star; + double time_done_par; + double time_done_lv; + double time_done_pre; + double time_done_mg; + double time_done_fnl; + // + double timePar[MAX_PARTITION]; + double timePar_all; + double timePar_save; + double timeLv[MAX_PARTITION]; + double timeLv_dev[MAX_DEVICE]; + double timeLv_all; + double timeWrkSend[MAX_DEVICE]; + double timeWrkLoad[MAX_DEVICE]; + double timeWrkCompute[MAX_DEVICE]; // the compute time on each nodes(May have multi cards) + double timeDriverSend; + double timeDriverLoad; + double timeDriverExecute; + double timeDriverCollect; + double timeDriverRecv; + double timePre; + double timeMerge; + double timeFinal; + double timeAll; +}; + +struct ParLVVar { + bool st_Partitioned; + bool st_ParLved; + bool st_PreMerged; + bool st_Merged; + bool st_FinalLved; + bool st_Merged_ll; + bool st_Merged_gh; + bool isMergeGhost; + bool isOnlyGL; + int kernelMode; + int num_par; + int num_dev; + long NV; + long NVl; + long NV_gh; + long NE; + long NEll; + long NElg; + long NEgl; + long NEgg; + long NEself; + long off_src[MAX_PARTITION]; + long off_lved[MAX_PARTITION]; + long max_NV; + long max_NE; + long max_NVl; + long max_NElg; + int scl_NV; + int scl_NE; + int scl_NVl; + int scl_NElg; + long NE_list_all; + long NE_list_ll; + long NE_list_gl; + long NE_list_gg; + long NV_list_all; + long NV_list_l; + long NV_list_g; + bool isPrun; + int th_prun; +}; + +struct bfs_selected { + int par_idx; // idx of the partition + int renum_in_par; // the new number index in the partition +}; + +class ParLV { + public: + bool st_Partitioned; + bool st_ParLved; + bool st_PreMerged; + bool st_Merged; + bool st_FinalLved; + bool st_Merged_ll; + bool st_Merged_gh; + bool isMergeGhost; + bool isOnlyGL; + int kernelMode; + int num_par; + int num_dev; + long NV; + long NVl; + long NV_gh; + long NE; + long NEll; + long NElg; + long NEgl; + long NEgg; + long NEself; + long off_src[MAX_PARTITION]; + long off_lved[MAX_PARTITION]; + long max_NV; + long max_NE; + long max_NVl; + long max_NElg; + int scl_NV; + int scl_NE; + int scl_NVl; + int scl_NElg; + long NE_list_all; + long NE_list_ll; + long NE_list_gl; + long NE_list_gg; + long NV_list_all; + long NV_list_l; + long NV_list_g; + bool isPrun; + int th_prun; + bool use_bfs; // if is useing bfs Low Bandwidth methods(BFS) + bfs_selected* bfs_adjacent; // added structure and saing on disk by BFS + int flowMode; + /////////////////////////////////// + int num_server; // default '1' means using concentration partition + int numServerCard[MAX_SERVER]; + int parInServer[MAX_PARTITION]; + long parOffsets[MAX_PARTITION]; // start vertex for each partition. Currently no use for it. Just recored in + // .par.proj file + /////////////////////////////////// + GLV* plv_src; + GLV* par_src[MAX_PARTITION]; + GLV* par_lved[MAX_PARTITION]; + GLV* plv_merged; + GLV* plv_final; + long* p_v_new[MAX_PARTITION]; + SttGPar stt[MAX_PARTITION]; + TimePartition timesPar; + map m_v_gh; + // list lv_list; + + edge* elist; + long* M_v; + + void Init(int mode); + void Init(int mode, GLV* src, int numpar, int numdev); + void Init(int mode, GLV* src, int num_p, int num_d, bool isPrun, int th_prun); + ParLV(); + ~ParLV(); + void PrintSelf(); + void UpdateTimeAll(); + void CleanList(GLV* glv_curr, GLV* glv_temp); + GLV* MergingPar2(int&); + // GLV* FinalLouvain(char*, int , int& , long minGraphSize, double threshold, double C_threshold, bool isParallel, + // int numPhase); + + long MergingPar2_ll(); + long MergingPar2_gh(); + long CheckGhost(); + int partition(GLV* glv_src, int& id_glv, int num, long th_size, int th_maxGhost); + void PreMerge(); + void Addedge(edge* edges, long head, long tail, double weight, long* M_g); + long FindGhostInLocalC(long m); + int FindParIdx(long e_org); + int FindParIdxByID(int id); + pair FindCM_1hop(int idx, long e_org); + pair FindCM_1hop(long e_org); + long FindC_nhop(long m_gh); + pair FindCM_1hop_bfs(int idx, long e_org, long addr_v); // for BFS premerge + long FindC_nhop_bfs(long m_gh); // for BFS premerge + int AddGLV(GLV* plv); + void PrintTime(); + void PrintTime2(); + void CleanTmpGlv(); + double TimeStar(); + double TimeDonePar(); + double TimeDoneLv(); + double TimeDonePre(); + double TimeDoneMerge(); + double TimeDoneFinal(); + double TimeAll_Done(); +}; + +GLV* par_general(GLV* src, SttGPar* pstt, int& id_glv, long start, long end, bool isPrun, int th_prun); +GLV* par_general(GLV* src, int& id_glv, long start, long end, bool isPrun, int th_prun); + +GLV* CreateByFile_general(char* inFile, int& id_glv); + +int SaveGLVBin(char* name, GLV* glv); + +double getTime(); + +int xai_save_partition(long* offsets_tg, + edge* edgelist_tg, + long* drglist_tg, + long start_vertex, // If a vertex is smaller than star_vertex, it is a ghost + long end_vertex, // If a vertex is larger than star_vertex-1, it is a ghost + char* path_prefix, // For saving the partition files like _xxx.par + // Different server can have different path_prefix + int par_prune, // Can always be set with value '1' + long NV_par_recommand, // Allow to partition small graphs not bigger than FPGA limitation + long NV_par_max // 64*1000*1000; + ); + +// API for BFS partition +int xai_save_partition_bfs(long* offsets_tg, + edge* edgelist_tg, + long* drglist_tg, + long start_vertex, // If a vertex is smaller than star_vertex, it is a ghost + long end_vertex, // If a vertex is larger than star_vertex-1, it is a ghost + char* path_prefix, // For saving the partition files like _xxx.par + // Different server can have different path_prefix + int par_prune, // Can always be set with value '1' + long NV_par_recommand, // Allow to partition small graphs not bigger than FPGA limitation + long NV_par_max // 64*1000*1000; + ); + +void SaveParLV(char* name, ParLV* p_parlv); + +void sim_getServerPar( + // input + graphNew* G, // Looks like a Global Graph but here only access dataset within + long start_vertex, // a range from start_vertex to end_vertex, which is stored locally + long end_vertex, // Here we assume that the vertices of a TigerGraph partition + // stored on a node are continuous + // Output + long* offsets_tg, // we can also use �degree� instead of �offsets� + edge* edges_tg, // + long* dgr_tail_tg // degrees for the tail of each edge; + ); + +int getNumPartitions(std::string alveoProjectFile); + +const char* NameNoPath(const char* name); + +void PathNoName(char* des, const char* name); + +int Phaseloop_InitColorBuff(graphNew* G, int* colors, int numThreads, double& totTimeColoring); + +#endif diff --git a/graph/L3/include/common.hpp b/graph/L3/include/common.hpp old mode 100755 new mode 100644 index 64cf81f7c6..3b185a369d --- a/graph/L3/include/common.hpp +++ b/graph/L3/include/common.hpp @@ -42,9 +42,72 @@ #define XCL_BANK13 XCL_BANK(13) #define XCL_BANK14 XCL_BANK(14) #define XCL_BANK15 XCL_BANK(15) +#define XCL_BANK16 XCL_BANK(16) +#define XCL_BANK17 XCL_BANK(17) +#define XCL_BANK18 XCL_BANK(18) +#define XCL_BANK19 XCL_BANK(19) +#define XCL_BANK20 XCL_BANK(20) +#define XCL_BANK21 XCL_BANK(21) +#define XCL_BANK22 XCL_BANK(22) +#define XCL_BANK23 XCL_BANK(23) +#define XCL_BANK24 XCL_BANK(24) +#define XCL_BANK25 XCL_BANK(25) +#define XCL_BANK26 XCL_BANK(26) +#define XCL_BANK27 XCL_BANK(27) +#define XCL_BANK28 XCL_BANK(28) +#define XCL_BANK29 XCL_BANK(29) +#define XCL_BANK30 XCL_BANK(30) +#define XCL_BANK31 XCL_BANK(31) typedef std::chrono::time_point TimePointType; +struct ToolOptions { + int argc; + char** argv; // strings not owned! + + double opts_C_thresh; //; //Threshold with coloring on + long opts_minGraphSize; //; //Min |V| to enable coloring + double threshold; //; //Value of threshold + int opts_ftype; //; //File type + char opts_inFile[4096]; //; + bool opts_coloring; // + bool opts_output; //; + std::string outputFile; + bool opts_VF; //; + std::string xclbinFile; + std::string deviceNames; + int numNodes; + int nodeId; + int numThreads; + int numPars; + int gh_par; // same as par_prune + int kernelMode; + int numDevices; + int modeZmq; + char path_zmq[4096]; + bool useCmd; + int mode_alveo; + char nameProj[4096]; // used for create partitions + std::string alveoProject; // used for load/compute TODO: consolidate with nameProj + int numPureWorker; + char* nameWorkers[128]; + int max_level; + int max_iter; + + ToolOptions(int argc, char** argv); +}; + +enum { ZMQ_NONE = 0, ZMQ_DRIVER = 1, ZMQ_WORKER = 2 }; + +template +T* aligned_alloc(std::size_t num) { + void* ptr = nullptr; + if (posix_memalign(&ptr, 4096, num * sizeof(T))) { + throw std::bad_alloc(); + } + return reinterpret_cast(ptr); +} + namespace xf { namespace graph { namespace L3 { diff --git a/graph/L3/include/op_base.hpp b/graph/L3/include/op_base.hpp old mode 100755 new mode 100644 index a3edec36df..3a38d8d172 --- a/graph/L3/include/op_base.hpp +++ b/graph/L3/include/op_base.hpp @@ -32,6 +32,16 @@ class opBase { opBase(){}; + void initThreadlouvain(class openXRM* xrm, + std::string kernelName, + std::string kernelAlias, + unsigned int requestLoad, + unsigned int deviceNeeded, + unsigned int cuNumber) { + task_workers.emplace_back(std::thread(louvainWorker, std::ref(task_queue[0]), xrm, kernelName, kernelAlias, + requestLoad, deviceNeeded, cuNumber)); + }; + void initThread(class openXRM* xrm, std::string kernelName, std::string kernelAlias, diff --git a/graph/L3/include/op_louvainmodularity.hpp b/graph/L3/include/op_louvainmodularity.hpp new file mode 100644 index 0000000000..713db22473 --- /dev/null +++ b/graph/L3/include/op_louvainmodularity.hpp @@ -0,0 +1,261 @@ +/* + * Copyright 2020 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#pragma once + +#ifndef _XF_GRAPH_L3_OP_LOUVAINMODULARITY_HPP_ +#define _XF_GRAPH_L3_OP_LOUVAINMODULARITY_HPP_ + +#include "graph.hpp" +#include "op_base.hpp" +#include "openclHandle.hpp" + +#include "xilinxlouvainInternal.h" +#include +#include "common.hpp" + +namespace xf { +namespace graph { +namespace L3 { + +class opLouvainModularity : public opBase { + public: + static uint32_t cuPerBoardLouvainModularity; + + static uint32_t dupNmLouvainModularity; + + std::thread louvainModularityThread; + + std::vector > eventQueue; + + class clHandle* handles; + + // KMemorys_host* buff_hosts; + + KMemorys_host_prune* buff_hosts_prune; + + opLouvainModularity() : opBase(){}; + + void setHWInfo(uint32_t numDev, uint32_t CUmax); + + void freeLouvainModularity(); + + void init(class openXRM* xrm, + std::string kernelName, + std::string kernelAlias, + std::string xclbinFile, + uint32_t* deviceIDs, + uint32_t* cuIDs, + unsigned int requestLoad); + + void mapHostToClBuffers( + graphNew* G, int flowMode, bool opts_coloring, long opts_minGraphSize, double opts_C_thresh, int numThreads); + + static int compute(unsigned int deviceID, + unsigned int cuID, + unsigned int channelID, + xrmContext* ctx, + xrmCuResource* resR, + std::string instanceName, + clHandle* handles, + int flowMode, + uint32_t numBuffers, + GLV* pglv_iter, + double opts_C_thresh, + /*KMemorys_host* buff_host,*/ + KMemorys_host_prune* buff_host_prune, + int* eachItrs, + double* currMod, + long* numClusters, + double* eachTimeInitBuff, + double* eachTimeReadBuff); + + void demo_par_core(int id_dev, int flowMode, GLV* pglv_orig, GLV* pglv_iter, LouvainPara* para_lv); + + event addwork(GLV* glv, + int flowMode, + double opts_C_thresh, + int* eachItrs, + double* currMod, + long* numClusters, + double* eachTimeInitBuff, + double* eachTimeReadBuff); + + private: + std::vector deviceOffset; + uint32_t numDevices_; + uint32_t maxCU_; + uint32_t numBuffers_ = 23; + + // static void bufferInit(clHandle* hds, long NV, long NE_mem_1, long NE_mem_2, KMemorys_host* buff_host); + static double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, + graphNew* G, + long* M, + double opts_C_thresh, + double* currMod, + // Updated variables + int* colors, + KMemorys_host_prune* buff_host); + static double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune_renumber_2cu(int numColors, + long NVl, + graphNew* G, + long* M, + double opts_C_thresh, + double* currMod, + // Updated variables + int* colors, + KMemorys_host_prune* buff_host); + + static void UsingFPGA_MapHostClBuff_prune( + clHandle* hds, long NV, long NE_mem_1, long NE_mem_2, KMemorys_host_prune* buff_hosts_prune); + + static int cuExecute( + clHandle* hds, cl::Kernel& kernel0, unsigned int num_runs, std::vector* evIn, cl::Event* evOut); + + static void migrateMemObj(clHandle* hds, + bool type, + unsigned int num_runs, + std::vector& ob, + std::vector* evIn, + cl::Event* evOut); + + static void releaseMemObjects(clHandle* hds, uint32_t numBuffer); + + static void cuRelease(xrmContext* ctx, xrmCuResource* resR); + + static void postProcess(); + + // static void PhaseLoop_UsingFPGA_1_KernelSetup(bool isLargeEdge, + // cl::Kernel& kernel_louvain, + // std::vector& ob_in, + // std::vector& ob_out, + // clHandle* hds); + static void PhaseLoop_UsingFPGA_1_KernelSetup_prune(bool isLargeEdge, + cl::Kernel& kernel_louvain, + std::vector& ob_in, + std::vector& ob_out, + clHandle* hds); + + static void UsingFPGA_MapHostClBuff_prune_2cu( + clHandle* hds, long NV, long NE_mem_1, long NE_mem_2, KMemorys_host_prune* buff_hosts_prune); + + static void PhaseLoop_UsingFPGA_1_KernelSetup_prune_2cu(bool isLargeEdge, + cl::Kernel& kernel_louvain, + std::vector& ob_in, + std::vector& ob_out, + clHandle* hds); + static double PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune(long vertexNum, + KMemorys_host_prune* buff_host, + int* eachItrs, + // output + long* C, + int* eachItr, + double* currMod); + + static double PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune_renumber(long vertexNum, + KMemorys_host_prune* buff_host, + int* eachItrs, + // output + long* C, + int* eachItr, + double* currMod, + long* numClusters); + + static void PhaseLoop_UpdatingC_org(int phase, long NV, long NV_G, long* C, long* C_orig); + + long* CreateM(long NV_new, long NV_orig, long* C_orig, long* M_orig); + + double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, + GLV* pglv_iter, + int numThreads, + double opts_threshold, + bool opts_coloring, + // modified: + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase, + double& time_renum, + double& time_C, + double& time_M, + double& time_buid, + double& time_set); + + double PhaseLoop_CommPostProcessing_par_renumber(GLV* pglv_orig, + GLV* pglv_iter, + int numThreads, + double opts_threshold, + bool opts_coloring, + // modified: + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase, + double& time_renum, + double& time_C, + double& time_M, + double& time_buid, + double& time_set); +}; + +} // L3 +} // graph +} // xf + +class myCmd { + public: + int argc; + char argv[64][256]; + // char line_last[1024]; + int cmd_last; + string line_last; + int cnt_his; + list his_cmd; + myCmd(); //{cnt_his=0; argc=0; cmd_last=-1;}; + const char* cmd_SkipSpace(const char* str); + int cmd_CpyWord(char* des, const char* src); + int cmd_Getline(); + int cmd_Getline(const char* str); + // int cmd_GetCmd(); + // int cmd_GetCmd(const char* str); + void cmd_resetArg(); + int cmd_findPara(const char* para); + // int PrintHistory(); +}; + +//#define NUM_CMD (28) + +float loadAlveoAndComputeLouvain(char* xclbinPath, + int kernelMode, + unsigned int numDevices, + std::string deviceNames, + char* alveoProject, + unsigned mode_zmq, + unsigned numPureWorker, + char* nameWorkers[128], + unsigned int nodeID, + char* opts_outputFile, + unsigned int max_iter, + unsigned int max_level, + float tolerance, + bool intermediateResult, + bool verbose, + bool final_Q, + bool all_Q); + +#endif diff --git a/graph/L3/include/openclHandle.hpp b/graph/L3/include/openclHandle.hpp index fe4ad2db59..626df0766c 100755 --- a/graph/L3/include/openclHandle.hpp +++ b/graph/L3/include/openclHandle.hpp @@ -32,7 +32,9 @@ class clHandle { cl::CommandQueue q; cl::Program::Binaries xclBins; cl::Program program; + cl::Kernel kernel; cl::Buffer* buffer; + xrmCuResource* resR; unsigned int deviceID; unsigned int cuID; unsigned int dupID; diff --git a/graph/L3/include/partitionLouvain.hpp b/graph/L3/include/partitionLouvain.hpp new file mode 100644 index 0000000000..750e0929ee --- /dev/null +++ b/graph/L3/include/partitionLouvain.hpp @@ -0,0 +1,144 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WANCUNCUANTIES ONCU CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _PARTITIONLOUVAIN_H_ +#define _PARTITIONLOUVAIN_H_ +#include "stdlib.h" +#include "xilinxlouvainInternal.h" +#include +using namespace std; + +#define MAXGHOST_PRUN 128 +// save the info of smallest ghost +struct VGMinDgr { + long tail[MAXGHOST_PRUN]; + long dgrs[MAXGHOST_PRUN]; + double wght[MAXGHOST_PRUN]; +}; + +void FreeG(graphNew*& G); +void printG(graphNew* G); +void printG(graphNew* G, long* C); +void printG(graphNew* G, long* C, long star, long end); +void printG(graphNew* G, long* C, long* M); +void printG(graphNew* G, long* C, long* M, long star, long end); +void printG(graphNew* G, long* C, long* M, long star, long end, bool isCid, bool isDir); +void printG(char* name, graphNew* G, long* C, long* M, long star, long end); + +void InitC(long* C, long NV); +void CreateSubG(graphNew* G_src, long start, long size, graphNew* G_sub, long* M_sub2src, long* M_sub2ghost); +void CreatSubG(long head, long end_line, graphNew* G_scr, graphNew* G_des); +void CopyG(graphNew* G_scr, graphNew* G_des); + +graphNew* CloneG(graphNew* G_scr); + +struct TimePar { + double total; + double par; + double lv; + double pre; + double merge; + double final; +}; + +class SttGPar { + public: + long num_e; + long num_e_dir; + long num_v; + long start; + long end; + long num_v_l; + long num_v_g; + long num_e_ll; + long num_e_ll_dir; + long num_e_lg; + long num_e_gl; + long num_e_gg; + map map_v_l; + map map_v_g; + map map_v; + + public: + SttGPar(); + SttGPar(long s, long e); + void PrintStt(); + // void AddEdge(edge* edges, long head, long tail, long* M_g); + void AddEdge(edge* edges, long head, long tail, double weight, long* M_g); + void AddEdge2(edge* edges, long head, long tail, long* M_g); + void AddEdge_org(edge* edges, long head, long tail, long* M_g); + void EdgePruning(edge* edges, + long head, + long tail, + double weight, + long* M_g, + VGMinDgr& min, + long& num_vg, + long& e_dgr, + int th_maxGhost); + // void CountV(graphNew* G, long star, long end); + void CountV(graphNew* G, edge* elist, long* M_g); + void CountV(graphNew* G, long star, long end, edge* elist, long* M_g); + void CountV(graphNew* G, long star, long end); + void CountVPruning(graphNew* G, long star, long end, int th_maxGhost); + void CountV(graphNew* G); + bool InRange(long v); + GLV* ParNewGlv(graphNew* G, long star, long end, int& id_glv); + GLV* ParNewGlv_Prun(graphNew* G, long star, long end, int& id_glv, int th_maxGhost); + GLV* ParNewGlv_Prun(long start_tg, + long* offsets_tg, + edge* edgelist_tg, + long* dgrlist_tg, + long start_par, + long size_par, + int& id_glv, + int th_maxGhost); + long findAt(VGMinDgr& gMinDgr, long tail, long dgr, long num_vg, int th_maxGhost); +}; + +long CountV(graphNew* G, long star, long end); +long CountV(graphNew* G); +long CountVGh(graphNew* G, long star, long end); +long CountVGh(graphNew* G); +void GetGFromEdge(graphNew* G, edge* edgeListTmp, long num_v, long num_e_dir); +long GetGFromEdge_selfloop(graphNew* G, edge* edgeListTmp, long num_v, long num_e_dir); +GLV* CloneGlv(GLV* glv_src, int& id_glv); +void cmd_runMultiPhaseLouvainAlgorithm( + GLV* pglv, GLV* pglv_iter, long minGraphSize, double threshold, double C_threshold, int numPhase); +void cmd_runMultiPhaseLouvainAlgorithm(GLV* pglv, + GLV* pglv_iter, + long minGraphSize, + double threshold, + double C_threshold, + bool isNoParallelLouvain, + int numPhase); +GLV* cmd_runMultiPhaseLouvainAlgorithm(GLV* pglv, + int& id_glv, + long minGraphSize, + double threshold, + double C_threshold, + bool isNoParallelLouvain, + int numPhase); +GLV* cmd_runMultiPhaseLouvainAlgorithm( + GLV* pglv, int& id_glv, long minGraphSize, double threshold, double C_threshold, int numPhase); +double cmd_lv_parallelLouvianMethod( + graphNew* G, long* C, long* M, int nThreads, double Lower, double thresh, double* totTime, int* numItr); + +double buildNextLevelGraphOpt(graphNew* Gin, graphNew* Gout, long* C, long numUniqueClusters, int nThreads); + +; +#endif diff --git a/graph/L3/include/task.hpp b/graph/L3/include/task.hpp old mode 100755 new mode 100644 index 46a8973529..8eae04b1ee --- a/graph/L3/include/task.hpp +++ b/graph/L3/include/task.hpp @@ -497,6 +497,56 @@ auto createL3(Q& q, F&& f, Args&&... args) -> event { return e; } +inline void louvainWorker(queue& q, + class openXRM* xrm, + std::string kernelName, + std::string kernelAlias, + unsigned int requestLoad, + unsigned int deviceNm, + unsigned int cuNm) { + int requestNm = deviceNm * cuNm; + xrmCuResource* resR[requestNm]; + int pendingRequests; + int curRequestId = 0; + + while (true) { + class task t[requestNm]; + pendingRequests = 0; + for (int i = 0; i < requestNm; ++i) { + // q.getWork is blocking until it has a job + t[i] = q.getWork(); + + resR[i] = (xrmCuResource*)malloc(sizeof(xrmCuResource)); + memset(resR[i], 0, sizeof(xrmCuResource)); + pendingRequests++; + if (q.empty()) break; // no more requests execute pending ones. + } + +#ifndef NDEBUG +// std::cout << "DEBUG: " << __FUNCTION__ +// << " pendingRequests" << pendingRequests +// << " curRequestId " << curRequestId << std::endl; +#endif + bool toStop = false; + for (int i = 0; i < pendingRequests; ++i) { + if (!t[i].valid()) toStop = true; + } + if (toStop) break; + + for (int i = 0; i < pendingRequests; i++) { + unsigned int deviceID = curRequestId / cuNm; + unsigned int cuID = curRequestId % cuNm; + unsigned int channelID = 0; + std::string instanceName = "PLACEHOLDER"; + + t[i].execute(deviceID, cuID, channelID, xrm, resR[curRequestId], instanceName); + + curRequestId++; + if (curRequestId == requestNm) curRequestId = 0; + } + } +} + inline void worker(queue& q, class openXRM* xrm, std::string kernelName, diff --git a/graph/L3/include/xf_graph_L3.hpp b/graph/L3/include/xf_graph_L3.hpp old mode 100755 new mode 100644 index 999ae24a73..1866c39497 --- a/graph/L3/include/xf_graph_L3.hpp +++ b/graph/L3/include/xf_graph_L3.hpp @@ -25,6 +25,21 @@ namespace xf { namespace graph { namespace L3 { +/** + * @brief louvain algorithm is implemented. + * + * @param handle Graph library L3 handle + * @param flowMode flowMode of multi louvain kernel. + * LOUVAINMOD_PRUNING_KERNEL = 1 is a 1cu kernel design fit for u50 + * LOUVAINMOD_2CU_U55C_KERNEL = 2 a 2cu kernel design fit for u55c + * the performance of one compute unit by different board is the same + * @param glv the original graph info before partition. + * @param pglv one of the partitioned sub-graph info to input to kernel. + * @param para_lv parameters of louvain kernel + * + */ +void louvainModularity( + std::shared_ptr handle, int flowMode, GLV* glv, GLV* pglv, LouvainPara* para_lv); /** * @brief twoHop algorithm is implemented. * diff --git a/graph/L3/include/xf_graph_L3_handle.hpp b/graph/L3/include/xf_graph_L3_handle.hpp old mode 100755 new mode 100644 index bdf8bbbad1..5f20ab94d9 --- a/graph/L3/include/xf_graph_L3_handle.hpp +++ b/graph/L3/include/xf_graph_L3_handle.hpp @@ -19,6 +19,16 @@ #ifndef _XF_GRAPH_L3_HANDLE_HPP_ #define _XF_GRAPH_L3_HANDLE_HPP_ +#define XF_GRAPH_L3_MAX_DEVICES_PER_NODE 16 // maximu supported devices per node +#define XF_GRAPH_L3_SUCCESS 0 +#define XF_GRAPH_L3_ERROR_CONFIG_FILE_NOT_EXIST -2 +#define XF_GRAPH_L3_ERROR_XCLBIN_FILE_NOT_EXIST -3 +#define XF_GRAPH_L3_ERROR_DLOPEN -5 +#define XF_GRAPH_L3_ERROR_NOT_ENOUGH_DEVICES -6 +#define XF_GRAPH_L3_ERROR_CU_NOT_SETUP -7 +#define XF_GRAPH_L3_ERROR_ALLOC_CU -8 +#define XF_GRAPH_L3_ERROR_DLSYM -9 + #include "op_pagerank.hpp" #include "op_sp.hpp" #include "op_trianglecount.hpp" @@ -30,6 +40,7 @@ #include "op_similaritysparse.hpp" #include "op_similaritydense.hpp" #include "op_twohop.hpp" +#include "op_louvainmodularity.hpp" namespace xf { namespace graph { @@ -64,18 +75,15 @@ class Handle { unsigned int deviceNeeded = 0; // requested FPGA device number unsigned int cuPerBoard = 1; // requested FPGA device number std::vector deviceIDs; // deviceID - void setKernelName(char* input) { - std::string tmp = ""; - kernelName = input; - kernelAlias = (char*)tmp.c_str(); - } - void setKernelAlias(char* input) { - std::string tmp = ""; - kernelName = (char*)tmp.c_str(); - kernelAlias = input; - } + void setKernelName(char* input) { kernelName = input; } + void setKernelAlias(char* input) { kernelAlias = input; } }; + /** + * \brief xilinx FPGA Resource Manager operation + * + */ + class opLouvainModularity* oplouvainmod; /** * \brief twohop operation * @@ -138,6 +146,7 @@ class Handle { class openXRM* xrm; Handle() { + oplouvainmod = new class opLouvainModularity; optwohop = new class opTwoHop; oppg = new class opPageRank; opsp = new class opSP; @@ -154,12 +163,19 @@ class Handle { void free(); + void showHandleInfo(); + int setUp(); + int setUp(std::string deviceNames); // Set up the handle with specified device names void getEnv(); + void getEnvMultiBoards(); + void addOp(singleOP op); + uint32_t getNumDevices() { return numDevices; } + private: uint32_t maxCU; @@ -167,6 +183,12 @@ class Handle { uint32_t numDevices; + uint32_t totalSupportedDevices_; + + std::vector supportedDeviceNames_; + + uint32_t supportedDeviceIds[XF_GRAPH_L3_MAX_DEVICES_PER_NODE]; + uint64_t maxChannelSize; std::vector ops; @@ -176,6 +198,13 @@ class Handle { std::thread loadXclbinNonBlock(unsigned int deviceId, char* xclbinName); std::future loadXclbinAsync(unsigned int deviceId, char* xclbinName); + int32_t initOpLouvainModularity(std::string xclbinFile, + std::string kernelName, + std::string kernelAlias, + unsigned int requestLoad, + unsigned int deviceNeeded, + unsigned int cuPerBoard); + void initOpTwoHop(const char* kernelName, char* xclbinFile, char* kernelAlias, diff --git a/graph/L3/include/xilinx_apps_common.hpp b/graph/L3/include/xilinx_apps_common.hpp new file mode 100644 index 0000000000..12bb86a310 --- /dev/null +++ b/graph/L3/include/xilinx_apps_common.hpp @@ -0,0 +1,110 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _XILINX_APPS_COMMON_H_ +#define _XILINX_APPS_COMMON_H_ + +/** + * @brief Simple string class for avoiding ABI problems + * + * This class provides string memory management like `std::string` but without ABI compatibility issues. + * ABI (Application Binary Interface) problems can arise when using standard C++ classes in a coding environment + * that uses multiple compiler versions. For example, if you compile your application code using a different + * version of the g++ compiler from the one used to compile this library, then when using dynamic loading, + * standard C++ types, such as `std::string`, may not pass correctly from your code into the library. + * This string class avoids these compatibility issues by using only plain data types internally. + */ +class XString { + public: + XString() = default; + ~XString() { clear(); } + XString(const XString& other) { copyIn(other.data); } + XString(XString&& other) { steal(std::forward(other)); } + XString(const char* cstr) { copyIn(cstr); } + XString(const std::string& str) { copyIn(str.c_str()); } + XString& operator=(const XString& other) { + copyIn(other.data); + return *this; + } + XString& operator=(XString&& other) { + steal(std::forward(other)); + return *this; + } + XString& operator=(const char* cstr) { + copyIn(cstr); + return *this; + } + XString& operator=(const std::string& str) { + copyIn(str.c_str()); + return *this; + } + operator std::string() const { return std::string(c_str()); } + operator const char*() const { return c_str(); } + const char* c_str() const { return data == nullptr ? "" : data; } + bool empty() const { return data == nullptr || std::strlen(data) == 0; } + + bool operator==(const XString& other) const { + if (data == nullptr && other.data == nullptr) return true; + if (data == nullptr || other.data == nullptr) return false; + return std::strcmp(data, other.data) == 0; + } + + void clear() { + if (data != nullptr) std::free(data); + data = nullptr; + } + + private: + char* data = nullptr; + + void copyIn(const char* other) { + clear(); + if (other != nullptr) { + data = static_cast(std::malloc(std::strlen(other) + 1)); + std::strcpy(data, other); + } + } + + void steal(XString&& other) { + clear(); + data = other.data; + other.data = nullptr; + } +}; + +// TODO: Move this to internal header after create/load_alveo_partitions are removed +enum { ALVEOAPI_NONE = 0, ALVEOAPI_PARTITION, ALVEOAPI_PARTITION_BFS, ALVEOAPI_LOAD, ALVEOAPI_RUN }; + +enum { LOUVAINMOD_PRUNING_KERNEL = 1, LOUVAINMOD_2CU_U55C_KERNEL = 2 }; + +enum { + ERRORCODE_COMPUTE_LOUVAIN_ALVEO_SEPERATED_LOAD = -3, + ERRORCODE_CREATESHAREDHANDLE = -4, + ERRORCODE_GETNUMPARTITIONS_INVALID_ARGC = -5, + ERRORCODE_GETNUMPARTITIONS_INVALID_NUMPARS = -6, + ERRORCODE_GETNUMPARTITIONS_FAILED_OPEN_ALVEOPRJ = -7, +}; + +/** + * Define this macro to make functions in louvainmod_loader.cpp inline instead of extern. You would use this macro + * when including louvainmod_loader.cpp in a header file, as opposed to linking with libXilinxCosineSim_loader.a. + */ +#ifdef XILINX_LOUVAINMOD_INLINE_IMPL +#define XILINX_LOUVAINMOD_IMPL_DECL inline +#else +#define XILINX_LOUVAINMOD_IMPL_DECL extern +#endif + +#endif diff --git a/graph/L3/include/xilinxlouvain.h b/graph/L3/include/xilinxlouvain.h new file mode 100644 index 0000000000..a7000f0360 --- /dev/null +++ b/graph/L3/include/xilinxlouvain.h @@ -0,0 +1,205 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _XILINXLOUVAIN_H_ +#define _XILINXLOUVAIN_H_ + +#include +#include +#include +#include +#include +#include + +#include "xilinx_apps_common.hpp" + +namespace xilinx_apps { +namespace louvainmod { + +class LouvainModImpl; +class Options; +} +} + +extern "C" { + +// XILINX_LOUVAINMOD_IMPL_DECL +// int create_and_load_alveo_partitions(int argc, char *argv[]); + +// XILINX_LOUVAINMOD_IMPL_DECL +// float loadAlveoAndComputeLouvain( +// char* xclbinPath, int kernelMode, unsigned numDevices, std::string deviceNames, +// char* alveoProject, unsigned mode_zmq, unsigned numPureWorker, +// char* nameWorkers[128], unsigned int nodeID, char* opts_outputFile, +// unsigned int max_iter, unsigned int max_level, float tolerance, +// bool intermediateResult, bool verbose, bool final_Q, bool all_Q); + +// XILINX_LOUVAINMOD_IMPL_DECL +xilinx_apps::louvainmod::LouvainModImpl* xilinx_louvainmod_createImpl(const xilinx_apps::louvainmod::Options& options); + +// XILINX_LOUVAINMOD_IMPL_DECL +void xilinx_louvainmod_destroyImpl(xilinx_apps::louvainmod::LouvainModImpl* pImpl); +} + +// int loadComputeUnitsToFPGAs(char* xclbinPath, int kernelMode, +// unsigned numDevices, std::string deviceNames); +// float loadAlveoAndComputeLouvainWrapper(int argc, char *argv[]); +// float louvain_modularity_alveo(int argc, char *argv[]); +// int compute_modularity(char* inFile, char* clusterInfoFile, int offset); + +namespace xilinx_apps { +namespace louvainmod { + +/** + * @brief %Exception class for Louvain modularity run-time errors + * + * This exception class is derived from `std::exception` and provides the standard @ref what() member function. + * An object of this class is constructed with an error message string, which is stored internally and + * retrieved with the @ref what() member function. + */ +class Exception : public std::exception { + std::string message; + + public: + /** + * Constructs an Exception object. + * + * @param msg an error message string, which is copied and stored internal to the object + */ + Exception(const std::string& msg) : message(msg) {} + + /** + * Returns the error message string passed to the constructor. + * + * @return the error message string + */ + virtual const char* what() const noexcept override { return message.c_str(); } +}; + +struct Edge { + long head; + long tail; + double weight; + Edge(long head_ = 0, long tail_ = 0, double weight_ = 1.0) { + head = head_; + tail = tail_; + weight = weight_; + } +}; + +enum class PartitionNameMode { + Auto = 0, // Name style depends on number of servers listed in clusterIpAddresses + Flat, // partitions are numbered consecutively with no regard for server cluster + Server // partitions are numbered with both a server number and partition number within the server +}; + +struct Options { + bool verbose = true; + XString xclbinPath; + XString nameProj; // -name option: location of "partition project" created by partitioning, read by load/compute + XString alveoProject; // Alveo project file .par.proj TODO: to be combined with nameProj + int modeAlveo; + int kernelMode = LOUVAINMOD_PRUNING_KERNEL; // Kernel mode + unsigned numDevices = 1; // number of devices + XString deviceNames; // space-separated list of target device names + unsigned nodeId = 0; // node ID 0 will be the driver, all others will be workers + unsigned serverIndex = 0; // node ID 0 will be the driver, all others will be workers + XString hostName; // optional host name of this server for debugging purposes + XString clusterIpAddresses; // space-separated list of server IP addresses in the cluster, or empty for 1 server + XString hostIpAddress; // IP address of this server, or empty for 1 server + PartitionNameMode partitionNameMode = PartitionNameMode::Auto; // format of partition names +}; + +/// partition class for louvain partition +class LouvainPar { + public: + /// Index for a vertex, which should be between 0 and the total number of vertices in the whole graph. + using VertexIndex = std::uint64_t; + + struct PartitionOptions { + bool BFS_partition = true; // use bfs partition mothed to get low-bandwidth subgraph + int numPars = 1; // total desired number of partitions across all servers + int par_prune = 1; // ghost pruning technique (1 means single ghost node of smallest degree per local node) + // >1 means keep that many ghost nodes per local node (TODO: verify description for >1) + // int numServers = 1; // number of servers, probably should be made obsolete + long totalNumVertices = 0; // TODO: figure this out internally during compute, eliminate need for .par.src file + + PartitionOptions() = default; + PartitionOptions(const PartitionOptions& opt) = default; + PartitionOptions& operator=(const PartitionOptions& opt) = default; + }; + + struct PartitionData { + const long* offsets_tg = nullptr; // values are indexes into edgelist_tg (not into some global edge list) + const Edge* edgelist_tg = nullptr; // head and tail are global vertex ids + const long* drglist_tg = nullptr; + long start_vertex = 0; + long end_vertex = 0; // one vertex ID BEYOND the last vertex of the server partition + long NV_par_requested = + 0; // Requested NV per partition. Leave as 0 to calculate from num Alveo cards on each server + int nodeId = -1; // Node ID for the server, or -1 to use Options::nodeId + bool isWholeGraph = false; // set to true if this server partition is the whole graph + }; + + LouvainPar(const Options& options) : pImpl_(xilinx_louvainmod_createImpl(options)) {} + + ~LouvainPar() { xilinx_louvainmod_destroyImpl(pImpl_); } + + /** + * Reads an input data file and partitions it in preparation for computing Louvain modularity. + * + * @param fileName the name of the file containing the graph to partition + */ + void partitionDataFile(const char* fileName, const PartitionOptions& options); + + void startPartitioning(const PartitionOptions& options); + int addPartitionData(const PartitionData&); // Returns actual number of partitions created + void finishPartitioning(int numAlveoPartitions[]); + + private: + LouvainModImpl* pImpl_ = nullptr; +}; + +/// louvain class for louvain modularity algorithm +class LouvainRun { + public: + struct ComputeOptions { + XString outputFile; + unsigned max_iter; + unsigned max_level; + float tolerance; + bool intermediateResult; + bool final_Q; + bool all_Q; + }; + + LouvainRun(const Options& options) : pImpl_(xilinx_louvainmod_createImpl(options)) {} + + ~LouvainRun() { xilinx_louvainmod_destroyImpl(pImpl_); } + + void setAlveoProject(const char* alveoProject); + void loadAlveo(); // Loads .par files into CPU memory. Can we load first .par per card into HBM here? + void computeLouvain(const ComputeOptions& computeOpts); + float loadAlveoAndComputeLouvain(const ComputeOptions& computeOpts); + + private: + LouvainModImpl* pImpl_ = nullptr; +}; + +} // namespace louvainmod +} // namespace xilinx_apps + +#endif diff --git a/graph/L3/include/xilinxlouvainInternal.h b/graph/L3/include/xilinxlouvainInternal.h new file mode 100644 index 0000000000..0b5f2553a8 --- /dev/null +++ b/graph/L3/include/xilinxlouvainInternal.h @@ -0,0 +1,506 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WANCUNCUANTIES ONCU CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _XILINXLOUVAININTERNAL_H_ +#define _XILINXLOUVAININTERNAL_H_ +#include "xilinxlouvain.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include "xcl2.hpp" +#include +using namespace std; + +#define DWIDTHS (256) +#define CSRWIDTHS (256) +#define COLORWIDTHS (32) +#define NUM (DWIDTHS / 32) +// design for kernel, but only host used now +//#ifndef USE_U55C +//#define MAXNV (1ul << 26) // 67,108,864 +//#define MAXNE (1 << 27) // 134,217.728 +//#define MAXNV_M (64000000) +//#else +//#define MAXNV (1ul << 27) +//#define MAXNE (1 << 28) +//#define MAXNV_M (128000000) +//#endif +//#define VERTEXS (MAXNV / NUM) +//#define EDGES (MAXNE / NUM) + +// glb will be init in ParLV.cpp:host_ParserParameters +extern long glb_MAXNV; +extern long glb_MAXNE; +extern long glb_MAXNV_M; + +#define DEGREES (1 << 17) +#define COLORS (4096) +typedef double DWEIGHT; + +#ifndef MULTITHREAD /* Enable multi-thread mode for using OpenMP for host code */ +#define NUMTHREAD (1) +#else +#define NUMTHREAD (16) /* For number of thread, usually it is not the more the best, 16 is based on expericece*/ +#endif +// For enlarge size of HBM space +#define WKARND_HBM /* Enable 2-HBM for storing large graphNew, to be as a default \ + configuration */ +#define NUM_PORT_KERNEL (16) +#define MAX_NUM_PHASE (200) +#define MAX_NUM_TOTITR (10000) +#define MAX_NUM_DEV (64) +#define MAX_NUM_PARTITIONS (1024) + +using edge = xilinx_apps::louvainmod::Edge; + +class graphNew { + public: + long numVertices; /* Number of columns */ + long sVertices; /* Number of rows: Bipartite graph: number of S vertices; T = N - S */ + long numEdges; /* Each edge stored twice, but counted once */ + long* edgeListPtrs; /* start vertex of edge, sorted, primary key */ + edge* edgeList; /* end vertex of edge, sorted, secondary key */ +}; + +struct TimeLv { + int parNo; + int phase; + int totItr; + unsigned int deviceID[MAX_NUM_PHASE]; + unsigned int cuID[MAX_NUM_PHASE]; + unsigned int channelID[MAX_NUM_PHASE]; + + double totTimeAll; + double totTimeInitBuff; // = 0; + double totTimeReadBuff; // = 0; + double totTimeReGraph; // = 0; + double totTimeE2E_2; // = 0; + double totTimeE2E; // = 0; + double totTimeE2E_DEV[MAX_NUM_DEV]; // = 0; + double totTimeBuildingPhase; + double totTimeClustering; + double totTimeColoring; + double totTimeFeature; // = 0; + + double timePrePre; + double timePrePre_dev; + double timePrePre_xclbin; + double timePrePre_buff; + + double eachTimeInitBuff[MAX_NUM_PHASE]; + double eachTimeReadBuff[MAX_NUM_PHASE]; + double eachTimeReGraph[MAX_NUM_PHASE]; + double eachTimeE2E_2[MAX_NUM_PHASE]; + double eachTimeE2E[MAX_NUM_PHASE]; + double eachTimePhase[MAX_NUM_PHASE]; + double eachTimeFeature[MAX_NUM_PHASE]; + double eachMod[MAX_NUM_PHASE]; + int eachItrs[MAX_NUM_PHASE]; + long eachClusters[MAX_NUM_PHASE]; + double eachNum[MAX_NUM_PHASE]; + double eachC[MAX_NUM_PHASE]; + double eachM[MAX_NUM_PHASE]; + double eachBuild[MAX_NUM_PHASE]; + double eachSet[MAX_NUM_PHASE]; +}; +struct GLVHead { + long NV; + long NVl; + long NE; + long NElg; + long NC; + double Q; + int numColors; + int numThreads; + char name[256]; + int ID; +}; +template +void SaveHead(char* name, T_HEAD* ptr) { + assert(name); + FILE* fp = fopen(name, "wb"); + fwrite(ptr, sizeof(T_HEAD), 1, fp); + fclose(fp); +} +template +void LoadHead(char* name, T_HEAD* ptr) { + assert(name); + FILE* fp = fopen(name, "rb"); + fread(ptr, sizeof(T_HEAD), 1, fp); + fclose(fp); +} +// loading an other file on disk by BFS +template +void Loadselected(char* name, T_HEAD** ptr) { + assert(name); + FILE* fp = fopen(name, "rb"); + long nv = 0; + fread(&nv, sizeof(long), 1, fp); + if (nv < 0) { + printf("ERROR: value(%ld) of NV is not right!!! \n", nv); + fclose(fp); + } + *ptr = (T_HEAD*)malloc(sizeof(T_HEAD) * nv); + fread(*ptr, sizeof(T_HEAD), nv, fp); + fclose(fp); +} +struct FeatureLV; +class GLV { + public: + long NV; + long NVl; + long NE; + long NElg; + long NC; + double Q; + int numColors; + int numThreads; + char name[256]; + int ID; + graphNew* G; + long* C; + long* M; + int* colors; + list com_list; + TimeLv times; + + public: + GLV(); + GLV(int& id); + ~GLV(); + void InitVar(); + void FreeMem(); + void CleanCurrentG(); + void InitByFile(char*); + void InitByOhterG(graphNew*); + void SetByOhterG(graphNew*); + void SetByOhterG(graphNew* G_src, long* M_src); + void InitG(graphNew* G_src); + void InitC(long* C_src); + void InitM(long* M_src); + void InitC(); + void InitM(); + void InitColor(); + void SetM(long* M_src); + void SetM(); + void SetC(long* C_src); + void SetC(); + void ResetColor(); + void ResetC(); + void SyncWithG(); + void print(); + void printSimple(); + void SetName(char* nm); //{strcpy(name, nm);}; + void SetName_par(int, int, long, long, int); + void SetName_loadg(int ID_curr, char* path); + void SetName_ParLvMrg(int num_par, int ID_src); + void SetName_lv(int, int); + void SetName_cat(int ID_src1, int ID_src2); + void PushFeature(int ph, int iter, double time, bool FPGA); + void printFeature(); + GLV* CloneSelf(int& id_glv); + GLV* CloneSelf_lite(int& id_glv); + GLV* RstColorWithGhost(); + void RstNVlByM(); + void RstNVElg(); +}; + +struct FeatureLV { + double totalTot; + double totalIn; + double m; + double Q; + long NV; + long NE; + long NC; // number of community/number of clusters + int No_phase; + int Num_iter; + double time; + bool isFPGA; + void init(); + FeatureLV(); + FeatureLV(GLV* glv); + double ComputeQ(GLV* glv); + double ComputeQ2(GLV* glv); + void PrintFeature(); +}; + +struct KMemorys_clBuff { + cl::Buffer db_config0; + cl::Buffer db_config1; + // + cl::Buffer db_offsets; + cl::Buffer db_indices; + cl::Buffer db_weights; + cl::Buffer db_indices2; + cl::Buffer db_weights2; + cl::Buffer db_colorAxi; + cl::Buffer db_colorInx; + // + cl::Buffer db_cidPrev; + cl::Buffer db_cidCurr; + // + cl::Buffer db_cidSizePrev; + cl::Buffer db_cidSizeUpdate; + cl::Buffer db_cidSizeCurr; + // + cl::Buffer db_totPrev; + cl::Buffer db_totUpdate; + cl::Buffer db_totCurr; + // + cl::Buffer db_cWeight; +}; + +struct KMemorys_host_prune { + int64_t* config0; + DWEIGHT* config1; + // Graph data + int* offsets; + int* indices; + float* weights; + int* indices2; + float* weights2; + int* colorAxi; + int* colorInx; + // Updated Community info + int* cidPrev; + int* cidCurr; + // Iterated size of communities + int* cidSizePrev; + int* cidSizeUpdate; + int* cidSizeCurr; + // Iterated tot of communities + float* totPrev; + float* totUpdate; + float* totCurr; + // + float* cWeight; + // + int* offsetsdup; + int* indicesdup; + int* indicesdup2; + uint8_t* flag; + uint8_t* flagUpdate; + KMemorys_host_prune() { memset((void*)this, 0, sizeof(KMemorys_host_prune)); } + void freeMem() { + free(config0); + free(config1); + // + free(offsets); + free(indices); + free(weights); + if (indices2) free(indices2); + if (weights2) free(weights2); + free(colorAxi); + free(colorInx); + // + free(cidPrev); + free(cidCurr); + // + free(totPrev); + free(totUpdate); + free(totCurr); + // + free(cidSizeCurr); + free(cidSizeUpdate); + free(cidSizePrev); + // + free(cWeight); + // free + free(offsetsdup); + free(indicesdup); + free(indicesdup2); + free(flag); + free(flagUpdate); + } +}; + +struct KMemorys_clBuff_prune { + cl::Buffer db_config0; + cl::Buffer db_config1; + // + cl::Buffer db_offsets; + cl::Buffer db_indices; + cl::Buffer db_weights; + cl::Buffer db_indices2; + cl::Buffer db_weights2; + cl::Buffer db_colorAxi; + cl::Buffer db_colorInx; + // + cl::Buffer db_cidPrev; + cl::Buffer db_cidCurr; + // + cl::Buffer db_cidSizePrev; + cl::Buffer db_cidSizeUpdate; + cl::Buffer db_cidSizeCurr; + // + cl::Buffer db_totPrev; + cl::Buffer db_totUpdate; + cl::Buffer db_totCurr; + // + cl::Buffer db_cWeight; + // + cl::Buffer db_offsetsdup; + cl::Buffer db_indicesdup; + cl::Buffer db_indicesdup2; + cl::Buffer db_flag; + cl::Buffer db_flagUpdate; +}; + +int host_ParserParameters(int argc, + char** argv, + double& opts_C_thresh, //; //Threshold with coloring on + long& opts_minGraphSize, //; //Min |V| to enable coloring + double& opts_threshold, //; //Value of threshold + int& opts_ftype, //; //File type + char* opts_inFile, //; + bool& opts_coloring, // + bool& opts_output, //; + bool& opts_VF, //; + char* opts_xclbinPath); + +graphNew* host_PrepareGraph(int opts_ftype, char* opts_inFile, bool opts_VF); + +int host_writeOut(char* opts_inFile, long NV_begin, long* C_orig); + +void runLouvainWithFPGA(graphNew* G, // Input graph, undirectioned + long* C_orig, // Output + char* opts_xclbinPath, + bool opts_coloring, + long opts_minGraphSize, + double opts_threshold, + double opts_C_thresh, + int numThreads); + +long renumberClustersContiguously_ghost(long* C, long size, long NV_l); + +// Only used by L3 + +bool PhaseLoop_CommPostProcessing(long NV, + int numThreads, + double opts_threshold, + bool opts_coloring, + double prevMod, + double currMod, + // modified: + graphNew*& G, + long*& C, + long*& C_orig, + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase); + +double PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, + GLV* pglv_iter, + int numThreads, + double opts_threshold, + bool opts_coloring, + // modified: + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase, + double& time_renum, + double& time_C, + double& time_M, + double& time_buid, + double& time_set); + +double PhaseLoop_CommPostProcessing_par_renumber(GLV* pglv_orig, + GLV* pglv_iter, + int numThreads, + double opts_threshold, + bool opts_coloring, + // modified: + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase, + double& time_renum, + double& time_C, + double& time_M, + double& time_buid, + double& time_set); + +double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, + graphNew* G, + long* M, + double opts_C_thresh, + double* currMod, + // Updated variables + int* colors, + KMemorys_host_prune* buff_host_prune); +double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune_renumber(int numColors, + long NVl, + graphNew* G, + long* M, + double opts_C_thresh, + double* currMod, + // Updated variables + int* colors, + KMemorys_host_prune* buff_host_prune); +double PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune_renumber_2cu(int numColors, + long NVl, + graphNew* G, + long* M, + double opts_C_thresh, + double* currMod, + // Updated variables + int* colors, + KMemorys_host_prune* buff_host); +double PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune(long vertexNum, + KMemorys_host_prune* buff_host_prune, + int* eachItrs, + // output + long* C, + int* eachItr, + double* currMod); +double PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune_renumber(long vertexNum, + KMemorys_host_prune* buff_host_prune, + int* eachItrs, + // output + long* C, + int* eachItr, + double* currMod, + long* numClusters); + +struct LouvainPara { + bool opts_coloring; // whether use coloring; It always be true for FPGA flow + long opts_minGraphSize; // Minimal number of community for stopping Louvain phase + double opts_threshold; // dQ threshold for Non-coloring flow + double opts_C_thresh; // dQ threshold for coloring flow + int numThreads; // Number of threads + int max_num_level; + int max_num_iter; +}; + +#endif diff --git a/graph/L3/lib/Makefile b/graph/L3/lib/Makefile index 6d3d60c6f3..780e9db3da 100755 --- a/graph/L3/lib/Makefile +++ b/graph/L3/lib/Makefile @@ -27,7 +27,8 @@ ifndef XILINX_XRT endif #Checks for g++ -CXX := g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +$(warning [WARNING]: CXX is $(CXX).) ifeq ($(HOST_ARCH), x86) ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) ifndef XILINX_VIVADO @@ -47,13 +48,14 @@ endif CXXFLAGS += -I$(XFLIB_DIR)/L2/include CXXFLAGS += -I$(XFLIB_DIR)/ext/xcl2 CXXFLAGS += -I$(XFLIB_DIR)/L3/include +CXXFLAGS += -I$(XFLIB_DIR)/L3/graphPartition/grappolo/include CXXFLAGS += -I$(XFLIB_DIR)/../utils/L1/include XILINX_XRM=/opt/xilinx/xrm -CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_VIVADO)/include -I$(XILINX_XRM)/include -std=c++11 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label +CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_VIVADO)/include -I$(XILINX_XRM)/include -std=c++11 -Wall -Wno-unknown-pragmas -Wno-unused-label LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -pthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE -L$(XILINX_XRM)/lib -lxrm -CXXFLAGS += -fmessage-length=0 -O3 +CXXFLAGS += -fmessage-length=0 -O3 -Ofast -DNDEBUG CXXFLAGS +=-I$(CUR_DIR)/src/ ifneq ($(HOST_ARCH), x86) @@ -66,6 +68,27 @@ CXXFLAGS += -D USE_HBM libGRAPHL3 = $(XFLIB_DIR)/L3/lib/libgraphL3.so libgraphL3 : $(libGRAPHL3) CPP_PATH += $(XFLIB_DIR)/L3/src/common.cpp + +#for graph partition API +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/louvainPartition/ParLV.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/louvainPartition/partitionLouvain.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/louvainPartition/xilinxlouvain.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/RngStream.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/parseInputFiles.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/parallelLouvainMethod.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/utilityClusteringFunctions.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/parseInputParameters.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/coloringDistanceOne.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/vertexFollowing.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/utilityFunctions.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/driverForGraphClustering.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/buildNextPhase.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/louvainMultiPhaseRun.cpp +CPP_PATH += $(XFLIB_DIR)/L3/graphPartition/grappolo/src/parallelLouvainWithColoring.cpp + +#for graph API +CPP_PATH += $(XFLIB_DIR)/L3/src/op_louvainmodularity.cpp +CPP_PATH += $(XFLIB_DIR)/L3/src/louvainRun.cpp CPP_PATH += $(XFLIB_DIR)/L3/src/op_twohop.cpp CPP_PATH += $(XFLIB_DIR)/L3/src/op_sp.cpp CPP_PATH += $(XFLIB_DIR)/L3/src/op_trianglecount.cpp diff --git a/graph/L3/src/louvainRun.cpp b/graph/L3/src/louvainRun.cpp new file mode 100644 index 0000000000..013e49e5b7 --- /dev/null +++ b/graph/L3/src/louvainRun.cpp @@ -0,0 +1,1398 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xf_graph_L3.hpp" +#include "op_louvainmodularity.hpp" +#include +#include "ParLV.h" + +//##################################################################################################################### +// +// LouvainRun myCmd +// +#if 1 +myCmd::myCmd() { + cnt_his = 0; + argc = 0; + cmd_last = -1; +}; +const char* myCmd::cmd_SkipSpace(const char* str) { + const char* pch = str; + while (*pch != 0) { + if (*pch == ' ' || *pch == '\t') { + pch++; + } else + break; + } + return pch; +} +bool isChNormal(char ch) { + return (ch != '\0') && (ch != '\n') && (ch != ' ') && (ch != '\t' && (ch != '#')); +} +int myCmd::cmd_CpyWord(char* des, const char* src) { + int cnt = 0; + assert(des); + assert(src); + while (isChNormal(*src)) { + *des = *src; + src++; + des++; + cnt++; + } + *des = '\0'; + return cnt; +} +void myCmd::cmd_resetArg() { + if (argc == 0) return; + for (int i = 0; i < argc; i++) argv[i][0] = '\0'; + argc = 0; +} + +int myCmd::cmd_findPara(const char* para) { + for (int i = 1; i < argc; i++) { + if (0 == strcmp(argv[i], para)) return i; + } + return -1; +} + +int Getline(char* str) { + char ch; + int cnt = 0; + do { + ch = getchar(); + str[cnt++] = ch; + } while (ch != '\n'); + return cnt; +} + +int myCmd::cmd_Getline() { //( char** argv){ + // int argc; + // assert(argv!=0); + char str[4096]; + + cmd_resetArg(); + // printf("$LVCMD:\/"); + printf("\033[1;31;40m$\033[0m\033[1;34;40m[LVCMD]$: \033[0m"); + // scanf("%[^\n]", str); + Getline(str); + line_last = str; + // his_cmd.push_back(line_last); + const char* pch = str; + do { + pch = cmd_SkipSpace(pch); + if (isChNormal(*pch)) { + pch += cmd_CpyWord(argv[argc++], pch); + } + } while (*pch != '\n' && *pch != '\0' && *pch != '#'); + return argc; +} +int myCmd::cmd_Getline(const char* str) { //( char** argv){ + cmd_resetArg(); + line_last = str; + // his_cmd.push_back(line_last); + const char* pch = str; + do { + pch = cmd_SkipSpace(pch); + if (isChNormal(*pch)) { + pch += cmd_CpyWord(argv[argc++], pch); + } + } while (*pch != '\n' && *pch != '\0' && *pch != '#'); + return argc; +} + +#endif + +//##################################################################################################################### +// +// LouvainRun +// +#if 1 + +void getDiffTime(TimePointType& t1, TimePointType& t2, double& time) { + t2 = chrono::high_resolution_clock::now(); + chrono::duration l_durationSec = t2 - t1; + time = l_durationSec.count(); +} + +/* + Return values: + -1: + Other positive numbers: number of partitions saved in the Alveo project file +*/ +int getNumPartitions(std::string alveoProjectFile) { + int numPartitions = 0; + int numServers; + FILE* fp = fopen(alveoProjectFile.c_str(), "r"); + if (fp == NULL) { + std::cout << "ERROR: Failed to open Alveo project file " << alveoProjectFile << std::endl; + return ERRORCODE_GETNUMPARTITIONS_FAILED_OPEN_ALVEOPRJ; + } + fseek(fp, 0, SEEK_END); + int fsize = ftell(fp); + fseek(fp, 0, SEEK_SET); + char* fdata = (char*)malloc(fsize * sizeof(char)); + assert(fdata); + fread(fdata, fsize, sizeof(char), fp); + fclose(fp); + + myCmd ps; + ps.cmd_Getline(fdata); + if (ps.argc < 8) { + std::cout << "ERROR: Invalid Alveo project settings in " << alveoProjectFile << std::endl; + free(fdata); + return ERRORCODE_GETNUMPARTITIONS_INVALID_ARGC; + } + + ////////////////////////////////////////////////////////////////////////// + // for multi-server partition [-server_par ] + int idx_server = ps.cmd_findPara("-server_par"); + if (idx_server > -1) { + numPartitions = 0; + numServers = atoi(ps.argv[idx_server + 1]); + for (int i_svr = 0; i_svr < numServers; i_svr++) { + numPartitions += atoi(ps.argv[idx_server + 2 + i_svr]); + } + } + + // make sure numPartitions is reasonable + if (numPartitions > MAX_NUM_PARTITIONS) { + std::cout << "ERROR: number of partitions in Alveo project file " << alveoProjectFile << " exceeds the maximum " + << MAX_NUM_PARTITIONS << std::endl; + std::cout << " Please check that the project file is on a shared drive accessible by all nodes and is not " + "corrupted." + << std::endl; + return ERRORCODE_GETNUMPARTITIONS_INVALID_NUMPARS; + } else + return numPartitions; +} + +// persistent storge for L3::Handle that is shared by L3 functions +class sharedHandlesLouvainMod { + public: + std::unordered_map > handlesMap; + static sharedHandlesLouvainMod& instance() { + static sharedHandlesLouvainMod theInstance; + return theInstance; + } +}; + +void freeSharedHandle() { + if (!sharedHandlesLouvainMod::instance().handlesMap.empty()) { + // free the object stored in handlsMap[0] and erase handlsMap[0] + std::cout << "INFO: " << __FUNCTION__ << std::endl; + std::shared_ptr handle0 = sharedHandlesLouvainMod::instance().handlesMap[0]; + handle0->free(); + sharedHandlesLouvainMod::instance().handlesMap.erase(0); + } +} + +int loadComputeUnitsToFPGAs(char* xclbinPath, int kernelMode, unsigned int numDevices, std::string deviceNames) { + int status = 0; + + std::string opName = "louvainModularity"; + std::string kernelName = "kernel_louvain"; + int requestLoad = 100; + + std::shared_ptr handle0 = sharedHandlesLouvainMod::instance().handlesMap[0]; + + xf::graph::L3::Handle::singleOP* op0 = new (xf::graph::L3::Handle::singleOP); + //----------------- Set parameters of op0 again some of those will be covered by command-line + op0->operationName = (char*)opName.c_str(); + op0->setKernelName((char*)kernelName.c_str()); + if (kernelMode == LOUVAINMOD_PRUNING_KERNEL) + op0->setKernelAlias("kernel_louvain_pruning_u50"); + else if (kernelMode == LOUVAINMOD_2CU_U55C_KERNEL) + op0->setKernelAlias("kernel_louvain_2cu_u55"); + + op0->requestLoad = requestLoad; + op0->xclbinFile = xclbinPath; + op0->deviceNeeded = numDevices; + op0->cuPerBoard = (kernelMode == LOUVAINMOD_2CU_U55C_KERNEL) ? 2 : 1; +#ifndef NDEBUG + std::cout << "DEBUG: loadComputeUnitsToFPGAs" + << "\n xclbinPath=" << xclbinPath << "\n kernelMode=" << kernelMode + << "\n numDevices=" << numDevices << "\n deviceNames=" << deviceNames + << "\n cuPerBoard=" << op0->cuPerBoard << std::endl; +#endif + //----------------- enable handle0-------- + handle0->addOp(*op0); + status = handle0->setUp(deviceNames); + + return status; +} + +// create a new shared handle if +// 1. The shared handle does not exist or +// 2. The numDevices option changes +int createSharedHandle(char* xclbinPath, + int kernelMode, + unsigned int numDevices, + std::string deviceNames, + bool opts_coloring, + long opts_minGraphSize, + double opts_C_thresh, + int numThreads) { + int status = 0; + + // return right away if the handle has already been created + if (!sharedHandlesLouvainMod::instance().handlesMap.empty()) { + std::shared_ptr handle0 = sharedHandlesLouvainMod::instance().handlesMap[0]; + + std::cout << "DEBUG: " << __FUNCTION__ << " numDevices=" << handle0->getNumDevices() << std::endl; + handle0->showHandleInfo(); + if (numDevices != handle0->getNumDevices()) { + std::cout << "INFO: " << __FUNCTION__ << "numDevices changed. Creating a new handle." + << " numDevices loaded=" << handle0->getNumDevices() << " numDevices requested=" << numDevices + << std::endl; + freeSharedHandle(); + } else { + std::cout << "INFO: " << __FUNCTION__ << " Using exsiting handle with " << handle0->getNumDevices() + << " devices loaded." << std::endl; + return 0; + } + } + std::cout << "INFO: " << __FUNCTION__ << std::endl; + std::shared_ptr handleInstance(new xf::graph::L3::Handle); + sharedHandlesLouvainMod::instance().handlesMap[0] = handleInstance; + status = loadComputeUnitsToFPGAs(xclbinPath, kernelMode, numDevices, deviceNames); + if (status < 0) return ERRORCODE_CREATESHAREDHANDLE; + + std::shared_ptr handle0 = sharedHandlesLouvainMod::instance().handlesMap[0]; + (handle0->oplouvainmod) + ->mapHostToClBuffers(NULL, kernelMode, opts_coloring, opts_minGraphSize, opts_C_thresh, numThreads); + + return status; +} + +int LoadParLV(char* name, ParLV* p_parlv) { + assert(name); + FILE* fp = fopen(name, "rb"); + + if (fp == NULL) { + printf("ERROR: Failed to open ParLV file %s\n", name); + return -1; + } + + char* ptr = (char*)p_parlv; + int kernelMode = p_parlv->kernelMode; + int num_dev = p_parlv->num_dev; + fread(ptr, sizeof(ParLVVar), 1, fp); + p_parlv->kernelMode = kernelMode; + p_parlv->num_dev = num_dev; + fclose(fp); + + return 0; +} + +// Parser_ParProjFile +// Return value: +// -2: ParLV file cannot be opened +// +int Parser_ParProjFile(std::string projFile, ParLV& parlv, char* path, char* name, char* name_inFile) { +#ifndef NDEBUG + printf("DEBUG:\n projFile=%s\n path=%s\n name=%s\n name_inFile=%s\n", projFile.c_str(), path, name, + name_inFile); +#endif + // Format: -create_alveo_partitions -num_pars -par_prune -name + assert(path); + assert(name); + assert(name_inFile); + FILE* fp = fopen(projFile.c_str(), "r"); + if (fp == NULL) { + printf("\033[1;31;40mERROR\033[0m: Project Metadata file %s failed for open \n", projFile.c_str()); + return -1; + } + fseek(fp, 0, SEEK_END); + int fsize = ftell(fp); + fseek(fp, 0, SEEK_SET); + char* fdata = (char*)malloc(fsize * sizeof(char)); + assert(fdata); + fread(fdata, fsize, sizeof(char), fp); + fclose(fp); + myCmd ps; + ps.cmd_Getline(fdata); + if (ps.argc < 8) { + printf("\033[1;31;40mERROR\033[0m: Partition Project Meta wrong\n"); + free(fdata); + return -1; + } + + if (strcmp("-create_alveo_partitions", ps.argv[0]) == 0 && + (strcmp("-create_alveo_BFS_partitions", ps.argv[0]) != 0)) { + parlv.use_bfs = false; + } else if (strcmp("-create_alveo_partitions", ps.argv[0]) != 0 && + (strcmp("-create_alveo_BFS_partitions", ps.argv[0]) == 0)) { + parlv.use_bfs = true; + } else { + printf("\033[1;31;40mERROR\033[0m: MessageParser_D2W: Unknow head%s. -create_alveo_partitions is required\n", + ps.argv[0]); + free(fdata); + return -1; + } + strcpy(name_inFile, ps.argv[1]); + char* str_par_num = ps.argv[3]; + char* str_par_prune = ps.argv[5]; + char* nameProj = ps.argv[7]; +#ifdef PRINTINFO_2 + printf("\033[1;37;40mINFO: The graph matrix is : %s \033[0m\n", name_inFile); +#endif + if (ps.argc > 9) { + parlv.timesPar.timePar_all = atof(ps.argv[9]); + parlv.timesPar.timePar_save = atof(ps.argv[11]); + } else { + parlv.timesPar.timePar_all = 0; + parlv.timesPar.timePar_save = 0; + } + ////////////////////////////////////////////////////////////////////////// + // for multi-server partition [-server_par num_server num_par_on_server0 ... num_par on serverN-1] + int idx_server = ps.cmd_findPara("-server_par"); + if (idx_server > -1) { + parlv.num_par = 0; + parlv.num_server = atoi(ps.argv[idx_server + 1]); + for (int i_svr = 0; i_svr < parlv.num_server; i_svr++) { + parlv.parInServer[i_svr] = atoi(ps.argv[idx_server + 2 + i_svr]); + parlv.num_par += parlv.parInServer[i_svr]; + } + } + /////////////////////////////////////////////////////////////////////////// + if (nameProj[0] == '/') + PathNoName(path, nameProj); // Absolute name used in project file, so abstract the path use project name + else + PathNoName(path, projFile.c_str()); // Use project file path for abstraction the path + strcpy(name, NameNoPath(nameProj)); + int id_glv = 0; + char namePath_tmp[1024]; + sprintf(namePath_tmp, "%s/%s.par.parlv", path, name); +#ifndef NDEBUG + printf("DEBUG: start LoadParLV, use_bfs=%d\n", parlv.use_bfs); +#endif + if (LoadParLV(namePath_tmp, &parlv) < 0) return -2; + + sprintf(namePath_tmp, "%s/%s.par.src", path, name); + // std::cout << "------------" << __FUNCTION__ << " id_glv=" << id_glv << std::endl; + parlv.plv_src = new GLV(id_glv); + LoadHead(namePath_tmp, (GLVHead*)parlv.plv_src); +#ifndef NDEBUG + printf( + "DEBUG: LoadHead results\n NV=%ld\n NVl=%ld\n NE=%ld\n NElg=%ld\n NC=%ld\n Q=%f\n " + "numColors=%d\n numThreads=%d\n name=%s\n ID=%d\n", + parlv.plv_src->NV, parlv.plv_src->NVl, parlv.plv_src->NE, parlv.plv_src->NElg, parlv.plv_src->NC, + parlv.plv_src->Q, parlv.plv_src->numColors, parlv.plv_src->numThreads, parlv.plv_src->name, parlv.plv_src->ID); +#endif + + // add to parser BFS partition's global ID + if (parlv.use_bfs) { + sprintf(namePath_tmp, "%s/%s.bfs.adj", path, name); + // std::cout << "------------" << __FUNCTION__ << " id_glv=" << id_glv << std::endl; + Loadselected(namePath_tmp, &(parlv.bfs_adjacent)); +#ifndef NDEBUG + printf("DEBUG: Loadselected results\n %d--> %d--> %d\t\n", 0, parlv.bfs_adjacent[0].par_idx, + parlv.bfs_adjacent[0].renum_in_par); +#endif + } + +#ifdef PRINTINFO + printf("\033[1;37;40mINFO\033[0m:Partition Project: path = %s name = %s\n", path, name); +#endif + if (parlv.num_par != atoi(str_par_num)) { + printf("\033[1;31;40mWARNING\033[0m: parlv.num_par(%d) != %d; Value in file will be used\n", parlv.num_par, + atoi(str_par_num)); + } + parlv.num_par = atoi(str_par_num); + parlv.th_prun = atoi(str_par_prune); + + int cnt_file = 0; + + int p = 0; + int i_svr = 0; + int p_svr = 0; + while (p < parlv.num_par) { + char nm[1024]; + if (parlv.num_server == 1) + sprintf(nm, "%s_%03d.par", name, p); + else { + sprintf(nm, "%s_svr%d_%03d.par", name, i_svr, p_svr); + } +#ifndef NDEBUG + printf("DEBUG: par_src->name[%3d]=%s\n", p, nm); +#endif + parlv.par_src[p]->SetName(nm); + cnt_file++; + if (p_svr == parlv.parInServer[i_svr] - 1) { + i_svr++; + p_svr = 0; + } else + p_svr++; + p++; + } + free(fdata); + if (cnt_file != parlv.num_par) + return -1; + else + return 0; +} + +GLV* LoadGLVBin(char* name, int& id_glv) { + assert(name); + + graphNew* g = (graphNew*)malloc(sizeof(graphNew)); + long nv = 0; + long ne = 0; + long ne_undir = 0; + long nc = 0; + double Q = -1; + long head = 0; + long nvl; //= glv->NVl; + long nelg; //= glv->NElg; + + FILE* fp = fopen(name, "rb"); + if (fp == NULL) { + printf("ERROR: LoadGLVBin failed to open %s \n", name); + // fclose(fp); + return NULL; + } + fread(&head, sizeof(long), 1, fp); + if (head != headGLVBin) { + printf("ERROR: head(%ld)!=headGLVBin(%ld) \n", head, headGLVBin); + fclose(fp); + free(g); + return NULL; + } + fread(&nv, sizeof(long), 1, fp); + if (nv <= 0) { + printf("ERROR: value(%ld) of NV is not right!!! \n", nv); + fclose(fp); + free(g); + return NULL; + } + fread(&ne, sizeof(long), 1, fp); + if (ne <= 0) { + printf("ERROR: value(%ld) of NE is not right!!! \n", ne); + fclose(fp); + free(g); + return NULL; + } + fread(&ne_undir, sizeof(long), 1, fp); + if (ne_undir <= 0) { + printf("ERROR: value(%ld) of ne_undir is not right!!! \n", ne_undir); + fclose(fp); + free(g); + return NULL; + } + fread(&nc, sizeof(long), 1, fp); + if (nc < 0) { + printf("ERROR: value(%ld) of NC is not right!!! \n", nc); + fclose(fp); + free(g); + return NULL; + } + fread(&Q, sizeof(double), 1, fp); + if (Q > 1) { + printf("ERROR: value(%lf) of Q is not right!!! \n", Q); + fclose(fp); + free(g); + return NULL; + } + fread(&nvl, sizeof(long), 1, fp); + fread(&nelg, sizeof(long), 1, fp); + + g->numEdges = ne; + g->numVertices = nv; +#ifdef PRINTINFO + printf("INFO: LoadGLVBin %s Successfully: nv=%ld ne=%ld undir ne=%ld nc=%ld Q=%lf \n", name, nv, ne, ne_undir, nc, + Q); +#endif + g->edgeListPtrs = (long*)malloc(sizeof(long) * nv + 1); + g->edgeList = (edge*)malloc(sizeof(edge) * ne_undir); + long* M = (long*)malloc(sizeof(long) * nv); + assert(g->edgeListPtrs); + assert(g->edgeList); + assert(M); + fread(g->edgeListPtrs, sizeof(long), nv + 1, fp); + fread(g->edgeList, sizeof(edge), ne_undir, fp); + fread(M, sizeof(long), nv, fp); + // std::cout << "------------" << __FUNCTION__ << " id_glv=" << id_glv << std::endl; + GLV* glv = new GLV(id_glv); + glv->SetByOhterG(g, M); + fread(glv->C, sizeof(long), nv, fp); + glv->NC = nc; + glv->Q = Q; + glv->NVl = nvl; //= glv->NVl; + glv->NElg = nelg; //= glv->NElg; + fclose(fp); + return glv; +} + +GLV* LoadGLVBin(char* path, char* file, int& id_glv) { + assert(path); + assert(file); + char pathName[2048]; + strcpy(pathName, path); + strcat(pathName, file); + return LoadGLVBin(pathName, id_glv); +} + +// Return values +// 0: Success +// -2: Fail to load partition file +int LouvainProcess_part1(int& nodeID, ParLV& parlv, char* path_driver, ParLV& parlv_wkr) { +#ifndef NDEBUG + std::cout << "DEBUG:" << __FILE__ << "::" << __FUNCTION__ + //<< "\n msg_d2w=" << tmp_msg_d2w + << "\n parlv_wkr num_par=" << parlv_wkr.num_par << std::endl; +#endif + + int status = 0; + + // this will be initialized by message again + // parlv_wkr.Init(parlv.kernelMode, NULL, parlv.num_par, parlv.num_dev, parlv.isPrun, parlv.th_prun); + // char path_driver[1024]; + // char names[32][256]; + + // MessageParser_D2W(tmp_msg_d2w, parlv_wkr, path_driver, names, nodeID); + // parlv_wkr.num_par = parlv.num_par; + + // parlv.PrintSelf(); + // worker: load file//////////////// + TimePointType l_load_start = chrono::high_resolution_clock::now(); + TimePointType l_load_end; + + int id_glv_wkr = 0; + char* path_worker = (char*)"./"; + // Worker: Loading from disk + for (int p = 0; p < parlv_wkr.num_par; p++) { +#ifndef NDEBUG + printf("INFO: Loading partition file %s%s \n", path_driver, parlv.par_src[p]->name); +#endif + parlv_wkr.par_src[p] = LoadGLVBin(path_driver, parlv.par_src[p]->name, id_glv_wkr); + if (parlv_wkr.par_src[p] == NULL) return -2; + parlv_wkr.par_src[p]->SetName(parlv.par_src[p]->name); + parlv_wkr.st_Partitioned = true; +#ifdef PRINTINFO + parlv_wkr.par_src[p]->printSimple(); +#endif + } + + getDiffTime(l_load_start, l_load_end, parlv_wkr.timesPar.timeWrkLoad[0]); + + return status; +} + +/* + For both driver; no zmq communications occur + Return values: + 0: Success + -1: Error in Parser_ParProjFile + -2: Error in LouvainProcess_part1 +*/ +int load_alveo_partitions_DriverSelf( // Driver* drivers, + std::string projFile, + int numNode, + int numPureWorker, + // output + ParLV& parlv_drv, + ParLV& parlv_wkr, + char* name_inFile) { + int status = 0; +#ifndef NDEBUG + std::cout << "DEBUG: " << __FILE__ << "::" << __FUNCTION__ << " numNode=" << numNode + << " numPureWorker=" << numPureWorker << std::endl; +#endif + + // ParLV parlv; + char path_proj[1024]; + char name_proj[1024]; + if (Parser_ParProjFile(projFile, parlv_drv, path_proj, name_proj, name_inFile) != 0) { + printf("\033[1;31;40mERROR\033[0m: load_alveo_partitions Failed\n"); + return -1; + } + + /* + //int id_glv = 0; + + // Assign partitions to the driver and all workers. + // The driver gets the last partitions. + // Each worker gets numPartitions/numNode partitions. + // Below is an example of partition assignment for 10 partitions on 3 servers (a.k.a nodes) + // worker1: par_svr0_000.par par_svr0_001.par par_svr0_002.par + // worker2: par_svr1_000.par par_svr1_001.par par_svr1_002.par + // driver : par_svr2_000.par par_svr2_001.par par_svr2_002.par par_svr2_003.par + //char msg_d2w[numPureWorker][MAX_LEN_MESSAGE]; + //char msg_driver[MAX_LEN_MESSAGE]; + { + //////////////////////////// CreateSendMessage for driver itself //////////////////////////// + //TimePointType l_send_start = chrono::high_resolution_clock::now(); + //TimePointType l_send_end; + //int stride = parlv_drv.num_par / numNode; + // Generate message to driver itself, which always gets the last partition files + // MessageGen_D2W(msg_driver, parlv_drv, path_proj, stride * (numNode - 1), parlv_drv.num_par, 0); + +// //////////////////////////// CreateSendMessage for worker to be sent //////////////////////////// +// for(int nodeID = 1; nodeID<=numPureWorker; nodeID++){ +// MessageGen_D2W(msg_d2w[nodeID-1], parlv_drv, path_proj, stride * (nodeID - 1), stride * nodeID, nodeID); +// #ifndef NDEBUG +// printf("DEBUG: after MessageGen_D2W msg_d2w=%s\n", msg_d2w[nodeID-1]); +// #endif +// drivers[nodeID-1].send(msg_d2w[nodeID-1], MAX_LEN_MESSAGE, 0); +// } + +// getDiffTime(l_send_start, l_send_end, parlv_drv.timesPar.timeDriverSend); + }*/ + int nodeID = 0; + // char msg_w2d[numNode][MAX_LEN_MESSAGE]; + { + // status = LouvainProcess_part1(nodeID, parlv_drv, msg_driver, parlv_wkr); + status = LouvainProcess_part1(nodeID, parlv_drv, path_proj, parlv_drv); + } + + return status; +} + +/* + Return values: + 0: Success + -1: + -2: + -3: +*/ +int compute_louvain_alveo_seperated_load(int kernelMode, + unsigned int numDevices, + unsigned int numPartitions, + char* alveoProject, + int mode_zmq, + int numPureWorker, + char* nameWorkers[128], + unsigned int nodeId, + float tolerance, + bool verbose, + std::shared_ptr& handle0, + ParLV* p_parlv_dvr, + ParLV* p_parlv_wkr) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << "\n kernelMode=" << kernelMode << "\n numDevices=" << numDevices + << "\n numPartitions=" << numPartitions << "\n alveoProject=" << alveoProject + << "\n mode_zmq=" << mode_zmq << "\n numPureWorker=" << numPureWorker + << "\n nodeId=" << nodeId << "\n tolerance=" << tolerance << "\n verbose=" << verbose + << std::endl; + + for (int i = 0; i < numPureWorker; i++) + std::cout << "DEBUG: nameWorker " << i << "=" << nameWorkers[i] << std::endl; + +#endif + int status = 0; + bool isPrun = true; + + double opts_threshold = 0.000001; // Value of threshold, no impect on for FPGA related flows. + int par_prune = 1; + int numNode = numPureWorker + 1; + + if (status < 0) return status; + + if (mode_zmq == ZMQ_DRIVER) { + //----------------------------------------------------------------- + // DRIVER + //----------------------------------------------------------------- + char inFile[1024] = ""; + + p_parlv_dvr->Init(kernelMode, NULL, numPartitions, numDevices, isPrun, par_prune); + p_parlv_wkr->Init(kernelMode, NULL, numPartitions, numDevices, isPrun, par_prune); + + // API FOR LOADING + { + // Driver* drivers = new Driver[numPureWorker]; + // ConnectWorkers(drivers, numPureWorker, nameWorkers); + TimePointType l_load_start = chrono::high_resolution_clock::now(); + TimePointType l_load_end; + status = load_alveo_partitions_DriverSelf(/*drivers,*/ alveoProject, numNode, numPureWorker, (*p_parlv_dvr), + (*p_parlv_wkr), inFile); + if (status < 0) return status; + + getDiffTime(l_load_start, l_load_end, p_parlv_dvr->timesPar.timeDriverLoad); + /* + const char* char_tmp = "shake hands from Driver"; + for (int i = 0; i < numPureWorker; i++) { + #ifdef PRINTINFO + printf("Driver shake hands with worker %d\n", (i + 1)); + #endif + drivers[i].send(char_tmp, MAX_LEN_MESSAGE, 0); + } + + isAllWorkerLoadingDone(drivers, numPureWorker); + delete[] drivers; + */ + } +#ifdef PRINTINFO + printf("\n\n\033[1;31;40mDriver's LOADING DONE \033[0m\n"); + printf("\n\n\033[1;31;40mPlease Wait for Workers' Done\033[0m\n"); + printf("\n\033[1;31;40mTO START LOUVAIN PUT ANY KEY: \033[0m"); + // getchar(); + + // TODO Add synchronization here + printf("\n\033[1;31;40mTO RUNNING LOUVAIN \033[0m\n"); +#endif + // API FOR RUNNING LOUVAIN + } + // else if (mode_zmq == ZMQ_WORKER) { + // //----------------------------------------------------------------- + // // WORKER + // //----------------------------------------------------------------- + // p_parlv_wkr->Init(kernelMode, NULL, numPartitions, numDevices, isPrun, par_prune); + // p_parlv_wkr->timesPar.timeAll = getTime(); + // char LoadCommand[MAX_LEN_MESSAGE]; + // { + // char inFile[1024]; + // ParLV parlv_tmp; + // parlv_tmp.Init(kernelMode, NULL, numPartitions, numDevices, isPrun, par_prune); + + // status = LouvainGLV_general_top_zmq_worker_new_part1(parlv_tmp, nodeId, (*p_parlv_wkr), NULL); + // } + // } + + return status; +} + +void Louvain_thread_core( + std::shared_ptr handle0, int kernelMode, GLV* glv_src, GLV* glv, LouvainPara* para_lv) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FILE__ << "::" << __FUNCTION__ << "\n kernelMode=" << kernelMode + << "\n NVl=" << glv->NVl << std::endl; +#endif + xf::graph::L3::louvainModularity(handle0, kernelMode, glv_src, glv, para_lv); +} + +GLV* L3_LouvainGLV_general( + int& id_glv, std::shared_ptr& handle0, int kernelMode, GLV* glv_src, LouvainPara* para_lv) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << std::endl; +#endif + GLV* glv_iter; + std::thread td; + + glv_iter = glv_src->CloneSelf(id_glv); + assert(glv_iter); + glv_iter->SetName_lv(glv_iter->ID, glv_src->ID); + + td = std::thread(Louvain_thread_core, handle0, kernelMode, glv_src, glv_iter, para_lv); + td.join(); + return glv_iter; +} + +/* + +*/ +void Server_SubLouvain(std::shared_ptr& handle0, + ParLV& parlv, + int& id_glv, + LouvainPara* para_lv) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FILE__ << "::" << __FUNCTION__ << "\n handle0=" << handle0 + << " parlv.num_par=" << parlv.num_par << "\n parlv.num_dev=" << parlv.num_dev + << "\n id_glv=" << id_glv << std::endl; +#endif + parlv.timesPar.timeLv_all = getTime(); + GLV* glv[parlv.num_par]; + std::thread td[parlv.num_par]; + for (int p = 0; p < parlv.num_par; p++) { + glv[p] = parlv.par_src[p]->CloneSelf(id_glv); + } + int cuPerBoard = handle0->oplouvainmod->cuPerBoardLouvainModularity; // cuPerBoard + int parCnt = 0; + while (parCnt < parlv.num_par) { + // Can only launch as many threads as numDevices + for (int cu = 0; cu < parlv.num_dev * cuPerBoard; cu++) { + // also need to handle when num_par is not divisible by num_dev + if (parCnt + cu >= parlv.num_par) break; + printf("INFO: start Louvain_thread_core thread %d\n", parCnt + cu); + parlv.timesPar.timeLv[parCnt + cu] = getTime(); + assert(glv[parCnt + cu]); + td[parCnt + cu] = std::thread(Louvain_thread_core, handle0, parlv.kernelMode, parlv.par_src[parCnt + cu], + glv[parCnt + cu], para_lv); + parlv.par_lved[parCnt + cu] = glv[parCnt + cu]; + char tmp_name[1024]; + strcpy(tmp_name, parlv.par_src[parCnt + cu]->name); + parlv.par_lved[parCnt + cu]->SetName(strcat(tmp_name, "_wrk_lv")); + } + + for (int cu = 0; cu < parlv.num_dev * cuPerBoard; cu++) { + if (parCnt + cu >= parlv.num_par) break; + td[parCnt + cu].join(); + parlv.timesPar.timeLv[parCnt + cu] = getTime() - parlv.timesPar.timeLv[parCnt + cu]; + } + parCnt += parlv.num_dev * cuPerBoard; + } + + parlv.st_ParLved = true; + parlv.timesPar.timeLv_all = getTime() - parlv.timesPar.timeLv_all; +} + +void BackAnnotateC(int num_par, + GLV* par_src[], + long* off_src, + long* C_mg_lved, + // OUTPUT + GLV* plv_src) { + for (int p = 0; p < num_par; p++) { + for (long v_sub = 0; v_sub < par_src[p]->NVl; v_sub++) { + long v_orig = v_sub + off_src[p]; + long v_merged = par_src[p]->C[v_sub]; + plv_src->C[v_orig] = C_mg_lved[v_merged]; + } + } +} + +void BackAnnotateC(ParLV& parlv, + // OUTPUT + GLV* plv_src) { + BackAnnotateC(parlv.num_par, parlv.par_src, parlv.off_src, parlv.plv_merged->C, plv_src); +} +void BackAnnotateC(ParLV& parlv) { + BackAnnotateC(parlv.num_par, parlv.par_src, parlv.off_src, parlv.plv_merged->C, parlv.plv_src); +} + +GLV* Driver_Merge_Final_LoacalPar(std::shared_ptr& handle0, + ParLV& parlv, + int& id_glv, + LouvainPara* para_lv) { + parlv.timesPar.timePre = getTime(); +#ifdef PRINTINFO_2 + printf("\033[1;37;40mINFO: Now doing PreMerging... \033[0m\n"); +#endif + parlv.PreMerge(); + parlv.timesPar.timePre = getTime() - parlv.timesPar.timePre; +#ifdef PRINTINFO + printf("\033[1;37;40mINFO\033[0m: Total time for partition pre-Merge : %lf\n", parlv.timesPar.timePre); +#endif +#ifdef PRINTINFO_2 + printf("\033[1;37;40mINFO: Now doing Merging... \033[0m\n"); +#endif + parlv.timesPar.timeMerge = getTime(); + parlv.MergingPar2(id_glv); + parlv.timesPar.timeMerge = getTime() - parlv.timesPar.timeMerge; +#ifdef PRINTINFO + printf("\033[1;37;40mINFO\033[0m: Total time for partition Merge : %lf\n", parlv.timesPar.timeMerge); +#endif + parlv.timesPar.timeFinal = getTime(); + +// parlv.PrintSelf(); +#ifdef PRINTINFO + parlv.plv_merged->printSimple(); +#endif + if (parlv.st_Merged == false) return NULL; + assert(parlv.plv_merged); +#ifdef PRINTINFO_2 + printf("\033[1;37;40mINFO: Now doing Final Louvain... \033[0m\n"); +#endif + + GLV* glv_final = parlv.plv_merged; //->CloneSelf(id_glv); +#ifdef PRINTINFO_2 + printf("\033[1;37;40mINFO: Now doing BackAnnotationg... \033[0m\n"); +#endif + + BackAnnotateC(parlv); + // printf( "Total time for final : %lf \n" , parlv.timesPar.timeFinal); + // parlv.plv_src->PushFeature(0, 0, 0.0, true); + + parlv.timesPar.timeFinal = getTime() - parlv.timesPar.timeFinal; + + return glv_final; +} + +GLV* louvain_modularity_alveo(std::shared_ptr& handle0, + ParLV& parlv, // To collect time and necessary data + ParLV& parlv_wkr, // Driver's self data for sub-louvain + LouvainPara* para_lv, + int numNode, + int numPureWorker, + char** nameWorkers // To enalbe all workers for Louvain + ) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << " handle0=" << handle0 << std::endl; +#endif + int id_glv = 0; + int nodeID = 0; + GLV* glv_final; + + TimePointType l_start = chrono::high_resolution_clock::now(); + TimePointType l_end; + + // Driver* drivers = new Driver[numPureWorker]; + // ConnectWorkers(drivers, numPureWorker, nameWorkers); + + // enalbeAllWorkerLouvain(drivers, numPureWorker); + + TimePointType l_driver_collect_start = chrono::high_resolution_clock::now(); + TimePointType l_driver_collect_end; + // char msg_w2d[numNode][MAX_LEN_MESSAGE]; + { /////////////// Louvain process on both driver and worker /////////////// + TimePointType l_par_start = chrono::high_resolution_clock::now(); + TimePointType l_par_end; + int id_glv = 0; + bool opts_coloring = true; + // Louvain + TimePointType l_compute_start = chrono::high_resolution_clock::now(); + TimePointType l_compute_end; + Server_SubLouvain(handle0, parlv, id_glv, para_lv); + getDiffTime(l_compute_start, l_compute_end, parlv_wkr.timesPar.timeWrkCompute[0]); + /* + worker: send(save) file//////////////// + parlv_wkr.timesPar.timeWrkSend[0] = 0; + + MessageGen_W2D(msg_w2d[numNode - 1], parlv_wkr, nodeID); + + parlv_wkr.st_ParLved = true; + #ifdef PRINTINFO + parlv_wkr.PrintSelf(); + #endif + getDiffTime(l_par_start, l_par_end, parlv.timesPar.timeLv_all); + } + + { /////////////// Receive messages and Load file for final Louvain in driver /////////////// + TimePointType l_receive_start = chrono::high_resolution_clock::now(); + TimePointType l_receive_end; + // Receive and Parse messages from worker and driver + int num_par_sub = 0; + int num_par_per_worker = parlv.num_par / numNode; + + #pragma omp parallel for + for (int i = 0; i < numPureWorker; i++) { + for (int j = 0; j < num_par_per_worker; j++) { + receiveGLV_OnlyC(&drivers[i], parlv.par_src[j + i * num_par_per_worker]); + parlv.par_lved[j + i * num_par_per_worker] = receiveGLV(&drivers[i], id_glv); + #ifdef PRINTINFO + printf("INFO: Received ID : %d\n", j + i * num_par_per_worker); + #endif + } + drivers[i].receive(msg_w2d[i], MAX_LEN_MESSAGE); + #ifdef PRINTINFO_2 + printf("INFO: Received from worker:%s (requester%d): %s\n", nameWorkers[i], i, msg_w2d[i]); + #endif + } + + for (int i = 0; i < numNode; i++) { + num_par_sub += MessageParser_W2D(i, msg_w2d[i], parlv); + } + + for (int p = numPureWorker * num_par_per_worker; p < num_par_sub; p++) { + parlv.par_src[p] = parlv_wkr.par_src[p - numPureWorker * num_par_per_worker]; + parlv.par_src[p]->ID = p + 1; + + parlv.par_lved[p] = parlv_wkr.par_lved[p - numPureWorker * num_par_per_worker]; + parlv.par_lved[p]->ID = p; + } + parlv.num_server = numNode; + + parlv.st_ParLved = true; + #ifdef PRINTINFO + parlv.PrintSelf(); + #endif + delete[] drivers; + getDiffTime(l_receive_start, l_receive_end, parlv.timesPar.timeDriverRecv); + } + getDiffTime(l_driver_collect_start, l_driver_collect_end, parlv.timesPar.timeDriverCollect); + */ + } + { /////////////// Merge and Final louvain on driver /////////////// + TimePointType l_merge_start = chrono::high_resolution_clock::now(); + TimePointType l_merge_end; + if (parlv.plv_src->C != NULL) free(parlv.plv_src->C); + parlv.plv_src->C = (long*)malloc(sizeof(long) * parlv.plv_src->NV); + printf("before merge, org id_glv = %d\n", id_glv); + glv_final = Driver_Merge_Final_LoacalPar(handle0, parlv, id_glv, para_lv); + + getDiffTime(l_merge_start, l_merge_end, parlv.timesPar.time_done_mg); + } + + getDiffTime(l_start, l_end, parlv.timesPar.timeAll); + +// parlv.plv_src->PushFeature(0, 0, 0.0, true);// calculate Q of results, no need to be included in total time +#ifdef PRINTINFO + printf("Total time for all flow : %lf \n", parlv.timesPar.timeAll); +#endif + return glv_final; + // delete( glv_final); +} + +int host_writeOut(const char* opts_inFile, long NV_begin, long* C_orig) { + if ((opts_inFile == 0) || (C_orig == 0)) { + printf( + "\033[1;31;40mERROR: Function host_writeOut got invalid input buff; Writing out " + "results failed!\n\033[0m"); + return -1; + } + char outFile[4096]; + sprintf(outFile, "%s.clustInfo", opts_inFile); +#ifdef PRINTINFO_2 + printf("\033[1;37;40mINFO: Cluster information will be stored in file: %s\n\033[0m", outFile); +#endif + FILE* out = fopen(outFile, "w"); + for (long i = 0; i < NV_begin; i++) { + fprintf(out, "%ld %ld\n", i, C_orig[i]); + } + fclose(out); + return 0; +} + +//##################################################################################################################### +// +// compute_louvain_alveo_seperated_compute + +template +void PrintArrayByNum(int num, T* array) { + for (int i = 0; i < num; i++) { + if (i == 0) + printf("["); + else + printf(", "); + if (std::is_same::value) + printf("%d", (int)(array[i])); + else if (std::is_same::value) + printf("%ld", (long)(array[i])); + else if (std::is_same::value) + printf("%f", (float)(array[i])); + else if (std::is_same::value) + printf("%lf", (double)(array[i])); + if (i == num - 1) printf("]\n"); + } +} +template +T SummArrayByNum(int num, T* array) { + T ret = 0; + for (int i = 0; i < num; i++) ret += array[i]; + return ret; +} + +int FindMinLevel(ParLV& parlv) { + int ret = MAX_NUM_PHASE; + for (int i = 0; i < parlv.num_par; i++) + ret = ret > parlv.par_src[i]->times.phase ? parlv.par_src[i]->times.phase : ret; + return ret; +} + +int FindMaxLevel(ParLV& parlv) { + int ret = 0; + for (int i = 0; i < parlv.num_par; i++) + ret = ret < parlv.par_src[i]->times.phase ? parlv.par_src[i]->times.phase : ret; + return ret; +} + +void PrintRptPartition(int mode_zmq, ParLV& parlv, int op0_numDevices, int numNode, int numPureWorker) { + if (mode_zmq != ZMQ_WORKER) { + printf("************************************************************************************************\n"); + printf( + "****************************** \033[1;35;40mPartition Louvain Performance\033[0m " + "********************************\n"); + printf("************************************************************************************************\n"); + printf("\033[1;37;40mINFO\033[0m: Original number of vertices : %ld\n", parlv.plv_src->NV); + printf("\033[1;37;40mINFO\033[0m: Original number of un-direct edges : %ld\n", parlv.plv_src->NE); + printf("\033[1;37;40mINFO\033[0m: number of partition : %d \n", parlv.num_par); + printf("\033[1;37;40mINFO\033[0m: number of device used : %d \n", op0_numDevices); + printf("\033[1;37;40mINFO\033[0m: Final number of communities : %ld\n", parlv.plv_src->NC); + printf("\033[1;37;40mINFO\033[0m: Final modularity : %lf\n", + parlv.plv_src->Q); // com_lit.back(). + printf("************************************************************************************************\n"); + + if (mode_zmq == ZMQ_NONE) { + double totTimeOnDev[parlv.num_dev]; + double totTimeFPGA_pure = 0; + double totTimeFPGA_wait = 0; + double totTimeCPU = 0; + for (int d = 0; d < op0_numDevices; d++) totTimeOnDev[d] = 0; + for (int p = 0; p < parlv.num_par; p++) { + for (int d = 0; d < op0_numDevices; d++) { + totTimeOnDev[d] += parlv.par_src[p]->times.totTimeE2E_DEV[d]; + totTimeFPGA_pure += parlv.par_src[p]->times.totTimeE2E_DEV[d]; + } + totTimeFPGA_wait += parlv.par_src[p]->times.totTimeE2E_2; + totTimeCPU += parlv.par_src[p]->times.totTimeAll - parlv.par_src[p]->times.totTimeE2E; + } + totTimeFPGA_pure += parlv.plv_merged->times.totTimeE2E; + totTimeFPGA_wait += parlv.plv_merged->times.totTimeE2E_2; + totTimeCPU += parlv.plv_merged->times.totTimeAll - parlv.plv_merged->times.totTimeE2E; + printf("\t--- Total for All CPU time (s) : %lf\t=\t", totTimeCPU); + for (int p = 0; p < parlv.num_par; p++) + printf(" +%lf (par-%d) ", parlv.par_src[p]->times.totTimeAll - parlv.par_src[p]->times.totTimeE2E, p); + printf(" +%lf (Final) \n", parlv.plv_merged->times.totTimeAll - parlv.plv_merged->times.totTimeE2E); + printf("\t--- Total for All FPGA time (s) : %lf\t=\t", totTimeFPGA_pure); + for (int p = 0; p < parlv.num_par; p++) printf(" +%lf (par-%d) ", parlv.par_src[p]->times.totTimeE2E, p); + printf(" +%lf (Final) \n", parlv.plv_merged->times.totTimeE2E); + + for (int d = 0; d < op0_numDevices; d++) + printf("\t--- Sub-Louvain on Dev-%d : %lf\n", d, totTimeOnDev[d]); + printf("\t--- Fnl-Louvain on Dev-0 : %lf\n", parlv.plv_merged->times.totTimeE2E); + printf( + "\t--- FPGA efficiency with %d device(s) : %2.2f\n", op0_numDevices, + (totTimeFPGA_pure * 100.0) / (op0_numDevices * (parlv.timesPar.timeAll - parlv.timesPar.timePar_all))); + printf( + "************************************************************************************************\n"); + } // end ZMQ_NONE + + printf("************************************************************************************************\n"); + printf("*********************************** Louvain Summary *****************************************\n"); + printf("************************************************************************************************\n"); + printf( + "\033[1;31;40m 1. Time for loading partitions \033[0m : " + "\033[1;31;40m%lf\033[0m (s)\n", + parlv.timesPar.timeDriverLoad); + printf( + "\033[1;31;40m 2. Time for computing distributed Louvain: \033[0m : " + "\033[1;31;40m%lf\033[0m (s) =", + parlv.timesPar.timeDriverExecute); + printf(" Time for sub-Louvain&transmission + Driver Time for Merge&Final-Louvain\n"); + printf(" 2.1 Time for sub-Louvain&transmission : %lf (s) = ", + parlv.timesPar.timeDriverCollect); + printf(" max( driver, worker-1, worker-2)\n"); + + printf(" 2.1.1 Driver Time for sub-Louvain and results receiving : %lf (s) = ", + parlv.timesPar.timeDriverCollect); + printf(" %lf (sub-lv) + %lf (waiting & recv) \n", parlv.timesPar.timeWrkCompute[numNode - 1], + parlv.timesPar.timeDriverCollect - parlv.timesPar.timeWrkCompute[numNode - 1]); + printf(" 2.1.2 Worker Time for sub-Louvain and results sending : %lf (s) = ", + parlv.timesPar.timeWrkCompute[0] + parlv.timesPar.timeWrkSend[0]); + printf(" %lf (sub-lv) + %lf (send) \n", parlv.timesPar.timeWrkCompute[0], parlv.timesPar.timeWrkSend[0]); + printf(" 2.1.3 Worker Time for sub-Louvain and results sending : %lf (s) = ", + parlv.timesPar.timeWrkCompute[1] + parlv.timesPar.timeWrkSend[1]); + printf(" %lf (sub-lv) + %lf (send) \n", parlv.timesPar.timeWrkCompute[1], parlv.timesPar.timeWrkSend[1]); + + printf(" 2.2 Driver Time for Merge&Final-Louavin : %lf (s) = ", + parlv.timesPar.time_done_mg); + printf(" pre-Merge + Merge + Final-Louvain \n"); + printf(" 2.2.1 Driver: pre-Merge : %lf (s)\n", + parlv.timesPar.timePre); + printf(" 2.2.2 Driver: Merge : %lf (s)\n", + parlv.timesPar.timeMerge); + printf(" 2.2.3 Driver: Final-Louvain : %lf (s)\n", + parlv.timesPar.timeFinal); + } + printf("************************************************************************************************\n"); +} + +// Summary +// Number of vertices : 30 +// Number of edges : 15 +// Number of partitions : 10 +// Partition size : 3 +// Number of nodes (machines) : 3 +// Number of Xilinx Alveo cards : 9 +// Number of levels : 3 +// Delta Q tolerance : 0.0001 +// Number of iterations : 20 [15, 10, 5] +// Number of communities : 12 [7, 3, 2] +// Modularity : 0.84 [0.64, 0.77, 0.84] +// Time : 9 sec (Partition Compute: 7 sec, Merge: 1 sec, Merge Compute: 1 sec) +void PrintRptPartition_Summary(ParLV& parlv, + // int numNode, int* card_Node, + double opts_C_thresh) { + int num_par = parlv.num_par; + int numNode = parlv.num_server; + int* card_Node = parlv.numServerCard; + + printf("****************************************Summary*************************************************\n"); + printf("Number of vertices : %ld\n", parlv.plv_src->NV); + printf("Number of edges : %ld\n", parlv.plv_src->NE); + printf("Number of partitions : %d\n", parlv.num_par); + printf("Partition size : < %ld\n", glb_MAXNV_M); + printf("Number of nodes (machines) : %d\n", numNode); + printf("Number of Xilinx Alveo cards : %d", SummArrayByNum(numNode, card_Node)); + PrintArrayByNum(numNode, card_Node); //[3, 3,3] + printf("Number of level [Min, Max] : [ %d, %d ]\n", FindMinLevel(parlv), FindMaxLevel(parlv)); + printf( + "Number of iterations : Each partition has its own iteration number for each level, so please check " + "the Partition Summary\n"); + printf("Delta Q tolerance : %lf\n", opts_C_thresh); + printf("Number of communities : %ld\n", parlv.plv_src->NC); + printf("Modularity : %lf\n", parlv.plv_src->Q); + + printf("Time : %4.3f sec ", parlv.timesPar.timeDriverExecute); + printf(" (Partition Compute: %4.3f sec", parlv.timesPar.timeDriverCollect); + printf(", Merge: %4.3f sec", parlv.timesPar.timePre + parlv.timesPar.timeMerge); + printf(", Merge Compute: %4.3f sec)", parlv.timesPar.timeFinal); + printf("\n"); + printf("********************************Partition Summary***********************************************\n"); + for (int p = 0; p < num_par; p++) { + printf("\tPARTITION-%d :\n ", p); + int numLevel = parlv.par_src[p]->times.phase; + printf("\t\tNumber of levels : %d\n", numLevel); + + printf("\t\tNumber of iterations : %d ", parlv.par_src[p]->times.totItr); + PrintArrayByNum(numLevel, parlv.par_src[p]->times.eachItrs); //[15, 10, 5] + + printf("\t\tNumber of communities : %ld ", parlv.par_src[p]->NC); + PrintArrayByNum(numLevel, parlv.par_src[p]->times.eachClusters); //[7, 3, 2] + + printf("\t\tModularity : %lf ", parlv.par_src[p]->Q); + PrintArrayByNum(numLevel, parlv.par_src[p]->times.eachMod); //[7, 3, 2]//[0.64, 0.77, 0.84] + } + printf("************************************************************************************************\n"); +} + +float compute_louvain_alveo_seperated_compute(int mode_zmq, + int numPureWorker, + char* nameWorkers[128], + unsigned int nodeID, + char* opts_outputFile, + unsigned int max_iter, + unsigned int max_level, + float tolerance, + bool intermediateResult, + bool verbose, + bool final_Q, + bool all_Q, + std::shared_ptr& handle0, + ParLV* p_parlv_dvr, + ParLV* p_parlv_wkr) { +#ifndef NDEBUG + printf("DEBUG: compute_louvain_alveo_seperated_compute"); + printf("\n mode_zmq=%d", mode_zmq); + printf("\n numPureWorker=%d", numPureWorker); + printf("\n nodeID=%d", nodeID); + printf("\n opts_outputFile=%s", opts_outputFile); + printf("\n max_iter=%d", max_iter); + printf("\n max_level=%d", max_level); + printf("\n tolerance=%f", tolerance); + printf("\n intermediateResult=%d", intermediateResult); + printf("\n verbose=%d", verbose); + printf("\n final_Q=%d", final_Q); + printf("\n all_Q=%d\n", all_Q); + + for (int i = 0; i < numPureWorker; i++) + std::cout << "DEBUG: nameWorker " << i << "=" << nameWorkers[i] << std::endl; + +#endif + // TODO: We should remove globals as this is quite confusing + int mode_alveo = ALVEOAPI_RUN; + double opts_C_thresh = tolerance; // Threshold with coloring on + long opts_minGraphSize = 100; // Min |V| to enable coloring + double opts_threshold = 0.000001; // Value of threshold + int numThreads = 16; + int numNode = numPureWorker + 1; + + LouvainPara* para_lv = new (LouvainPara); + para_lv->opts_coloring = true; + para_lv->opts_minGraphSize = opts_minGraphSize; + para_lv->opts_threshold = opts_threshold; + para_lv->opts_C_thresh = opts_C_thresh; + para_lv->numThreads = numThreads; + para_lv->max_num_level = max_level; + para_lv->max_num_iter = max_iter; + + if (mode_alveo == ALVEOAPI_RUN) { + if (mode_zmq == ZMQ_DRIVER) { + // API FOR RUNNING LOUVAIN + GLV* glv_final; + TimePointType l_execute_start = chrono::high_resolution_clock::now(); + TimePointType l_execute_end; + + glv_final = louvain_modularity_alveo(handle0, *p_parlv_dvr, *p_parlv_wkr, para_lv, numNode, numPureWorker, + nameWorkers); + + getDiffTime(l_execute_start, l_execute_end, p_parlv_dvr->timesPar.timeDriverExecute); + glv_final->PushFeature(0, 0, 0.0, true); + p_parlv_dvr->plv_src->Q = glv_final->Q; + p_parlv_dvr->plv_src->NC = glv_final->NC; + PrintRptPartition(mode_zmq, *p_parlv_dvr, p_parlv_dvr->num_dev, numNode, numPureWorker); + PrintRptPartition_Summary(*p_parlv_dvr, opts_C_thresh); + std::string outputFileName(opts_outputFile); + if (!outputFileName.empty()) { + host_writeOut(outputFileName.c_str(), p_parlv_dvr->plv_src->NV, p_parlv_dvr->plv_src->C); + } else { +#ifdef PRINTINFO_2 + printf("\033[1;37;40mINFO: Please use -o to store Cluster information\033[0m\n"); +#endif + } +#ifdef PRINTINFO + printf("Deleting orignal graph... \n"); +#endif +#ifdef PRINTINFO + p_parlv_dvr->plv_src->printSimple(); +#endif + glv_final->printSimple(); + double ret = glv_final->Q; + return ret; + } + // else if (mode_zmq == ZMQ_WORKER) { + // LouvainGLV_general_top_zmq_worker_new_part2(handle0, para_lv, nodeID, *p_parlv_wkr); + // } + } + + return 0; +} + +/* +loadAlveoAndComputeLouvain +Return values: + -1 to 1: Modularity value + -2: Error in getNumPartitions + -3: Error in compute_louvain_alveo_seperated_load + -4: Error in createSharedHandle +*/ +float loadAlveoAndComputeLouvain(char* xclbinPath, + int kernelMode, + unsigned int numDevices, + std::string deviceNames, + char* alveoProject, + unsigned mode_zmq, + unsigned numPureWorker, + char* nameWorkers[128], + unsigned int nodeID, + char* opts_outputFile, + unsigned int max_iter, + unsigned int max_level, + float tolerance, + bool intermediateResult, + bool verbose, + bool final_Q, + bool all_Q) { + ParLV parlv_drv, parlv_wkr; + float ret = 0; + + bool opts_coloring = false; + long opts_minGraphSize = 10; // Min |V| to enable coloring + double opts_C_thresh = tolerance; // Threshold with coloring on + int numThreads = 16; + + int numPartitions = getNumPartitions(alveoProject); + + if (numPartitions < 0) // return error code directly + return numPartitions; + + // Allocating memory for load + if (mode_zmq == ZMQ_DRIVER) { + int id_glv = 0; + for (int i = 0; i < numPartitions; i++) { + parlv_drv.par_src[i] = new GLV(id_glv); + } + } + + int status = createSharedHandle(xclbinPath, kernelMode, numDevices, deviceNames, opts_coloring, opts_minGraphSize, + opts_C_thresh, numThreads); + if (status < 0) return status; + + std::shared_ptr handle0 = sharedHandlesLouvainMod::instance().handlesMap[0]; + ret = compute_louvain_alveo_seperated_load(kernelMode, numDevices, numPartitions, alveoProject, mode_zmq, + numPureWorker, nameWorkers, nodeID, tolerance, verbose, handle0, + &parlv_drv, &parlv_wkr); + + // return right away if load returns an error code + if (ret < 0) return ERRORCODE_COMPUTE_LOUVAIN_ALVEO_SEPERATED_LOAD; + + ret = compute_louvain_alveo_seperated_compute(mode_zmq, numPureWorker, nameWorkers, nodeID, opts_outputFile, + max_iter, max_level, tolerance, intermediateResult, verbose, final_Q, + all_Q, handle0, &parlv_drv, &parlv_wkr); + + return ret; +} + +#endif \ No newline at end of file diff --git a/graph/L3/src/op_louvainmodularity.cpp b/graph/L3/src/op_louvainmodularity.cpp new file mode 100644 index 0000000000..39f80e721c --- /dev/null +++ b/graph/L3/src/op_louvainmodularity.cpp @@ -0,0 +1,1478 @@ +/* + * Copyright 2020-2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include "op_louvainmodularity.hpp" +#include "defs.h" +#include + +namespace xf { +namespace graph { +namespace L3 { + +#define MAX_LOUVAINMOD_CU 128 +std::mutex louvainmodComputeMutex[MAX_LOUVAINMOD_CU]; + +void createHandleLouvainModularity(class openXRM* xrm, + clHandle& handle, + std::string kernelName, + std::string kernelAlias, + std::string xclbinFile, + int32_t IDDevice, + unsigned int requestLoad) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << "\n IDDevice=" << IDDevice << "\n handle=" << &handle << std::endl; +#endif + // Platform related operations + std::vector devices = xcl::get_xil_devices(); + handle.device = devices[IDDevice]; + handle.context = cl::Context(handle.device); + handle.q = cl::CommandQueue(handle.context, handle.device, + CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); + std::string devName = handle.device.getInfo(); + // set up global values based on device selected + // TODO: this needs to be revisited to support mixed cards. + if (devName == "xilinx_u50_gen3x16_xdma_201920_3") { + glb_MAXNV = (1ul << 26); + glb_MAXNE = (1ul << 27); + glb_MAXNV_M = (64000000); + } else if (devName == "xilinx_u55c_gen3x16_xdma_base_2") { + glb_MAXNV = (1ul << 27); + glb_MAXNE = (1ul << 28); + glb_MAXNV_M = (128000000); + } +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << "\n device:" << devName << "\n glb_MAXNV:" << glb_MAXNV + << "\n glb_MAXNE:" << glb_MAXNE << "\n glb_MAXNV_M:" << glb_MAXNV_M << std::endl; +#endif + handle.xclBins = xcl::import_binary_file(xclbinFile); + std::vector devices2; + devices2.push_back(handle.device); + // TODO: handle execption from cl::Program + devices2.resize(1); // must be here in U55C + handle.program = cl::Program(handle.context, devices2, handle.xclBins); + handle.resR = (xrmCuResource*)malloc(sizeof(xrmCuResource)); + memset(handle.resR, 0, sizeof(xrmCuResource)); + xrm->allocCU(handle.resR, kernelName.c_str(), kernelAlias.c_str(), requestLoad); + std::string instanceName0 = handle.resR->instanceName; // "kernel_louvain_0";// + instanceName0 = "kernel_louvain:{" + instanceName0 + "}"; + + const char* instanceName = instanceName0.c_str(); + handle.kernel = cl::Kernel(handle.program, instanceName); + +#ifndef NDEBUG + std::cout << "DEBUG:" << __FUNCTION__ << " IDDevice=" << IDDevice << "=" << devName << " CommandQueue=" << &handle.q + << " kernel=" << &handle.kernel << " kernelName=" << kernelName << " kernelAlias=" << kernelAlias + << " resR.deviceId=" << handle.resR->deviceId << " resR.cuId=" << handle.resR->cuId + << " resR.channelID=" << handle.resR->channelId << " resR.instanceName=" << handle.resR->instanceName + << " instanceName0=" << instanceName0 << " created" << std::endl; + +#endif +} + +uint32_t opLouvainModularity::cuPerBoardLouvainModularity; + +uint32_t opLouvainModularity::dupNmLouvainModularity; + +void opLouvainModularity::setHWInfo(uint32_t numDevices, uint32_t maxCU) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << " numDevices=" << numDevices << " maxCU=" << maxCU << std::endl; +#endif + maxCU_ = maxCU; + numDevices_ = numDevices; + cuPerBoardLouvainModularity = maxCU_ / numDevices_; + + handles = new clHandle[maxCU_]; + // buff_hosts = new KMemorys_host[numDevices_]; + buff_hosts_prune = new KMemorys_host_prune[maxCU_]; //[numDevices_]; +}; + +void opLouvainModularity::freeLouvainModularity(){ + /*for (int i = 0; i < maxCU_; ++i) { + delete[] handles[i].buffer; + } + delete[] handles;*/ +}; + +void opLouvainModularity::cuRelease(xrmContext* ctx, xrmCuResource* resR){ + /*while (!xrmCuRelease(ctx, resR)) { + }; + free(resR);*/ +}; + +void opLouvainModularity::init(class openXRM* xrm, + std::string kernelName, + std::string kernelAlias, + std::string xclbinFile, + uint32_t* deviceIDs, + uint32_t* cuIDs, + unsigned int requestLoad) { + dupNmLouvainModularity = 100 / requestLoad; + cuPerBoardLouvainModularity /= dupNmLouvainModularity; + unsigned int cnt = 0; + unsigned int cntCU = 0; + unsigned int* handleID = new unsigned int[maxCU_]; + handleID[0] = cnt; + handles[0].deviceID = deviceIDs[0]; + handles[0].cuID = cuIDs[0]; + handles[0].dupID = 0; + std::thread th[maxCU_]; + + createHandleLouvainModularity(xrm, handles[cnt], kernelName, kernelAlias, xclbinFile, deviceIDs[cnt], requestLoad); + handles[cnt].buffer = new cl::Buffer[numBuffers_]; + unsigned int prev = deviceIDs[0]; + deviceOffset.push_back(0); + for (int i = 1; i < maxCU_; ++i) { + handles[i].deviceID = deviceIDs[i]; + handles[i].cuID = cuIDs[i]; + handles[i].dupID = i % dupNmLouvainModularity; + createHandleLouvainModularity(xrm, handles[i], kernelName, kernelAlias, xclbinFile, deviceIDs[i], requestLoad); + handles[i].buffer = new cl::Buffer[numBuffers_]; + if (deviceIDs[i] != prev) { + prev = deviceIDs[i]; + deviceOffset.push_back(i); + } + } + delete[] handleID; +} + +void opLouvainModularity::migrateMemObj(clHandle* hds, + bool type, + unsigned int num_runs, + std::vector& ob, + std::vector* evIn, + cl::Event* evOut) { + for (int i = 0; i < num_runs; ++i) { + hds[0].q.enqueueMigrateMemObjects(ob, type, evIn, evOut); // 0 : migrate from host to dev + } +}; + +void opLouvainModularity::releaseMemObjects(clHandle* hds, uint32_t numBuffers) { +#ifndef NDEBUG + std::cout << "DEBUG: releaseMemObjects numBuffers=" << numBuffers << std::endl; + delete[] hds[0].buffer; +#endif +}; + +// mapHostToClBuffers runs only once for each handle since all buffers are mapped +// to FPGA with fixed sizes. +void opLouvainModularity::mapHostToClBuffers( + graphNew* Graph, int kernelMode, bool opts_coloring, long opts_minGraphSize, double opts_C_thresh, int numThreads) { + unsigned long NV_orig; // = G->numVertices; + unsigned long NE_orig; // = G->numEdges; + + NV_orig = glb_MAXNV_M; // Now using fixed size for L3 + NE_orig = (glb_MAXNV_M); // Now using fixed size for L3 + if (NV_orig >= glb_MAXNV - 1) { + printf("WARNING: G->numVertices(%lx) is more than glb_MAXNV(%lx), partition should be used\n", NV_orig, + glb_MAXNV); + NV_orig = glb_MAXNV - 2; + } + + long NE_mem = NE_orig * 2; // number for real edge to be stored in memory + long NE_mem_1 = NE_mem < (glb_MAXNV) ? NE_mem : (glb_MAXNV); + long NE_mem_2 = NE_mem - NE_mem_1; +#ifndef NDEBUG + printf("INFO: in mapHostToClBuffers kernelMode = %d\n\n", kernelMode); +#endif + // for(int i=0; i < numDevices_; i++) { + for (int i = 0; i < maxCU_; i++) { + if (kernelMode == LOUVAINMOD_PRUNING_KERNEL) { +#ifndef NDEBUG + std::cout << "DEBUG: Start LOUVAINMOD_PRUNING_KERNEL UsingFPGA_MapHostClBuff_prune for host buffer[" << i + << "]" << std::endl; +#endif + UsingFPGA_MapHostClBuff_prune(&handles[i], NV_orig, NE_mem_1, NE_mem_2, &buff_hosts_prune[i]); + } else if (kernelMode == LOUVAINMOD_2CU_U55C_KERNEL) { +#ifndef NDEBUG + std::cout << "INFO: Start LOUVAINMOD_2CU_U55C_KERNEL Create host buffer[" << i << "] for 2-cu " + << std::endl; +#endif + unsigned long NV_MAX = 85000000; // limited max vertexes for 2cu verion + UsingFPGA_MapHostClBuff_prune_2cu(&handles[i], NV_MAX, NE_mem_1, NE_mem_2, &buff_hosts_prune[i]); + } + } +}; + +int opLouvainModularity::compute(unsigned int deviceID, + unsigned int cuID, + unsigned int channelID, + xrmContext* ctx, + xrmCuResource* resR, + std::string instanceName0, + clHandle* handles, + int kernelMode, + uint32_t numBuffers, + GLV* pglv_iter, + double opts_C_thresh, + // KMemorys_host* buff_host, + KMemorys_host_prune* buff_host_prune, + int* eachItrs, + double* currMod, + long* numClusters, + double* eachTimeInitBuff, + double* eachTimeReadBuff) { + uint32_t which = + channelID + cuID * dupNmLouvainModularity + deviceID * dupNmLouvainModularity * cuPerBoardLouvainModularity; +#ifdef PRINTINFO + printf( + "INFO: compute channelID=%d, cuID=%d dupNmLouvainModularity=%d deviceID=%d cuPerBoardLouvainModularity=%d " + "which=%d \n", + channelID, cuID, dupNmLouvainModularity, deviceID, cuPerBoardLouvainModularity, which); + printf(" kernelMode = %d\n", kernelMode); +#endif + + std::lock_guard lockMutex(louvainmodComputeMutex[which]); + + clHandle* hds = &handles[which]; +#ifdef PRINTINFO + std::cout << "DEBUG: " << __FUNCTION__ << " IDDevice=" << deviceID << " handle=" << &handles[which] << std::endl; +#endif + pglv_iter->times.deviceID[0] = deviceID; + pglv_iter->times.cuID[0] = cuID; + pglv_iter->times.channelID[0] = channelID; + pglv_iter->times.eachTimeE2E[0] = omp_get_wtime(); + std::vector ob_in; + std::vector ob_out; + std::vector > kernel_evt0(1); + std::vector > kernel_evt1(1); + kernel_evt0[0].resize(1); + kernel_evt1[0].resize(1); + std::vector events_write(1); + std::vector events_kernel(1); + std::vector events_read(1); + + cl::Device device = hds[0].device; + // const char* instanceName = instanceName0.c_str(); + // Creating Context and Command Queue for selected Device + cl::Context context = hds[0].context; + cl::CommandQueue q = hds[0].q; + std::string devName = device.getInfo(); +#ifdef PRINTINFO + printf("INFO: Found Device=%s\n", devName.c_str()); +#endif + cl::Kernel kernel_louvain = hds[0].kernel; + +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << " kernel=" << &kernel_louvain << " which=" << which << std::endl; +#endif + + bool isLargeEdge = pglv_iter->G->numEdges > (glb_MAXNV / 2); + + if (kernelMode == LOUVAINMOD_PRUNING_KERNEL) { +#ifdef PRINTINFO + std::cout << "INFO: inside flow LOUVAINMOD_PRUNING_KERNEL " << std::endl; +#endif + KMemorys_host_prune* buf_host_prune = &buff_host_prune[which]; +#ifdef PRINTINFO + std::cout << "INFO: buf_host_prune has been created" << std::endl; +#endif + + eachTimeInitBuff[0] = + PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(pglv_iter->numColors, pglv_iter->G, pglv_iter->M, + opts_C_thresh, currMod, pglv_iter->colors, buf_host_prune); +#ifdef PRINTINFO + std::cout << "INFO: PhaseLoop_UsingFPGA_Prep_Init_buff_host #prune# done" << std::endl; +#endif + PhaseLoop_UsingFPGA_1_KernelSetup_prune(isLargeEdge, kernel_louvain, ob_in, ob_out, hds); +#ifdef PRINTINFO + std::cout << "\twhich=" << which << " PhaseLoop_UsingFPGA_1_KernelSetup Device Available: " + << std::endl; // << device.getInfo() << std::endl; +#endif + // PhaseLoop_UsingFPGA_2_DataWriteTo (q, kernel_evt0, ob_in); + migrateMemObj(hds, 0, 1, ob_in, nullptr, &events_write[0]); + + // PhaseLoop_UsingFPGA_3_KernelRun (q, kernel_evt0, kernel_evt1, kernel_louvain); + int ret = cuExecute(hds, kernel_louvain, 1, &events_write, &events_kernel[0]); + + // PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); + migrateMemObj(hds, 1, 1, ob_out, &events_kernel, &events_read[0]); +#ifdef PRINTINFO + std::cout << "\twhich=" << which << " PhaseLoop_UsingFPGA_4_DataReadBack Device Available: " + << std::endl; // << device.getInfo() << std::endl; +#endif + // PhaseLoop_UsingFPGA_5_KernelFinish(q); + q.finish(); +#ifdef PRINTINFO + std::cout << "\twhich=" << which << " PhaseLoop_UsingFPGA_5_KernelFinish Device Available: " + << std::endl; // << device.getInfo() << std::endl; +#endif + eachTimeReadBuff[0] = PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune(pglv_iter->NV, buf_host_prune, eachItrs, + pglv_iter->C, eachItrs, currMod); + + cuRelease(ctx, resR); + + } else { +#ifdef PRINTINFO + std::cout << "INFO: inside flow 4 for renum+2cu opt version " << std::string(hds[0].resR->instanceName) + << std::endl; +#endif + KMemorys_host_prune* buf_host_prune = &buff_host_prune[which]; // +#ifdef PRINTINFO + std::cout << "INFO: buf_host_prune has been created" << std::endl; +#endif + + eachTimeInitBuff[0] = PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune_renumber_2cu( + pglv_iter->numColors, pglv_iter->NVl, pglv_iter->G, pglv_iter->M, opts_C_thresh, currMod, pglv_iter->colors, + buf_host_prune); +#ifdef PRINTINFO + std::cout << "INFO: PhaseLoop_UsingFPGA_Prep_Init_buff_host #prune# done" << std::endl; +#endif + PhaseLoop_UsingFPGA_1_KernelSetup_prune_2cu(isLargeEdge, kernel_louvain, ob_in, ob_out, hds); +#ifdef PRINTINFO + std::cout << "\tPhaseLoop_UsingFPGA_1_KernelSetup Device Available: " + << std::endl; // << device.getInfo() << std::endl; +#endif + // PhaseLoop_UsingFPGA_2_DataWriteTo (q, kernel_evt0, ob_in); + migrateMemObj(hds, 0, 1, ob_in, nullptr, &events_write[0]); + + // PhaseLoop_UsingFPGA_3_KernelRun (q, kernel_evt0, kernel_evt1, kernel_louvain); + int ret = cuExecute(hds, kernel_louvain, 1, &events_write, &events_kernel[0]); + + // PhaseLoop_UsingFPGA_4_DataReadBack(q, kernel_evt1, ob_out); + migrateMemObj(hds, 1, 1, ob_out, &events_kernel, &events_read[0]); +#ifdef PRINTINFO + std::cout << "\tPhaseLoop_UsingFPGA_4_DataReadBack Device Available: " + << std::endl; // << device.getInfo() << std::endl; +#endif + // PhaseLoop_UsingFPGA_5_KernelFinish(q); + q.finish(); +#ifdef PRINTINFO + std::cout << "\tPhaseLoop_UsingFPGA_5_KernelFinish Device Available: " + << std::endl; // << device.getInfo() << std::endl; +#endif + eachTimeReadBuff[0] = PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune_renumber( + pglv_iter->NV, buf_host_prune, eachItrs, pglv_iter->C, eachItrs, currMod, numClusters); + cuRelease(ctx, resR); + } + pglv_iter->times.eachTimeE2E[0] = omp_get_wtime() - pglv_iter->times.eachTimeE2E[0]; + return 0; +} + +double opLouvainModularity::PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune(int numColors, + graphNew* G, + long* M, + double opts_C_thresh, + double* currMod, + // Updated variables + int* colors, + KMemorys_host_prune* buff_host) { + long edgeNum; + double time1 = omp_get_wtime(); + assert(numColors < COLORS); + long vertexNum = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + long NE = G->numEdges; + long NEx2 = NE << 1; + long NE1 = NEx2 < (glb_MAXNV) ? NEx2 : (glb_MAXNV); // 256MB/sizeof(int/float)=64M + + long cnt_e = 0; + for (int i = 0; i < vertexNum + 1; i++) { + buff_host[0].offsets[i] = (int)vtxPtr[i]; + if (i != vertexNum) { + if (M[i] < 0) buff_host[0].offsets[i] = (int)(0x80000000 | (unsigned int)vtxPtr[i]); + } else + buff_host[0].offsets[i] = (int)(vtxPtr[i]); + } + edgeNum = buff_host[0].offsets[vertexNum]; + for (int i = 0; i < vertexNum + 1; i++) { + buff_host[0].offsets[i] = (int)vtxPtr[i]; + buff_host[0].offsetsdup[i] = buff_host[0].offsets[i]; // + if (i != vertexNum) { + if (M[i] < 0) buff_host[0].offsets[i] = (int)(0x80000000 | (unsigned int)vtxPtr[i]); + } else + buff_host[0].offsets[i] = (int)(vtxPtr[i]); + } + edgeNum = buff_host[0].offsets[vertexNum]; + + for (int i = 0; i < vertexNum; i++) { + int adj1 = vtxPtr[i]; + int adj2 = vtxPtr[i + 1]; + buff_host[0].flag[i] = 0; // + buff_host[0].flagUpdate[i] = 0; // + for (int j = adj1; j < adj2; j++) { + if (cnt_e < NE1) { + buff_host[0].indices[j] = (int)vtxInd[j].tail; + buff_host[0].indicesdup[j] = (int)vtxInd[j].tail; + buff_host[0].weights[j] = vtxInd[j].weight; + } else { + buff_host[0].indices2[j - NE1] = (int)vtxInd[j].tail; + buff_host[0].indicesdup2[j - NE1] = (int)vtxInd[j].tail; + buff_host[0].weights2[j - NE1] = vtxInd[j].weight; + } + cnt_e++; + } + } + for (int i = 0; i < vertexNum; i++) { + buff_host[0].colorAxi[i] = colors[i]; + } + + buff_host[0].config0[0] = vertexNum; + buff_host[0].config0[1] = numColors; + buff_host[0].config0[2] = 0; + buff_host[0].config0[3] = edgeNum; + buff_host[0].config0[4] = 0; // totItr= 0 + + buff_host[0].config1[0] = opts_C_thresh; + buff_host[0].config1[1] = currMod[0]; + time1 = omp_get_wtime() - time1; + // printf("maxv:%ld, NEx2:%ld, vertexNum: %ld, numColors:%d, edgeNum:%ld, opts_C_thresh:%f, currMod:%f\n", + // glb_MAXNV, NEx2, vertexNum, numColors, edgeNum, opts_C_thresh, currMod[0]); + return time1; +#ifdef PRINTINFO_LVPHASE + std::cout << "INFO: eachItrs" << buff_host[0].config0[2] << ", " + << "eachItr[0] = " << buff_host[0].config0[2] << ", " + << "currMod[0] = " << buff_host[0].config1[1] << std::endl; +#endif +} + +double opLouvainModularity::PhaseLoop_UsingFPGA_Prep_Init_buff_host_prune_renumber_2cu(int numColors, + long NVl, + graphNew* G, + long* M, + double opts_C_thresh, + double* currMod, + // Updated variables + int* colors, + KMemorys_host_prune* buff_host) { + long edgeNum; + double time1 = omp_get_wtime(); + assert(numColors < COLORS); + long vertexNum = G->numVertices; + long* vtxPtr = G->edgeListPtrs; + edge* vtxInd = G->edgeList; + long NE = G->numEdges; + long NEx2 = NE << 1; + long NE1 = NEx2 < (glb_MAXNV) ? NEx2 : (glb_MAXNV); // 256MB/sizeof(int/float)=64M + + long cnt_e = 0; + for (int i = 0; i < vertexNum + 1; i++) { + buff_host[0].offsets[i] = (int)vtxPtr[i]; + if (i != vertexNum) { + if (M[i] < 0) buff_host[0].offsets[i] = (int)(0x80000000 | (unsigned int)vtxPtr[i]); + } else + buff_host[0].offsets[i] = (int)(vtxPtr[i]); + } + edgeNum = buff_host[0].offsets[vertexNum]; + for (int i = 0; i < vertexNum + 1; i++) { + buff_host[0].offsets[i] = (int)vtxPtr[i]; + // buff_host[0].offsetsdup[i] = buff_host[0].offsets[i];// + if (i != vertexNum) { + if (M[i] < 0) buff_host[0].offsets[i] = (int)(0x80000000 | (unsigned int)vtxPtr[i]); + } else + buff_host[0].offsets[i] = (int)(vtxPtr[i]); + } + edgeNum = buff_host[0].offsets[vertexNum]; + + for (int i = 0; i < vertexNum; i++) { + int adj1 = vtxPtr[i]; + int adj2 = vtxPtr[i + 1]; + buff_host[0].flag[i] = 0; // + buff_host[0].flagUpdate[i] = 0; // + for (int j = adj1; j < adj2; j++) { + if (cnt_e < NE1) { + buff_host[0].indices[j] = (int)vtxInd[j].tail; + // buff_host[0].indicesdup[j] = (int)vtxInd[j].tail; + buff_host[0].weights[j] = vtxInd[j].weight; + } else { + buff_host[0].indices2[j - NE1] = (int)vtxInd[j].tail; + // buff_host[0].indicesdup2[j-NE1] = (int)vtxInd[j].tail; + buff_host[0].weights2[j - NE1] = vtxInd[j].weight; + } + cnt_e++; + } + } + for (int i = 0; i < vertexNum; i++) { + buff_host[0].colorAxi[i] = colors[i]; + } + + buff_host[0].config0[0] = vertexNum; + buff_host[0].config0[1] = numColors; + buff_host[0].config0[2] = 0; + buff_host[0].config0[3] = edgeNum; + buff_host[0].config0[4] = 0; // zyx renumber + buff_host[0].config0[5] = NVl; + + buff_host[0].config1[0] = opts_C_thresh; + buff_host[0].config1[1] = currMod[0]; + time1 = omp_get_wtime() - time1; + + // printf("INFO: glb_MAXNV:%ld, vertexNum: %ld, NE: %ld , edgeNum:%ld, NVl:%ld, buff_host[0].config0[4]=%ld \n", + // glb_MAXNV, vertexNum, NE, edgeNum,NVl,buff_host[0].config0[4]); + // std::cout << "INFO: numColors" < 0) { + mext_in[3 + 18] = {(unsigned int)(1) | XCL_MEM_TOPOLOGY, buff_host_prune[0].indices2, 0}; + mext_in[4 + 18] = {(unsigned int)(3) | XCL_MEM_TOPOLOGY, buff_host_prune[0].weights2, 0}; + } + mext_in[5] = {(unsigned int)(6) | XCL_MEM_TOPOLOGY, buff_host_prune[0].colorAxi, 0}; + mext_in[6] = {(unsigned int)(8) | XCL_MEM_TOPOLOGY, buff_host_prune[0].colorInx, 0}; + mext_in[7] = {(unsigned int)(10) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidPrev, 0}; + mext_in[8] = {(unsigned int)(12) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidSizePrev, 0}; + mext_in[9] = {(unsigned int)(14) | XCL_MEM_TOPOLOGY, buff_host_prune[0].totPrev, 0}; + mext_in[10] = {(unsigned int)(16) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidCurr, 0}; + mext_in[11] = {(unsigned int)(18) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidSizeCurr, 0}; + mext_in[12] = {(unsigned int)(20) | XCL_MEM_TOPOLOGY, buff_host_prune[0].totCurr, 0}; + mext_in[13] = {(unsigned int)(22) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidSizeUpdate, 0}; + mext_in[14] = {(unsigned int)(24) | XCL_MEM_TOPOLOGY, buff_host_prune[0].totUpdate, 0}; + mext_in[15] = {(unsigned int)(26) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cWeight, 0}; + + mext_in[16] = {(unsigned int)(27) | XCL_MEM_TOPOLOGY, buff_host_prune[0].offsetsdup, 0}; + mext_in[17] = {(unsigned int)(28) | XCL_MEM_TOPOLOGY, buff_host_prune[0].indicesdup, 0}; //| (unsigned int)(29) + mext_in[20] = {(unsigned int)(29) | XCL_MEM_TOPOLOGY, buff_host_prune[0].indicesdup2, 0}; + + mext_in[18] = {(unsigned int)(7) | XCL_MEM_TOPOLOGY, buff_host_prune[0].flag, 0}; + mext_in[19] = {(unsigned int)(9) | XCL_MEM_TOPOLOGY, buff_host_prune[0].flagUpdate, 0}; + + int flag_RW = CL_MEM_EXT_PTR_XILINX | CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE; + int flag_RD = CL_MEM_EXT_PTR_XILINX | CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY; + + hds[0].buffer[0] = cl::Buffer(hds[0].context, flag_RW, sizeof(int64_t) * (6), &mext_in[0]); + hds[0].buffer[1] = cl::Buffer(hds[0].context, flag_RW, sizeof(DWEIGHT) * (4), &mext_in[1]); + hds[0].buffer[2] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * (NV + 1), &mext_in[2]); + hds[0].buffer[3] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_1, &mext_in[3]); + hds[0].buffer[4] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_1, &mext_in[4]); + hds[0].buffer[5] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * (NV), &mext_in[5]); + hds[0].buffer[6] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[6]); + hds[0].buffer[7] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[7]); + hds[0].buffer[8] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[8]); + hds[0].buffer[9] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[9]); + hds[0].buffer[10] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[10]); + hds[0].buffer[11] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[11]); + hds[0].buffer[12] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[12]); + hds[0].buffer[13] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[13]); + hds[0].buffer[14] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[14]); + hds[0].buffer[15] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[15]); + hds[0].buffer[16] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * (NV + 1), &mext_in[16]); // offset + hds[0].buffer[17] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * (NE_mem_1), &mext_in[17]); + hds[0].buffer[18] = cl::Buffer(hds[0].context, flag_RW, sizeof(uint8_t) * (NV), &mext_in[18]); + hds[0].buffer[19] = cl::Buffer(hds[0].context, flag_RW, sizeof(uint8_t) * (NV), &mext_in[19]); + + if (NE_mem_2 > 0) { +#ifndef NDEBUG + std::cout << "INFO: NE_mem_2 = " << NE_mem_2 << std::endl; +#endif + hds[0].buffer[20] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_2, &mext_in[20]); + hds[0].buffer[21] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_2, &mext_in[21]); + hds[0].buffer[22] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_2, &mext_in[22]); + } +#ifndef NDEBUG + std::cout << "INFO: init buffer done! " << std::endl; +#endif +} + +int opLouvainModularity::cuExecute( + clHandle* hds, cl::Kernel& kernel0, unsigned int num_runs, std::vector* evIn, cl::Event* evOut) + +{ + for (int i = 0; i < num_runs; ++i) { + hds[0].q.enqueueTask(kernel0, evIn, evOut); + } + return 0; +} + +void opLouvainModularity::PhaseLoop_UsingFPGA_1_KernelSetup_prune(bool isLargeEdge, + cl::Kernel& kernel_louvain, + std::vector& ob_in, + std::vector& ob_out, + // KMemorys_clBuff_prune &buff_cl + clHandle* hds) { + // Data transfer from host buffer to device buffer + ob_in.push_back(hds[0].buffer[0]); + ob_in.push_back(hds[0].buffer[1]); + ob_in.push_back(hds[0].buffer[2]); + ob_in.push_back(hds[0].buffer[3]); + if (isLargeEdge) ob_in.push_back(hds[0].buffer[21]); + ob_in.push_back(hds[0].buffer[4]); + if (isLargeEdge) ob_in.push_back(hds[0].buffer[22]); + ob_in.push_back(hds[0].buffer[5]); + ob_in.push_back(hds[0].buffer[6]); + ob_in.push_back(hds[0].buffer[8]); + ob_in.push_back(hds[0].buffer[9]); + ob_in.push_back(hds[0].buffer[10]); + ob_in.push_back(hds[0].buffer[11]); + ob_in.push_back(hds[0].buffer[12]); + ob_in.push_back(hds[0].buffer[13]); + ob_in.push_back(hds[0].buffer[14]); + ob_in.push_back(hds[0].buffer[15]); + ob_out.push_back(hds[0].buffer[0]); + ob_out.push_back(hds[0].buffer[1]); + ob_out.push_back(hds[0].buffer[7]); + ob_in.push_back(hds[0].buffer[16]); + ob_in.push_back(hds[0].buffer[17]); + ob_in.push_back(hds[0].buffer[18]); + ob_in.push_back(hds[0].buffer[19]); + if (isLargeEdge) ob_in.push_back(hds[0].buffer[20]); + + kernel_louvain.setArg(0, hds[0].buffer[0]); // config0 + kernel_louvain.setArg(1, hds[0].buffer[1]); // config1 + kernel_louvain.setArg(2, hds[0].buffer[2]); // offsets + kernel_louvain.setArg(3, hds[0].buffer[3]); // indices + kernel_louvain.setArg(4, hds[0].buffer[4]); // weights + kernel_louvain.setArg(5, hds[0].buffer[5]); // colorAxi + kernel_louvain.setArg(6, hds[0].buffer[6]); // colorInx + kernel_louvain.setArg(7, hds[0].buffer[7]); // cidPrev + kernel_louvain.setArg(8, hds[0].buffer[8]); // cidSizePrev + kernel_louvain.setArg(9, hds[0].buffer[9]); // totPrev + kernel_louvain.setArg(10, hds[0].buffer[10]); // cidCurr + kernel_louvain.setArg(11, hds[0].buffer[11]); // cidSizeCurr + kernel_louvain.setArg(12, hds[0].buffer[12]); // totCurr + kernel_louvain.setArg(13, hds[0].buffer[13]); // cUpdate + kernel_louvain.setArg(14, hds[0].buffer[14]); // totCurr + kernel_louvain.setArg(15, hds[0].buffer[15]); // cWeight + kernel_louvain.setArg(16, hds[0].buffer[16]); // offsets + kernel_louvain.setArg(17, hds[0].buffer[17]); // indices + kernel_louvain.setArg(18, hds[0].buffer[18]); // flag + kernel_louvain.setArg(19, hds[0].buffer[19]); // db_flagUpdate +#ifdef PRINTINFO + std::cout << "INFO: Finish kernel setup" << std::endl; +#endif +} + +void opLouvainModularity::UsingFPGA_MapHostClBuff_prune_2cu( + clHandle* hds, long NV, long NE_mem_1, long NE_mem_2, KMemorys_host_prune* buff_host_prune) { + if (std::string(hds[0].resR->instanceName) == "kernel_louvain_0") { +#ifdef PRINTINFO + std::cout << "INFO: start MapHostClBuff kernel_louvain_0" << std::endl; +#endif + std::vector mext_in(NUM_PORT_KERNEL + 7); + buff_host_prune[0].config0 = aligned_alloc(6); + buff_host_prune[0].config1 = aligned_alloc(4); + buff_host_prune[0].offsets = aligned_alloc(NV + 1); + buff_host_prune[0].indices = aligned_alloc(NE_mem_1); + // + // + buff_host_prune[0].weights = aligned_alloc(NE_mem_1); + buff_host_prune[0].flag = aligned_alloc(NV); + buff_host_prune[0].flagUpdate = aligned_alloc(NV); + if (NE_mem_2 > 0) { + buff_host_prune[0].indices2 = aligned_alloc(NE_mem_2); + // + } + if (NE_mem_2 > 0) { + buff_host_prune[0].weights2 = aligned_alloc(NE_mem_2); + } + buff_host_prune[0].cidPrev = aligned_alloc(NV); + buff_host_prune[0].cidCurr = aligned_alloc(NV); + buff_host_prune[0].cidSizePrev = aligned_alloc(NV); + buff_host_prune[0].totPrev = aligned_alloc(NV); + buff_host_prune[0].cidSizeCurr = aligned_alloc(NV); + buff_host_prune[0].totCurr = aligned_alloc(NV); + buff_host_prune[0].cidSizeUpdate = aligned_alloc(NV); + buff_host_prune[0].totUpdate = aligned_alloc(NV); + buff_host_prune[0].cWeight = aligned_alloc(NV); + buff_host_prune[0].colorAxi = aligned_alloc(NV); + buff_host_prune[0].colorInx = aligned_alloc(NV); + +// ap_uint* axi_offsets = reinterpret_cast*>(buff_host_prune[0].offsets); +// ap_uint* axi_indices = reinterpret_cast*>(buff_host_prune[0].indices); +// // +// // +// ap_uint* axi_weights = reinterpret_cast*>(buff_host_prune[0].weights); +// ap_uint* axi_indices2; +// // +// ap_uint* axi_weights2; +// if(NE_mem_2>0){ +// axi_indices2 = reinterpret_cast*>(buff_host_prune[0].indices2); +// // +// axi_weights2 = reinterpret_cast*>(buff_host_prune[0].weights2); +// } +// ap_uint* axi_cidPrev = reinterpret_cast*>(buff_host_prune[0].cidPrev); +// ap_uint* axi_cidCurr = reinterpret_cast*>(buff_host_prune[0].cidCurr); +// ap_uint* axi_cidSizePrev = reinterpret_cast*>(buff_host_prune[0].cidSizePrev); +// ap_uint* axi_totPrev = reinterpret_cast*>(buff_host_prune[0].totPrev); +// ap_uint* axi_cidSizeCurr = reinterpret_cast*>(buff_host_prune[0].cidSizeCurr); +// ap_uint* axi_totCurr = reinterpret_cast*>(buff_host_prune[0].totCurr); +// ap_uint* axi_cidSizeUpdate = reinterpret_cast*>(buff_host_prune[0].cidSizeUpdate); +// ap_uint* axi_totUpdate = reinterpret_cast*>(buff_host_prune[0].totUpdate); +// ap_uint* axi_cWeight = reinterpret_cast*>(buff_host_prune[0].cWeight); +// ap_uint* axi_colorAxi = reinterpret_cast*>(buff_host_prune[0].colorAxi); +// ap_uint* axi_colorInx = reinterpret_cast*>(buff_host_prune[0].colorInx); +// uint8_t* axi_flag = reinterpret_cast(buff_host_prune[0].flag); +// uint8_t* axi_flagUpdate = reinterpret_cast(buff_host_prune[0].flagUpdate); +#ifdef PRINTINFO + std::cout << "INFO: start mext_in " << std::endl; +#endif + // DDR Settings + mext_in[0] = {(unsigned int)(4) | XCL_MEM_TOPOLOGY, buff_host_prune[0].config0, 0}; + mext_in[1] = {(unsigned int)(4) | XCL_MEM_TOPOLOGY, buff_host_prune[0].config1, 0}; + mext_in[2] = {(unsigned int)(4) | XCL_MEM_TOPOLOGY, buff_host_prune[0].offsets, 0}; + mext_in[3] = {(unsigned int)(0) | XCL_MEM_TOPOLOGY, buff_host_prune[0].indices, 0}; + mext_in[4] = {(unsigned int)(2) | XCL_MEM_TOPOLOGY, buff_host_prune[0].weights, 0}; + if (NE_mem_2 > 0) { + mext_in[3 + 18] = {(unsigned int)(1) | XCL_MEM_TOPOLOGY, buff_host_prune[0].indices2, 0}; + mext_in[4 + 18] = {(unsigned int)(3) | XCL_MEM_TOPOLOGY, buff_host_prune[0].weights2, 0}; + } + mext_in[5] = {(unsigned int)(5) | XCL_MEM_TOPOLOGY, buff_host_prune[0].colorAxi, 0}; + mext_in[6] = {(unsigned int)(6) | XCL_MEM_TOPOLOGY, buff_host_prune[0].colorInx, 0}; + mext_in[7] = {(unsigned int)(7) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidPrev, 0}; + mext_in[8] = {(unsigned int)(8) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidSizePrev, 0}; + mext_in[9] = {(unsigned int)(9) | XCL_MEM_TOPOLOGY, buff_host_prune[0].totPrev, 0}; + mext_in[10] = {(unsigned int)(10) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidCurr, 0}; + mext_in[11] = {(unsigned int)(11) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidSizeCurr, 0}; + mext_in[12] = {(unsigned int)(12) | XCL_MEM_TOPOLOGY, buff_host_prune[0].totCurr, 0}; + mext_in[13] = {(unsigned int)(13) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidSizeUpdate, 0}; + mext_in[14] = {(unsigned int)(14) | XCL_MEM_TOPOLOGY, buff_host_prune[0].totUpdate, 0}; + mext_in[15] = {(unsigned int)(15) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cWeight, 0}; + + mext_in[18] = {(unsigned int)(5) | XCL_MEM_TOPOLOGY, buff_host_prune[0].flag, 0}; + mext_in[19] = {(unsigned int)(5) | XCL_MEM_TOPOLOGY, buff_host_prune[0].flagUpdate, 0}; + int flag_RW = CL_MEM_EXT_PTR_XILINX | CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE; + int flag_RD = CL_MEM_EXT_PTR_XILINX | CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY; + + hds[0].buffer[0] = cl::Buffer(hds[0].context, flag_RW, sizeof(int64_t) * (6), &mext_in[0]); + hds[0].buffer[1] = cl::Buffer(hds[0].context, flag_RW, sizeof(DWEIGHT) * (4), &mext_in[1]); + hds[0].buffer[2] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * (NV + 1), &mext_in[2]); + hds[0].buffer[3] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_1, &mext_in[3]); + hds[0].buffer[4] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_1, &mext_in[4]); + hds[0].buffer[5] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * (NV), &mext_in[5]); + hds[0].buffer[6] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[6]); + hds[0].buffer[7] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[7]); + hds[0].buffer[8] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[8]); + hds[0].buffer[9] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[9]); + hds[0].buffer[10] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[10]); + hds[0].buffer[11] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[11]); + hds[0].buffer[12] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[12]); + hds[0].buffer[13] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[13]); + hds[0].buffer[14] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[14]); + hds[0].buffer[15] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[15]); + ////offset + // + hds[0].buffer[18] = cl::Buffer(hds[0].context, flag_RW, sizeof(uint8_t) * (NV), &mext_in[18]); + std::cout << "INFO: init buffer " << std::endl; + hds[0].buffer[19] = cl::Buffer(hds[0].context, flag_RW, sizeof(uint8_t) * (NV), &mext_in[19]); + std::cout << "INFO: init buffer 1 " << std::endl; + if (NE_mem_2 > 0) { +#ifdef PRINTINFO + std::cout << "INFO: NE_mem_2 = " << NE_mem_2 << std::endl; +#endif + // + hds[0].buffer[21] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_2, &mext_in[21]); + hds[0].buffer[22] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_2, &mext_in[22]); + } +#ifdef PRINTINFO + std::cout << "INFO: init buffer done! " << std::endl; +#endif + + } else { +#ifdef PRINTINFO + std::cout << "INFO: start MapHostClBuff kernel_louvain_1" << std::endl; +#endif + std::vector mext_in(NUM_PORT_KERNEL + 7); + buff_host_prune[0].config0 = aligned_alloc(6); + buff_host_prune[0].config1 = aligned_alloc(4); + buff_host_prune[0].offsets = aligned_alloc(NV + 1); + buff_host_prune[0].indices = aligned_alloc(NE_mem_1); + // + // + buff_host_prune[0].weights = aligned_alloc(NE_mem_1); + buff_host_prune[0].flag = aligned_alloc(NV); + buff_host_prune[0].flagUpdate = aligned_alloc(NV); + if (NE_mem_2 > 0) { + buff_host_prune[0].indices2 = aligned_alloc(NE_mem_2); + // + } + if (NE_mem_2 > 0) { + buff_host_prune[0].weights2 = aligned_alloc(NE_mem_2); + } + buff_host_prune[0].cidPrev = aligned_alloc(NV); + buff_host_prune[0].cidCurr = aligned_alloc(NV); + buff_host_prune[0].cidSizePrev = aligned_alloc(NV); + buff_host_prune[0].totPrev = aligned_alloc(NV); + buff_host_prune[0].cidSizeCurr = aligned_alloc(NV); + buff_host_prune[0].totCurr = aligned_alloc(NV); + buff_host_prune[0].cidSizeUpdate = aligned_alloc(NV); + buff_host_prune[0].totUpdate = aligned_alloc(NV); + buff_host_prune[0].cWeight = aligned_alloc(NV); + buff_host_prune[0].colorAxi = aligned_alloc(NV); + buff_host_prune[0].colorInx = aligned_alloc(NV); + +// ap_uint* axi_offsets = reinterpret_cast*>(buff_host_prune[0].offsets); +// ap_uint* axi_indices = reinterpret_cast*>(buff_host_prune[0].indices); +// // +// // +// ap_uint* axi_weights = reinterpret_cast*>(buff_host_prune[0].weights); +// ap_uint* axi_indices2; +// // +// ap_uint* axi_weights2; +// if(NE_mem_2>0){ +// axi_indices2 = reinterpret_cast*>(buff_host_prune[0].indices2); +// // +// axi_weights2 = reinterpret_cast*>(buff_host_prune[0].weights2); +// } +// ap_uint* axi_cidPrev = reinterpret_cast*>(buff_host_prune[0].cidPrev); +// ap_uint* axi_cidCurr = reinterpret_cast*>(buff_host_prune[0].cidCurr); +// ap_uint* axi_cidSizePrev = reinterpret_cast*>(buff_host_prune[0].cidSizePrev); +// ap_uint* axi_totPrev = reinterpret_cast*>(buff_host_prune[0].totPrev); +// ap_uint* axi_cidSizeCurr = reinterpret_cast*>(buff_host_prune[0].cidSizeCurr); +// ap_uint* axi_totCurr = reinterpret_cast*>(buff_host_prune[0].totCurr); +// ap_uint* axi_cidSizeUpdate = reinterpret_cast*>(buff_host_prune[0].cidSizeUpdate); +// ap_uint* axi_totUpdate = reinterpret_cast*>(buff_host_prune[0].totUpdate); +// ap_uint* axi_cWeight = reinterpret_cast*>(buff_host_prune[0].cWeight); +// ap_uint* axi_colorAxi = reinterpret_cast*>(buff_host_prune[0].colorAxi); +// ap_uint* axi_colorInx = reinterpret_cast*>(buff_host_prune[0].colorInx); +// uint8_t* axi_flag = reinterpret_cast(buff_host_prune[0].flag); +// uint8_t* axi_flagUpdate = reinterpret_cast(buff_host_prune[0].flagUpdate); +#ifdef PRINTINFO + std::cout << "INFO: start mext_in " << std::endl; +#endif + // DDR Settings + mext_in[0] = {(unsigned int)(20) | XCL_MEM_TOPOLOGY, buff_host_prune[0].config0, 0}; + mext_in[1] = {(unsigned int)(20) | XCL_MEM_TOPOLOGY, buff_host_prune[0].config1, 0}; + mext_in[2] = {(unsigned int)(20) | XCL_MEM_TOPOLOGY, buff_host_prune[0].offsets, 0}; + mext_in[3] = {(unsigned int)(16) | XCL_MEM_TOPOLOGY, buff_host_prune[0].indices, 0}; + mext_in[4] = {(unsigned int)(18) | XCL_MEM_TOPOLOGY, buff_host_prune[0].weights, 0}; + if (NE_mem_2 > 0) { + mext_in[3 + 18] = {(unsigned int)(17) | XCL_MEM_TOPOLOGY, buff_host_prune[0].indices2, 0}; + mext_in[4 + 18] = {(unsigned int)(19) | XCL_MEM_TOPOLOGY, buff_host_prune[0].weights2, 0}; + } + mext_in[5] = {(unsigned int)(21) | XCL_MEM_TOPOLOGY, buff_host_prune[0].colorAxi, 0}; + mext_in[6] = {(unsigned int)(22) | XCL_MEM_TOPOLOGY, buff_host_prune[0].colorInx, 0}; + mext_in[7] = {(unsigned int)(23) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidPrev, 0}; + mext_in[8] = {(unsigned int)(24) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidSizePrev, 0}; + mext_in[9] = {(unsigned int)(25) | XCL_MEM_TOPOLOGY, buff_host_prune[0].totPrev, 0}; + mext_in[10] = {(unsigned int)(26) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidCurr, 0}; + mext_in[11] = {(unsigned int)(27) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidSizeCurr, 0}; + mext_in[12] = {(unsigned int)(28) | XCL_MEM_TOPOLOGY, buff_host_prune[0].totCurr, 0}; + mext_in[13] = {(unsigned int)(29) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cidSizeUpdate, 0}; + mext_in[14] = {(unsigned int)(30) | XCL_MEM_TOPOLOGY, buff_host_prune[0].totUpdate, 0}; + mext_in[15] = {(unsigned int)(31) | XCL_MEM_TOPOLOGY, buff_host_prune[0].cWeight, 0}; + + mext_in[18] = {(unsigned int)(21) | XCL_MEM_TOPOLOGY, buff_host_prune[0].flag, 0}; + mext_in[19] = {(unsigned int)(21) | XCL_MEM_TOPOLOGY, buff_host_prune[0].flagUpdate, 0}; + + int flag_RW = CL_MEM_EXT_PTR_XILINX | CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE; + int flag_RD = CL_MEM_EXT_PTR_XILINX | CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY; + + hds[0].buffer[0] = cl::Buffer(hds[0].context, flag_RW, sizeof(int64_t) * (6), &mext_in[0]); + hds[0].buffer[1] = cl::Buffer(hds[0].context, flag_RW, sizeof(DWEIGHT) * (4), &mext_in[1]); + hds[0].buffer[2] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * (NV + 1), &mext_in[2]); + hds[0].buffer[3] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_1, &mext_in[3]); + hds[0].buffer[4] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_1, &mext_in[4]); + hds[0].buffer[5] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * (NV), &mext_in[5]); + hds[0].buffer[6] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[6]); + hds[0].buffer[7] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[7]); + hds[0].buffer[8] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[8]); + hds[0].buffer[9] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[9]); + hds[0].buffer[10] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[10]); + hds[0].buffer[11] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[11]); + hds[0].buffer[12] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[12]); + hds[0].buffer[13] = cl::Buffer(hds[0].context, flag_RW, sizeof(int) * (NV), &mext_in[13]); + hds[0].buffer[14] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[14]); + hds[0].buffer[15] = cl::Buffer(hds[0].context, flag_RW, sizeof(float) * (NV), &mext_in[15]); + ////offset + // + hds[0].buffer[18] = cl::Buffer(hds[0].context, flag_RW, sizeof(uint8_t) * (NV), &mext_in[18]); + hds[0].buffer[19] = cl::Buffer(hds[0].context, flag_RW, sizeof(uint8_t) * (NV), &mext_in[19]); + if (NE_mem_2 > 0) { +#ifdef PRINTINFO + std::cout << "INFO: NE_mem_2 = " << NE_mem_2 << std::endl; +#endif + hds[0].buffer[21] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_2, &mext_in[21]); + hds[0].buffer[22] = cl::Buffer(hds[0].context, flag_RD, sizeof(int) * NE_mem_2, &mext_in[22]); + } +#ifdef PRINTINFO + std::cout << "INFO: init buffer done! " << std::endl; +#endif + } +} + +void opLouvainModularity::PhaseLoop_UsingFPGA_1_KernelSetup_prune_2cu(bool isLargeEdge, + cl::Kernel& kernel_run, + std::vector& ob_in, + std::vector& ob_out, + clHandle* hds) { +#ifdef PRINTINFO + std::cout << "INFO: start 2cu kernel setup " << std::endl; +#endif + + cl::Kernel kernel_louvain = hds[0].kernel; + + // Data transfer from host buffer to device buffer + ob_in.push_back(hds[0].buffer[0]); + ob_in.push_back(hds[0].buffer[1]); + ob_in.push_back(hds[0].buffer[2]); + ob_in.push_back(hds[0].buffer[3]); + if (isLargeEdge) ob_in.push_back(hds[0].buffer[21]); + ob_in.push_back(hds[0].buffer[4]); + if (isLargeEdge) ob_in.push_back(hds[0].buffer[22]); + ob_in.push_back(hds[0].buffer[5]); // axi_colorAxi + ob_in.push_back(hds[0].buffer[6]); // axi_cidPrev + ob_in.push_back(hds[0].buffer[7]); + ob_in.push_back(hds[0].buffer[8]); + ob_in.push_back(hds[0].buffer[9]); + ob_in.push_back(hds[0].buffer[10]); + ob_in.push_back(hds[0].buffer[11]); + ob_in.push_back(hds[0].buffer[12]); + ob_in.push_back(hds[0].buffer[13]); + ob_in.push_back(hds[0].buffer[14]); + ob_in.push_back(hds[0].buffer[15]); + // ob_in.push_back(hds[0].buffer[16]); + // ob_in.push_back(hds[0].buffer[17]); + ob_in.push_back(hds[0].buffer[18]); + ob_in.push_back(hds[0].buffer[19]); + + ob_out.push_back(hds[0].buffer[0]); + ob_out.push_back(hds[0].buffer[1]); + ob_out.push_back(hds[0].buffer[7]); + + kernel_louvain.setArg(0, hds[0].buffer[0]); // config0 + kernel_louvain.setArg(1, hds[0].buffer[1]); // config1 + kernel_louvain.setArg(2, hds[0].buffer[2]); // offsets + kernel_louvain.setArg(3, hds[0].buffer[3]); // indices + kernel_louvain.setArg(4, hds[0].buffer[4]); // weights + kernel_louvain.setArg(5, hds[0].buffer[5]); // colorAxi + kernel_louvain.setArg(6, hds[0].buffer[6]); // colorInx + kernel_louvain.setArg(7, hds[0].buffer[7]); // cidPrev + kernel_louvain.setArg(8, hds[0].buffer[8]); // cidSizePrev + kernel_louvain.setArg(9, hds[0].buffer[9]); // totPrev + kernel_louvain.setArg(10, hds[0].buffer[10]); // cidCurr + kernel_louvain.setArg(11, hds[0].buffer[11]); // cidSizeCurr + kernel_louvain.setArg(12, hds[0].buffer[12]); // totCurr + kernel_louvain.setArg(13, hds[0].buffer[13]); // cUpdate + kernel_louvain.setArg(14, hds[0].buffer[14]); // totCurr + kernel_louvain.setArg(15, hds[0].buffer[15]); // cWeight + kernel_louvain.setArg(16, hds[0].buffer[2]); // offsets + kernel_louvain.setArg(17, hds[0].buffer[3]); // indices + kernel_louvain.setArg(18, hds[0].buffer[18]); // flag + kernel_louvain.setArg(19, hds[0].buffer[19]); // db_flagUpdate +#ifdef PRINTINFO + std::cout << "INFO: Finish kernel setup" << std::endl; +#endif +} + +double opLouvainModularity::PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune(long vertexNum, + KMemorys_host_prune* buff_host, + int* eachItrs, + // output + long* C, + int* eachItr, + double* currMod) { + double time1 = omp_get_wtime(); + // updating + eachItrs[0] = buff_host[0].config0[2]; + eachItr[0] = buff_host[0].config0[2]; + currMod[0] = buff_host[0].config1[1]; + + for (int i = 0; i < vertexNum; i++) { + C[i] = (long)buff_host[0].cidPrev[i]; + } +#ifdef PRINTINFO_LVPHASE + std::cout << " read INFO: eachItrs" << eachItrs[0] << ", " + << "eachItr[0] = " << eachItr[0] << ", " + << "currMod[0] = " << currMod[0] << std::endl; +#endif + time1 = omp_get_wtime() - time1; + return time1; +} + +double opLouvainModularity::PhaseLoop_UsingFPGA_Prep_Read_buff_host_prune_renumber(long vertexNum, + KMemorys_host_prune* buff_host, + int* eachItrs, + // output + long* C, + int* eachItr, + double* currMod, + long* numClusters) { + double time1 = omp_get_wtime(); + // updating + eachItrs[0] = buff_host[0].config0[2]; + eachItr[0] = buff_host[0].config0[2]; + currMod[0] = buff_host[0].config1[1]; + numClusters[0] = buff_host[0].config0[4]; + + for (int i = 0; i < vertexNum; i++) { + C[i] = (long)buff_host[0].cidPrev[i]; + } +#ifdef PRINTINFO_LVPHASE + std::cout << " read INFO: eachItrs" << eachItrs[0] << ", " + << "eachItr[0] = " << eachItr[0] << ", " + << "currMod[0] = " << currMod[0] << std::endl; +#endif + time1 = omp_get_wtime() - time1; + return time1; +} + +void opLouvainModularity::postProcess(){}; + +void opLouvainModularity::PhaseLoop_UpdatingC_org(int phase, long NV, long NV_G, long* C, long* C_orig) { + if (phase == 1) { +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + C_orig[i] = C[i]; // After the first phase + } + } else { +#pragma omp parallel for + for (long i = 0; i < NV; i++) { + assert(C_orig[i] < NV_G); + if (C_orig[i] >= 0) C_orig[i] = C[C_orig[i]]; // Each cluster in a previous phase becomes a vertex + } + } +} + +long* opLouvainModularity::CreateM(long NV_new, long NV_orig, long* C_orig, long* M_orig) { + long* M = (long*)malloc(NV_new * sizeof(long)); + assert(M); + memset(M, 0, NV_new * sizeof(long)); + for (int i = 0; i < NV_orig; i++) { + if (M_orig[i] < 0) M[C_orig[i]] = M_orig[i]; + } + return M; +} + +double opLouvainModularity::PhaseLoop_CommPostProcessing_par(GLV* pglv_orig, + GLV* pglv_iter, + int numThreads, + double opts_threshold, + bool opts_coloring, + // modified: + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase, + double& time_renum, + double& time_C, + double& time_M, + double& time_buid, + double& time_set) { + double time1 = 0; + time1 = omp_get_wtime(); + time_renum = time1; + graphNew* Gnew; + numClusters = renumberClustersContiguously_ghost(pglv_iter->C, pglv_iter->G->numVertices, pglv_iter->NVl); +#ifdef PRINTINFO_LVPHASE + printf("Number of unique clusters: %ld\n", numClusters); +#endif + time_renum = omp_get_wtime() - time_renum; + + time_C = omp_get_wtime(); + PhaseLoop_UpdatingC_org(phase, pglv_orig->NV, pglv_iter->NV, pglv_iter->C, pglv_orig->C); + time_C = omp_get_wtime() - time_C; + + time_M = omp_get_wtime(); + long* M_new = CreateM(numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M); + time_M = omp_get_wtime() - time_M; + + Gnew = (graphNew*)malloc(sizeof(graphNew)); + assert(Gnew != 0); + double tmpTime = buildNextLevelGraphOpt(pglv_iter->G, Gnew, pglv_iter->C, numClusters, 8); + totTimeBuildingPhase += tmpTime; + time_buid = tmpTime; + + time_set = omp_get_wtime(); + pglv_iter->SetByOhterG(Gnew, M_new); + time_set = omp_get_wtime() - time_set; + + time1 = omp_get_wtime() - time1; + + return time1; +} +double opLouvainModularity::PhaseLoop_CommPostProcessing_par_renumber(GLV* pglv_orig, + GLV* pglv_iter, + int numThreads, + double opts_threshold, + bool opts_coloring, + // modified: + bool& nonColor, + int& phase, + int& totItr, + long& numClusters, + double& totTimeBuildingPhase, + double& time_renum, + double& time_C, + double& time_M, + double& time_buid, + double& time_set) { + double time1 = 0; + time1 = omp_get_wtime(); + time_renum = time1; + graphNew* Gnew; +// numClusters = renumberClustersContiguously_ghost(pglv_iter->C, pglv_iter->G->numVertices, pglv_iter->NVl); +#ifdef PRINTINFO_LVPHASE + printf("Number of unique clusters renumber: %ld\n", numClusters); +#endif + time_renum = omp_get_wtime() - time_renum; + + time_C = omp_get_wtime(); + PhaseLoop_UpdatingC_org(phase, pglv_orig->NV, pglv_iter->NV, pglv_iter->C, pglv_orig->C); + time_C = omp_get_wtime() - time_C; + + time_M = omp_get_wtime(); + long* M_new = CreateM(numClusters, pglv_orig->NV, pglv_orig->C, pglv_orig->M); + time_M = omp_get_wtime() - time_M; + + Gnew = (graphNew*)malloc(sizeof(graphNew)); + assert(Gnew != 0); + double tmpTime = buildNextLevelGraphOpt(pglv_iter->G, Gnew, pglv_iter->C, numClusters, 8); + totTimeBuildingPhase += tmpTime; + time_buid = tmpTime; + + time_set = omp_get_wtime(); + pglv_iter->SetByOhterG(Gnew, M_new); + time_set = omp_get_wtime() - time_set; + + time1 = omp_get_wtime() - time1; + + return time1; +} + +void opLouvainModularity::demo_par_core( + int id_dev, int kernelMode, GLV* pglv_orig, GLV* pglv_iter, LouvainPara* para_lv) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << " id_dev=" << id_dev << std::endl; +#endif + bool opts_coloring = para_lv->opts_coloring; + long opts_minGraphSize = para_lv->opts_minGraphSize; + double opts_threshold = para_lv->opts_threshold; + double opts_C_thresh = para_lv->opts_C_thresh; + int numThreads = para_lv->numThreads; + int max_num_level = para_lv->max_num_level; + int max_num_iter = para_lv->max_num_iter; + pglv_orig->times.totTimeAll = omp_get_wtime(); + + pglv_orig->times.phase = 1; // Total phase counter + pglv_orig->times.totItr = 0; // Total iteration counter + + pglv_orig->times.totTimeInitBuff = 0; + pglv_orig->times.totTimeReadBuff = 0; + pglv_orig->times.totTimeReGraph = 0; + pglv_orig->times.totTimeE2E_2 = 0; + pglv_orig->times.totTimeE2E = 0; + + pglv_orig->times.totTimeBuildingPhase = 0; + pglv_orig->times.totTimeClustering = 0; + pglv_orig->times.totTimeColoring = 0; + pglv_orig->times.totTimeFeature = 0; + + pglv_orig->times.timePrePre_dev = 0; + pglv_orig->times.timePrePre_xclbin = 0; + pglv_orig->times.timePrePre_buff = 0; + pglv_orig->times.timePrePre = omp_get_wtime(); + // double time2 = omp_get_wtime(); + long NV_orig = pglv_orig->G->numVertices; + long NE_orig = pglv_orig->G->numEdges; + long numClusters; + + assert(NV_orig < glb_MAXNV); + assert(NE_orig < glb_MAXNE); + + long NE_mem = NE_orig * 2; // number for real edge to be stored in memory + long NE_mem_1 = NE_mem < (glb_MAXNV) ? NE_mem : (glb_MAXNV); + long NE_mem_2 = NE_mem - NE_mem_1; + + double prevMod = -1; // Last-phase modularity + double mod = pglv_orig->Q; // Current modularity + double* currMod = &mod; + + bool nonColor = false; // Make sure that at least one phase with lower opts_threshold runs + bool isItrStop = false; + + pglv_orig->times.timePrePre = omp_get_wtime() - pglv_orig->times.timePrePre; + + while (!isItrStop) { + int phase_tmp = pglv_orig->times.phase; + pglv_orig->times.eachTimePhase[pglv_orig->times.phase - 1] = omp_get_wtime(); +#ifdef PRINTINFO + printf("===============================\n"); + printf("Phase Begin%d\n", pglv_orig->times.phase); + printf("===============================\n"); +#endif + + { + pglv_orig->times.eachTimeE2E_2[pglv_orig->times.phase - 1] = omp_get_wtime(); + +#ifdef PRINTINFO + printf("DEBUG: addwork to FPGA task queue\n"); +#endif + auto ev = + addwork(pglv_iter, kernelMode, opts_C_thresh, &pglv_orig->times.eachItrs[pglv_orig->times.phase - 1], + currMod, &numClusters, &pglv_orig->times.eachTimeInitBuff[pglv_orig->times.phase - 1], + &pglv_orig->times.eachTimeReadBuff[pglv_orig->times.phase - 1]); + ev.wait(); + + pglv_orig->times.eachTimeE2E[pglv_orig->times.phase - 1] = pglv_iter->times.eachTimeE2E[0]; + pglv_orig->times.deviceID[pglv_orig->times.phase - 1] = pglv_iter->times.deviceID[0]; + pglv_orig->times.cuID[pglv_orig->times.phase - 1] = pglv_iter->times.cuID[0]; + pglv_orig->times.channelID[pglv_orig->times.phase - 1] = pglv_iter->times.channelID[0]; + pglv_orig->times.eachTimeE2E_2[pglv_orig->times.phase - 1] = + omp_get_wtime() - pglv_orig->times.eachTimeE2E_2[pglv_orig->times.phase - 1]; + + pglv_orig->times.totTimeInitBuff += pglv_orig->times.eachTimeInitBuff[pglv_orig->times.phase - 1]; + pglv_orig->times.totTimeReadBuff += pglv_orig->times.eachTimeReadBuff[pglv_orig->times.phase - 1]; + pglv_orig->times.totTimeE2E_2 += pglv_orig->times.eachTimeE2E_2[pglv_orig->times.phase - 1]; + pglv_orig->times.totTimeE2E += pglv_orig->times.eachTimeE2E[pglv_orig->times.phase - 1]; + pglv_orig->times.totItr += pglv_orig->times.eachItrs[pglv_orig->times.phase - 1]; + } + if (kernelMode == LOUVAINMOD_PRUNING_KERNEL) { + pglv_orig->times.eachTimeReGraph[pglv_orig->times.phase - 1] = PhaseLoop_CommPostProcessing_par( + pglv_orig, pglv_iter, numThreads, opts_threshold, opts_coloring, nonColor, pglv_orig->times.phase, + pglv_orig->times.totItr, numClusters, pglv_orig->times.totTimeBuildingPhase, + pglv_orig->times.eachNum[pglv_orig->times.phase - 1], + pglv_orig->times.eachC[pglv_orig->times.phase - 1], pglv_orig->times.eachM[pglv_orig->times.phase - 1], + pglv_orig->times.eachBuild[pglv_orig->times.phase - 1], + pglv_orig->times.eachSet[pglv_orig->times.phase - 1]); + } else { + pglv_orig->times.eachTimeReGraph[pglv_orig->times.phase - 1] = PhaseLoop_CommPostProcessing_par_renumber( + pglv_orig, pglv_iter, numThreads, opts_threshold, opts_coloring, nonColor, pglv_orig->times.phase, + pglv_orig->times.totItr, numClusters, pglv_orig->times.totTimeBuildingPhase, + pglv_orig->times.eachNum[pglv_orig->times.phase - 1], + pglv_orig->times.eachC[pglv_orig->times.phase - 1], pglv_orig->times.eachM[pglv_orig->times.phase - 1], + pglv_orig->times.eachBuild[pglv_orig->times.phase - 1], + pglv_orig->times.eachSet[pglv_orig->times.phase - 1]); + } + + pglv_orig->times.eachClusters[pglv_orig->times.phase - 1] = numClusters; + pglv_orig->times.eachMod[pglv_orig->times.phase - 1] = currMod[0]; + pglv_orig->times.totTimeReGraph += pglv_orig->times.eachTimeReGraph[pglv_orig->times.phase - 1]; + pglv_orig->NC = numClusters; + pglv_iter->NC = numClusters; +#ifdef PRINTINFO + printf("INFO: numClusters=%ld \n", numClusters); +#endif + pglv_orig->Q = currMod[0]; + pglv_iter->Q = currMod[0]; + pglv_orig->times.eachTimeFeature[pglv_orig->times.phase - 1] = omp_get_wtime(); + pglv_orig->times.eachTimeFeature[pglv_orig->times.phase - 1] = + omp_get_wtime() - pglv_orig->times.eachTimeFeature[pglv_orig->times.phase - 1]; + pglv_orig->times.totTimeFeature += pglv_orig->times.eachTimeFeature[pglv_orig->times.phase - 1]; + + if ((pglv_orig->times.phase >= max_num_level) || (pglv_orig->times.totItr >= max_num_iter)) { + isItrStop = true; // Break if too many phases or iterations + } else if ((currMod[0] - prevMod) <= opts_threshold) { + isItrStop = true; + } else if (pglv_iter->NV <= opts_minGraphSize) { + isItrStop = true; + } else { + isItrStop = false; + pglv_orig->times.phase++; + } + prevMod = currMod[0]; + /*if (isItrStop == false) + pglv_orig->times.eachTimePhase[pglv_orig->times.phase - 2] = omp_get_wtime() - + pglv_orig->times.eachTimePhase[pglv_orig->times.phase - 2]; + else + pglv_orig->times.eachTimePhase[pglv_orig->times.phase - 1] = omp_get_wtime() - + pglv_orig->times.eachTimePhase[pglv_orig->times.phase - 1];*/ + pglv_orig->times.eachTimePhase[phase_tmp - 1] = omp_get_wtime() - pglv_orig->times.eachTimePhase[phase_tmp - 1]; +#ifdef PRINTINFO + printf("=======================================================\n"); + printf("Par:%d Phase:%d Done! at Device:%d Phase time =%lf E2E_wait=%lf E2E_pure=%lf \n", + pglv_orig->times.parNo, phase_tmp, pglv_orig->times.deviceID[phase_tmp - 1], + pglv_orig->times.eachTimePhase[phase_tmp - 1], pglv_orig->times.eachTimeE2E_2[phase_tmp - 1], + pglv_orig->times.eachTimeE2E[phase_tmp - 1]); + printf("=====================================================\n"); +#endif + } // End of while(1) = End of Louvain + pglv_orig->times.totTimeAll = omp_get_wtime() - pglv_orig->times.totTimeAll; + double timePostPost; + double timePostPost_feature; + timePostPost_feature = omp_get_wtime(); + timePostPost = omp_get_wtime(); +#ifdef PRINTINFO + printf("********************************************\n"); + printf("********* Compact Summary *************\n"); + printf("********************************************\n"); + printf("Number of threads : %d\n", numThreads); + printf("Total number of phases : %d\n", pglv_orig->times.phase); + printf("Total number of iterations : %d\t\t = ", pglv_orig->times.totItr); + for (int i = 0; i < pglv_orig->times.phase; i++) printf(" + %8d ", pglv_orig->times.eachItrs[i]); + printf("\n"); + printf("Final number of clusters : %ld\t\t : ", numClusters); + for (int i = 0; i < pglv_orig->times.phase; i++) printf(" %8d ", pglv_orig->times.eachClusters[i]); + printf("\n"); + printf("Final modularity : %lf : \t", prevMod); + for (int i = 0; i < pglv_orig->times.phase; i++) printf(" %2.6f ", pglv_orig->times.eachMod[i]); + printf("\n"); + printf("Total time for clustering : %lf\n", pglv_orig->times.totTimeClustering); + printf("Total time for building phases : %lf\n", pglv_orig->times.totTimeBuildingPhase); + printf("Total E2E time(s) : %lf = \t", pglv_orig->times.totTimeE2E); + for (int i = 0; i < pglv_orig->times.phase; i++) printf("+ %2.6f ", pglv_orig->times.eachTimeE2E_2[i]); + printf("\n"); + if (opts_coloring) { + printf("Total time for coloring : %lf\n", pglv_orig->times.totTimeColoring); + } + printf("********************************************\n"); + printf("TOTAL TIME : %lf\n", + pglv_orig->times.totTimeE2E_2 + pglv_orig->times.totTimeClustering + pglv_orig->times.totTimeBuildingPhase + + pglv_orig->times.totTimeColoring); + printf("********************************************\n"); + printf("Total time for Init buff_host : %lf = \t", pglv_orig->times.totTimeInitBuff); + for (int i = 0; i < pglv_orig->times.phase; i++) printf("+ %2.6f ", pglv_orig->times.eachTimeInitBuff[i]); + printf("\n"); + printf("Total time for Read buff_host : %lf = \t", pglv_orig->times.totTimeReadBuff); + for (int i = 0; i < pglv_orig->times.phase; i++) printf("+ %2.6f ", pglv_orig->times.eachTimeReadBuff[i]); + printf("\n"); + printf("Total time for totTimeE2E_2 : %lf = \t", pglv_orig->times.totTimeE2E_2); + for (int i = 0; i < pglv_orig->times.phase; i++) printf("+ %2.6f ", pglv_orig->times.eachTimeE2E_2[i]); + printf("\n"); + + printf("Total time for totTimeReGraph : %lf = \t", pglv_orig->times.totTimeReGraph); + for (int i = 0; i < pglv_orig->times.phase; i++) printf("+ %2.6f ", pglv_orig->times.eachTimeReGraph[i]); + printf("\n"); +#endif + + double ToTeachNum = 0; // [MAX_NUM_PHASE]; + double ToTeachC = 0; // [MAX_NUM_PHASE]; + double ToTeachM = 0; // [MAX_NUM_PHASE]; + double ToTeachBuild = 0; // [MAX_NUM_PHASE]; + double ToTeachSet = 0; // [MAX_NUM_PHASE]; + + for (int i = 0; i < pglv_orig->times.phase; i++) { + ToTeachNum += pglv_orig->times.eachNum[i]; // [MAX_NUM_PHASE]; + ToTeachC += pglv_orig->times.eachC[i]; // [MAX_NUM_PHASE]; + ToTeachM += pglv_orig->times.eachM[i]; // [MAX_NUM_PHASE]; + ToTeachBuild += pglv_orig->times.eachBuild[i]; // [MAX_NUM_PHASE]; + ToTeachSet += pglv_orig->times.eachSet[i]; + } + int phase = pglv_orig->times.phase; +#ifdef PRINTINFO + printf("----- time for ToTeachNum : %lf = \t", ToTeachNum); + for (int i = 0; i < phase; i++) printf("+ %2.6f ", pglv_orig->times.eachNum[i]); + printf("\n"); + printf("----- time for ToTeachC : %lf = \t", ToTeachC); + for (int i = 0; i < phase; i++) printf("+ %2.6f ", pglv_orig->times.eachC[i]); + printf("\n"); + printf("----- time for ToTeachM : %lf = \t", ToTeachM); + for (int i = 0; i < phase; i++) printf("+ %2.6f ", pglv_orig->times.eachM[i]); + printf("\n"); + printf("----- time for ToTeachBuild : %lf = \t", ToTeachBuild); + for (int i = 0; i < phase; i++) printf("+ %2.6f ", pglv_orig->times.eachBuild[i]); + printf("\n"); + printf("----- time for ToTeachSet : %lf = \t", ToTeachSet); + for (int i = 0; i < phase; i++) printf("+ %2.6f ", pglv_orig->times.eachSet[i]); + printf("\n"); + + printf("Total time for totTimeFeature : %lf = \t", pglv_orig->times.totTimeFeature); + for (int i = 0; i < phase; i++) printf("+ %2.6f ", pglv_orig->times.eachTimeFeature[i]); + printf("\n"); + printf("********************************************\n"); + printf("TOTAL TIME2 : %lf = \t", pglv_orig->times.totTimeAll); // eachTimePhase + for (int i = 0; i < phase; i++) printf("+ %2.6f ", pglv_orig->times.eachTimePhase[i]); + printf("\n"); + printf("********************************************\n"); +#endif + // buff_host.freeMem(); + // pglv_orig->PushFeature(phase, pglv_orig->times.totItr, pglv_orig->times.totTimeE2E_2, true); // isUsingFPGA); + // pglv_iter->PushFeature(phase, pglv_orig->times.totItr, pglv_orig->times.totTimeE2E_2, true); // isUsingFPGA); + timePostPost = omp_get_wtime() - timePostPost; + timePostPost_feature = omp_get_wtime() - timePostPost_feature; +#ifdef PRINTINFO + printf("TOTAL PrePre : %lf = %f(dev) + %lf(bin) + %lf(buff) +%lf\n", pglv_orig->times.timePrePre, + pglv_orig->times.timePrePre_dev, pglv_orig->times.timePrePre_xclbin, pglv_orig->times.timePrePre_buff, + pglv_orig->times.timePrePre - pglv_orig->times.timePrePre_dev - pglv_orig->times.timePrePre_xclbin - + pglv_orig->times.timePrePre_buff); // eachTimePhase + printf("TOTAL PostPost : %lf = %lf + %lf\n", timePostPost, timePostPost_feature, + timePostPost - timePostPost_feature); // eachTimePhase +#endif +} + +event opLouvainModularity::addwork(GLV* glv, + int kernelMode, + double opts_C_thresh, + int* eachItrs, + double* currMod, + long* numClusters, + double* eachTimeInitBuff, + double* eachTimeReadBuff) { + return createL3(task_queue[0], &(compute), handles, kernelMode, numBuffers_, glv, opts_C_thresh, + /*buff_hosts,*/ buff_hosts_prune, eachItrs, currMod, numClusters, eachTimeInitBuff, + eachTimeReadBuff); +}; + +} // L3 +} // graph +} // xf diff --git a/graph/L3/src/xf_graph_L3.cpp b/graph/L3/src/xf_graph_L3.cpp old mode 100755 new mode 100644 index 0039c723fe..643b075362 --- a/graph/L3/src/xf_graph_L3.cpp +++ b/graph/L3/src/xf_graph_L3.cpp @@ -33,6 +33,14 @@ int runMultiEvents(uint32_t number, std::vector >& f) return ret; } +void louvainModularity( + std::shared_ptr handle, int flowMode, GLV* glv, GLV* pglv, LouvainPara* para_lv) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << " handle=" << handle << std::endl; +#endif + (handle->oplouvainmod)->demo_par_core(0, flowMode, glv, pglv, para_lv); +}; + event twoHop(xf::graph::L3::Handle& handle, uint32_t* numPart, uint64_t** pairPart, diff --git a/graph/L3/src/xf_graph_L3_handle.cpp b/graph/L3/src/xf_graph_L3_handle.cpp old mode 100755 new mode 100644 index 56996a069d..21126e71cf --- a/graph/L3/src/xf_graph_L3_handle.cpp +++ b/graph/L3/src/xf_graph_L3_handle.cpp @@ -25,6 +25,32 @@ namespace xf { namespace graph { namespace L3 { +int32_t Handle::initOpLouvainModularity(std::string xclbinFile, + std::string kernelName, + std::string kernelAlias, + unsigned int requestLoad, + unsigned int numDevices, + unsigned int cuPerBoard) { + uint32_t* deviceID; + uint32_t* cuID; + int32_t status = 0; + + // fetchCuInfo will scan all available devices/CUs. + // numDevices_ = numDevices; // set initial requested number of devices + xrm->fetchCuInfo(kernelName.c_str(), kernelAlias.c_str(), requestLoad, numDevices, maxChannelSize, maxCU, &deviceID, + &cuID); + // if (status < 0) + // return status; + + oplouvainmod->setHWInfo(numDevices, maxCU); + oplouvainmod->init(xrm, kernelName, kernelAlias, xclbinFile, deviceID, cuID, requestLoad); + oplouvainmod->initThreadlouvain(xrm, kernelName, kernelAlias, requestLoad, numDevices, cuPerBoard); + delete[] cuID; + delete[] deviceID; + + return 0; +}; + void Handle::initOpTwoHop(const char* kernelName, char* xclbinFile, char* kernelAlias, @@ -523,6 +549,132 @@ int Handle::setUp() { return 0; } +int Handle::setUp(std::string deviceNames) { + const std::string delimiters(" "); + for (int i = deviceNames.find_first_not_of(delimiters, 0); i != std::string::npos; + i = deviceNames.find_first_not_of(delimiters, i)) { + auto tokenEnd = deviceNames.find_first_of(delimiters, i); + if (tokenEnd == std::string::npos) tokenEnd = deviceNames.size(); + const std::string token = deviceNames.substr(i, tokenEnd - i); + supportedDeviceNames_.push_back(token); + i = tokenEnd; + } + + getEnvMultiBoards(); + //getEnv(); + //totalSupportedDevices_ = 1; + + unsigned int opNm = ops.size(); + unsigned int deviceCounter = 0; + int32_t status = 0; + + for (unsigned int i = 0; i < opNm; ++i) { +#if 0 + if (ops[i].operationName == "similarityDense") { + unsigned int boardNm = ops[i].deviceNeeded; + if (deviceCounter + boardNm > totalSupportedDevices_) { + std::cout << "ERROR: Current node does not have requested device count." + << "Requested: " << deviceCounter + boardNm + << "Available: " << totalSupportedDevices_ << std::endl; + return XF_GRAPH_L3_ERROR_NOT_ENOUGH_DEVICES; + } + std::thread thUn[boardNm]; + for (unsigned int j = 0; j < boardNm; ++j) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << ": xrm->unloadXclbinNonBlock " + << supportedDeviceIds[j] << std::endl; +#endif + thUn[j] = xrm->unloadXclbinNonBlock(supportedDeviceIds[j]); + } + for (unsigned int j = 0; j < boardNm; ++j) { + thUn[j].join(); + } + std::future th[boardNm]; + for (unsigned int j = 0; j < boardNm; ++j) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << ": xrm->loadXclbinAsync " + << "\n devId=" << supportedDeviceIds[j] + << "\n ops[i].xclbinFile=" << ops[i].xclbinFile << std::endl; +#endif + th[j] = loadXclbinAsync(supportedDeviceIds[j], ops[i].xclbinFile); + } + for (unsigned int j = 0; j < boardNm; ++j) { + auto loadedDevId = th[j].get(); + if (loadedDevId < 0) { + std::cout << "ERROR: Failed to load " << ops[i].xclbinFile << + "(Status=" << loadedDevId << ")." << std::endl; + std::cout << " Try 'xbutil reset -d " << supportedDeviceIds[j] + << "' and rerun the application." << std::endl; + return loadedDevId; + } + } + deviceCounter += boardNm; + + initOpSimDense(ops[i].xclbinFile, ops[i].kernelName, ops[i].kernelAlias, + ops[i].requestLoad, ops[i].deviceNeeded, ops[i].cuPerBoard); + } +#endif + + // if (ops[i].operationName == "louvainModularity") { + unsigned int boardNm = ops[i].deviceNeeded; + if (deviceCounter + boardNm > totalSupportedDevices_) { + std::cout << "ERROR: Current node does not have requested device count." + << " Requested: " << deviceCounter + boardNm << " Available: " << totalSupportedDevices_ + << std::endl; + return XF_GRAPH_L3_ERROR_NOT_ENOUGH_DEVICES; + } + + // Unload existing xclbin first if present + std::thread thUn[boardNm]; + for (int j = 0; j < boardNm; ++j) { +#ifndef NDEBUG + std::cout << "DEBUG: " + << "xrm->unloadXclbinNonBlock devId=" << supportedDeviceIds[j] << std::endl; +#endif + thUn[j] = xrm->unloadXclbinNonBlock(supportedDeviceIds[j]); + } + for (int j = 0; j < boardNm; ++j) { + thUn[j].join(); + } + + // load xclbin asynchronously (i.e. non-blocking) using thread + std::future th[boardNm]; + + for (int j = 0; j < boardNm; ++j) { +#ifndef NDEBUG + std::cout << "DEBUG: " << __FUNCTION__ << ": xrm->loadXclbinAsync " + << "\n devId=" << supportedDeviceIds[j] << "\n ops[i].xclbinFile=" << ops[i].xclbinFile + << std::endl; +#endif + th[j] = loadXclbinAsync(supportedDeviceIds[j], ops[i].xclbinFile); + } + + // wait for thread to finish + for (int j = 0; j < boardNm; ++j) { + auto loadedDevId = th[j].get(); + if (loadedDevId < 0) { + std::cout << "ERROR: Failed to load " << ops[i].xclbinFile << "(Status=" << loadedDevId + << "). Please check if it is " + << "created for the Xilinx Acceleration card installed on " + << "the server." << std::endl; + return loadedDevId; + } + } + + deviceCounter += boardNm; + status = initOpLouvainModularity(ops[i].xclbinFile, ops[i].kernelName, ops[i].kernelAlias, ops[i].requestLoad, + ops[i].deviceNeeded, ops[i].cuPerBoard); + if (status < 0) return XF_GRAPH_L3_ERROR_ALLOC_CU; + //} + + if (0) { + std::cout << "Error: the operation " << ops[i].operationName << " is not supported" << std::endl; + exit(1); + } + } + return 0; +} + void Handle::getEnv() { cl_uint platformID = NULL; cl_platform_id* platforms = NULL; @@ -566,11 +718,84 @@ void Handle::getEnv() { } } +void Handle::getEnvMultiBoards() { + cl_uint platformID = 0; + cl_platform_id* platforms = NULL; + char vendor_name[128] = {0}; + cl_uint num_platforms = 0; + cl_int err2 = clGetPlatformIDs(0, NULL, &num_platforms); + if (CL_SUCCESS != err2) { + std::cout << "INFO: get platform failed1" << std::endl; + } + platforms = (cl_platform_id*)malloc(sizeof(cl_platform_id) * num_platforms); + if (NULL == platforms) { + std::cout << "INFO: allocate platform failed" << std::endl; + } + err2 = clGetPlatformIDs(num_platforms, platforms, NULL); + if (CL_SUCCESS != err2) { + std::cout << "INFO: get platform failed2" << std::endl; + } + for (cl_uint ui = 0; ui < num_platforms; ++ui) { + err2 = clGetPlatformInfo(platforms[ui], CL_PLATFORM_VENDOR, 128 * sizeof(char), vendor_name, NULL); + if (CL_SUCCESS != err2) { + std::cout << "INFO: get platform failed3" << std::endl; + } else if (!std::strcmp(vendor_name, "Xilinx")) { + platformID = ui; + } + } + cl_device_id* devices; + std::vector devices0 = xcl::get_xil_devices(); + uint32_t totalXilinxDevices = devices0.size(); + totalSupportedDevices_ = 0; + devices = (cl_device_id*)malloc(sizeof(cl_device_id) * totalXilinxDevices); + err2 = clGetDeviceIDs(platforms[platformID], CL_DEVICE_TYPE_ALL, totalXilinxDevices, devices, NULL); + std::cout << "INFO: total xilinx devices = " << totalXilinxDevices << std::endl; + size_t valueSize; + char* value; + + for (int i = 0; i < totalXilinxDevices; ++i) { + // print device name + clGetDeviceInfo(devices[i], CL_DEVICE_NAME, 0, NULL, &valueSize); + value = new char[valueSize]; + clGetDeviceInfo(devices[i], CL_DEVICE_NAME, valueSize, value, NULL); + std::cout << "INFO: " << __FUNCTION__ << ": Scanned device " << i << ":" << value << std::endl; + if (std::find(supportedDeviceNames_.begin(), supportedDeviceNames_.end(), value) != supportedDeviceNames_.end()) { + std::cout << " Supported device found:" << value << std::endl; + supportedDeviceIds[totalSupportedDevices_++] = i; // save curret supported supported devices + } + delete[] value; + } + std::cout << "INFO: Total matching devices: " << totalSupportedDevices_ << std::endl; +} + +void Handle::showHandleInfo() { +#ifndef NDEBUG + std::cout << "INFO: " << __FUNCTION__ << " deviceNm_=" << deviceNm << " maxCU=" << maxCU << std::endl; + unsigned int opNm = ops.size(); + for (unsigned int i = 0; i < opNm; ++i) { + std::cout << "INFO: " << __FUNCTION__ << " operationName=" << ops[i].operationName + << " kernelname=" << ops[i].kernelName << " requestLoad=" << ops[i].requestLoad + << " xclbinFile=" << ops[i].xclbinFile << std::endl; + } +#endif +} + void Handle::free() { unsigned int opNm = ops.size(); unsigned int deviceCounter = 0; for (int i = 0; i < opNm; ++i) { - if (strcmp(ops[i].operationName, "twoHop") == 0) { + if (ops[i].operationName == "louvainModularity") { + unsigned int boardNm = ops[i].deviceNeeded; + std::thread thUn[boardNm]; + for (int j = 0; j < boardNm; ++j) { + thUn[j] = xrm->unloadXclbinNonBlock(deviceCounter + j); + } + for (int j = 0; j < boardNm; ++j) { + thUn[j].join(); + } + deviceCounter += boardNm; + oplouvainmod->freeLouvainModularity(); + } else if (strcmp(ops[i].operationName, "twoHop") == 0) { unsigned int boardNm = ops[i].deviceNeeded; std::thread thUn[boardNm]; for (int j = 0; j < boardNm; ++j) { diff --git a/graph/L3/tests/louvainModularity/Makefile b/graph/L3/tests/louvainModularity/Makefile new file mode 100644 index 0000000000..2b09dbc476 --- /dev/null +++ b/graph/L3/tests/louvainModularity/Makefile @@ -0,0 +1,226 @@ +# +# Copyright 2019-2021 Xilinx, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# makefile-generator v1.0.4 +# + +# ####################################### Help Section ##################################### +.PHONY: help + +help:: + $(ECHO) "Makefile Usage:" + $(ECHO) " make all TARGET= DEVICE= HOST_ARCH=" + $(ECHO) " Command to generate the design for specified Target and Shell." + $(ECHO) "" + $(ECHO) " make clean " + $(ECHO) " Command to remove the generated non-hardware files." + $(ECHO) "" + $(ECHO) " make cleanall" + $(ECHO) " Command to remove all the generated files." + $(ECHO) "" + $(ECHO) " make run TARGET= DEVICE= HOST_ARCH=" + $(ECHO) " Command to run application in emulation or on board." + $(ECHO) "" + $(ECHO) " make build TARGET= DEVICE= HOST_ARCH=" + $(ECHO) " Command to build xclbin application." + $(ECHO) "" + $(ECHO) " make host HOST_ARCH=" + $(ECHO) " Command to build host application." + $(ECHO) "" + +# ##################### Setting up default value of TARGET ########################## +TARGET ?= sw_emu + +# ################### Setting up default value of DEVICE ############################## +DEVICE ?= xilinx_u55c_gen3x16_xdma_2_202110_1 + +# ###################### Setting up default value of HOST_ARCH ####################### +HOST_ARCH ?= x86 + +# #################### Checking if DEVICE in whitelist ############################ +ifneq ($(findstring u55c, $(DEVICE)), u55c) +$(warning [WARNING]: This project has not been tested for $(DEVICE). It may or may not work.) +endif + +# ######################## Setting up Project Variables ################################# +MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) +XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L3/*}') +CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) +XFLIB_DIR = $(XF_PROJ_ROOT) + +# ######################### Include environment variables in utils.mk #################### +include ./utils.mk +XDEVICE := $(call device2xsa, $(DEVICE)) +TEMP_DIR := _x_temp.$(TARGET).$(XDEVICE) +TEMP_REPORT_DIR := $(CUR_DIR)/reports/_x.$(TARGET).$(XDEVICE) +BUILD_DIR := build_dir.$(TARGET).$(XDEVICE) +BUILD_REPORT_DIR := $(CUR_DIR)/reports/_build.$(TARGET).$(XDEVICE) +EMCONFIG_DIR := $(BUILD_DIR) +XCLBIN_DIR := $(CUR_DIR)/$(BUILD_DIR) +export XCL_BINDIR = $(XCLBIN_DIR) + +# ######################### Setting up Host Variables ######################### +#Include Required Host Source Files +HOST_SRCS += $(XFLIB_DIR)/L3/tests/louvainModularity/test_louvainRun.cpp +HOST_SRCS += $(XFLIB_DIR)/ext/xcl2/xcl2.cpp +CXXFLAGS += -I$(XFLIB_DIR)/L3/include +LDFLAGS += -L$(XFLIB_DIR)/L3/lib +LDFLAGS += -lgraphL3 +LDFLAGS += -L$(XILINX_XRM)/lib -lxrm -lgomp -B/usr/lib/x86_64-linux-gnu +CXXFLAGS += -I$(XFLIB_DIR)/L2/include +CXXFLAGS += -I$(XFLIB_DIR)/../database/L1/include/hw +CXXFLAGS += -I$(XFLIB_DIR)/../quantitative_finance/L1/include +CXXFLAGS += -I$(XFLIB_DIR)/../utils/L1/include +CXXFLAGS += -I$(XFLIB_DIR)/ext/xcl2 + +ifeq ($(TARGET),sw_emu) +CXXFLAGS += -D SW_EMU_TEST +endif + +ifeq ($(TARGET),hw_emu) +CXXFLAGS += -D HW_EMU_TEST +endif + +# ######################### Host compiler global settings ############################ +CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++11 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label +LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE +CXXFLAGS += -fmessage-length=0 -O3 -I$(XILINX_XRM)/include -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD -DNDEBUG -Wno-sign-compare +CXXFLAGS += -I$(CUR_DIR)/src/ + +ifeq ($(HOST_ARCH), x86) +LDFLAGS += -L$(XILINX_HLS)/lnx64/tools/fpo_v7_0 -Wl,--as-needed -lgmp -lmpfr -lIp_floating_point_v7_0_bitacc_cmodel +endif +ifneq (,$(shell echo $(XPLATFORM) | awk '/u55c/')) +CXXFLAGS += -D USE_U55C +endif + +# ################### Setting package and image directory ####################### + +EXE_NAME := host.exe +EXE_FILE := $(BUILD_DIR)/$(EXE_NAME) +HOST_ARGS := -x $($(CUR_DIR)PATH)/kernel_louvain.xclbin -kernel_mode 2 -num_devices 1 -devices xilinx_u55c_gen3x16_xdma_base_2 -num_level 100 -num_iter 100 -load_alveo_partitions ../louvainModularity/example_tx.par.proj -setwkr 0 -driverAlone +LIBRARY_PATH =P:R:O:J:E:C:T:/:.:.:/:.:.:/:l:i:b:::$:(:X:I:L:I:N:X:_:X:R:T:):/:l:i:b:::$:(:X:I:L:I:N:X:_:X:R:M:):/:l:i:b:$(LD_LIBRARY_PATH) + +# ##################### Kernel compiler global settings ########################## +VPP_FLAGS += -t $(TARGET) --platform $(XPLATFORM) --save-temps --optimize 2 +VPP_FLAGS += --hls.jobs 8 +VPP_LDFLAGS += --vivado.synth.jobs 8 --vivado.impl.jobs 8 +ifneq (,$(shell echo $(XPLATFORM) | awk '/u55c/')) +VPP_FLAGS += --config $(CUR_DIR)/conn_u55c.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=$(CUR_DIR)/postSysLink.tcl +endif + +VPP_FLAGS += -I$(XFLIB_DIR)/L2/include +VPP_FLAGS += -I$(XFLIB_DIR)/../database/L1/include/hw +VPP_FLAGS += -I$(XFLIB_DIR)/../quantitative_finance/L1/include +VPP_FLAGS += -I$(XFLIB_DIR)/../utils/L1/include + +VPP_FLAGS += -I$(XFLIB_DIR)/L2/include +VPP_FLAGS += -I$(XFLIB_DIR)/../utils/L1/include +VPP_FLAGS += -I$(XFLIB_DIR)/../database/L1/include/hw +VPP_FLAGS += -I$(XFLIB_DIR)/../quantitative_finance/L1/include +VPP_FLAGS += -I$(XFLIB_DIR)/L2/tests/louvianfast/kernel + +kernel_louvain_VPP_FLAGS += -D KERNEL_NAME=kernel_louvain +kernel_louvain_VPP_FLAGS += --hls.clock 250000000:kernel_louvain +VPP_LDFLAGS_kernel_louvain += --kernel_frequency 250 + + +# Kernel args + +# ############################ Declaring Binary Containers ########################## + +BINARY_CONTAINERS += $(BUILD_DIR)/kernel_louvain.xclbin +BINARY_CONTAINER_kernel_louvain_OBJS += $(TEMP_DIR)/kernel_louvain.xo + +# ######################### Setting Targets of Makefile ################################ +DATA_DIR += $(CUR_DIR)/data + +.PHONY: all clean cleanall docs emconfig +ifeq ($(HOST_ARCH), x86) +all: check_version check_vpp check_platform check_xrt $(EXE_FILE) $(BINARY_CONTAINERS) emconfig +else +all: check_version check_vpp check_platform check_sysroot $(EXE_FILE) $(BINARY_CONTAINERS) emconfig sd_card +endif + +.PHONY: host +ifeq ($(HOST_ARCH), x86) +host: check_xrt $(EXE_FILE) +else +host: check_sysroot $(EXE_FILE) +endif + +.PHONY: xclbin +ifeq ($(HOST_ARCH), x86) +xclbin: check_vpp check_xrt $(BINARY_CONTAINERS) +else +xclbin: check_vpp check_sysroot $(BINARY_CONTAINERS) +endif + +.PHONY: build +build: xclbin + +# ################ Setting Rules for Binary Containers (Building Kernels) ################ +$(TEMP_DIR)/kernel_louvain.xo: $(XFLIB_DIR)/L2/tests/louvain_fast/kernel/kernel_louvain.cpp + $(ECHO) "Compiling Kernel: kernel_louvain" + mkdir -p $(TEMP_DIR) + $(VPP) -c $(kernel_louvain_VPP_FLAGS) $(VPP_FLAGS) -k kernel_louvain -I'$( +#include + +#include "xilinxlouvain.h" +#include "xf_graph_L3.hpp" +#include "common.hpp" + +using namespace xilinx_apps::louvainmod; + +int main(int argc, char** argv) { + int status = 0; + float finalQ; + ToolOptions toolOptions(argc, argv); + Options options; + LouvainRun::ComputeOptions computeOpts; + // LouvainMod::PartitionOptions partOpts; + + // set internal options fields based to commandline options + options.modeAlveo = toolOptions.mode_alveo; + options.xclbinPath = toolOptions.xclbinFile; + options.kernelMode = toolOptions.kernelMode; + options.nameProj = toolOptions.nameProj; + options.alveoProject = toolOptions.alveoProject; + options.numDevices = toolOptions.numDevices; + options.deviceNames = toolOptions.deviceNames; + options.nodeId = 0; + + std::cout << "toolOptions.modeZmq=" << toolOptions.modeZmq << " toolOptions.nodeId=" << toolOptions.nodeId + << " toolOptions.numNodes=" << toolOptions.numNodes << std::endl; + + // create louvainMod object with internal "options". These options are common + // between partition and load/compute operations + LouvainRun louvainRun(options); + + switch (toolOptions.mode_alveo) { + // case ALVEOAPI_PARTITION: // 1 + // partOpts.LBW_partition = false; + // partOpts.numPars = toolOptions.numPars; + // partOpts.par_prune = toolOptions.gh_par; + // louvainMod.partitionDataFile(toolOptions.opts_inFile, partOpts); + // break; + // case ALVEOAPI_PARTITION_LBW: // 2 + // partOpts.LBW_partition = true; + // partOpts.numPars = toolOptions.numPars; + // partOpts.par_prune = toolOptions.gh_par; + // louvainMod.partitionDataFile(toolOptions.opts_inFile, partOpts); + // break; + case ALVEOAPI_LOAD: // 3 + std::cout << "ALVEOAPI_LOAD" << std::endl; + + computeOpts.outputFile = toolOptions.outputFile; + computeOpts.max_iter = toolOptions.max_iter; + computeOpts.max_level = toolOptions.max_level; + computeOpts.tolerance = toolOptions.threshold; + computeOpts.intermediateResult = false; + computeOpts.final_Q = true; + computeOpts.all_Q = false; + + finalQ = louvainRun.loadAlveoAndComputeLouvain(computeOpts); + if (finalQ < -1) { + std::cout << "ERROR: loadAlveoAndComputeLouvain completed with error. ErrorCode=" << finalQ + << std::endl; + status = -1; + } else if (toolOptions.modeZmq == ZMQ_DRIVER) // only the driver reports the final modularity value + std::cout << "INFO: loadAlveoAndComputeLouvain completed. finalQ=" << finalQ << std::endl; + break; + default: + std::cout << "ERROR: Unknown tool mode " << toolOptions.mode_alveo << std::endl; + break; + } + return status; +} diff --git a/graph/L3/tests/louvainModularity/utils.mk b/graph/L3/tests/louvainModularity/utils.mk new file mode 100755 index 0000000000..b2cda39901 --- /dev/null +++ b/graph/L3/tests/louvainModularity/utils.mk @@ -0,0 +1,221 @@ +# +# Copyright 2019-2021 Xilinx, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#+------------------------------------------------------------------------------- +# The following parameters are assigned with default values. These parameters can +# be overridden through the make command line +#+------------------------------------------------------------------------------- + +REPORT := no +PROFILE := no +DEBUG := no + +#'estimate' for estimate report generation +#'system' for system report generation +ifneq ($(REPORT), no) +VPP_LDFLAGS += --report estimate +VPP_LDFLAGS += --report system +endif + +#Generates profile summary report +ifeq ($(PROFILE), yes) +VPP_LDFLAGS += --profile_kernel data:all:all:all +endif + +#Generates debug summary report +ifeq ($(DEBUG), yes) +VPP_LDFLAGS += --dk protocol:all:all:all +endif + +#Checks for XILINX_XRT +ifeq ($(HOST_ARCH), x86) +ifndef XILINX_XRT + XILINX_XRT = /opt/xilinx/xrt + export XILINX_XRT +endif +else +ifndef XILINX_VITIS + XILINX_VITIS = /opt/xilinx/Vitis/$(TOOL_VERSION) + export XILINX_VITIS +endif +endif + +#Checks for Device Family +ifeq ($(HOST_ARCH), aarch32) + DEV_FAM = 7Series +else ifeq ($(HOST_ARCH), aarch64) + DEV_FAM = Ultrascale +endif + +B_NAME = $(shell dirname $(XPLATFORM)) + +#Checks for Correct architecture +ifneq ($(HOST_ARCH), $(filter $(HOST_ARCH),aarch64 aarch32 x86)) +$(error HOST_ARCH variable not set, please set correctly and rerun) +endif + +#Checks for SYSROOT +check_sysroot: +ifneq ($(HOST_ARCH), x86) +ifndef SYSROOT + $(error SYSROOT ENV variable is not set, please set ENV variable correctly and rerun) +endif +endif + +check_version: +ifneq (, $(shell which git)) +ifneq (,$(wildcard $(XFLIB_DIR)/.git)) + @cd $(XFLIB_DIR) && git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -n 1 && cd - +endif +endif + +#Checks for g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +ifeq ($(HOST_ARCH), x86) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifndef XILINX_VIVADO +$(error [ERROR]: g++ version too old. Please use 5.0 or above) +else +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +ifeq ($(LD_LIBRARY_PATH),) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +else +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +endif +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) +endif +endif +else ifeq ($(HOST_ARCH), aarch64) +CXX := $(XILINX_VITIS)/gnu/aarch64/lin/aarch64-linux/bin/aarch64-linux-gnu-g++ +else ifeq ($(HOST_ARCH), aarch32) +CXX := $(XILINX_VITIS)/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++ +endif + +#Setting VPP +VPP := v++ + +#Cheks for aiecompiler + +.PHONY: check_vivado +check_vivado: +ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) + @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false +endif + +.PHONY: check_vpp +check_vpp: +ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) + @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false +endif + +.PHONY: check_xrt +check_xrt: +ifeq ($(HOST_ARCH), x86) +ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) + @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false +endif +endif + +export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) +ifeq ($(HOST_ARCH), x86) +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(XILINX_XRT)/lib +else +LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) +endif +else # aarch64 +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib +else +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) +endif +endif + +# check target +ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) +$(error TARGET is not sw_emu, hw_emu or hw) +endif + +ifneq (,$(wildcard $(DEVICE))) +# Use DEVICE as a file path +XPLATFORM := $(DEVICE) +else +# Use DEVICE as a file name pattern +# 1. search paths specified by variable +ifneq (,$(PLATFORM_REPO_PATHS)) +# 1.1 as exact name +XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE)/$(DEVICE).xpfm))) +# 1.2 as a pattern +ifeq (,$(XPLATFORM)) +XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) +XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) +endif # 1.2 +endif # 1 +# 2. search Vitis installation +ifeq (,$(XPLATFORM)) +# 2.1 as exact name +XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE)/$(DEVICE).xpfm)) +# 2.2 as a pattern +ifeq (,$(XPLATFORM)) +XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) +XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) +endif # 2.2 +endif # 2 +# 3. search default locations +ifeq (,$(XPLATFORM)) +# 3.1 as exact name +XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE)/$(DEVICE).xpfm)) +# 3.2 as a pattern +ifeq (,$(XPLATFORM)) +XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) +XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) +endif # 3.2 +endif # 3 +endif + +define MSG_PLATFORM +No platform matched pattern '$(DEVICE)'. +Available platforms are: $(XPLATFORMS) +To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. +endef +export MSG_PLATFORM + +define MSG_DEVICE +More than one platform matched: $(XPLATFORM) +Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. +endef +export MSG_DEVICE + +.PHONY: check_platform +check_platform: +ifeq (,$(XPLATFORM)) + @echo "$${MSG_PLATFORM}" && false +endif +ifneq (,$(word 2,$(XPLATFORM))) + @echo "$${MSG_DEVICE}" && false +endif +#Check ends + +# device2xsa - create a filesystem friendly name from device name +# $(1) - full name of device +device2xsa = $(strip $(patsubst %.xpfm, % , $(shell basename $(DEVICE)))) + +# Cleaning stuff +RM = rm -f +RMDIR = rm -rf + +MV = mv -f +CP = cp -rf +ECHO:= @echo diff --git a/graph/L3/tests/louvainPartition/Makefile b/graph/L3/tests/louvainPartition/Makefile new file mode 100644 index 0000000000..b657e3642f --- /dev/null +++ b/graph/L3/tests/louvainPartition/Makefile @@ -0,0 +1,226 @@ +# +# Copyright 2019-2021 Xilinx, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# makefile-generator v1.0.4 +# + +# ####################################### Help Section ##################################### +.PHONY: help + +help:: + $(ECHO) "Makefile Usage:" + $(ECHO) " make all TARGET= DEVICE= HOST_ARCH=" + $(ECHO) " Command to generate the design for specified Target and Shell." + $(ECHO) "" + $(ECHO) " make clean " + $(ECHO) " Command to remove the generated non-hardware files." + $(ECHO) "" + $(ECHO) " make cleanall" + $(ECHO) " Command to remove all the generated files." + $(ECHO) "" + $(ECHO) " make run TARGET= DEVICE= HOST_ARCH=" + $(ECHO) " Command to run application in emulation or on board." + $(ECHO) "" + $(ECHO) " make build TARGET= DEVICE= HOST_ARCH=" + $(ECHO) " Command to build xclbin application." + $(ECHO) "" + $(ECHO) " make host HOST_ARCH=" + $(ECHO) " Command to build host application." + $(ECHO) "" + +# ##################### Setting up default value of TARGET ########################## +TARGET ?= sw_emu + +# ################### Setting up default value of DEVICE ############################## +DEVICE ?= xilinx_u55c_gen3x16_xdma_2_202110_1 + +# ###################### Setting up default value of HOST_ARCH ####################### +HOST_ARCH ?= x86 + +# #################### Checking if DEVICE in whitelist ############################ +ifneq ($(findstring u55c, $(DEVICE)), u55c) +$(warning [WARNING]: This project has not been tested for $(DEVICE). It may or may not work.) +endif + +# ######################## Setting up Project Variables ################################# +MK_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) +XF_PROJ_ROOT ?= $(shell bash -c 'export MK_PATH=$(MK_PATH); echo $${MK_PATH%/L3/*}') +CUR_DIR := $(patsubst %/,%,$(dir $(MK_PATH))) +XFLIB_DIR = $(XF_PROJ_ROOT) + +# ######################### Include environment variables in utils.mk #################### +include ./utils.mk +XDEVICE := $(call device2xsa, $(DEVICE)) +TEMP_DIR := _x_temp.$(TARGET).$(XDEVICE) +TEMP_REPORT_DIR := $(CUR_DIR)/reports/_x.$(TARGET).$(XDEVICE) +BUILD_DIR := build_dir.$(TARGET).$(XDEVICE) +BUILD_REPORT_DIR := $(CUR_DIR)/reports/_build.$(TARGET).$(XDEVICE) +EMCONFIG_DIR := $(BUILD_DIR) +XCLBIN_DIR := $(CUR_DIR)/$(BUILD_DIR) +export XCL_BINDIR = $(XCLBIN_DIR) + +# ######################### Setting up Host Variables ######################### +#Include Required Host Source Files +HOST_SRCS += $(XFLIB_DIR)/L3/tests/louvainPartition/test_partition.cpp +HOST_SRCS += $(XFLIB_DIR)/ext/xcl2/xcl2.cpp +CXXFLAGS += -I$(XFLIB_DIR)/L3/include +LDFLAGS += -L$(XFLIB_DIR)/L3/lib +LDFLAGS += -lgraphL3 +LDFLAGS += -L$(XILINX_XRM)/lib -lxrm -lgomp +CXXFLAGS += -I$(XFLIB_DIR)/L2/include +CXXFLAGS += -I$(XFLIB_DIR)/../database/L1/include/hw +CXXFLAGS += -I$(XFLIB_DIR)/../quantitative_finance/L1/include +CXXFLAGS += -I$(XFLIB_DIR)/../utils/L1/include +CXXFLAGS += -I$(XFLIB_DIR)/ext/xcl2 + +ifeq ($(TARGET),sw_emu) +CXXFLAGS += -D SW_EMU_TEST +endif + +ifeq ($(TARGET),hw_emu) +CXXFLAGS += -D HW_EMU_TEST +endif + +# ######################### Host compiler global settings ############################ +CXXFLAGS += -I$(XILINX_XRT)/include -I$(XILINX_HLS)/include -std=c++11 -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label +LDFLAGS += -L$(XILINX_XRT)/lib -lOpenCL -lpthread -lrt -Wno-unused-label -Wno-narrowing -DVERBOSE +CXXFLAGS += -fmessage-length=0 -O3 -I$(XILINX_XRM)/include -DPRAGMA -Ofast -fopenmp -fPIC -DMULTITHREAD -DNDEBUG -B/usr/lib/x86_64-linux-gnu +CXXFLAGS += -I$(CUR_DIR)/src/ + +ifeq ($(HOST_ARCH), x86) +LDFLAGS += -L$(XILINX_HLS)/lnx64/tools/fpo_v7_0 -Wl,--as-needed -lgmp -lmpfr -lIp_floating_point_v7_0_bitacc_cmodel +endif +ifneq (,$(shell echo $(XPLATFORM) | awk '/u55c/')) +CXXFLAGS += -D USE_U55C +endif + +# ################### Setting package and image directory ####################### + +EXE_NAME := host.exe +EXE_FILE := $(BUILD_DIR)/$(EXE_NAME) +HOST_ARGS := ./data/example-wt.txt -kernel_mode 2 -num_pars 2 -create_alveo_BFS_partitions -name example_tx +LIBRARY_PATH =P:R:O:J:E:C:T:/:.:.:/:.:.:/:l:i:b:::$:(:X:I:L:I:N:X:_:X:R:T:):/:l:i:b:::$:(:X:I:L:I:N:X:_:X:R:M:):/:l:i:b:$(LD_LIBRARY_PATH) + +# ##################### Kernel compiler global settings ########################## +VPP_FLAGS += -t $(TARGET) --platform $(XPLATFORM) --save-temps --optimize 2 +VPP_FLAGS += --hls.jobs 8 +VPP_LDFLAGS += --vivado.synth.jobs 8 --vivado.impl.jobs 8 +ifneq (,$(shell echo $(XPLATFORM) | awk '/u55c/')) +VPP_FLAGS += --config $(CUR_DIR)/conn_u55c.cfg --advanced.param compiler.userPostSysLinkOverlayTcl=$(CUR_DIR)/postSysLink.tcl +endif + +VPP_FLAGS += -I$(XFLIB_DIR)/L2/include +VPP_FLAGS += -I$(XFLIB_DIR)/../database/L1/include/hw +VPP_FLAGS += -I$(XFLIB_DIR)/../quantitative_finance/L1/include +VPP_FLAGS += -I$(XFLIB_DIR)/../utils/L1/include + +VPP_FLAGS += -I$(XFLIB_DIR)/L2/include +VPP_FLAGS += -I$(XFLIB_DIR)/../utils/L1/include +VPP_FLAGS += -I$(XFLIB_DIR)/../database/L1/include/hw +VPP_FLAGS += -I$(XFLIB_DIR)/../quantitative_finance/L1/include +VPP_FLAGS += -I$(XFLIB_DIR)/L2/tests/louvianfast/kernel + +kernel_louvain_VPP_FLAGS += -D KERNEL_NAME=kernel_louvain +kernel_louvain_VPP_FLAGS += --hls.clock 250000000:kernel_louvain +VPP_LDFLAGS_kernel_louvain += --kernel_frequency 250 + + +# Kernel args + +# ############################ Declaring Binary Containers ########################## + +BINARY_CONTAINERS += $(BUILD_DIR)/kernel_louvain.xclbin +BINARY_CONTAINER_kernel_louvain_OBJS += $(TEMP_DIR)/kernel_louvain.xo + +# ######################### Setting Targets of Makefile ################################ +DATA_DIR += $(CUR_DIR)/data + +.PHONY: all clean cleanall docs emconfig +ifeq ($(HOST_ARCH), x86) +all: check_version check_vpp check_platform check_xrt $(EXE_FILE) $(BINARY_CONTAINERS) emconfig +else +all: check_version check_vpp check_platform check_sysroot $(EXE_FILE) $(BINARY_CONTAINERS) emconfig sd_card +endif + +.PHONY: host +ifeq ($(HOST_ARCH), x86) +host: check_xrt $(EXE_FILE) +else +host: check_sysroot $(EXE_FILE) +endif + +.PHONY: xclbin +ifeq ($(HOST_ARCH), x86) +xclbin: check_vpp check_xrt $(BINARY_CONTAINERS) +else +xclbin: check_vpp check_sysroot $(BINARY_CONTAINERS) +endif + +.PHONY: build +build: xclbin + +# ################ Setting Rules for Binary Containers (Building Kernels) ################ +$(TEMP_DIR)/kernel_louvain.xo: $(XFLIB_DIR)/L2/tests/louvain_fast/kernel/kernel_louvain.cpp + $(ECHO) "Compiling Kernel: kernel_louvain" + mkdir -p $(TEMP_DIR) + $(VPP) -c $(kernel_louvain_VPP_FLAGS) $(VPP_FLAGS) -k kernel_louvain -I'$( +#include + +#include "xilinxlouvain.h" +#include "xf_graph_L3.hpp" +#include "common.hpp" + +using namespace xilinx_apps::louvainmod; + +int main(int argc, char** argv) { + int status = 0; + float finalQ; + ToolOptions toolOptions(argc, argv); + Options options; + // LouvainMod::ComputeOptions computeOpts; + LouvainPar::PartitionOptions partOpts; + + // set internal options fields based to commandline options + options.modeAlveo = toolOptions.mode_alveo; + options.xclbinPath = toolOptions.xclbinFile; + options.kernelMode = toolOptions.kernelMode; + options.nameProj = toolOptions.nameProj; + options.alveoProject = toolOptions.alveoProject; + options.numDevices = toolOptions.numDevices; + options.deviceNames = toolOptions.deviceNames; + options.nodeId = 0; + + std::cout << "toolOptions.modeZmq=" << toolOptions.modeZmq << " toolOptions.nodeId=" << toolOptions.nodeId + << " toolOptions.numNodes=" << toolOptions.numNodes << std::endl; + + // create louvainMod object with internal "options". These options are common + // between partition and load/compute operations + LouvainPar louvainMod(options); + + switch (toolOptions.mode_alveo) { + case ALVEOAPI_PARTITION: // 1 + partOpts.BFS_partition = false; + partOpts.numPars = toolOptions.numPars; + partOpts.par_prune = toolOptions.gh_par; + louvainMod.partitionDataFile(toolOptions.opts_inFile, partOpts); + break; + case ALVEOAPI_PARTITION_BFS: // 2 + partOpts.BFS_partition = true; + partOpts.numPars = toolOptions.numPars; + partOpts.par_prune = toolOptions.gh_par; + louvainMod.partitionDataFile(toolOptions.opts_inFile, partOpts); + break; + // case ALVEOAPI_LOAD: // 3 + // std::cout << "ALVEOAPI_LOAD" << std::endl; + + // computeOpts.outputFile = toolOptions.outputFile; + // computeOpts.max_iter = toolOptions.max_iter; + // computeOpts.max_level = toolOptions.max_level; + // computeOpts.tolerance = toolOptions.threshold; + // computeOpts.intermediateResult = false; + // computeOpts.final_Q = true; + // computeOpts.all_Q = false; + + // finalQ = louvainMod.loadAlveoAndComputeLouvain(computeOpts); + // if (finalQ < -1) { + // std::cout << "ERROR: loadAlveoAndComputeLouvain completed with error. ErrorCode=" << finalQ << + // std::endl; + // status = -1; + // } else if (toolOptions.modeZmq == ZMQ_DRIVER) // only the driver reports the final modularity value + // std::cout << "INFO: loadAlveoAndComputeLouvain completed. finalQ=" << finalQ << std::endl; + // break; + case ALVEOAPI_RUN: // 3 + std::cout << "ALVEOAPI_RUN" << std::endl; + break; + default: + std::cout << "ERROR: Unknown tool mode " << toolOptions.mode_alveo << std::endl; + break; + } + return status; +} diff --git a/graph/L3/tests/louvainPartition/utils.mk b/graph/L3/tests/louvainPartition/utils.mk new file mode 100755 index 0000000000..b2cda39901 --- /dev/null +++ b/graph/L3/tests/louvainPartition/utils.mk @@ -0,0 +1,221 @@ +# +# Copyright 2019-2021 Xilinx, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#+------------------------------------------------------------------------------- +# The following parameters are assigned with default values. These parameters can +# be overridden through the make command line +#+------------------------------------------------------------------------------- + +REPORT := no +PROFILE := no +DEBUG := no + +#'estimate' for estimate report generation +#'system' for system report generation +ifneq ($(REPORT), no) +VPP_LDFLAGS += --report estimate +VPP_LDFLAGS += --report system +endif + +#Generates profile summary report +ifeq ($(PROFILE), yes) +VPP_LDFLAGS += --profile_kernel data:all:all:all +endif + +#Generates debug summary report +ifeq ($(DEBUG), yes) +VPP_LDFLAGS += --dk protocol:all:all:all +endif + +#Checks for XILINX_XRT +ifeq ($(HOST_ARCH), x86) +ifndef XILINX_XRT + XILINX_XRT = /opt/xilinx/xrt + export XILINX_XRT +endif +else +ifndef XILINX_VITIS + XILINX_VITIS = /opt/xilinx/Vitis/$(TOOL_VERSION) + export XILINX_VITIS +endif +endif + +#Checks for Device Family +ifeq ($(HOST_ARCH), aarch32) + DEV_FAM = 7Series +else ifeq ($(HOST_ARCH), aarch64) + DEV_FAM = Ultrascale +endif + +B_NAME = $(shell dirname $(XPLATFORM)) + +#Checks for Correct architecture +ifneq ($(HOST_ARCH), $(filter $(HOST_ARCH),aarch64 aarch32 x86)) +$(error HOST_ARCH variable not set, please set correctly and rerun) +endif + +#Checks for SYSROOT +check_sysroot: +ifneq ($(HOST_ARCH), x86) +ifndef SYSROOT + $(error SYSROOT ENV variable is not set, please set ENV variable correctly and rerun) +endif +endif + +check_version: +ifneq (, $(shell which git)) +ifneq (,$(wildcard $(XFLIB_DIR)/.git)) + @cd $(XFLIB_DIR) && git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -n 1 && cd - +endif +endif + +#Checks for g++ +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +ifeq ($(HOST_ARCH), x86) +ifneq ($(shell expr $(shell g++ -dumpversion) \>= 5), 1) +ifndef XILINX_VIVADO +$(error [ERROR]: g++ version too old. Please use 5.0 or above) +else +CXX := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/bin/g++ +ifeq ($(LD_LIBRARY_PATH),) +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64 +else +export LD_LIBRARY_PATH := $(XILINX_VIVADO)/tps/lnx64/gcc-6.2.0/lib64:$(LD_LIBRARY_PATH) +endif +$(warning [WARNING]: g++ version too old. Using g++ provided by the tool: $(CXX)) +endif +endif +else ifeq ($(HOST_ARCH), aarch64) +CXX := $(XILINX_VITIS)/gnu/aarch64/lin/aarch64-linux/bin/aarch64-linux-gnu-g++ +else ifeq ($(HOST_ARCH), aarch32) +CXX := $(XILINX_VITIS)/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-g++ +endif + +#Setting VPP +VPP := v++ + +#Cheks for aiecompiler + +.PHONY: check_vivado +check_vivado: +ifeq (,$(wildcard $(XILINX_VIVADO)/bin/vivado)) + @echo "Cannot locate Vivado installation. Please set XILINX_VIVADO variable." && false +endif + +.PHONY: check_vpp +check_vpp: +ifeq (,$(wildcard $(XILINX_VITIS)/bin/v++)) + @echo "Cannot locate Vitis installation. Please set XILINX_VITIS variable." && false +endif + +.PHONY: check_xrt +check_xrt: +ifeq ($(HOST_ARCH), x86) +ifeq (,$(wildcard $(XILINX_XRT)/lib/libxilinxopencl.so)) + @echo "Cannot locate XRT installation. Please set XILINX_XRT variable." && false +endif +endif + +export PATH := $(XILINX_VITIS)/bin:$(XILINX_XRT)/bin:$(PATH) +ifeq ($(HOST_ARCH), x86) +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(XILINX_XRT)/lib +else +LD_LIBRARY_PATH := $(XILINX_XRT)/lib:$(LD_LIBRARY_PATH) +endif +else # aarch64 +ifeq (,$(LD_LIBRARY_PATH)) +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib +else +LD_LIBRARY_PATH := $(SYSROOT)/usr/lib:$(LD_LIBRARY_PATH) +endif +endif + +# check target +ifeq ($(filter $(TARGET),sw_emu hw_emu hw),) +$(error TARGET is not sw_emu, hw_emu or hw) +endif + +ifneq (,$(wildcard $(DEVICE))) +# Use DEVICE as a file path +XPLATFORM := $(DEVICE) +else +# Use DEVICE as a file name pattern +# 1. search paths specified by variable +ifneq (,$(PLATFORM_REPO_PATHS)) +# 1.1 as exact name +XPLATFORM := $(strip $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/$(DEVICE)/$(DEVICE).xpfm))) +# 1.2 as a pattern +ifeq (,$(XPLATFORM)) +XPLATFORMS := $(foreach p, $(subst :, ,$(PLATFORM_REPO_PATHS)), $(wildcard $(p)/*/*.xpfm)) +XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) +endif # 1.2 +endif # 1 +# 2. search Vitis installation +ifeq (,$(XPLATFORM)) +# 2.1 as exact name +XPLATFORM := $(strip $(wildcard $(XILINX_VITIS)/platforms/$(DEVICE)/$(DEVICE).xpfm)) +# 2.2 as a pattern +ifeq (,$(XPLATFORM)) +XPLATFORMS := $(wildcard $(XILINX_VITIS)/platforms/*/*.xpfm) +XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) +endif # 2.2 +endif # 2 +# 3. search default locations +ifeq (,$(XPLATFORM)) +# 3.1 as exact name +XPLATFORM := $(strip $(wildcard /opt/xilinx/platforms/$(DEVICE)/$(DEVICE).xpfm)) +# 3.2 as a pattern +ifeq (,$(XPLATFORM)) +XPLATFORMS := $(wildcard /opt/xilinx/platforms/*/*.xpfm) +XPLATFORM := $(strip $(foreach p, $(XPLATFORMS), $(shell echo $(p) | awk '$$1 ~ /$(DEVICE)/'))) +endif # 3.2 +endif # 3 +endif + +define MSG_PLATFORM +No platform matched pattern '$(DEVICE)'. +Available platforms are: $(XPLATFORMS) +To add more platform directories, set the PLATFORM_REPO_PATHS variable or point DEVICE variable to the full path of platform .xpfm file. +endef +export MSG_PLATFORM + +define MSG_DEVICE +More than one platform matched: $(XPLATFORM) +Please set DEVICE variable more accurately to select only one platform file, or set DEVICE variable to the full path of the platform .xpfm file. +endef +export MSG_DEVICE + +.PHONY: check_platform +check_platform: +ifeq (,$(XPLATFORM)) + @echo "$${MSG_PLATFORM}" && false +endif +ifneq (,$(word 2,$(XPLATFORM))) + @echo "$${MSG_DEVICE}" && false +endif +#Check ends + +# device2xsa - create a filesystem friendly name from device name +# $(1) - full name of device +device2xsa = $(strip $(patsubst %.xpfm, % , $(shell basename $(DEVICE)))) + +# Cleaning stuff +RM = rm -f +RMDIR = rm -rf + +MV = mv -f +CP = cp -rf +ECHO:= @echo diff --git a/graph/L3/tests/pre_launch.sh b/graph/L3/tests/pre_launch.sh new file mode 100644 index 0000000000..6508533e5b --- /dev/null +++ b/graph/L3/tests/pre_launch.sh @@ -0,0 +1,2 @@ +#export PROJECTPATH=/../louvain_fast +export LD_LIBRARY_PATH=../../L3/lib:$LD_LIBRARY_PATH diff --git a/graph/docs/guide_L2/kernels/LouvainFast.rst b/graph/docs/guide_L2/kernels/LouvainFast.rst index 0fbc41e2ff..8cf5ceede7 100644 --- a/graph/docs/guide_L2/kernels/LouvainFast.rst +++ b/graph/docs/guide_L2/kernels/LouvainFast.rst @@ -22,6 +22,11 @@ Internal Design of Louvain Modularity Overview ======== The Louvain method for community detection is a method to extract communities from large networks created by Blondel from the University of Louvain (the source of this method's name). The method is a greedy optimization method that appears to run in time O(n \cdot log n), if n is the number of nodes in the network. +Since we release the louvain kernel on FPGA from 21.1, the performance of 1 compute unit in this kernel is improved from 18x, to 33x, to 65x vs CPU. +The latest design cloud achieve 2 compute units in u55c by Vitis 21.2, which means the max speed up by u55c cloud be 2*65x vs CPU. +Now the L2 API cloud achieve the entire graph louvain modularity directly. when the graph is less than 128M vertexes and 128M edges by 1 cu on u55c(64M is the limit by 1 cu on u50). +If the graph is larger, we should launch the L3 louvainPartition API, partition the graph to multi pieces, then run the L3 louvainRun API which cloud run louvain algorithm on multi cu on multi board by the support of xrm. +More details cloud be find in L3 API. Algorithm ============ diff --git a/graph/docs/guide_L2/manual/louvainFast.rst b/graph/docs/guide_L2/manual/louvainFast.rst index 936009440e..d7f223402a 100644 --- a/graph/docs/guide_L2/manual/louvainFast.rst +++ b/graph/docs/guide_L2/manual/louvainFast.rst @@ -38,7 +38,7 @@ Run the following make command to build your XCLBIN and host binary targeting a .. code-block:: bash - make run TARGET=hw DEVICE=xilinx_u50_gen3x16_xdma_201920_3 + make run TARGET=hw DEVICE=xilinx_u55c_gen3x16_xdma_2_202110_1 * **Run kernel(Step 3)** @@ -46,7 +46,7 @@ To get the benchmark results, please run the following command. .. code-block:: bash - ./build_dir.hw.xilinx_u50_gen3x16_xdma_201920_3/host.exe -x build_dir.hw.xilinx_u50_gen3x16_xdma_201920_3/kernel_louvain.xclbin -f 3 -c -o -m 10 -prun data/example-wt.txt + ./build_dir.hw.xilinx_u55c_gen3x16_xdma_2_202110_1/host.exe -x build_dir.hw.xilinx_u55c_gen3x16_xdma_2_202110_1/kernel_louvain.xclbin -f 3 -c -o -m 10 data/example-wt.txt -prun Louvain fast Input Arguments: @@ -109,7 +109,18 @@ Profiling The hardware resource utilizations are listed in the following table. Different tool versions may result slightly different resource. -.. table:: Table 1 Hardware resources for Louvain fast +.. table:: Table 1 Hardware resources for Louvain fast in u55c now in 21.2, higher frequency and lower resources. + :align: center + + +-------------------+----------+----------+----------+----------+---------+-----------------+ + | Kernel | BRAM | URAM | DSP | FF | LUT | Frequency(MHz) | + +-------------------+----------+----------+----------+----------+---------+-----------------+ + | kernel_louvain_0 | 150 | 208 | 118 | 169109 | 147344 | 214.1 | + +-------------------+----------+----------+----------+----------+---------+-----------------+ + | kernel_louvain_1 | 150 | 208 | 118 | 169109 | 147344 | 214.1 | + +-------------------+----------+----------+----------+----------+---------+-----------------+ + +.. table:: Table 2 Hardware resources for Louvain fast in u50 before 21.2 :align: center +-------------------+----------+----------+----------+----------+---------+-----------------+ @@ -119,7 +130,7 @@ Different tool versions may result slightly different resource. +-------------------+----------+----------+----------+----------+---------+-----------------+ -Table 2 Louvain FPGA acceleration benchmark +Table 3 Louvain FPGA acceleration benchmark by L2 .. image:: /images/louvainPerformace.PNG :alt: Performance of louvainPerformance @@ -128,14 +139,15 @@ Table 2 Louvain FPGA acceleration benchmark .. note:: - 1. 2 FPGA versions of kernel are used: - * Normal kernel : 18.1 X - * Prune kernel : 33.1 X without modularity loss VS. parallel Louvain on CPU + 1. 3 FPGA versions of kernel are used: + * Normal kernel : 18.1 X + * Prune kernel : 33.1 X without modularity loss VS. parallel Louvain on CPU + * Opt kernel in u55c : 65.6 X without modularity loss by just 1cu VS. parallel Louvain on CPU * the Latency time = CPU time + FPGA time 2. TigerGraph running on platform with Intel(R) Xeon(R) CPU E5-2640 v3 @2.60GHz, cache(20480 KB), cores(8). 3. Parallel Louvain running on Intel(R) Xeon(R) CPU E5-2690 v4 @ 2.60GHz, cache(35840 KB), cores(14). 4. time unit: second. - 5. FPGA platorm is Alveo u50 + 5. FPGA platorm is Alveo u50 for Prune kernel, Alveo u55c for 2cu opt kernel .. toctree:: :maxdepth: 1 diff --git a/graph/docs/guide_L3/L3_internal/getting_started.rst b/graph/docs/guide_L3/L3_internal/getting_started.rst index add70e327c..66f63b945d 100644 --- a/graph/docs/guide_L3/L3_internal/getting_started.rst +++ b/graph/docs/guide_L3/L3_internal/getting_started.rst @@ -35,6 +35,7 @@ Software Requirements Hardware Requirements ##################### * `Alveo U50 `_ +* `Alveo U55C `_ Environment Setup @@ -65,7 +66,11 @@ In order to build **libgraphL3.so**, please follow the following steps: .. code-block:: sh - cd xf_graph/L3/lib - ./build_so.sh + cd xf_graph/L3/lib + ./build_so.sh + cd xf_graph/L3/tests + ./pre_launch.sh After the build is complete, **libgraphL3.so** should be available in *Vitis_Libraries/graph/L3/lib* + + diff --git a/graph/docs/guide_L3/L3_internal/louvainPartition.rst b/graph/docs/guide_L3/L3_internal/louvainPartition.rst new file mode 100644 index 0000000000..b56c9a40d2 --- /dev/null +++ b/graph/docs/guide_L3/L3_internal/louvainPartition.rst @@ -0,0 +1,82 @@ +.. + Copyright 2021 Xilinx, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +******************************** +Louvain Paritition Demo +******************************** + +To get scalability for graph size and get high-level concurrency for multi compute units on multi boards, we provided louvainPartition API with two partition methods which no communication between subgraphs processing. + +* Linear louvain partition mothed, simply dived vertexes linearly, and save the connection edges between subgraphs to ghost edges. So it is faster in low bandwidth graph but result more ghost edges. +* BFS louvain partition mothed, dived vertexes by BFS method, and save the connection edges between subgraphs to ghost edges. Its performance of modularity result keeps the same level between high and low bandwidth input graph. + +Linear partition achieve on the high bandwidth and low bandwidth graph is shown as the Figure 1. Linear partition is not suitable for High bandwidth graph. + +.. image:: /images/louvainlinearpartition.PNG + :alt: Figure 1 Linear partition achieve on the high bandwidth and low bandwidth graph + :width: 80% + :align: center + +In this demo, two methods can be switched by corresponding commands. The comparison of input and output is shown as the table 1. + +.. table:: Table 1 input and output comparison for different partition algorithms + :align: center + + +-------------------+----------------------------+---------------------------------+ + | | Linear paritition | BFS partition | + +-------------------+----------------------------+---------------------------------+ + | input graph | *.mtx, *.txt ... | *.mtx, *.txt ... | + +-------------------+----------------------------+---------------------------------+ + | input commend | -create_alveo_partitions | -create_alveo_BFS_partitions | + +-------------------+----------------------------+---------------------------------+ + | output project | name.par.proj | name.par.proj | + +-------------------+----------------------------+---------------------------------+ + | output header file| *.par.src, *.par.parlv | *.par.src, *.par.parlv *.bfs.adj| + +-------------------+----------------------------+---------------------------------+ + | output subgraph | name_000.par ... | name_000.par ... | + +-------------------+----------------------------+---------------------------------+ + +Linear Louvain Partition Flow +########################################## + +Ensure run the script L3/tests/pre_launch.sh to set the path of libgraphL3.so + +.. code-block:: sh + + cd L3/tests/louvainPartition + make host + ./build_dir.sw_emu.xilinx_u55c_gen3x16_xdma_2_202110_1/host.exe ./data/example-wt.txt -kernel_mode 2 -num_pars 2 -create_alveo_partitions -name example_tx + +Louvain fast Input Arguments: + +.. code-block:: sh + + Usage: host.exe -[-kernel_mode -num_pars -create_alveo_partitions -create_alveo_BFS_partitions -name] + -kernel_mode: the kernel mode : 1 is u50 1 cu, 2 is u55c 2cu parallel launch in louvainRunSubGraph + -num_pars: partition number : 2~n + -create_alveo_partitions: Linear partition flow + -create_alveo_BFS_partitions: BFS partition flow + -name: name of subgraph : name + +BFS Louvain Partition Flow +########################################## + +Ensure run the script L3/tests/pre_launch.sh to set the path of libgraphL3.so + +.. code-block:: sh + + cd L3/tests/louvainPartition + make host + ./build_dir.sw_emu.xilinx_u55c_gen3x16_xdma_2_202110_1/host.exe ./data/example-wt.txt -kernel_mode 2 -num_pars 2 -create_alveo_BFS_partitions -name example_tx diff --git a/graph/docs/guide_L3/L3_internal/louvainRun.rst b/graph/docs/guide_L3/L3_internal/louvainRun.rst new file mode 100644 index 0000000000..5295ac7a52 --- /dev/null +++ b/graph/docs/guide_L3/L3_internal/louvainRun.rst @@ -0,0 +1,67 @@ +.. + Copyright 2021 Xilinx, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +******************************** +Louvain Modularity Launch Demo +******************************** + +To load and launch louvain Modularity for multi compute units on multi boards, we provided louvainRun API with two kernel modes which command is -kernel_mode. + +* LOUVAINMOD_PRUNING_KERNEL, -kernel_mode 1, launch the pre-build L2 u50 1 cu kernel on multi boards. +* LOUVAINMOD_2CU_U55C_KERNEL, -kernel_mode 2, launch the pre-build L2 u55c 2 cu kernel on multi boards parallelly. + +Launch u50 Flow +##################### + +Ensure run the script L3/tests/pre_launch.sh to set the path of libgraphL3.so +Ensure export the right $(PROJECTPATH) for the L2 pre-build U50 xclbin path, this xclbin may need 777 permission by xrm. + +.. code-block:: sh + + cd L3/tests/louvainRun + make host + ./build_dir.sw_emu.xilinx_u50_gen3x16_xdma_201920_3/host.exe -x $(PROJECTPATH)/build_dir.sw_emu.xilinx_u50_gen3x16_xdma_201920_3/kernel_louvain.xclbin -kernel_mode 1 -num_devices 1 -devices xilinx_u50_gen3x16_xdma_201920_3 -num_level 100 -num_iter 100 -load_alveo_partitions ../louvainPartition/example_tx.par.proj -setwkr 0 -driverAlone + +Louvain fast Input Arguments: + +.. code-block:: sh + + Usage: host.exe -[-kernel_mode -x -num_devices -devices -num_level -num_iter -load_alveo_partitions -setwkr -driverAlone] + -kernel_mode: the kernel mode : 1 is u50 1 cu, 2 is for u55c 2cu parallel launch in louvainRunSubGraph + -x: path of the xclbin : path + -num_devices: the number of boards : 1~n + -devices: the shell name of device : xilinx_u50_gen3x16_xdma_201920_3 xilinx_u55c_gen3x16_xdma_base_2 + -num_level: the max number of level or phase the louvain modularity : 1~n + -num_iter: the max number of iteration the louvain modularity :1~n + -load_alveo_partitions: the project to be load : *.par.proj + -setwkr the number Client nodes in CS modes, currently is 0 : 0 + -driverAlone only use the Server node in CS modes. + +Launch u55c Flow +##################### + +Ensure run the script L3/tests/pre_launch.sh to set the path of libgraphL3.so +Ensure export the right $(PROJECTPATH) for the L2 pre-build U55C xclbin path, this xclbin may need 777 permission by xrm. + +.. code-block:: sh + + cd L3/tests/louvainRun + make host + ./build_dir.sw_emu.xilinx_u55c_gen3x16_xdma_base_2/host.exe -x $(PROJECTPATH)/build_dir.sw_emu.xilinx_u55c_gen3x16_xdma_base_2/kernel_louvain.xclbin -kernel_mode 2 -num_devices 1 -devices xilinx_u55c_gen3x16_xdma_base_2 -num_level 100 -num_iter 100 -load_alveo_partitions ../louvainPartition/example_tx.par.proj -setwkr 0 -driverAlone + + + + + diff --git a/graph/docs/guide_L3/utilization_L3.rst b/graph/docs/guide_L3/utilization_L3.rst index 0a41a9d723..9f0360c426 100644 --- a/graph/docs/guide_L3/utilization_L3.rst +++ b/graph/docs/guide_L3/utilization_L3.rst @@ -29,9 +29,14 @@ The graph L3 layer provides an asynchronous and easy-to-integrate framework. By .. toctree:: - :maxdepth: 1 + :maxdepth: 4 L3_internal/getting_started.rst L3_internal/user_model.rst + L3_internal/louvainPartition.rst + L3_internal/louvainRun.rst + + + diff --git a/graph/docs/images/louvainPerformace.PNG b/graph/docs/images/louvainPerformace.PNG index b9cd6fd778..678d369506 100644 Binary files a/graph/docs/images/louvainPerformace.PNG and b/graph/docs/images/louvainPerformace.PNG differ diff --git a/graph/docs/images/louvainlinearpartition.PNG b/graph/docs/images/louvainlinearpartition.PNG new file mode 100644 index 0000000000..84ba5a8b1f Binary files /dev/null and b/graph/docs/images/louvainlinearpartition.PNG differ diff --git a/graph/docs/index.rst b/graph/docs/index.rst index 212b0b7d7d..7f77a82e66 100644 --- a/graph/docs/index.rst +++ b/graph/docs/index.rst @@ -83,7 +83,7 @@ Otherwise, full path to .xpfm file needs to be provided via ``DEVICE`` variable. .. toctree:: :caption: L3 User Guide - :maxdepth: 3 + :maxdepth: 4 guide_L3/utilization_L3.rst diff --git a/security/Jenkinsfile b/security/Jenkinsfile index 08b20497fd..bba6c04870 100644 --- a/security/Jenkinsfile +++ b/security/Jenkinsfile @@ -1,4 +1,4 @@ @Library('pipeline-library')_ -VitisLibPipeline (branch: 'next', libname: 'xf_security', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', - upstream_dependencies: 'xf_utils_hw,next,../utils', - email: 'tuol@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_stable_latest') +VitisLibPipeline (branch: 'master', libname: 'xf_security', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', + upstream_dependencies: 'xf_utils_hw,master,../utils', + email: 'tuol@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_released') diff --git a/security/README.md b/security/README.md index d7b5a11660..1a93b4c0f0 100644 --- a/security/README.md +++ b/security/README.md @@ -165,7 +165,7 @@ Recommended design flows are decribed as follows: L1 provides the basic primitives which cover the most common algorithms in security. -The recommend flow to evaluate and test L1 components is described as follows using Vivado HLS tool. +The recommend flow to evaluate and test L1 components is described as follows using Vitis HLS tool. A top level C/C++ testbench (typically `algorithm_name.cpp`) prepares the input data, passes them to the design under test, then performs any output data post processing and validation checks. A Makefile is used to drive this flow with available steps including `CSIM` (high level simulation), `CSYNTH` (high level synthesis to RTL) and `COSIM` (cosimulation between software testbench and generated RTL), `VIVADO_SYN` (synthesis by Vivado), `VIVADO_IMPL` (implementation by Vivado). The flow is launched from the shell by calling `make` with variables set as in the example below: diff --git a/security/docs/index.rst b/security/docs/index.rst index 252f817a9d..884628a7c4 100644 --- a/security/docs/index.rst +++ b/security/docs/index.rst @@ -266,7 +266,7 @@ L1 L1 provides the basic primitives which cover the most common algorithms in security. -The recommend flow to evaluate and test L1 components is described as follows using Vivado HLS tool. +The recommend flow to evaluate and test L1 components is described as follows using Vitis HLS tool. A top level C/C++ testbench (typically `algorithm_name.cpp`) prepares the input data, passes them to the design under test, then performs any output data post processing and validation checks. A Makefile is used to drive this flow with available steps including `CSIM` (high level simulation), `CSYNTH` (high level synthesis to RTL) and `COSIM` (cosimulation between software testbench and generated RTL), `VIVADO_SYN` (synthesis by Vivado), `VIVADO_IMPL` (implementation by Vivado). The flow is launched from the shell by calling `make` with variables set as in the example below: diff --git a/solver/Jenkinsfile b/solver/Jenkinsfile index 50fc1f0936..7c2aa90390 100644 --- a/solver/Jenkinsfile +++ b/solver/Jenkinsfile @@ -1,5 +1,5 @@ @Library('pipeline-library')_ -VitisLibPipeline (branch: 'next', libname: 'xf_solver', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', - upstream_dependencies: 'xf_utils_hw,next,../utils', - email: 'tuol@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_stable_latest') +VitisLibPipeline (branch: 'master', libname: 'xf_solver', TARGETS: 'hls_csim:hls_csynth:hls_cosim:vitis_sw_emu:vitis_hw_emu:vitis_hw_build', + upstream_dependencies: 'xf_utils_hw,master,../utils', + email: 'tuol@xilinx.com', devtest: 'RunDeploy.sh', TOOLVERSION: '2021.2_released') diff --git a/solver/L1/include/hw/qrf.hpp b/solver/L1/include/hw/qrf.hpp new file mode 100644 index 0000000000..2b5b2e5ac0 --- /dev/null +++ b/solver/L1/include/hw/qrf.hpp @@ -0,0 +1,765 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file qrf.hpp + * @brief This files contains implentation of QRF functions + * - QRF : Entry point function + * - QRF_TOP : Top level function that selects implementation architecture and internal types based on a + * traits class. + * - QRF_BASIC : Basic implementation requiring lower resource + * - QRF_ALT : Optimized for throughput requiring more resources + */ + +#ifndef _XF_SOLVER_QRF_HPP_ +#define _XF_SOLVER_QRF_HPP_ + +#include "utils/x_matrix_utils.hpp" +#include "hls_x_complex.h" +#include "utils/std_complex_utils.h" +#include "hls_stream.h" +#ifndef __SYNTHESIS__ +#include +#endif +#include +#include "hls_math.h" + +namespace xf { +namespace solver { + +// =================================================================================================================== +// Traits struct defining architecture selection +struct qrfTraits { + static const int ARCH = 1; // Select implementation. 0=Basic. 1=Lower latency/thoughput architecture. + static const int CALC_ROT_II = 1; // Specify the rotation calculation loop target II of the QRF_ALT architecture(1) + static const int UPDATE_II = 4; // Specify the pipelining target for the Q & R update loops + static const int UNROLL_FACTOR = + 1; // Specify the unrolling factor for Q & R update loops of the QRF_ALT architecture(1) +}; + +struct DEFAULT_QRF_TRAITS : qrfTraits {}; + +// =================================================================================================================== +// Helper functions +template +struct is_cmplx { + static const bool value = 0; +}; + +template +struct is_cmplx > { + static const bool value = 1; +}; + +template +int qrf_require_extra_pass(const int rows, const int cols, T x) { +qrf_require_extra_pass_real:; + return 0; +} + +template +int qrf_require_extra_pass(const int rows, const int cols, hls::x_complex x) { +qrf_require_extra_pass_complex:; + if (rows == cols) { + // Unitary transformation only required for square matrices + return 1; + } else { + return 0; + } +} + +template +bool is_zero(T a) { + return a == 0; +} +template <> +bool is_zero(float a) { + union single_cast v; + union single_cast zero_p; + union single_cast zero_n; + v.f = a; + zero_p.f = +0.0f; + zero_n.f = -0.0f; + return (v.i == zero_p.i || v.i == zero_n.i); +} +template <> +bool is_zero(double a) { + union double_cast v; + union double_cast zero_p; + union double_cast zero_n; + v.d = a; + zero_p.d = +0.0f; + zero_n.d = -0.0f; + return (v.i == zero_p.i || v.i == zero_n.i); +} + +// Vector multiply +template +T qrf_vm(T a, T b, T c, T d) { + return a * c + b * d; +} + +// Matrix-vector multiply +template +void qrf_mm(const T G[2][2], T& a, T& b) { + T x, y; + x = qrf_vm(G[0][0], G[0][1], a, b); + y = qrf_vm(G[1][0], G[1][1], a, b); + a = x; + b = y; +} + +// +template +void qrf_mm_or_mag(const T G[2][2], T& a, T& b, const T mag, const int use_mag, const int extra_pass) { + T x, y; + x = qrf_vm(G[0][0], G[0][1], a, b); + y = qrf_vm(G[1][0], G[1][1], a, b); + if (use_mag == 0) { + a = x; + b = y; + } else { + if (extra_pass == 1) { + // a = a; + b = hls::x_real(mag); + } else { + a = hls::x_real(mag); + b = 0; + } + } +} + +// Magnitude computation for real Givens rotation, guarding against under-/overflow +// - Returns real-valued magnitude +template +T qrf_magnitude(T a, T b) { +Function_qrf_magnitude_real:; + const T ONE = 1.0; + const T ZERO = 0.0; + T abs_a, abs_b; + T y, mag; + + abs_a = hls::abs(a); // declared in x_hls_utils.h + abs_b = hls::abs(b); + if (abs_a > abs_b) { + y = b / a; + mag = a * x_sqrt(ONE + y * y); + + } else if (abs_b == ZERO) { + mag = ZERO; + } else { + y = a / b; + mag = b * x_sqrt(ONE + y * y); + } + return mag; +} + +// Magnitude computation for complex Givens rotation, avoiding squaring values which have just been square-rooted +// and guarding against under-/overflow +// - Returns real-valued magnitude +template +T qrf_magnitude(hls::x_complex a, hls::x_complex b) { +Function_qrf_magnitude_complex:; + + const T ONE = 1.0; + const T ZERO = 0.0; + T ar, ai, br, bi, d1, d2, d3, d3a, d3b, x1, x2, x3; + T a_largest, b_largest, largest; + ar = hls::abs(a.real()); + ai = hls::abs(a.imag()); + br = hls::abs(b.real()); + bi = hls::abs(b.imag()); + + // Lower latency, builds tree structures. + if (ar > ai && ar > br && ar > bi) { + largest = ar; + d1 = ai; + d2 = br; + d3 = bi; + } else if (ai > ar && ai > br && ai > bi) { + largest = ai; + d1 = ar; + d2 = br; + d3 = bi; + } else if (br > ar && br > ai && br > bi) { + largest = br; + d1 = ar; + d2 = ai; + d3 = bi; + } else { + largest = bi; + d1 = ar; + d2 = ai; + d3 = br; + } + + if (largest == ZERO) { // Avoid divide-by-zero + return ZERO; + } else { + x1 = d1 / largest; + x2 = d2 / largest; + x3 = d3 / largest; + T x1_sqd = x1 * x1; + T x2_sqd = x2 * x2; + T x3_sqd = x3 * x3; + + T s1 = ONE + x1_sqd; + T s2 = x2_sqd + x3_sqd; + T s3 = s1 + s2; + + return largest * x_sqrt(s3); + } +} + +// =================================================================================================================== +// Real Givens rotation guarding against under-/overflow situations. +// +// Returns matrix G = | c s | +// | ss cc | +// +// Note: argument 'extra_pass' is not used for the real case, but is present only to permit function overloading +// +template +void qrf_givens(int extra_pass, T a, T b, T& c, T& s, T& ss, T& cc, T& r) { +Function_qrf_givens_real:; + const T ONE = 1.0; + const T ZERO = 0.0; + T mag; + + mag = qrf_magnitude(a, b); + + if (hls::abs(a) == ZERO && hls::abs(b) == ZERO) { // more efficient than "if (mag == ZERO)" + c = x_copysign(ONE, a); + s = ZERO; + } else { + c = a / mag; + s = b / mag; + } + cc = c; + ss = -s; + + r = mag; +} + +// =================================================================================================================== +// Complex Givens rotation +// +// This implements a modified Givens rotation of the form: +// +// G = | c* s* | +// | -s c | +// +// to produce real diagonal elements suitable for subsquent computation of the inverse of input matrix A. +// +// Returns matrix G = | c s | +// | ss cc | +// +// This implementation does not use the same approach as the version of qrf_givens() for real data, as that +// would require that a divider for complex data be implemented, which is expensive. +// +// When argument 'extra_pass' is set to 1, the function computes a unitary transformation rather than a standard Givens +// matrix. +// This is required to ensure that the bottom-rightmost element of the R matrix is real. This transformation matrix has +// the form: +// +// G(trans) = | 1 0 | +// | 0 e^-j*T | +// where T = Theta for the bottom-rightmost element +// +template +void qrf_givens(int extra_pass, + hls::x_complex a, + hls::x_complex b, + hls::x_complex& c, + hls::x_complex& s, + hls::x_complex& ss, + hls::x_complex& cc, + hls::x_complex& r) { +Function_qrf_givens_complex:; + const T ONE = 1.0; + const T ZERO = 0.0; + const hls::x_complex CZERO = ZERO; + T sqrt_mag_a_mag_b; + hls::x_complex c_tmp, s_tmp; + + if (extra_pass == 0) { + // Standard modified Givens matrix, guarding against over-/underflow + sqrt_mag_a_mag_b = qrf_magnitude(a, b); + if (is_zero(hls::abs(a.real())) && is_zero(hls::abs(a.imag())) && is_zero(hls::abs(b.real())) && + is_zero(hls::abs(b.imag()))) { // more efficient than "if (sqrt_mag_a_mag_b == ZERO)" + c_tmp = x_copysign(ONE, a.real()); + s_tmp = ZERO; + } else { + c_tmp = a / sqrt_mag_a_mag_b; + s_tmp = b / sqrt_mag_a_mag_b; + } + c = hls::x_conj(c_tmp); + cc = c_tmp; + s = hls::x_conj(s_tmp); + ss = -s_tmp; + + r.real() = sqrt_mag_a_mag_b; + } else { + // Transformation matrix to ensure real diagonal in R, guarding against over-/underflow + sqrt_mag_a_mag_b = qrf_magnitude(CZERO, b); + + c_tmp = ONE; + + if (hls::abs(b.real()) == ZERO && + hls::abs(b.imag()) == ZERO) { // more efficient than "if (sqrt_mag_a_mag_b == ZERO)" + s_tmp = ONE; + } else { + s_tmp = b / sqrt_mag_a_mag_b; + } + + c = c_tmp; + cc = hls::x_conj(s_tmp); + s = ZERO; + ss = ZERO; + r.real() = sqrt_mag_a_mag_b; + } +} + +// =================================================================================================================== +// Configuration class for QRF_ALT implementation +// o Determines the ROM content for the address sequence used to zero the array elements plus the number and size of +// the batches pushed through the inner loop. The batches consist of independent address accesses. +// o Initially calculates a static constant batch estimate which is used to size the look up tables. +// o Then an accurate batch count is generated by calculating the actually processing sequence. +template +struct qrf_alt_config { + // Catch for div by 0 and ensure we infer a ROM for the lookup arrays + static const int ROWS_INT = (ROWS < 5 ? 5 : ROWS); + static const int COLS_INT = (COLS < 5 ? 5 : COLS); + + // Intermediate values used to calculate NUM_BATCHES_EST for rectangular cases + static const int SEQ_LEN_FULL_SQ = (ROWS_INT * (ROWS_INT - 1) / 2); + static const int NUM_BATCHES_FULL_SQ_EST = SEQ_LEN_FULL_SQ * 4 / ROWS_INT; + static const int NUM_BATCHES_RECT_EST = NUM_BATCHES_FULL_SQ_EST - (ROWS_INT - COLS_INT) - (ROWS_INT / COLS_INT); + + // Triangle + square + static const int SEQUENCE_LENGTH = (COLS_INT * (COLS_INT - 1) / 2) + ((ROWS - COLS) * COLS) + + (is_cmplx::value && ROWS_INT == COLS_INT ? 1 : 0); + static const int NUM_BATCHES_EST = (ROWS_INT == COLS_INT ? SEQUENCE_LENGTH * 4 / COLS_INT : NUM_BATCHES_RECT_EST); + + // Actual number of batches calculated in the constructor + int NUM_BATCHES; + // SEQUENCE & BATCH_CNTS should implement as roms. + int BATCH_CNTS[NUM_BATCHES_EST]; + int SEQUENCE[SEQUENCE_LENGTH][3]; + + qrf_alt_config() { + int available[SEQUENCE_LENGTH][COLS]; + int available_cnt[COLS]; + int available_first[COLS]; + int available_last[COLS]; + int zeroed[COLS]; + int a, b, num_avail, tmp; + int cnt = 0; // Counts how many pairs we process in a batch + int seq_cnt = 0; + int actual_num_batches; + + // Initialize first column and counters + init_indices: + for (int row = 0; row < ROWS; row++) { + available[row][0] = row; + } + init_counts: + for (int col = 0; col < COLS; col++) { + if (col == 0) { + available_cnt[col] = ROWS; + available_last[col] = ROWS; + } else { + available_cnt[col] = 0; + available_last[col] = 0; + } + available_first[col] = 0; + zeroed[col] = 0; + } + // Increment through the processing sequence + NUM_BATCHES = 0; // Set to zero so we can test if we've completed within the estimate + px: + for (int batch_num = 0; batch_num < NUM_BATCHES_EST; batch_num++) { + cnt = 0; + check_col_indices: + for (int col = COLS - 1; col >= 0; col--) { + num_avail = available_cnt[col]; + if (num_avail > 1) { + read_indices: + for (int rows = 0; rows < num_avail / 2; rows++) { + if (rows < num_avail / 2) { + a = available[available_first[col]][col]; + available_first[col]++; + b = available[available_first[col]][col]; + available_first[col]++; + available_cnt[col] = available_cnt[col] - 2; + if (b < a) { + tmp = a; + a = b; + b = tmp; + } + // a & b are the row indexes we read from the memory for this rotation + SEQUENCE[seq_cnt][0] = a; + SEQUENCE[seq_cnt][1] = b; + SEQUENCE[seq_cnt][2] = col; + seq_cnt++; + cnt++; + available[available_last[col]][col] = a; // Non-zeroed element so store again + available_cnt[col]++; + available_last[col]++; + zeroed[col]++; + if (col < COLS - 1) { + available[available_last[col + 1]][col + 1] = + b; // Zeroed, row available to the next column + available_cnt[col + 1]++; + available_last[col + 1]++; + } + } + } + } + } + BATCH_CNTS[batch_num] = cnt; + // Check for end condition + if ((ROWS == COLS && zeroed[COLS - 2] == 1) || (ROWS > COLS && zeroed[COLS - 1] == ROWS - COLS)) { + NUM_BATCHES = batch_num + 1; + if (is_cmplx::value && ROWS == COLS) { + // Add an extra rotation to ensure last element on the diagonal is real + NUM_BATCHES = batch_num + 2; + BATCH_CNTS[batch_num + 1] = 1; + SEQUENCE[seq_cnt][0] = ROWS - 2; + SEQUENCE[seq_cnt][1] = ROWS - 1; + SEQUENCE[seq_cnt][2] = ROWS - 1; + } + break; + } + } + if (NUM_BATCHES == 0) { +#ifndef __SYNTHESIS__ + printf( + "ERROR: hls_qrf.h: qrf_alt_config: ERROR: NUM_BATCHES_EST count reached without completing the " + "processing sequence. Increase the NUM_BATCHES_EST value.\n"); + exit(1); +#endif + } + }; +}; + +// =================================================================================================================== +// QRF_BASIC +template +void qrf_basic(hls::stream& matrixAStrm, + hls::stream& matrixQStrm, + hls::stream& matrixRStrm) { + // Verify that template parameters are correct in simulation + if (RowsA < ColsA) { +#ifndef __SYNTHESIS__ + printf( + "ERROR: hls_qrf.h: Template parameter error - RowsA must be greater than ColsA; currently RowsA = %d ColsA " + "= %d\n", + RowsA, ColsA); +#endif + exit(1); + } + + // Buffers + OutputType Qi[RowsA][RowsA]; + OutputType Ri[RowsA][ColsA]; + OutputType G[2][2]; + + // Magnitude from Givens computation + OutputType mag = 0; + + // Flags for complex-valued case + const int DO_UNITARY_TF = qrf_require_extra_pass(RowsA, ColsA, mag); + int extra_pass = 0; + +// Initialize Qi and initialize/load Ri +qrf_in_row_assign: + for (int r = 0; r < RowsA; r++) { + qrf_in_col_assign_Qi: + for (int c = 0; c < RowsA; c++) { +#pragma HLS PIPELINE + if (r == c) { + Qi[r][c] = 1.0; + } else { + Qi[r][c] = 0.0; + } + } + qrf_in_col_assign_Ri: + for (int c = 0; c < ColsA; c++) { +#pragma HLS PIPELINE + Ri[r][c] = matrixAStrm.read(); + } + } + +qrf_col_loop: + for (int j = 0; j < ColsA; j++) { + // For complex data and square matrices, we perform an additional pass to ensure that the diagonal of R is real + // For non-square matrices, the modified Givens rotation ensures that the diagonal will be real-valued + if (DO_UNITARY_TF == 1) { + if (j == ColsA - 1) { + extra_pass = 1; + } else { + extra_pass = 0; + } + } else { + extra_pass = 0; + } + qrf_row_loop: + for (int i = RowsA - 1; i > 0; i--) { + if (i <= j - extra_pass) { + continue; + } else { + // Compute Givens values + qrf_givens(extra_pass, Ri[i - 1][j], Ri[i][j], G[0][0], G[0][1], G[1][0], G[1][1], mag); + + if (!extra_pass) { + Ri[i - 1][j] = hls::x_real(mag); + } else { + Ri[i][j] = hls::x_real(mag); + } + + qrf_r_update: + for (int k = 0; k < ColsA; k++) { +#pragma HLS PIPELINE II = QRF_TRAITS::UPDATE_II + if (k < j + 1) { + continue; + } else { + qrf_mm(G, Ri[i - 1][k], Ri[i][k]); + } + } + qrf_q_update: + for (int k = 0; k < RowsA; k++) { +#pragma HLS PIPELINE II = QRF_TRAITS::UPDATE_II + if (k < (i - (1 + j) + extra_pass)) { + continue; + } else { + qrf_mm(G, Qi[i - 1][k], Qi[i][k]); + } + } + } // end if i<=j + } // end qrf_row_loop + } // end qrf_col_loop + +// Assign final outputs +qrf_out_row_assign: + for (int r = 0; r < RowsA; r++) { + qrf_out_col_assign: + for (int c = 0; c < RowsA; c++) { +#pragma HLS PIPELINE + if (TransposedQ == true) { + matrixQStrm.write(Qi[r][c]); + } else { + matrixQStrm.write(hls::x_conj(Qi[c][r])); + } + + if (c < ColsA) { + matrixRStrm.write(Ri[r][c]); + } + } + } +} // end template qrf_basic + +// =================================================================================================================== +// QRF_ALT: Optimized for throughput. +template +void qrf_alt(hls::stream& matrixAStrm, + hls::stream& matrixQStrm, + hls::stream& matrixRStrm) { + // Verify that template parameters are correct in simulation + if (RowsA < ColsA) { + exit(1); + } + + // Declare the ROMs defining the processing sequence + static const qrf_alt_config CONFIG; + + // Internal array memories + // IMPLEMENTATION TIP: To further increase the throughput of the function partion the q_i and r_i arrays on the + // column + // dimension and unroll the update_r/q loops by the same amount. + OutputType q_i[RowsA][RowsA]; + OutputType r_i[RowsA][ColsA]; + +#pragma HLS ARRAY_PARTITION variable = q_i cyclic dim = 2 factor = QRF_TRAITS::UNROLL_FACTOR +#pragma HLS ARRAY_PARTITION variable = r_i cyclic dim = 2 factor = QRF_TRAITS::UNROLL_FACTOR + + hls::stream to_rot[3]; +#pragma HLS STREAM variable = to_rot depth = RowsA / 2 + int seq_cnt = 0; + int extra_pass = 0; + int extra_pass2 = 0; + int use_mag = 0; + int px_row1, px_row2, px_col, rot_row1, rot_row2, rot_col; + OutputType G[2][2]; + OutputType mag = 0; + hls::stream rotations[5]; +#pragma HLS STREAM variable = rotations depth = RowsA / 2 + OutputType G_delay[2][2]; + OutputType mag_delay; + +// Copy input data to local R memory and initialize Q +row_copy: + for (int r = 0; r < RowsA; r++) { +// Merge loops to parallelize the A input read and the Q matrix prime. +#pragma HLS LOOP_MERGE force + col_copy_q_i: + for (int c = 0; c < RowsA; c++) { +#pragma HLS PIPELINE + if (r == c) { + q_i[r][c] = 1.0; + } else { + q_i[r][c] = 0.0; + } + } + col_copy_r_i: + for (int c = 0; c < ColsA; c++) { +#pragma HLS PIPELINE + r_i[r][c] = matrixAStrm.read(); + } + } + +// Process R in batches of non-dependent array elements +px: + for (int batch_num = 0; batch_num < CONFIG.NUM_BATCHES; batch_num++) { + calc_rotations: + for (int px_cnt = 0; px_cnt < CONFIG.BATCH_CNTS[batch_num]; px_cnt++) { +#pragma HLS LOOP_TRIPCOUNT min = 1 max = RowsA / 2 +#pragma HLS PIPELINE II = QRF_TRAITS::CALC_ROT_II + px_row1 = CONFIG.SEQUENCE[seq_cnt][0]; + px_row2 = CONFIG.SEQUENCE[seq_cnt][1]; + px_col = CONFIG.SEQUENCE[seq_cnt][2]; + seq_cnt++; + extra_pass = 0; + if (is_cmplx::value && RowsA == ColsA && batch_num == CONFIG.NUM_BATCHES - 1) { + extra_pass = 1; + } + qrf_givens(extra_pass, r_i[px_row1][px_col], r_i[px_row2][px_col], G[0][0], G[0][1], G[1][0], G[1][1], mag); + // Pass on rotation to next block to apply rotations + rotations[0].write(G[0][0]); + rotations[1].write(G[0][1]); + rotations[2].write(G[1][0]); + rotations[3].write(G[1][1]); + rotations[4].write(mag); + to_rot[0].write(px_row1); + to_rot[1].write(px_row2); + to_rot[2].write(px_col); + } + + rotate: + for (int px_cnt = 0; px_cnt < CONFIG.BATCH_CNTS[batch_num]; px_cnt++) { +#pragma HLS LOOP_TRIPCOUNT min = 1 max = RowsA / 2 + G_delay[0][0] = rotations[0].read(); + G_delay[0][1] = rotations[1].read(); + G_delay[1][0] = rotations[2].read(); + G_delay[1][1] = rotations[3].read(); + mag_delay = rotations[4].read(); + rot_row1 = to_rot[0].read(); + rot_row2 = to_rot[1].read(); + rot_col = to_rot[2].read(); + + extra_pass2 = 0; + if (is_cmplx::value && RowsA == ColsA && batch_num == CONFIG.NUM_BATCHES - 1) { + extra_pass2 = 1; + } + +// Merge the loops to maximize throughput, otherwise HLS will execute them sequentially and +// share hardware. +#pragma HLS LOOP_MERGE force + update_r: + for (int k = 0; k < ColsA; k++) { +#pragma HLS PIPELINE II = QRF_TRAITS::UPDATE_II +#pragma HLS UNROLL FACTOR = QRF_TRAITS::UNROLL_FACTOR + use_mag = 0; + if (k == rot_col) { + use_mag = 1; + } + qrf_mm_or_mag(G_delay, r_i[rot_row1][k], r_i[rot_row2][k], mag_delay, use_mag, extra_pass2); + } + update_q: + for (int k = 0; k < RowsA; k++) { +#pragma HLS PIPELINE II = QRF_TRAITS::UPDATE_II +#pragma HLS UNROLL FACTOR = QRF_TRAITS::UNROLL_FACTOR + qrf_mm(G_delay, q_i[rot_row1][k], q_i[rot_row2][k]); + } + } + } + +// Assign final outputs +row_assign_loop: + for (int r = 0; r < RowsA; r++) { +// Merge loops to parallelize the Q and R writes +#pragma HLS LOOP_MERGE force + col_assign_loop: + for (int c = 0; c < RowsA; c++) { +#pragma HLS PIPELINE + if (TransposedQ == true) { + matrixQStrm.write(q_i[r][c]); + } else { + matrixQStrm.write(hls::x_conj(q_i[c][r])); + } + + if (c < ColsA) { + matrixRStrm.write(r_i[r][c]); + } + } + } + +} // end qrf_alt + +/** + * @brief QRF, to computes the full QR factorization (QR decomposition) of input matrix A, A=QR, producing orthogonal + * output matrix Q and upper-triangular matrix R. + * + * @tparam TransposedQ Selects whether Q is output in transposed form + * @tparam RowsA Number of rows in input matrix A + * @tparam ColsA Number of columns in input matrix A + * @tparam InputType Input data type + * @tparam OutputType Output data type + * @tparam QRF_TRAITS qrfTraits type with specified values + * + * @param A Input matrix + * @param Q Orthogonal output matrix + * @param R Upper triangular output matrix + */ +template +void qrf(hls::stream& matrixAStrm, + hls::stream& matrixQStrm, + hls::stream& matrixRStrm) { + switch (QRF_TRAITS::ARCH) { + case 0: + qrf_basic(matrixAStrm, matrixQStrm, + matrixRStrm); + break; + case 1: + qrf_alt(matrixAStrm, matrixQStrm, + matrixRStrm); + break; + default: + qrf_basic(matrixAStrm, matrixQStrm, + matrixRStrm); + break; + } +} +} // namespace solver +} // namespace xf + +#endif diff --git a/solver/L1/include/hw/utils/x_matrix_utils.hpp b/solver/L1/include/hw/utils/x_matrix_utils.hpp new file mode 100755 index 0000000000..e2b497f031 --- /dev/null +++ b/solver/L1/include/hw/utils/x_matrix_utils.hpp @@ -0,0 +1,255 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _XF_SOLVER_MATRIX_UTILS_HPP_ +#define _XF_SOLVER_MATRIX_UTILS_HPP_ + +#include "ap_fixed.h" +#include "utils/x_hls_utils.h" +#include "hls_x_complex.h" +#include "utils/std_complex_utils.h" +#include "hls_math.h" + +#ifndef __SYNTHESIS__ +#include +#include +#include +#include +#include +#endif + +namespace xf { +namespace solver { + +// =================================================================================================================== +// Transpose Types & Operation +struct NoTranspose { + const static int TransposeType = 0; + template + static InputType GetElement(const InputType A[RowsA][ColsA], unsigned Row, unsigned Col) { + // No transpose, default + return A[Row][Col]; + } +}; + +struct Transpose { + const static int TransposeType = 1; + template + static InputType GetElement(const InputType A[RowsA][ColsA], unsigned Row, unsigned Col) { + // Transpose, no conjugate + return A[Col][Row]; + } +}; + +struct ConjugateTranspose { + const static int TransposeType = 2; + template + static InputType GetElement(const InputType A[RowsA][ColsA], unsigned Row, unsigned Col) { + // Complex conjugate transpose. + // o For non x_complex types this function will return an unaltered value. + return x_conj(A[Col][Row]); + } +}; + +template +InputType GetMatrixElement(const InputType A[RowsA][ColsA], unsigned Row, unsigned Col) { + // Need to help the compiler identify that the GetElement member function is a template + return TransposeForm::template GetElement(A, Row, Col); +} + +// =================================================================================================================== +// Common math operations and constants. Wrappers/templates to select the correct function based on type. + +// sqrt +static half x_sqrt(half x) { + return hls::half_sqrt(x); +} +static float x_sqrt(float x) { + return sqrtf(x); +} +static double x_sqrt(double x) { + return sqrt(x); +} +template +ap_fixed x_sqrt(ap_fixed x) { + return hls::sqrt((double)x); +} + +// copysign +static float x_copysign(float a, float b) { + return copysignf(a, b); +} +static double x_copysign(double a, double b) { + return copysign(a, b); +} + +// sign +static float x_sign(float x) { + if (x == 0.0f) { + return 0.0f; + } else { + return copysignf(1.0f, x); + } +} +static double x_sign(double x) { + if (x == 0.0) { + return 0.0; + } else { + return copysign(1.0, x); + } +} +template +ap_fixed x_sign(ap_fixed x) { + ap_fixed tmp = 0; + if (x > 0) { + tmp = 1; + } else { + tmp = -1; + } + return tmp; +} + +// reciprocal sqrt +static half x_rsqrt(half x) { + return hls::half_rsqrt(x); +} +static float x_rsqrt(float x) { + return hls::rsqrtf(x); +} +static double x_rsqrt(double x) { + return hls::rsqrt(x); +} + +// isneg +static int x_isneg(float x) { + fp_struct fs = x; + return fs.__signbit(); +} +static int x_isneg(double x) { + fp_struct fs = x; + return fs.__signbit(); +} + +#ifndef __SYNTHESIS__ +// Matrix Display +// ============================================================================ + +// Non-specific data +// ----------------- +// This can be used by PoD or any class supporting "<<" +// setprecision may fail on non floating point types +template +struct xil_printer { + static std::string to_s(T x, unsigned prec = 10) { + std::stringstream ss; + ss << std::setiosflags(std::ios::fixed) << std::setprecision(prec) << x; + + return ss.str(); + } +}; + +// Complex data +// ---------------- +// This is used by complex data of any type. A printer is called to print the real and imaginary +// parts, so this just handles the formating of x+jy +template +struct xil_printer > { + static std::string to_s(hls::x_complex x, unsigned prec = 10) { + // Use the basic type printer to print the real and imaginary parts + typedef xil_printer printer; + + std::stringstream ss; + // Remember to deal with -0 + bool neg_imag = x.imag() <= -0 ? true : false; + + // Casting to "T" avoids "error: operands to ?: have different types." when using ap_fixed. + T imag = neg_imag ? (T)-x.imag() : (T)x.imag(); + + ss << printer::to_s(x.real(), prec) << (neg_imag ? " - j*" : " + j*") << printer::to_s(imag, prec); + return ss.str(); + } +}; + +template +void print_matrix(T a[ROWS][COLS], std::string prefix = "", unsigned prec = 10, unsigned matlab_format = 0) { + typedef xil_printer printer; + + std::string res[ROWS][COLS]; + unsigned widest_entry = 0; + + // Get the individual fields + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + T tmp; + + tmp = GetMatrixElement(a, r, c); + + res[r][c] = printer::to_s(tmp, prec); + if (res[r][c].length() > widest_entry) { + widest_entry = res[r][c].length(); + } + } + } + + // Print fields. Each column should be "widest_entry" chars wide + char col_gap_str[5] = " "; + unsigned col_width = widest_entry; + + for (int r = 0; r < ROWS; r++) { + if (!matlab_format) { + printf("%s|", prefix.c_str()); + } else { + if (r == 0) { + printf("%s[", prefix.c_str()); + } else { + printf("%s ", prefix.c_str()); + } + } + for (int c = 0; c < COLS; c++) { + unsigned num_spaces_needed = col_width - res[r][c].length(); + for (int x = 0; x < num_spaces_needed; x++) { + printf(" "); + } + if (!matlab_format) { + printf("(%s)", res[r][c].c_str()); + } else { + printf("%s", res[r][c].c_str()); + } + + if (c != COLS - 1) { + printf("%s", col_gap_str); + if (matlab_format) { + printf(","); + } + } + } + if (!matlab_format) { + printf(" |\n"); + } else { + if (r == ROWS - 1) { + printf(" ];\n"); + } else { + printf(" ;\n"); + } + } + } +} +#endif + +} // namespace solver +} // namespace xf + +#endif diff --git a/solver/L1/include/xf_solver_L1.hpp b/solver/L1/include/xf_solver_L1.hpp index da22250d9e..c9aad9f3a8 100644 --- a/solver/L1/include/xf_solver_L1.hpp +++ b/solver/L1/include/xf_solver_L1.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2019 Xilinx, Inc. + * Copyright 2021 Xilinx, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,14 @@ */ /** - * @file xf_solver_L2.h - * @brief Top-levle header for XF Solver Libaray level-2. + * @file xf_solver_L1.h + * @brief Top-levle header for XF Solver Libaray level-1. */ -#ifndef _XF_SOLVER_L2_HPP_ -#define _XF_SOLVER_L2_HPP_ +#ifndef _XF_SOLVER_L1_HPP_ +#define _XF_SOLVER_L1_HPP_ -// Matrix decomposition #include "hw/pseudosqrt.hpp" +#include "hw/qrf.hpp" #endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/Makefile b/solver/L1/tests/qrf/Makefile similarity index 98% rename from dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/Makefile rename to solver/L1/tests/qrf/Makefile index 3b623af8da..c7f8976192 100644 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r4_l32/Makefile +++ b/solver/L1/tests/qrf/Makefile @@ -61,7 +61,7 @@ export PATH := $(XILINX_VIVADO)/bin:$(PATH) # MK_INC_END vivado.mk -DEVICE ?= u200 +DEVICE ?= u250 # MK_INC_BEGIN vitis_set_part.mk @@ -239,7 +239,7 @@ runhls: data setup | check_vivado check_vpp $(HLS) -f run_hls.tcl; clean: - rm -rf settings.tcl *_hls.log prj_ssr_fft_reg_test_r4_l32.prj + rm -rf settings.tcl *_hls.log qrf_test.prj # Used by Jenkins test cleanall: clean diff --git a/solver/L1/tests/qrf/datas/complex/A_matType_1_0.txt b/solver/L1/tests/qrf/datas/complex/A_matType_1_0.txt new file mode 100644 index 0000000000..38d48f653c --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/A_matType_1_0.txt @@ -0,0 +1,9 @@ +1 0 +0 0 +0 0 +0 0 +0.707107 0 +0 0 +0 0 +0 0 +0.5 0 diff --git a/solver/L1/tests/qrf/datas/complex/A_matType_2_0.txt b/solver/L1/tests/qrf/datas/complex/A_matType_2_0.txt new file mode 100644 index 0000000000..473d1f8df2 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/A_matType_2_0.txt @@ -0,0 +1,9 @@ +0.52514 -0.477058 +0.0751031 0.0267326 +0.266026 -0.18024 +0 0 +0.0043508 0.746774 +0.333473 -0.151159 +0 0 +0 0 +0.451568 -0.491298 diff --git a/solver/L1/tests/qrf/datas/complex/A_matType_3_0.txt b/solver/L1/tests/qrf/datas/complex/A_matType_3_0.txt new file mode 100644 index 0000000000..aaa8390fb6 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/A_matType_3_0.txt @@ -0,0 +1,9 @@ +-0.864891 -0.178738 +0 0 +0 0 +0.224635 0.0317125 +-0.695539 0.103699 +0 0 +0.173313 0.211084 +0.103849 -0.120735 +0.568383 -0.0317426 diff --git a/solver/L1/tests/qrf/datas/complex/A_matType_4_0.txt b/solver/L1/tests/qrf/datas/complex/A_matType_4_0.txt new file mode 100644 index 0000000000..41ef1dbf00 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/A_matType_4_0.txt @@ -0,0 +1,9 @@ +0.597082 0.273489 +-0.28804 0.348745 +0.16186 -0.0677104 +-0.130026 0.163844 +0.35046 0.0559557 +0.410103 0.269426 +-0.235586 -0.392687 +-0.30045 0.349015 +0.0460424 -0.498937 diff --git a/solver/L1/tests/qrf/datas/complex/A_matType_5_0.txt b/solver/L1/tests/qrf/datas/complex/A_matType_5_0.txt new file mode 100644 index 0000000000..21704f6ec2 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/A_matType_5_0.txt @@ -0,0 +1,9 @@ +0.47256 0.000325495 +0.00598755 0.226378 +-0.0273328 0.0549273 +0.661012 0.174792 +-0.0746829 0.319979 +-0.0915662 0.0778907 +-0.249673 0.204662 +-0.0999715 -0.115466 +-0.0310097 -0.0657107 diff --git a/solver/L1/tests/qrf/datas/complex/A_matType_6_0.txt b/solver/L1/tests/qrf/datas/complex/A_matType_6_0.txt new file mode 100644 index 0000000000..6e13134140 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/A_matType_6_0.txt @@ -0,0 +1,9 @@ +0.430619 0.000137513 +0.327354 0.0928753 +-0.0596712 -0.18261 +0.243304 -0.212111 +0.23137 -0.108649 +-0.123257 -0.0732041 +-0.0830354 0.501851 +-0.172338 0.363511 +0.22355 -0.0351212 diff --git a/solver/L1/tests/qrf/datas/complex/A_matType_8_0.txt b/solver/L1/tests/qrf/datas/complex/A_matType_8_0.txt new file mode 100644 index 0000000000..f0bcd46157 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/A_matType_8_0.txt @@ -0,0 +1,9 @@ +3.77451e+37 2.38729e+37 +-1.99879e+37 1.34333e+37 +1.85552e+36 2.48118e+37 +1.71376e+37 1.59881e+37 +5.39477e+37 -1.23953e+37 +-1.29388e+37 3.75469e+36 +-6.35396e+36 3.54491e+35 +1.64791e+37 1.00951e+37 +6.66323e+37 -2.86784e+37 diff --git a/solver/L1/tests/qrf/datas/complex/A_matType_9_0.txt b/solver/L1/tests/qrf/datas/complex/A_matType_9_0.txt new file mode 100644 index 0000000000..803e2f4744 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/A_matType_9_0.txt @@ -0,0 +1,9 @@ +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 diff --git a/solver/L1/tests/qrf/datas/complex/Q_matType_1_0.txt b/solver/L1/tests/qrf/datas/complex/Q_matType_1_0.txt new file mode 100644 index 0000000000..a08360e153 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/Q_matType_1_0.txt @@ -0,0 +1,9 @@ +1 0 +0 0 +0 0 +0 -0 +1 0 +0 0 +0 -0 +0 -0 +1 0 diff --git a/solver/L1/tests/qrf/datas/complex/Q_matType_2_0.txt b/solver/L1/tests/qrf/datas/complex/Q_matType_2_0.txt new file mode 100644 index 0000000000..233f89b3d7 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/Q_matType_2_0.txt @@ -0,0 +1,9 @@ +-0.74018 0.672409 +0 0 +0 0 +-0 0 +-0.005826 -0.999983 +0 0 +-0 0 +0 -0 +-0.67671 0.736249 diff --git a/solver/L1/tests/qrf/datas/complex/Q_matType_3_0.txt b/solver/L1/tests/qrf/datas/complex/Q_matType_3_0.txt new file mode 100644 index 0000000000..7f48efa0ed --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/Q_matType_3_0.txt @@ -0,0 +1,9 @@ +-0.908629 -0.187777 +-0.219168 -0.0417355 +-0.254145 0.157375 +0.235995 0.0333162 +-0.935272 0.155044 +-0.166938 -0.128668 +0.182077 0.221759 +0.192744 -0.119586 +-0.929261 0.0518967 diff --git a/solver/L1/tests/qrf/datas/complex/Q_matType_4_0.txt b/solver/L1/tests/qrf/datas/complex/Q_matType_4_0.txt new file mode 100644 index 0000000000..6d5aa20906 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/Q_matType_4_0.txt @@ -0,0 +1,9 @@ +-0.721548 -0.3305 +0.17467 -0.570078 +-0.0729544 0.0965258 +0.157131 -0.197998 +-0.457266 -0.146471 +-0.823882 -0.163645 +0.284696 0.474545 +0.532738 -0.360758 +-0.366959 0.380973 diff --git a/solver/L1/tests/qrf/datas/complex/Q_matType_5_0.txt b/solver/L1/tests/qrf/datas/complex/Q_matType_5_0.txt new file mode 100644 index 0000000000..10a8d58215 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/Q_matType_5_0.txt @@ -0,0 +1,9 @@ +-0.529988 -0.000365051 +0.122605 -0.00467583 +-0.473767 0.692534 +-0.741343 -0.196034 +-0.0310966 -0.435999 +0.312447 -0.351135 +0.280015 -0.229534 +-0.652695 -0.606526 +-0.108135 0.251652 diff --git a/solver/L1/tests/qrf/datas/complex/Q_matType_6_0.txt b/solver/L1/tests/qrf/datas/complex/Q_matType_6_0.txt new file mode 100644 index 0000000000..a0afc1517d --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/Q_matType_6_0.txt @@ -0,0 +1,9 @@ +-0.581508 -0.000185698 +0.14416 0.731769 +0.236438 -0.222883 +-0.328559 0.286435 +-0.418523 0.101873 +-0.785357 0.0876329 +0.112131 -0.677701 +0.467369 0.199394 +-0.502573 0.131819 diff --git a/solver/L1/tests/qrf/datas/complex/Q_matType_8_0.txt b/solver/L1/tests/qrf/datas/complex/Q_matType_8_0.txt new file mode 100644 index 0000000000..c64b314082 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/Q_matType_8_0.txt @@ -0,0 +1,9 @@ +-0.742469 -0.469596 +0.38405 -0.221734 +-0.143003 0.105398 +-0.337107 -0.314496 +-0.817881 0.198031 +0.0805492 -0.269847 +0.124986 -0.00697306 +-0.267879 -0.153084 +-0.899447 0.283075 diff --git a/solver/L1/tests/qrf/datas/complex/Q_matType_9_0.txt b/solver/L1/tests/qrf/datas/complex/Q_matType_9_0.txt new file mode 100644 index 0000000000..a08360e153 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/Q_matType_9_0.txt @@ -0,0 +1,9 @@ +1 0 +0 0 +0 0 +0 -0 +1 0 +0 0 +0 -0 +0 -0 +1 0 diff --git a/solver/L1/tests/qrf/datas/complex/R_matType_1_0.txt b/solver/L1/tests/qrf/datas/complex/R_matType_1_0.txt new file mode 100644 index 0000000000..38d48f653c --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/R_matType_1_0.txt @@ -0,0 +1,9 @@ +1 0 +0 0 +0 0 +0 0 +0.707107 0 +0 0 +0 0 +0 0 +0.5 0 diff --git a/solver/L1/tests/qrf/datas/complex/R_matType_2_0.txt b/solver/L1/tests/qrf/datas/complex/R_matType_2_0.txt new file mode 100644 index 0000000000..15eea2dda6 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/R_matType_2_0.txt @@ -0,0 +1,9 @@ +-0.709476 0 +-0.0376145 -0.0702869 +-0.318102 -0.0454681 +0 0 +-0.746787 0 +0.149214 0.334348 +0 0 +0 0 +-0.667299 0 diff --git a/solver/L1/tests/qrf/datas/complex/R_matType_3_0.txt b/solver/L1/tests/qrf/datas/complex/R_matType_3_0.txt new file mode 100644 index 0000000000..b7b3cca6bd --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/R_matType_3_0.txt @@ -0,0 +1,9 @@ +0.951864 0 +-0.168554 0.00263259 +0.0964503 -0.131824 +0 0 +0.70105 0 +0.113348 0.0618527 +0 0 +0 0 +-0.529823 0 diff --git a/solver/L1/tests/qrf/datas/complex/R_matType_4_0.txt b/solver/L1/tests/qrf/datas/complex/R_matType_4_0.txt new file mode 100644 index 0000000000..736f2548ce --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/R_matType_4_0.txt @@ -0,0 +1,9 @@ +-0.827502 0 +0.216651 -0.0267102 +-0.306977 0.0619914 +0 0 +-0.703544 0 +0.0444069 -0.231877 +0 0 +0 0 +-0.607288 0 diff --git a/solver/L1/tests/qrf/datas/complex/R_matType_5_0.txt b/solver/L1/tests/qrf/datas/complex/R_matType_5_0.txt new file mode 100644 index 0000000000..772c28693f --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/R_matType_5_0.txt @@ -0,0 +1,9 @@ +-0.891642 0 +-0.0121073 -0.427109 +0.0734783 -0.130332 +0 0 +-0.00222873 0 +0.0253742 -0.0116576 +0 0 +0 0 +-0.0181544 0 diff --git a/solver/L1/tests/qrf/datas/complex/R_matType_6_0.txt b/solver/L1/tests/qrf/datas/complex/R_matType_6_0.txt new file mode 100644 index 0000000000..8387ad19d0 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/R_matType_6_0.txt @@ -0,0 +1,9 @@ +-0.740521 0 +-0.563192 -0.160555 +0.103131 0.313097 +0 0 +-0.000810711 0 +-0.000625281 -0.000454543 +0 0 +0 0 +-2.18703e-06 0 diff --git a/solver/L1/tests/qrf/datas/complex/R_matType_8_0.txt b/solver/L1/tests/qrf/datas/complex/R_matType_8_0.txt new file mode 100644 index 0000000000..27a5de8170 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/R_matType_8_0.txt @@ -0,0 +1,9 @@ +-5.08372e+37 0 +-3.76645e+36 3.16152e+36 +-1.32014e+36 -2.60054e+37 +0 0 +-6.31922e+37 0 +-6.92225e+36 2.73145e+37 +0 0 +0 0 +-6.7756e+37 0 diff --git a/solver/L1/tests/qrf/datas/complex/R_matType_9_0.txt b/solver/L1/tests/qrf/datas/complex/R_matType_9_0.txt new file mode 100644 index 0000000000..803e2f4744 --- /dev/null +++ b/solver/L1/tests/qrf/datas/complex/R_matType_9_0.txt @@ -0,0 +1,9 @@ +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 +0 0 diff --git a/solver/L1/tests/qrf/datas/float/A_matType_1_0.txt b/solver/L1/tests/qrf/datas/float/A_matType_1_0.txt new file mode 100644 index 0000000000..9f94a25b28 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/A_matType_1_0.txt @@ -0,0 +1,9 @@ +1 +0 +0 +0 +0.707107 +0 +0 +0 +0.5 diff --git a/solver/L1/tests/qrf/datas/float/A_matType_2_0.txt b/solver/L1/tests/qrf/datas/float/A_matType_2_0.txt new file mode 100644 index 0000000000..fd9208e103 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/A_matType_2_0.txt @@ -0,0 +1,9 @@ +-0.65416 +-0.232662 +-0.380752 +0 +-0.641225 +0.037024 +0 +0 +0.842871 diff --git a/solver/L1/tests/qrf/datas/float/A_matType_3_0.txt b/solver/L1/tests/qrf/datas/float/A_matType_3_0.txt new file mode 100644 index 0000000000..1d9a1837fa --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/A_matType_3_0.txt @@ -0,0 +1,9 @@ +-0.885968 +0 +0 +0.234091 +0.696766 +0 +0.29646 +-0.0941891 +-0.572731 diff --git a/solver/L1/tests/qrf/datas/float/A_matType_4_0.txt b/solver/L1/tests/qrf/datas/float/A_matType_4_0.txt new file mode 100644 index 0000000000..09b332a017 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/A_matType_4_0.txt @@ -0,0 +1,9 @@ +0.504787 +-0.514481 +-0.154762 +0.0165026 +0.568036 +-0.33399 +0.618868 +0.0567508 +0.621162 diff --git a/solver/L1/tests/qrf/datas/float/A_matType_5_0.txt b/solver/L1/tests/qrf/datas/float/A_matType_5_0.txt new file mode 100644 index 0000000000..940a80633b --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/A_matType_5_0.txt @@ -0,0 +1,9 @@ +0.56281 +0.121149 +0.0131272 +0.557196 +0.123222 +-0.0124462 +-0.571439 +-0.126537 +0.0335787 diff --git a/solver/L1/tests/qrf/datas/float/A_matType_6_0.txt b/solver/L1/tests/qrf/datas/float/A_matType_6_0.txt new file mode 100644 index 0000000000..99045ec9fc --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/A_matType_6_0.txt @@ -0,0 +1,9 @@ +0.365851 +0.347248 +-0.183606 +-0.0647058 +-0.0609936 +0.0328599 +0.57173 +0.54122 +-0.288237 diff --git a/solver/L1/tests/qrf/datas/float/A_matType_8_0.txt b/solver/L1/tests/qrf/datas/float/A_matType_8_0.txt new file mode 100644 index 0000000000..b2316512e7 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/A_matType_8_0.txt @@ -0,0 +1,9 @@ +3.71395e+37 +-1.0493e+37 +-5.39489e+37 +7.92379e+36 +6.13713e+37 +5.59868e+36 +2.1726e+37 +1.69687e+36 +6.26846e+37 diff --git a/solver/L1/tests/qrf/datas/float/A_matType_9_0.txt b/solver/L1/tests/qrf/datas/float/A_matType_9_0.txt new file mode 100644 index 0000000000..bc6ff2b709 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/A_matType_9_0.txt @@ -0,0 +1,9 @@ +0 +0 +0 +0 +0 +0 +0 +0 +0 diff --git a/solver/L1/tests/qrf/datas/float/Q_matType_1_0.txt b/solver/L1/tests/qrf/datas/float/Q_matType_1_0.txt new file mode 100644 index 0000000000..561aa73362 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/Q_matType_1_0.txt @@ -0,0 +1,9 @@ +1 +0 +0 +-0 +1 +0 +-0 +-0 +1 diff --git a/solver/L1/tests/qrf/datas/float/Q_matType_2_0.txt b/solver/L1/tests/qrf/datas/float/Q_matType_2_0.txt new file mode 100644 index 0000000000..561aa73362 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/Q_matType_2_0.txt @@ -0,0 +1,9 @@ +1 +0 +0 +-0 +1 +0 +-0 +-0 +1 diff --git a/solver/L1/tests/qrf/datas/float/Q_matType_3_0.txt b/solver/L1/tests/qrf/datas/float/Q_matType_3_0.txt new file mode 100644 index 0000000000..85bf08eec0 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/Q_matType_3_0.txt @@ -0,0 +1,9 @@ +-0.919881 +-0.187404 +0.344528 +0.243051 +-0.961827 +0.12576 +0.307808 +0.199422 +0.930314 diff --git a/solver/L1/tests/qrf/datas/float/Q_matType_4_0.txt b/solver/L1/tests/qrf/datas/float/Q_matType_4_0.txt new file mode 100644 index 0000000000..b5dc273edc --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/Q_matType_4_0.txt @@ -0,0 +1,9 @@ +-0.631933 +0.478284 +-0.60984 +-0.0206592 +-0.796983 +-0.603648 +-0.774748 +-0.368866 +0.513521 diff --git a/solver/L1/tests/qrf/datas/float/Q_matType_5_0.txt b/solver/L1/tests/qrf/datas/float/Q_matType_5_0.txt new file mode 100644 index 0000000000..39a7d4b797 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/Q_matType_5_0.txt @@ -0,0 +1,9 @@ +-0.57629 +0.816544 +-0.0338543 +-0.570541 +-0.37232 +0.732025 +0.585126 +0.441174 +0.680436 diff --git a/solver/L1/tests/qrf/datas/float/Q_matType_6_0.txt b/solver/L1/tests/qrf/datas/float/Q_matType_6_0.txt new file mode 100644 index 0000000000..5755add14b --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/Q_matType_6_0.txt @@ -0,0 +1,9 @@ +-0.536563 +-0.802421 +-0.26119 +0.0948985 +-0.364932 +0.926185 +-0.838507 +0.47217 +0.271958 diff --git a/solver/L1/tests/qrf/datas/float/Q_matType_8_0.txt b/solver/L1/tests/qrf/datas/float/Q_matType_8_0.txt new file mode 100644 index 0000000000..b802b0a265 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/Q_matType_8_0.txt @@ -0,0 +1,9 @@ +-0.848885 +0.210293 +-0.484946 +-0.181111 +-0.977634 +-0.106913 +-0.496582 +-0.00292787 +0.867985 diff --git a/solver/L1/tests/qrf/datas/float/Q_matType_9_0.txt b/solver/L1/tests/qrf/datas/float/Q_matType_9_0.txt new file mode 100644 index 0000000000..561aa73362 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/Q_matType_9_0.txt @@ -0,0 +1,9 @@ +1 +0 +0 +-0 +1 +0 +-0 +-0 +1 diff --git a/solver/L1/tests/qrf/datas/float/R_matType_1_0.txt b/solver/L1/tests/qrf/datas/float/R_matType_1_0.txt new file mode 100644 index 0000000000..9f94a25b28 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/R_matType_1_0.txt @@ -0,0 +1,9 @@ +1 +0 +0 +0 +0.707107 +0 +0 +0 +0.5 diff --git a/solver/L1/tests/qrf/datas/float/R_matType_2_0.txt b/solver/L1/tests/qrf/datas/float/R_matType_2_0.txt new file mode 100644 index 0000000000..fd9208e103 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/R_matType_2_0.txt @@ -0,0 +1,9 @@ +-0.65416 +-0.232662 +-0.380752 +0 +-0.641225 +0.037024 +0 +0 +0.842871 diff --git a/solver/L1/tests/qrf/datas/float/R_matType_3_0.txt b/solver/L1/tests/qrf/datas/float/R_matType_3_0.txt new file mode 100644 index 0000000000..0d72074a73 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/R_matType_3_0.txt @@ -0,0 +1,9 @@ +0.963133 +0.140357 +-0.176291 +0 +-0.688951 +-0.114215 +0 +0 +-0.53282 diff --git a/solver/L1/tests/qrf/datas/float/R_matType_4_0.txt b/solver/L1/tests/qrf/datas/float/R_matType_4_0.txt new file mode 100644 index 0000000000..a6bf26f883 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/R_matType_4_0.txt @@ -0,0 +1,9 @@ +-0.798799 +0.269415 +-0.376545 +0 +-0.719717 +-0.0369615 +0 +0 +0.614973 diff --git a/solver/L1/tests/qrf/datas/float/R_matType_5_0.txt b/solver/L1/tests/qrf/datas/float/R_matType_5_0.txt new file mode 100644 index 0000000000..100157fc76 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/R_matType_5_0.txt @@ -0,0 +1,9 @@ +-0.976609 +-0.21416 +0.0191837 +0 +-0.002779 +0.030167 +0 +0 +0.0132928 diff --git a/solver/L1/tests/qrf/datas/float/R_matType_6_0.txt b/solver/L1/tests/qrf/datas/float/R_matType_6_0.txt new file mode 100644 index 0000000000..80f0bbad8f --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/R_matType_6_0.txt @@ -0,0 +1,9 @@ +-0.681842 +-0.645926 +0.343323 +0 +-0.00083232 +-0.000759007 +0 +0 +2.25136e-06 diff --git a/solver/L1/tests/qrf/datas/float/R_matType_8_0.txt b/solver/L1/tests/qrf/datas/float/R_matType_8_0.txt new file mode 100644 index 0000000000..ec5423ee82 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/R_matType_8_0.txt @@ -0,0 +1,9 @@ +-4.3751e+37 +-3.0503e+36 +1.36543e+37 +0 +-6.22103e+37 +-1.7002e+37 +0 +0 +7.9973e+37 diff --git a/solver/L1/tests/qrf/datas/float/R_matType_9_0.txt b/solver/L1/tests/qrf/datas/float/R_matType_9_0.txt new file mode 100644 index 0000000000..bc6ff2b709 --- /dev/null +++ b/solver/L1/tests/qrf/datas/float/R_matType_9_0.txt @@ -0,0 +1,9 @@ +0 +0 +0 +0 +0 +0 +0 +0 +0 diff --git a/solver/L1/tests/qrf/description.json b/solver/L1/tests/qrf/description.json new file mode 100644 index 0000000000..bed9bc0ea7 --- /dev/null +++ b/solver/L1/tests/qrf/description.json @@ -0,0 +1,68 @@ +{ + "name": "Xilinx QR Factorization", + "description": "", + "flow": "hls", + "platform_allowlist": [ + "u250", + "aws-vu9p-f1", + "vck190" + ], + "platform_blacklist": [], + "part_whitelist": [], + "part_blacklist": [], + "project": "qrf_test", + "solution": "sol1", + "clock": "300MHz", + "topfunction": "kernel_qrf_0", + "top": { + "source": [ + "./kernel/kernel_qrf_0.cpp" + ], + "cflags": "-DQRF_A_ROWS=3 -DQRF_A_COLS=3 -DQRF_TRANSPOSED_Q=0 -DSEL_ARCH=0 -I./host/ -I./kernel/ -I${XF_PROJ_ROOT}/L1/tests/ -I${XF_PROJ_ROOT}/L1/include/ -I${XF_PROJ_ROOT}/L1/include/hw -I${XF_PROJ_ROOT}/L2/include -I${XF_PROJ_ROOT}/../utils/L1/include/" + }, + "testbench": { + "source": [ + "./host/test_qrf.cpp" + ], + "cflags": "-DQRF_A_ROWS=3 -DQRF_A_COLS=3 -DQRF_TRANSPOSED_Q=0 -DSEL_ARCH=0 -I./host/ -I./kernel/ -I${XF_PROJ_ROOT}/L1/tests/ -I${XF_PROJ_ROOT}/L1/include/ -I${XF_PROJ_ROOT}/L1/include/hw -I ./host -I${XF_PROJ_ROOT}/../utils/L1/include/", + "ldflags": "", + "argv": { + "hls_csim": "", + "hls_cosim": "" + }, + "stdmath": false + }, + "testinfo": { + "disable": false, + "jobs": [ + { + "index": 0, + "dependency": [], + "env": "", + "cmd": "", + "max_memory_MB": { + "hls_vivado_syn": 16384, + "hls_csim": 10240, + "hls_cosim": 16384, + "hls_vivado_impl": 16384, + "hls_csynth": 10240 + }, + "max_time_min": { + "hls_vivado_syn": 60, + "hls_csim": 60, + "hls_cosim": 60, + "hls_vivado_impl": 60, + "hls_csynth": 60 + } + } + ], + "targets": [ + "hls_csim", + "hls_csynth", + "hls_cosim", + "hls_vivado_syn", + "hls_vivado_impl" + ], + "category": "canary" + } +} diff --git a/solver/L1/tests/qrf/host/test_qrf.cpp b/solver/L1/tests/qrf/host/test_qrf.cpp new file mode 100755 index 0000000000..e96fec988c --- /dev/null +++ b/solver/L1/tests/qrf/host/test_qrf.cpp @@ -0,0 +1,853 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ====================================================================== +// Common testbench for QR Factorisation function. +// +// Golden data is generated from reference Model LAPACKe +// +// ====================================================================== + +#include "test_qrf.hpp" +#include "kernel_qrf.hpp" +#include "src/utils.hpp" +#include "utils/x_matrix_utils.hpp" + +// shipped utils +#include "src/matrix_test_utils.hpp" +#include "src/type_test_utils.hpp" + +#include +#include +#include +#include +#include // for abs +#include //for find +#include + +template +T* aligned_alloc(std::size_t num) { + void* ptr = nullptr; + if (posix_memalign(&ptr, 4096, num * sizeof(T))) { + throw std::bad_alloc(); + } + return reinterpret_cast(ptr); +} + +// Compute time difference +unsigned long diff(const struct timeval* newTime, const struct timeval* oldTime) { + return (newTime->tv_sec - oldTime->tv_sec) * 1000000 + (newTime->tv_usec - oldTime->tv_usec); +} + +// Arguments parser +class ArgParser { + public: + ArgParser(int& argc, const char** argv) { + for (int i = 1; i < argc; ++i) mTokens.push_back(std::string(argv[i])); + } + bool getCmdOption(const std::string option, std::string& value) const { + std::vector::const_iterator itr; + itr = std::find(this->mTokens.begin(), this->mTokens.end(), option); + if (itr != this->mTokens.end() && ++itr != this->mTokens.end()) { + value = *itr; + return true; + } + return false; + } + + private: + std::vector mTokens; +}; + +// --------------------------------------------------------------------------------------------- +// Main test program +// --------------------------------------------------------------------------------------------- + +int main(int argc, char* argv[]) { + // Variables set by command line + // ==================================================================== + // long unsigned num_tests = (A_ROWS >= 16 ? 4 : 20); // Small default for HLS + long unsigned num_tests = 1; + unsigned allowed_ulp_mismatch = 0; + unsigned print_precision = 10; + unsigned int debug = 0; + float R_ratio_threshold = 30.0; // Defined in lapack-X.Y.Z/TESTING/[s|d|c|x]test.in + float Q_ratio_threshold = 30.0; // Defined in lapack-X.Y.Z/TESTING/[s|d|c|x]test.in + float mat_type = 0; // Specify to only run a single matrix type. + unsigned int skip_mat_type = 7; + + // Parse command line options + // ==================================================================== + std::vector args(argv + 1, argv + argc); + for (std::vector::iterator i = args.begin(); i != args.end(); ++i) { + if (*i == "-h" || *i == "--help") { + std::cout << "Syntax: main.exe [-num_tests -mat_type -skip_mat_type " + "]" + << std::endl; + return 0; + } else if (*i == "-num_tests") { + // This loses the MSB so 18446744073709551615 gets converted into 9223372036854775807. + // It's probably not abig issue though. + num_tests = (long unsigned)atol((*++i).c_str()); + printf("num_tests as long unsigned = %lu\n", num_tests); + } else if (*i == "-max_ulp_mismatch_in_l") { + allowed_ulp_mismatch = (unsigned)atol((*++i).c_str()); + } else if (*i == "-prec") { + print_precision = (unsigned)atol((*++i).c_str()); + } else if (*i == "-q_ratio_threshold") { + Q_ratio_threshold = (float)atol((*++i).c_str()); + } else if (*i == "-r_ratio_threshold") { + R_ratio_threshold = (float)atol((*++i).c_str()); + } else if (*i == "-mat_type") { + mat_type = (unsigned)atol((*++i).c_str()); + } else if (*i == "-skip_mat_type") { + skip_mat_type = (unsigned)atol((*++i).c_str()); + } else if (*i == "-debug") { + debug = (unsigned)atol((*++i).c_str()); + } else { + printf("Unknown command line option %s. Try again\n", i->c_str()); + exit(1); + } + } + + // Variables + // ==================================================================== + + // Matrix arrays + MATRIX_IN_T A[A_ROWS][A_COLS] = {0}; // The input array. Cast from A_generated + // Note that this needs to be maximally-sized to support the largest + // Q, otherwise we get strange LAPACK results when ROWS > COLS + + MATRIX_OUT_T Q[A_ROWS][A_ROWS] = {0}; // The Q result from the DUT + MATRIX_OUT_T Q_expected[A_ROWS][A_ROWS] = {0}; // The Q result from LAPACK in target format + + MATRIX_OUT_T R[A_ROWS][A_COLS] = {0}; // The R result from the DUT + MATRIX_OUT_T R_expected[A_ROWS][A_COLS] = {0}; // The R result from LAPACK in target format + + MATRIX_OUT_T I[A_ROWS][A_ROWS] = {0}; // The identity matrix to compare against + + // Test variables + QR_TYPE A_cast[A_ROWS][A_COLS] = {0}; // Cast A back to LAPACK compatible type for analysis + MATRIX_OUT_T Q_delta_vs_lapack[A_ROWS][A_ROWS] = {0}; // The difference between the DUT's Q and LAPACK's Q + MATRIX_OUT_T R_delta_vs_lapack[A_ROWS][A_COLS] = {0}; // The difference between the DUT's R and LAPACK's R + MATRIX_IN_T R_restored[A_ROWS][A_COLS] = {0}; // R recreated from Q'*A + MATRIX_IN_T R_restored_lapack[A_ROWS][A_COLS] = {0}; // R recreated from LAPACK's Q'*A + MATRIX_IN_T I_restored[A_ROWS][A_ROWS] = {0}; // I recreated from Q'*Q + MATRIX_IN_T I_restored_lapack[A_ROWS][A_ROWS] = {0}; // I recreated from LAPACK's Q'*Q + + QR_TYPE R_delta[A_ROWS][A_COLS] = { + 0}; // The delta values will be passed to xLANSY so need to use LAPACK compatible types + QR_TYPE R_delta_lapack[A_ROWS][A_COLS] = {0}; // + QR_TYPE I_delta[A_ROWS][A_ROWS] = { + 0}; // The delta values will be passed to xLANSY so need to use LAPACK compatible types + QR_TYPE I_delta_lapack[A_ROWS][A_ROWS] = {0}; // + + // Non-complex type + double A_norm = 0; + QR_BASE_TYPE R_delta_norm = 0; + QR_BASE_TYPE R_delta_lapack_norm = 0; + QR_BASE_TYPE R_DUT_ratio = 0; + QR_BASE_TYPE R_LAPACK_ratio = 0; + QR_BASE_TYPE I_delta_norm = 0; + QR_BASE_TYPE I_delta_lapack_norm = 0; + QR_BASE_TYPE I_DUT_ratio = 0; + QR_BASE_TYPE I_LAPACK_ratio = 0; + + float R_imat_max_ratio_diff[NUM_MAT_TYPES] = {0}; + float R_imat_min_ratio_diff[NUM_MAT_TYPES] = {0}; + float R_imat_max_ratio[NUM_MAT_TYPES] = {0}; + float R_imat_min_ratio[NUM_MAT_TYPES] = {0}; + float I_imat_max_ratio_diff[NUM_MAT_TYPES] = {0}; + float I_imat_min_ratio_diff[NUM_MAT_TYPES] = {0}; + float I_imat_max_ratio[NUM_MAT_TYPES] = {0}; + float I_imat_min_ratio[NUM_MAT_TYPES] = {0}; + + unsigned int R_ratio_same = 0; + unsigned int R_ratio_better = 0; + unsigned int R_ratio_worse = 0; + unsigned int R_imat_ratio_same[NUM_MAT_TYPES] = {0}; + unsigned int R_imat_ratio_better[NUM_MAT_TYPES] = {0}; + unsigned int R_imat_ratio_worse[NUM_MAT_TYPES] = {0}; + unsigned int I_ratio_same = 0; + unsigned int I_ratio_better = 0; + unsigned int I_ratio_worse = 0; + unsigned int I_imat_ratio_same[NUM_MAT_TYPES] = {0}; + unsigned int I_imat_ratio_better[NUM_MAT_TYPES] = {0}; + unsigned int I_imat_ratio_worse[NUM_MAT_TYPES] = {0}; + + // Zero values + for (int i = 0; i < NUM_MAT_TYPES; i++) { + R_imat_max_ratio_diff[i] = 0; + R_imat_min_ratio_diff[i] = 0; + R_imat_ratio_same[i] = 0; + R_imat_ratio_better[i] = 0; + R_imat_ratio_worse[i] = 0; + R_imat_max_ratio[i] = 0; + R_imat_min_ratio[i] = R_ratio_threshold; + I_imat_max_ratio_diff[i] = 0; + I_imat_min_ratio_diff[i] = 0; + I_imat_ratio_same[i] = 0; + I_imat_ratio_better[i] = 0; + I_imat_ratio_worse[i] = 0; + I_imat_max_ratio[i] = 0; + I_imat_min_ratio[i] = Q_ratio_threshold; + } + + float R_ratio_difference = 0; + float I_ratio_difference = 0; + unsigned int R_pass_fail = 0; // Pass=0 Fail =1 + unsigned int I_pass_fail = 0; // Pass=0 Fail =1 + unsigned int pass_fail = 0; // Pass=0 Fail =1 + + bool matched_lapack_Q = false; + bool matched_lapack_R = false; + + printf("Running %lu %s tests per matrix type on %d x %d matrices with TransposedQ %d\n", num_tests, + x_is_float(R_expected[0][0]) + ? "single precision" + : x_is_double(R_expected[0][0]) ? "double precision" + : x_is_fixed(R_expected[0][0]) ? "fixed point" : "Unknown type", + A_ROWS, A_COLS, TRANSPOSED_Q); + + std::cout << " MIN: " << hls::numeric_limits::min() << std::endl; + std::cout << " MAX: " << hls::numeric_limits::max() << std::endl; + + // Generate results table header + std::cout << "RESULTS_TABLE,Test,IMAT,kl,ku,cond,anorm,R Matching,DUT Ratio,LAPACK Ratio,Relative Ratio " + "Difference,Q Matching,DUT Ratio,LAPACK Ratio,Relative Ratio Difference" + << std::endl; + + // Create I to compare against later + for (int r = 0; r < A_ROWS; r++) { + for (int c = 0; c < A_ROWS; c++) { + if (r == c) { + I[r][c] = 1.0; + } else { + I[r][c] = 0.0; + } + } + } + + //---------------- New code post-test review ---------- + std::cout << "Post-Test: NUM_MAT_TYPES is " << NUM_MAT_TYPES << ", num_tests is " << num_tests << "\n"; + for (unsigned int imat = 0; imat < NUM_MAT_TYPES; imat++) { + // Test which matrix type to run + if ((mat_type == 0 || imat + 1 == mat_type) && skip_mat_type != imat + 1) { + for (long unsigned i = 0; i < num_tests; i++) { + if (imat == 6) { + // this matrix type is used to test abnormal situation, the element of matrix is very small + // HLS do not support abnormal situation. + continue; + } + + if (imat == 8 && i > 0) { + // Test only one zero matrix + break; + } + + // Read input matrix and golden matrix from files + std::string base_path; + if (x_is_complex(A[0][0]) == true) { + base_path = "../../../../datas/complex/"; + } else { + base_path = "../../../../datas/float/"; + } + std::string file_A = + base_path + "A_matType_" + std::to_string(imat + 1) + "_" + std::to_string(i) + ".txt"; + std::string file_Q = + base_path + "Q_matType_" + std::to_string(imat + 1) + "_" + std::to_string(i) + ".txt"; + std::string file_R = + base_path + "R_matType_" + std::to_string(imat + 1) + "_" + std::to_string(i) + ".txt"; + + int A_size = A_ROWS * A_COLS; + int Q_size = A_ROWS * A_ROWS; + int R_size = A_ROWS * A_COLS; + + MATRIX_IN_T* A_ptr = reinterpret_cast(A); + MATRIX_OUT_T* Q_ptr = reinterpret_cast(Q_expected); + MATRIX_OUT_T* R_ptr = reinterpret_cast(R_expected); + + // printf("Read datas from file\n"); + readTxt(file_A, A_ptr, A_size); + readTxt(file_Q, Q_ptr, Q_size); + readTxt(file_R, R_ptr, R_size); + + for (int r = 0; r < A_ROWS; r++) { + for (int c = 0; c < A_COLS; c++) { + // Cast back to pick up quantization. Used in test criteria + A_cast[r][c] = A[r][c]; + } + } + + hls::stream matrixAStrm; + hls::stream matrixQStrm; + hls::stream matrixRStrm; + for (int r = 0; r < A_ROWS; r++) { + for (int c = 0; c < A_COLS; c++) { + matrixAStrm.write(A[r][c]); + } + } + + // Get Actual results + // + // Q is output in (conjugate) transposed form, specified in generic_wrapper.cpp, + // which means Q*A = R + // ==================================================================== + kernel_qrf_0(matrixAStrm, matrixQStrm, matrixRStrm); + + // Force zeros in lower triangle of our R, as we did that for LAPACK as well + for (int r = 0; r < A_ROWS; r++) { + for (int c = 0; c < A_ROWS; c++) { + Q[r][c] = matrixQStrm.read(); + } + } + + for (int r = 0; r < A_ROWS; r++) { + for (int c = 0; c < A_COLS; c++) { + R[r][c] = matrixRStrm.read(); + if (r > c) { + R[r][c] = 0; + } + } + } + + // Check for NaNs + if (anyNaN(R) == 1) { + printf("ERROR: Caught NaN in R\n"); + xf::solver::print_matrix(R, " ", + print_precision, 1); + printf("TB:Fail\n"); + return (32); + } + if (anyNaN(Q) == 1) { + printf("ERROR: Caught NaN in Q\n"); + xf::solver::print_matrix(Q, " ", + print_precision, 1); + printf("TB:Fail\n"); + return (33); + } + // Validation checks (i.e. are the matrices correctly formed) + // ==================================================================== + + // Check 1: Complex matrices should have a real-valued diagonal (for QR inverse, and also to match + // Matlab/LAPACK results) + if (x_is_complex(R_expected[0][0]) == true) { + // printf("INFO: Checking for real-valued diagonal entries\n"); + for (int r = 0; r < A_ROWS; r++) { + for (int c = 0; c < A_COLS; c++) { + if (r == c) { + if (hls::x_imag(R[r][c]) != 0) { + printf("ERROR: Complex-valued diagonal element detected in R\n"); + xf::solver::print_matrix( + R, " ", print_precision, 1); + printf("TB:Fail\n"); + return (22); + } + } + } + } + } + /* + // Check 2: Verify that the lower-triangular portion of R is zeroed + // Note this is disabled for now because I haven't decided whether to force zero values when applying + the Givens + // rotations or not. If I don't force zeros, then there's the chance that catastrophic cancellation can + occur and + // some lower-triangular values can be non-zero (although we would document for users that these + elements are not + // explicitly zeroed). + for(int r = 0; r < A_ROWS; r++){ + for(int c = 0; c < A_COLS; c++){ + if (r > c) { + if (R[r][c] != 0) { + printf("ERROR: Lower-triangular element R[%d][%d] is not zero\n",r,c); + xf::solver::print_matrix(R, " ", + print_precision,1); + printf("TB:Fail\n"); + return(23); + } + } + } + } + */ + + // Test results + // ==================================================================== + + // Basic check cell by cell check based on allowed_ulp_mismatch value. + matched_lapack_Q = are_matrices_equal( + (MATRIX_OUT_T*)Q, (MATRIX_OUT_T*)Q_expected, allowed_ulp_mismatch, + (MATRIX_OUT_T*)Q_delta_vs_lapack); + matched_lapack_R = are_matrices_equal( + (MATRIX_OUT_T*)R, (MATRIX_OUT_T*)R_expected, allowed_ulp_mismatch, + (MATRIX_OUT_T*)R_delta_vs_lapack); + + // Test Criteria + // - Uses a norm based test against a threshold for Q and R: + // norm(R - Q'*A)/(rows * norm(A) * EPS) + // norm(I - Q'*Q)/(rows * EPS) + // - Our intention is to compare the LAPACK result ratio against our function ratio and compare those + // figures. + // - Can remove the divisor as both ratios will be scaled in the same way. Removes uncertainity about + // what EPS should be + // - SO just compare norms of delta? + // - Might be usefull to consider the relative values when trying to determine a threshold for a + // "fail" + // - Will use the LAPACK norm function.....yet another horrible function call..... + // TODO/WARNING: Using implementation types. When fixed complex will have bit growth issues....should we + // cast everything to double... + mmult(Q, A_cast, R_restored); + mmult( + Q_expected, A_cast, R_restored_lapack); // LAPACK produces Q such that Q*R=A, so we (conjugate) + // transpose Q to compute Q*A = R + msub(R, R_restored, R_delta); + msub(R_expected, R_restored_lapack, R_delta_lapack); + + // norm1 as used in SPOT01 + // This norm needs to be computed in double precision to avoid overflow, as the elements can be quite + // large for the 1/Min norm case (imat=8) + A_norm = norm1_dbl(A_cast); + + if (isinf(A_norm)) { + // Should never be Inf - if it is, we've probably overflowed + printf("ERROR: Caught unexpected Inf for A_norm\n"); + printf("TB:Fail\n"); + return (3); + } + + // norm1 as used in SPOT01 + R_delta_norm = norm1(R_delta); + + // norm1 as used in SPOT01 + R_delta_lapack_norm = norm1(R_delta_lapack); + + //---------------------------------------------------------------------------------------------------------------------------------------- + // printf("A_norm %.15f R_delta_norm %.15f R_delta_lapack_norm %.15f\n",A_norm , R_delta_norm , + // R_delta_lapack_norm ); + + // printf("A \n"); + // xf::solver::print_matrix(A, " ", + // print_precision,1); + + // printf("A_cast \n"); + // xf::solver::print_matrix(A_cast, " ", + // print_precision,1); + + // printf("Q \n"); + // xf::solver::print_matrix(Q, " ", + // print_precision,1); + // printf("Q_expected\n"); + // xf::solver::print_matrix(Q_expected, " ", + // print_precision,1); + + // printf("Q' \n"); + // xf::solver::print_matrix(Q, " ", + // print_precision,1); + // printf("Q'_expected\n"); + // xf::solver::print_matrix(Q_expected, " + // ", + // print_precision,1); + + // printf("R \n"); + // xf::solver::print_matrix(R, " ", + // print_precision,1); + // printf("R_expected\n"); + // xf::solver::print_matrix(R_expected, " ", + // print_precision,1); + + // printf("R_delta \n"); + // xf::solver::print_matrix(R_delta, " ", + // print_precision,1); + // printf("R_delta_lapack\n"); + // xf::solver::print_matrix(R_delta_lapack, " ", + // print_precision,1); + + // printf("R_restored \n"); + // xf::solver::print_matrix(R_restored, " ", + // print_precision,1); + // printf("R_restored_lapack \n"); + // xf::solver::print_matrix(R_restored_lapack, " + // ", + // print_precision,1); + //---------------------------------------------------------------------------------------------------------------------------------------- + + R_DUT_ratio = (double)R_delta_norm / ((double)A_ROWS * (double)A_norm * (double)eps); + std::cout << R_DUT_ratio << " " << R_delta_norm << " " << A_ROWS << " " << A_norm << " " << eps + << std::endl; + R_LAPACK_ratio = (double)R_delta_lapack_norm / ((double)A_ROWS * (double)A_norm * (double)eps); + + // Check that the norm values are OK and we are not comparing two bad ratios + // + if (isnan(R_DUT_ratio)) { + // Should only be NaN if A_norm was zero, so check that + if (A_norm != 0) { + printf("ERROR: Caught unexpected NaN for R_DUT_ratio\n"); + printf("TB:Fail\n"); + return (4); + } + } + + if (isnan(R_LAPACK_ratio)) { + // Should only be NaN if A_norm was zero, so check that + if (A_norm != 0) { + printf("ERROR: Caught unexpected NaN for R_LAPACK_ratio\n"); + printf("TB:Fail\n"); + return (5); + } + } + + if (isinf(R_DUT_ratio)) { + // Should never be Inf + printf("ERROR: Caught unexpected Inf for R_DUT_ratio\n"); + printf("TB:Fail\n"); + return (6); + } + + if (isinf(R_LAPACK_ratio)) { + // Should never be Inf + printf("ERROR: Caught unexpected Inf for R_LAPACK_ratio\n"); + printf("TB:Fail\n"); + return (7); + } + + if (R_DUT_ratio == 0) { + if (!(imat == 0 || imat == 1)) { + // Neither diagonal nor upper-triangular, so there should be error in the reconstruction, but we + // didn't detect that, so fail + printf("ERROR: Caught unexpected Zero for R_DUT_ratio\n"); + printf("TB:Fail\n"); + return (8); + } + } + + if (R_LAPACK_ratio == 0) { + if (!(imat == 0 || imat == 1)) { + // Neither diagonal nor upper-triangular, so there should be error in the reconstruction, but we + // didn't detect that, so fail + printf("ERROR: Caught unexpected Zero for R_LAPACK_ratio\n"); + printf("TB:Fail\n"); + return (9); + } + } + + if (R_DUT_ratio < 0) { + // Should never be less than zero - if it is, it's either an error code or something went badly + // wrong + printf("ERROR: Caught unexpected negative R_DUT_ratio\n"); + printf("TB:Fail\n"); + return (10); + } + + if (R_LAPACK_ratio < 0) { + // Should never be less than zero - if it is, it's either an error code or something went badly + // wrong + printf("ERROR: Caught unexpected negative R_LAPACK_ratio\n"); + printf("TB:Fail\n"); + return (11); + } + + // mmult performs conjugate transpose via x_conj + mmult(Q, Q, I_restored); + mmult(Q_expected, Q_expected, + I_restored_lapack); + msub(I, I_restored, I_delta); + msub(I, I_restored_lapack, I_delta_lapack); + + I_delta_norm = norm1(I_delta); + I_delta_lapack_norm = norm1(I_delta_lapack); + + ////---------------------------------------------------------------------------------------------------------------------------------------- + // printf("I_delta \n"); + // xf::solver::print_matrix(I_delta, " ", + // print_precision,1); + // printf("I_delta_lapack\n"); + // xf::solver::print_matrix(I_delta_lapack, " ", + // print_precision,1); + + // printf("I_restored \n"); + // xf::solver::print_matrix(I_restored, " ", + // print_precision,1); + // printf("I_restored_lapack \n"); + // xf::solver::print_matrix(I_restored_lapack, " + // ", + // print_precision,1); + + // printf("A_norm %f R_delta_norm %f R_delta_lapack_norm %f I_delta_norm %f I_delta_lapack_norm + // %f\n",A_norm, R_delta_norm , R_delta_lapack_norm , I_delta_norm , I_delta_lapack_norm); + ////---------------------------------------------------------------------------------------------------------------------------------------- + + I_DUT_ratio = (double)I_delta_norm / ((double)A_ROWS * (double)eps); + I_LAPACK_ratio = (double)I_delta_lapack_norm / ((double)A_ROWS * (double)eps); + + // Check that the norm values are OK and we are not comparing two bad ratios + // + if (isnan(I_DUT_ratio)) { + // Should only be NaN if A_norm was zero, so check that + if (A_norm != 0) { + printf("ERROR: Caught unexpected NaN for I_DUT_ratio\n"); + printf("TB:Fail\n"); + return (12); + } + } + + if (isnan(I_LAPACK_ratio)) { + // Should only be NaN if A_norm was zero, so check that + if (A_norm != 0) { + printf("ERROR: Caught unexpected NaN for I_LAPACK_ratio\n"); + printf("TB:Fail\n"); + return (13); + } + } + + if (isinf(I_DUT_ratio)) { + // Should never be Inf + printf("ERROR: Caught unexpected Inf for I_DUT_ratio\n"); + printf("TB:Fail\n"); + return (14); + } + + if (isinf(I_LAPACK_ratio)) { + // Should never be Inf + printf("ERROR: Caught unexpected Inf for I_LAPACK_ratio\n"); + printf("TB:Fail\n"); + return (15); + } + + if (I_DUT_ratio == 0) { + if (!(imat == 0 || imat == 1 || imat == 8)) { + // Neither diagonal nor upper-triangular nor zero matrix, so there should be error in the + // reconstruction, but we didn't detect that, so fail + printf("ERROR: Caught unexpected Zero for I_DUT_ratio\n"); + printf("TB:Fail\n"); + return (16); + } + } + + // The LAPACK result might reconstruct exactly + // if (I_LAPACK_ratio == 0) { + // if (!(imat == 0 || imat == 1)) { + // // Neither diagonal nor upper-triangular, so there should be error in the reconstruction, but we + // didn't detect that, so fail + // printf("ERROR: Caught unexpected Zero for I_LAPACK_ratio\n"); + // printf("TB:Fail\n"); + // return(17); + // } + //} + + if (I_DUT_ratio < 0) { + // Should never be less than zero - if it is, it's either an error code or something went badly + // wrong + printf("ERROR: Caught unexpected negative I_DUT_ratio\n"); + printf("TB:Fail\n"); + return (18); + } + + if (I_LAPACK_ratio < 0) { + // Should never be less than zero - if it is, it's either an error code or something went badly + // wrong + printf("ERROR: Caught unexpected negative I_LAPACK_ratio\n"); + printf("TB:Fail\n"); + return (19); + } + + // Compare DUT vs LAPACK ratios + R_ratio_difference = (R_DUT_ratio - R_LAPACK_ratio) * 100.0; + + if (R_ratio_difference > R_imat_max_ratio_diff[imat]) { + R_imat_max_ratio_diff[imat] = R_ratio_difference; + } + if (R_ratio_difference < R_imat_min_ratio_diff[imat]) { + R_imat_min_ratio_diff[imat] = R_ratio_difference; + } + + // NOTE: Not tolerance just now. + if (R_ratio_difference < 0) { + R_imat_ratio_better[imat]++; + } else if (R_ratio_difference > 0) { + R_imat_ratio_worse[imat]++; + } else { + R_imat_ratio_same[imat]++; + } + // Log max and min ratio values, use DUT value + if (R_DUT_ratio > R_imat_max_ratio[imat]) { + R_imat_max_ratio[imat] = R_DUT_ratio; + } + if (R_DUT_ratio < R_imat_min_ratio[imat]) { + R_imat_min_ratio[imat] = R_DUT_ratio; + } + + I_ratio_difference = (I_DUT_ratio - I_LAPACK_ratio) * 100.0; + if (I_ratio_difference > I_imat_max_ratio_diff[imat]) { + I_imat_max_ratio_diff[imat] = I_ratio_difference; + } + if (I_ratio_difference < I_imat_min_ratio_diff[imat]) { + I_imat_min_ratio_diff[imat] = I_ratio_difference; + } + // NOTE: Not tolerance just now. + if (I_ratio_difference < 0) { + I_imat_ratio_better[imat]++; + } else if (I_ratio_difference > 0) { + I_imat_ratio_worse[imat]++; + } else { + I_imat_ratio_same[imat]++; + } + // Log max and min ratio values, use DUT value + if (I_DUT_ratio > I_imat_max_ratio[imat]) { + I_imat_max_ratio[imat] = I_DUT_ratio; + } + if (I_DUT_ratio < I_imat_min_ratio[imat]) { + I_imat_min_ratio[imat] = I_DUT_ratio; + } + + // Determine if pass or fail. + // o Check DUT ratio against test threshold, default taken from LAPACK + if (R_DUT_ratio > R_ratio_threshold) { + std::cout << "ERROR: R_DUT_ratio(" << R_DUT_ratio << ") > R_ratio_threshold(" << R_ratio_threshold + << "). R_LAPACK ratio = " << R_LAPACK_ratio << std::endl; + R_pass_fail = 1; // Test run fails + } + if (I_DUT_ratio > Q_ratio_threshold) { + std::cout << "ERROR: I_DUT_ratio(" << I_DUT_ratio << ") > Q_ratio_threshold(" << Q_ratio_threshold + << "). I LAPACK ratio = " << I_LAPACK_ratio << std::endl; + I_pass_fail = 1; // Test run fails + } + + // Print matrices for debug when worse than LAPACK + if ((R_ratio_difference > 0 && debug > 0) || debug > 1 || R_DUT_ratio > R_ratio_threshold) { + printf(" A=\n"); + xf::solver::print_matrix(A, " ", + print_precision, 1); + printf(" Q=\n"); + xf::solver::print_matrix(Q, " ", + print_precision, 1); + printf(" Q_expeced=\n"); + xf::solver::print_matrix(Q_expected, " ", + print_precision, 1); + + printf(" R=\n"); + xf::solver::print_matrix(R, " ", + print_precision, 1); + printf(" R_expeced=\n"); + xf::solver::print_matrix(R_expected, " ", + print_precision, 1); + printf(" R_restored=\n"); + xf::solver::print_matrix(R_restored, " ", + print_precision, 1); + printf(" R_restored_lapack=\n"); + xf::solver::print_matrix( + R_restored_lapack, " ", print_precision, 1); + printf(" R_delta=\n"); + xf::solver::print_matrix(R_delta, " ", + print_precision, 1); + printf(" R_delta_lapack=\n"); + xf::solver::print_matrix(R_delta_lapack, " ", + print_precision, 1); + } + if ((I_ratio_difference > 0 && debug > 0) || debug > 1 || I_DUT_ratio > Q_ratio_threshold) { + printf(" A=\n"); + xf::solver::print_matrix(A, " ", + print_precision, 1); + printf(" I_restored=\n"); + xf::solver::print_matrix(I_restored, " ", + print_precision, 1); + printf(" I_restored_lapack=\n"); + xf::solver::print_matrix( + I_restored_lapack, " ", print_precision, 1); + printf(" I_delta=\n"); + xf::solver::print_matrix(I_delta, " ", + print_precision, 1); + printf(" I_delta_lapack=\n"); + xf::solver::print_matrix(I_delta_lapack, " ", + print_precision, 1); + } + + } // End of test loop + // printf("\n"); + } // Type test + } // Matrix type loop + + // Summary table, catagorize by input matrix (imat) type + std::cout << "" << std::endl; + std::cout << "SUMMARY_TABLE R,imat,Min Ratio,Max Ratio,Min Diff (Smaller),Max Diff (Larger),Same,Better,Worse" + << std::endl; + float R_max_ratio_diff = 0; + float R_min_ratio_diff = 0; + float R_max_ratio = 0; + float R_min_ratio = R_ratio_threshold; // as per the imat array starting point + for (int i = 0; i < NUM_MAT_TYPES; i++) { + std::cout << "SUMMARY_TABLE R," << i + 1 << "," << R_imat_min_ratio[i] << "," << R_imat_max_ratio[i] << "," + << R_imat_min_ratio_diff[i] << "," << R_imat_max_ratio_diff[i] << "," << R_imat_ratio_same[i] << "," + << R_imat_ratio_better[i] << "," << R_imat_ratio_worse[i] << std::endl; + // Calc totals + if (R_imat_max_ratio_diff[i] > R_max_ratio_diff) { + R_max_ratio_diff = R_imat_max_ratio_diff[i]; + } + if (R_imat_min_ratio_diff[i] < R_min_ratio_diff) { + R_min_ratio_diff = R_imat_min_ratio_diff[i]; + } + if (R_imat_max_ratio[i] > R_max_ratio) { + R_max_ratio = R_imat_max_ratio[i]; + } + if (R_imat_min_ratio[i] < R_min_ratio) { + R_min_ratio = R_imat_min_ratio[i]; + } + R_ratio_better += R_imat_ratio_better[i]; + R_ratio_worse += R_imat_ratio_worse[i]; + R_ratio_same += R_imat_ratio_same[i]; + } + std::cout << "SUMMARY_TABLE R,all," << R_min_ratio << "," << R_max_ratio << "," << R_min_ratio_diff << "," + << R_max_ratio_diff << "," << R_ratio_same << "," << R_ratio_better << "," << R_ratio_worse << std::endl; + + std::cout << "" << std::endl; + + std::cout << "SUMMARY_TABLE Q,imat,Min Ratio,Max Ratio,Min Diff (Smaller),Max Diff (Larger),Same,Better,Worse" + << std::endl; + float I_max_ratio_diff = 0; + float I_min_ratio_diff = 0; + float I_max_ratio = 0; + float I_min_ratio = Q_ratio_threshold; // as per the imat array starting point + for (int i = 0; i < NUM_MAT_TYPES; i++) { + std::cout << "SUMMARY_TABLE Q," << i + 1 << "," << I_imat_min_ratio[i] << "," << I_imat_max_ratio[i] << "," + << I_imat_min_ratio_diff[i] << "," << I_imat_max_ratio_diff[i] << "," << I_imat_ratio_same[i] << "," + << I_imat_ratio_better[i] << "," << I_imat_ratio_worse[i] << std::endl; + // Calc totals + if (I_imat_max_ratio_diff[i] > I_max_ratio_diff) { + I_max_ratio_diff = I_imat_max_ratio_diff[i]; + } + if (I_imat_min_ratio_diff[i] < I_min_ratio_diff) { + I_min_ratio_diff = I_imat_min_ratio_diff[i]; + } + if (I_imat_max_ratio[i] > I_max_ratio) { + I_max_ratio = I_imat_max_ratio[i]; + } + if (I_imat_min_ratio[i] < I_min_ratio) { + I_min_ratio = I_imat_min_ratio[i]; + } + I_ratio_better += I_imat_ratio_better[i]; + I_ratio_worse += I_imat_ratio_worse[i]; + I_ratio_same += I_imat_ratio_same[i]; + } + std::cout << "SUMMARY_TABLE Q,all," << I_min_ratio << "," << I_max_ratio << "," << I_min_ratio_diff << "," + << I_max_ratio_diff << "," << I_ratio_same << "," << I_ratio_better << "," << I_ratio_worse << std::endl; + if (R_pass_fail == 1 || I_pass_fail == 1) { + std::cout << "TB:Fail" << std::endl; + pass_fail = 1; + } else { + std::cout << "TB:Pass" << std::endl; + } + std::cout << "" << std::endl; + return (pass_fail); +} diff --git a/solver/L1/tests/qrf/host/test_qrf.hpp b/solver/L1/tests/qrf/host/test_qrf.hpp new file mode 100755 index 0000000000..aaf2e53848 --- /dev/null +++ b/solver/L1/tests/qrf/host/test_qrf.hpp @@ -0,0 +1,122 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DUT_QRF_H__ +#define __DUT_QRF_H__ + +#include "hls_x_complex.h" +#include "utils/x_hls_traits.h" +#include "dut_type_float.hpp" +//#include "dut_type_complex.hpp" +#include + +template +struct testbench_traits { + typedef unsigned ULP_T; + typedef double A_STIMULI_T; + typedef T BASE_T; + + // // I need this to transpose a real matrix. For complex testbenches, I need to pass + // // CONJUGATE so this sets the correct value at compile time. + // typedef hls::matrix_transpose_type __TRANSPOSE__T_; + // static const typename __TRANSPOSE__T_::transpose_t TRANSPOSE_TYPE = __TRANSPOSE__T_::TRANSPOSE; + + // I need to set the type for L_expected_raw, which is the output of the LAPACK functions. + // If T is fixed point then it is to be of type float, else T +}; + +template +struct testbench_traits > { + typedef hls::x_complex ULP_T; + typedef hls::x_complex A_STIMULI_T; + typedef T BASE_T; + + // // I need this to conjugate transpose a complex matrix + // typedef hls::matrix_transpose_type > __TRANSPOSE__T_; + // static const typename __TRANSPOSE__T_::transpose_t TRANSPOSE_TYPE = __TRANSPOSE__T_::CONJUGATE; +}; + +template +struct testbench_traits > { + typedef std::complex ULP_T; + typedef std::complex A_STIMULI_T; + typedef T BASE_T; + + // // I need this to conjugate transpose a complex matrix + // typedef hls::matrix_transpose_type > __TRANSPOSE__T_; + // static const typename __TRANSPOSE__T_::transpose_t TRANSPOSE_TYPE = __TRANSPOSE__T_::CONJUGATE; +}; +// I need to set the type for L_expected_raw, which is the output of the LAPACK functions. +// If T is fixed point then it is to be of type float, else T + +template +struct lapack_interface { + typedef T QR_TYPE; + typedef T QR_BASE_TYPE; + + static void identify() { printf(" template struct lapack_interface\n"); } +}; + +template +struct lapack_interface > { + typedef hls::x_complex QR_TYPE; + typedef T QR_BASE_TYPE; + + static void identify() { printf(" template struct lapack_interface< hls::x_complex\n"); } +}; + +template +struct lapack_interface > { + typedef std::complex QR_TYPE; + typedef T QR_BASE_TYPE; + + static void identify() { printf(" template struct lapack_interface< std::complex\n"); } +}; +template +struct lapack_interface > { + typedef double QR_TYPE; + typedef double QR_BASE_TYPE; + + static void identify() { printf(" template struct lapack_interface >{\n"); } +}; + +template +struct lapack_interface > > { + typedef hls::x_complex QR_TYPE; + typedef double QR_BASE_TYPE; + + static void identify() { + printf(" template struct lapack_interface< hls::x_complex > >{\n"); + } +}; +template +struct lapack_interface > > { + typedef std::complex QR_TYPE; + typedef double QR_BASE_TYPE; + + static void identify() { + printf(" template struct lapack_interface< std::complex > >{\n"); + } +}; + +typedef testbench_traits::BASE_T MATRIX_IN_BASE_T; +typedef lapack_interface::QR_TYPE QR_TYPE; +typedef lapack_interface::QR_BASE_TYPE QR_BASE_TYPE; + +const unsigned int NUM_MAT_TYPES = 9; +const QR_BASE_TYPE eps = hls::numeric_limits::epsilon(); + +#endif diff --git a/solver/L1/tests/qrf/host/utils.hpp b/solver/L1/tests/qrf/host/utils.hpp new file mode 100644 index 0000000000..52b4b4d712 --- /dev/null +++ b/solver/L1/tests/qrf/host/utils.hpp @@ -0,0 +1,144 @@ +/* + * Copyright 2021 Xilinx, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "hls_x_complex.h" + +template +void readTxt(std::string file, T* buffer, int size) { + int index = 0; + char line[1024] = {0}; + + std::fstream fhdl(file.c_str(), std::ios::in); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + while (fhdl.getline(line, sizeof(line))) { + std::string str(line); + std::replace(str.begin(), str.end(), ',', ' '); + std::stringstream data(str.c_str()); + data >> buffer[index++]; + if (index >= size) { + break; + } + } + fhdl.close(); +} + +template +void readTxt(std::string file, hls::x_complex* buffer, int size) { + int index = 0; + T real = 0; + T imag = 0; + hls::x_complex tmp; + char line[1024] = {0}; + + std::fstream fhdl(file.c_str(), std::ios::in); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + while (fhdl.getline(line, sizeof(line))) { + std::string str(line); + std::replace(str.begin(), str.end(), ',', ' '); + std::stringstream data(str.c_str()); + data >> real; + data >> imag; + tmp.real(real); + tmp.imag(imag); + buffer[index] = tmp; + index++; + if (index >= size) { + break; + } + } + fhdl.close(); +} + +template +void readTxt(std::string file, std::complex* buffer, int size) { + int index = 0; + T real = 0; + T imag = 0; + std::complex tmp; + char line[1024] = {0}; + + std::fstream fhdl(file.c_str(), std::ios::in); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + while (fhdl.getline(line, sizeof(line))) { + std::string str(line); + std::replace(str.begin(), str.end(), ',', ' '); + std::stringstream data(str.c_str()); + data >> real; + data >> imag; + tmp.real(real); + tmp.imag(imag); + buffer[index] = tmp; + index++; + if (index >= size) { + break; + } + } + fhdl.close(); +} + +template +void writeTxt(std::string file, T* buffer, int size) { + std::fstream fhdl(file.c_str(), std::ios::out); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " file could not open !" << std::endl; + exit(1); + } + for (int i = 0; i < size; i++) { + fhdl << buffer[i] << "\n"; + } + fhdl.close(); +} + +template +void writeTxt(std::string file, hls::x_complex* buffer, int size) { + std::fstream fhdl(file.c_str(), std::ios::out); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + for (int i = 0; i < size; i++) { + fhdl << buffer[i].real() << " "; + fhdl << buffer[i].imag() << "\n"; + } + fhdl.close(); +} + +template +void writeTxt(std::string file, std::complex* buffer, int size) { + std::fstream fhdl(file.c_str(), std::ios::out); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + for (int i = 0; i < size; i++) { + fhdl << buffer[i].real << " "; + fhdl << buffer[i].imag << "\n"; + } + fhdl.close(); +} diff --git a/solver/L1/tests/qrf/kernel/dut_type_complex.hpp b/solver/L1/tests/qrf/kernel/dut_type_complex.hpp new file mode 100755 index 0000000000..ec9f727df9 --- /dev/null +++ b/solver/L1/tests/qrf/kernel/dut_type_complex.hpp @@ -0,0 +1,13 @@ +#ifndef __DUT_TYPE__H__ +#define __DUT_TYPE__H__ + +#ifndef USE_X_COMPLEX_TEST +#define USE_X_COMPLEX_TEST +#endif + +#include "hls_x_complex.h" + +typedef hls::x_complex MATRIX_IN_T; +typedef hls::x_complex MATRIX_OUT_T; + +#endif diff --git a/vision/L2/tests/aie/blobFromImage/xf_blobfromimage.cc b/solver/L1/tests/qrf/kernel/dut_type_float.hpp old mode 100644 new mode 100755 similarity index 75% rename from vision/L2/tests/aie/blobFromImage/xf_blobfromimage.cc rename to solver/L1/tests/qrf/kernel/dut_type_float.hpp index 3828e29571..a2929f3c02 --- a/vision/L2/tests/aie/blobFromImage/xf_blobfromimage.cc +++ b/solver/L1/tests/qrf/kernel/dut_type_float.hpp @@ -14,9 +14,10 @@ * limitations under the License. */ -#include "kernels.h" -#include "imgproc/xf_blobfromimage_aie.hpp" +#ifndef __DUT_TYPE__H__ +#define __DUT_TYPE__H__ -void blobFromImage(input_window_float* input, output_window_float* output) { - xf::cv::aie::blobFromImage_api(input, output); -}; +typedef float MATRIX_IN_T; +typedef float MATRIX_OUT_T; + +#endif diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/fft_size.hpp b/solver/L1/tests/qrf/kernel/kernel_qrf.hpp old mode 100644 new mode 100755 similarity index 53% rename from dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/fft_size.hpp rename to solver/L1/tests/qrf/kernel/kernel_qrf.hpp index a5d67680c3..d090a7a60a --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_digit_reversed_order/ssr_fft_dro_r16_l256/src/fft_size.hpp +++ b/solver/L1/tests/qrf/kernel/kernel_qrf.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2019 Xilinx, Inc. + * Copyright 2021 Xilinx, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,10 +12,18 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. -*/ -//================================== End Lic ================================================= -#ifndef __FFT_SIZE_H__ -#define __FFT_SIZE_H__ -#define SSR_FFT_L (256) -#define SSR_FFT_R 16 -#endif //__FFT_SIZE_H__ + */ +#ifndef __KERNEL_QRF__ +#define __KERNEL_QRF__ +#include "dut_type_float.hpp" +#include "hls_stream.h" +//#include "dut_type_complex.hpp" + +const int A_ROWS = QRF_A_ROWS; +const int A_COLS = QRF_A_COLS; +const bool TRANSPOSED_Q = QRF_TRANSPOSED_Q; + +extern "C" void kernel_qrf_0(hls::stream& matrixAStrm, + hls::stream& matrixQStrm, + hls::stream& matrixRStrm); +#endif diff --git a/vision/L2/tests/aie/blobFromImage/s2mm.cpp b/solver/L1/tests/qrf/kernel/kernel_qrf_0.cpp old mode 100644 new mode 100755 similarity index 50% rename from vision/L2/tests/aie/blobFromImage/s2mm.cpp rename to solver/L1/tests/qrf/kernel/kernel_qrf_0.cpp index c5b0e9c095..e67956d50a --- a/vision/L2/tests/aie/blobFromImage/s2mm.cpp +++ b/solver/L1/tests/qrf/kernel/kernel_qrf_0.cpp @@ -14,25 +14,15 @@ * limitations under the License. */ -#include -#include -#include +#include "kernel_qrf.hpp" +#include "xf_solver_L1.hpp" +struct my_qrf_traits : xf::solver::qrfTraits { + static const int ARCH = SEL_ARCH; +}; -extern "C" { - -void s2mm(ap_int<32>* mem, hls::stream >& s, int size) { -#pragma HLS INTERFACE m_axi port = mem offset = slave bundle = gmem - -#pragma HLS interface axis port = s - -#pragma HLS INTERFACE s_axilite port = mem bundle = control -#pragma HLS INTERFACE s_axilite port = size bundle = control -#pragma HLS interface s_axilite port = return bundle = control - - for (int i = 0; i < size; i++) { -#pragma HLS PIPELINE II = 1 - qdma_axis<32, 0, 0, 0> x = s.read(); - mem[i] = x.data; - } -} +extern "C" void kernel_qrf_0(hls::stream& matrixAStrm, + hls::stream& matrixQStrm, + hls::stream& matrixRStrm) { + xf::solver::qrf(matrixAStrm, matrixQStrm, + matrixRStrm); } diff --git a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/run_hls.tcl b/solver/L1/tests/qrf/run_hls.tcl old mode 100755 new mode 100644 similarity index 55% rename from dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/run_hls.tcl rename to solver/L1/tests/qrf/run_hls.tcl index 89cf415e31..fa0199f481 --- a/dsp/L1/tests/hw/1dfft/fixed/fft_1d_snr/testsfft_natural_order/ssr_fft_r16_l1024/run_hls.tcl +++ b/solver/L1/tests/qrf/run_hls.tcl @@ -1,5 +1,5 @@ # -# Copyright 2019-2020 Xilinx, Inc. +# Copyright 2019-2021 Xilinx, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,18 +16,18 @@ source settings.tcl -set PROJ "prj_ssr_fft_reg_test_r16_l1024.prj" -set SOLN "solution1" +set PROJ "qrf_test.prj" +set SOLN "sol1" if {![info exists CLKP]} { - set CLKP 3.3 + set CLKP 300MHz } open_project -reset $PROJ -add_files "src/main.cpp src/hls_ssr_fft_data_path.hpp src/DEBUG_CONSTANTS.hpp" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -add_files -tb "src/main.cpp ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftStimulusIn_L1024.verif ${XF_PROJ_ROOT}/L1/tests/hw/1dfft/fixed/commonFix/verif/fftGoldenOut_L1024.verif" -cflags "-I${XF_PROJ_ROOT}/L1/include/hw/vitis_fft/fixed -I${XF_PROJ_ROOT}/L1/tests/common" -set_top fft_top +add_files "./kernel/kernel_qrf_0.cpp" -cflags "-DQRF_A_ROWS=3 -DQRF_A_COLS=3 -DQRF_TRANSPOSED_Q=0 -DSEL_ARCH=0 -I./host/ -I./kernel/ -I${XF_PROJ_ROOT}/L1/tests/ -I${XF_PROJ_ROOT}/L1/include/ -I${XF_PROJ_ROOT}/L1/include/hw -I${XF_PROJ_ROOT}/L2/include -I${XF_PROJ_ROOT}/../utils/L1/include/ " +add_files -tb "./host/test_qrf.cpp" -cflags "-DQRF_A_ROWS=3 -DQRF_A_COLS=3 -DQRF_TRANSPOSED_Q=0 -DSEL_ARCH=0 -I./host/ -I./kernel/ -I${XF_PROJ_ROOT}/L1/tests/ -I${XF_PROJ_ROOT}/L1/include/ -I${XF_PROJ_ROOT}/L1/include/hw -I ./host -I${XF_PROJ_ROOT}/../utils/L1/include/ " +set_top kernel_qrf_0 open_solution -reset $SOLN @@ -36,10 +36,9 @@ open_solution -reset $SOLN set_part $XPART create_clock -period $CLKP -config_compile -disable_auto_rewind if {$CSIM == 1} { - csim_design + csim_design -ldflags "" } if {$CSYNTH == 1} { @@ -47,7 +46,7 @@ if {$CSYNTH == 1} { } if {$COSIM == 1} { - cosim_design + cosim_design -ldflags "" } if {$VIVADO_SYN == 1} { diff --git a/solver/L1/tests/src/matrix_test_utils.hpp b/solver/L1/tests/src/matrix_test_utils.hpp new file mode 100755 index 0000000000..efa93e81c0 --- /dev/null +++ b/solver/L1/tests/src/matrix_test_utils.hpp @@ -0,0 +1,324 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _XF_SOLVER_MATRIX_TEST_UTILS_HPP_ +#define _XF_SOLVER_MATRIX_TEST_UTILS_HPP_ + +// ------------------------------------------------- +// Utilities for matrix *test* code. +// ------------------------------------------------- +// Not for use in synthesisable code +// ------------------------------------------------- + +#include "ap_fixed.h" +#include "hls_math.h" + +#include "hls_x_complex.h" +#include "utils/std_complex_utils.h" +#include "utils/x_hls_utils.h" +#include "utils/x_hls_traits.h" + +// test_utils +#include "src/x_tb_utils.hpp" +#include "src/scalar_test_utils.hpp" +#include "src/type_test_utils.hpp" + +#include +#include +#include +#include + +// Matrix Compare +// ============================================================================ + +template +bool are_matrices_equal(T* actual, T* expected, unsigned allowed_ulp_mismatch = 0, T* delta = NULL) { + bool ret = true; + + typedef xil_equality e; + + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + T a = *(expected + (r * COLS) + c); + T b = *(actual + (r * COLS) + c); + + if (delta != NULL) *(delta + (r * COLS) + c) = a - b; + + if (e::equal(a, b, allowed_ulp_mismatch) == false) { + ret = false; + } + } + } + return ret; +} + +template +bool are_matrices_equal(T actual[ROWS][COLS], + T expected[ROWS][COLS], + unsigned allowed_ulp_mismatch = 0, + T* delta = NULL) { + return are_matrices_equal((T*)actual, (T*)expected, allowed_ulp_mismatch, delta); +} + +// Generic test for NaN anywhere in a floating-point matrix +template +int anyNaN(T A[ROWS][COLS]) { + int foundNaN = 0; + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + if (hls::__isnan(A[r][c]) == 1) { + foundNaN = 1; + } + } + } + return foundNaN; +} + +// Generic test for NaN anywhere in a complex-valued floating-point matrix +template +int anyNaN(hls::x_complex A[ROWS][COLS]) { + int foundNaN = 0; + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + if (hls::__isnan(hls::x_real(A[r][c])) == 1 || hls::__isnan(hls::x_imag(A[r][c])) == 1) { + foundNaN = 1; + } + } + } + return foundNaN; +} +template +int anyNaN(std::complex A[ROWS][COLS]) { + int foundNaN = 0; + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + if (hls::__isnan(hls::x_real(A[r][c])) == 1 || hls::__isnan(hls::x_imag(A[r][c])) == 1) { + foundNaN = 1; + } + } + } + return foundNaN; +} +// NaN does not apply for fixed-point +template +int anyNaN(ap_fixed A[ROWS][COLS]) { + return 0; +} + +// NaN does not apply for complex fixed-point +template +int anyNaN(hls::x_complex > A[ROWS][COLS]) { + return 0; +} + +template +int anyNaN(std::complex > A[ROWS][COLS]) { + return 0; +} +// Basic matrix operations +// ============================================================================ + +// Basic matrix mult +template +void mmult(const T_IN A[AROWS][ACOLS], const T_IN B[BROWS][BCOLS], T_OUT C[CROWS][CCOLS]) { + const int AROWS_INT = (transA ? ACOLS : AROWS); + const int ACOLS_INT = (transA ? AROWS : ACOLS); + const int BROWS_INT = (transB ? BCOLS : BROWS); + const int BCOLS_INT = (transB ? BROWS : BCOLS); + + assert(ACOLS_INT == BROWS_INT); + assert(CROWS == AROWS_INT); + assert(CCOLS == BCOLS_INT); + + T_IN a_tmp, b_tmp; + T_OUT sum; + for (int a_row = 0; a_row < AROWS_INT; a_row++) { + for (int b_col = 0; b_col < BCOLS_INT; b_col++) { + sum = 0; + for (int i = 0; i < ACOLS_INT; i++) { + if (transA) { + a_tmp = hls::x_conj(A[i][a_row]); + } else { + a_tmp = A[a_row][i]; + } + if (transB) { + b_tmp = hls::x_conj(B[b_col][i]); + } else { + b_tmp = B[i][b_col]; + } + sum = sum + (a_tmp * b_tmp); + } + C[a_row][b_col] = sum; + } + } +}; + +// Basic sub +template +int msub(const T_IN A[ROWS][COLS], const T_IN B[ROWS][COLS], T_OUT C[ROWS][COLS]) { + T_IN tmp; + for (int row = 0; row < ROWS; row++) { + for (int col = 0; col < COLS; col++) { + // Hack due to the rubish implementation of the x_complex LHS can't be a const.... + tmp = A[row][col]; + C[row][col] = tmp - B[row][col]; + } + } + return 0; +}; + +// Matrix Conditioning +// ============================================================================ + +template +void set_upper_triangle_to_zero(T* a, unsigned dim) { + for (int r = 0; r < dim; r++) { + for (int c = r + 1; c < dim; c++) { + *(a + (r * dim) + c) = 0.0; + } + } +} + +template +void set_lower_triangle_to_zero(T* a, unsigned dim) { + for (int r = 0; r < dim; r++) { + for (int c = 0; c < r; c++) { + *(a + (r * dim) + c) = 0.0; + } + } +} + +template +T_BASE norm1_magnitude(T_BASE re, T_BASE im) { + const T_BASE ONE = 1.0f; // REVISIT: not suitable for double + const T_BASE ZERO = 0.0f; + T_BASE t; + + re = solver_tb::fabs(re); // should call float version of fabs in C++? + im = solver_tb::fabs(im); + if (re > im) { + t = im / re; + return re * sqrt(ONE + t * t); // should call float version of sqrt in C++? + } else { + if (im == ZERO) { + return ZERO; + } + t = re / im; + return im * sqrt(ONE + t * t); + } +} + +template +T_BASE norm1_abs(T x) { + T_BASE y; + y = norm1_magnitude(hls::x_real(x), hls::x_imag(x)); + return y; +} + +// Compute 1-norm of a matrix directly +template +T_BASE norm1(T in[ROWS][COLS]) { + T_BASE norm = 0; + T_BASE norm_cols[COLS]; + + // Initialise + for (int c = 0; c < COLS; c++) { + norm_cols[c] = 0; + } + + // Sum column absolute values + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + norm_cols[c] += norm1_abs(in[r][c]); + } + } + + // Find largest column sum + for (int c = 0; c < COLS; c++) { + if (norm_cols[c] > norm) { + norm = norm_cols[c]; + } + } + + return norm; +} + +// Variant of norm1 which computes in double and returns double. +// This is necessary for computing the 1-norm of A, as very large values can +// cause float to overflow. +template +double norm1_dbl(T in[ROWS][COLS]) { + double norm = 0; + double norm_cols[COLS]; + + // Initialise + for (int c = 0; c < COLS; c++) { + norm_cols[c] = 0; + } + + // Sum column absolute values + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + norm_cols[c] += norm1_abs(in[r][c]); + } + } + + // Find largest column sum + for (int c = 0; c < COLS; c++) { + if (norm_cols[c] > norm) { + norm = norm_cols[c]; + } + } + + return norm; +} + +// Checks the TB generated test criteria ratios: +// - isnan +// - isinf +// - iszero - optional. Default disabled +// - less than zero +// Returns non-zero if test fails +int check_ratio(double ratio, bool check_is_zero = false) { + if (isnan(ratio)) { + std::cout << "ERROR: check_ratio: ISNAN" << std::endl; + return (1); + } + if (isinf(ratio)) { + std::cout << "ERROR: check_ratio: ISINF" << std::endl; + return (2); + } + if (ratio == 0 && check_is_zero) { + std::cout << "ERROR: check_ratio: Is zero" << std::endl; + return (4); + } + if (ratio < 0) { + std::cout << "ERROR: check_ratio: Negative ratio: " << ratio << std::endl; + return (1); + } + return (0); +} + +#endif diff --git a/solver/L1/tests/src/scalar_test_utils.hpp b/solver/L1/tests/src/scalar_test_utils.hpp new file mode 100755 index 0000000000..b0f82611f9 --- /dev/null +++ b/solver/L1/tests/src/scalar_test_utils.hpp @@ -0,0 +1,82 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _XF_SOLVER_SCALAR_TEST_UTILS_HPP_ +#define _XF_SOLVER_SCALAR_TEST_UTILS_HPP_ + +// ------------------------------------------------- +// Utilities for scalar *test* code. +// ------------------------------------------------- +// Not for use in synthesisable code +// ------------------------------------------------- + +#include "ap_fixed.h" + +#include "hls_x_complex.h" +#include + +// ====================================================================== +// Compare a single value +// ====================================================================== +// +// Using a struct to allow different types of equality to be added later +// (e.g. GE, NE, etc). +// +template +struct xil_equality { + static bool equal(T a, T b, unsigned allowed_ulp_mismatch) { + int diff = calcULP(a, b); + if (diff <= allowed_ulp_mismatch) + return true; + else + return false; + } +}; + +// Complex data +// ---------------- +// This is used by complex data of any type. A xil_equality is called to compare the real and imaginary +// parts, so this just handles the calling of the individual parts +// +template +struct xil_equality > { + static bool equal(hls::x_complex a, hls::x_complex b, unsigned allowed_ulp_mismatch) { + // Use the basic type equals to compare the real and imaginary parts + // + typedef xil_equality e; + + if (e::equal(a.real(), b.real(), allowed_ulp_mismatch) && e::equal(a.imag(), b.imag(), allowed_ulp_mismatch)) + return true; + else + return false; + } +}; +template +struct xil_equality > { + static bool equal(std::complex a, std::complex b, unsigned allowed_ulp_mismatch) { + // Use the basic type equals to compare the real and imaginary parts + // + typedef xil_equality e; + + if (e::equal(a.real(), b.real(), allowed_ulp_mismatch) && e::equal(a.imag(), b.imag(), allowed_ulp_mismatch)) + return true; + else + return false; + } +}; +// ==End: Compare a single value ======================================== + +#endif diff --git a/solver/L1/tests/src/type_test_utils.hpp b/solver/L1/tests/src/type_test_utils.hpp new file mode 100755 index 0000000000..ed327b8d8e --- /dev/null +++ b/solver/L1/tests/src/type_test_utils.hpp @@ -0,0 +1,242 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _XF_SOLVER_TYPE_TEST_UTILS_HPP_ +#define _XF_SOLVER_TYPE_TEST_UTILS_HPP_ + +// ------------------------------------------------- +// Utilities for *test* code to help work with types +// ------------------------------------------------- +// Not for use in synthesisable code +// ------------------------------------------------- + +// ====================================================================== +// Type identification +// ====================================================================== +// +#include + +// Generic types +// ------------- +template +bool x_is_float(T x) { + return false; +}; +template +bool x_is_double(T x) { + return false; +}; +template +bool x_is_fixed(T x) { + return false; +}; +template +bool x_is_complex(T x) { + return false; +}; + +// Floats +// ------ +template <> +bool x_is_float(float x) { + return true; +}; +template <> +bool x_is_double(float x) { + return false; +}; +template <> +bool x_is_fixed(float x) { + return false; +}; +template <> +bool x_is_complex(float x) { + return false; +}; + +// Doubles +// ------ +template <> +bool x_is_float(double x) { + return false; +}; +template <> +bool x_is_double(double x) { + return true; +}; +template <> +bool x_is_fixed(double x) { + return false; +}; +template <> +bool x_is_complex(double x) { + return false; +}; + +// Fixed point +// ------ +template +bool x_is_float(ap_fixed x) { + return false; +}; +template +bool x_is_double(ap_fixed x) { + return false; +}; +template +bool x_is_fixed(ap_fixed x) { + return true; +}; +template +bool x_is_complex(ap_fixed x) { + return false; +}; + +// Complex +// --------- + +template +bool x_is_complex(hls::x_complex x) { + return true; +}; + +template <> +bool x_is_float(hls::x_complex x) { + return true; +}; +template <> +bool x_is_float(hls::x_complex x) { + return false; +}; +template +bool x_is_float(hls::x_complex > x) { + return false; +}; + +template <> +bool x_is_double(hls::x_complex x) { + return false; +}; +template <> +bool x_is_double(hls::x_complex x) { + return true; +}; +template +bool x_is_double(hls::x_complex > x) { + return false; +}; + +template <> +bool x_is_fixed(hls::x_complex x) { + return false; +}; +template <> +bool x_is_fixed(hls::x_complex x) { + return false; +}; +template +bool x_is_fixed(hls::x_complex > x) { + return true; +}; + +template +bool x_is_complex(std::complex x) { + return true; +}; + +template <> +bool x_is_float(std::complex x) { + return true; +}; +template <> +bool x_is_float(std::complex x) { + return false; +}; +template +bool x_is_float(std::complex > x) { + return false; +}; + +template <> +bool x_is_double(std::complex x) { + return false; +}; +template <> +bool x_is_double(std::complex x) { + return true; +}; +template +bool x_is_double(std::complex > x) { + return false; +}; + +template <> +bool x_is_fixed(std::complex x) { + return false; +}; +template <> +bool x_is_fixed(std::complex x) { + return false; +}; +template +bool x_is_fixed(std::complex > x) { + return true; +}; + +// ====================================================================== +// End: Type identification +// ====================================================================== + +// Some test code for type identification: +// float f; +// double d; +// ap_fixed<16, 1> fxd; +// x_complex comp_f; +// x_complex comp_d; +// x_complex > comp_fxd; +// +// printf("x_is_float (f ) = %d\n", x_is_float (f ) ); +// printf("x_is_float (d ) = %d\n", x_is_float (d ) ); +// printf("x_is_float (fxd) = %d\n", x_is_float (fxd) ); +// printf("x_is_float (comp_f ) = %d\n", x_is_float (comp_f ) ); +// printf("x_is_float (comp_d ) = %d\n", x_is_float (comp_d ) ); +// printf("x_is_float (comp_fxd) = %d\n", x_is_float (comp_fxd) ); +// +// printf("x_is_double (f ) = %d\n", x_is_double (f ) ); +// printf("x_is_double (d ) = %d\n", x_is_double (d ) ); +// printf("x_is_double (fxd) = %d\n", x_is_double (fxd) ); +// printf("x_is_double (comp_f ) = %d\n", x_is_double (comp_f ) ); +// printf("x_is_double (comp_d ) = %d\n", x_is_double (comp_d ) ); +// printf("x_is_double (comp_fxd) = %d\n", x_is_double (comp_fxd) ); +// +// printf("x_is_fixed (f ) = %d\n", x_is_fixed (f ) ); +// printf("x_is_fixed (d ) = %d\n", x_is_fixed (d ) ); +// printf("x_is_fixed (fxd) = %d\n", x_is_fixed (fxd) ); +// printf("x_is_fixed (comp_f ) = %d\n", x_is_fixed (comp_f ) ); +// printf("x_is_fixed (comp_d ) = %d\n", x_is_fixed (comp_d ) ); +// printf("x_is_fixed (comp_fxd) = %d\n", x_is_fixed (comp_fxd) ); +// +// printf("x_is_complex (f ) = %d\n", x_is_complex (f ) ); +// printf("x_is_complex (d ) = %d\n", x_is_complex (d ) ); +// printf("x_is_complex (fxd) = %d\n", x_is_complex (fxd) ); +// printf("x_is_complex (comp_f ) = %d\n", x_is_complex (comp_f ) ); +// printf("x_is_complex (comp_d ) = %d\n", x_is_complex (comp_d ) ); +// printf("x_is_complex (comp_fxd) = %d\n", x_is_complex (comp_fxd) ); +// +// +// exit(0); + +#endif diff --git a/solver/L1/tests/src/utils.hpp b/solver/L1/tests/src/utils.hpp new file mode 100644 index 0000000000..96a78224c6 --- /dev/null +++ b/solver/L1/tests/src/utils.hpp @@ -0,0 +1,149 @@ +/* + * Copyright 2021 Xilinx, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _XF_SOLVER_UTILS_HPP_ +#define _XF_SOLVER_UTILS_HPP_ + +#include +#include +#include +#include +#include +#include "hls_x_complex.h" + +template +void readTxt(std::string file, T* buffer, int size) { + int index = 0; + char line[1024] = {0}; + + std::fstream fhdl(file.c_str(), std::ios::in); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + while (fhdl.getline(line, sizeof(line))) { + std::string str(line); + std::replace(str.begin(), str.end(), ',', ' '); + std::stringstream data(str.c_str()); + data >> buffer[index++]; + if (index >= size) { + break; + } + } + fhdl.close(); +} + +template +void readTxt(std::string file, hls::x_complex* buffer, int size) { + int index = 0; + T real = 0; + T imag = 0; + hls::x_complex tmp; + char line[1024] = {0}; + + std::fstream fhdl(file.c_str(), std::ios::in); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + while (fhdl.getline(line, sizeof(line))) { + std::string str(line); + std::replace(str.begin(), str.end(), ',', ' '); + std::stringstream data(str.c_str()); + data >> real; + data >> imag; + tmp.real(real); + tmp.imag(imag); + buffer[index] = tmp; + index++; + if (index >= size) { + break; + } + } + fhdl.close(); +} + +template +void readTxt(std::string file, std::complex* buffer, int size) { + int index = 0; + T real = 0; + T imag = 0; + std::complex tmp; + char line[1024] = {0}; + + std::fstream fhdl(file.c_str(), std::ios::in); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + while (fhdl.getline(line, sizeof(line))) { + std::string str(line); + std::replace(str.begin(), str.end(), ',', ' '); + std::stringstream data(str.c_str()); + data >> real; + data >> imag; + tmp.real(real); + tmp.imag(imag); + buffer[index] = tmp; + index++; + if (index >= size) { + break; + } + } + fhdl.close(); +} + +template +void writeTxt(std::string file, T* buffer, int size) { + std::fstream fhdl(file.c_str(), std::ios::out); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " file could not open !" << std::endl; + exit(1); + } + for (int i = 0; i < size; i++) { + fhdl << buffer[i] << "\n"; + } + fhdl.close(); +} + +template +void writeTxt(std::string file, hls::x_complex* buffer, int size) { + std::fstream fhdl(file.c_str(), std::ios::out); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + for (int i = 0; i < size; i++) { + fhdl << buffer[i].real() << " "; + fhdl << buffer[i].imag() << "\n"; + } + fhdl.close(); +} + +template +void writeTxt(std::string file, std::complex* buffer, int size) { + std::fstream fhdl(file.c_str(), std::ios::out); + if (!fhdl) { + std::cout << "[ERROR] File: " << file << " could not open !" << std::endl; + exit(1); + } + for (int i = 0; i < size; i++) { + fhdl << buffer[i].real << " "; + fhdl << buffer[i].imag << "\n"; + } + fhdl.close(); +} + +#endif diff --git a/solver/L1/tests/src/x_tb_utils.hpp b/solver/L1/tests/src/x_tb_utils.hpp new file mode 100644 index 0000000000..ec04457568 --- /dev/null +++ b/solver/L1/tests/src/x_tb_utils.hpp @@ -0,0 +1,4841 @@ +/* + * Copyright 2021 Xilinx, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the Licens/. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _XF_SOLVER_X_TB_UTILS_HPP_ +#define _XF_SOLVER_X_TB_UTILS_HPP_ + +#include +#include +#include +#include +#include +#include "utils/x_hls_utils.h" +#include "ap_fixed.h" +#include +#include +#include "utils/x_hls_defines.h" +#include "utils/x_hls_traits.h" +#include +#include +#include "hls_half.h" +#include "hls_x_complex.h" +#include + +namespace solver_tb { +template +struct enable_if {}; + +template +struct enable_if { + typedef T type; +}; +template +struct integral_constant { + static const T value = _v; + typedef T value_type; + typedef integral_constant type; + operator value_type() { return value; } +}; + +typedef integral_constant true_type; +typedef integral_constant false_type; + +template +struct is_same; + +template +struct is_same : public false_type {}; + +template +struct is_same : public true_type {}; + +template +struct is_arithmetic : public integral_constant::value || is_fptype::value)> {}; +} + +#include +#include + +// Dump a C++ type... useful for debugging templates. +template +static void dump_type(std::ostream& os) { + size_t len; + int s; + char* p = abi::__cxa_demangle(typeid(T).name(), 0, &len, &s); + os << p; +} + +// return the max/min value of a specific integer type +template +class max_min_ { + public: + max_min_() { + _max = ((T)(-1) > 0) ? (((1ULL << Type_BitWidth::Value) - 1) * 2 + 1) + : ((1ULL << (Type_BitWidth::Value - 1)) - 1); + _min = ((T)(-1) > 0) ? 0 : -(1ULL << (Type_BitWidth::Value - 1)); + } + T _max; + T _min; +}; + +template +struct binary_spec { + template + static std::string f(T x); +}; + +template <> +struct binary_spec { + template + static std::string f(T x) { + std::stringstream s; + s << std::hex << x; + return s.str(); + } +}; + +template <> +struct binary_spec { + template + static std::string f(T x) { + char s2[1024]; + snprintf(s2, 1024, "%a", x); + std::stringstream s; + s << std::hex << fp_struct(x).data() << " " << s2; + return s.str(); + } +}; + +template +std::string binary(T x) { + return binary_spec::is_integer>::f(x); +} + +#ifdef X_AP_FLOAT_H +template +std::string binary(ap_float x) { + return x.to_string(16); +} +#endif + +template +std::string binary(ap_fixed x) { + return x.to_string(16); +} + +template +std::string binary(ap_ufixed x) { + return x.to_string(16); +} + +template +std::string binary(ap_int x) { + return x.to_string(16); +} + +template +std::string binary(ap_uint x) { + return x.to_string(16); +} + +static std::string binary(std::string x) { + return x; +} + +static std::string binary(half x) { + float f = x; + char s2[1024]; + snprintf(s2, 1024, "%a", f); + std::stringstream s; + s << std::hex << x.get_bits() << " " << s2; + return s.str(); +} +namespace solver_tb { +#ifdef X_AP_FLOAT_H +template +ap_float fabs(ap_float x) { + return x > 0 ? ap_float(x) : ap_float(-x); +} +#endif + +template +ap_fixed fabs(ap_fixed x) { + return x > 0 ? ap_fixed(x) : ap_fixed(-x); +} + +template +ap_ufixed fabs(ap_ufixed x) { + return x; +} + +template +ap_int fabs(ap_int x) { + return x > 0 ? ap_int(x) : ap_int(-x); +} + +template +ap_uint fabs(ap_uint x) { + return x; +} + +template +T fabs(T x) { + return std::fabs(x); +} +} + +#ifdef X_AP_FLOAT_H +template +bool generic_isnan(ap_float x) { + return false; +} +#endif + +template +bool generic_isnan(ap_fixed x) { + return false; +} + +template +bool generic_isnan(ap_ufixed x) { + return false; +} + +template +bool generic_isnan(ap_int x) { + return false; +} + +template +bool generic_isnan(ap_uint x) { + return false; +} + +#ifndef AESL_SYN +static bool generic_isnan(half x) { + return detail::isnan(x); +} +#endif + +template +bool generic_isnan(T x) { + return std::isnan(x); +} + +#ifdef X_AP_FLOAT_H +template +bool generic_issubnormal(ap_float x) { + return false; +} +#endif +template +bool generic_issubnormal(ap_fixed x) { + return false; +} + +template +bool generic_issubnormal(ap_ufixed x) { + return false; +} + +template +bool generic_issubnormal(ap_int x) { + return false; +} + +template +bool generic_issubnormal(ap_uint x) { + return false; +} + +static bool generic_issubnormal(half x) { + return (detail::fpclassify(x) == FP_SUBNORMAL); +} + +template +bool generic_issubnormal(T x) { + return (std::fpclassify(x) == FP_SUBNORMAL); +} + +static void load_from_file(char* file_name, int* destination_array, int array_size) { + /*======================================================*/ + /* Loads the data from .txt file created in MATLAB. */ + /* Used in testbench scenarios to perform data testing */ + /*======================================================*/ + + FILE* file_id; + int counter; + + printf("Loading from file %s\n", file_name); + file_id = fopen(file_name, "r"); + if (file_id != NULL) { + printf("File name valid!\n"); + for (counter = 0; counter < array_size; counter++) { + fscanf(file_id, "%i", &destination_array[counter]); + } + fclose(file_id); + } else { + printf("File %s not found.\n", file_name); + } +} + +template +void load_from_file(char* file_name, T* destination_array, int array_size) { + /*======================================================*/ + /* Loads the data from .txt file created in MATLAB. */ + /* Used in testbench scenarios to perform data testing */ + /*======================================================*/ + + FILE* file_id; + int counter; + + printf("Loading from file %s\n", file_name); + file_id = fopen(file_name, "r"); + if (file_id != NULL) { + printf("File name valid!\n"); + for (counter = 0; counter < array_size; counter++) { + fscanf(file_id, "%e", &destination_array[counter]); + } + fclose(file_id); + } else { + printf("File %s not found.\n", file_name); + } +} + +static void save_to_file(char* file_name, int* source_array, int array_size) { + /*======================================================*/ + /* Saves the data to a txt. The files are used */ + /* for comparison to expected, MATLAB generated values */ + /*======================================================*/ + + FILE* file_id; + int counter; + + file_id = fopen(file_name, "w+"); + if (file_id != NULL) { + for (counter = 0; counter < array_size; counter++) { + fprintf(file_id, "%d\n", source_array[counter]); + } + fclose(file_id); + } +} + +template +void save_to_file(char* file_name, T* source_array, int array_size) { + /*======================================================*/ + /* Saves the data to a txt. The files are used */ + /* for comparison to expected, MATLAB generated values */ + /*======================================================*/ + + FILE* file_id; + int counter; + + file_id = fopen(file_name, "w+"); + if (file_id != NULL) { + for (counter = 0; counter < array_size; counter++) { + fprintf(file_id, "%e\n", source_array[counter]); + } + fclose(file_id); + } +} + +/* +* return value +* 0: failed, 1: passed +*/ + +/* +* Compare values approximately. +* Returns true if error is within a certain threshold (0.1%) +*/ +static int comp_approx(float d1, float d2, float base, float err) { + float diff = solver_tb::fabs(d1 - d2); + float perc = 100 * diff / base; + printf("comp_approx (%e, %e), delta: %e, base: %e\n", d1, d2, perc, base); + if (perc >= err) printf("Exceed error threshold!\n"); + return (perc < err); +} + +template +int compare_files( + ap_fixed dummy, char* expected_file, char* generated_file, int start_index, int stop_index) { + /*======================================================*/ + /* Compares the values from two txt files. If the */ + /* the values differ, the values are printed in the */ + /* in the command line. It is possible to specify the */ + /* range of the compared values */ + /*======================================================*/ + + FILE *exp_file_id, *gen_file_id; + int counter; + int error_count = 0; + int expected_value, generated_value; + + exp_file_id = fopen(expected_file, "r"); + gen_file_id = fopen(generated_file, "r"); + if (exp_file_id == NULL) { + printf("Failed to open expected file!\n"); + return 0; + } else { + if (gen_file_id == NULL) { + printf("Failed to open generated file!\n"); + return 0; + } else { + for (counter = 0; counter < stop_index; counter++) { + fscanf(exp_file_id, "%i", &expected_value); + fscanf(gen_file_id, "%i", &generated_value); + if (counter >= start_index - 1) { + if (expected_value != generated_value) { + // Debug code + error_count = error_count + 1; + if (error_count <= 10) { + printf("Error! Line: %i, Expected: %i; Generated: %i\n", counter, expected_value, + generated_value); + } + if (error_count == 11) { + printf("To many errors, abort displaying...\n"); + } + + return 0; + } + } + } + fclose(gen_file_id); + } + fclose(exp_file_id); + } + + return 1; +} + +static int scan_file_for_avg(float dummy, char* target_file, int start_index, int stop_index, float& avg) { + FILE* file_id; + int counter; + float value; + + avg = 0.0; + + file_id = fopen(target_file, "r"); + if (file_id == NULL) { + printf("Failed to open file!\n"); + return 0; + } else { + counter = 0; + while (counter < stop_index) { + fscanf(file_id, "%e", &value); + if (counter >= start_index - 1) { + avg += solver_tb::fabs(value); + counter++; + // printf("current avg = %e (%e/%d), val: %e\n",avg/counter,avg,counter,value); + } + } + fclose(file_id); + } + avg = avg / counter; + printf("Scan for file avg: %e (%d)\n", avg, counter); + + return 1; +} + +static int compare_files( + float dummy, char* expected_file, char* generated_file, int start_index, int stop_index, float base, float err) { + /*======================================================*/ + /* Compares the values from two txt files. If the */ + /* the values differ, the values are printed in the */ + /* in the command line. It is possible to specify the */ + /* range of the compared values */ + /*======================================================*/ + + // float base = 0.0; + // scan_file_for_avg(dummy, expected_file, start_index, stop_index, base); + + FILE *exp_file_id, *gen_file_id; + int counter; + int error_count = 0; + float expected_value, generated_value; + + exp_file_id = fopen(expected_file, "r"); + gen_file_id = fopen(generated_file, "r"); + if (exp_file_id == NULL) { + printf("Failed to open expected file!\n"); + return 0; + } else { + if (gen_file_id == NULL) { + printf("Failed to open generated file!\n"); + return 0; + } else { + for (counter = 0; counter < stop_index; counter++) { + fscanf(exp_file_id, "%e", &expected_value); + fscanf(gen_file_id, "%e", &generated_value); + if (counter >= start_index - 1) { + // if(expected_value != generated_value) + if (!comp_approx(expected_value, generated_value, base, err)) { + // Debug code + error_count = error_count + 1; + if (error_count <= 10) { + printf("Error! Line: %i, Expected: %e; Generated: %e\n", counter, expected_value, + generated_value); + } + if (error_count == 11) { + printf("To many errors, abort displaying...\n"); + } + + return 0; + } + } + } + fclose(gen_file_id); + } + fclose(exp_file_id); + } + + return 1; +} + +static void dump(float a) { + printf("%e\n", a); +} + +template +void dump(ap_fixed a) { + printf("%e\n", a.to_float()); +} + +// static +// void +// dump(x_complex a) { +// printf("(%e,%e)\n",a.real(),a.imag()); +// } + +template +void dump(float_struct a) { + printf("(mant.x,exp.d,sign.d)(%x,%d,%d)\n", a.mant.to_uint(), a.exp.to_uint(), a.sign.to_uint()); +} + +// template +// void +// dump(x_complex > a) { +// printf("(mant.x,exp.d,sign.d)(%x,%d,%d)(%x,%d,%d)\n",a.real().mant.to_uint(),a.real().exp.to_uint(),a.real().sign.to_uint(),a.imag().mant.to_uint(),a.imag().exp.to_uint(),a.imag().sign.to_uint()); +// } + +// template +// void +// dump(x_complex > a) { +// printf("(%x,%x)\n",a.real().to_int(),a.imag().to_int()); +// } + +// template +// void +// dump(x_complex > a) { +// printf("(%e,%e)\n",a.real().to_int(),a.imag().to_int()); +// } + +template +void dumpv(float a[DIM]) { + for (int i = 0; i < DIM; i++) { + printf("%e ", a[i]); + } + printf("\n"); +} + +// template +// void +// dumpv( +// x_complex a[DIM]) +// { +// for(int i=0; i +// void +// dumpv( +// x_complex > a[DIM]) +// { +// for(int i=0; i +void dumpm(float a[ROWS][COLS][_TDM_CHUNKS]) { + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLS; j++) { + float tmp = (TRANS) ? a[j][i][0] : a[i][j][0]; + printf("%e\t", tmp); + } + printf("\n"); + } + printf("\n"); +} + +template +void dumpm(ap_fixed a[ROWS][COLS][_TDM_CHUNKS]) { + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLS; j++) { + float tmp = (TRANS) ? a[j][i][0] : a[i][j][0]; + printf("%e\t", tmp); + } + printf("\n"); + } + printf("\n"); +} + +// template +// void +// dumpm( +// x_complex in_a[ROWS][COLS][_TDM_CHUNKS]) +// { +// printf("Real matrix\n"); +// for(int i=0; i +void dumpm_div_2(float a[DIM / 2][DIM / 2]) { + for (int i = 0; i < DIM / 2; i++) { + for (int j = 0; j < DIM / 2; j++) { + printf("%e\t", a[i][j]); + } + printf("\n"); + } + printf("\n"); +} + +/* +* chunks: <0 : all chunks, else chunk num +* +*/ +template +void dumpmf(float a[ROWS][COLS][CHUNKS], int chunks) { + int maxchunk, ch; + + if (chunks < 0) { + maxchunk = CHUNKS; + ch = 0; + } else { + maxchunk = chunks + 1; + ch = chunks; + } + for (; ch < maxchunk; ch++) { + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLS; j++) { + printf("%e\t", a[i][j][ch]); + } + printf("\n"); + } + printf("\n"); + } +} + +/* +* Dump out the complex transformation matrices +*/ +template +void dumpct(float tl_w_re[DIM / 2][DIM / 2], + float tl_x_re[DIM / 2][DIM / 2], + float tl_y_re[DIM / 2][DIM / 2], + float tl_z_re[DIM / 2][DIM / 2], + float tl_w_im[DIM / 2][DIM / 2], + float tl_x_im[DIM / 2][DIM / 2], + float tl_y_im[DIM / 2][DIM / 2], + float tl_z_im[DIM / 2][DIM / 2], + float tr_w_re[DIM / 2][DIM / 2], + float tr_x_re[DIM / 2][DIM / 2], + float tr_y_re[DIM / 2][DIM / 2], + float tr_z_re[DIM / 2][DIM / 2], + float tr_w_im[DIM / 2][DIM / 2], + float tr_x_im[DIM / 2][DIM / 2], + float tr_y_im[DIM / 2][DIM / 2], + float tr_z_im[DIM / 2][DIM / 2]) { + printf("DEBUG: tl_w_re state\n"); + dumpm_div_2(tl_w_re); + printf("DEBUG: tl_w_im state\n"); + dumpm_div_2(tl_w_im); + + printf("DEBUG: tl_x_re state\n"); + dumpm_div_2(tl_x_re); + printf("DEBUG: tl_x_im state\n"); + dumpm_div_2(tl_x_im); + + printf("DEBUG: tl_y_re state\n"); + dumpm_div_2(tl_y_re); + printf("DEBUG: tl_y_im state\n"); + dumpm_div_2(tl_y_im); + + printf("DEBUG: tl_z_re state\n"); + dumpm_div_2(tl_z_re); + printf("DEBUG: tl_z_im state\n"); + dumpm_div_2(tl_z_im); + + printf("DEBUG: tr_w_re state\n"); + dumpm_div_2(tr_w_re); + printf("DEBUG: tr_w_im state\n"); + dumpm_div_2(tr_w_im); + + printf("DEBUG: tr_x_re state\n"); + dumpm_div_2(tr_x_re); + printf("DEBUG: tr_x_im state\n"); + dumpm_div_2(tr_x_im); + + printf("DEBUG: tr_y_re state\n"); + dumpm_div_2(tr_y_re); + printf("DEBUG: tr_y_im state\n"); + dumpm_div_2(tr_y_im); + + printf("DEBUG: tr_z_re state\n"); + dumpm_div_2(tr_z_re); + printf("DEBUG: tr_z_im state\n"); + dumpm_div_2(tr_z_im); +} + +// template +// void +// dump_bs( +// x_complex data_1, int i, int j, int k, x_complex R, x_complex tmp_inv) +// { +// float data_1_re_f = data_1.real(); +// float data_1_im_f = data_1.imag(); +// float R_re_f = R.real(); +// float R_im_f = R.imag(); +// float tmp_inv_re_f = tmp_inv.real(); +// float tmp_inv_im_f = tmp_inv.imag(); +// printf("\ndata_1 (re:%e, im: %e) / R[%i][%i][%i] (re: %e, im: %e) = tmp_inv (re: %e, im: +// %e)\n",data_1_re_f,data_1_im_f,i,j,k,R_re_f,R_im_f,tmp_inv_re_f,tmp_inv_im_f); +// } + +template +void dump_bs(T1 data_1, int i, int j, int k, T2 R, T3 tmp_inv) { + float data_1_f = data_1; + float R_f = R; + float tmp_inv_f = tmp_inv; + printf("\ndata_1 (%e) / R[%i][%i][%i] (%e) = tmp_inv (%e)\n", data_1_f, i, j, k, R_f, tmp_inv_f); +} + +/* +* set matrix a values to matrix b +*/ +template +void setm(float a[DIM][DIM], float b[DIM][DIM]) { + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + b[i][j] = a[i][j]; + } + } +} + +// template +// void +// mm( +// // bool tranA, bool tranB, +// x_complex in_a[DIM][DIM][_TDM_CHUNKS], +// x_complex in_b[DIM][DIM][_TDM_CHUNKS], +// x_complex out_c[DIM][DIM][_TDM_CHUNKS]) +// { +// int i,j,k; +// x_complex tmp; +// for(i=0; i tmp_a = (tranA) ? x_conj(in_a[k][i][0]) : in_a[i][k][0]; +// x_complex tmp_b = (tranB) ? x_conj(in_b[j][k][0]) : in_b[k][j][0]; + +// // printf("mm: (%d,%d,%d) tmp_a_re: %e, tmp_a_im: %e, tmp_b_re: %e, tmp_b_im: +// %e\n",i,j,k,tmp_a_re,tmp_a_im,tmp_b_re,tmp_b_im); +// tmp += (tmp_a * tmp_b); +// } +// out_c[i][j][0] = tmp; +// } +// } +// } + +// /* +// * Like mm but does not conjugate when it transposes +// */ +// template +// void +// mm2( +// x_complex in_a[DIM][DIM][_TDM_CHUNKS], +// x_complex in_b[DIM][DIM][_TDM_CHUNKS], +// x_complex out_c[DIM][DIM][_TDM_CHUNKS]) +// { +// int i,j,k; +// x_complex tmp; +// for(i=0; i tmp_a = (tranA) ? in_a[k][i][0] : in_a[i][k][0]; +// x_complex tmp_b = (tranB) ? in_b[j][k][0] : in_b[k][j][0]; + +// // printf("mm: (%d,%d,%d) tmp_a_re: %e, tmp_a_im: %e, tmp_b_re: %e, tmp_b_im: +// %e\n",i,j,k,tmp_a_re,tmp_a_im,tmp_b_re,tmp_b_im); +// tmp += (tmp_a * tmp_b); +// } +// out_c[i][j][0] = tmp; +// } +// } +// } + +template +void mm(float a[DIM][DIM][_TDM_CHUNKS], float b[DIM][DIM][_TDM_CHUNKS], float c[DIM][DIM][_TDM_CHUNKS]) { + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + c[i][j][0] = vmult(a, b, i, j, DIM, tranA, tranB); + } + } +} + +template +void mm(ap_fixed a[DIM][DIM][_TDM_CHUNKS], + ap_fixed b[DIM][DIM][_TDM_CHUNKS], + ap_fixed c[DIM][DIM][_TDM_CHUNKS]) { + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + c[i][j][0] = vmult(a, b, i, j, DIM, tranA, tranB); + } + } +} + +template +void test_orthogonal(float a[DIM][DIM][_TDM_CHUNKS]) { + float c[DIM][DIM]; + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + c[i][j] = vmult(a, a, i, j, DIM, false, true); + printf("%e ", c[i][j]); + } + printf("\n"); + } + printf("\n\n"); +} + +template +void swap_diag_elements(float r_out[DIM][DIM], int c1, int c2) { + float tmp = r_out[c1][c1]; + r_out[c1][c1] = r_out[c2][c2]; + r_out[c2][c2] = tmp; +} + +template +void swap_columns(float m[DIM][DIM], int c1, int c2) { + float tmp[DIM]; + for (int i = 0; i < DIM; i++) { + tmp[i] = m[i][c1]; + } + for (int i = 0; i < DIM; i++) { + m[i][c1] = m[i][c2]; + m[i][c2] = tmp[i]; + } +} + +template +void abssort(float r_out[DIM][DIM], float u_out[DIM][DIM], float v_out[DIM][DIM]) { + int i, j, k; + float w, x, y, z; + float i_perm[DIM][DIM]; + + for (i = 0; i < DIM; i++) { + for (j = 0; j < DIM; j++) { + if (i == j) { + i_perm[i][j] = (r_out[i][j] < 0.0f) ? -1.0f : 1.0f; + } else { + i_perm[i][j] = 0.0f; + } + } + } + float tmp[DIM][DIM]; + + // r_out matrix + printf("DEBUG: abssort, r_out before\n"); + dumpm(r_out); + + mm(i_perm, r_out, tmp); + setm(tmp, r_out); + + printf("DEBUG: abssort, r_out after\n"); + dumpm(r_out); + + // u_out matrix + printf("DEBUG: abssort, u_out after\n"); + dumpm(u_out); + + mm(i_perm, u_out, tmp); + setm(tmp, u_out); + + printf("DEBUG: abssort, u_out after\n"); + dumpm(u_out); +} + +template +void abssort2(float r_out[DIM][DIM], float u_out[DIM][DIM], float v_out[DIM][DIM]) { + int i, j; + + // r_out matrix + printf("DEBUG: abssort2, r_out before\n"); + dumpm(r_out); + + // v_out matrix + printf("DEBUG: abssort2, v_out before\n"); + dumpm(v_out); + + for (j = 0; j < DIM; j++) { + float tmps = r_out[j][j]; + if (tmps < 0.0f) { + for (i = 0; i < DIM; i++) { + float tmpv = v_out[i][j]; + v_out[i][j] = -tmpv; + } + r_out[j][j] = -tmps; + } + } + + printf("DEBUG: abssort2, r_out after\n"); + dumpm(r_out); + + printf("DEBUG: abssort2, v_out after\n"); + dumpm(v_out); +} + +template +void dsort2(float s_out[DIM][DIM], float u_out[DIM][DIM], float v_out[DIM][DIM]) { + int i, j, i_max; + float S_max, Sj; + + printf("DEBUG: dsort2, s_out before\n"); + dumpm(s_out); + + printf("DEBUG: dsort2, u_out before\n"); + dumpm(u_out); + + printf("DEBUG: dsort2, v_out before\n"); + dumpm(v_out); + + for (i = 0; i < DIM; i++) { + S_max = s_out[i][i]; + i_max = i; + for (j = i + 1; j < DIM; j++) { + Sj = s_out[j][j]; + if (Sj > S_max) { + S_max = Sj; + i_max = j; + } + } + if (i_max != i) { + swap_diag_elements(s_out, i, i_max); + swap_columns(u_out, i, i_max); + swap_columns(v_out, i, i_max); + } + } + printf("DEBUG: dsort2, s_out after\n"); + dumpm(s_out); + + printf("DEBUG: dsort2, u_out after\n"); + dumpm(u_out); + + printf("DEBUG: dsort2, v_out after\n"); + dumpm(v_out); +} + +template +void swap_rows(float m[DIM][DIM], int c1, int c2) { + float tmp[DIM]; + for (int i = 0; i < DIM; i++) { + tmp[i] = m[c1][i]; + } + for (int i = 0; i < DIM; i++) { + m[c1][i] = m[c2][i]; + m[c2][i] = tmp[i]; + } +} + +template +void swap_row_columns(float m[DIM][DIM], int c1, int c2) { + float tmp[DIM]; + for (int i = 0; i < DIM; i++) { + tmp[i] = m[c1][i]; + } + for (int i = 0; i < DIM; i++) { + m[c1][i] = m[c2][i]; + m[c2][i] = tmp[i]; + } + swap_columns(m, c1, c2); +} + +template +void clear_diagm(float s_re[DIM][DIM]) { + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + if (i != j) s_re[i][j] = 0.0f; + } + } +} + +template +void dumpcs(float c1i[DIM / 2][DIM / 2], + float s1i[DIM / 2][DIM / 2], + float c2i[DIM / 2][DIM / 2], + float s2i[DIM / 2][DIM / 2], + float k[DIM / 2][DIM / 2]) { + printf("DEBUG: c1 state\n"); + for (int ti = 0; ti < DIM / 2; ti++) { + for (int tj = 0; tj < DIM / 2; tj++) { + printf("%e\t", c1i[ti][tj]); + } + printf("\n"); + } + printf("\n"); + + printf("DEBUG: s1 state\n"); + for (int ti = 0; ti < DIM / 2; ti++) { + for (int tj = 0; tj < DIM / 2; tj++) { + printf("%e\t", s1i[ti][tj]); + } + printf("\n"); + } + printf("\n"); + + printf("DEBUG: k state\n"); + for (int ti = 0; ti < DIM / 2; ti++) { + for (int tj = 0; tj < DIM / 2; tj++) { + printf("%e\t", k[ti][tj]); + } + printf("\n"); + } + printf("\n"); + + printf("DEBUG: c2 state\n"); + for (int ti = 0; ti < DIM / 2; ti++) { + for (int tj = 0; tj < DIM / 2; tj++) { + printf("%e\t", c2i[ti][tj]); + } + printf("\n"); + } + printf("\n"); + + printf("DEBUG: s2 state\n"); + for (int ti = 0; ti < DIM / 2; ti++) { + for (int tj = 0; tj < DIM / 2; tj++) { + printf("%e\t", s2i[ti][tj]); + } + printf("\n"); + } + printf("\n"); +} + +template +void vmultc(float* out_re, + float* out_im, + float a_re[X_DIM][X_DIM][_TDM_CHUNKS], + float a_im[X_DIM][X_DIM][_TDM_CHUNKS], + float b_re[X_DIM][X_DIM][_TDM_CHUNKS], + float b_im[X_DIM][X_DIM][_TDM_CHUNKS], + int i, + int j, + int l, + bool a_t, + bool b_t) { + float tmp_re, tmp_im, aval_re, aval_im, bval_re, bval_im; + tmp_re = 0.0; + tmp_im = 0.0; + for (int k = 0; k < l; k++) { + aval_re = (a_t) ? a_re[k][i][0] : a_re[i][k][0]; + aval_im = (a_t) ? -a_im[k][i][0] : a_im[i][k][0]; + bval_re = (b_t) ? b_re[j][k][0] : b_re[k][j][0]; + bval_im = (b_t) ? -b_im[j][k][0] : b_im[k][j][0]; + tmp_re += aval_re * bval_re - aval_im * bval_im; + tmp_im += aval_re * bval_im + aval_im * bval_re; + } + *out_re = tmp_re; + *out_im = tmp_im; +} + +// template +// void +// vmultc( +// x_complex &out_a, +// x_complex in_a[X_DIM][X_DIM][_TDM_CHUNKS], +// x_complex in_b[X_DIM][X_DIM][_TDM_CHUNKS], +// int i, int j, int l, bool a_t, bool b_t) +// { +// x_complex tmp, aval, bval; +// tmp = 0.0; +// for(int k=0; k +void jacobi_mult_c(float u_re[X_DIM][X_DIM][_TDM_CHUNKS], + float u_im[X_DIM][X_DIM][_TDM_CHUNKS], + float s_re[X_DIM][X_DIM][_TDM_CHUNKS], + float s_im[X_DIM][X_DIM][_TDM_CHUNKS], + float v_re[X_DIM][X_DIM][_TDM_CHUNKS], + float v_im[X_DIM][X_DIM][_TDM_CHUNKS], + float A_re[X_DIM][X_DIM][_TDM_CHUNKS], + float A_im[X_DIM][X_DIM][_TDM_CHUNKS], + bool v_trans) // TODO printf out A_re +{ + int maxd = (X_DIM > Y_DIM) ? X_DIM : Y_DIM; + float tmp_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + float tmp_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + for (int i = 0; i < X_DIM; i++) { + for (int j = 0; j < Y_DIM; j++) { + vmultc(&tmp_re[i][j][0], &tmp_im[i][j][0], u_re, u_im, s_re, s_im, i, j, X_DIM, + false, false); + } + } + for (int i = 0; i < X_DIM; i++) { + for (int j = 0; j < Y_DIM; j++) { + vmultc(&A_re[i][j][0], &A_im[i][j][0], tmp_re, tmp_im, v_re, v_im, i, j, X_DIM, + false, v_trans); + } + } +} + +// template +// void +// jacobi_mult_c( +// x_complex in_u[X_DIM][X_DIM][_TDM_CHUNKS], +// x_complex in_s[X_DIM][X_DIM][_TDM_CHUNKS], +// x_complex in_v[X_DIM][X_DIM][_TDM_CHUNKS], +// x_complex out_A[X_DIM][X_DIM][_TDM_CHUNKS], +// bool v_trans) // TODO printf out A_re +// { +// int maxd = (X_DIM > Y_DIM) ? X_DIM : Y_DIM; +// x_complex tmp[X_DIM][Y_DIM][_TDM_CHUNKS]; +// for(int i=0; i(tmp[i][j][0], in_u, in_s, i, j, X_DIM, false, false); +// } +// } +// for(int i=0; i(out_A[i][j][0], tmp, in_v, i, j, X_DIM, false, v_trans); +// } +// } +// } + +// float vmult(float a[][N], float b[][N], int i, int j, int l, bool a_t, bool b_t); + +template +void mm_comp(float a_re[DIM][DIM], + float a_im[DIM][DIM], + float b_re[DIM][DIM], + float b_im[DIM][DIM], + float c_re[DIM][DIM], + float c_im[DIM][DIM]) { + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + c_re[i][j] = 0; + c_im[i][j] = 0; + for (int k = 0; k < DIM; k++) { + c_re[i][j] += (a_re[i][k] * b_re[k][j] - a_im[i][k] * b_im[k][j]); + c_im[i][j] += (a_re[i][k] * b_im[k][j] + a_im[i][k] * b_re[k][j]); + } + printf("[%e %e] ", c_re[i][j], c_im[i][j]); + } + } +} + +template +void mm_transp_comp(float a_re[DIM][DIM], float a_im[DIM][DIM], float c_re[DIM][DIM], float c_im[DIM][DIM]) { + float b_re[DIM][DIM]; + float b_im[DIM][DIM]; + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + b_re[i][j] = a_re[j][i]; + b_im[i][j] = -a_im[j][i]; + } + } + mm_comp(a_re, a_im, b_re, b_im, c_re, c_im); +} + +template +void transp(float a[DIM][DIM]) { + float tmp[DIM][DIM]; + + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + tmp[j][i] = a[i][j]; + } + } + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + a[i][j] = tmp[i][j]; + } + } +} + +template +float vmult(T a[DIM][DIM][_TDM_CHUNKS], T b[DIM][DIM][_TDM_CHUNKS], int i, int j, int l, bool a_t, bool b_t) { + T tmp, aval, bval; + tmp = 0; + for (int k = 0; k < l; k++) { + aval = (a_t) ? a[k][i][0] : a[i][k][0]; + bval = (b_t) ? b[j][k][0] : b[k][j][0]; + tmp += aval * bval; + } + return tmp; +} + +// TODO Placeholder - shouldn't need this after SVD is cleaned up +template +void jacobi_mult(float u_re[DIM][DIM][_TDM_CHUNKS], + float s_re[DIM][DIM][_TDM_CHUNKS], + float v_re[DIM][DIM][_TDM_CHUNKS], + float A_re[DIM][DIM][_TDM_CHUNKS], + bool v_trans) // TODO printf out A_re +{ + int maxd = DIM; //(DIM > DIM) ? DIM : DIM; + float tmp[DIM][DIM][_TDM_CHUNKS]; + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + tmp[i][j][0] = vmult(u_re, s_re, i, j, DIM, false, false); + } + } + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + A_re[i][j][0] = vmult(tmp, v_re, i, j, DIM, false, v_trans); + } + } +} + +// void clear_diagm(float s_re[N][N]); + +/* +* v_re input matrix +* v_out_re mult operation result +*/ +template +void multbytrans(float m_re[DIM][DIM], + float m_out_re[DIM][DIM], + bool trans2) // transpose mult second (m*m^t) +{ + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + m_out_re[i][j] = vmult(m_re, m_re, i, j, DIM, !trans2, trans2); + } + } +} + +/* +* v_re input matrix (real) +* v_im input matrix (imaginary) +* v_out_re mult operation result (real) +* v_out_im mult operation result (imaginary) +*/ +template +void multbytransc(float m_re[DIM][DIM][_TDM_CHUNKS], + float m_im[DIM][DIM][_TDM_CHUNKS], + float m_out_re[DIM][DIM][_TDM_CHUNKS], + float m_out_im[DIM][DIM][_TDM_CHUNKS], + bool trans2) // transpose mult second (m*m^t) +{ + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + vmultc(&m_out_re[i][j][0], &m_out_im[i][j][0], m_re, m_im, m_re, m_im, i, j, DIM, + !trans2, trans2); + } + } +} + +// template +// void +// multbytransc( +// x_complex in_a[DIM][DIM][_TDM_CHUNKS], +// x_complex out_a[DIM][DIM][_TDM_CHUNKS], +// bool trans2) // transpose mult second (m*m^t) +// { +// for(int i=0; i(out_a[i][j][0], in_a, in_a, i, j, DIM, !trans2, trans2); +// } +// } +// } + +static float conv_int_to_float(int a, int fixed_width, int int_width) { + float tmp = a / (float)pow((double)2.0, (double)(fixed_width - int_width)); + printf("int(dec): %d, int(hex): %x, float: %f\n", a, a, tmp); + return tmp; +} + +/* +* mask only works with 12 fractional bits +*/ +static int conv_float_to_int(float a, int fixed_width, int int_width) { + int tmp = (int)(a * (float)pow((double)2, (double)(fixed_width - int_width))); + ; + printf("int(dec): %d, int(hex): %x, float: %f\n", tmp, tmp, a); + return tmp; +} + +template +void check_QRD_results(T x[X_DIM][2 * Y_DIM][_TDM_CHUNKS]) { + printf("QRD done.\n"); + + printf("\nMatrix after QRD\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < 2 * Y_DIM; tj++) { + float ptmp = x[ti][tj][0]; + printf("%f ", ptmp); + } + printf("\n"); + } + printf("\n\n"); + + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < ti; tj++) { + printf("0.000000e+00 "); + } + for (int tj = 0; tj < Y_DIM - ti; tj++) { + float ptmp = x[ti][tj][0]; + printf("%e ", ptmp); + } + printf("\n"); + } + printf("\n\n"); + + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = x[ti][Y_DIM - ti + tj][0]; + printf("%e ", ptmp); + } + printf("\n"); + } +} + +template +void check_QRD_results(T x_re[X_DIM][2 * Y_DIM][_TDM_CHUNKS], T x_im[X_DIM][2 * Y_DIM][_TDM_CHUNKS]) { + printf("QRD done.\n"); + + printf("\nMatrix (X) after QRD\n"); + printf("-------------------------n"); + printf("\nMatrix (real)\n"); + printf("----------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < ti; tj++) { + printf("0.000000 "); + } + for (int tj = 0; tj < Y_DIM - ti; tj++) { + float ptmp = x_re[ti][tj][0]; + printf("%f ", ptmp); + } + printf(" "); + + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = x_re[ti][Y_DIM - ti + tj][0]; + printf("%f ", ptmp); + } + printf("\n"); + } + + printf("\nMatrix (imag)\n"); + printf("----------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < ti; tj++) { + printf("0.000000 "); + } + for (int tj = 0; tj < Y_DIM - ti; tj++) { + float ptmp = x_im[ti][tj][0]; + printf("%f ", ptmp); + } + printf(" "); + + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = x_im[ti][Y_DIM - ti + tj][0]; + printf("%f ", ptmp); + } + printf("\n"); + } + + /* + * TODO + * Multiply Q*Q^t to see if it produces the Identity matrix + * Multiply Q*R to see if produces A again + */ + printf("Check Q*Q^t\n"); + printf("Store Q, R\n"); + float tmp_mat_re[X_DIM][Y_DIM]; + float tmp_mat_im[X_DIM][Y_DIM]; + float tmp_q_re[X_DIM][Y_DIM]; + float tmp_q_im[X_DIM][Y_DIM]; + float tmp_r_re[X_DIM][Y_DIM]; + float tmp_r_im[X_DIM][Y_DIM]; + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + printf("ti: %d, tj: %d\n", ti, tj); + tmp_mat_re[ti][tj] = x_re[ti][tj + Y_DIM - ti][0]; + printf("X_re[%d][%d][0] = %e\n", ti, tj + Y_DIM - ti, tmp_mat_re[ti][tj]); + tmp_mat_im[ti][tj] = x_im[ti][tj + Y_DIM - ti][0]; + printf("X_im[%d][%d][0] = %e\n", ti, tj + Y_DIM - ti, tmp_mat_im[ti][tj]); + + tmp_q_re[tj][ti] = x_re[ti][tj + Y_DIM - ti][0]; + printf("X_re[%d][%d][0] = %e\n", ti, tj + Y_DIM - ti, tmp_q_re[tj][ti]); + tmp_q_im[tj][ti] = -x_im[ti][tj + Y_DIM - ti][0]; + printf("X_im[%d][%d][0] = %e\n", ti, tj + Y_DIM - ti, tmp_q_im[tj][ti]); + + if (tj < ti) { + tmp_r_re[ti][tj] = 0; + tmp_r_im[ti][tj] = 0; + } else { + tmp_r_re[ti][tj] = x_re[ti][tj - ti][0]; + tmp_r_im[ti][tj] = x_im[ti][tj - ti][0]; + } + } + } + + /* + tmp_mat_re[0][0] = -0.090691; + tmp_mat_re[0][1] = 0.417296; + tmp_mat_re[0][2] = -0.306837; + tmp_mat_re[0][3] = -0.520790; + tmp_mat_re[1][0] = -0.475003; + tmp_mat_re[1][1] = -0.237293; + tmp_mat_re[1][2] = -0.169015; + tmp_mat_re[1][3] = 0.008679; + tmp_mat_re[2][0] = 0.479512; + tmp_mat_re[2][1] = -0.332793; + tmp_mat_re[2][2] = 0.030529; + tmp_mat_re[2][3] = 0.079810; + tmp_mat_re[3][0] = -0.297628; + tmp_mat_re[3][1] = -0.468605; + tmp_mat_re[3][2] = -0.174566; + tmp_mat_re[3][3] = -0.608285; + + tmp_mat_im[0][0] = -0.161341; + tmp_mat_im[0][1] = 0.456402; + tmp_mat_im[0][2] = -0.373242; + tmp_mat_im[0][3] = 0.280402; + tmp_mat_im[1][0] = 0.496548; + tmp_mat_im[1][1] = -0.283132; + tmp_mat_im[1][2] = -0.601775; + tmp_mat_im[1][3] = -0.023788; + tmp_mat_im[2][0] = -0.352745; + tmp_mat_im[2][1] = -0.281551; + tmp_mat_im[2][2] = -0.433460; + tmp_mat_im[2][3] = 0.510322; + tmp_mat_im[3][0] = -0.224975; + tmp_mat_im[3][1] = -0.267352; + tmp_mat_im[3][2] = 0.395663; + tmp_mat_im[3][3] = 0.112706; + */ + + printf("\nQ Matrix (real)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_mat_re[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + + printf("\nQ Matrix (imag)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_mat_im[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + printf("\n\n"); + + printf("\nR Matrix (real)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_r_re[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + + printf("\nR Matrix (imag)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_r_im[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + printf("\n\n"); + + float tmp_mat_res_re[X_DIM][Y_DIM]; + float tmp_mat_res_im[X_DIM][Y_DIM]; + + mm_comp(tmp_mat_re, tmp_mat_im, tmp_r_re, tmp_r_im, tmp_mat_res_re, tmp_mat_res_im); + + printf("\nQ*R Matrix (real)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_mat_res_re[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + + printf("\nQ*R Matrix (imag)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_mat_res_im[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + printf("\n\n"); + + mm_transp_comp(tmp_mat_re, tmp_mat_im, tmp_mat_res_re, tmp_mat_res_im); + + printf("\nQ*Q^t Matrix (real)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_mat_res_re[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + + printf("\nQ*Q^t Matrix (imag)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_mat_res_im[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + printf("\n\n"); +} + +template +void check_inverse_results(T x_inv[X_DIM][Y_DIM][_TDM_CHUNKS]) { + printf("Backsub done.\n"); + + printf("\nMatrix (real) after Backsub\n"); + printf("------------------------\n"); + dumpm(x_inv); +} + +template +void check_inverse_results(T in_mat_re[X_DIM][Y_DIM][_TDM_CHUNKS], + T in_mat_im[X_DIM][Y_DIM][_TDM_CHUNKS], + T x_inv_re[X_DIM][Y_DIM][_TDM_CHUNKS], + T x_inv_im[X_DIM][Y_DIM][_TDM_CHUNKS]) { + float tmp_mat_res_re[X_DIM][Y_DIM]; + float tmp_mat_res_im[X_DIM][Y_DIM]; + + printf("Backsub done.\n"); + + printf("\nMatrix (real) after Backsub\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = x_inv_re[ti][tj][0]; + printf("%f ", ptmp); + } + printf("\n"); + } + + printf("\nMatrix (imaginary) after Backsub\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = x_inv_im[ti][tj][0]; + printf("%f ", ptmp); + } + printf("\n"); + } + printf("\n"); + + printf("Test accuracy of inverse\n"); + float in_mat_re_float[X_DIM][Y_DIM]; + float in_mat_im_float[X_DIM][Y_DIM]; + float x_inv_re_float[X_DIM][Y_DIM]; + float x_inv_im_float[X_DIM][Y_DIM]; + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + in_mat_re_float[ti][tj] = in_mat_re[ti][tj][0]; + in_mat_im_float[ti][tj] = in_mat_im[ti][tj][0]; + x_inv_re_float[ti][tj] = x_inv_re[ti][tj][0]; + x_inv_im_float[ti][tj] = x_inv_im[ti][tj][0]; + } + } + + mm_comp(in_mat_re_float, in_mat_im_float, x_inv_re_float, x_inv_im_float, tmp_mat_res_re, tmp_mat_res_im); + + printf("\nA*A^-1 Matrix (real)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_mat_res_re[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + + printf("\nA*A^-1 Matrix (imag)\n"); + printf("------------------------\n"); + for (int ti = 0; ti < X_DIM; ti++) { + for (int tj = 0; tj < Y_DIM; tj++) { + float ptmp = tmp_mat_res_im[ti][tj]; + printf("%f ", ptmp); + } + printf("\n"); + } + printf("\n\n"); +} + +template +static void conv_data_formats(int data_in, ap_fixed& data_out) { + data_out = conv_int_to_float(data_in, WA, WMA); +} + +template +static void conv_data_formats(ap_fixed data_in, int& data_out) { + data_out = conv_float_to_int(data_in, WA, WMA); +} + +template +static void conv_data_formats(T1 data_in, T2& data_out) { + data_out = data_in; +} + +template +void load_input_matrix(int chunk_num, T1* data_in, T2 in_re[X_DIM][Y_DIM][_TDM_CHUNKS]) { + for (int i = 0; i < X_DIM; i++) { + for (int j = 0; j < Y_DIM; j++) { + for (int k = 0; k < _TDM_CHUNKS; k++) { + conv_data_formats( + data_in[chunk_num * _TDM_CHUNKS * X_DIM * Y_DIM + j * _TDM_CHUNKS * X_DIM + i * _TDM_CHUNKS + k], + in_re[i][j][k]); + float tmp = in_re[i][j][k]; + printf("in[%d][%d][%d] = %e\n", i, j, k, tmp); + } + } + } +} + +union ufloat { + float f; + unsigned u; +}; + +/* +* Automatically stores data to a float array as well (even if the first array +* is already a float). This is to support ap_fixed (or other) data types to ensure +* a float version exists for comparison. +*/ +template +void store_output_matrix(int chunk_num, T1 out_re[X_DIM][Y_DIM][_TDM_CHUNKS], T2* data_out, float* data_out_float) { + for (int i = 0; i < X_DIM; i++) { + for (int j = 0; j < Y_DIM; j++) { + for (int k = 0; k < _TDM_CHUNKS; k++) { + conv_data_formats(out_re[i][j][k], *(data_out + chunk_num * _TDM_CHUNKS * X_DIM * Y_DIM + + j * _TDM_CHUNKS * X_DIM + i * _TDM_CHUNKS + k)); + *(data_out_float + chunk_num * _TDM_CHUNKS * X_DIM * Y_DIM + j * _TDM_CHUNKS * X_DIM + i * _TDM_CHUNKS + + k) = out_re[i][j][k]; // Relies on overloaded = operation to convert format + // TODO temp + + ufloat tmp; + tmp.f = (float)(out_re[i][j][k]); + int sign = (tmp.u >> 31) & 0x1; + int exponent = ((tmp.u >> 23) & 0xff) - 127; + unsigned int mantissa = tmp.u & 0x7fffff; + float mantissaf = 1 + ((float)mantissa / 8388608); + float num = (exponent < 0) ? mantissaf / pow((double)2, (double)(0 - exponent)) + : mantissaf * pow((double)2, (double)exponent); + num = (sign > 0) ? -num : num; + printf("out_re[%d][%d][%d] = %e (%x:%d,%d,%x/%f; %f) \n", i, j, k, tmp.f, tmp.u, sign, exponent, + mantissa, mantissaf, num); + } + } + } +} + +/* +* real B = f(real A) +* +* T2: default data type (float, ap_fixed) +* T1: storage data type of input file (float -> float, ap_fixed -> int) +*/ +template +int test_func_1_1(int argc, + char* argv[], + float base, + float err, + void (*func)(T2in[X_DIM][Y_DIM][_TDM_CHUNKS], T2out[X_DIM][Y_DIM][_TDM_CHUNKS])) { + // File names + char* input_data_file = argv[1]; //"ch_matrices_re.txt"; + char* output_data_file = argv[2]; //"results_re.txt"; + char* expected_data_file = argv[3]; //"simulation_data_re.txt"; + + // Matrix dimension + short matrix_dimension[2] = {X_DIM, Y_DIM}; + int m = 2 * matrix_dimension[0]; + int n = 2 * matrix_dimension[1]; + + // Data size + int input_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + int output_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + + // File data pointers + T1* data_in; + T1* data_out; + float* data_out_float; + data_in = (T1*)malloc(input_data_size * sizeof(T1)); + data_out = (T1*)malloc(output_data_size * sizeof(T1)); + data_out_float = (float*)malloc(output_data_size * sizeof(float)); + + // Function arguments - data matrices + T2in chunk_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + + printf("Test beginning...\n"); + /* + ****************************************************************************** + * Load data, perfrom function, and store result + ****************************************************************************** + */ + printf("Loading values from txt files ...\n"); + load_from_file(input_data_file, data_in, input_data_size); + + for (int i = 0; i < NUM_CHUNKS; i++) { + printf("Loading input data array ...\n"); + load_input_matrix(i, data_in, chunk_in_re); + + printf("Perform main function!!\n"); + (*func)(chunk_in_re, chunk_out_re); + + printf("Store output result ... \n"); + // store_output_matrix(i, chunk_out_re, data_out, data_out_float); + store_output_matrix(i, chunk_out_re, data_out, data_out_float); + } + + printf("Saving results to output file (%s) ...\n", output_data_file); + save_to_file(output_data_file, data_out, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + int out_name_len = strlen(output_data_file); + char output_data_file_float[out_name_len + 7]; + strcpy(output_data_file_float, output_data_file); + output_data_file_float[out_name_len - 4] = '\0'; + const char* float_end = "_float.txt"; + strcat(output_data_file_float, float_end); + printf("Saving results to output file (%s) ...\n", output_data_file_float); + save_to_file(output_data_file_float, data_out_float, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + /* + ****************************************************************************** + * Compare C code results to expected Matlab reference script results + ****************************************************************************** + */ + printf("Comparing results (%s,%s)...\n", output_data_file, expected_data_file); + int cmp_res_i; + T2out dummy; + cmp_res_i = compare_files(dummy, expected_data_file, output_data_file, 1, output_data_size, base, err); + + if (cmp_res_i != 0) { + printf("Data verification completed successfully.\n"); + } else { + printf("Data verification completed with errors.\n"); + } + + free(data_in); + free(data_out); + free(data_out_float); + + return 0; +} + +/* +* real C = f(real A, real B) +* +* T2: default data type (float, ap_fixed) +* T1: storage data type of input file (float -> float, ap_fixed -> int) +*/ +template +int test_func_2_1(int argc, + char* argv[], + float base, + float err, + void (*func)(T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS])) { + // File names + char* input_a_data_file = argv[1]; //"ch_matrices_re.txt"; + char* input_b_data_file = argv[2]; //"ch_matrices_re.txt"; + char* output_data_file = argv[3]; //"results_re.txt"; + char* expected_data_file = argv[4]; //"simulation_data_re.txt"; + + // Matrix dimension + short matrix_dimension[2] = {X_DIM, Y_DIM}; + int m = 2 * matrix_dimension[0]; + int n = 2 * matrix_dimension[1]; + + // Data size + int input_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + int output_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + + // File data pointers + T1 *data_a_in, *data_b_in; + T1* data_out; + float* data_out_float; + data_a_in = (T1*)malloc(input_data_size * sizeof(T1)); + data_b_in = (T1*)malloc(input_data_size * sizeof(T1)); + data_out = (T1*)malloc(output_data_size * sizeof(T1)); + data_out_float = (float*)malloc(output_data_size * sizeof(float)); + + // Function arguments - data matrices + T2in chunk_a_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2in chunk_b_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + + printf("Test beginning...\n"); + /* + ****************************************************************************** + * Load data, perfrom function, and store result + ****************************************************************************** + */ + printf("Loading values from txt files (%s, %s)...\n", input_a_data_file, input_b_data_file); + load_from_file(input_a_data_file, data_a_in, input_data_size); + load_from_file(input_b_data_file, data_b_in, input_data_size); + + for (int i = 0; i < NUM_CHUNKS; i++) { + printf("Loading input data array ...\n"); + load_input_matrix(i, data_a_in, chunk_a_in_re); + load_input_matrix(i, data_b_in, chunk_b_in_re); + + printf("Perform main function!!\n"); + (*func)(chunk_a_in_re, chunk_b_in_re, chunk_out_re); + + printf("Store output result ... \n"); + store_output_matrix(i, chunk_out_re, data_out, data_out_float); + } + + printf("Saving results to output file (%s)...\n", output_data_file); + save_to_file(output_data_file, data_out, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + int out_name_len = strlen(output_data_file); + char output_data_file_float[out_name_len + 7]; + strcpy(output_data_file_float, output_data_file); + output_data_file_float[out_name_len - 4] = '\0'; + const char* float_end = "_float.txt"; + strcat(output_data_file_float, float_end); + printf("Saving results to output file (%s) ...\n", output_data_file_float); + save_to_file(output_data_file_float, data_out_float, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + /* + ****************************************************************************** + * Compare C code results to expected Matlab reference script results + ****************************************************************************** + */ + printf("Comparing results (%s, %s)...\n", output_data_file, expected_data_file); + int cmp_res_i; + T2out dummy; + cmp_res_i = compare_files(dummy, expected_data_file, output_data_file, 1, output_data_size, base, err); + + if (cmp_res_i != 0) { + printf("Data verification completed successfully.\n"); + } else { + printf("Data verification completed with errors.\n"); + } + + free(data_out); + free(data_out_float); + free(data_a_in); + free(data_b_in); + + return 0; +} + +/* +* (real B, real C) = f(real A) +* +* T2: default data type (float, ap_fixed) +* T1: storage data type of input file (float -> float, ap_fixed -> int) +*/ +template +int test_func_1_2(int argc, + char* argv[], + float base, + float err, + void (*func)(T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS])) { + // File names + char* input_data_file = argv[1]; //"ch_matrices_re.txt"; + char* output_a_data_file = argv[2]; //"results_a_re.txt"; + char* output_b_data_file = argv[3]; //"results_b_re.txt"; + char* expected_a_data_file = argv[4]; //"simulation_a_data_re.txt"; + char* expected_b_data_file = argv[5]; //"simulation_b_data_re.txt"; + + // Matrix dimension + short matrix_dimension[2] = {X_DIM, Y_DIM}; + int m = 2 * matrix_dimension[0]; + int n = 2 * matrix_dimension[1]; + + // Data size + int input_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + int output_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + + // File data pointers + T1* data_in; + T1 *data_a_out, *data_b_out; + float *data_a_out_float, *data_b_out_float; + data_in = (T1*)malloc(input_data_size * sizeof(T1)); + data_a_out = (T1*)malloc(output_data_size * sizeof(T1)); + data_b_out = (T1*)malloc(output_data_size * sizeof(T1)); + data_a_out_float = (float*)malloc(output_data_size * sizeof(float)); + data_b_out_float = (float*)malloc(output_data_size * sizeof(float)); + + // Function arguments - data matrices + T2in chunk_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_a_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_b_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + + printf("Test beginning...\n"); + /* + ****************************************************************************** + * Load data, perfrom function, and store result + ****************************************************************************** + */ + printf("Loading values from txt files (%s)...\n", input_data_file); + load_from_file(input_data_file, data_in, input_data_size); + + for (int i = 0; i < NUM_CHUNKS; i++) { + printf("Loading input data array ...\n"); + load_input_matrix(i, data_in, chunk_in_re); + + printf("Perform main function!!\n"); + (*func)(chunk_in_re, chunk_a_out_re, chunk_b_out_re); + + printf("Store output result ... \n"); + store_output_matrix(i, chunk_a_out_re, data_a_out, data_a_out_float); + store_output_matrix(i, chunk_b_out_re, data_b_out, data_b_out_float); + } + + printf("Saving results to output file (%s, %s)...\n", output_a_data_file, output_b_data_file); + save_to_file(output_a_data_file, data_a_out, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_b_data_file, data_b_out, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + int filename_len; + const char* float_end = "_float.txt"; + + filename_len = strlen(output_a_data_file); + char* output_a_data_file_float = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_a_data_file_float, output_a_data_file); + output_a_data_file_float[filename_len - 4] = '\0'; + strcat(output_a_data_file_float, float_end); + + filename_len = strlen(output_b_data_file); + char* output_b_data_file_float = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_b_data_file_float, output_b_data_file); + output_b_data_file_float[filename_len - 4] = '\0'; + strcat(output_b_data_file_float, float_end); + + printf("Saving results to output file (%s, %s) ...\n", output_a_data_file_float, output_b_data_file_float); + save_to_file(output_a_data_file_float, data_a_out_float, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_b_data_file_float, data_b_out_float, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + /* + ****************************************************************************** + * Compare C code results to expected Matlab reference script results + ****************************************************************************** + */ + printf("Comparing results (%s, %s, %s, %s)...\n", output_a_data_file, expected_a_data_file, output_b_data_file, + expected_b_data_file); + int cmp_res_i; + T2out dummy; + cmp_res_i = compare_files(dummy, expected_a_data_file, output_a_data_file, 1, output_data_size, base, err); + cmp_res_i = + cmp_res_i & compare_files(dummy, expected_b_data_file, output_b_data_file, 1, output_data_size, base, err); + + if (cmp_res_i != 0) { + printf("Data verification completed successfully.\n"); + } else { + printf("Data verification completed with errors.\n"); + } + + free(data_a_out); + free(data_a_out_float); + free(data_b_out); + free(data_b_out_float); + free(data_in); + + return 0; +} + +// template +// int test_func_1_2_c( +// int argc, char* argv[], float base, float err, +// void (*func)(x_complex[X_DIM][Y_DIM][_TDM_CHUNKS], +// x_complex[X_DIM][Y_DIM][_TDM_CHUNKS], +// x_complex[X_DIM][Y_DIM][_TDM_CHUNKS])) +// { +// // File names +// char *input_data_file_re = argv[1];//"ch_matrices_re.txt"; +// char *input_data_file_im = argv[2];//"ch_matrices_im.txt"; +// char *output_a_data_file_re = argv[3];//"results_a_re.txt"; +// char *output_a_data_file_im = argv[4];//"results_a_im.txt"; +// char *output_b_data_file_re = argv[5];//"results_b_re.txt"; +// char *output_b_data_file_im = argv[6];//"results_b_im.txt"; +// char *expected_a_data_file_re = argv[7];//"simulation_a_data_re.txt"; +// char *expected_a_data_file_im = argv[8];//"simulation_a_data_im.txt"; +// char *expected_b_data_file_re = argv[9]; //"simulation_b_data_re.txt"; +// char *expected_b_data_file_im = argv[10];//"simulation_b_data_im.txt"; + +// // Matrix dimension +// short matrix_dimension[2] = {X_DIM,Y_DIM}; +// int m = 2*matrix_dimension[0]; +// int n = 2*matrix_dimension[1]; + +// // Data size +// int input_data_size = X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS; +// int output_data_size = X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS; + +// // File data pointers +// T1 *data_in_re, *data_in_im; +// T1 *data_a_out_re, *data_a_out_im, *data_b_out_re, *data_b_out_im; +// float *data_a_out_float_re, *data_a_out_float_im, *data_b_out_float_re, *data_b_out_float_im; +// data_in_re = (T1*)malloc(input_data_size * sizeof(T1)); +// data_in_im = (T1*)malloc(input_data_size * sizeof(T1)); +// data_a_out_re = (T1*)malloc(output_data_size * sizeof(T1)); +// data_a_out_im = (T1*)malloc(output_data_size * sizeof(T1)); +// data_b_out_re = (T1*)malloc(output_data_size * sizeof(T1)); +// data_b_out_im = (T1*)malloc(output_data_size * sizeof(T1)); +// data_a_out_float_re = (float*)malloc(output_data_size * sizeof(float)); +// data_a_out_float_im = (float*)malloc(output_data_size * sizeof(float)); +// data_b_out_float_re = (float*)malloc(output_data_size * sizeof(float)); +// data_b_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + +// // Function arguments - data matrices +// T2in chunk_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2in chunk_in_im[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_a_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_a_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_b_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_b_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + +// printf("Test beginning...\n"); +// /* +// ****************************************************************************** +// * Load data, perfrom function, and store result +// ****************************************************************************** +// */ +// printf("Loading values from txt files (%s, %s)...\n",input_data_file_re,input_data_file_im); +// load_from_file(input_data_file_re, data_in_re, input_data_size); +// load_from_file(input_data_file_im, data_in_im, input_data_size); + +// for(int i = 0; i < NUM_CHUNKS; i++) +// { +// printf("Loading input data array ...\n"); +// load_input_matrix(i, data_in_re,chunk_in_re); +// load_input_matrix(i, data_in_im,chunk_in_im); + +// x_complex in_a[X_DIM][Y_DIM][_TDM_CHUNKS]; +// x_complex out_a[X_DIM][Y_DIM][_TDM_CHUNKS]; +// x_complex out_b[X_DIM][Y_DIM][_TDM_CHUNKS]; +// for(int ii=0; ii(i, chunk_a_out_re, data_a_out_re, data_a_out_float_re); +// store_output_matrix(i, chunk_a_out_im, data_a_out_im, data_a_out_float_im); +// store_output_matrix(i, chunk_b_out_re, data_b_out_re, data_b_out_float_re); +// store_output_matrix(i, chunk_b_out_im, data_b_out_im, data_b_out_float_im); +// } + +// printf("Saving results to output file (%s, %s, %s, %s)...\n",output_a_data_file_re,output_a_data_file_im, +// output_b_data_file_re,output_b_data_file_im ); +// save_to_file(output_a_data_file_re, data_a_out_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_a_data_file_im, data_a_out_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_b_data_file_re, data_b_out_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_b_data_file_im, data_b_out_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); + +// int filename_len; +// const char *float_end = "_float.txt"; + +// filename_len = strlen(output_a_data_file_re); +// char *output_a_data_file_float_re = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_a_data_file_float_re, output_a_data_file_re); +// output_a_data_file_float_re[filename_len-4] = '\0'; +// strcat(output_a_data_file_float_re, float_end); + +// filename_len = strlen(output_a_data_file_im); +// char *output_a_data_file_float_im = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_a_data_file_float_im, output_a_data_file_im); +// output_a_data_file_float_im[filename_len-4] = '\0'; +// strcat(output_a_data_file_float_im, float_end); + +// filename_len = strlen(output_b_data_file_re); +// char *output_b_data_file_float_re = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_b_data_file_float_re, output_b_data_file_re); +// output_b_data_file_float_re[filename_len-4] = '\0'; +// strcat(output_b_data_file_float_re, float_end); + +// filename_len = strlen(output_b_data_file_im); +// char *output_b_data_file_float_im = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_b_data_file_float_im, output_b_data_file_im); +// output_b_data_file_float_im[filename_len-4] = '\0'; +// strcat(output_b_data_file_float_im, float_end); + +// printf("Saving results to output file (%s, %s, %s, %s) ...\n", output_a_data_file_float_re, +// output_a_data_file_float_im, output_b_data_file_float_re, output_b_data_file_im ); +// save_to_file(output_a_data_file_float_re, data_a_out_float_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_a_data_file_float_im, data_a_out_float_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_b_data_file_float_re, data_b_out_float_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_b_data_file_float_im, data_b_out_float_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); + +// /* +// ****************************************************************************** +// * Compare C code results to expected Matlab reference script results +// ****************************************************************************** +// */ +// printf("Comparing results (%s, %s, %s, %s, %s, %s, %s, %s)...\n", +// output_a_data_file_re,expected_a_data_file_re, +// output_a_data_file_im,expected_a_data_file_im, +// output_b_data_file_re,expected_b_data_file_re, +// output_b_data_file_im,expected_b_data_file_im); +// int cmp_res_i; +// T2out dummy; +// cmp_res_i = compare_files(dummy, expected_a_data_file_re, output_a_data_file_re, 1, output_data_size, base, +// err); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_a_data_file_im, output_a_data_file_im, 1, +// output_data_size, base, err); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_b_data_file_re, output_b_data_file_re, 1, +// output_data_size, base, err); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_b_data_file_im, output_b_data_file_im, 1, +// output_data_size, base, err); + +// if (cmp_res_i != 0) { +// printf("Data verification completed successfully.\n"); +// } else { +// printf("Data verification completed with errors.\n"); +// } + +// free(data_a_out_re); +// free(data_a_out_im); +// free(data_a_out_float_re); +// free(data_a_out_float_im); +// free(data_b_out_re); +// free(data_b_out_im); +// free(data_b_out_float_re); +// free(data_b_out_float_im); +// free(data_in_re); +// free(data_in_im); + +// return 0; +// } + +// /* +// * real C = f(real A, real B) +// * +// * T2: default data type (float, ap_fixed) +// * T1: storage data type of input file (float -> float, ap_fixed -> int) +// */ + +// template +// int test_func_2_1_c( +// int argc, char* argv[], float base, float err, +// void (*func)(x_complex [X_DIM][Y_DIM][_TDM_CHUNKS], +// x_complex [X_DIM][Y_DIM][_TDM_CHUNKS], +// x_complex [X_DIM][Y_DIM][_TDM_CHUNKS])) +// { +// // File names +// char *input_a_data_file_re = argv[1];//"ch_matrices_re.txt"; +// char *input_a_data_file_im = argv[2];//"ch_matrices_im.txt"; +// char *input_b_data_file_re = argv[3];//"ch_matrices_re.txt"; +// char *input_b_data_file_im = argv[4];//"ch_matrices_im.txt"; +// char *output_data_file_re = argv[5];//"results_re.txt"; +// char *output_data_file_im = argv[6];//"results_im.txt"; +// char *expected_data_file_re = argv[7];//"simulation_data_re.txt"; +// char *expected_data_file_im = argv[8];//"simulation_data_im.txt"; + +// // Matrix dimension +// short matrix_dimension[2] = {X_DIM,Y_DIM}; +// int m = 2*matrix_dimension[0]; +// int n = 2*matrix_dimension[1]; + +// // Data size +// int input_data_size = X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS; +// int output_data_size = X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS; + +// // File data pointers +// T1 *data_a_in_re, *data_a_in_im, *data_b_in_re, *data_b_in_im; +// T1 *data_out_re, *data_out_im; +// float *data_out_float_re, *data_out_float_im; +// data_a_in_re = (T1*)malloc(input_data_size * sizeof(T1)); +// data_a_in_im = (T1*)malloc(input_data_size * sizeof(T1)); +// data_b_in_re = (T1*)malloc(input_data_size * sizeof(T1)); +// data_b_in_im = (T1*)malloc(input_data_size * sizeof(T1)); +// data_out_re = (T1*)malloc(output_data_size * sizeof(T1)); +// data_out_im = (T1*)malloc(output_data_size * sizeof(T1)); +// data_out_float_re = (float*)malloc(output_data_size * sizeof(float)); +// data_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + +// // Function arguments - data matrices +// T2in chunk_a_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2in chunk_a_in_im[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2in chunk_b_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2in chunk_b_in_im[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + +// printf("Test beginning...\n"); +// /* +// ****************************************************************************** +// * Load data, perfrom function, and store result +// ****************************************************************************** +// */ +// printf("Loading values from txt files (%s, %s, %s, +// %s)...\n",input_a_data_file_re,input_a_data_file_im,input_b_data_file_re,input_b_data_file_im); +// load_from_file(input_a_data_file_re, data_a_in_re, input_data_size); +// load_from_file(input_a_data_file_im, data_a_in_im, input_data_size); +// load_from_file(input_b_data_file_re, data_b_in_re, input_data_size); +// load_from_file(input_b_data_file_im, data_b_in_im, input_data_size); + +// for(int i = 0; i < NUM_CHUNKS; i++) +// { +// printf("Loading input data array ...\n"); +// load_input_matrix(i, data_a_in_re,chunk_a_in_re); +// load_input_matrix(i, data_a_in_im,chunk_a_in_im); +// load_input_matrix(i, data_b_in_re,chunk_b_in_re); +// load_input_matrix(i, data_b_in_im,chunk_b_in_im); + +// x_complex in_a[X_DIM][Y_DIM][_TDM_CHUNKS]; +// x_complex in_b[X_DIM][Y_DIM][_TDM_CHUNKS]; +// x_complex out_c[X_DIM][Y_DIM][_TDM_CHUNKS]; +// for(int ii=0; ii(i, chunk_out_re, data_out_re, data_out_float_re); +// store_output_matrix(i, chunk_out_im, data_out_im, data_out_float_im); +// } + +// printf("Saving results to output file (%s, %s)...\n",output_data_file_re,output_data_file_im); +// save_to_file(output_data_file_re, data_out_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_data_file_im, data_out_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); + +// int out_name_len_re = strlen(output_data_file_re); +// char output_data_file_float_re[out_name_len_re+7]; +// strcpy(output_data_file_float_re, output_data_file_re); +// output_data_file_float_re[out_name_len_re-4] = '\0'; +// const char *float_end_re = "_float.txt"; +// strcat(output_data_file_float_re, float_end_re); + +// int out_name_len_im = strlen(output_data_file_im); +// char output_data_file_float_im[out_name_len_im+7]; +// strcpy(output_data_file_float_im, output_data_file_im); +// output_data_file_float_im[out_name_len_im-4] = '\0'; +// const char *float_end_im = "_float.txt"; +// strcat(output_data_file_float_im, float_end_im); + +// printf("Saving results to output file (%s, %s) ...\n", output_data_file_float_re, output_data_file_float_im); +// save_to_file(output_data_file_float_re, data_out_float_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_data_file_float_im, data_out_float_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); + +// /* +// ****************************************************************************** +// * Compare C code results to expected Matlab reference script results +// ****************************************************************************** +// */ +// printf("Comparing results (%s, %s)...\n",output_data_file_re,expected_data_file_re); +// int cmp_res_i; +// T2out dummy; +// cmp_res_i = compare_files(dummy, expected_data_file_re, output_data_file_re, 1, output_data_size, base, err); +// printf("Comparing results (%s, %s)...\n",output_data_file_im,expected_data_file_im); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_data_file_im, output_data_file_im, 1, output_data_size, +// base, err); + +// if (cmp_res_i != 0) { +// printf("Data verification completed successfully.\n"); +// } else { +// printf("Data verification completed with errors.\n"); +// } + +// free(data_out_re); +// free(data_out_im); +// free(data_out_float_re); +// free(data_out_float_im); +// free(data_a_in_re); +// free(data_a_in_im); +// free(data_b_in_re); +// free(data_b_in_im); + +// return 0; +// } + +// /* +// * real C = f(real A, real B) +// * +// * T2: default data type (float, ap_fixed) +// * T1: storage data type of input file (float -> float, ap_fixed -> int) +// */ +// template +// int test_func_2_1_c( +// int argc, char* argv[], float base, float err, +// void (*func)(x_complex [X_DIM1][Y_DIM1][_TDM_CHUNKS], +// x_complex [X_DIM2][Y_DIM2][_TDM_CHUNKS], +// x_complex [X_DIM3][Y_DIM3][_TDM_CHUNKS])) +// { +// // File names +// char *input_a_data_file_re = argv[1];//"ch_matrices_re.txt"; +// char *input_a_data_file_im = argv[2];//"ch_matrices_im.txt"; +// char *input_b_data_file_re = argv[3];//"ch_matrices_re.txt"; +// char *input_b_data_file_im = argv[4];//"ch_matrices_im.txt"; +// char *output_data_file_re = argv[5];//"results_re.txt"; +// char *output_data_file_im = argv[6];//"results_im.txt"; +// char *expected_data_file_re = argv[7];//"simulation_data_re.txt"; +// char *expected_data_file_im = argv[8];//"simulation_data_im.txt"; + +// // Matrix dimension +// // short matrix_dimension[2] = {X_DIM,Y_DIM}; +// // int m = 2*matrix_dimension[0]; +// // int n = 2*matrix_dimension[1]; + +// // Data size +// int input1_data_size = X_DIM1*Y_DIM1*NUM_CHUNKS*_TDM_CHUNKS; +// int input2_data_size = X_DIM2*Y_DIM2*NUM_CHUNKS*_TDM_CHUNKS; +// int output_data_size = X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS; + +// // File data pointers +// T1 *data_a_in_re, *data_a_in_im, *data_b_in_re, *data_b_in_im; +// T1 *data_out_re, *data_out_im; +// float *data_out_float_re, *data_out_float_im; +// data_a_in_re = (T1*)malloc(input1_data_size * sizeof(T1)); +// data_a_in_im = (T1*)malloc(input1_data_size * sizeof(T1)); +// data_b_in_re = (T1*)malloc(input2_data_size * sizeof(T1)); +// data_b_in_im = (T1*)malloc(input2_data_size * sizeof(T1)); +// data_out_re = (T1*)malloc(output_data_size * sizeof(T1)); +// data_out_im = (T1*)malloc(output_data_size * sizeof(T1)); +// data_out_float_re = (float*)malloc(output_data_size * sizeof(float)); +// data_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + +// // Function arguments - data matrices +// T2in chunk_a_in_re[X_DIM1][Y_DIM1][_TDM_CHUNKS]; +// T2in chunk_a_in_im[X_DIM1][Y_DIM1][_TDM_CHUNKS]; +// T2in chunk_b_in_re[X_DIM2][Y_DIM2][_TDM_CHUNKS]; +// T2in chunk_b_in_im[X_DIM2][Y_DIM2][_TDM_CHUNKS]; +// T2out chunk_out_re[X_DIM3][Y_DIM3][_TDM_CHUNKS]; +// T2out chunk_out_im[X_DIM3][Y_DIM3][_TDM_CHUNKS]; + +// printf("Test beginning...\n"); +// /* +// ****************************************************************************** +// * Load data, perfrom function, and store result +// ****************************************************************************** +// */ +// printf("Loading values from txt files (%s, %s, %s, +// %s)...\n",input_a_data_file_re,input_a_data_file_im,input_b_data_file_re,input_b_data_file_im); +// load_from_file(input_a_data_file_re, data_a_in_re, input1_data_size); +// load_from_file(input_a_data_file_im, data_a_in_im, input1_data_size); +// load_from_file(input_b_data_file_re, data_b_in_re, input2_data_size); +// load_from_file(input_b_data_file_im, data_b_in_im, input2_data_size); + +// for(int i = 0; i < NUM_CHUNKS; i++) +// { +// printf("Loading input data array ...\n"); +// load_input_matrix(i, data_a_in_re,chunk_a_in_re); +// load_input_matrix(i, data_a_in_im,chunk_a_in_im); +// load_input_matrix(i, data_b_in_re,chunk_b_in_re); +// load_input_matrix(i, data_b_in_im,chunk_b_in_im); + +// x_complex in_a[X_DIM1][Y_DIM1][_TDM_CHUNKS]; +// x_complex in_b[X_DIM2][Y_DIM2][_TDM_CHUNKS]; +// x_complex out_c[X_DIM3][Y_DIM3][_TDM_CHUNKS]; +// for(int ii=0; ii(i, chunk_out_re, data_out_re, data_out_float_re); +// store_output_matrix(i, chunk_out_im, data_out_im, data_out_float_im); + +// } + +// printf("Saving results to output file (%s, %s)...\n",output_data_file_re,output_data_file_im); +// save_to_file(output_data_file_re, data_out_re, X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_data_file_im, data_out_im, X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS); + +// int out_name_len_re = strlen(output_data_file_re); +// char output_data_file_float_re[out_name_len_re+7]; +// strcpy(output_data_file_float_re, output_data_file_re); +// output_data_file_float_re[out_name_len_re-4] = '\0'; +// const char *float_end_re = "_float.txt"; +// strcat(output_data_file_float_re, float_end_re); + +// int out_name_len_im = strlen(output_data_file_im); +// char output_data_file_float_im[out_name_len_im+7]; +// strcpy(output_data_file_float_im, output_data_file_im); +// output_data_file_float_im[out_name_len_im-4] = '\0'; +// const char *float_end_im = "_float.txt"; +// strcat(output_data_file_float_im, float_end_im); + +// printf("Saving results to output file (%s, %s) ...\n", output_data_file_float_re, output_data_file_float_im); +// save_to_file(output_data_file_float_re, data_out_float_re, X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_data_file_float_im, data_out_float_im, X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS); + +// //------------------------------------------------------------------------------ +// //- Compare C code results to expected Matlab reference script results +// //------------------------------------------------------------------------------ + +// printf("Comparing results (%s, %s)...\n",output_data_file_re,expected_data_file_re); +// int cmp_res_i; +// T2out dummy; +// cmp_res_i = compare_files(dummy, expected_data_file_re, output_data_file_re, 1, output_data_size, base, err); +// printf("Comparing results (%s, %s)...\n",output_data_file_im,expected_data_file_im); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_data_file_im, output_data_file_im, 1, output_data_size, +// base, err); + +// if (cmp_res_i != 0) { +// printf("Data verification completed successfully.\n"); +// } else { +// printf("Data verification completed with errors.\n"); +// } + +// free(data_out_re); +// free(data_out_im); +// free(data_out_float_re); +// free(data_out_float_im); +// free(data_a_in_re); +// free(data_a_in_im); +// free(data_b_in_re); +// free(data_b_in_im); + +// return 0; +// } + +// /* +// * real C, real D = f(real A, real B) +// * +// * T2: default data type (float, ap_fixed) +// * T1: storage data type of input file (float -> float, ap_fixed -> int) +// */ +// template +// int test_func_2_2_c( +// int argc, char* argv[], float base, float err, +// void (*func)(x_complex [X_DIM1][Y_DIM1][_TDM_CHUNKS], +// x_complex [X_DIM2][Y_DIM2][_TDM_CHUNKS], +// x_complex [X_DIM3][Y_DIM3][_TDM_CHUNKS], +// x_complex [X_DIM4][Y_DIM4][_TDM_CHUNKS])) +// { +// // File names +// char *input_a_data_file_re = argv[1];//"ch_matrices_re.txt"; +// char *input_a_data_file_im = argv[2];//"ch_matrices_im.txt"; +// char *input_b_data_file_re = argv[3];//"ch_matrices_re.txt"; +// char *input_b_data_file_im = argv[4];//"ch_matrices_im.txt"; +// char *output_c_data_file_re = argv[5];//"results_re.txt"; +// char *output_c_data_file_im = argv[6];//"results_im.txt"; +// char *output_d_data_file_re = argv[7];//"results_re.txt"; +// char *output_d_data_file_im = argv[8];//"results_im.txt"; +// char *expected_c_data_file_re = argv[9];//"simulation_data_re.txt"; +// char *expected_c_data_file_im = argv[10];//"simulation_data_im.txt"; +// char *expected_d_data_file_re = argv[11];//"simulation_data_re.txt"; +// char *expected_d_data_file_im = argv[12];//"simulation_data_im.txt"; + +// // Matrix dimension +// // short matrix_dimension[2] = {X_DIM,Y_DIM}; +// // int m = 2*matrix_dimension[0]; +// // int n = 2*matrix_dimension[1]; + +// // Data size +// int input1_data_size = X_DIM1*Y_DIM1*NUM_CHUNKS*_TDM_CHUNKS; +// int input2_data_size = X_DIM2*Y_DIM2*NUM_CHUNKS*_TDM_CHUNKS; +// int output1_data_size = X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS; +// int output2_data_size = X_DIM4*Y_DIM4*NUM_CHUNKS*_TDM_CHUNKS; + +// // File data pointers +// T1 *data_a_in_re, *data_a_in_im, *data_b_in_re, *data_b_in_im; +// T1 *data_c_out_re, *data_c_out_im, *data_d_out_re, *data_d_out_im; +// float *data_c_out_float_re, *data_c_out_float_im; +// float *data_d_out_float_re, *data_d_out_float_im; + +// data_a_in_re = (T1*)malloc(input1_data_size * sizeof(T1)); +// data_a_in_im = (T1*)malloc(input1_data_size * sizeof(T1)); +// data_b_in_re = (T1*)malloc(input2_data_size * sizeof(T1)); +// data_b_in_im = (T1*)malloc(input2_data_size * sizeof(T1)); +// data_c_out_re = (T1*)malloc(output1_data_size * sizeof(T1)); +// data_c_out_im = (T1*)malloc(output1_data_size * sizeof(T1)); +// data_d_out_re = (T1*)malloc(output2_data_size * sizeof(T1)); +// data_d_out_im = (T1*)malloc(output2_data_size * sizeof(T1)); +// data_c_out_float_re = (float*)malloc(output1_data_size * sizeof(float)); +// data_c_out_float_im = (float*)malloc(output1_data_size * sizeof(float)); +// data_d_out_float_re = (float*)malloc(output2_data_size * sizeof(float)); +// data_d_out_float_im = (float*)malloc(output2_data_size * sizeof(float)); + +// // Function arguments - data matrices +// T2in chunk_a_in_re[X_DIM1][Y_DIM1][_TDM_CHUNKS]; +// T2in chunk_a_in_im[X_DIM1][Y_DIM1][_TDM_CHUNKS]; +// T2in chunk_b_in_re[X_DIM2][Y_DIM2][_TDM_CHUNKS]; +// T2in chunk_b_in_im[X_DIM2][Y_DIM2][_TDM_CHUNKS]; +// T2out chunk_c_out_re[X_DIM3][Y_DIM3][_TDM_CHUNKS]; +// T2out chunk_c_out_im[X_DIM3][Y_DIM3][_TDM_CHUNKS]; +// T2out chunk_d_out_re[X_DIM4][Y_DIM4][_TDM_CHUNKS]; +// T2out chunk_d_out_im[X_DIM4][Y_DIM4][_TDM_CHUNKS]; + +// printf("Test beginning...\n"); +// /* +// ****************************************************************************** +// * Load data, perfrom function, and store result +// ****************************************************************************** +// */ +// printf("Loading values from txt files (%s, %s, %s, +// %s)...\n",input_a_data_file_re,input_a_data_file_im,input_b_data_file_re,input_b_data_file_im); +// load_from_file(input_a_data_file_re, data_a_in_re, input1_data_size); +// load_from_file(input_a_data_file_im, data_a_in_im, input1_data_size); +// load_from_file(input_b_data_file_re, data_b_in_re, input2_data_size); +// load_from_file(input_b_data_file_im, data_b_in_im, input2_data_size); + +// for(int i = 0; i < NUM_CHUNKS; i++) +// { +// printf("Loading input a data array ...\n"); +// load_input_matrix(i, data_a_in_re,chunk_a_in_re); +// load_input_matrix(i, data_a_in_im,chunk_a_in_im); +// printf("Loading input a data array ...\n"); +// load_input_matrix(i, data_b_in_re,chunk_b_in_re); +// load_input_matrix(i, data_b_in_im,chunk_b_in_im); + +// x_complex in_a[X_DIM1][Y_DIM1][_TDM_CHUNKS]; +// x_complex in_b[X_DIM2][Y_DIM2][_TDM_CHUNKS]; +// x_complex out_c[X_DIM3][Y_DIM3][_TDM_CHUNKS]; +// x_complex out_d[X_DIM4][Y_DIM4][_TDM_CHUNKS]; + +// for(int ii=0; ii(in_a); + +// printf("in_b\n"); +// printf("-------\n"); +// dumpm(in_b); + +// //printf("Perform main function!!\n"); +// printf("Perform main function now!!\n"); +// (*func)(in_a,in_b,out_c,out_d); + +// printf("Main function done!!\n"); + +// printf("out_c\n"); +// printf("-------\n"); +// dumpm(out_c); + +// printf("out_d\n"); +// printf("-------\n"); +// dumpm(out_d); + +// for(int ii=0; ii(i, chunk_c_out_re, data_c_out_re, data_c_out_float_re); +// store_output_matrix(i, chunk_c_out_im, data_c_out_im, data_c_out_float_im); +// store_output_matrix(i, chunk_d_out_re, data_d_out_re, data_d_out_float_re); +// store_output_matrix(i, chunk_d_out_im, data_d_out_im, data_d_out_float_im); + +// } + +// printf("Saving results to output file (%s, %s)...\n",output_c_data_file_re,output_c_data_file_im); +// save_to_file(output_c_data_file_re, data_c_out_re, X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_c_data_file_im, data_c_out_im, X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS); + +// int out_c_name_len_re = strlen(output_c_data_file_re); +// char output_c_data_file_float_re[out_c_name_len_re+7]; +// strcpy(output_c_data_file_float_re, output_c_data_file_re); +// output_c_data_file_float_re[out_c_name_len_re-4] = '\0'; +// const char *float_c_end_re = "_float.txt"; +// strcat(output_c_data_file_float_re, float_c_end_re); + +// int out_c_name_len_im = strlen(output_c_data_file_im); +// char output_c_data_file_float_im[out_c_name_len_im+7]; +// strcpy(output_c_data_file_float_im, output_c_data_file_im); +// output_c_data_file_float_im[out_c_name_len_im-4] = '\0'; +// const char *float_c_end_im = "_float.txt"; +// strcat(output_c_data_file_float_im, float_c_end_im); + +// printf("Saving results to output file (%s, %s) ...\n", output_c_data_file_float_re, +// output_c_data_file_float_im); +// save_to_file(output_c_data_file_float_re, data_c_out_float_re, X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_c_data_file_float_im, data_c_out_float_im, X_DIM3*Y_DIM3*NUM_CHUNKS*_TDM_CHUNKS); + +// printf("Saving results to output file (%s, %s)...\n",output_d_data_file_re,output_d_data_file_im); +// save_to_file(output_d_data_file_re, data_d_out_re, X_DIM4*Y_DIM4*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_d_data_file_im, data_d_out_im, X_DIM4*Y_DIM4*NUM_CHUNKS*_TDM_CHUNKS); + +// int out_d_name_len_re = strlen(output_d_data_file_re); +// char output_d_data_file_float_re[out_d_name_len_re+7]; +// strcpy(output_d_data_file_float_re, output_d_data_file_re); +// output_d_data_file_float_re[out_d_name_len_re-4] = '\0'; +// const char *float_d_end_re = "_float.txt"; +// strcat(output_d_data_file_float_re, float_d_end_re); + +// int out_d_name_len_im = strlen(output_d_data_file_im); +// char output_d_data_file_float_im[out_d_name_len_im+7]; +// strcpy(output_d_data_file_float_im, output_d_data_file_im); +// output_d_data_file_float_im[out_d_name_len_im-4] = '\0'; +// const char *float_d_end_im = "_float.txt"; +// strcat(output_d_data_file_float_im, float_d_end_im); + +// printf("Saving results to output file (%s, %s) ...\n", output_d_data_file_float_re, +// output_d_data_file_float_im); +// save_to_file(output_d_data_file_float_re, data_d_out_float_re, X_DIM4*Y_DIM4*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_d_data_file_float_im, data_d_out_float_im, X_DIM4*Y_DIM4*NUM_CHUNKS*_TDM_CHUNKS); + +// //------------------------------------------------------------------------------ +// //- Compare C code results to expected Matlab reference script results +// //------------------------------------------------------------------------------ + +// printf("Comparing results (%s, %s)...\n",output_c_data_file_re,expected_c_data_file_re); +// int cmp_res_i; +// T2out dummy; +// cmp_res_i = compare_files(dummy, expected_c_data_file_re, output_c_data_file_re, 1, output1_data_size, base, +// err); +// printf("Comparing results (%s, %s)...\n",output_c_data_file_im,expected_c_data_file_im); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_c_data_file_im, output_c_data_file_im, 1, +// output1_data_size, base, err); + +// printf("Comparing results (%s, %s)...\n",output_d_data_file_re,expected_d_data_file_re); +// cmp_res_i = compare_files(dummy, expected_d_data_file_re, output_d_data_file_re, 1, output2_data_size, base, +// err); +// printf("Comparing results (%s, %s)...\n",output_d_data_file_im,expected_d_data_file_im); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_d_data_file_im, output_d_data_file_im, 1, +// output2_data_size, base, err); + +// if (cmp_res_i != 0) { +// printf("Data verification completed successfully.\n"); +// } else { +// printf("Data verification completed with errors.\n"); +// } + +// free(data_c_out_re); +// free(data_c_out_im); +// free(data_c_out_float_re); +// free(data_c_out_float_im); +// free(data_d_out_re); +// free(data_d_out_im); +// free(data_d_out_float_re); +// free(data_d_out_float_im); +// free(data_a_in_re); +// free(data_a_in_im); +// free(data_b_in_re); +// free(data_b_in_im); + +// return 0; +// } + +/* +* (real B, real C, real D) = f(real A) +* +* T2: default data type (float, ap_fixed) +* T1: storage data type of input file (float -> float, ap_fixed -> int) +*/ +template +int test_func_1_3(int argc, + char* argv[], + float base, + float err, + void (*func)(T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS])) { + // File names + char* input_data_file = argv[1]; //"ch_matrices_re.txt"; + char* output_a_data_file = argv[2]; //"results_a_re.txt"; + char* output_b_data_file = argv[3]; //"results_b_re.txt"; + char* output_c_data_file = argv[4]; //"results_c_re.txt"; + char* expected_a_data_file = argv[5]; //"simulation_a_data_re.txt"; + char* expected_b_data_file = argv[6]; //"simulation_b_data_re.txt"; + char* expected_c_data_file = argv[7]; //"simulation_c_data_re.txt"; + + // Matrix dimension + short matrix_dimension[2] = {X_DIM, Y_DIM}; + int m = 2 * matrix_dimension[0]; + int n = 2 * matrix_dimension[1]; + + // Data size + int input_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + int output_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + + // File data pointers + T1* data_in; + T1 *data_a_out, *data_b_out, *data_c_out; + float *data_a_out_float, *data_b_out_float, *data_c_out_float; + data_in = (T1*)malloc(input_data_size * sizeof(T1)); + data_a_out = (T1*)malloc(output_data_size * sizeof(T1)); + data_b_out = (T1*)malloc(output_data_size * sizeof(T1)); + data_c_out = (T1*)malloc(output_data_size * sizeof(T1)); + data_a_out_float = (float*)malloc(output_data_size * sizeof(float)); + data_b_out_float = (float*)malloc(output_data_size * sizeof(float)); + data_c_out_float = (float*)malloc(output_data_size * sizeof(float)); + + // Function arguments - data matrices + T2in chunk_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_a_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_b_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_c_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + + printf("Test beginning...\n"); + /* + ****************************************************************************** + * Load data, perfrom function, and store result + ****************************************************************************** + */ + printf("Loading values from txt files (%s)...\n", input_data_file); + load_from_file(input_data_file, data_in, input_data_size); + + for (int i = 0; i < NUM_CHUNKS; i++) { + printf("Loading input data array ...\n"); + load_input_matrix(i, data_in, chunk_in_re); + + printf("Perform main function!!\n"); + //(*func)(chunk_in_re, chunk_out_re); + (*func)(chunk_in_re, chunk_a_out_re, chunk_b_out_re, chunk_c_out_re); + + printf("Store output result ... \n"); + store_output_matrix(i, chunk_a_out_re, data_a_out, data_a_out_float); + store_output_matrix(i, chunk_b_out_re, data_b_out, data_b_out_float); + store_output_matrix(i, chunk_c_out_re, data_c_out, data_c_out_float); + } + + printf("Saving results to output file (%s, %s, %s)...\n", output_a_data_file, output_b_data_file, + output_c_data_file); + save_to_file(output_a_data_file, data_a_out, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_b_data_file, data_b_out, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_c_data_file, data_c_out, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + int filename_len; + const char* float_end = "_float.txt"; + + filename_len = strlen(output_a_data_file); + char* output_a_data_file_float = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_a_data_file_float, output_a_data_file); + output_a_data_file_float[filename_len - 4] = '\0'; + strcat(output_a_data_file_float, float_end); + + filename_len = strlen(output_b_data_file); + char* output_b_data_file_float = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_b_data_file_float, output_b_data_file); + output_b_data_file_float[filename_len - 4] = '\0'; + strcat(output_b_data_file_float, float_end); + + filename_len = strlen(output_c_data_file); + char* output_c_data_file_float = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_c_data_file_float, output_c_data_file); + output_c_data_file_float[filename_len - 4] = '\0'; + strcat(output_c_data_file_float, float_end); + + printf("Saving results to output file (%s, %s, %s) ...\n", output_a_data_file_float, output_b_data_file_float, + output_c_data_file_float); + save_to_file(output_a_data_file_float, data_a_out_float, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_b_data_file_float, data_b_out_float, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_c_data_file_float, data_c_out_float, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + /* + ****************************************************************************** + * Compare C code results to expected Matlab reference script results + ****************************************************************************** + */ + printf("Comparing results (%s, %s)...\n", output_a_data_file, expected_a_data_file); + int cmp_res_i; + T2out dummy; + cmp_res_i = compare_files(dummy, expected_a_data_file, output_a_data_file, 1, output_data_size, base, err); + printf("Comparing results (%s, %s)...\n", output_b_data_file, expected_b_data_file); + cmp_res_i = + cmp_res_i & compare_files(dummy, expected_b_data_file, output_b_data_file, 1, output_data_size, base, err); + printf("Comparing results (%s, %s)...\n", output_c_data_file, expected_c_data_file); + cmp_res_i = + cmp_res_i & compare_files(dummy, expected_c_data_file, output_c_data_file, 1, output_data_size, base, err); + + if (cmp_res_i != 0) { + printf("Data verification completed successfully.\n"); + } else { + printf("Data verification completed with errors.\n"); + } + + free(data_a_out); + free(data_a_out_float); + free(data_b_out); + free(data_b_out_float); + free(data_c_out); + free(data_c_out_float); + free(data_in); + + return 0; +} + +/* +* complex C = f(complex A) +* +* T2: default data type (float, ap_fixed) +* T1: storage data type of input file (float -> float, ap_fixed -> int) +*/ +template +int test_func_1_1(int argc, + char* argv[], + float base, + float err, + void (*func)(T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS])) { + // File names + char* input_data_file_re = argv[1]; //"ch_matrices_re.txt"; + char* input_data_file_im = argv[2]; //"ch_matrices_im.txt"; + char* output_data_file_re = argv[3]; //"results_re.txt"; + char* output_data_file_im = argv[4]; //"results_im.txt"; + char* expected_data_file_re = argv[5]; //"simulation_data_re.txt"; + char* expected_data_file_im = argv[6]; //"simulation_data_im.txt"; + + // Matrix dimension + short matrix_dimension[2] = {X_DIM, Y_DIM}; + int m = 2 * matrix_dimension[0]; + int n = 2 * matrix_dimension[1]; + + // Data size + int input_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + int output_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + + // File data pointers + T1 *data_in_re, *data_in_im; + T1 *data_out_re, *data_out_im; + float *data_out_float_re, *data_out_float_im; + data_in_re = (T1*)malloc(input_data_size * sizeof(T1)); + data_in_im = (T1*)malloc(input_data_size * sizeof(T1)); + data_out_re = (T1*)malloc(output_data_size * sizeof(T1)); + data_out_im = (T1*)malloc(output_data_size * sizeof(T1)); + data_out_float_re = (float*)malloc(output_data_size * sizeof(float)); + data_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + + // Function arguments - data matrices + T2in chunk_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2in chunk_in_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + + printf("Test beginning...\n"); + /* + ****************************************************************************** + * Load data, perfrom function, and store result + ****************************************************************************** + */ + printf("Loading values from txt files (%s, %s)...\n", input_data_file_re, input_data_file_im); + load_from_file(input_data_file_re, data_in_re, input_data_size); + load_from_file(input_data_file_im, data_in_im, input_data_size); + + for (int i = 0; i < NUM_CHUNKS; i++) { + printf("Loading input data array ...\n"); + load_input_matrix(i, data_in_re, chunk_in_re); + load_input_matrix(i, data_in_im, chunk_in_im); + + printf("Perform main function!!\n"); + (*func)(chunk_in_re, chunk_in_im, chunk_out_re, chunk_out_im); + + printf("Store output result ... \n"); + store_output_matrix(i, chunk_out_re, data_out_re, data_out_float_re); + store_output_matrix(i, chunk_out_im, data_out_im, data_out_float_im); + } + + printf("Saving results to output file (%s, %s)...\n", output_data_file_re, output_data_file_im); + save_to_file(output_data_file_re, data_out_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_data_file_im, data_out_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + int out_name_len_re = strlen(output_data_file_re); + char output_data_file_float_re[out_name_len_re + 7]; + strcpy(output_data_file_float_re, output_data_file_re); + output_data_file_float_re[out_name_len_re - 4] = '\0'; + const char* float_end_re = "_float.txt"; + strcat(output_data_file_float_re, float_end_re); + + int out_name_len_im = strlen(output_data_file_im); + char output_data_file_float_im[out_name_len_im + 7]; + strcpy(output_data_file_float_im, output_data_file_im); + output_data_file_float_im[out_name_len_im - 4] = '\0'; + const char* float_end_im = "_float.txt"; + strcat(output_data_file_float_im, float_end_im); + + printf("Saving results to output file (%s, %s) ...\n", output_data_file_float_re, output_data_file_float_im); + save_to_file(output_data_file_float_re, data_out_float_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_data_file_float_im, data_out_float_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + /* + ****************************************************************************** + * Compare C code results to expected Matlab reference script results + ****************************************************************************** + */ + printf("Comparing results (%s, %s)...\n", output_data_file_re, expected_data_file_re); + int cmp_res_i; + T2out dummy; + cmp_res_i = compare_files(dummy, expected_data_file_re, output_data_file_re, 1, output_data_size, base, err); + printf("Comparing results (%s, %s)...\n", output_data_file_im, expected_data_file_im); + cmp_res_i = + cmp_res_i & compare_files(dummy, expected_data_file_im, output_data_file_im, 1, output_data_size, base, err); + + if (cmp_res_i != 0) { + printf("Data verification completed successfully.\n"); + } else { + printf("Data verification completed with errors.\n"); + } + + free(data_out_re); + free(data_out_im); + free(data_out_float_re); + free(data_out_float_im); + free(data_in_re); + free(data_in_im); + + return 0; +} + +// /* +// * complex C = f(complex A) +// * +// * T2: default data type (float, ap_fixed) +// * T1: storage data type of input file (float -> float, ap_fixed -> int) +// */ +// template +// int test_func_1_1_c( +// int argc, char* argv[], float base, float err, +// void (*func)(x_complex[X_DIM][Y_DIM][_TDM_CHUNKS], +// x_complex[X_DIM][Y_DIM][_TDM_CHUNKS])) +// { +// // File names +// char *input_data_file_re = argv[1];//"ch_matrices_re.txt"; +// char *input_data_file_im = argv[2];//"ch_matrices_im.txt"; +// char *output_data_file_re = argv[3];//"results_re.txt"; +// char *output_data_file_im = argv[4];//"results_im.txt"; +// char *expected_data_file_re = argv[5];//"simulation_data_re.txt"; +// char *expected_data_file_im = argv[6];//"simulation_data_im.txt"; + +// // Matrix dimension +// short matrix_dimension[2] = {X_DIM,Y_DIM}; +// int m = 2*matrix_dimension[0]; +// int n = 2*matrix_dimension[1]; + +// // Data size +// int input_data_size = X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS; +// int output_data_size = X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS; + +// // File data pointers +// T1 *data_in_re, *data_in_im; +// T1 *data_out_re, *data_out_im; +// float *data_out_float_re, *data_out_float_im; +// data_in_re = (T1*)malloc(input_data_size * sizeof(T1)); +// data_in_im = (T1*)malloc(input_data_size * sizeof(T1)); +// data_out_re = (T1*)malloc(output_data_size * sizeof(T1)); +// data_out_im = (T1*)malloc(output_data_size * sizeof(T1)); +// data_out_float_re = (float*)malloc(output_data_size * sizeof(float)); +// data_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + +// // Function arguments - data matrices +// T2in chunk_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2in chunk_in_im[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + +// printf("Test beginning...\n"); +// /* +// ****************************************************************************** +// * Load data, perfrom function, and store result +// ****************************************************************************** +// */ +// printf("Loading values from txt files (%s, %s)...\n",input_data_file_re,input_data_file_im); +// load_from_file(input_data_file_re, data_in_re, input_data_size); +// load_from_file(input_data_file_im, data_in_im, input_data_size); + +// for(int i = 0; i < NUM_CHUNKS; i++) +// { +// printf("Loading input data array ...\n"); +// load_input_matrix(i, data_in_re,chunk_in_re); +// load_input_matrix(i, data_in_im,chunk_in_im); + +// x_complex in_a[X_DIM][Y_DIM][_TDM_CHUNKS]; +// x_complex out_c[X_DIM][Y_DIM][_TDM_CHUNKS]; +// for(int ii=0; ii(i, chunk_out_re, data_out_re, data_out_float_re); +// store_output_matrix(i, chunk_out_im, data_out_im, data_out_float_im); +// } + +// printf("Saving results to output file (%s, %s)...\n",output_data_file_re,output_data_file_im); +// save_to_file(output_data_file_re, data_out_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_data_file_im, data_out_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); + +// int out_name_len_re = strlen(output_data_file_re); +// char output_data_file_float_re[out_name_len_re+7]; +// strcpy(output_data_file_float_re, output_data_file_re); +// output_data_file_float_re[out_name_len_re-4] = '\0'; +// const char *float_end_re = "_float.txt"; +// strcat(output_data_file_float_re, float_end_re); + +// int out_name_len_im = strlen(output_data_file_im); +// char output_data_file_float_im[out_name_len_im+7]; +// strcpy(output_data_file_float_im, output_data_file_im); +// output_data_file_float_im[out_name_len_im-4] = '\0'; +// const char *float_end_im = "_float.txt"; +// strcat(output_data_file_float_im, float_end_im); + +// printf("Saving results to output file (%s, %s) ...\n", output_data_file_float_re, output_data_file_float_im); +// save_to_file(output_data_file_float_re, data_out_float_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_data_file_float_im, data_out_float_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); + +// /* +// ****************************************************************************** +// * Compare C code results to expected Matlab reference script results +// ****************************************************************************** +// */ +// printf("Comparing results (%s, %s)...\n",output_data_file_re,expected_data_file_re); +// int cmp_res_i; +// T2out dummy; +// cmp_res_i = compare_files(dummy, expected_data_file_re, output_data_file_re, 1, output_data_size, base, err); +// printf("Comparing results (%s, %s)...\n",output_data_file_im,expected_data_file_im); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_data_file_im, output_data_file_im, 1, output_data_size, +// base, err); + +// if (cmp_res_i != 0) { +// printf("Data verification completed successfully.\n"); +// } else { +// printf("Data verification completed with errors.\n"); +// } + +// free(data_out_re); +// free(data_out_im); +// free(data_out_float_re); +// free(data_out_float_im); +// free(data_in_re); +// free(data_in_im); + +// return 0; +// } + +/* +* complex C = f(complex A, complex B) +* +* T2: default data type (float, ap_fixed) +* T1: storage data type of input file (float -> float, ap_fixed -> int) +*/ +template +int test_func_2_1(int argc, + char* argv[], + float base, + float err, + void (*func)(T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS])) { + // File names + char* input_a_data_file_re = argv[1]; //"ch_matrices_re.txt"; + char* input_a_data_file_im = argv[2]; //"ch_matrices_im.txt"; + char* input_b_data_file_re = argv[3]; //"ch_matrices_re.txt"; + char* input_b_data_file_im = argv[4]; //"ch_matrices_im.txt"; + char* output_data_file_re = argv[5]; //"results_re.txt"; + char* output_data_file_im = argv[6]; //"results_im.txt"; + char* expected_data_file_re = argv[7]; //"simulation_data_re.txt"; + char* expected_data_file_im = argv[8]; //"simulation_data_im.txt"; + + // Matrix dimension + short matrix_dimension[2] = {X_DIM, Y_DIM}; + int m = 2 * matrix_dimension[0]; + int n = 2 * matrix_dimension[1]; + + // Data size + int input_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + int output_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + + // File data pointers + T1 *data_a_in_re, *data_a_in_im, *data_b_in_re, *data_b_in_im; + T1 *data_out_re, *data_out_im; + float *data_out_float_re, *data_out_float_im; + data_a_in_re = (T1*)malloc(input_data_size * sizeof(T1)); + data_a_in_im = (T1*)malloc(input_data_size * sizeof(T1)); + data_b_in_re = (T1*)malloc(input_data_size * sizeof(T1)); + data_b_in_im = (T1*)malloc(input_data_size * sizeof(T1)); + data_out_re = (T1*)malloc(output_data_size * sizeof(T1)); + data_out_im = (T1*)malloc(output_data_size * sizeof(T1)); + data_out_float_re = (float*)malloc(output_data_size * sizeof(float)); + data_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + + // Function arguments - data matrices + T2in chunk_a_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2in chunk_a_in_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2in chunk_b_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2in chunk_b_in_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + + printf("Test beginning...\n"); + /* + ****************************************************************************** + * Load data, perfrom function, and store result + ****************************************************************************** + */ + printf("Loading values from txt files (%s, %s, %s, %s)...\n", input_a_data_file_re, input_a_data_file_im, + input_b_data_file_re, input_b_data_file_im); + load_from_file(input_a_data_file_re, data_a_in_re, input_data_size); + load_from_file(input_a_data_file_im, data_a_in_im, input_data_size); + load_from_file(input_b_data_file_re, data_b_in_re, input_data_size); + load_from_file(input_b_data_file_im, data_b_in_im, input_data_size); + + for (int i = 0; i < NUM_CHUNKS; i++) { + printf("Loading input data array ...\n"); + load_input_matrix(i, data_a_in_re, chunk_a_in_re); + load_input_matrix(i, data_a_in_im, chunk_a_in_im); + load_input_matrix(i, data_b_in_re, chunk_b_in_re); + load_input_matrix(i, data_b_in_im, chunk_b_in_im); + + printf("Perform main function!!\n"); + (*func)(chunk_a_in_re, chunk_a_in_im, chunk_b_in_re, chunk_b_in_im, chunk_out_re, chunk_out_im); + + printf("Store output result ... \n"); + store_output_matrix(i, chunk_out_re, data_out_re, data_out_float_re); + store_output_matrix(i, chunk_out_im, data_out_im, data_out_float_im); + } + + printf("Saving results to output file (%s, %s)...\n", output_data_file_re, output_data_file_im); + save_to_file(output_data_file_re, data_out_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_data_file_im, data_out_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + int out_name_len_re = strlen(output_data_file_re); + char output_data_file_float_re[out_name_len_re + 7]; + strcpy(output_data_file_float_re, output_data_file_re); + output_data_file_float_re[out_name_len_re - 4] = '\0'; + const char* float_end_re = "_float.txt"; + strcat(output_data_file_float_re, float_end_re); + + int out_name_len_im = strlen(output_data_file_im); + char output_data_file_float_im[out_name_len_im + 7]; + strcpy(output_data_file_float_im, output_data_file_im); + output_data_file_float_im[out_name_len_im - 4] = '\0'; + const char* float_end_im = "_float.txt"; + strcat(output_data_file_float_im, float_end_im); + + printf("Saving results to output file (%s, %s) ...\n", output_data_file_float_re, output_data_file_float_im); + save_to_file(output_data_file_float_re, data_out_float_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_data_file_float_im, data_out_float_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + /* + ****************************************************************************** + * Compare C code results to expected Matlab reference script results + ****************************************************************************** + */ + printf("Comparing results (%s, %s)...\n", output_data_file_re, expected_data_file_re); + int cmp_res_i; + T2out dummy; + cmp_res_i = compare_files(dummy, expected_data_file_re, output_data_file_re, 1, output_data_size, base, err); + printf("Comparing results (%s, %s)...\n", output_data_file_im, expected_data_file_im); + cmp_res_i = + cmp_res_i & compare_files(dummy, expected_data_file_im, output_data_file_im, 1, output_data_size, base, err); + + if (cmp_res_i != 0) { + printf("Data verification completed successfully.\n"); + } else { + printf("Data verification completed with errors.\n"); + } + + free(data_out_re); + free(data_out_im); + free(data_out_float_re); + free(data_out_float_im); + free(data_a_in_re); + free(data_a_in_im); + free(data_b_in_re); + free(data_b_in_im); + + return 0; +} + +/* +* (complex B, complex C, complex D) = f(complex A) +* +* T2: default data type (float, ap_fixed) +* T1: storage data type of input file (float -> float, ap_fixed -> int) +*/ +template +int test_func_1_3(int argc, + char* argv[], + float base, + float err, + void (*func)(T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2in[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS], + T2out[X_DIM][Y_DIM][_TDM_CHUNKS])) { + // File names + char* input_data_file_re = argv[1]; //"ch_matrices_re.txt"; + char* input_data_file_im = argv[2]; //"ch_matrices_im.txt"; + char* output_a_data_file_re = argv[3]; //"results_a_re.txt"; + char* output_a_data_file_im = argv[4]; //"results_a_im.txt"; + char* output_b_data_file_re = argv[5]; //"results_b_re.txt"; + char* output_b_data_file_im = argv[6]; //"results_b_im.txt"; + char* output_c_data_file_re = argv[7]; //"results_c_re.txt"; + char* output_c_data_file_im = argv[8]; //"results_c_im.txt"; + char* expected_a_data_file_re = argv[9]; //"simulation_a_data_re.txt"; + char* expected_a_data_file_im = argv[10]; //"simulation_a_data_im.txt"; + char* expected_b_data_file_re = argv[11]; //"simulation_b_data_re.txt"; + char* expected_b_data_file_im = argv[12]; //"simulation_b_data_im.txt"; + char* expected_c_data_file_re = argv[13]; //"simulation_c_data_re.txt"; + char* expected_c_data_file_im = argv[14]; //"simulation_c_data_im.txt"; + + // Matrix dimension + short matrix_dimension[2] = {X_DIM, Y_DIM}; + int m = 2 * matrix_dimension[0]; + int n = 2 * matrix_dimension[1]; + + // Data size + int input_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + int output_data_size = X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS; + + // File data pointers + T1 *data_in_re, *data_in_im; + T1 *data_a_out_re, *data_a_out_im; + T1 *data_b_out_re, *data_b_out_im; + T1 *data_c_out_re, *data_c_out_im; + + float *data_a_out_float_re, *data_a_out_float_im; + float *data_b_out_float_re, *data_b_out_float_im; + float *data_c_out_float_re, *data_c_out_float_im; + + data_in_re = (T1*)malloc(input_data_size * sizeof(T1)); + data_in_im = (T1*)malloc(input_data_size * sizeof(T1)); + data_a_out_re = (T1*)malloc(output_data_size * sizeof(T1)); + data_a_out_im = (T1*)malloc(output_data_size * sizeof(T1)); + data_b_out_re = (T1*)malloc(output_data_size * sizeof(T1)); + data_b_out_im = (T1*)malloc(output_data_size * sizeof(T1)); + data_c_out_re = (T1*)malloc(output_data_size * sizeof(T1)); + data_c_out_im = (T1*)malloc(output_data_size * sizeof(T1)); + data_a_out_float_re = (float*)malloc(output_data_size * sizeof(float)); + data_a_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + data_b_out_float_re = (float*)malloc(output_data_size * sizeof(float)); + data_b_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + data_c_out_float_re = (float*)malloc(output_data_size * sizeof(float)); + data_c_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + + // Function arguments - data matrices + T2in chunk_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2in chunk_in_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_a_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_a_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_b_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_b_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_c_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; + T2out chunk_c_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + + printf("Test beginning...\n"); + /* + ****************************************************************************** + * Load data, perfrom function, and store result + ****************************************************************************** + */ + printf("Loading values from txt files (%s, %s)...\n", input_data_file_re, input_data_file_im); + load_from_file(input_data_file_re, data_in_re, input_data_size); + load_from_file(input_data_file_im, data_in_im, input_data_size); + + for (int i = 0; i < NUM_CHUNKS; i++) { + printf("Loading input data array ...\n"); + load_input_matrix(i, data_in_re, chunk_in_re); + load_input_matrix(i, data_in_im, chunk_in_im); + + printf("Perform main function!!\n"); + (*func)(chunk_in_re, chunk_in_im, chunk_a_out_re, chunk_a_out_im, chunk_b_out_re, chunk_b_out_im, + chunk_c_out_re, chunk_c_out_im); + + printf("Store output result ... \n"); + store_output_matrix(i, chunk_a_out_re, data_a_out_re, data_a_out_float_re); + store_output_matrix(i, chunk_a_out_im, data_a_out_im, data_a_out_float_im); + store_output_matrix(i, chunk_b_out_re, data_b_out_re, data_b_out_float_re); + store_output_matrix(i, chunk_b_out_im, data_b_out_im, data_b_out_float_im); + store_output_matrix(i, chunk_c_out_re, data_c_out_re, data_c_out_float_re); + store_output_matrix(i, chunk_c_out_im, data_c_out_im, data_c_out_float_im); + } + + printf("Saving results to output file (%s, %s, %s, %s, %s, %s)...\n", output_a_data_file_re, output_a_data_file_im, + output_b_data_file_re, output_b_data_file_im, output_c_data_file_re, output_c_data_file_im); + save_to_file(output_a_data_file_re, data_a_out_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_a_data_file_im, data_a_out_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_b_data_file_re, data_b_out_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_b_data_file_im, data_b_out_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_c_data_file_re, data_c_out_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_c_data_file_im, data_c_out_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + int filename_len; + const char* float_end = "_float.txt"; + + filename_len = strlen(output_a_data_file_re); + char* output_a_data_file_float_re = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_a_data_file_float_re, output_a_data_file_re); + output_a_data_file_float_re[filename_len - 4] = '\0'; + strcat(output_a_data_file_float_re, float_end); + + filename_len = strlen(output_a_data_file_im); + char* output_a_data_file_float_im = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_a_data_file_float_im, output_a_data_file_im); + output_a_data_file_float_im[filename_len - 4] = '\0'; + strcat(output_a_data_file_float_im, float_end); + + filename_len = strlen(output_b_data_file_re); + char* output_b_data_file_float_re = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_b_data_file_float_re, output_b_data_file_re); + output_b_data_file_float_re[filename_len - 4] = '\0'; + strcat(output_b_data_file_float_re, float_end); + + filename_len = strlen(output_b_data_file_im); + char* output_b_data_file_float_im = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_b_data_file_float_im, output_b_data_file_im); + output_b_data_file_float_im[filename_len - 4] = '\0'; + strcat(output_b_data_file_float_im, float_end); + + filename_len = strlen(output_c_data_file_re); + char* output_c_data_file_float_re = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_c_data_file_float_re, output_c_data_file_re); + output_c_data_file_float_re[filename_len - 4] = '\0'; + strcat(output_c_data_file_float_re, float_end); + + filename_len = strlen(output_c_data_file_im); + char* output_c_data_file_float_im = (char*)malloc((filename_len + 7) * sizeof(char)); + strcpy(output_c_data_file_float_im, output_c_data_file_im); + output_c_data_file_float_im[filename_len - 4] = '\0'; + strcat(output_c_data_file_float_im, float_end); + + printf("Saving results to output file (%s, %s, %s, %s, %s, %s) ...\n", output_a_data_file_float_re, + output_a_data_file_float_im, output_b_data_file_float_re, output_b_data_file_float_im, + output_c_data_file_float_re, output_c_data_file_float_im); + save_to_file(output_a_data_file_float_re, data_a_out_float_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_a_data_file_float_im, data_a_out_float_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_b_data_file_float_re, data_b_out_float_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_b_data_file_float_im, data_b_out_float_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_c_data_file_float_re, data_c_out_float_re, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + save_to_file(output_c_data_file_float_im, data_c_out_float_im, X_DIM * Y_DIM * NUM_CHUNKS * _TDM_CHUNKS); + + /* + ****************************************************************************** + * Compare C code results to expected Matlab reference script results + ****************************************************************************** + */ + printf("Comparing results (%s - %s, %s - %s, %s - %s, %s - %s, %s - %s, %s - %s)...\n", output_a_data_file_re, + expected_a_data_file_re, output_a_data_file_im, expected_a_data_file_im, output_b_data_file_re, + expected_b_data_file_re, output_a_data_file_im, expected_b_data_file_im, output_c_data_file_re, + expected_c_data_file_re, output_c_data_file_im, expected_c_data_file_im); + int cmp_res_i; + T2out dummy; + cmp_res_i = compare_files(dummy, expected_a_data_file_re, output_a_data_file_re, 1, output_data_size, base, err); + cmp_res_i = cmp_res_i & + compare_files(dummy, expected_a_data_file_im, output_a_data_file_im, 1, output_data_size, base, err); + cmp_res_i = cmp_res_i & + compare_files(dummy, expected_b_data_file_re, output_b_data_file_re, 1, output_data_size, base, err); + cmp_res_i = cmp_res_i & + compare_files(dummy, expected_b_data_file_im, output_b_data_file_im, 1, output_data_size, base, err); + cmp_res_i = cmp_res_i & + compare_files(dummy, expected_c_data_file_re, output_c_data_file_re, 1, output_data_size, base, err); + cmp_res_i = cmp_res_i & + compare_files(dummy, expected_c_data_file_im, output_c_data_file_im, 1, output_data_size, base, err); + + if (cmp_res_i != 0) { + printf("Data verification completed successfully.\n"); + } else { + printf("Data verification completed with errors.\n"); + } + + free(data_a_out_re); + free(data_a_out_im); + free(data_a_out_float_re); + free(data_a_out_float_im); + free(data_b_out_re); + free(data_b_out_im); + free(data_b_out_float_re); + free(data_b_out_float_im); + free(data_c_out_re); + free(data_c_out_im); + free(data_c_out_float_re); + free(data_c_out_float_im); + free(data_in_re); + free(data_in_im); + + return 0; +} + +// /* +// * (complex B, complex C, complex D) = f(complex A) +// * +// * T2: default data type (float, ap_fixed) +// * T1: storage data type of input file (float -> float, ap_fixed -> int) +// */ +// template +// int test_func_1_3_c( +// int argc, char* argv[], float base, float err, +// void (*func)(x_complex[X_DIM][Y_DIM][_TDM_CHUNKS], +// x_complex[X_DIM][Y_DIM][_TDM_CHUNKS], +// x_complex[X_DIM][Y_DIM][_TDM_CHUNKS], +// x_complex[X_DIM][Y_DIM][_TDM_CHUNKS])) +// { +// // File names +// char *input_data_file_re = argv[1];//"ch_matrices_re.txt"; +// char *input_data_file_im = argv[2];//"ch_matrices_im.txt"; +// char *output_a_data_file_re = argv[3];//"results_a_re.txt"; +// char *output_a_data_file_im = argv[4];//"results_a_im.txt"; +// char *output_b_data_file_re = argv[5];//"results_b_re.txt"; +// char *output_b_data_file_im = argv[6];//"results_b_im.txt"; +// char *output_c_data_file_re = argv[7];//"results_c_re.txt"; +// char *output_c_data_file_im = argv[8];//"results_c_im.txt"; +// char *expected_a_data_file_re = argv[9];//"simulation_a_data_re.txt"; +// char *expected_a_data_file_im = argv[10];//"simulation_a_data_im.txt"; +// char *expected_b_data_file_re = argv[11];//"simulation_b_data_re.txt"; +// char *expected_b_data_file_im = argv[12];//"simulation_b_data_im.txt"; +// char *expected_c_data_file_re = argv[13];//"simulation_c_data_re.txt"; +// char *expected_c_data_file_im = argv[14];//"simulation_c_data_im.txt"; + +// // Matrix dimension +// short matrix_dimension[2] = {X_DIM,Y_DIM}; +// int m = 2*matrix_dimension[0]; +// int n = 2*matrix_dimension[1]; + +// // Data size +// int input_data_size = X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS; +// int output_data_size = X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS; + +// // File data pointers +// T1 *data_in_re, *data_in_im; +// T1 *data_a_out_re, *data_a_out_im; +// T1 *data_b_out_re, *data_b_out_im; +// T1 *data_c_out_re, *data_c_out_im; + +// float *data_a_out_float_re, *data_a_out_float_im; +// float *data_b_out_float_re, *data_b_out_float_im; +// float *data_c_out_float_re, *data_c_out_float_im; + +// data_in_re = (T1*)malloc(input_data_size * sizeof(T1)); +// data_in_im = (T1*)malloc(input_data_size * sizeof(T1)); +// data_a_out_re = (T1*)malloc(output_data_size * sizeof(T1)); +// data_a_out_im = (T1*)malloc(output_data_size * sizeof(T1)); +// data_b_out_re = (T1*)malloc(output_data_size * sizeof(T1)); +// data_b_out_im = (T1*)malloc(output_data_size * sizeof(T1)); +// data_c_out_re = (T1*)malloc(output_data_size * sizeof(T1)); +// data_c_out_im = (T1*)malloc(output_data_size * sizeof(T1)); +// data_a_out_float_re = (float*)malloc(output_data_size * sizeof(float)); +// data_a_out_float_im = (float*)malloc(output_data_size * sizeof(float)); +// data_b_out_float_re = (float*)malloc(output_data_size * sizeof(float)); +// data_b_out_float_im = (float*)malloc(output_data_size * sizeof(float)); +// data_c_out_float_re = (float*)malloc(output_data_size * sizeof(float)); +// data_c_out_float_im = (float*)malloc(output_data_size * sizeof(float)); + +// // Function arguments - data matrices +// T2in chunk_in_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2in chunk_in_im[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_a_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_a_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_b_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_b_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_c_out_re[X_DIM][Y_DIM][_TDM_CHUNKS]; +// T2out chunk_c_out_im[X_DIM][Y_DIM][_TDM_CHUNKS]; + +// printf("Test beginning...\n"); +// /* +// ****************************************************************************** +// * Load data, perfrom function, and store result +// ****************************************************************************** +// */ +// printf("Loading values from txt files (%s, %s)...\n",input_data_file_re, input_data_file_im); +// load_from_file(input_data_file_re, data_in_re, input_data_size); +// load_from_file(input_data_file_im, data_in_im, input_data_size); + +// for(int i = 0; i < NUM_CHUNKS; i++) +// { +// printf("Loading input data array ...\n"); +// load_input_matrix(i, data_in_re,chunk_in_re); +// load_input_matrix(i, data_in_im,chunk_in_im); + +// x_complex in_a[X_DIM][Y_DIM][_TDM_CHUNKS]; +// x_complex out_s[X_DIM][Y_DIM][_TDM_CHUNKS]; +// x_complex out_u[X_DIM][Y_DIM][_TDM_CHUNKS]; +// x_complex out_v[X_DIM][Y_DIM][_TDM_CHUNKS]; +// for(int ii=0; ii(i, chunk_a_out_re, data_a_out_re, data_a_out_float_re); +// store_output_matrix(i, chunk_a_out_im, data_a_out_im, data_a_out_float_im); +// store_output_matrix(i, chunk_b_out_re, data_b_out_re, data_b_out_float_re); +// store_output_matrix(i, chunk_b_out_im, data_b_out_im, data_b_out_float_im); +// store_output_matrix(i, chunk_c_out_re, data_c_out_re, data_c_out_float_re); +// store_output_matrix(i, chunk_c_out_im, data_c_out_im, data_c_out_float_im); +// } + +// printf("Saving results to output file (%s, %s, %s, %s, %s, %s)...\n", +// output_a_data_file_re, output_a_data_file_im, +// output_b_data_file_re, output_b_data_file_im, +// output_c_data_file_re, output_c_data_file_im); +// save_to_file(output_a_data_file_re, data_a_out_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_a_data_file_im, data_a_out_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_b_data_file_re, data_b_out_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_b_data_file_im, data_b_out_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_c_data_file_re, data_c_out_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_c_data_file_im, data_c_out_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); + +// int filename_len; +// const char *float_end = "_float.txt"; + +// filename_len = strlen(output_a_data_file_re); +// char *output_a_data_file_float_re = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_a_data_file_float_re, output_a_data_file_re); +// output_a_data_file_float_re[filename_len-4] = '\0'; +// strcat(output_a_data_file_float_re, float_end); + +// filename_len = strlen(output_a_data_file_im); +// char *output_a_data_file_float_im = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_a_data_file_float_im, output_a_data_file_im); +// output_a_data_file_float_im[filename_len-4] = '\0'; +// strcat(output_a_data_file_float_im, float_end); + +// filename_len = strlen(output_b_data_file_re); +// char *output_b_data_file_float_re = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_b_data_file_float_re, output_b_data_file_re); +// output_b_data_file_float_re[filename_len-4] = '\0'; +// strcat(output_b_data_file_float_re, float_end); + +// filename_len = strlen(output_b_data_file_im); +// char *output_b_data_file_float_im = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_b_data_file_float_im, output_b_data_file_im); +// output_b_data_file_float_im[filename_len-4] = '\0'; +// strcat(output_b_data_file_float_im, float_end); + +// filename_len = strlen(output_c_data_file_re); +// char *output_c_data_file_float_re = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_c_data_file_float_re, output_c_data_file_re); +// output_c_data_file_float_re[filename_len-4] = '\0'; +// strcat(output_c_data_file_float_re, float_end); + +// filename_len = strlen(output_c_data_file_im); +// char *output_c_data_file_float_im = (char*)malloc((filename_len+7)*sizeof(char)); +// strcpy(output_c_data_file_float_im, output_c_data_file_im); +// output_c_data_file_float_im[filename_len-4] = '\0'; +// strcat(output_c_data_file_float_im, float_end); + +// printf("Saving results to output file (%s, %s, %s, %s, %s, %s) ...\n", +// output_a_data_file_float_re, output_a_data_file_float_im, +// output_b_data_file_float_re, output_b_data_file_float_im, +// output_c_data_file_float_re, output_c_data_file_float_im); +// save_to_file(output_a_data_file_float_re, data_a_out_float_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_a_data_file_float_im, data_a_out_float_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_b_data_file_float_re, data_b_out_float_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_b_data_file_float_im, data_b_out_float_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_c_data_file_float_re, data_c_out_float_re, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); +// save_to_file(output_c_data_file_float_im, data_c_out_float_im, X_DIM*Y_DIM*NUM_CHUNKS*_TDM_CHUNKS); + +// /* +// ****************************************************************************** +// * Compare C code results to expected Matlab reference script results +// ****************************************************************************** +// */ +// printf("Comparing results (%s - %s, %s - %s, %s - %s, %s - %s, %s - %s, %s - %s)...\n", +// output_a_data_file_re,expected_a_data_file_re, +// output_a_data_file_im,expected_a_data_file_im, +// output_b_data_file_re,expected_b_data_file_re, +// output_a_data_file_im,expected_b_data_file_im, +// output_c_data_file_re,expected_c_data_file_re, +// output_c_data_file_im,expected_c_data_file_im); +// int cmp_res_i; +// T2out dummy; +// cmp_res_i = compare_files(dummy, expected_a_data_file_re, output_a_data_file_re, 1, output_data_size, base, +// err); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_a_data_file_im, output_a_data_file_im, 1, +// output_data_size, base, err); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_b_data_file_re, output_b_data_file_re, 1, +// output_data_size, base, err); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_b_data_file_im, output_b_data_file_im, 1, +// output_data_size, base, err); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_c_data_file_re, output_c_data_file_re, 1, +// output_data_size, base, err); +// cmp_res_i = cmp_res_i & compare_files(dummy, expected_c_data_file_im, output_c_data_file_im, 1, +// output_data_size, base, err); + +// if (cmp_res_i != 0) { +// printf("Data verification completed successfully.\n"); +// } else { +// printf("Data verification completed with errors.\n"); +// } + +// free(data_a_out_re); +// free(data_a_out_im); +// free(data_a_out_float_re); +// free(data_a_out_float_im); +// free(data_b_out_re); +// free(data_b_out_im); +// free(data_b_out_float_re); +// free(data_b_out_float_im); +// free(data_c_out_re); +// free(data_c_out_im); +// free(data_c_out_float_re); +// free(data_c_out_float_im); +// free(data_in_re); +// free(data_in_im); + +// return 0; +// } + +// d1(base) = d1Int x 2^d1Exp +// d2(target) = d2Int x 2^d2Exp +// h = 2^hExp ( = d1Exp-1) +// int +// calcULP( +// float d1, // base +// float d2) // target +// { +// int d1Exp, d2Exp, hExp; //normalized exponents +// // int +// hExp = d1Exp - 1; + +// int d1_exp = 0; +// int d2_exp = 0; +// int hS_exp = 0; + +// if(d1Exp >= 0) { +// d1_exp += d1Exp; +// } else { +// d2_exp -= d1Exp; +// hS_exp -= d1Exp; +// } + +// if(d2Exp >= 0) { +// d2_exp += d2Exp; +// } else { +// d1_exp -= d2Exp; +// hS_exp -= d2Exp; +// } + +// // Adjust for half ulp exponent +// if(hExp >= 0) { +// hS_exp += hExp; +// } else { +// d1_exp -= hExp; +// d2_exp -= hExp; +// } + +// // Remove common power of two factor from all three scaled values +// int common_exp2 = min(d1_exp, min(d2_exp, hS_exp)); +// d1_exp -= common_exp2; +// d2_exp -= common_exp2; +// hS_exp -= common_exp2; + +// Recreate d1,d2 and subtract d1, d2 and compare? +//} + +template +uint64_t calcULP(ap_int A, ap_int B) { + ap_int diff = A - B; + if (diff < 0) diff = -diff; + if (diff > 0x7FFFFFFFFFFFFFFFULL) diff = 0x7FFFFFFFFFFFFFFFULL; + ap_uint<64> intDiff = diff; + return intDiff; +} + +template +uint64_t calcULP(ap_uint A, ap_uint B) { + ap_uint diff = A - B; + if (diff < 0) diff = -diff; + if (diff > 0x7FFFFFFFFFFFFFFFULL) diff = 0x7FFFFFFFFFFFFFFFULL; + ap_uint<64> intDiff = diff; + return intDiff; +} + +template +uint64_t calcULP(ap_fixed A, ap_fixed B) { + ap_int A_bits, B_bits; + A_bits(W - 1, 0) = A(W - 1, 0); + B_bits(W - 1, 0) = B(W - 1, 0); + + ap_int diff = A_bits - B_bits; + if (diff < 0) diff = -diff; + if (diff > 0x7FFFFFFFFFFFFFFFULL) diff = 0x7FFFFFFFFFFFFFFFULL; + ap_uint<64> intDiff = diff; + return intDiff; +} + +template +uint64_t calcULP(ap_ufixed A, ap_ufixed B) { + ap_int A_bits = 0, B_bits = 0; + A_bits(W - 1, 0) = A(W - 1, 0); + B_bits(W - 1, 0) = B(W - 1, 0); + + ap_int diff = A_bits - B_bits; + if (diff < 0) diff = -diff; + if (diff > 0x7FFFFFFFFFFFFFFFULL) diff = 0x7FFFFFFFFFFFFFFFULL; + ap_uint<64> intDiff = diff; + return intDiff; +} + +#ifdef X_AP_FLOAT_H +template +uint64_t calcULP(ap_float a, ap_float b) { + if (a.is_nan() && b.is_nan()) return 0; + if (a.is_infinity() && b.is_infinity()) return 0; + + bool a_big = a.exp > b.exp; + ap_uint shift = a_big ? (a.exp - b.exp) : (b.exp - a.exp); + ap_fixed temp1 = a.mant, temp2 = b.mant; + if (!a_big) { + temp1 = b.mant; + temp2 = a.mant; + } + temp2 = temp2 >> shift; + return calcULP(temp1, temp2); +} +#endif + +template +uint64_t calcULP(T1 A, T2 B) { + return std::fabs(double(A - B)); +} + +// static +// uint64_t calcULP(char A, char B) { +// return abs(A-B); +//} + +#ifndef AESL_SYN +static uint64_t calcULP(half A, half B) { + if (detail::isnan(A) && detail::isnan(B)) return 0; + unsigned short A_bits = A.get_bits(); + unsigned short B_bits = B.get_bits(); + int aInt = (detail::signbit(A) ? (0x8000 - A_bits) : A_bits); + int bInt = (detail::signbit(B) ? (0x8000 - B_bits) : B_bits); + return abs(aInt - bInt); +} +#endif + +static uint64_t calcULP(float A, float B) { + class fp_struct d1s(A), d2s(B); + + dumpSingle(A, d1s); + dumpSingle(B, d2s); + + if (std::isnan(A) && std::isnan(B)) return 0; + int32_t aInt = d1s.data(); + // Make aInt lexicographically ordered as a twos-complement int + if (std::signbit(A)) aInt = 0x80000000 - aInt; + // Make bInt lexicographically ordered as a twos-complement int + int32_t bInt = d2s.data(); + if (std::signbit(B)) bInt = 0x80000000 - bInt; + int32_t intDiff = abs(aInt - bInt); + return intDiff; +} + +static uint64_t calcULP(double A, // base + double B) // target +{ + class fp_struct d1s(A); + class fp_struct d2s(B); + + dumpDouble(A, d1s); + dumpDouble(B, d2s); + + if (std::isnan(A) && std::isnan(B)) return 0; + // Make sure maxUlps is non-negative and small enough that the + // default NAN won't compare as equal to anything. + // assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); + int64_t aInt = d1s.data(); + // Make aInt lexicographically ordered as a twos-complement int + if (A < 0.0) aInt = 0x8000000000000000LL - aInt; + // Make bInt lexicographically ordered as a twos-complement int + int64_t bInt = d2s.data(); + if (B < 0.0) bInt = 0x8000000000000000LL - bInt; + int64_t intDiff = aInt - bInt; + if (intDiff < 0) intDiff = -intDiff; + // if (intDiff <= maxUlps) + // return true; + // return false; + return intDiff; +} + +hls::x_complex calcULP(hls::x_complex A, // base + hls::x_complex B) { // target + + hls::x_complex ret; + ret.real(calcULP(A.real(), B.real())); + ret.imag(calcULP(A.imag(), B.imag())); + return ret; +} + +hls::x_complex calcULP(hls::x_complex A, // base + hls::x_complex B) { // target + + hls::x_complex ret; + ret.real(calcULP(A.real(), B.real())); + ret.imag(calcULP(A.imag(), B.imag())); + return ret; +} + +template +hls::x_complex calcULP(hls::x_complex > A, // base + hls::x_complex > B) { // target + + hls::x_complex ret; + ret.real(calcULP(A.real(), B.real())); + ret.imag(calcULP(A.imag(), B.imag())); + return ret; +}; +//////////////////////////////////////////////////////////////////////////// +std::complex calcULP(std::complex A, // base + std::complex B) { // target + + std::complex ret; + ret.real(calcULP(A.real(), B.real())); + ret.imag(calcULP(A.imag(), B.imag())); + return ret; +} + +std::complex calcULP(std::complex A, // base + std::complex B) { // target + + std::complex ret; + ret.real(calcULP(A.real(), B.real())); + ret.imag(calcULP(A.imag(), B.imag())); + return ret; +} + +template +std::complex calcULP(std::complex > A, // base + std::complex > B) { // target + + std::complex ret; + ret.real(calcULP(A.real(), B.real())); + ret.imag(calcULP(A.imag(), B.imag())); + return ret; +}; +//////////////////////////////////////////////////////////////////////////// +// --------------------------------------------------------------------------------------------- +// Compare this ULP error to the max so far, and update the max if this is greater. +// --------------------------------------------------------------------------------------------- +// These funcitons are needed to handle the fact that complex numbers need each field tested +// individually, so "value > *max_ulp_error" won't work +// +void update_max_ulp_error(unsigned value, double* max_ulp_error) { + if (value > *max_ulp_error) { + *max_ulp_error = (double)value; + } +} + +void update_max_ulp_error(hls::x_complex value, double* max_ulp_error) { + update_max_ulp_error(value.real(), max_ulp_error); + update_max_ulp_error(value.imag(), max_ulp_error); +} +void update_max_ulp_error(std::complex value, double* max_ulp_error) { + update_max_ulp_error(value.real(), max_ulp_error); + update_max_ulp_error(value.imag(), max_ulp_error); +} + +// Usable AlmostEqual function +static bool AlmostEqual2sComplement(float A, float B, int maxUlps) { +// Make sure maxUlps is non-negative and small enough that the +// default NAN won't compare as equal to anything. +#ifndef __SYNTHESIS__ + assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); +#endif + class fp_struct d1s(A); + class fp_struct d2s(B); + + int aInt = d1s.data(); + // Make aInt lexicographically ordered as a twos-complement int + if (aInt < 0) aInt = 0x80000000 - aInt; + // Make bInt lexicographically ordered as a twos-complement int + int bInt = d2s.data(); + if (bInt < 0) bInt = 0x80000000 - bInt; + int intDiff = abs(aInt - bInt); + if (intDiff <= maxUlps) return true; + return false; +} + +static int rand8() { + assert(RAND_MAX > 0xFF); + return rand() & 0xFF; +} + +static int rand32() { + return (rand8() << 24) | (rand8() << 16) | (rand8() << 8) | (rand8()); +} + +#define RS_SCALE (1.0 / (1.0 + RAND_MAX)) +static double drand() { + double d; + do { + d = (((rand() * RS_SCALE) + rand()) * RS_SCALE + rand()) * RS_SCALE; + } while (d >= 1); /* Round off */ + return d; +} + +static const uint64_t double_corner_cases[] = { + 0x0000000000000000LL, // +zero + 0x0000000000000001LL, // positive denormalized real + 0x7FF0000000000000LL, // +infinity + 0x7FF0000000000001LL, // SNaN + 0x7FFFFFFFFFFFFFFFLL, // QNaN + 0x8000000000000000LL, // -zero + 0x8000000000000001LL, // Negative denormalized real + 0xFFF0000000000000LL, // -infinity + 0xFFF0000000000001LL, // -SNaN + 0xFFFFFFFFFFFFFFFFLL, // -QNaN + 0x7FEFFFFFFFFFFFFFLL, // positive max + 0xFFEFFFFFFFFFFFFFLL, // negative max + 0x3FE0000000000000LL, // normal positive, 1.0x2^-1 + 0xBFE0000000000000LL, // normal negative, -1.0x2^-1 +}; + +static const uint32_t float_corner_cases[] = { + 0x00000000, // +zero + 0x00000001, // positive denormalized real + 0x007FFFFF, // largest positive denormalized real + 0x00800000, // smallest positive normalized real + 0x7F800000, // +infinity + 0x7F800001, // SNaN + 0x7FFFFFFF, // QNaN + 0x80000000, // -zero + 0x80000001, // Negative denormalized real + 0x807FFFFF, // largest positive denormalized real + 0x80800000, // smallest positive normalized real + 0xFF800000, // -infinity + 0xFF800001, // -SNaN + 0xFFFFFFFF, // -QNaN + 0x7F7FFFFF, // positive max + 0xFF7FFFFF, // negative max + 0x3F000000, // normal positive, 1.0x2^-1 + 0xBF000000, // normal negative, -1.0x2^-1 +}; + +static const uint16_t half_corner_cases[] = { + 0x0000, // +zero + 0x0001, // positive denormalized real + 0x7C00, // +infinity + 0x7C01, // SNaN + 0x7FFF, // QNaN + 0x8000, // -zero + 0x8001, // Negative denormalized real + 0xFC00, // -infinity + 0xFC01, // -SNaN + 0xFFFF, // -QNaN + 0x7BFF, // positive max + 0xFBFF, // negative max + 0x3800, // normal positive, 1.0x2^-1 + 0xB800, // normal negative, -1.0x2^-1 +}; + +static int NUM_CORNER_CASES = sizeof(float_corner_cases) / sizeof(float_corner_cases[0]); + +static const uint32_t float_corner_cases_fpclassify[] = { + FP_ZERO, // +zero + FP_SUBNORMAL, // positive denormalized real + FP_INFINITE, // +infinity + FP_NAN, // SNaN + FP_NAN, // QNaN + FP_ZERO, // -zero + FP_SUBNORMAL, // Negative denormalized real + FP_INFINITE, // -infinity + FP_NAN, // -SNaN + FP_NAN, // -QNaN + FP_NORMAL, // positive max + FP_NORMAL, // negative max + FP_NORMAL, // normal positive, 1.0x2^-1 + FP_NORMAL, // normal negative, -1.0x2^-1 +}; + +static const uint16_t half_corner_cases_2[] = { + 0x0000, 0x8000, // +zero, -zero + 0x8000, 0x0000, // -zero, +zero + 0x7C00, 0xFC00, // +inf, -inf + 0xFC00, 0x7C00, // +inf, -inf + 0x0400, 0x03FF, // norm1, subn1 + 0x03FF, 0x0400, // subn1, norm1 + 0x03FF, 0x03FE, // subn1, subn2 + 0x03FE, 0x03FF, // subn2, subn1 + 0xFC01, 0x7E00, // snan1, qnan0 + 0x7E00, 0xFC01, // qnan0, snan1 + 0xFC01, 0xFE01, // snan1, neg_snan1 + 0xFE01, 0xFC01, // neg_snan1, snan1 + 0xFC01, 0xFC02, // snan1, snan2 + 0xFC02, 0xFC01, // snan2, snan1 + 0xFC01, 0x7E03, // snan1, qnan3 + 0x7E03, 0xFC01, // qnan3, snan1 + 0xFE01, 0x7E00, // neg_snan1, neg_qnan0 + 0x7E00, 0xFE01, // neg_qnan0, neg_snan1 + 0xFC01, 0x3C00, // snan1, one + 0x3C00, 0xFC01, // one, snan1 + 0x7C00, 0x3C00, // inf, one + 0x3C00, 0x7C00, // one, inf + 0xFC01, 0x7C00, // snan1, inf + 0xFC00, 0xFC01, // inf, snan1 + 0xFC01, 0x0000, // snan1, +zero + 0x0000, 0xFC01, // +zero, snan1 + 0xFC01, 0xBC00, // snan1, neg_one + 0xBC00, 0xFC01, // neg_one, snan1 + 0xFC01, 0xFC00, // snan1, -inf + 0xFC00, 0xFC01, // -inf, snan1 + 0xFC01, 0x8000, // snan1, -zero + 0x8000, 0xFC01, // -zero, snan1 +}; + +static const uint32_t float_corner_cases_2[] = { + 0x00000000, 0x80000000, // +zero, -zero + 0x80000000, 0x00000000, // -zero, +zero + 0x7f800000, 0xff800000, // +inf, -inf + 0xff800000, 0x7f800000, // +inf, -inf + 0x00800000, 0x007fffff, // norm1, subn1 + 0x007fffff, 0x00800000, // subn1, norm1 + 0x007fffff, 0x007ffffe, // subn1, subn2 + 0x007ffffe, 0x007fffff, // subn2, subn1 + 0x7f800001, 0x7fc00000, // snan1, qnan0 + 0x7fc00000, 0x7f800001, // qnan0, snan1 + 0x7f800001, 0xff800001, // snan1, neg_snan1 + 0xff800001, 0x7f800001, // neg_snan1, snan1 + 0x7f800001, 0x7f800002, // snan1, snan2 + 0x7f800002, 0x7f800001, // snan2, snan1 + 0x7f800001, 0x7fc00003, // snan1, qnan3 + 0x7fc00003, 0x7f800001, // qnan3, snan1 + 0xff800001, 0xffc00000, // neg_snan1, neg_qnan0 + 0xffc00000, 0xff800001, // neg_qnan0, neg_snan1 + 0x7f800001, 0x3f800000, // snan1, one + 0x3f800000, 0x7f800001, // one, snan1 + 0x7f800000, 0x3f800000, // inf, one + 0x3f800000, 0x7f800000, // one, inf + 0x7f800001, 0x7f800000, // snan1, inf + 0x7f800000, 0x7f800001, // inf, snan1 + 0x7f800001, 0x00000000, // snan1, +zero + 0x00000000, 0x7f800001, // +zero, snan1 + 0x7f800001, 0xbf800000, // snan1, neg_one + 0xbf800000, 0x7f800001, // neg_one, snan1 + 0x7f800001, 0xff800000, // snan1, -inf + 0xff800000, 0x7f800001, // -inf, snan1 + 0x7f800001, 0x80000000, // snan1, -zero + 0x80000000, 0x7f800001, // -zero, snan1 +}; + +static const uint64_t double_corner_cases_2[] = { + 0x0000000000000000ULL, 0x8000000000000000ULL, // +zero00000000, -zero + 0x8000000000000000ULL, 0x0000000000000000ULL, // -zero00000000, +zero + 0x7ff0000000000000ULL, 0xfff0000000000000ULL, // +inf00000000, -inf + 0xfff0000000000000ULL, 0x7ff0000000000000ULL, // +inf00000000, -inf + 0x00f0000000000000ULL, 0x007fffffffffffffULL, // norm100000000, subn1 + 0x000fffffffffffffULL, 0x0008000000000000ULL, // subn100000000, norm1 + 0x000fffffffffffffULL, 0x000ffffffffffffeULL, // subn100000000, subn2 + 0x000ffffffffffffeULL, 0x000fffffffffffffULL, // subn200000000, subn1 + 0x7ff0000000000001ULL, 0x7ff8000000000000ULL, // snan100000000, qnan0 + 0x7ff8000000000000ULL, 0x7ff0000000000001ULL, // qnan000000000, snan1 + 0x7ff0000000000001ULL, 0xfff0000000000001ULL, // snan100000000, neg_snan1 + 0xfff0000000000001ULL, 0x7ff0000000000001ULL, // neg_snan100000000, snan1 + 0x7ff0000000000001ULL, 0x7ff0000000000002ULL, // snan100000000, snan2 + 0x7ff0000000000002ULL, 0x7ff0000000000001ULL, // snan200000000, snan1 + 0x7ff0000000000001ULL, 0x7ff8000000000003ULL, // snan100000000, qnan3 + 0x7ff8000000000003ULL, 0x7ff0000000000001ULL, // qnan300000000, snan1 + 0xfff0000000000001ULL, 0xfff8000000000000ULL, // neg_snan100000000, neg_qnan0 + 0xfff8000000000000ULL, 0xfff0000000000001ULL, // neg_qnan000000000, neg_snan1 + 0x7ff0000000000001ULL, 0x3ff0000000000000ULL, // snan100000000, one + 0x3ff0000000000000ULL, 0x7ff0000000000001ULL, // one00000000, snan1 + 0x7ff0000000000000ULL, 0x3ff0000000000000ULL, // inf, one + 0x3ff0000000000000ULL, 0x7ff0000000000000ULL, // one00000000, inf + 0x7ff0000000000001ULL, 0x7ff0000000000000ULL, // snan100000000, inf + 0x7ff0000000000000ULL, 0x7ff0000000000001ULL, // inf00000000, snan1 + 0x7ff0000000000001ULL, 0x0000000000000000ULL, // snan100000000, +zero + 0x0000000000000000ULL, 0x7ff0000000000001ULL, // +zero00000000, snan1 + 0x7ff0000000000001ULL, 0xbff0000000000000ULL, // snan100000000, neg_one + 0xbff0000000000000ULL, 0x7ff0000000000001ULL, // neg_one00000000, snan1 + 0x7ff0000000000001ULL, 0xfff0000000000000ULL, // snan100000000, -inf + 0xfff0000000000000ULL, 0x7ff0000000000001ULL, // -inf00000000, snan1 + 0x7ff0000000000001ULL, 0x8000000000000000ULL, // snan100000000, -zero + 0x8000000000000000ULL, 0x7ff0000000000001ULL, // -zero00000000, snan1 +}; + +static int NUM_CORNER_CASES_2 = sizeof(float_corner_cases_2) / sizeof(float_corner_cases_2[0]); + +#define irand(x) ((unsigned int)((x)*drand())) + +#include +template +class generator { + public: + std::vector values; + virtual int size() const { return values.size(); } + virtual const T operator[](int i) const { + assert(i >= 0); + assert((unsigned int)i < values.size()); + return values[i]; + } + virtual ~generator() {} +}; + +// A little syntactic sugar over a vector. +template +class array_generator : public generator { + public: + array_generator() {} + array_generator(const T* array, int N) { + std::cout << "array Generator\n"; + generator::values.resize(N); + for (int i = 0; i < N; i++) { + generator::values[i] = array[i]; + // std::cout << "value = " << generator::values[i] << "\n"; + } + } + array_generator(const uint32_t* array, int N) { + generator::values.resize(N); + for (int i = 0; i < N; i++) { + generator::values[i] = fp_struct(array[i]).to_ieee(); + } + } + array_generator(const uint64_t* array, int N) { + generator::values.resize(N); + for (int i = 0; i < N; i++) { + generator::values[i] = fp_struct(array[i]).to_ieee(); + } + } + array_generator(const uint16_t* array, int N) { + generator::values.resize(N); + for (int i = 0; i < N; i++) { + generator::values[i] = fp_struct(array[i]).to_ieee(); + } + } +}; + +template +class corner_cases_generator : public generator { + public: + corner_cases_generator() { std::cerr << "No corner cases for type..\n"; } +}; + +template +class corner_cases_generator, typename solver_tb::enable_if::type> : public generator > { + public: + typedef ap_uint T; + corner_cases_generator() { + // generator::values.resize(N); + T zero(0); + generator::values.push_back(zero); + T max(-1); // largest positive value + generator::values.push_back(max); + T max_less(-1); + max_less[0] = 0; + generator::values.push_back(max_less); + T one(1); + generator::values.push_back(one); + } +}; + +template +class corner_cases_generator, typename solver_tb::enable_if::type> : public generator > { + public: + typedef ap_int T; + corner_cases_generator() { + T zero(0); + generator::values.push_back(zero); + T max(-1); // Largest positive value + max[W - 1] = 0; + generator::values.push_back(max); + T min(0); // Largest magnitude negative value + min[W - 1] = 1; + generator::values.push_back(min); + T max_less(max); + max_less[0] = 0; + generator::values.push_back(max_less); + T one(1); + generator::values.push_back(one); + T minus_one(-1); + generator::values.push_back(minus_one); + } +}; + +template +class corner_cases_generator, typename solver_tb::enable_if::type> + : public generator > { + public: + typedef ap_ufixed T; + corner_cases_generator() { + // generator::values.resize(N); + T zero(0); + generator::values.push_back(zero); + T max(-1); + generator::values.push_back(max); + T max_less(-1); + max_less[0] = 0; + generator::values.push_back(max_less); + T one(1); + generator::values.push_back(one); + } +}; + +template +class corner_cases_generator, typename solver_tb::enable_if::type> + : public generator > { + public: + typedef ap_fixed T; + corner_cases_generator() { + // generator::values.resize(N); + T zero(0); + generator::values.push_back(zero); + T max(-1); + max[W - 1] = 0; + generator::values.push_back(max); + T min(0); + min[W - 1] = 1; + generator::values.push_back(min); + T max_less(max); + max_less[0] = 0; + generator::values.push_back(max_less); + T one(1); + generator::values.push_back(one); + T minus_one(-1); + generator::values.push_back(minus_one); + } +}; + +template <> +class corner_cases_generator::type> : public array_generator { + public: + corner_cases_generator() + : array_generator(half_corner_cases, sizeof(half_corner_cases) / sizeof(half_corner_cases[0])) {} +}; + +template <> +class corner_cases_generator::type> : public array_generator { + public: + corner_cases_generator() + : array_generator(float_corner_cases, sizeof(float_corner_cases) / sizeof(float_corner_cases[0])) {} +}; + +template <> +class corner_cases_generator::type> : public array_generator { + public: + corner_cases_generator() + : array_generator(double_corner_cases, sizeof(double_corner_cases) / sizeof(double_corner_cases[0])) {} +}; + +template +class rand_generator; + +template +class rand_generator::value>::type> : public generator { + public: + rand_generator(int N) { + std::cout << "rand Generator\n"; + generator::values.resize(N); + for (int i = 0; i < N; i++) { + long long r = rand32() + ((long long)rand32() << 32); // 64 bit random + generator::values[i] = fp_struct((typename fp_struct::data_type)r).to_ieee(); + // std::cout << "value = " << generator::values[i] << " " << std::hex << r << " " << + // generator::values[i] << std::dec << "\n"; + } + } +}; + +template <> +class rand_generator : public generator { + public: + rand_generator(int N) { + std::cout << "rand Generator\n"; + generator::values.resize(N); + for (int i = 0; i < N; i++) { + int r = (rand8() | (rand8() << 8)); + half h; + h.set_bits((unsigned short)r); + generator::values[i] = h; + // std::cout << "value = " << generator::values[i] << " " << std::hex << r << " " << + // generator::values[i] << std::dec << "\n"; + } + } +}; + +#ifdef X_AP_FLOAT_H +template +class rand_generator, void> : public generator > { + rand_generator > mant_generator; + rand_generator > exp_generator; + using generator >::values; + + public: + rand_generator(int N) : mant_generator(N), exp_generator(N) { + generator >::values.resize(N); + for (int i = 0; i < N; i++) { + ap_float x; + x.exp = exp_generator.values[i]; + x.mant = mant_generator.values[i]; + generator >::values[i] = x; + if (Normal) values[i] = values[i].normalize(); + } + } +}; +#endif + +template +class rand_generator, void> : public generator > { + public: + rand_generator(int N) { + generator >::values.resize(N); + for (int i = 0; i < N; i++) { + ap_uint x = 0; + for (int j = 0; j < (W + 31) / 32; j++) { + x = (x << 32) + rand32(); + } + generator >::values[i](W - 1, 0) = x(W - 1, 0); + if (O == AP_SAT_SYM) { + // It is possible to generate an unsaturated value. + // Below ensures that the result is always saturated. + generator >::values[i]++; + } + } + } +}; + +template +class rand_generator, void> : public generator > { + public: + rand_generator(int N) { + generator >::values.resize(N); + for (int i = 0; i < N; i++) { + ap_uint x = 0; + for (int j = 0; j < (W + 31) / 32; j++) { + x = (x << 32) + rand32(); + } + generator >::values[i](W - 1, 0) = x(W - 1, 0); + } + } +}; + +template +class rand_generator::value>::type> : public generator { + public: + rand_generator(int N) { + generator::values.resize(N); + for (int i = 0; i < N; i++) { + long long r = rand32() + ((long long)rand32() << 32); // 64 bit random + generator::values[i] = r; + } + } +}; + +// template +// class rand_generator::value >::type> : public generator { +// public: +// rand_generator(int N) { +// generator::values.resize(N); +// for(int i = 0; i < N; i++) { +// long long r = rand32() + ((long long)rand32() << 32); // 64 bit random +// generator::values[i] = fp_struct((typename fp_struct::data_type)r).to_ieee(); +// } +// } +// }; + +template +class rand_range_generator; + +template +class rand_range_generator::value>::type> : public generator { + public: + rand_range_generator(T minVal, T maxVal, int N) { + generator::values.resize(N); + for (int i = 0; i < N; i++) { + double range = maxVal - minVal; + generator::values[i] = drand() * range + minVal; + } + } +}; + +template <> +class rand_range_generator : public generator { + public: + rand_range_generator(half minVal, half maxVal, int N) { + generator::values.resize(N); + for (int i = 0; i < N; i++) { + double range = (double)(maxVal - minVal); + generator::values[i] = drand() * range + (double)minVal; + // std::cout << "value = " << generator::values[i] << " " << std::hex << " " << + // generator::values[i] << std::dec << "\n"; + } + } +}; + +template +class rand_range_generator, void> : public generator > { + public: + rand_range_generator(ap_fixed minVal, ap_fixed maxVal, int N) { + generator >::values.resize(N); + for (int i = 0; i < N; i++) { + ap_fixed range = maxVal - minVal; + generator >::values[i] = + ap_fixed(ap_fixed<64, 32, AP_RND, AP_SAT>(drand()) * range + minVal); + } + } +}; + +template +class rand_range_generator, void> : public generator > { + public: + rand_range_generator(ap_ufixed minVal, ap_ufixed maxVal, int N) { + generator >::values.resize(N); + for (int i = 0; i < N; i++) { + ap_ufixed range = maxVal - minVal; + generator >::values[i] = + ap_ufixed(ap_ufixed<64, 32, AP_RND, AP_SAT>(drand()) * range + minVal); + } + } +}; + +template +class rand_range_generator::value>::type> : public generator { + public: + rand_range_generator(T minVal, T maxVal, int N) { + generator::values.resize(N); + for (int i = 0; i < N; i++) { + double range = maxVal - minVal; + generator::values[i] = drand() * range + (double)minVal; + } + } +}; + +template +class rand_subnormal_generator : public generator { + public: + rand_subnormal_generator(int N) { + generator::values.resize(N); + for (int i = 0; i < N; i++) { + long long r = rand32() + ((long long)rand32() << 32); + fp_struct x((typename fp_struct::data_type)r); + x.exp = 0; + generator::values[i] = x.to_ieee(); + } + } +}; + +template +class range_generator; + +template +class range_generator::value>::type> : public generator { + public: + range_generator(T minVal, T maxVal, int N) { + generator::values.resize(N); + bool minNeg = minVal < 0.0; + bool maxNeg = maxVal < 0.0; + fp_struct minVals = minVal; + fp_struct maxVals = maxVal; + fp_struct negZero = (T)-0.0; + long long start = minNeg ? (negZero.to_int() - minVals.to_int()) : minVals.to_int(); + long long end = maxNeg ? (negZero.to_int() - maxVals.to_int()) : maxVals.to_int(); + + std::cout << "range Generator\n"; + std::cout << start << " to " << end << "\n"; + long long incr = (end - start) / N; + if (incr < 0) incr = -incr; + std::cout << N << " steps of " << incr << "\n"; + assert(incr > 1); + // incr = incr/N; + // std::cout << "incr = " << incr << "\n"; + long long news = start; + for (int i = 0; i < N; i++) { + // std::cout << "news = " << std::hex << news << std::dec << "\n"; + fp_struct s = typename fp_struct::data_type((news < 0) ? (negZero.to_int() - news) : news); + // std::cout << "v = " << s.to_ieee() << " " << s.data().to_string(2) << "\n"; + T t = s.to_ieee(); + generator::values[i] = t; + news += incr; + } + } +}; + +template +class range_generator, is_fixedtype >::value>::type> + : public generator { + public: + range_generator(T minVal, T maxVal, int N) { + generator::values.resize(N); + + std::cout << "range Generator\n"; + std::cout << minVal << " to " << maxVal << "\n"; + T incr = (maxVal - minVal) / N; + std::cout << N << " steps of " << incr << "\n"; + assert(incr > 0); + T news = minVal; + for (int i = 0; i < N; i++) { + generator::values[i] = news; + news += incr; + } + } +}; + +template <> +class range_generator : public generator { + public: + range_generator(half minVal, half maxVal, int N) { + generator::values.resize(N); + std::cout << "range Generator\n"; + std::cout << minVal << " to " << maxVal << "\n"; + half incr = (maxVal - minVal) / N; + std::cout << N << " steps of " << incr << "\n"; + assert(incr > 0); + half news = minVal; + for (int i = 0; i < N; i++) { + generator::values[i] = news; + news += incr; + } + } +}; + +template +class sweep_exp_rand_mantissa_generator : public generator { + public: + sweep_exp_rand_mantissa_generator() { + fp_struct tmp; + int N = tmp.EXP_BIAS + 1; + generator::values.resize(2 * N); + int sign = 1; + int exp = 0; + for (int i = 0; i < 2 * N; i++) { + fp_struct din; + din.exp = exp; + exp = (din.exp == (N - 1)) ? 0 : exp + 1; + din.sign = sign; + sign = (din.exp == (N - 1)) ? ~sign : sign; + din.sig = (rand32() + ((long long)rand32() << 32)); + generator::values[i] = din.to_ieee(); + } + } +}; + +#ifdef X_AP_FLOAT_H +template +class sweep_exp_rand_mantissa_generator > : public generator > { + rand_generator > mant_generator; + range_generator > exp_generator; + const static int N = 1 << (E_W - 1); + + public: + sweep_exp_rand_mantissa_generator() : mant_generator(N), exp_generator(0, -1, N) { + generator >::values.resize(N); + for (int i = 0; i < N; i++) { + ap_float x; + x.exp = exp_generator.values[i]; + x.mant = mant_generator.values[i]; + if (Normal) x.mant[W - 2] = !x.mant[W - 1]; + generator >::values[i] = x; + } + } +}; +#endif + +template +class dense_generator; + +template +class dense_generator::value>::type> : public generator { + public: + dense_generator(T centerVal, int N) { + generator::values.resize(N); + fp_struct s = centerVal; + fp_struct negZero = (T)-0.0; + int news = (centerVal < 0.0) ? (negZero.to_int() - s.to_int()) : s.to_int(); + for (int i = 0; i < N; i++) { + fp_struct s = typename fp_struct::data_type((news < 0) ? (negZero.to_int() - news) : news); + generator::values[i] = s.to_ieee(); + news = (i % 2 == 0) ? news + i : news - i; + } + } +}; + +template +class dense_generator, typename solver_tb::enable_if::type> + : public generator > { + public: + typedef ap_fixed T; + dense_generator(T centerVal, int N) { + generator::values.resize(N); + T news = centerVal; + for (int i = 0; i < N; i++) { + generator::values[i] = news; + T incr; + incr(W - 1, 0) = i; + news = (i % 2 == 0) ? news + incr : news - incr; + } + } +}; + +template +class dense_generator, typename solver_tb::enable_if::type> + : public generator > { + public: + typedef ap_ufixed T; + dense_generator(T centerVal, int N) { + generator::values.resize(N); + T news = centerVal; + for (int i = 0; i < N; i++) { + generator::values[i] = news; + T incr; + incr(W - 1, 0) = i; + news = (i % 2 == 0) ? ap_ufixed(news + incr) : ap_ufixed(news - incr); + } + } +}; + +template <> +class dense_generator : public generator { + public: + dense_generator(half centerVal, int N) { + generator::values.resize(N); + fp_struct s = centerVal; + fp_struct negZero = (half)-0.0; + int news = (centerVal < 0.0) ? (negZero.to_int() - s.to_int()) : s.to_int(); + for (int i = 0; i < N; i++) { + fp_struct s = typename fp_struct::data_type((news < 0) ? (negZero.to_int() - news) : news); + generator::values[i] = s.to_ieee(); + news = (i % 2 == 0) ? news + i : news - i; + } + } +}; + +// template +// class dense_generator::value >::type> : public generator { +// public: +// dense_generator(T centerVal, int N) { +// generator::values.resize(N); +// T news = centerVal; +// for(int i = 0; i < N; i++) { +// generator::values[i] = news; +// news = (i%2 == 0) ? news+i : news-i; +// } +// } +// }; + +template +class exhaustive_generator; + +template +class exhaustive_generator, typename solver_tb::enable_if::type> + : public generator > { + public: + typedef ap_fixed T; + exhaustive_generator() { + int N = 1 << W; + generator::values.resize(N); + for (int i = 0; i < N; i++) { + T val; + val(W - 1, 0) = i; + generator::values[i] = val; + } + } +}; + +template +class exhaustive_generator, typename solver_tb::enable_if::type> + : public generator > { + public: + typedef ap_ufixed T; + exhaustive_generator() { + int N = 1 << W; + generator::values.resize(N); + for (int i = 0; i < N; i++) { + T val; + val(W - 1, 0) = i; + generator::values[i] = val; + } + } +}; + +template <> +class exhaustive_generator : public generator { + public: + exhaustive_generator() { + const int N = 65536; + generator::values.resize(N); + for (int i = 0; i < N; i++) { + fp_struct s = typename fp_struct::data_type(i); + generator::values[i] = s.to_ieee(); + } + } +}; + +template <> +class exhaustive_generator : public generator { + public: + typename fp_struct::data_type min, max; + exhaustive_generator() { + min = fp_struct(std::numeric_limits::min()).data(); + max = fp_struct(std::numeric_limits::max()).data(); + } + exhaustive_generator(float _min, float _max) { + min = fp_struct(_min).data(); + max = fp_struct(_max).data(); + assert(max > min); + } + int size() const { return max - min + 1; } + const float operator[](int i) const { + assert(i >= 0); + assert(i < size()); + typename fp_struct::data_type x = min + i; + if ((i & 0xFFFFF) == 0) { + std::cout << std::hex << i << " " << x << " " << fp_struct(x).to_ieee() << "\n"; + } + fp_struct s = x; + return s.to_ieee(); + } +}; + +#endif diff --git a/solver/docs/Doxyfile_L1 b/solver/docs/Doxyfile_L1 new file mode 100644 index 0000000000..2781b4d3ad --- /dev/null +++ b/solver/docs/Doxyfile_L1 @@ -0,0 +1,2445 @@ +# +# Copyright 2019 Xilinx, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Doxyfile 1.8.14 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Vitis Solver Library" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./ + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. + +ALIASES = "rst=\verbatim embed:rst:leading-asterisk" \ + "endrst=\endverbatim" + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = NO + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ../L1/include/hw +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = NO + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /