diff --git a/accelerators/catapult_hls/common/inc/core/systems/esp_dma_controller.hpp b/accelerators/catapult_hls/common/inc/core/systems/esp_dma_controller.hpp index b2600ad6b7..0cba6bbcbd 100644 --- a/accelerators/catapult_hls/common/inc/core/systems/esp_dma_controller.hpp +++ b/accelerators/catapult_hls/common/inc/core/systems/esp_dma_controller.hpp @@ -6,123 +6,105 @@ #include -template < - int _DMA_WIDTH_, - int _MEM_SIZE_ - > -class esp_dma_controller : public sc_module -{ +template class esp_dma_controller : public sc_module { - public: + public: + // Input ports - // Input ports + // Clock signal + sc_in clk; - // Clock signal - sc_in clk; + // Reset signal + sc_in rst; - // Reset signal - sc_in rst; + // DMA read control (non blocking) + Connections::In dma_read_ctrl; - // DMA read control (non blocking) - Connections::In dma_read_ctrl; + // DMA write control (non blocking) + Connections::In dma_write_ctrl; - // DMA write control (non blocking) - Connections::In dma_write_ctrl; + // DMA write channel (blocking) + Connections::In> dma_write_chnl; - // DMA write channel (blocking) - Connections::In> dma_write_chnl; + // Accelerator done + sc_in acc_done; - // Accelerator done - sc_in acc_done; + // Output ports - // Output ports + // DMA read channel (blocking) + Connections::Out> dma_read_chnl; - // DMA read channel (blocking) - Connections::Out> dma_read_chnl; + // Accelerator reset + sc_out acc_rst; - // Accelerator reset - sc_out acc_rst; + // Constructor + SC_HAS_PROCESS(esp_dma_controller); + esp_dma_controller(sc_module_name name, ac_int *ptr) : + sc_module(name), clk("clk"), rst("rst"), dma_read_ctrl("dma_read_ctrl"), + dma_write_ctrl("dma_write_ctrl"), dma_write_chnl("dma_write_chnl"), + dma_read_chnl("dma_read_chnl"), acc_done("acc_done"), acc_rst("acc_rst"), + num_of_write_burst(0), num_of_read_burst(0), total_write_bytes(0), total_read_bytes(0), + mem(ptr) + { + SC_THREAD(read); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); - // Constructor - SC_HAS_PROCESS(esp_dma_controller); - esp_dma_controller(sc_module_name name, ac_int *ptr) - : sc_module(name) - , clk("clk") - , rst("rst") - , dma_read_ctrl("dma_read_ctrl") - , dma_write_ctrl("dma_write_ctrl") - , dma_write_chnl("dma_write_chnl") - , dma_read_chnl("dma_read_chnl") - , acc_done("acc_done") - , acc_rst("acc_rst") - , num_of_write_burst(0) - , num_of_read_burst(0) - , total_write_bytes(0) - , total_read_bytes(0) - , mem(ptr) - { - SC_THREAD(read); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); + SC_THREAD(write); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); - SC_THREAD(write); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); + SC_THREAD(res); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + } - SC_THREAD(res); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); + // Process - } + // Handle requests + void read(); + void write(); + void res(); - // Process + // Functions - // Handle requests - void read(); - void write(); - void res(); + // Handle read requests + inline void dma_read(uint32_t mem_base, uint32_t burst_size); - // Functions + // Handle write requests + inline void dma_write(uint32_t mem_base, uint32_t burst_size); - // Handle read requests - inline void dma_read(uint32_t mem_base, uint32_t burst_size); + // Report information - // Handle write requests - inline void dma_write(uint32_t mem_base, uint32_t burst_size); + // End time of the first read burst + sc_time load_input_end; - // Report information + // End time of the first write burst + sc_time store_output_end; - // End time of the first read burst - sc_time load_input_end; + // Begin time of the first read burst + sc_time load_input_begin; - // End time of the first write burst - sc_time store_output_end; + // Begin time of the first write burst + sc_time store_output_begin; - // Begin time of the first read burst - sc_time load_input_begin; + // Number of dma write bursts + unsigned num_of_write_burst; - // Begin time of the first write burst - sc_time store_output_begin; + // Number of dma read bursts + unsigned num_of_read_burst; - // Number of dma write bursts - unsigned num_of_write_burst; + // Number of written bytes + unsigned total_write_bytes; - // Number of dma read bursts - unsigned num_of_read_burst; - - // Number of written bytes - unsigned total_write_bytes; - - // Number of read bytes - unsigned total_read_bytes; - - // Memory pointer - ac_int<_DMA_WIDTH_> *mem; + // Number of read bytes + unsigned total_read_bytes; + // Memory pointer + ac_int<_DMA_WIDTH_> *mem; }; // Implementation #include "esp_dma_controller.i.hpp" #endif // __ESP_DMA_CONTROLLER_HPP__ - diff --git a/accelerators/catapult_hls/common/inc/esp_dma_info.hpp b/accelerators/catapult_hls/common/inc/esp_dma_info.hpp index 7b1e485ed7..87f3fe4bd7 100644 --- a/accelerators/catapult_hls/common/inc/esp_dma_info.hpp +++ b/accelerators/catapult_hls/common/inc/esp_dma_info.hpp @@ -25,7 +25,6 @@ struct dma_info_t { // Length ac_int<3, false> size; - }; #endif // __ESP_DMA_INFO_HPP__ diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/aes/aes.h b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/aes/aes.h index 170534672c..202c76c23e 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/aes/aes.h +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/aes/aes.h @@ -3,19 +3,13 @@ #include "defines.h" -int aes( - uint32 oper_mode, - uint32 encryption, - uint32 key_bytes, - uint32 iv_bytes, - uint32 input_bytes, - uint32 aad_bytes, - uint32 tag_bytes, - uint32 key[AES_MAX_KEY_WORDS], // input, max=8 - uint32 iv[AES_MAX_IV_WORDS], // input, max=4 (parameter for cbc, ctr, gcm only) - uint32 in[AES_MAX_IN_WORDS], // input, max=40(ecb,cbc),16(ctr).32(gcm) - uint32 out[AES_MAX_IN_WORDS], // output, max=40(ecb,cbc),16(ctr),32(gcm) - uint32 aad[AES_MAX_IN_WORDS], // input, max=32 (parameter for gcm only) - uint32 tag[AES_MAX_IN_WORDS]); // input/output, max=4 (parameter gcm only) +int aes(uint32 oper_mode, uint32 encryption, uint32 key_bytes, uint32 iv_bytes, uint32 input_bytes, + uint32 aad_bytes, uint32 tag_bytes, + uint32 key[AES_MAX_KEY_WORDS], // input, max=8 + uint32 iv[AES_MAX_IV_WORDS], // input, max=4 (parameter for cbc, ctr, gcm only) + uint32 in[AES_MAX_IN_WORDS], // input, max=40(ecb,cbc),16(ctr).32(gcm) + uint32 out[AES_MAX_IN_WORDS], // output, max=40(ecb,cbc),16(ctr),32(gcm) + uint32 aad[AES_MAX_IN_WORDS], // input, max=32 (parameter for gcm only) + uint32 tag[AES_MAX_IN_WORDS]); // input/output, max=4 (parameter gcm only) #endif /* __AES_H__ */ diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/aes/modes/cbc.h b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/aes/modes/cbc.h index e935344f14..43378e0188 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/aes/modes/cbc.h +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/aes/modes/cbc.h @@ -1,20 +1,15 @@ #ifndef __CBC_H__ #define __CBC_H__ +#include "../dec.h" #include "../defines.h" -#include "../exp.h" #include "../enc.h" -#include "../dec.h" +#include "../exp.h" /* Cipher Block Chaining (CBC) */ -int aes_cbc_cipher(uint32 encryption, - uint32 key_bytes, - uint32 input_bytes, - uint32 iv_bytes, - uint32 ekey[AES_EXP_KEY_SIZE], - uint32 iv[AES_MAX_IV_WORDS], - uint32 in[AES_MAX_IN_WORDS], - uint32 out[AES_MAX_IN_WORDS]); +int aes_cbc_cipher(uint32 encryption, uint32 key_bytes, uint32 input_bytes, uint32 iv_bytes, + uint32 ekey[AES_EXP_KEY_SIZE], uint32 iv[AES_MAX_IV_WORDS], + uint32 in[AES_MAX_IN_WORDS], uint32 out[AES_MAX_IN_WORDS]); #endif /* __CBC_H__ */ diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/conf_info.hpp b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/conf_info.hpp index eb2867b738..7bb252d2e3 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/conf_info.hpp +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/conf_info.hpp @@ -16,7 +16,7 @@ struct conf_info_t { uint32 aes_iv_bytes; uint32 aes_in_bytes; uint32 aes_key_bytes; - //uint32 aes_encryption; + // uint32 aes_encryption; uint32 aes_oper_mode; // sha2 uint32 sha2_out_bytes; diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/sha1/defines.h b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/sha1/defines.h index 2e4a7fe76e..73fe6c8331 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/sha1/defines.h +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/sha1/defines.h @@ -1,18 +1,18 @@ #ifndef __SHA1_DEFINES_H__ #define __SHA1_DEFINES_H__ +#include +#include #include #include #include -#include -#include -#define SHA1_HBLOCK_WORDS 5 -#define SHA1_CBLOCK_BYTES 64 -#define SHA1_CBLOCK_WORDS 16 +#define SHA1_HBLOCK_WORDS 5 +#define SHA1_CBLOCK_BYTES 64 +#define SHA1_CBLOCK_WORDS 16 #define SHA1_CBLOCK_BYTES_MASK ~63 #define SHA1_DIGEST_LENGTH 20 -#define SHA1_DIGEST_WORDS 5 +#define SHA1_DIGEST_WORDS 5 #endif /* __DEFINES_H__ */ diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/sha2/defines.h b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/sha2/defines.h index 386826a3b5..1f3c16ee0d 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/sha2/defines.h +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/inc/sha2/defines.h @@ -1,20 +1,20 @@ #ifndef __SHA2_DEFINES_H__ #define __SHA2_DEFINES_H__ +#include +#include #include #include #include -#include -#include -#define SHA256_HBLOCK_WORDS 8 -#define SHA256_CBLOCK_BYTES 64 -#define SHA256_CBLOCK_WORDS 16 +#define SHA256_HBLOCK_WORDS 8 +#define SHA256_CBLOCK_BYTES 64 +#define SHA256_CBLOCK_WORDS 16 #define SHA256_CBLOCK_BYTES_MASK ~63 -#define SHA512_HBLOCK_WORDS 8 -#define SHA512_CBLOCK_BYTES 128 -#define SHA512_CBLOCK_WORDS 32 +#define SHA512_HBLOCK_WORDS 8 +#define SHA512_CBLOCK_BYTES 128 +#define SHA512_CBLOCK_WORDS 32 #define SHA512_CBLOCK_BYTES_MASK ~127 #define SHA224_DIGEST_LENGTH 28 diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/aes/aes.cpp b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/aes/aes.cpp index bba2453894..cdb38447c6 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/aes/aes.cpp +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/aes/aes.cpp @@ -1,88 +1,75 @@ #include "aes.h" #if defined(SYN_AES_ECB) || defined(SYN_AES_CTR) -#include "ecb.h" -#include "modes/ecb.cpp" + #include "ecb.h" + #include "modes/ecb.cpp" #endif // defined(SYN_AES_ECB) || defined(SYN_AES_CTR) #ifdef SYN_AES_CBC -#include "cbc.h" -#include "modes/cbc.cpp" + #include "cbc.h" + #include "modes/cbc.cpp" #endif // SYN_AES_CBC #ifdef SYN_AES_GCM -#include "gcm.h" -#include "modes/gcm.cpp" + #include "gcm.h" + #include "modes/gcm.cpp" #endif // SYN_AES_GCM -#include "exp.h" #include "exp.cpp" // TODO: this is a workaround +#include "exp.h" -int aes( - uint32 oper_mode, - uint32 encryption, - uint32 key_bytes, - uint32 iv_bytes, - uint32 input_bytes, - uint32 aad_bytes, - uint32 tag_bytes, - uint32 key[AES_MAX_KEY_WORDS], - uint32 iv[AES_MAX_IV_WORDS], - uint32 in[AES_MAX_IN_WORDS], - uint32 out[AES_MAX_IN_WORDS], - uint32 aad[AES_MAX_IN_WORDS], - uint32 tag[AES_MAX_IN_WORDS]) +int aes(uint32 oper_mode, uint32 encryption, uint32 key_bytes, uint32 iv_bytes, uint32 input_bytes, + uint32 aad_bytes, uint32 tag_bytes, uint32 key[AES_MAX_KEY_WORDS], + uint32 iv[AES_MAX_IV_WORDS], uint32 in[AES_MAX_IN_WORDS], uint32 out[AES_MAX_IN_WORDS], + uint32 aad[AES_MAX_IN_WORDS], uint32 tag[AES_MAX_IN_WORDS]) { - #pragma HLS interface s_axilite port=oper_mode - #pragma HLS interface s_axilite port=encryption - #pragma HLS interface s_axilite port=key_bytes - #pragma HLS interface s_axilite port=iv_bytes - #pragma HLS interface s_axilite port=input_bytes - #pragma HLS interface s_axilite port=aad_bytes - #pragma HLS interface s_axilite port=tag_bytes - #pragma HLS interface s_axilite port=return - #pragma HLS interface m_axi depth=aes_max_addr_mem port=key offset=slave - #pragma HLS interface m_axi depth=aes_max_addr_mem port=iv offset=slave - #pragma HLS interface m_axi depth=aes_max_addr_mem port=in offset=slave - #pragma HLS interface m_axi depth=aes_max_addr_mem port=out offset=slave - #pragma HLS interface m_axi depth=aes_max_addr_mem port=aad offset=slave - #pragma HLS interface m_axi depth=aes_max_addr_mem port=tag offset=slave +#pragma HLS interface s_axilite port = oper_mode +#pragma HLS interface s_axilite port = encryption +#pragma HLS interface s_axilite port = key_bytes +#pragma HLS interface s_axilite port = iv_bytes +#pragma HLS interface s_axilite port = input_bytes +#pragma HLS interface s_axilite port = aad_bytes +#pragma HLS interface s_axilite port = tag_bytes +#pragma HLS interface s_axilite port = return +#pragma HLS interface m_axi depth = aes_max_addr_mem port = key offset = slave +#pragma HLS interface m_axi depth = aes_max_addr_mem port = iv offset = slave +#pragma HLS interface m_axi depth = aes_max_addr_mem port = in offset = slave +#pragma HLS interface m_axi depth = aes_max_addr_mem port = out offset = slave +#pragma HLS interface m_axi depth = aes_max_addr_mem port = aad offset = slave +#pragma HLS interface m_axi depth = aes_max_addr_mem port = tag offset = slave - int ret = 0; - uint32 ekey[AES_EXP_KEY_SIZE] = { 0x0000 }; - uint32 enc = (oper_mode == AES_CTR_OPERATION_MODE || - oper_mode == AES_GCM_OPERATION_MODE) ? - uint32(AES_ENCRYPTION_MODE) : encryption; + int ret = 0; + uint32 ekey[AES_EXP_KEY_SIZE] = {0x0000}; + uint32 enc = (oper_mode == AES_CTR_OPERATION_MODE || oper_mode == AES_GCM_OPERATION_MODE) ? + uint32(AES_ENCRYPTION_MODE) : + encryption; - #pragma HLS array_partition variable=ekey cyclic factor=8 +#pragma HLS array_partition variable = ekey cyclic factor = 8 aes_expand(enc, key_bytes, key, ekey); - switch (oper_mode) - { + switch (oper_mode) { #if defined(SYN_AES_ECB) || defined(SYN_AES_CTR) case AES_ECB_OPERATION_MODE: case AES_CTR_OPERATION_MODE: - ret |= aes_ecb_ctr_cipher(oper_mode, encryption, key_bytes, - iv_bytes, input_bytes, ekey, iv, in, out); + ret |= aes_ecb_ctr_cipher(oper_mode, encryption, key_bytes, iv_bytes, input_bytes, ekey, + iv, in, out); break; #endif // defined(SYN_AES_ECB) || defined(SYN_AES_CTR) #ifdef SYN_AES_CBC case AES_CBC_OPERATION_MODE: - ret |= aes_cbc_cipher(encryption, key_bytes, input_bytes, iv_bytes, - ekey, iv, in, out); + ret |= aes_cbc_cipher(encryption, key_bytes, input_bytes, iv_bytes, ekey, iv, in, out); break; #endif // SYN_AES_CBC #ifdef SYN_AES_GCM case AES_GCM_OPERATION_MODE: - ret |= aes_gcm_cipher(encryption, key_bytes, input_bytes, iv_bytes, - aad_bytes, tag_bytes, ekey, iv, in, out, aad, tag); - break; + ret |= aes_gcm_cipher(encryption, key_bytes, input_bytes, iv_bytes, aad_bytes, + tag_bytes, ekey, iv, in, out, aad, tag); + break; #endif // SYN_AES_GCM - default: - break; - } + default: break; + } return ret; } diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/aes/modes/cbc.cpp b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/aes/modes/cbc.cpp index 064fe58e88..188511340f 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/aes/modes/cbc.cpp +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/aes/modes/cbc.cpp @@ -5,56 +5,46 @@ /* Cipher Block Chaining (CBC) */ -int aes_cbc_cipher(uint32 encryption, - uint32 key_bytes, - uint32 input_bytes, - uint32 iv_bytes, - uint32 ekey[AES_EXP_KEY_SIZE], - uint32 iv[AES_MAX_IV_WORDS], - uint32 in[AES_MAX_IN_WORDS], - uint32 out[AES_MAX_IN_WORDS]) +int aes_cbc_cipher(uint32 encryption, uint32 key_bytes, uint32 input_bytes, uint32 iv_bytes, + uint32 ekey[AES_EXP_KEY_SIZE], uint32 iv[AES_MAX_IV_WORDS], + uint32 in[AES_MAX_IN_WORDS], uint32 out[AES_MAX_IN_WORDS]) { - #pragma HLS inline +#pragma HLS inline uint32 tmp_mem[AES_BLOCK_WORDS]; uint32 out_mem[AES_BLOCK_WORDS]; uint32 in_mem[AES_BLOCK_WORDS]; unsigned input_words = input_bytes >> 2; - #pragma HLS array_partition variable=in_mem complete - #pragma HLS array_partition variable=out_mem complete - #pragma HLS array_partition variable=tmp_mem complete +#pragma HLS array_partition variable = in_mem complete +#pragma HLS array_partition variable = out_mem complete +#pragma HLS array_partition variable = tmp_mem complete AES_CBC_CIPHER_L_1: - for (unsigned k = 0; k < iv_bytes >> 2; ++k) - { - #pragma HLS loop_tripcount min=4 max=4 - #pragma HLS pipeline II=1 + for (unsigned k = 0; k > 2; ++k) { +#pragma HLS loop_tripcount min = 4 max = 4 +#pragma HLS pipeline II = 1 tmp_mem[k] = iv[k]; } - if (encryption == AES_ENCRYPTION_MODE) - { + if (encryption == AES_ENCRYPTION_MODE) { AES_CBC_CIPHER_L_2: - for (unsigned i = 0; i < input_words; i += AES_BLOCK_WORDS) - { - /* Considering an input of 65536 bytes. */ - #pragma HLS loop_tripcount min=1 max=4096 - #pragma HLS pipeline II=18 + for (unsigned i = 0; i < input_words; i += AES_BLOCK_WORDS) { +/* Considering an input of 65536 bytes. */ +#pragma HLS loop_tripcount min = 1 max = 4096 +#pragma HLS pipeline II = 18 AES_CBC_CIPHER_L_2_1: - for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) { +#pragma HLS unroll complete in_mem[k] = in[i + k] ^ tmp_mem[k]; } AES_CBC_CIPHER_L_2_2: - for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) { +#pragma HLS unroll complete in_mem[k] = AES_SWAP(in_mem[k]); } @@ -62,17 +52,15 @@ int aes_cbc_cipher(uint32 encryption, aes_encrypt(key_bytes, in_mem, tmp_mem, ekey); AES_CBC_CIPHER_L_2_3: - for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) { +#pragma HLS unroll complete tmp_mem[k] = AES_SWAP(tmp_mem[k]); } AES_CBC_CIPHER_L_2_4: - for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) { +#pragma HLS unroll complete out[i + k] = tmp_mem[k]; } @@ -81,24 +69,21 @@ int aes_cbc_cipher(uint32 encryption, else // if (encryption == DECRYPTION_MODE) { AES_CBC_CIPHER_L_3: - for (unsigned i = 0; i < input_words; i += AES_BLOCK_WORDS) - { - /* Considering an input of 65536 bytes. */ - #pragma HLS loop_tripcount min=1 max=4096 - #pragma HLS pipeline II=4 + for (unsigned i = 0; i < input_words; i += AES_BLOCK_WORDS) { +/* Considering an input of 65536 bytes. */ +#pragma HLS loop_tripcount min = 1 max = 4096 +#pragma HLS pipeline II = 4 AES_CBC_CIPHER_L_3_1: - for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) { +#pragma HLS unroll complete in_mem[k] = in[i + k]; } AES_CBC_CIPHER_L_3_2: - for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) { +#pragma HLS unroll complete in_mem[k] = AES_SWAP(in_mem[k]); } @@ -106,25 +91,22 @@ int aes_cbc_cipher(uint32 encryption, aes_decrypt(key_bytes, in_mem, out_mem, ekey); AES_CBC_CIPHER_L_3_3: - for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) { +#pragma HLS unroll complete out_mem[k] = AES_SWAP(out_mem[k]); } AES_CBC_CIPHER_L_3_4: - for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) { +#pragma HLS unroll complete out[i + k] = out_mem[k] ^ tmp_mem[k]; } AES_CBC_CIPHER_L_3_5: - for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < AES_BLOCK_WORDS; ++k) { +#pragma HLS unroll complete tmp_mem[k] = AES_SWAP(in_mem[k]); } diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/crypto_cxx_catapult.cpp b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/crypto_cxx_catapult.cpp index 7a42cf54fa..51913929b1 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/crypto_cxx_catapult.cpp +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/crypto_cxx_catapult.cpp @@ -3,10 +3,10 @@ #include "esp_headers.hpp" +#include "aes.h" #include "crypto_cxx_catapult.hpp" #include "sha1.h" #include "sha2.h" -#include "aes.h" #include @@ -17,33 +17,39 @@ #define ZERO data_t(0) -template -void sha1_compute_wrapper(uint32 in_bytes, T1 &input, T2 &output) { +template void sha1_compute_wrapper(uint32 in_bytes, T1 &input, T2 &output) +{ ESP_REPORT_INFO(VOFF, "sha1_in_bytes: %u", ESP_TO_UINT32(in_bytes)); sha1(in_bytes, input.data, output.data); } template -void sha2_compute_wrapper(uint32 in_bytes, uint32 out_bytes, T1 &input, T2 &output) { +void sha2_compute_wrapper(uint32 in_bytes, uint32 out_bytes, T1 &input, T2 &output) +{ ESP_REPORT_INFO(VOFF, "sha2_in_bytes: %u", ESP_TO_UINT32(in_bytes)); ESP_REPORT_INFO(VOFF, "sha2_out_bytes: %u", ESP_TO_UINT32(out_bytes)); sha2(in_bytes, out_bytes, input.data, output.data); } -void aes_compute_wrapper(uint32 oper_mode, uint32 encryption, uint32 key_bytes, uint32 iv_bytes, uint32 in_bytes, uint32 aad_bytes, uint32 tag_bytes, aes_plm_key_t &key, aes_plm_iv_t &iv, aes_plm_in_t &in, aes_plm_out_t &out, aes_plm_aad_t &aad, aes_plm_tag_t &tag) { +void aes_compute_wrapper(uint32 oper_mode, uint32 encryption, uint32 key_bytes, uint32 iv_bytes, + uint32 in_bytes, uint32 aad_bytes, uint32 tag_bytes, aes_plm_key_t &key, + aes_plm_iv_t &iv, aes_plm_in_t &in, aes_plm_out_t &out, aes_plm_aad_t &aad, + aes_plm_tag_t &tag) +{ ESP_REPORT_INFO(VON, "aes_oper_mode: %u", ESP_TO_UINT32(oper_mode)); ESP_REPORT_INFO(VON, "aes_encryption: %u", ESP_TO_UINT32(encryption)); ESP_REPORT_INFO(VON, "aes_key_bytes: %u", ESP_TO_UINT32(key_bytes)); ESP_REPORT_INFO(VON, "aes_in_bytes: %u", ESP_TO_UINT32(in_bytes)); - aes(oper_mode, encryption, key_bytes, iv_bytes, in_bytes, aad_bytes, tag_bytes, key.data, iv.data, in.data, out.data, aad.data, tag.data); + aes(oper_mode, encryption, key_bytes, iv_bytes, in_bytes, aad_bytes, tag_bytes, key.data, + iv.data, in.data, out.data, aad.data, tag.data); } #define CRYPTO_SHA1_MODE 1 #define CRYPTO_SHA2_MODE 2 -#define CRYPTO_AES_MODE 3 +#define CRYPTO_AES_MODE 3 #define AES_ECB_OPERATION_MODE 1 #define AES_CTR_OPERATION_MODE 2 @@ -56,37 +62,35 @@ void crypto_cxx_catapult( #else void CCS_BLOCK(crypto_cxx_catapult)( #endif - ac_channel &conf_info, - ac_channel &dma_read_ctrl, - ac_channel &dma_write_ctrl, - ac_channel &dma_read_chnl, - ac_channel &dma_write_chnl, - ac_sync &acc_done) { + ac_channel &conf_info, ac_channel &dma_read_ctrl, + ac_channel &dma_write_ctrl, ac_channel &dma_read_chnl, + ac_channel &dma_write_chnl, ac_sync &acc_done) +{ // Bookkeeping variables - uint32 dma_read_data_index = 0; - uint32 dma_read_data_length = 0; - uint32 dma_write_data_index= 0; + uint32 dma_read_data_index = 0; + uint32 dma_read_data_length = 0; + uint32 dma_write_data_index = 0; uint32 dma_write_data_length = SHA1_PLM_OUT_SIZE; // DMA configuration - dma_info_t dma_read_info = {0, 0, 0}; + dma_info_t dma_read_info = {0, 0, 0}; dma_info_t dma_write_info = {0, 0, 0}; // Accelerator configuration conf_info_t config; - uint32 crypto_algo = 0; - uint32 sha1_in_bytes = 0; - uint32 sha2_in_bytes = 0; - uint32 sha2_out_bytes = 0; - uint32 aes_oper_mode = 0; - uint32 aes_encryption = 0; - uint32 aes_key_bytes = 0; - uint32 aes_iv_bytes = 0; - uint32 aes_in_bytes = 0; + uint32 crypto_algo = 0; + uint32 sha1_in_bytes = 0; + uint32 sha2_in_bytes = 0; + uint32 sha2_out_bytes = 0; + uint32 aes_oper_mode = 0; + uint32 aes_encryption = 0; + uint32 aes_key_bytes = 0; + uint32 aes_iv_bytes = 0; + uint32 aes_in_bytes = 0; uint32 aes_output_bytes = 0; - uint32 aes_aad_bytes = 0; - uint32 aes_tag_bytes = 0; + uint32 aes_aad_bytes = 0; + uint32 aes_tag_bytes = 0; // Private Local Memories sha1_plm_in_t sha1_plm_in; @@ -105,7 +109,7 @@ void CCS_BLOCK(crypto_cxx_catapult)( while (!conf_info.available(1)) {} // Hardware stalls until data ready #endif - config = conf_info.read(); + config = conf_info.read(); crypto_algo = config.crypto_algo; if (crypto_algo == CRYPTO_SHA1_MODE) { @@ -119,18 +123,25 @@ void CCS_BLOCK(crypto_cxx_catapult)( // - SHA1 input word is 32 bits // - Each DMA transaction is 2 input words // - Do some math (ceil) to get the number of data and DMA words given in_bytes - dma_read_data_index = 0; - dma_read_data_length = (sha1_in_bytes + 4 - 1) / 4; // ceil(in_bytes / 4) - dma_read_info = {dma_read_data_index, (dma_read_data_length + 2 - 1) / 2, SIZE_WORD}; // ceil(dma_read_data_legnth / 2) + dma_read_data_index = 0; + dma_read_data_length = (sha1_in_bytes + 4 - 1) / 4; // ceil(in_bytes / 4) + dma_read_info = {dma_read_data_index, (dma_read_data_length + 2 - 1) / 2, + SIZE_WORD}; // ceil(dma_read_data_legnth / 2) bool dma_read_ctrl_done = false; SHA1_LOAD_CTRL_LOOP: - do { dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); } while (!dma_read_ctrl_done); + do { + dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); + } while (!dma_read_ctrl_done); - ESP_REPORT_INFO(VON, "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, 2=32b, 3=64b] = %llu", ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), dma_read_info.size.to_uint64()); + ESP_REPORT_INFO(VON, + "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, " + "2=32b, 3=64b] = %llu", + ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), + dma_read_info.size.to_uint64()); if (dma_read_ctrl_done) { // Force serialization between DMA control and DATA data transfer SHA1_LOAD_LOOP: - for (uint16_t i = 0; i < SHA1_PLM_IN_SIZE; i+=2) { + for (uint16_t i = 0; i < SHA1_PLM_IN_SIZE; i += 2) { if (i >= dma_read_data_length) break; @@ -152,41 +163,52 @@ void CCS_BLOCK(crypto_cxx_catapult)( // ... data_t data_0; data_t data_1; - data_0 = data_dma.template slc(WL*0).to_uint(); - data_1 = data_dma.template slc(WL*1).to_uint(); - sha1_plm_in.data[i+0] = data_0; - sha1_plm_in.data[i+1] = data_1; - - ESP_REPORT_INFO(VOFF, "sha1_plm_in[%u] = %02X", ESP_TO_UINT32(i)+0, data_0.to_uint()); - ESP_REPORT_INFO(VOFF, "sha1_plm_in[%u] = %02X", ESP_TO_UINT32(i)+1, data_1.to_uint()); + data_0 = data_dma.template slc(WL * 0).to_uint(); + data_1 = data_dma.template slc(WL * 1).to_uint(); + sha1_plm_in.data[i + 0] = data_0; + sha1_plm_in.data[i + 1] = data_1; + + ESP_REPORT_INFO(VOFF, "sha1_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 0, + data_0.to_uint()); + ESP_REPORT_INFO(VOFF, "sha1_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 1, + data_1.to_uint()); } } - sha1_compute_wrapper(sha1_in_bytes, sha1_plm_in, sha1_plm_out); + sha1_compute_wrapper(sha1_in_bytes, sha1_plm_in, + sha1_plm_out); // Configure DMA write channel (CTRL) // - DMA_WIDTH for EPOCHS is 64 bits // - SHA1 output word is 32 bits // - Each DMA transaction is 2 output words // - There are 3 DMA-word as output (last 32bits are zeros) - dma_write_data_index = dma_read_data_length; + dma_write_data_index = dma_read_data_length; dma_write_data_length = SHA1_PLM_OUT_SIZE; - dma_write_info = {(dma_write_data_index + 2 - 1) / 2, (dma_write_data_length + 2 - 1) / 2, SIZE_WORD}; + dma_write_info = {(dma_write_data_index + 2 - 1) / 2, (dma_write_data_length + 2 - 1) / 2, + SIZE_WORD}; bool dma_write_ctrl_done = false; SHA1_STORE_CTRL_LOOP: - do { dma_write_ctrl_done = dma_write_ctrl.nb_write(dma_write_info); } while (!dma_write_ctrl_done); + do { + dma_write_ctrl_done = dma_write_ctrl.nb_write(dma_write_info); + } while (!dma_write_ctrl_done); - ESP_REPORT_INFO(VON, "DMA write ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, 2=32b, 3=64b] = %llu", ESP_TO_UINT32(dma_write_info.index), ESP_TO_UINT32(dma_write_info.length), dma_write_info.size.to_uint64()); + ESP_REPORT_INFO(VON, + "DMA write ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, " + "2=32b, 3=64b] = %llu", + ESP_TO_UINT32(dma_write_info.index), ESP_TO_UINT32(dma_write_info.length), + dma_write_info.size.to_uint64()); if (dma_write_ctrl_done) { // Force serialization between DMA control and DATA data transfer SHA1_STORE_LOOP: - for (uint16_t i = 0; i < SHA1_PLM_OUT_SIZE; i+=2) { + for (uint16_t i = 0; i < SHA1_PLM_OUT_SIZE; i += 2) { // TODO: not necessary because PLM_OUT_SIZE == dma_write_data_lenght == 6 == 5 + 1 - //if (i >= dma_write_data_length) break; + // if (i >= dma_write_data_length) break; assert(DMA_WIDTH == 64 && "DMA_WIDTH should be 64 bits"); - assert(SHA1_PLM_OUT_SIZE == 6 && "PLM_OUT_SIZE should be 6 32-bit words (5 + 1 extra dummy word)"); + assert(SHA1_PLM_OUT_SIZE == 6 && + "PLM_OUT_SIZE should be 6 32-bit words (5 + 1 extra dummy word)"); // PLM (in) // |<--- 0 --->| @@ -202,21 +224,24 @@ void CCS_BLOCK(crypto_cxx_catapult)( // Zeros the 64-bit DMA word when necessary ac_int data_dma = 0; - data_t data_0(sha1_plm_out.data[i+0]); - data_t data_1(sha1_plm_out.data[i+1]); + data_t data_0(sha1_plm_out.data[i + 0]); + data_t data_1(sha1_plm_out.data[i + 1]); - data_dma.set_slc(WL*0, data_0.template slc(0)); - data_dma.set_slc(WL*1, data_1.template slc(0)); + data_dma.set_slc(WL * 0, data_0.template slc(0)); + data_dma.set_slc(WL * 1, data_1.template slc(0)); - ESP_REPORT_INFO(VOFF, "sha1_plm_in[%u] = %02X", ESP_TO_UINT32(i)+0, data_0.to_uint()); - ESP_REPORT_INFO(VOFF, "sha1_plm_in[%u] = %02X", ESP_TO_UINT32(i)+1, data_1.to_uint()); + ESP_REPORT_INFO(VOFF, "sha1_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 0, + data_0.to_uint()); + ESP_REPORT_INFO(VOFF, "sha1_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 1, + data_1.to_uint()); dma_write_chnl.write(data_dma); } } - } else if (crypto_algo == CRYPTO_SHA2_MODE) { + } + else if (crypto_algo == CRYPTO_SHA2_MODE) { - sha2_in_bytes = config.sha2_in_bytes; + sha2_in_bytes = config.sha2_in_bytes; sha2_out_bytes = config.sha2_out_bytes; ESP_REPORT_INFO(VOFF, "conf_info.sha2_in_bytes = %u", ESP_TO_UINT32(sha2_in_bytes)); @@ -227,18 +252,25 @@ void CCS_BLOCK(crypto_cxx_catapult)( // - SHA2 input word is 32 bits // - Each DMA transaction is 2 input words // - Do some math (ceil) to get the number of data and DMA words given in_bytes - dma_read_data_index = 0; - dma_read_data_length = (sha2_in_bytes + 4 - 1) / 4; // ceil(in_bytes / 4) - dma_read_info = {dma_read_data_index, (dma_read_data_length + 2 - 1) / 2, SIZE_WORD}; // ceil(dma_read_data_legnth / 2) + dma_read_data_index = 0; + dma_read_data_length = (sha2_in_bytes + 4 - 1) / 4; // ceil(in_bytes / 4) + dma_read_info = {dma_read_data_index, (dma_read_data_length + 2 - 1) / 2, + SIZE_WORD}; // ceil(dma_read_data_legnth / 2) bool dma_read_ctrl_done = false; SHA2_LOAD_CTRL_LOOP: - do { dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); } while (!dma_read_ctrl_done); + do { + dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); + } while (!dma_read_ctrl_done); - ESP_REPORT_INFO(VON, "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, 2=32b, 3=64b] = %llu", ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), dma_read_info.size.to_uint64()); + ESP_REPORT_INFO(VON, + "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, " + "2=32b, 3=64b] = %llu", + ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), + dma_read_info.size.to_uint64()); if (dma_read_ctrl_done) { // Force serialization between DMA control and DATA data transfer SHA2_LOAD_LOOP: - for (uint16_t i = 0; i < SHA2_PLM_IN_SIZE; i+=2) { + for (uint16_t i = 0; i < SHA2_PLM_IN_SIZE; i += 2) { if (i >= dma_read_data_length) break; @@ -260,35 +292,45 @@ void CCS_BLOCK(crypto_cxx_catapult)( // ... data_t data_0; data_t data_1; - data_0 = data_dma.template slc(WL*0).to_uint(); - data_1 = data_dma.template slc(WL*1).to_uint(); - sha2_plm_in.data[i+0] = data_0; - sha2_plm_in.data[i+1] = data_1; - - ESP_REPORT_INFO(VOFF, "sha2_plm_in[%u] = %02X", ESP_TO_UINT32(i)+0, data_0.to_uint()); - ESP_REPORT_INFO(VOFF, "sha2_plm_in[%u] = %02X", ESP_TO_UINT32(i)+1, data_1.to_uint()); + data_0 = data_dma.template slc(WL * 0).to_uint(); + data_1 = data_dma.template slc(WL * 1).to_uint(); + sha2_plm_in.data[i + 0] = data_0; + sha2_plm_in.data[i + 1] = data_1; + + ESP_REPORT_INFO(VOFF, "sha2_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 0, + data_0.to_uint()); + ESP_REPORT_INFO(VOFF, "sha2_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 1, + data_1.to_uint()); } } - sha2_compute_wrapper(sha2_in_bytes, sha2_out_bytes, sha2_plm_in, sha2_plm_out); + sha2_compute_wrapper(sha2_in_bytes, sha2_out_bytes, + sha2_plm_in, sha2_plm_out); // Configure DMA write channel (CTRL) // - DMA_WIDTH for EPOCHS is 64 bits // - SHA2 output word is 32 bits // - Each DMA transaction is 2 output words // - Do some math (ceil) to get the number of data and DMA words given out_bytes - dma_write_data_index = dma_read_data_length; + dma_write_data_index = dma_read_data_length; dma_write_data_length = (sha2_out_bytes + 4 - 1) / 4; // ceil(out_bytes / 4) - dma_write_info = {(dma_write_data_index + 2 - 1) / 2, (dma_write_data_length + 2 - 1) / 2, SIZE_WORD}; + dma_write_info = {(dma_write_data_index + 2 - 1) / 2, (dma_write_data_length + 2 - 1) / 2, + SIZE_WORD}; bool dma_write_ctrl_done = false; SHA2_STORE_CTRL_LOOP: - do { dma_write_ctrl_done = dma_write_ctrl.nb_write(dma_write_info); } while (!dma_write_ctrl_done); + do { + dma_write_ctrl_done = dma_write_ctrl.nb_write(dma_write_info); + } while (!dma_write_ctrl_done); - ESP_REPORT_INFO(VON, "DMA write ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, 2=32b, 3=64b] = %llu", ESP_TO_UINT32(dma_write_info.index), ESP_TO_UINT32(dma_write_info.length), dma_write_info.size.to_uint64()); + ESP_REPORT_INFO(VON, + "DMA write ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, " + "2=32b, 3=64b] = %llu", + ESP_TO_UINT32(dma_write_info.index), ESP_TO_UINT32(dma_write_info.length), + dma_write_info.size.to_uint64()); if (dma_write_ctrl_done) { // Force serialization between DMA control and DATA data transfer SHA2_STORE_LOOP: - for (uint16_t i = 0; i < SHA2_PLM_OUT_SIZE; i+=2) { + for (uint16_t i = 0; i < SHA2_PLM_OUT_SIZE; i += 2) { if (i >= dma_write_data_length) break; @@ -305,28 +347,30 @@ void CCS_BLOCK(crypto_cxx_catapult)( ac_int data_dma = 0; - data_t data_0(sha2_plm_out.data[i+0]); - data_t data_1((i+1 >= dma_write_data_length)?ZERO:sha2_plm_out.data[i+1]); + data_t data_0(sha2_plm_out.data[i + 0]); + data_t data_1((i + 1 >= dma_write_data_length) ? ZERO : sha2_plm_out.data[i + 1]); - data_dma.set_slc(WL*0, data_0.template slc(0)); - data_dma.set_slc(WL*1, data_1.template slc(0)); + data_dma.set_slc(WL * 0, data_0.template slc(0)); + data_dma.set_slc(WL * 1, data_1.template slc(0)); - ESP_REPORT_INFO(VOFF, "sha2_plm_out[%u] = %02X", ESP_TO_UINT32(i)+0, data_0.to_uint()); - ESP_REPORT_INFO(VOFF, "sha2_plm_out[%u] = %02X", ESP_TO_UINT32(i)+1, data_1.to_uint()); + ESP_REPORT_INFO(VOFF, "sha2_plm_out[%u] = %02X", ESP_TO_UINT32(i) + 0, + data_0.to_uint()); + ESP_REPORT_INFO(VOFF, "sha2_plm_out[%u] = %02X", ESP_TO_UINT32(i) + 1, + data_1.to_uint()); dma_write_chnl.write(data_dma); } } + } + else if (crypto_algo == CRYPTO_AES_MODE) { - } else if (crypto_algo == CRYPTO_AES_MODE) { - - aes_oper_mode = config.aes_oper_mode; + aes_oper_mode = config.aes_oper_mode; aes_encryption = config.encryption; - aes_key_bytes = config.aes_key_bytes; - aes_in_bytes = config.aes_in_bytes; - aes_iv_bytes = config.aes_iv_bytes; - aes_aad_bytes = config.aes_aad_bytes; - aes_tag_bytes = config.aes_tag_bytes; + aes_key_bytes = config.aes_key_bytes; + aes_in_bytes = config.aes_in_bytes; + aes_iv_bytes = config.aes_iv_bytes; + aes_aad_bytes = config.aes_aad_bytes; + aes_tag_bytes = config.aes_tag_bytes; aes_output_bytes = aes_in_bytes; @@ -343,18 +387,25 @@ void CCS_BLOCK(crypto_cxx_catapult)( // - AES input word is 32 bits // - Each DMA transaction is 2 input words // - Do some math (ceil) to get the number of data and DMA words given key_bytes - dma_read_data_index = 0; + dma_read_data_index = 0; dma_read_data_length = (aes_key_bytes + 4 - 1) / 4; // ceil(aes_key_bytes / 4) - dma_read_info = {(dma_read_data_index + 2 - 1) / 2, (dma_read_data_length + 2 - 1) / 2, SIZE_WORD}; // ceil(dma_read_data_legnth / 2) + dma_read_info = {(dma_read_data_index + 2 - 1) / 2, (dma_read_data_length + 2 - 1) / 2, + SIZE_WORD}; // ceil(dma_read_data_legnth / 2) bool dma_read_ctrl_done = false; AES_LOAD_KEY_CTRL_LOOP: - do { dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); } while (!dma_read_ctrl_done); + do { + dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); + } while (!dma_read_ctrl_done); - ESP_REPORT_INFO(VON, "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, 2=32b, 3=64b] = %llu", ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), dma_read_info.size.to_uint64()); + ESP_REPORT_INFO(VON, + "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, " + "2=32b, 3=64b] = %llu", + ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), + dma_read_info.size.to_uint64()); if (dma_read_ctrl_done) { // Force serialization between DMA control and DATA data transfer AES_LOAD_KEY_LOOP: - for (uint16_t i = 0; i < AES_PLM_KEY_SIZE; i+=2) { + for (uint16_t i = 0; i < AES_PLM_KEY_SIZE; i += 2) { if (i >= dma_read_data_length) break; @@ -376,13 +427,15 @@ void CCS_BLOCK(crypto_cxx_catapult)( // ... data_t data_0; data_t data_1; - data_0 = data_dma.template slc(WL*0).to_uint(); - data_1 = data_dma.template slc(WL*1).to_uint(); - aes_plm_key.data[i+0] = data_0; - aes_plm_key.data[i+1] = data_1; - - ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i)+0, data_0.to_uint()); - ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i)+1, data_1.to_uint()); + data_0 = data_dma.template slc(WL * 0).to_uint(); + data_1 = data_dma.template slc(WL * 1).to_uint(); + aes_plm_key.data[i + 0] = data_0; + aes_plm_key.data[i + 1] = data_1; + + ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 0, + data_0.to_uint()); + ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 1, + data_1.to_uint()); } } @@ -392,18 +445,26 @@ void CCS_BLOCK(crypto_cxx_catapult)( // - Each DMA transaction is 2 input words // - Do some math (ceil) to get the number of data and DMA words given iv_bytes if (aes_oper_mode == AES_CTR_OPERATION_MODE || aes_oper_mode == AES_CBC_OPERATION_MODE) { - dma_read_data_index = (aes_key_bytes + 4 - 1) / 4; + dma_read_data_index = (aes_key_bytes + 4 - 1) / 4; dma_read_data_length = (aes_iv_bytes + 4 - 1) / 4; // ceil(aes_iv_bytes / 4) - dma_read_info = {(dma_read_data_index + 2 - 1) / 2, (dma_read_data_length + 2 - 1) / 2, SIZE_WORD}; // ceil(dma_read_data_legnth / 2) + dma_read_info = {(dma_read_data_index + 2 - 1) / 2, (dma_read_data_length + 2 - 1) / 2, + SIZE_WORD}; // ceil(dma_read_data_legnth / 2) bool dma_read_ctrl_done = false; AES_LOAD_IV_CTRL_LOOP: - do { dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); } while (!dma_read_ctrl_done); - - ESP_REPORT_INFO(VON, "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, 2=32b, 3=64b] = %llu", ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), dma_read_info.size.to_uint64()); - - if (dma_read_ctrl_done) { // Force serialization between DMA control and DATA data transfer + do { + dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); + } while (!dma_read_ctrl_done); + + ESP_REPORT_INFO(VON, + "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, " + "2=32b, 3=64b] = %llu", + ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), + dma_read_info.size.to_uint64()); + + if (dma_read_ctrl_done) { // Force serialization between DMA control and DATA data + // transfer AES_LOAD_IV_LOOP: - for (uint16_t i = 0; i < AES_PLM_IV_SIZE; i+=2) { + for (uint16_t i = 0; i < AES_PLM_IV_SIZE; i += 2) { if (i >= dma_read_data_length) break; @@ -425,13 +486,15 @@ void CCS_BLOCK(crypto_cxx_catapult)( // ... data_t data_0; data_t data_1; - data_0 = data_dma.template slc(WL*0).to_uint(); - data_1 = data_dma.template slc(WL*1).to_uint(); - aes_plm_iv.data[i+0] = data_0; - aes_plm_iv.data[i+1] = data_1; - - ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i)+0, data_0.to_uint()); - ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i)+1, data_1.to_uint()); + data_0 = data_dma.template slc(WL * 0).to_uint(); + data_1 = data_dma.template slc(WL * 1).to_uint(); + aes_plm_iv.data[i + 0] = data_0; + aes_plm_iv.data[i + 1] = data_1; + + ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 0, + data_0.to_uint()); + ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 1, + data_1.to_uint()); } } } @@ -441,18 +504,25 @@ void CCS_BLOCK(crypto_cxx_catapult)( // - AES input word is 32 bits // - Each DMA transaction is 2 input words // - Do some math (ceil) to get the number of data and DMA words given key_bytes - dma_read_data_index = (aes_key_bytes + 4 - 1) / 4 + (aes_iv_bytes + 4 - 1) / 4; + dma_read_data_index = (aes_key_bytes + 4 - 1) / 4 + (aes_iv_bytes + 4 - 1) / 4; dma_read_data_length = (aes_in_bytes + 4 - 1) / 4; // ceil(key_bytes / 4) - dma_read_info = {(dma_read_data_index + 2 - 1) / 2, (dma_read_data_length + 2 - 1) / 2, SIZE_WORD}; // ceil(dma_read_data_legnth / 2) + dma_read_info = {(dma_read_data_index + 2 - 1) / 2, (dma_read_data_length + 2 - 1) / 2, + SIZE_WORD}; // ceil(dma_read_data_legnth / 2) dma_read_ctrl_done = false; AES_LOAD_INPUT_CTRL_LOOP: - do { dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); } while (!dma_read_ctrl_done); + do { + dma_read_ctrl_done = dma_read_ctrl.nb_write(dma_read_info); + } while (!dma_read_ctrl_done); - ESP_REPORT_INFO(VON, "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, 2=32b, 3=64b] = %llu", ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), dma_read_info.size.to_uint64()); + ESP_REPORT_INFO(VON, + "DMA read ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, " + "2=32b, 3=64b] = %llu", + ESP_TO_UINT32(dma_read_info.index), ESP_TO_UINT32(dma_read_info.length), + dma_read_info.size.to_uint64()); if (dma_read_ctrl_done) { // Force serialization between DMA control and DATA data transfer AES_LOAD_INPUT_LOOP: - for (uint16_t i = 0; i < AES_PLM_IN_SIZE; i+=2) { + for (uint16_t i = 0; i < AES_PLM_IN_SIZE; i += 2) { if (i >= dma_read_data_length) break; @@ -474,35 +544,47 @@ void CCS_BLOCK(crypto_cxx_catapult)( // ... data_t data_0; data_t data_1; - data_0 = data_dma.template slc(WL*0).to_uint(); - data_1 = data_dma.template slc(WL*1).to_uint(); - aes_plm_in.data[i+0] = data_0; - aes_plm_in.data[i+1] = data_1; - - ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i)+0, data_0.to_uint()); - ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i)+1, data_1.to_uint()); + data_0 = data_dma.template slc(WL * 0).to_uint(); + data_1 = data_dma.template slc(WL * 1).to_uint(); + aes_plm_in.data[i + 0] = data_0; + aes_plm_in.data[i + 1] = data_1; + + ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 0, + data_0.to_uint()); + ESP_REPORT_INFO(VOFF, "aes_plm_in[%u] = %02X", ESP_TO_UINT32(i) + 1, + data_1.to_uint()); } } - aes_compute_wrapper(aes_oper_mode, aes_encryption, aes_key_bytes, aes_iv_bytes, aes_in_bytes, aes_aad_bytes, aes_tag_bytes, aes_plm_key, aes_plm_iv, aes_plm_in, aes_plm_out, aes_plm_aad, aes_plm_tag); + aes_compute_wrapper(aes_oper_mode, aes_encryption, aes_key_bytes, aes_iv_bytes, + aes_in_bytes, aes_aad_bytes, aes_tag_bytes, aes_plm_key, aes_plm_iv, + aes_plm_in, aes_plm_out, aes_plm_aad, aes_plm_tag); // Configure DMA write channel (CTRL) // - DMA_WIDTH for EPOCHS is 64 bits // - AES output word is 32 bits // - Each DMA transaction is 2 output words // - Do some math (ceil) to get the number of data and DMA words given out_bytes - dma_write_data_index = (aes_key_bytes + 4 - 1) / 4 + (aes_iv_bytes + 4 - 1) / 4 + (aes_in_bytes + 4 - 1) / 4; + dma_write_data_index = + (aes_key_bytes + 4 - 1) / 4 + (aes_iv_bytes + 4 - 1) / 4 + (aes_in_bytes + 4 - 1) / 4; dma_write_data_length = (aes_output_bytes + 4 - 1) / 4; // ceil(out_bytes / 4) - dma_write_info = {(dma_write_data_index + 2 - 1) / 2, (dma_write_data_length + 2 - 1) / 2, SIZE_WORD}; + dma_write_info = {(dma_write_data_index + 2 - 1) / 2, (dma_write_data_length + 2 - 1) / 2, + SIZE_WORD}; bool dma_write_ctrl_done = false; AES_STORE_CTRL_LOOP: - do { dma_write_ctrl_done = dma_write_ctrl.nb_write(dma_write_info); } while (!dma_write_ctrl_done); + do { + dma_write_ctrl_done = dma_write_ctrl.nb_write(dma_write_info); + } while (!dma_write_ctrl_done); - ESP_REPORT_INFO(VON, "DMA write ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, 2=32b, 3=64b] = %llu", ESP_TO_UINT32(dma_write_info.index), ESP_TO_UINT32(dma_write_info.length), dma_write_info.size.to_uint64()); + ESP_REPORT_INFO(VON, + "DMA write ctrl: data index = %u, data length = %u, size [0=8b, 1=16b, " + "2=32b, 3=64b] = %llu", + ESP_TO_UINT32(dma_write_info.index), ESP_TO_UINT32(dma_write_info.length), + dma_write_info.size.to_uint64()); if (dma_write_ctrl_done) { // Force serialization between DMA control and DATA data transfer AES_STORE_LOOP: - for (uint16_t i = 0; i < AES_PLM_OUT_SIZE; i+=2) { + for (uint16_t i = 0; i < AES_PLM_OUT_SIZE; i += 2) { if (i >= dma_write_data_length) break; @@ -519,15 +601,17 @@ void CCS_BLOCK(crypto_cxx_catapult)( ac_int data_dma = 0; - data_t data_0(aes_plm_out.data[i+0]); - //data_t data_1((i+1 >= dma_write_data_length)?ZERO:plm_out.data[i+1]); - data_t data_1(aes_plm_out.data[i+1]); + data_t data_0(aes_plm_out.data[i + 0]); + // data_t data_1((i+1 >= dma_write_data_length)?ZERO:plm_out.data[i+1]); + data_t data_1(aes_plm_out.data[i + 1]); - data_dma.set_slc(WL*0, data_0.template slc(0)); - data_dma.set_slc(WL*1, data_1.template slc(0)); + data_dma.set_slc(WL * 0, data_0.template slc(0)); + data_dma.set_slc(WL * 1, data_1.template slc(0)); - ESP_REPORT_INFO(VOFF, "aes_plm_out[%u] = %02X", ESP_TO_UINT32(i)+0, data_0.to_uint()); - ESP_REPORT_INFO(VOFF, "aes_plm_out[%u] = %02X", ESP_TO_UINT32(i)+1, data_1.to_uint()); + ESP_REPORT_INFO(VOFF, "aes_plm_out[%u] = %02X", ESP_TO_UINT32(i) + 0, + data_0.to_uint()); + ESP_REPORT_INFO(VOFF, "aes_plm_out[%u] = %02X", ESP_TO_UINT32(i) + 1, + data_1.to_uint()); dma_write_chnl.write(data_dma); } diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/sha1/sha1.cpp b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/sha1/sha1.cpp index 0680cbd31c..0971385527 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/sha1/sha1.cpp +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/sha1/sha1.cpp @@ -4,37 +4,35 @@ #define ROTATE5(V) ((V << 5) | (V >> 27)) #define ROTATE30(V) ((V << 30) | (V >> 2)) -#define Xupdate(a, ix, ia, ib, ic, id) \ - a = (ia ^ ib ^ ic ^ id), \ - ix = (a) = ROTATE1((a)) \ +#define Xupdate(a, ix, ia, ib, ic, id) a = (ia ^ ib ^ ic ^ id), ix = (a) = ROTATE1((a)) -#define BODY_00_15(xi) \ - T = E + 0x5a827999UL + (((C ^ D) & B) ^ D); \ - E = D, D = C, C = ROTATE30(B), B = A; \ +#define BODY_00_15(xi) \ + T = E + 0x5a827999UL + (((C ^ D) & B) ^ D); \ + E = D, D = C, C = ROTATE30(B), B = A; \ A = ROTATE5(A) + T + xi; -#define BODY_16_19(xa, xb, xc, xd) \ - Xupdate(T, xa, xa, xb, xc, xd); \ - T += E + 0x5a827999UL + (((C ^ D) & B) ^ D); \ - E = D, D = C, C = ROTATE30(B), B = A; \ +#define BODY_16_19(xa, xb, xc, xd) \ + Xupdate(T, xa, xa, xb, xc, xd); \ + T += E + 0x5a827999UL + (((C ^ D) & B) ^ D); \ + E = D, D = C, C = ROTATE30(B), B = A; \ A = ROTATE5(A) + T; -#define BODY_20_39(xa, xb, xc, xd) \ - Xupdate(T, xa, xa, xb, xc, xd); \ - T += E + 0x6ed9eba1UL + (B ^ C ^ D); \ - E = D, D = C, C = ROTATE30(B), B = A; \ +#define BODY_20_39(xa, xb, xc, xd) \ + Xupdate(T, xa, xa, xb, xc, xd); \ + T += E + 0x6ed9eba1UL + (B ^ C ^ D); \ + E = D, D = C, C = ROTATE30(B), B = A; \ A = ROTATE5(A) + T; -#define BODY_40_59(xa, xb, xc, xd) \ - Xupdate(T, xa, xa, xb, xc, xd); \ - T += E + 0x8f1bbcdcUL + ((B & C) | ((B | C) & D)); \ - E = D, D = C, C = ROTATE30(B), B = A; \ +#define BODY_40_59(xa, xb, xc, xd) \ + Xupdate(T, xa, xa, xb, xc, xd); \ + T += E + 0x8f1bbcdcUL + ((B & C) | ((B | C) & D)); \ + E = D, D = C, C = ROTATE30(B), B = A; \ A = ROTATE5(A) + T; -#define BODY_60_79(xa, xb, xc, xd) \ - Xupdate(T, xa, xa, xb, xc, xd); \ - T = E + 0xca62c1d6UL + (B ^ C ^ D); \ - E = D, D = C, C = ROTATE30(B), B = A; \ +#define BODY_60_79(xa, xb, xc, xd) \ + Xupdate(T, xa, xa, xb, xc, xd); \ + T = E + 0xca62c1d6UL + (B ^ C ^ D); \ + E = D, D = C, C = ROTATE30(B), B = A; \ A = ROTATE5(A) + T + xa; // Disable byte swapping @@ -55,32 +53,28 @@ void sha1_init(uint32 h[SHA1_HBLOCK_WORDS]) h[4] = 0xc3d2e1f0UL; } -void sha1_load(uint32 data[SHA1_CBLOCK_WORDS], - uint32 in[SHA1_MAX_BLOCK_SIZE]) +void sha1_load(uint32 data[SHA1_CBLOCK_WORDS], uint32 in[SHA1_MAX_BLOCK_SIZE]) { - #pragma HLS inline off +#pragma HLS inline off /* memcpy(data, in, SHA1_CBLOCK_BYTES); */ SHA1_L_1_1: - for (unsigned i = 0; i < SHA1_CBLOCK_WORDS; ++i) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < SHA1_CBLOCK_WORDS; ++i) { +#pragma HLS unroll complete data[i] = in[i]; } SHA1_L_1_2: - for (unsigned i = 0; i < SHA1_CBLOCK_WORDS; ++i) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < SHA1_CBLOCK_WORDS; ++i) { +#pragma HLS unroll complete data[i] = SHA1_SWAP(data[i]); } } -void sha1_block(uint32 h[SHA1_HBLOCK_WORDS], - uint32 X[SHA1_CBLOCK_WORDS]) +void sha1_block(uint32 h[SHA1_HBLOCK_WORDS], uint32 X[SHA1_CBLOCK_WORDS]) { uint32 T; uint32 A = h[0]; @@ -89,52 +83,43 @@ void sha1_block(uint32 h[SHA1_HBLOCK_WORDS], uint32 D = h[3]; uint32 E = h[4]; - #pragma HLS inline off - #pragma HLS loop_merge - #pragma HLS loop_flatten +#pragma HLS inline off +#pragma HLS loop_merge +#pragma HLS loop_flatten SHA1_BLOCK_L_1: - for (unsigned i = 0; i < 16; i++) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < 16; i++) { +#pragma HLS unroll complete BODY_00_15(X[i]); } SHA1_BLOCK_L_2: - for (unsigned i = 0; i < 4; i++) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < 4; i++) { +#pragma HLS unroll complete - BODY_16_19(X[i], X[i + 2], X[i + 8], - X[((i + 13) & 15)]); + BODY_16_19(X[i], X[i + 2], X[i + 8], X[((i + 13) & 15)]); } SHA1_BLOCK_L_3: - for (unsigned i = 4; i < 24; i++) - { - #pragma HLS unroll complete + for (unsigned i = 4; i < 24; i++) { +#pragma HLS unroll complete - BODY_20_39(X[(i & 15)], X[((i + 2) & 15)], - X[((i + 8) & 15)], X[((i + 13) & 15)]); + BODY_20_39(X[(i & 15)], X[((i + 2) & 15)], X[((i + 8) & 15)], X[((i + 13) & 15)]); } SHA1_BLOCK_L_4: - for (unsigned i = 0; i < 20; i++) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < 20; i++) { +#pragma HLS unroll complete - BODY_40_59(X[((i + 8) & 15)], X[((i + 10) & 15)], - X[(i & 15)], X[((i + 5) & 15)]); + BODY_40_59(X[((i + 8) & 15)], X[((i + 10) & 15)], X[(i & 15)], X[((i + 5) & 15)]); } SHA1_BLOCK_L_5: - for (unsigned i = 4; i < 24; i++) - { - #pragma HLS unroll complete + for (unsigned i = 4; i < 24; i++) { +#pragma HLS unroll complete - BODY_60_79(X[((i + 8) & 15)], X[((i + 10) & 15)], - X[(i & 15)], X[((i + 5) & 15)]); + BODY_60_79(X[((i + 8) & 15)], X[((i + 10) & 15)], X[(i & 15)], X[((i + 5) & 15)]); } h[0] += A; @@ -144,34 +129,28 @@ void sha1_block(uint32 h[SHA1_HBLOCK_WORDS], h[4] += E; } -void sha1_process(uint32 h[SHA1_HBLOCK_WORDS], - uint32 data[SHA1_CBLOCK_WORDS], - uint32 in[SHA1_MAX_BLOCK_SIZE], - uint32 blocks) +void sha1_process(uint32 h[SHA1_HBLOCK_WORDS], uint32 data[SHA1_CBLOCK_WORDS], + uint32 in[SHA1_MAX_BLOCK_SIZE], uint32 blocks) { - #pragma HLS inline +#pragma HLS inline SHA1_L_1: - for (unsigned t = 0; t < blocks; t += SHA1_CBLOCK_BYTES) - { - /* Considering an input of 65536 bytes. */ - #pragma HLS loop_tripcount min=1 max=1024 - #pragma HLS pipeline II=17 rewind + for (unsigned t = 0; t < blocks; t += SHA1_CBLOCK_BYTES) { +/* Considering an input of 65536 bytes. */ +#pragma HLS loop_tripcount min = 1 max = 1024 +#pragma HLS pipeline II = 17 rewind sha1_load(data, &(in[t >> 2])); sha1_block(h, data); } } -int sha1( - uint32 in_bytes, - uint32 in[SHA1_MAX_BLOCK_SIZE], - uint32 out[SHA1_DIGEST_WORDS]) +int sha1(uint32 in_bytes, uint32 in[SHA1_MAX_BLOCK_SIZE], uint32 out[SHA1_DIGEST_WORDS]) { - #pragma HLS INTERFACE s_axilite port=return - #pragma HLS INTERFACE s_axilite port=in_bytes - #pragma HLS INTERFACE m_axi depth=sha1_max_addr_mem port=in offset=slave - #pragma HLS INTERFACE m_axi depth=sha1_max_addr_mem port=out offset=slave +#pragma HLS INTERFACE s_axilite port = return +#pragma HLS INTERFACE s_axilite port = in_bytes +#pragma HLS INTERFACE m_axi depth = sha1_max_addr_mem port = in offset = slave +#pragma HLS INTERFACE m_axi depth = sha1_max_addr_mem port = out offset = slave uint32 bytes; uint32 blocks; @@ -179,39 +158,36 @@ int sha1( uint32 data[SHA1_CBLOCK_WORDS]; int ret = 0; - #pragma HLS array_partition variable=h complete - #pragma HLS array_partition variable=data complete +#pragma HLS array_partition variable = h complete +#pragma HLS array_partition variable = data complete sha1_init(h); blocks = in_bytes & SHA1_CBLOCK_BYTES_MASK; - bytes = in_bytes - blocks; + bytes = in_bytes - blocks; /* sha1_update(); */ sha1_process(h, data, in, blocks); SHA1_L_1_3: - for (unsigned i = 0; i < SHA1_CBLOCK_WORDS; ++i) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < SHA1_CBLOCK_WORDS; ++i) { +#pragma HLS unroll complete data[i] = 0; } SHA1_L_1_4: - for (unsigned i = 0; i < SHA1_WORDS(bytes); ++i) - { - #pragma HLS loop_tripcount min=1 max=16 - #pragma HLS pipeline II=1 + for (unsigned i = 0; i < SHA1_WORDS(bytes); ++i) { +#pragma HLS loop_tripcount min = 1 max = 16 +#pragma HLS pipeline II = 1 data[i] = in[(blocks >> 2) + i]; } SHA1_L_1_5: - for (unsigned i = 0; i < SHA1_CBLOCK_WORDS; ++i) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < SHA1_CBLOCK_WORDS; ++i) { +#pragma HLS unroll complete data[i] = SHA1_SWAP(data[i]); } @@ -220,18 +196,16 @@ int sha1( data[bytes >> 2] |= (0x80U << (24 - ((bytes & 0x03) << 3))); - if (++bytes > (SHA1_CBLOCK_BYTES - 8)) - { + if (++bytes > (SHA1_CBLOCK_BYTES - 8)) { sha1_block(h, data); data[0] = 0; - bytes = 0; + bytes = 0; } SHA1_L_1_6: - for (unsigned k = bytes + 1; k < SHA1_CBLOCK_WORDS - 2; ++k) - { - #pragma HLS loop_tripcount min=1 max=13 - #pragma HLS unroll factor=13 + for (unsigned k = bytes + 1; k < SHA1_CBLOCK_WORDS - 2; ++k) { +#pragma HLS loop_tripcount min = 1 max = 13 +#pragma HLS unroll factor = 13 data[k] = 0; } @@ -241,17 +215,15 @@ int sha1( sha1_block(h, data); SHA1_L_1_7: - for (unsigned k = 0; k < SHA1_DIGEST_LENGTH >> 2; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k > 2; ++k) { +#pragma HLS unroll complete h[k] = SHA1_SWAP(h[k]); } SHA1_L_1_8: - for (unsigned k = 0; k < SHA1_DIGEST_LENGTH >> 2; ++k) - { - #pragma HLS pipeline II=1 + for (unsigned k = 0; k > 2; ++k) { +#pragma HLS pipeline II = 1 out[k] = h[k]; } diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/sha2/sha2.cpp b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/sha2/sha2.cpp index e54ce6dfb5..308ac29ed9 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/sha2/sha2.cpp +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/src/sha2/sha2.cpp @@ -22,29 +22,21 @@ static const uint32 K256[64] = { 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; #endif -#define SHA256_SHR(bits, word) \ - ((word) >> (bits)) +#define SHA256_SHR(bits, word) ((word) >> (bits)) -#define SHA256_ROTR(bits, word) \ - (((word) >> (bits)) | ((word) << (32-(bits)))) +#define SHA256_ROTR(bits, word) (((word) >> (bits)) | ((word) << (32 - (bits)))) -#define SHA256_SIGMA0(word) \ - (SHA256_ROTR( 2, word) ^ SHA256_ROTR(13, word) ^ SHA256_ROTR(22, word)) +#define SHA256_SIGMA0(word) (SHA256_ROTR(2, word) ^ SHA256_ROTR(13, word) ^ SHA256_ROTR(22, word)) -#define SHA256_SIGMA1(word) \ - (SHA256_ROTR( 6, word) ^ SHA256_ROTR(11, word) ^ SHA256_ROTR(25, word)) +#define SHA256_SIGMA1(word) (SHA256_ROTR(6, word) ^ SHA256_ROTR(11, word) ^ SHA256_ROTR(25, word)) -#define SHA256_sigma0(word) \ - (SHA256_ROTR( 7, word) ^ SHA256_ROTR(18, word) ^ SHA256_SHR( 3, word)) +#define SHA256_sigma0(word) (SHA256_ROTR(7, word) ^ SHA256_ROTR(18, word) ^ SHA256_SHR(3, word)) -#define SHA256_sigma1(word) \ - (SHA256_ROTR(17, word) ^ SHA256_ROTR(19, word) ^ SHA256_SHR(10, word)) +#define SHA256_sigma1(word) (SHA256_ROTR(17, word) ^ SHA256_ROTR(19, word) ^ SHA256_SHR(10, word)) -#define SHA256_Maj(x, y, z) \ - (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define SHA256_Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) -#define SHA256_Ch(x, y, z) \ - (((x) & (y)) ^ ((~(x)) & (z))) +#define SHA256_Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) // Disable byte swapping //#define SHA256_SWAP(x) \ @@ -55,11 +47,9 @@ static const uint32 K256[64] = { #define SHA256_WORDS(x) (((x + 3) & ~0x3) >> 2) -void sha256_init(uint32 h[SHA256_HBLOCK_WORDS], - uint32 out_bytes) +void sha256_init(uint32 h[SHA256_HBLOCK_WORDS], uint32 out_bytes) { - if (out_bytes == SHA224_DIGEST_LENGTH) - { + if (out_bytes == SHA224_DIGEST_LENGTH) { h[0] = 0xc1059ed8UL; h[1] = 0x367cd507UL; h[2] = 0x3070dd17UL; @@ -69,8 +59,7 @@ void sha256_init(uint32 h[SHA256_HBLOCK_WORDS], h[6] = 0x64f98fa7UL; h[7] = 0xbefa4fa4UL; } - else if (out_bytes == SHA256_DIGEST_LENGTH) - { + else if (out_bytes == SHA256_DIGEST_LENGTH) { h[0] = 0x6a09e667UL; h[1] = 0xbb67ae85UL; h[2] = 0x3c6ef372UL; @@ -82,79 +71,66 @@ void sha256_init(uint32 h[SHA256_HBLOCK_WORDS], } } -void sha256_load(uint32 data[SHA256_CBLOCK_WORDS], - uint32 in[SHA2_MAX_BLOCK_SIZE]) +void sha256_load(uint32 data[SHA256_CBLOCK_WORDS], uint32 in[SHA2_MAX_BLOCK_SIZE]) { - #pragma HLS inline off +#pragma HLS inline off /* memcpy(data, in, SHA256_CBLOCK_BYTES); */ SHA256_L_1_1: - for (unsigned i = 0; i < SHA256_CBLOCK_WORDS; ++i) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < SHA256_CBLOCK_WORDS; ++i) { +#pragma HLS unroll complete data[i] = in[i]; } SHA256_L_1_2: - for (unsigned i = 0; i < SHA256_CBLOCK_WORDS; ++i) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < SHA256_CBLOCK_WORDS; ++i) { +#pragma HLS unroll complete data[i] = SHA256_SWAP(data[i]); } } -void sha256_block(uint32 h[SHA256_HBLOCK_WORDS], - uint32 X[SHA256_CBLOCK_WORDS]) +void sha256_block(uint32 h[SHA256_HBLOCK_WORDS], uint32 X[SHA256_CBLOCK_WORDS]) { uint32 tmp[8]; uint32 s0, s1, T1, T2; - - uint32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; - #pragma HLS array_partition variable=tmp complete - #pragma HLS resource variable=K256 core=ROM_nP_BRAM + uint32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, + 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, + 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, + 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, + 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL}; + +#pragma HLS array_partition variable = tmp complete +#pragma HLS resource variable = K256 core = ROM_nP_BRAM SHA256_BLOCK_L_1: - for (unsigned t = 0; t < 8; ++t) - { - #pragma HLS unroll complete + for (unsigned t = 0; t < 8; ++t) { +#pragma HLS unroll complete tmp[t] = h[t]; } SHA256_BLOCK_L_2: - for (unsigned i = 0; i < 16; i++) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < 16; i++) { +#pragma HLS unroll complete - T1 = X[i] + tmp[7] + SHA256_SIGMA1(tmp[4]) + - SHA256_Ch(tmp[4], tmp[5], tmp[6]) + K256[i]; + T1 = X[i] + tmp[7] + SHA256_SIGMA1(tmp[4]) + SHA256_Ch(tmp[4], tmp[5], tmp[6]) + K256[i]; T2 = SHA256_SIGMA0(tmp[0]) + SHA256_Maj(tmp[0], tmp[1], tmp[2]); SHA256_BLOCK_L_2_1: - for (unsigned t = 7; t >= 1; --t) - { - #pragma HLS unroll complete + for (unsigned t = 7; t >= 1; --t) { +#pragma HLS unroll complete tmp[t] = tmp[t - 1]; } @@ -163,9 +139,8 @@ void sha256_block(uint32 h[SHA256_HBLOCK_WORDS], } SHA256_BLOCK_L_3: - for (unsigned i = 16; i < 64; i++) - { - #pragma HLS unroll complete + for (unsigned i = 16; i < 64; i++) { +#pragma HLS unroll complete s0 = X[((i + 1) & 0x0f)]; s0 = SHA256_sigma0(s0); @@ -175,15 +150,14 @@ void sha256_block(uint32 h[SHA256_HBLOCK_WORDS], X[(i & 0xf)] += s0 + s1 + X[((i + 9) & 0xf)]; - T1 = X[(i & 0xf)] + tmp[7] + SHA256_SIGMA1(tmp[4]) + - SHA256_Ch(tmp[4], tmp[5], tmp[6]) + K256[i]; + T1 = X[(i & 0xf)] + tmp[7] + SHA256_SIGMA1(tmp[4]) + SHA256_Ch(tmp[4], tmp[5], tmp[6]) + + K256[i]; T2 = SHA256_SIGMA0(tmp[0]) + SHA256_Maj(tmp[0], tmp[1], tmp[2]); SHA256_BLOCK_L_3_1: - for (unsigned t = 7; t >= 1; --t) - { - #pragma HLS unroll complete + for (unsigned t = 7; t >= 1; --t) { +#pragma HLS unroll complete tmp[t] = tmp[t - 1]; } @@ -193,27 +167,23 @@ void sha256_block(uint32 h[SHA256_HBLOCK_WORDS], } SHA256_BLOCK_L_4: - for (unsigned t = 0; t < 8; ++t) - { - #pragma HLS unroll complete + for (unsigned t = 0; t < 8; ++t) { +#pragma HLS unroll complete h[t] += tmp[t]; } } -void sha256_process(uint32 h[SHA256_HBLOCK_WORDS], - uint32 data[SHA256_CBLOCK_WORDS], - uint32 in[SHA2_MAX_BLOCK_SIZE], - uint32 blocks) +void sha256_process(uint32 h[SHA256_HBLOCK_WORDS], uint32 data[SHA256_CBLOCK_WORDS], + uint32 in[SHA2_MAX_BLOCK_SIZE], uint32 blocks) { - #pragma HLS inline +#pragma HLS inline SHA256_L_1: - for (unsigned t = 0; t < blocks; t += SHA256_CBLOCK_BYTES) - { - /* Considering an input of 65536 bytes. */ - #pragma HLS loop_tripcount min=1 max=1024 - #pragma HLS pipeline II=50 rewind + for (unsigned t = 0; t < blocks; t += SHA256_CBLOCK_BYTES) { +/* Considering an input of 65536 bytes. */ +#pragma HLS loop_tripcount min = 1 max = 1024 +#pragma HLS pipeline II = 50 rewind sha256_load(data, &(in[t >> 2])); sha256_block(h, data); @@ -240,32 +210,24 @@ static const uint64_t K512[80] = { 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, - 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL}; -#define SHA512_SHR(bits, word) \ - (((uint64_t)(word)) >> (bits)) +#define SHA512_SHR(bits, word) (((uint64_t)(word)) >> (bits)) #define SHA512_ROTR(bits, word) \ - ((((uint64_t)(word)) >> (bits)) | \ - (((uint64_t)(word)) << (64-(bits)))) + ((((uint64_t)(word)) >> (bits)) | (((uint64_t)(word)) << (64 - (bits)))) -#define SHA512_SIGMA0(word) \ - (SHA512_ROTR(28, word) ^ SHA512_ROTR(34, word) ^ SHA512_ROTR(39, word)) +#define SHA512_SIGMA0(word) (SHA512_ROTR(28, word) ^ SHA512_ROTR(34, word) ^ SHA512_ROTR(39, word)) -#define SHA512_SIGMA1(word) \ - (SHA512_ROTR(14, word) ^ SHA512_ROTR(18, word) ^ SHA512_ROTR(41, word)) +#define SHA512_SIGMA1(word) (SHA512_ROTR(14, word) ^ SHA512_ROTR(18, word) ^ SHA512_ROTR(41, word)) -#define SHA512_sigma0(word) \ - (SHA512_ROTR( 1, word) ^ SHA512_ROTR( 8, word) ^ SHA512_SHR( 7, word)) +#define SHA512_sigma0(word) (SHA512_ROTR(1, word) ^ SHA512_ROTR(8, word) ^ SHA512_SHR(7, word)) -#define SHA512_sigma1(word) \ - (SHA512_ROTR(19, word) ^ SHA512_ROTR(61, word) ^ SHA512_SHR( 6, word)) +#define SHA512_sigma1(word) (SHA512_ROTR(19, word) ^ SHA512_ROTR(61, word) ^ SHA512_SHR(6, word)) -#define SHA512_Maj(x,y,z) \ - (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define SHA512_Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) -#define SHA512_Ch(x, y, z) \ - (((x) & (y)) ^ ((~(x)) & (z))) +#define SHA512_Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) // Disable byte swapping //#define SHA512_SWAP(x) \ @@ -276,11 +238,9 @@ static const uint64_t K512[80] = { #define SHA512_WORDS(x) (((x + 3) & ~0x3) >> 2) -void sha512_init(uint64_t h[SHA512_HBLOCK_WORDS], - uint32 out_bytes) +void sha512_init(uint64_t h[SHA512_HBLOCK_WORDS], uint32 out_bytes) { - if (out_bytes == SHA384_DIGEST_LENGTH) - { + if (out_bytes == SHA384_DIGEST_LENGTH) { h[0] = 0xcbbb9d5dc1059ed8ULL; h[1] = 0x629a292a367cd507ULL; h[2] = 0x9159015a3070dd17ULL; @@ -290,8 +250,7 @@ void sha512_init(uint64_t h[SHA512_HBLOCK_WORDS], h[6] = 0xdb0c2e0d64f98fa7ULL; h[7] = 0x47b5481dbefa4fa4ULL; } - else if (out_bytes == SHA512_DIGEST_LENGTH) - { + else if (out_bytes == SHA512_DIGEST_LENGTH) { h[0] = 0x6a09e667f3bcc908ULL; h[1] = 0xbb67ae8584caa73bULL; h[2] = 0x3c6ef372fe94f82bULL; @@ -303,32 +262,28 @@ void sha512_init(uint64_t h[SHA512_HBLOCK_WORDS], } } -void sha512_load(uint32 data[SHA512_CBLOCK_WORDS], - uint32 in[SHA2_MAX_BLOCK_SIZE]) +void sha512_load(uint32 data[SHA512_CBLOCK_WORDS], uint32 in[SHA2_MAX_BLOCK_SIZE]) { - #pragma HLS inline off +#pragma HLS inline off /* memcpy(data, in, SHA512_CBLOCK_BYTES); */ SHA512_L_1_1: - for (unsigned k = 0; k < SHA512_CBLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < SHA512_CBLOCK_WORDS; ++k) { +#pragma HLS unroll complete data[k] = in[k]; } SHA512_L_1_2: - for (unsigned k = 0; k < SHA512_CBLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < SHA512_CBLOCK_WORDS; ++k) { +#pragma HLS unroll complete data[k] = SHA512_SWAP(data[k]); } } -void sha512_block(uint64_t h[SHA512_HBLOCK_WORDS], - uint32 T[SHA512_CBLOCK_WORDS]) +void sha512_block(uint64_t h[SHA512_HBLOCK_WORDS], uint32 T[SHA512_CBLOCK_WORDS]) { uint64_t A, E; uint64_t T1, T2; @@ -337,42 +292,37 @@ void sha512_block(uint64_t h[SHA512_HBLOCK_WORDS], A = h[0]; E = h[4]; - #pragma HLS resource variable=K512 core=ROM_nP_BRAM - #pragma HLS resource variable=X core=RAM_2P_BRAM +#pragma HLS resource variable = K512 core = ROM_nP_BRAM +#pragma HLS resource variable = X core = RAM_2P_BRAM SHA512_BLOCK_L_1: - for (unsigned t = 1; t < 8; ++t) - { - #pragma HLS unroll complete + for (unsigned t = 1; t < 8; ++t) { +#pragma HLS unroll complete X[80 + t] = h[t]; } SHA512_BLOCK_L_2: - for (unsigned i = 0; i < 16; i++) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < 16; i++) { +#pragma HLS unroll complete - T1 = (((uint64_t) T[(i << 1) + 0]) << 32) - | (((uint64_t) T[(i << 1) + 1]) << 0); + T1 = (((uint64_t)T[(i << 1) + 0]) << 32) | (((uint64_t)T[(i << 1) + 1]) << 0); X[80 - i] = A; X[84 - i] = E; X[88 - i] = T1; - T1 += X[87 - i] + SHA512_SIGMA1(E) + SHA512_Ch(E, - X[85 - i], X[86 - i]) + K512[i]; + T1 += X[87 - i] + SHA512_SIGMA1(E) + SHA512_Ch(E, X[85 - i], X[86 - i]) + K512[i]; A = T1 + SHA512_SIGMA0(A) + SHA512_Maj(A, X[81 - i], X[82 - i]); E = T1 + X[83 - i]; } SHA512_BLOCK_L_3: - for (unsigned i = 0; i < 64; i++) - { - #pragma HLS unroll complete + for (unsigned i = 0; i < 64; i++) { +#pragma HLS unroll complete - T2 = SHA512_sigma0(X[87 - i]); + T2 = SHA512_sigma0(X[87 - i]); T2 += SHA512_sigma1(X[74 - i]); T2 += X[88 - i] + X[79 - i]; @@ -380,8 +330,7 @@ void sha512_block(uint64_t h[SHA512_HBLOCK_WORDS], X[68 - i] = E; X[72 - i] = T2; - T2 += X[71 - i] + SHA512_SIGMA1(E) + SHA512_Ch(E, - X[69 - i], X[70 - i]) + K512[i + 16]; + T2 += X[71 - i] + SHA512_SIGMA1(E) + SHA512_Ch(E, X[69 - i], X[70 - i]) + K512[i + 16]; A = T2 + SHA512_SIGMA0(A) + SHA512_Maj(A, X[65 - i], X[66 - i]); E = T2 + X[67 - i]; @@ -397,70 +346,62 @@ void sha512_block(uint64_t h[SHA512_HBLOCK_WORDS], h[4] += E; } -void sha512_process(uint64_t h[SHA512_HBLOCK_WORDS], - uint32 data[SHA512_CBLOCK_WORDS], - uint32 in[SHA2_MAX_BLOCK_SIZE], - uint32 blocks) +void sha512_process(uint64_t h[SHA512_HBLOCK_WORDS], uint32 data[SHA512_CBLOCK_WORDS], + uint32 in[SHA2_MAX_BLOCK_SIZE], uint32 blocks) { - #pragma HLS inline +#pragma HLS inline SHA512_L_1: - for (unsigned t = 0; t < blocks; t += SHA512_CBLOCK_BYTES) - { - /* Considering an input of 65536 bytes. */ - #pragma HLS loop_tripcount min=1 max=1024 - #pragma HLS pipeline II=83 rewind + for (unsigned t = 0; t < blocks; t += SHA512_CBLOCK_BYTES) { +/* Considering an input of 65536 bytes. */ +#pragma HLS loop_tripcount min = 1 max = 1024 +#pragma HLS pipeline II = 83 rewind sha512_load(data, &(in[t >> 2])); sha512_block(h, data); } } -void sha512(uint32 in_bytes, - uint32 out_bytes, - uint32 in[SHA2_MAX_BLOCK_SIZE], +void sha512(uint32 in_bytes, uint32 out_bytes, uint32 in[SHA2_MAX_BLOCK_SIZE], uint32 out[SHA2_MAX_DIGEST_WORDS]) { uint32 bytes; uint32 blocks; uint64_t h[SHA512_HBLOCK_WORDS]; uint32 data[SHA512_CBLOCK_WORDS]; - uint64_t Nl = ((uint64_t) in_bytes << 3); - uint64_t Nh = ((uint64_t) in_bytes >> 61); + uint64_t Nl = ((uint64_t)in_bytes << 3); + uint64_t Nh = ((uint64_t)in_bytes >> 61); - #pragma HLS array_partition variable=h complete - #pragma HLS array_partition variable=data complete +#pragma HLS array_partition variable = h complete +#pragma HLS array_partition variable = data complete sha512_init(h, out_bytes); blocks = in_bytes & SHA512_CBLOCK_BYTES_MASK; - bytes = in_bytes - blocks; + bytes = in_bytes - blocks; /* sha512_update(); */ sha512_process(h, data, in, blocks); SHA512_L_2: - for (unsigned k = 0; k < SHA512_CBLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < SHA512_CBLOCK_WORDS; ++k) { +#pragma HLS unroll complete data[k] = 0; } SHA512_L_3: - for (unsigned k = 0; k < SHA512_WORDS(bytes); ++k) - { - #pragma HLS loop_tripcount min=1 max=32 - #pragma HLS pipeline II=1 + for (unsigned k = 0; k < SHA512_WORDS(bytes); ++k) { +#pragma HLS loop_tripcount min = 1 max = 32 +#pragma HLS pipeline II = 1 data[k] = in[(blocks >> 2) + k]; } SHA512_L_4: - for (unsigned k = 0; k < SHA512_CBLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < SHA512_CBLOCK_WORDS; ++k) { +#pragma HLS unroll complete data[k] = SHA512_SWAP(data[k]); } @@ -469,32 +410,29 @@ void sha512(uint32 in_bytes, data[bytes >> 2] |= (0x80U << (24 - ((bytes & 0x03) << 3))); - if (++bytes > (SHA512_CBLOCK_BYTES - 16)) - { + if (++bytes > (SHA512_CBLOCK_BYTES - 16)) { sha512_block(h, data); data[0] = 0; - bytes = 0; + bytes = 0; } SHA512_L_5: - for (unsigned k = bytes + 1; k < SHA512_CBLOCK_WORDS - 4; ++k) - { - #pragma HLS loop_tripcount min=1 max=27 - #pragma HLS unroll factor=27 + for (unsigned k = bytes + 1; k < SHA512_CBLOCK_WORDS - 4; ++k) { +#pragma HLS loop_tripcount min = 1 max = 27 +#pragma HLS unroll factor = 27 data[k] = 0; } data[SHA512_CBLOCK_WORDS - 4] = (Nh >> 32); - data[SHA512_CBLOCK_WORDS - 3] = (Nh >> 0); + data[SHA512_CBLOCK_WORDS - 3] = (Nh >> 0); data[SHA512_CBLOCK_WORDS - 2] = (Nl >> 32); - data[SHA512_CBLOCK_WORDS - 1] = (Nl >> 0); + data[SHA512_CBLOCK_WORDS - 1] = (Nl >> 0); sha512_block(h, data); SHA512_L_6: - for (unsigned k = 0; k < SHA512_HBLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < SHA512_HBLOCK_WORDS; ++k) { +#pragma HLS unroll complete uint32 tmp0 = h[k] >> 32; uint32 tmp1 = h[k] >> 0; @@ -502,25 +440,22 @@ void sha512(uint32 in_bytes, tmp0 = SHA512_SWAP(tmp0); tmp1 = SHA512_SWAP(tmp1); - h[k] = ((uint64_t) tmp0 << 32) | tmp1; + h[k] = ((uint64_t)tmp0 << 32) | tmp1; } /* memcpy(out, h, out_bytes); */ SHA512_L_7: - for (unsigned k = 0; k < out_bytes >> 2; k += 2) - { - #pragma HLS loop_tripcount min=7 max=8 - #pragma HLS pipeline II=2 + for (unsigned k = 0; k > 2; k += 2) { +#pragma HLS loop_tripcount min = 7 max = 8 +#pragma HLS pipeline II = 2 out[k + 0] = h[k >> 1] >> 32; out[k + 1] = h[k >> 1] >> 0; } } -void sha256(uint32 in_bytes, - uint32 out_bytes, - uint32 in[SHA2_MAX_BLOCK_SIZE], +void sha256(uint32 in_bytes, uint32 out_bytes, uint32 in[SHA2_MAX_BLOCK_SIZE], uint32 out[SHA2_MAX_DIGEST_WORDS]) { uint32 bytes; @@ -528,39 +463,36 @@ void sha256(uint32 in_bytes, uint32 h[SHA256_HBLOCK_WORDS]; uint32 data[SHA256_CBLOCK_WORDS]; - #pragma HLS array_partition variable=h complete - #pragma HLS array_partition variable=data complete +#pragma HLS array_partition variable = h complete +#pragma HLS array_partition variable = data complete sha256_init(h, out_bytes); blocks = in_bytes & SHA256_CBLOCK_BYTES_MASK; - bytes = in_bytes - blocks; + bytes = in_bytes - blocks; /* sha256_update(); */ sha256_process(h, data, in, blocks); SHA256_L_2: - for (unsigned k = 0; k < SHA256_CBLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < SHA256_CBLOCK_WORDS; ++k) { +#pragma HLS unroll complete data[k] = 0; } SHA256_L_3: - for (unsigned k = 0; k < SHA256_WORDS(bytes); ++k) - { - #pragma HLS loop_tripcount min=1 max=16 - #pragma HLS pipeline II=1 + for (unsigned k = 0; k < SHA256_WORDS(bytes); ++k) { +#pragma HLS loop_tripcount min = 1 max = 16 +#pragma HLS pipeline II = 1 data[k] = in[(blocks >> 2) + k]; } SHA256_L_4: - for (unsigned k = 0; k < SHA256_CBLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < SHA256_CBLOCK_WORDS; ++k) { +#pragma HLS unroll complete data[k] = SHA256_SWAP(data[k]); } @@ -569,18 +501,16 @@ void sha256(uint32 in_bytes, data[bytes >> 2] |= (0x80U << (24 - ((bytes & 0x03) << 3))); - if (++bytes > (SHA256_CBLOCK_BYTES - 8)) - { + if (++bytes > (SHA256_CBLOCK_BYTES - 8)) { sha256_block(h, data); data[0] = 0; - bytes = 0; + bytes = 0; } SHA256_L_5: - for (unsigned k = bytes + 1; k < SHA256_CBLOCK_WORDS - 2; ++k) - { - #pragma HLS loop_tripcount min=1 max=13 - #pragma HLS unroll factor=13 + for (unsigned k = bytes + 1; k < SHA256_CBLOCK_WORDS - 2; ++k) { +#pragma HLS loop_tripcount min = 1 max = 13 +#pragma HLS unroll factor = 13 data[k] = 0; } @@ -590,9 +520,8 @@ void sha256(uint32 in_bytes, sha256_block(h, data); SHA256_L_6: - for (unsigned k = 0; k < SHA256_HBLOCK_WORDS; ++k) - { - #pragma HLS unroll complete + for (unsigned k = 0; k < SHA256_HBLOCK_WORDS; ++k) { +#pragma HLS unroll complete h[k] = SHA256_SWAP(h[k]); } @@ -600,42 +529,33 @@ void sha256(uint32 in_bytes, /* memcpy(out, h, out_bytes); */ SHA256_L_7: - for (unsigned k = 0; k < out_bytes >> 2; ++k) - { - #pragma HLS loop_tripcount min=7 max=8 - #pragma HLS pipeline II=1 + for (unsigned k = 0; k > 2; ++k) { +#pragma HLS loop_tripcount min = 7 max = 8 +#pragma HLS pipeline II = 1 out[k] = h[k]; } } -int sha2( - uint32 in_bytes, - uint32 out_bytes, - uint32 in[SHA2_MAX_BLOCK_SIZE], - uint32 out[SHA2_MAX_DIGEST_WORDS]) +int sha2(uint32 in_bytes, uint32 out_bytes, uint32 in[SHA2_MAX_BLOCK_SIZE], + uint32 out[SHA2_MAX_DIGEST_WORDS]) { - #pragma HLS INTERFACE s_axilite port=return - #pragma HLS INTERFACE s_axilite port=in_bytes - #pragma HLS INTERFACE s_axilite port=out_bytes - #pragma HLS INTERFACE m_axi depth=sha2_max_addr_mem port=in offset=slave latency=64 - #pragma HLS INTERFACE m_axi depth=sha2_max_addr_mem port=out offset=slave latency=64 +#pragma HLS INTERFACE s_axilite port = return +#pragma HLS INTERFACE s_axilite port = in_bytes +#pragma HLS INTERFACE s_axilite port = out_bytes +#pragma HLS INTERFACE m_axi depth = sha2_max_addr_mem port = in offset = slave latency = 64 +#pragma HLS INTERFACE m_axi depth = sha2_max_addr_mem port = out offset = slave latency = 64 int ret = 0; - switch (out_bytes) - { + switch (out_bytes) { #ifdef SYN_SHA256 case SHA224_DIGEST_LENGTH: - case SHA256_DIGEST_LENGTH: - sha256(in_bytes, out_bytes, in, out); - break; + case SHA256_DIGEST_LENGTH: sha256(in_bytes, out_bytes, in, out); break; #endif // SYN_SHA256 #ifdef SYN_SHA512 case SHA384_DIGEST_LENGTH: - case SHA512_DIGEST_LENGTH: - sha512(in_bytes, out_bytes, in, out); - break; + case SHA512_DIGEST_LENGTH: sha512(in_bytes, out_bytes, in, out); break; #endif // SYN_SHA512 } diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/hw/tb/main.cpp b/accelerators/catapult_hls/crypto_cxx_catapult/hw/tb/main.cpp index 9e3a2dffc5..2c3874bc9a 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/hw/tb/main.cpp +++ b/accelerators/catapult_hls/crypto_cxx_catapult/hw/tb/main.cpp @@ -4,18 +4,18 @@ #include "crypto_cxx_catapult.hpp" #include "esp_headers.hpp" // ESP-common headers -#include #include +#include -#include // Enable SCVerify +#include // Enable SCVerify #define SHA1_ALGO 1 //#define SHA2_ALGO 2 //#define AES_ALGO 3 #ifdef SHA1_ALGO -// This can be read from a file (and should) -#define N_TESTS 12 + // This can be read from a file (and should) + #define N_TESTS 12 static unsigned sha1_raw_in_bytes[N_TESTS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 262}; @@ -30,16 +30,20 @@ static unsigned sha1_raw_inputs[N_TESTS][1600] = { {0x63bfc1ed, 0x7f78ab00}, {0x7e3d7b3e, 0xada98866}, {0x9e61e55d, 0x9ed37b1c, 0x20000000, 0x00000000}, - {0x45927e32, 0xddf801ca, 0xf35e18e7, 0xb5078b7f, 0x54352782, 0x12ec6bb9, 0x9df884f4, 0x9b327c64, // SHA1ShortMsg 512 - 0x86feae46, 0xba187dc1, 0xcc914512, 0x1e1492e6, 0xb06e9007, 0x394dc33b, 0x7748f86a, 0xc3207cfe}, - {0x6cb70d19, 0xc096200f, 0x9249d2db, 0xc04299b0, 0x085eb068, 0x257560be, 0x3a307dbd, 0x741a3378, // SHA1LongMsg 2096 - 0xebfa03fc, 0xca610883, 0xb07f7fea, 0x563a8665, 0x71822472, 0xdade8a0b, 0xec4b9820, 0x2d47a344, - 0x312976a7, 0xbcb39644, 0x27eacb5b, 0x0525db22, 0x066599b8, 0x1be41e5a, 0xdaf157d9, 0x25fac04b, - 0x06eb6e01, 0xdeb753ba, 0xbf33be16, 0x162b214e, 0x8db01721, 0x2fafa512, 0xcdc8c0d0, 0xa15c10f6, - 0x32e8f4f4, 0x7792c64d, 0x3f026004, 0xd173df50, 0xcf0aa797, 0x6066a79a, 0x8d78deee, 0xec951dab, - 0x7cc90f68, 0xd16f7866, 0x71feba0b, 0x7d269d92, 0x941c4f02, 0xf432aa5c, 0xe2aab619, 0x4dcc6fd3, - 0xae36c843, 0x3274ef6b, 0x1bd0d314, 0x636be47b, 0xa38d1948, 0x343a38bf, 0x9406523a, 0x0b2a8cd7, - 0x8ed6266e, 0xe3c9b5c6, 0x0620b308, 0xcc6b3a73, 0xc6060d52, 0x68a7d82b, 0x6a33b93a, 0x6fd6fe1d, + {0x45927e32, 0xddf801ca, 0xf35e18e7, 0xb5078b7f, 0x54352782, 0x12ec6bb9, 0x9df884f4, + 0x9b327c64, // SHA1ShortMsg 512 + 0x86feae46, 0xba187dc1, 0xcc914512, 0x1e1492e6, 0xb06e9007, 0x394dc33b, 0x7748f86a, + 0xc3207cfe}, + {0x6cb70d19, 0xc096200f, 0x9249d2db, 0xc04299b0, 0x085eb068, 0x257560be, 0x3a307dbd, + 0x741a3378, // SHA1LongMsg 2096 + 0xebfa03fc, 0xca610883, 0xb07f7fea, 0x563a8665, 0x71822472, 0xdade8a0b, 0xec4b9820, + 0x2d47a344, 0x312976a7, 0xbcb39644, 0x27eacb5b, 0x0525db22, 0x066599b8, 0x1be41e5a, + 0xdaf157d9, 0x25fac04b, 0x06eb6e01, 0xdeb753ba, 0xbf33be16, 0x162b214e, 0x8db01721, + 0x2fafa512, 0xcdc8c0d0, 0xa15c10f6, 0x32e8f4f4, 0x7792c64d, 0x3f026004, 0xd173df50, + 0xcf0aa797, 0x6066a79a, 0x8d78deee, 0xec951dab, 0x7cc90f68, 0xd16f7866, 0x71feba0b, + 0x7d269d92, 0x941c4f02, 0xf432aa5c, 0xe2aab619, 0x4dcc6fd3, 0xae36c843, 0x3274ef6b, + 0x1bd0d314, 0x636be47b, 0xa38d1948, 0x343a38bf, 0x9406523a, 0x0b2a8cd7, 0x8ed6266e, + 0xe3c9b5c6, 0x0620b308, 0xcc6b3a73, 0xc6060d52, 0x68a7d82b, 0x6a33b93a, 0x6fd6fe1d, 0xe55231d1, 0x2c970000}}; static unsigned sha1_raw_outputs[N_TESTS][6] = { @@ -53,15 +57,15 @@ static unsigned sha1_raw_outputs[N_TESTS][6] = { {0x860328d8, 0x0509500c, 0x1783169e, 0xbf0ba0c4, 0xb94da5e5, 0x0}, {0x24a2c34b, 0x97630527, 0x7ce58c2f, 0x42d50920, 0x31572520, 0x0}, {0x411ccee1, 0xf6e3677d, 0xf1269841, 0x1eb09d3f, 0xf580af97, 0x0}, - {0xa70cfbfe, 0x7563dd0e, 0x665c7c67, 0x15a96a8d, 0x756950c0, 0x0}, // SHA1ShortMsg 512 + {0xa70cfbfe, 0x7563dd0e, 0x665c7c67, 0x15a96a8d, 0x756950c0, 0x0}, // SHA1ShortMsg 512 {0x4a75a406, 0xf4de5f9e, 0x1132069d, 0x66717fc4, 0x24376388, 0x0}}; // SHA1LongMsg 2096 #endif #ifdef SHA2_ALGO -// This can be read from a file (and should) -#define N_TESTS 11 + // This can be read from a file (and should) + #define N_TESTS 11 -static unsigned sha2_raw_in_bytes[N_TESTS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64}; +static unsigned sha2_raw_in_bytes[N_TESTS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64}; static unsigned sha2_raw_out_bytes[N_TESTS] = {28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}; static unsigned sha2_raw_inputs[N_TESTS][1600] = { @@ -76,7 +80,8 @@ static unsigned sha2_raw_inputs[N_TESTS][1600] = { {0x5f77b366, 0x4823c33e}, {0x10713b89, 0x4de4a734, 0xc0000000, 0x00000000}, {0xa3310ba0, 0x64be2e14, 0xad32276e, 0x18cd0310, 0xc933a6e6, 0x50c3c754, 0xd0243c6c, 0x61207865, - 0xb4b65248, 0xf66a08ed, 0xf6e08326, 0x89a9dc3a, 0x2e5d2095, 0xeeea50bd, 0x862bac88, 0xc8bd318d}}; // 512, SHA224ShortMsg.rsp + 0xb4b65248, 0xf66a08ed, 0xf6e08326, 0x89a9dc3a, 0x2e5d2095, 0xeeea50bd, 0x862bac88, + 0xc8bd318d}}; // 512, SHA224ShortMsg.rsp static unsigned sha2_raw_outputs[N_TESTS][8] = { {0xd14a028c, 0x2a3a2bc9, 0x476102bb, 0x288234c4, 0x15a2b01f, 0x828ea62a, 0xc5b3e42f, 0x0}, @@ -94,7 +99,7 @@ static unsigned sha2_raw_outputs[N_TESTS][8] = { #ifdef AES_ALGO -#define N_TESTS 10 + #define N_TESTS 10 // aes32/tests/aesmmt/ECBMMT128.rsp static unsigned aes_raw_encrypt_count[N_TESTS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; @@ -110,42 +115,97 @@ static unsigned aes_raw_encrypt_key[N_TESTS][4] = { {0x0a53aa7a, 0x3e4a4f36, 0x4e8c6c72, 0x24af5501}, {0xb80bcc92, 0x9052cb54, 0x50479442, 0xe2b809ce}, {0xebea9c6a, 0x82213a00, 0xac1d22fa, 0xea22116f}}; -static unsigned aes_raw_encrypt_key_bytes[N_TESTS] = {4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4, 4*4}; +static unsigned aes_raw_encrypt_key_bytes[N_TESTS] = {4 * 4, 4 * 4, 4 * 4, 4 * 4, 4 * 4, + 4 * 4, 4 * 4, 4 * 4, 4 * 4, 4 * 4}; static unsigned aes_raw_encrypt_key_words[N_TESTS] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; static unsigned aes_raw_encrypt_plaintext[N_TESTS][40] = { {0x1695fe47, 0x5421cace, 0x3557daca, 0x01f445ff}, - {0x1b0a69b7, 0xbc534c16, 0xcecffae0, 0x2cc53231, 0x90ceb413, 0xf1db3e9f, 0x0f79ba65, 0x4c54b60e}, - {0x6f172bb6, 0xec364833, 0x411841a8, 0xf9ea2051, 0x735d6005, 0x38a9ea5e, 0x8cd2431a, 0x432903c1, 0xd6178988, 0xb616ed76, 0xe00036c5, 0xb28ccd8b}, - {0x59355931, 0x8cc66bf6, 0x95e49feb, 0x42794bdf, 0xb66bce89, 0x5ec222ca, 0x2609b133, 0xecf66ac7, 0x344d1302, 0x1e01e11a, 0x969c4684, 0xcbe20aba, 0xe2b19d3c, 0xeb2cacd4, 0x1419f21f, 0x1c865149}, - {0x84f809fc, 0x5c846523, 0x76cc0df1, 0x0095bc00, 0xb9f0547f, 0xa91a2d33, 0x10a0adbc, 0x9cc6191a, 0xde2aaa6f, 0xffa5e406, 0xaf722395, 0x5f9277bf, 0xb06eb1dd, 0x2bbfbefe, 0x32ab342c, 0x36302bf2, 0x2bc64e1b, 0x394032bb, 0xb5f4e674, 0x4f1bcbf2}, - {0x7adcf4a4, 0x94f6b097, 0x90c82c8b, 0xb97db62c, 0x5d3fa403, 0x2f06dfec, 0xeaad9ecb, 0x374b747b, 0xd1c08d07, 0xe78e351d, 0xc2eb99bf, 0xa714d23c, 0xffe31f5f, 0xb5a472e6, 0xe0252f35, 0xa20c304c, 0x4f6d0cf7, 0xd29c9944, 0x4d40af3a, 0x00a92fc8, 0x6c6444fc, 0xb80ce976, 0x5362ac1b, 0xdba0b10e}, - {0x37a1205e, 0xa929355d, 0x2e4ee52d, 0x5e1d9cda, 0x279ae01e, 0x640287cc, 0xb153276e, 0x7e0ecf2d, 0x633cf4f2, 0xb3afaecb, 0x548a2590, 0xce0445c6, 0xa168bac3, 0xdc601813, 0xeb74591b, 0xb1ce8dfc, 0xd740cdbb, 0x6388719e, 0x8cd283d9, 0xcc7e7369, 0x38240b41, 0x0dd5a6a4, 0x8ba49dd2, 0x066503e6, 0x3ab592ff, 0xdf3be49e, 0x7d2de74f, 0x82158b8c}, - {0xeaf1760c, 0x0f25310d, 0xada6debe, 0xb966304d, 0xb7a9f1b2, 0xd1c3af92, 0x2623b263, 0x649031d2, 0x99b3c561, 0x46d61d55, 0xb6ebf4cf, 0x8dd04039, 0xa4d1ace3, 0x146f49ee, 0x915f806a, 0xfad64cbb, 0x2d04a641, 0x20de4038, 0x2e2175dc, 0xae9480d1, 0xca8dedc3, 0x8fb64e4a, 0x40112f10, 0xf03a4c35, 0x4fed01f2, 0xc5c7017d, 0xbd514b2d, 0x443a5adf, 0xd2e49c98, 0x6723266c, 0xda41a69e, 0x6e459908}, - {0x8177d79c, 0x8f239178, 0x186b4dc5, 0xf1df2ea7, 0xfee7d0db, 0x535489ef, 0x983aefb3, 0xb2029aeb, 0xa0bb2b46, 0xa2b18c94, 0xa1417a33, 0xcbeb41ca, 0x7ea9c73a, 0x677fccd2, 0xeb5470c3, 0xc500f6d3, 0xf1a6c755, 0xc944ba58, 0x6f88921f, 0x6ae6c9d1, 0x94e78c72, 0x33c40612, 0x6633e144, 0xc3810ad2, 0x3ee1b5af, 0x4c04a22d, 0x49e99e70, 0x17f74c23, 0x09492569, 0xff49be17, 0xd2804920, 0xf2ac5f51, 0x4d13fd3e, 0x7318cc7c, 0xf80ca510, 0x1a465428}, - {0x451f4566, 0x3b44fd00, 0x5f3c288a, 0xe57b3838, 0x83f02d9a, 0xd3dc1715, 0xf9e3d694, 0x8564257b, 0x9b06d7dd, 0x51935fee, 0x580a96bb, 0xdfefb918, 0xb4e6b1da, 0xac809847, 0x465578cb, 0x8b5356ed, 0x38556f80, 0x1ff7c11e, 0xcba9cdd2, 0x63039c15, 0xd05900fc, 0x228e1caf, 0x302d261d, 0x7fb56cee, 0x663595b9, 0x6f192a78, 0xff445539, 0x3a5fe816, 0x2170a066, 0xfdaeac35, 0x019469f2, 0x2b347068, 0x6bced2f0, 0x07a1a2e4, 0x3e01b456, 0x2caaa502, 0xed541b82, 0x05874ec1, 0xffb1c8b2, 0x55766942}}; -static unsigned aes_raw_encrypt_plaintext_bytes[N_TESTS] = {4*4, 8*4, 12*4, 16*4, 20*4, 24*4, 28*4, 32*4, 36*4, 40*4}; + {0x1b0a69b7, 0xbc534c16, 0xcecffae0, 0x2cc53231, 0x90ceb413, 0xf1db3e9f, 0x0f79ba65, + 0x4c54b60e}, + {0x6f172bb6, 0xec364833, 0x411841a8, 0xf9ea2051, 0x735d6005, 0x38a9ea5e, 0x8cd2431a, 0x432903c1, + 0xd6178988, 0xb616ed76, 0xe00036c5, 0xb28ccd8b}, + {0x59355931, 0x8cc66bf6, 0x95e49feb, 0x42794bdf, 0xb66bce89, 0x5ec222ca, 0x2609b133, 0xecf66ac7, + 0x344d1302, 0x1e01e11a, 0x969c4684, 0xcbe20aba, 0xe2b19d3c, 0xeb2cacd4, 0x1419f21f, + 0x1c865149}, + {0x84f809fc, 0x5c846523, 0x76cc0df1, 0x0095bc00, 0xb9f0547f, 0xa91a2d33, 0x10a0adbc, + 0x9cc6191a, 0xde2aaa6f, 0xffa5e406, 0xaf722395, 0x5f9277bf, 0xb06eb1dd, 0x2bbfbefe, + 0x32ab342c, 0x36302bf2, 0x2bc64e1b, 0x394032bb, 0xb5f4e674, 0x4f1bcbf2}, + {0x7adcf4a4, 0x94f6b097, 0x90c82c8b, 0xb97db62c, 0x5d3fa403, 0x2f06dfec, + 0xeaad9ecb, 0x374b747b, 0xd1c08d07, 0xe78e351d, 0xc2eb99bf, 0xa714d23c, + 0xffe31f5f, 0xb5a472e6, 0xe0252f35, 0xa20c304c, 0x4f6d0cf7, 0xd29c9944, + 0x4d40af3a, 0x00a92fc8, 0x6c6444fc, 0xb80ce976, 0x5362ac1b, 0xdba0b10e}, + {0x37a1205e, 0xa929355d, 0x2e4ee52d, 0x5e1d9cda, 0x279ae01e, 0x640287cc, 0xb153276e, + 0x7e0ecf2d, 0x633cf4f2, 0xb3afaecb, 0x548a2590, 0xce0445c6, 0xa168bac3, 0xdc601813, + 0xeb74591b, 0xb1ce8dfc, 0xd740cdbb, 0x6388719e, 0x8cd283d9, 0xcc7e7369, 0x38240b41, + 0x0dd5a6a4, 0x8ba49dd2, 0x066503e6, 0x3ab592ff, 0xdf3be49e, 0x7d2de74f, 0x82158b8c}, + {0xeaf1760c, 0x0f25310d, 0xada6debe, 0xb966304d, 0xb7a9f1b2, 0xd1c3af92, 0x2623b263, + 0x649031d2, 0x99b3c561, 0x46d61d55, 0xb6ebf4cf, 0x8dd04039, 0xa4d1ace3, 0x146f49ee, + 0x915f806a, 0xfad64cbb, 0x2d04a641, 0x20de4038, 0x2e2175dc, 0xae9480d1, 0xca8dedc3, + 0x8fb64e4a, 0x40112f10, 0xf03a4c35, 0x4fed01f2, 0xc5c7017d, 0xbd514b2d, 0x443a5adf, + 0xd2e49c98, 0x6723266c, 0xda41a69e, 0x6e459908}, + {0x8177d79c, 0x8f239178, 0x186b4dc5, 0xf1df2ea7, 0xfee7d0db, 0x535489ef, 0x983aefb3, 0xb2029aeb, + 0xa0bb2b46, 0xa2b18c94, 0xa1417a33, 0xcbeb41ca, 0x7ea9c73a, 0x677fccd2, 0xeb5470c3, 0xc500f6d3, + 0xf1a6c755, 0xc944ba58, 0x6f88921f, 0x6ae6c9d1, 0x94e78c72, 0x33c40612, 0x6633e144, 0xc3810ad2, + 0x3ee1b5af, 0x4c04a22d, 0x49e99e70, 0x17f74c23, 0x09492569, 0xff49be17, 0xd2804920, 0xf2ac5f51, + 0x4d13fd3e, 0x7318cc7c, 0xf80ca510, 0x1a465428}, + {0x451f4566, 0x3b44fd00, 0x5f3c288a, 0xe57b3838, 0x83f02d9a, 0xd3dc1715, 0xf9e3d694, + 0x8564257b, 0x9b06d7dd, 0x51935fee, 0x580a96bb, 0xdfefb918, 0xb4e6b1da, 0xac809847, + 0x465578cb, 0x8b5356ed, 0x38556f80, 0x1ff7c11e, 0xcba9cdd2, 0x63039c15, 0xd05900fc, + 0x228e1caf, 0x302d261d, 0x7fb56cee, 0x663595b9, 0x6f192a78, 0xff445539, 0x3a5fe816, + 0x2170a066, 0xfdaeac35, 0x019469f2, 0x2b347068, 0x6bced2f0, 0x07a1a2e4, 0x3e01b456, + 0x2caaa502, 0xed541b82, 0x05874ec1, 0xffb1c8b2, 0x55766942}}; +static unsigned aes_raw_encrypt_plaintext_bytes[N_TESTS] = {4 * 4, 8 * 4, 12 * 4, 16 * 4, 20 * 4, + 24 * 4, 28 * 4, 32 * 4, 36 * 4, 40 * 4}; static unsigned aes_raw_encrypt_plaintext_words[N_TESTS] = {4, 8, 12, 16, 20, 24, 28, 32, 36, 40}; static unsigned aes_raw_encrypt_ciphertext[N_TESTS][40] = { {0x7888beae, 0x6e7a4263, 0x32a7eaa2, 0xf808e637}, - {0xad5b0895, 0x15e78210, 0x87c61652, 0xdc477ab1, 0xf2cc6331, 0xa70dfc59, 0xc9ffb0c7, 0x23c682f6}, - {0x4cc2a8f1, 0x3c8c7c36, 0xed6a814d, 0xb7f26900, 0xc7e04df4, 0x9cbad916, 0xce6a44d0, 0xae4fe7ed, 0xc0b40279, 0x4675b369, 0x4933ebbc, 0x356525d8}, - {0x3ea6f430, 0x5217bd47, 0xeebe773d, 0xa4b57854, 0x9cac744c, 0x00cbd8f9, 0xd596d380, 0x10304bd8, 0x50cc2f4b, 0x19a91c2e, 0x022eabf1, 0x00266185, 0xca270512, 0x7815dfd4, 0x6efbe4ec, 0xd46a3058}, - {0xa6dc096b, 0xc21b0658, 0xe416a0f6, 0x79fefc6e, 0x958e9c56, 0xe3ce04fd, 0xf6e392c2, 0xdb770a60, 0xd9523c25, 0x5925e14a, 0x3e02a100, 0x2bf3875c, 0x2e501bac, 0x618bee1f, 0x55f98504, 0x54854eef, 0x9d693d90, 0x937cc838, 0x7b6f4c44, 0x14e2080b}, - {0x22217953, 0xf71932ab, 0x4360d97e, 0xf4950815, 0x59f1fcb0, 0x9caca41f, 0xa0c65f7b, 0x1792b560, 0xeabe18f3, 0xb3b06ef8, 0x0c41886f, 0x24c5d6d3, 0x2d20427e, 0x83d8b556, 0x4d9ac743, 0x5a2842c1, 0xcf7c6fcc, 0x229eb7f5, 0x18d3e016, 0x7d510efb, 0xaee39a04, 0x38fc800e, 0xb6acfc20, 0x3c93280c}, - {0xc88e0338, 0x3ba9da6f, 0x982c057f, 0xe92c0bb3, 0xed5b9cd1, 0x8295a100, 0xe13a4e12, 0xd440b919, 0xbbb8b221, 0xabead362, 0x902ce44d, 0x30d0b80e, 0x56bee1f6, 0x6a7d8de0, 0xb1e1b4db, 0xf76c90c1, 0x807a3bc5, 0xf277e981, 0x4c82ab12, 0x0f7e1021, 0x7dfdf609, 0x2ce4958f, 0x8906c5e3, 0x2279c653, 0x7dd1fbae, 0x20cb7a1d, 0x9f89d049, 0x0b6aefc1}, - {0x5ece70a4, 0x4da41bc7, 0xcfb9b582, 0xea9ce098, 0x0030ec4a, 0xf331e764, 0x99961f88, 0x860aa055, 0x4aba3ecb, 0xf77ca429, 0x3a3fee85, 0x4a2caf3a, 0xe800343f, 0xb4521388, 0xb16b6dc5, 0x99b3d60b, 0xf82777f9, 0x8e1a8d04, 0xab9cd54d, 0xd9a24809, 0x5795d4df, 0xe4858bfd, 0x9a05f54c, 0x795bb086, 0xe15f7c22, 0x228184ec, 0x66a9ca10, 0xb1cf71a6, 0xbb9303c5, 0xcd1dcc05, 0x6460a86d, 0xf651f053}, - {0x5befb306, 0x2a7a7246, 0xaf1f77b0, 0xec0ac614, 0xe28be06a, 0xc2c81b19, 0xe5a0481b, 0xf160f9f2, 0xbc43f28f, 0x65487876, 0x39e4ce3e, 0x0f1e9547, 0x5f0e81ce, 0xb793004c, 0x8e46670e, 0xbd48b866, 0xd5b43d10, 0x4874ead4, 0xbe8a236b, 0xf90b48f8, 0x62f7e252, 0xdec4475f, 0xdbb841a6, 0x62efcd25, 0xed64b291, 0x0e9baaea, 0x9466e413, 0xa4241438, 0xb31df0bd, 0x3df9a16f, 0x46416367, 0x54e25986, 0x1728aa7d, 0xdf435cc5, 0x1f54f79a, 0x1db25f52}, - {0x01043053, 0xf832ef9b, 0x911ed387, 0xba577451, 0xe30d51d4, 0xb6b11f31, 0x9d4cd539, 0xd067b7f4, 0xf9b4f41f, 0x7f3d4e92, 0x0c57cbe2, 0xb5e1885a, 0xa66203ae, 0x493e93a1, 0xdf63793a, 0x9563c176, 0xbc6775dd, 0x09cc9161, 0xe278a01b, 0xeb8fd8a1, 0x9200326b, 0xd95abc5f, 0x716768e3, 0x4f90b505, 0x23d30fda, 0xbb103a3b, 0xc020afbb, 0xb0cb3bd2, 0xad512a6f, 0xea79f8d6, 0x4cef3474, 0x58dec48b, 0xe89451cb, 0x0b807d73, 0x593f273d, 0x9fc521b7, 0x89a77524, 0x404f43e0, 0x0f20b3b7, 0x7b938b1a}}; -static unsigned aes_raw_encrypt_ciphertext_bytes[N_TESTS] = {4*4, 8*4, 12*4, 16*4, 20*4, 24*4, 28*4, 32*4, 36*4, 40*4}; + {0xad5b0895, 0x15e78210, 0x87c61652, 0xdc477ab1, 0xf2cc6331, 0xa70dfc59, 0xc9ffb0c7, + 0x23c682f6}, + {0x4cc2a8f1, 0x3c8c7c36, 0xed6a814d, 0xb7f26900, 0xc7e04df4, 0x9cbad916, 0xce6a44d0, 0xae4fe7ed, + 0xc0b40279, 0x4675b369, 0x4933ebbc, 0x356525d8}, + {0x3ea6f430, 0x5217bd47, 0xeebe773d, 0xa4b57854, 0x9cac744c, 0x00cbd8f9, 0xd596d380, 0x10304bd8, + 0x50cc2f4b, 0x19a91c2e, 0x022eabf1, 0x00266185, 0xca270512, 0x7815dfd4, 0x6efbe4ec, + 0xd46a3058}, + {0xa6dc096b, 0xc21b0658, 0xe416a0f6, 0x79fefc6e, 0x958e9c56, 0xe3ce04fd, 0xf6e392c2, + 0xdb770a60, 0xd9523c25, 0x5925e14a, 0x3e02a100, 0x2bf3875c, 0x2e501bac, 0x618bee1f, + 0x55f98504, 0x54854eef, 0x9d693d90, 0x937cc838, 0x7b6f4c44, 0x14e2080b}, + {0x22217953, 0xf71932ab, 0x4360d97e, 0xf4950815, 0x59f1fcb0, 0x9caca41f, + 0xa0c65f7b, 0x1792b560, 0xeabe18f3, 0xb3b06ef8, 0x0c41886f, 0x24c5d6d3, + 0x2d20427e, 0x83d8b556, 0x4d9ac743, 0x5a2842c1, 0xcf7c6fcc, 0x229eb7f5, + 0x18d3e016, 0x7d510efb, 0xaee39a04, 0x38fc800e, 0xb6acfc20, 0x3c93280c}, + {0xc88e0338, 0x3ba9da6f, 0x982c057f, 0xe92c0bb3, 0xed5b9cd1, 0x8295a100, 0xe13a4e12, + 0xd440b919, 0xbbb8b221, 0xabead362, 0x902ce44d, 0x30d0b80e, 0x56bee1f6, 0x6a7d8de0, + 0xb1e1b4db, 0xf76c90c1, 0x807a3bc5, 0xf277e981, 0x4c82ab12, 0x0f7e1021, 0x7dfdf609, + 0x2ce4958f, 0x8906c5e3, 0x2279c653, 0x7dd1fbae, 0x20cb7a1d, 0x9f89d049, 0x0b6aefc1}, + {0x5ece70a4, 0x4da41bc7, 0xcfb9b582, 0xea9ce098, 0x0030ec4a, 0xf331e764, 0x99961f88, + 0x860aa055, 0x4aba3ecb, 0xf77ca429, 0x3a3fee85, 0x4a2caf3a, 0xe800343f, 0xb4521388, + 0xb16b6dc5, 0x99b3d60b, 0xf82777f9, 0x8e1a8d04, 0xab9cd54d, 0xd9a24809, 0x5795d4df, + 0xe4858bfd, 0x9a05f54c, 0x795bb086, 0xe15f7c22, 0x228184ec, 0x66a9ca10, 0xb1cf71a6, + 0xbb9303c5, 0xcd1dcc05, 0x6460a86d, 0xf651f053}, + {0x5befb306, 0x2a7a7246, 0xaf1f77b0, 0xec0ac614, 0xe28be06a, 0xc2c81b19, 0xe5a0481b, 0xf160f9f2, + 0xbc43f28f, 0x65487876, 0x39e4ce3e, 0x0f1e9547, 0x5f0e81ce, 0xb793004c, 0x8e46670e, 0xbd48b866, + 0xd5b43d10, 0x4874ead4, 0xbe8a236b, 0xf90b48f8, 0x62f7e252, 0xdec4475f, 0xdbb841a6, 0x62efcd25, + 0xed64b291, 0x0e9baaea, 0x9466e413, 0xa4241438, 0xb31df0bd, 0x3df9a16f, 0x46416367, 0x54e25986, + 0x1728aa7d, 0xdf435cc5, 0x1f54f79a, 0x1db25f52}, + {0x01043053, 0xf832ef9b, 0x911ed387, 0xba577451, 0xe30d51d4, 0xb6b11f31, 0x9d4cd539, + 0xd067b7f4, 0xf9b4f41f, 0x7f3d4e92, 0x0c57cbe2, 0xb5e1885a, 0xa66203ae, 0x493e93a1, + 0xdf63793a, 0x9563c176, 0xbc6775dd, 0x09cc9161, 0xe278a01b, 0xeb8fd8a1, 0x9200326b, + 0xd95abc5f, 0x716768e3, 0x4f90b505, 0x23d30fda, 0xbb103a3b, 0xc020afbb, 0xb0cb3bd2, + 0xad512a6f, 0xea79f8d6, 0x4cef3474, 0x58dec48b, 0xe89451cb, 0x0b807d73, 0x593f273d, + 0x9fc521b7, 0x89a77524, 0x404f43e0, 0x0f20b3b7, 0x7b938b1a}}; +static unsigned aes_raw_encrypt_ciphertext_bytes[N_TESTS] = { + 4 * 4, 8 * 4, 12 * 4, 16 * 4, 20 * 4, 24 * 4, 28 * 4, 32 * 4, 36 * 4, 40 * 4}; static unsigned aes_raw_encrypt_ciphertext_words[N_TESTS] = {4, 8, 12, 16, 20, 24, 28, 32, 36, 40}; #endif #ifdef __CUSTOM_SIM__ -int sc_main(int argc, char **argv) { +int sc_main(int argc, char **argv) +{ #else -CCS_MAIN(int argc, char **argv) { +CCS_MAIN(int argc, char **argv) +{ #endif #ifdef SHA1_ALGO @@ -169,7 +229,7 @@ CCS_MAIN(int argc, char **argv) { ESP_REPORT_INFO(VON, "--------------------------------"); #endif - const unsigned sha1_in_size = SHA1_PLM_IN_SIZE; + const unsigned sha1_in_size = SHA1_PLM_IN_SIZE; const unsigned sha1_out_size = SHA1_PLM_OUT_SIZE; // Testbench return value (0 = PASS, non-0 = FAIL) @@ -230,53 +290,62 @@ CCS_MAIN(int argc, char **argv) { for (unsigned t = 1; t < N_TESTS; t++) { #ifdef SHA1_ALGO - conf_info_data.crypto_algo = SHA1_ALGO; + conf_info_data.crypto_algo = SHA1_ALGO; conf_info_data.sha1_in_bytes = sha1_raw_in_bytes[t]; - unsigned sha1_in_words = (ESP_TO_UINT32(conf_info_data.sha1_in_bytes) + 4 - 1)/4; + unsigned sha1_in_words = (ESP_TO_UINT32(conf_info_data.sha1_in_bytes) + 4 - 1) / 4; ESP_REPORT_INFO(VON, "Configuration:"); - ESP_REPORT_INFO(VON, " - sha1_in_bytes: %u (words %u)", ESP_TO_UINT32(conf_info_data.sha1_in_bytes), sha1_in_words); + ESP_REPORT_INFO(VON, " - sha1_in_bytes: %u (words %u)", + ESP_TO_UINT32(conf_info_data.sha1_in_bytes), sha1_in_words); #endif #ifdef SHA2_ALGO - conf_info_data.crypto_algo = SHA2_ALGO; - conf_info_data.sha2_in_bytes = sha2_raw_in_bytes[t]; + conf_info_data.crypto_algo = SHA2_ALGO; + conf_info_data.sha2_in_bytes = sha2_raw_in_bytes[t]; conf_info_data.sha2_out_bytes = sha2_raw_out_bytes[t]; - unsigned sha2_in_words = (ESP_TO_UINT32(conf_info_data.sha2_in_bytes) + 4 - 1)/4; - unsigned sha2_out_words = (ESP_TO_UINT32(conf_info_data.sha2_out_bytes) + 4 - 1)/4; + unsigned sha2_in_words = (ESP_TO_UINT32(conf_info_data.sha2_in_bytes) + 4 - 1) / 4; + unsigned sha2_out_words = (ESP_TO_UINT32(conf_info_data.sha2_out_bytes) + 4 - 1) / 4; ESP_REPORT_INFO(VON, "Configuration:"); - ESP_REPORT_INFO(VON, " - sha2_in_bytes: %u (words %u)", ESP_TO_UINT32(conf_info_data.sha2_in_bytes), sha2_in_words); - ESP_REPORT_INFO(VON, " - sha2_out_bytes: %u (words %u)", ESP_TO_UINT32(conf_info_data.sha2_out_bytes), sha2_out_words); + ESP_REPORT_INFO(VON, " - sha2_in_bytes: %u (words %u)", + ESP_TO_UINT32(conf_info_data.sha2_in_bytes), sha2_in_words); + ESP_REPORT_INFO(VON, " - sha2_out_bytes: %u (words %u)", + ESP_TO_UINT32(conf_info_data.sha2_out_bytes), sha2_out_words); #endif #ifdef AES_ALGO - conf_info_data.crypto_algo = AES_ALGO; + conf_info_data.crypto_algo = AES_ALGO; conf_info_data.aes_oper_mode = AES_ECB_OPERATION_MODE; - //conf_info_data.aes_encryption = AES_ENCRYPTION_MODE; - conf_info_data.encryption = AES_ENCRYPTION_MODE; + // conf_info_data.aes_encryption = AES_ENCRYPTION_MODE; + conf_info_data.encryption = AES_ENCRYPTION_MODE; conf_info_data.aes_key_bytes = aes_raw_encrypt_key_bytes[t]; - conf_info_data.aes_in_bytes = aes_raw_encrypt_plaintext_bytes[t]; - conf_info_data.aes_iv_bytes = 0; // 0 for ECB + conf_info_data.aes_in_bytes = aes_raw_encrypt_plaintext_bytes[t]; + conf_info_data.aes_iv_bytes = 0; // 0 for ECB conf_info_data.aes_aad_bytes = 0; // 0 for ECB conf_info_data.aes_tag_bytes = 0; // 0 for ECB unsigned aes_key_words = aes_raw_encrypt_key_words[t]; - unsigned aes_in_words = aes_raw_encrypt_plaintext_words[t]; + unsigned aes_in_words = aes_raw_encrypt_plaintext_words[t]; unsigned aes_out_words = aes_raw_encrypt_ciphertext_words[t]; - unsigned aes_iv_words = 0; // 0 for ECB + unsigned aes_iv_words = 0; // 0 for ECB unsigned aes_aad_words = 0; // 0 for ECB unsigned aes_tag_words = 0; // 0 for ECB ESP_REPORT_INFO(VON, "Configuration:"); ESP_REPORT_INFO(VON, " - aes_oper_mode: %u", ESP_TO_UINT32(conf_info_data.aes_oper_mode)); - //ESP_REPORT_INFO(VON, " - aes_encryption: %u", ESP_TO_UINT32(conf_info_data.aes_encryption)); + // ESP_REPORT_INFO(VON, " - aes_encryption: %u", + // ESP_TO_UINT32(conf_info_data.aes_encryption)); ESP_REPORT_INFO(VON, " - aes_encryption: %u", ESP_TO_UINT32(conf_info_data.encryption)); - ESP_REPORT_INFO(VON, " - aes_key_bytes: %u (words %u)", ESP_TO_UINT32(conf_info_data.aes_key_bytes), aes_key_words); - ESP_REPORT_INFO(VON, " - aes_in_bytes: %u (words %u)", ESP_TO_UINT32(conf_info_data.aes_in_bytes), aes_in_words); - ESP_REPORT_INFO(VON, " - aes_iv_bytes: %u (words %u)", ESP_TO_UINT32(conf_info_data.aes_iv_bytes), aes_iv_words); - ESP_REPORT_INFO(VON, " - aes_aad_bytes: %u (words %u)", ESP_TO_UINT32(conf_info_data.aes_aad_bytes), aes_aad_words); - ESP_REPORT_INFO(VON, " - aes_tag_bytes: %u (words %u)", ESP_TO_UINT32(conf_info_data.aes_tag_bytes), aes_tag_words); + ESP_REPORT_INFO(VON, " - aes_key_bytes: %u (words %u)", + ESP_TO_UINT32(conf_info_data.aes_key_bytes), aes_key_words); + ESP_REPORT_INFO(VON, " - aes_in_bytes: %u (words %u)", + ESP_TO_UINT32(conf_info_data.aes_in_bytes), aes_in_words); + ESP_REPORT_INFO(VON, " - aes_iv_bytes: %u (words %u)", + ESP_TO_UINT32(conf_info_data.aes_iv_bytes), aes_iv_words); + ESP_REPORT_INFO(VON, " - aes_aad_bytes: %u (words %u)", + ESP_TO_UINT32(conf_info_data.aes_aad_bytes), aes_aad_words); + ESP_REPORT_INFO(VON, " - aes_tag_bytes: %u (words %u)", + ESP_TO_UINT32(conf_info_data.aes_tag_bytes), aes_tag_words); #endif #ifdef SHA1_ALGO @@ -284,37 +353,36 @@ CCS_MAIN(int argc, char **argv) { // |<--- 0 --->|<--- 1 --->| // // Pass inputs to the accelerator - for (unsigned j = 0; j < sha1_in_words; j+=2) { - ac_int data_fp_0(sha1_raw_inputs[t][j+0]); - ac_int data_fp_1(sha1_raw_inputs[t][j+1]); + for (unsigned j = 0; j < sha1_in_words; j += 2) { + ac_int data_fp_0(sha1_raw_inputs[t][j + 0]); + ac_int data_fp_1(sha1_raw_inputs[t][j + 1]); - sha1_inputs[j+0] = data_fp_0; - sha1_inputs[j+1] = data_fp_1; + sha1_inputs[j + 0] = data_fp_0; + sha1_inputs[j + 1] = data_fp_1; ac_int data_ac; - data_ac.set_slc(WL*0, sha1_inputs[j+0].template slc(0)); - data_ac.set_slc(WL*1, sha1_inputs[j+1].template slc(0)); + data_ac.set_slc(WL * 0, sha1_inputs[j + 0].template slc(0)); + data_ac.set_slc(WL * 1, sha1_inputs[j + 1].template slc(0)); dma_read_chnl.write(data_ac); } #endif - #ifdef SHA2_ALGO // DMA word // |<--- 0 --->|<--- 1 --->| // // Pass inputs to the accelerator - for (unsigned j = 0; j < sha2_in_words; j+=2) { - ac_int data_fp_0(sha2_raw_inputs[t][j+0]); - ac_int data_fp_1(sha2_raw_inputs[t][j+1]); + for (unsigned j = 0; j < sha2_in_words; j += 2) { + ac_int data_fp_0(sha2_raw_inputs[t][j + 0]); + ac_int data_fp_1(sha2_raw_inputs[t][j + 1]); - sha2_inputs[j+0] = data_fp_0; - sha2_inputs[j+1] = data_fp_1; + sha2_inputs[j + 0] = data_fp_0; + sha2_inputs[j + 1] = data_fp_1; ac_int data_ac; - data_ac.set_slc(WL*0, sha2_inputs[j+0].template slc(0)); - data_ac.set_slc(WL*1, sha2_inputs[j+1].template slc(0)); + data_ac.set_slc(WL * 0, sha2_inputs[j + 0].template slc(0)); + data_ac.set_slc(WL * 1, sha2_inputs[j + 1].template slc(0)); dma_read_chnl.write(data_ac); } @@ -326,30 +394,30 @@ CCS_MAIN(int argc, char **argv) { // // Pass inputs to the accelerator - for (unsigned j = 0; j < aes_key_words; j+=2) { - ac_int data_0(aes_raw_encrypt_key[t][j+0]); - ac_int data_1(aes_raw_encrypt_key[t][j+1]); + for (unsigned j = 0; j < aes_key_words; j += 2) { + ac_int data_0(aes_raw_encrypt_key[t][j + 0]); + ac_int data_1(aes_raw_encrypt_key[t][j + 1]); - aes_inputs[j+0] = data_0; - aes_inputs[j+1] = data_1; + aes_inputs[j + 0] = data_0; + aes_inputs[j + 1] = data_1; ac_int data_ac; - data_ac.set_slc(WL*0, aes_inputs[j+0].template slc(0)); - data_ac.set_slc(WL*1, aes_inputs[j+1].template slc(0)); + data_ac.set_slc(WL * 0, aes_inputs[j + 0].template slc(0)); + data_ac.set_slc(WL * 1, aes_inputs[j + 1].template slc(0)); dma_read_chnl.write(data_ac); } - for (unsigned j = 0; j < aes_in_words; j+=2) { - ac_int data_0(aes_raw_encrypt_plaintext[t][j+0]); - ac_int data_1(aes_raw_encrypt_plaintext[t][j+1]); + for (unsigned j = 0; j < aes_in_words; j += 2) { + ac_int data_0(aes_raw_encrypt_plaintext[t][j + 0]); + ac_int data_1(aes_raw_encrypt_plaintext[t][j + 1]); - aes_inputs[j+0] = data_0; - aes_inputs[j+1] = data_1; + aes_inputs[j + 0] = data_0; + aes_inputs[j + 1] = data_1; ac_int data_ac; - data_ac.set_slc(WL*0, aes_inputs[j+0].template slc(0)); - data_ac.set_slc(WL*1, aes_inputs[j+1].template slc(0)); + data_ac.set_slc(WL * 0, aes_inputs[j + 0].template slc(0)); + data_ac.set_slc(WL * 1, aes_inputs[j + 1].template slc(0)); dma_read_chnl.write(data_ac); } @@ -360,20 +428,22 @@ CCS_MAIN(int argc, char **argv) { // Run the accelerator #ifdef __CUSTOM_SIM__ - crypto_cxx_catapult(conf_info, dma_read_ctrl, dma_write_ctrl, dma_read_chnl, dma_write_chnl, acc_done); + crypto_cxx_catapult(conf_info, dma_read_ctrl, dma_write_ctrl, dma_read_chnl, dma_write_chnl, + acc_done); #else - CCS_DESIGN(crypto_cxx_catapult)(conf_info, dma_read_ctrl, dma_write_ctrl, dma_read_chnl, dma_write_chnl, acc_done); + CCS_DESIGN(crypto_cxx_catapult) + (conf_info, dma_read_ctrl, dma_write_ctrl, dma_read_chnl, dma_write_chnl, acc_done); #endif #ifdef SHA1_ALGO // Fetch outputs from the accelerator - while (!dma_write_chnl.available(sha1_out_size/2)) {} // Testbench stalls until data ready - for (unsigned i = 0; i < sha1_out_size; i+=2) { + while (!dma_write_chnl.available(sha1_out_size / 2)) {} // Testbench stalls until data ready + for (unsigned i = 0; i < sha1_out_size; i += 2) { ac_int data = dma_write_chnl.read().template slc(0); - ac_int data_0 = data.template slc(WL*0); - ac_int data_1 = data.template slc(WL*1); - sha1_outputs[i+0].template set_slc(0, data_0); - sha1_outputs[i+1].template set_slc(0, data_1); + ac_int data_0 = data.template slc(WL * 0); + ac_int data_1 = data.template slc(WL * 1); + sha1_outputs[i + 0].template set_slc(0, data_0); + sha1_outputs[i + 1].template set_slc(0, data_1); } // Validation @@ -396,7 +466,8 @@ CCS_MAIN(int argc, char **argv) { if (errors > 0) { ESP_REPORT_INFO(VON, "Validation: FAIL (errors %u / total %u)", errors, sha1_out_size); rc |= 1; - } else { + } + else { ESP_REPORT_INFO(VON, "Validation: PASS"); rc |= 0; } @@ -406,13 +477,14 @@ CCS_MAIN(int argc, char **argv) { #ifdef SHA2_ALGO // Fetch outputs from the accelerator - while (!dma_write_chnl.available(sha2_out_words/2)) {} // Testbench stalls until data ready - for (unsigned i = 0; i < sha2_out_words; i+=2) { + while (!dma_write_chnl.available(sha2_out_words / 2)) { + } // Testbench stalls until data ready + for (unsigned i = 0; i < sha2_out_words; i += 2) { ac_int data = dma_write_chnl.read().template slc(0); - ac_int data_0 = data.template slc(WL*0); - ac_int data_1 = data.template slc(WL*1); - sha2_outputs[i+0].template set_slc(0, data_0); - sha2_outputs[i+1].template set_slc(0, data_1); + ac_int data_0 = data.template slc(WL * 0); + ac_int data_1 = data.template slc(WL * 1); + sha2_outputs[i + 0].template set_slc(0, data_0); + sha2_outputs[i + 1].template set_slc(0, data_1); } // Validation @@ -435,7 +507,8 @@ CCS_MAIN(int argc, char **argv) { if (errors > 0) { ESP_REPORT_INFO(VON, "Validation: FAIL (errors %u / total %u)", errors, sha2_out_words); rc |= 1; - } else { + } + else { ESP_REPORT_INFO(VON, "Validation: PASS"); rc |= 0; } @@ -445,13 +518,13 @@ CCS_MAIN(int argc, char **argv) { #ifdef AES_ALGO // Fetch outputs from the accelerator - while (!dma_write_chnl.available(aes_out_words/2)) {} // Testbench stalls until data ready - for (unsigned i = 0; i < aes_out_words; i+=2) { + while (!dma_write_chnl.available(aes_out_words / 2)) {} // Testbench stalls until data ready + for (unsigned i = 0; i < aes_out_words; i += 2) { ac_int data = dma_write_chnl.read().template slc(0); - ac_int data_0 = data.template slc(WL*0); - ac_int data_1 = data.template slc(WL*1); - aes_outputs[i+0].template set_slc(0, data_0); - aes_outputs[i+1].template set_slc(0, data_1); + ac_int data_0 = data.template slc(WL * 0); + ac_int data_1 = data.template slc(WL * 1); + aes_outputs[i + 0].template set_slc(0, data_0); + aes_outputs[i + 1].template set_slc(0, data_1); } // Validation @@ -474,7 +547,8 @@ CCS_MAIN(int argc, char **argv) { if (errors > 0) { ESP_REPORT_INFO(VON, "Validation: FAIL (errors %u / total %u)", errors, aes_out_words); rc |= 1; - } else { + } + else { ESP_REPORT_INFO(VON, "Validation: PASS"); rc |= 0; } diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/sw/baremetal/crypto_cxx.c b/accelerators/catapult_hls/crypto_cxx_catapult/sw/baremetal/crypto_cxx.c index 7f4589e0a8..1250a5720e 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/sw/baremetal/crypto_cxx.c +++ b/accelerators/catapult_hls/crypto_cxx_catapult/sw/baremetal/crypto_cxx.c @@ -12,14 +12,10 @@ typedef uint32_t token_t; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} - +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } #define SLD_CRYPTO_CXX 0x091 -#define DEV_NAME "sld,crypto_cxx_catapult" +#define DEV_NAME "sld,crypto_cxx_catapult" /* <<--params-->> */ static unsigned crypto_algo; @@ -39,7 +35,7 @@ static unsigned aes_encryption; static unsigned aes_oper_mode; /* Other parameters */ -//const unsigned sha1_in_words = 1600; +// const unsigned sha1_in_words = 1600; static unsigned sha1_in_words; static unsigned sha1_out_words; static unsigned sha1_out_bytes; @@ -54,54 +50,51 @@ static unsigned aes_out_words; static unsigned aes_aad_words; static unsigned aes_tag_words; -static unsigned mem_bytes; /* Total memory buffer size in bytes */ -static unsigned mem_words; /* Total memory buffer size in words */ +static unsigned mem_bytes; /* Total memory buffer size in bytes */ +static unsigned mem_words; /* Total memory buffer size in words */ static unsigned out_offset; /* Output offset in memory buffer */ -static unsigned out_bytes; /* Output buffer size in bytes */ -static unsigned out_words; /* Output buffer size in words */ +static unsigned out_bytes; /* Output buffer size in bytes */ +static unsigned out_words; /* Output buffer size in words */ /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ #define CRYPTO_CXX_CRYPTO_ALGO_REG 0x40 -#define CRYPTO_CXX_ENCRYPTION_REG 0x44 +#define CRYPTO_CXX_ENCRYPTION_REG 0x44 #define CRYPTO_CXX_SHA1_IN_BYTES_REG 0x48 -#define CRYPTO_CXX_SHA2_IN_BYTES_REG 0x4C +#define CRYPTO_CXX_SHA2_IN_BYTES_REG 0x4C #define CRYPTO_CXX_SHA2_OUT_BYTES_REG 0x50 -#define CRYPTO_CXX_AES_OPER_MODE_REG 0x54 -#define CRYPTO_CXX_AES_KEY_BYTES_REG 0x58 +#define CRYPTO_CXX_AES_OPER_MODE_REG 0x54 +#define CRYPTO_CXX_AES_KEY_BYTES_REG 0x58 #define CRYPTO_CXX_AES_INPUT_BYTES_REG 0x5C -#define CRYPTO_CXX_AES_IV_BYTES_REG 0x60 -#define CRYPTO_CXX_AES_AAD_BYTES_REG 0x64 -#define CRYPTO_CXX_AES_TAG_BYTES_REG 0x68 +#define CRYPTO_CXX_AES_IV_BYTES_REG 0x60 +#define CRYPTO_CXX_AES_AAD_BYTES_REG 0x64 +#define CRYPTO_CXX_AES_TAG_BYTES_REG 0x68 //#define SHA1_ALGO 1 //#define SHA2_ALGO 2 //#define AES_ALGO 3 #if defined(SHA1_ALGO) -#include "sha1_tests.h" + #include "sha1_tests.h" // #include "SHA1ShortMsg.h" // #include "SHA1LongMsg.h" #elif defined(SHA2_ALGO) -#include "sha2_tests.h" + #include "sha2_tests.h" #elif defined(AES_ALGO) -#include "aes_tests.h" + #include "aes_tests.h" #else -#error "Crypto algo is not defined!" -#error "Compilation flags: [-DSHA1_ALGO | -DSHA2_ALGO | -DAES_ALGO]" + #error "Crypto algo is not defined!" + #error "Compilation flags: [-DSHA1_ALGO | -DSHA2_ALGO | -DAES_ALGO]" #endif - static int validate_buf(token_t *out, token_t *gold, unsigned out_words) { int j; @@ -110,16 +103,15 @@ static int validate_buf(token_t *out, token_t *gold, unsigned out_words) printf("INFO: gold output data @%p\n", gold); printf("INFO: output data @%p\n", out); - for (j = 0; j < out_words; j++) - { + for (j = 0; j < out_words; j++) { token_t gold_data = gold[j]; - token_t out_data = out[j]; + token_t out_data = out[j]; - if (out_data != gold_data) - { + if (out_data != gold_data) { errors++; #ifdef __DEBUG__ - printf("[%u] @%p %x (%x) %s\n", j, out + j, out_data, gold_data, ((out_data != gold_data)?" !!!":"")); + printf("[%u] @%p %x (%x) %s\n", j, out + j, out_data, gold_data, + ((out_data != gold_data) ? " !!!" : "")); #endif } } @@ -129,20 +121,19 @@ static int validate_buf(token_t *out, token_t *gold, unsigned out_words) return errors; } -static inline uint64_t get_counter() { - uint64_t counter; - asm volatile ( - "li t0, 0;" - "csrr t0, mcycle;" - "mv %0, t0" - : "=r" ( counter ) - : - : "t0" - ); - return counter; +static inline uint64_t get_counter() +{ + uint64_t counter; + asm volatile("li t0, 0;" + "csrr t0, mcycle;" + "mv %0, t0" + : "=r"(counter) + : + : "t0"); + return counter; } -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { int i; int n; @@ -171,22 +162,22 @@ int main(int argc, char * argv[]) for (unsigned idx = 1; idx < N_TESTS; idx++) { - printf("INFO: Test: %u / %u\n", idx, N_TESTS-1); + printf("INFO: Test: %u / %u\n", idx, N_TESTS - 1); #ifdef SHA1_ALGO crypto_algo = SHA1_ALGO; printf("INFO: === SHA1 ===\n"); - sha1_in_bytes = sha1_raw_in_bytes[idx]; - sha1_in_words = sha1_raw_in_words[idx]; + sha1_in_bytes = sha1_raw_in_bytes[idx]; + sha1_in_words = sha1_raw_in_words[idx]; sha1_out_bytes = sha1_raw_out_bytes[idx]; sha1_out_words = sha1_raw_out_words[idx]; mem_bytes = sha1_in_bytes + sha1_out_bytes; out_offset = sha1_in_words; - out_bytes = sha1_out_bytes; + out_bytes = sha1_out_bytes; // ATTENTION: SHA1 output is 5 32-bit words, DMA is 64 bits // Discard the last extra word @@ -198,16 +189,16 @@ int main(int argc, char * argv[]) printf("INFO: === SHA2 ===\n"); - sha2_in_bytes = sha2_raw_in_bytes[idx]; - sha2_in_words = sha2_raw_in_words[idx]; + sha2_in_bytes = sha2_raw_in_bytes[idx]; + sha2_in_words = sha2_raw_in_words[idx]; sha2_out_bytes = sha2_raw_out_bytes[idx]; sha2_out_words = sha2_raw_out_words[idx]; mem_bytes = sha2_in_bytes + sha2_out_bytes; out_offset = sha2_in_words; - out_bytes = sha2_out_bytes; - out_words = sha2_out_words; + out_bytes = sha2_out_bytes; + out_words = sha2_out_words; #endif #if defined(AES_ALGO) && defined(AES_ECB_OPERATION_MODE) @@ -223,11 +214,11 @@ int main(int argc, char * argv[]) aes_tag_bytes = 0; aes_aad_bytes = 0; - aes_iv_bytes = 0; + aes_iv_bytes = 0; out_offset = aes_key_words + aes_in_words; - out_bytes = aes_in_bytes; - out_words = aes_in_words; + out_bytes = aes_in_bytes; + out_words = aes_in_words; mem_bytes = aes_key_bytes + aes_in_bytes + out_bytes; #endif @@ -250,8 +241,8 @@ int main(int argc, char * argv[]) aes_aad_bytes = 0; out_offset = aes_key_words + aes_iv_words + aes_in_words; - out_bytes = aes_in_bytes; - out_words = aes_in_words; + out_bytes = aes_in_bytes; + out_words = aes_in_words; mem_bytes = aes_key_bytes + aes_iv_bytes + aes_in_bytes + out_bytes; #endif @@ -274,15 +265,15 @@ int main(int argc, char * argv[]) aes_aad_bytes = 0; out_offset = aes_key_words + aes_iv_words + aes_in_words; - out_bytes = aes_in_bytes; - out_words = aes_in_words; + out_bytes = aes_in_bytes; + out_words = aes_in_words; mem_bytes = aes_key_bytes + aes_iv_bytes + aes_in_bytes + out_bytes; #endif // Allocate memory gold = aligned_malloc(out_bytes); - mem = aligned_malloc(mem_bytes); + mem = aligned_malloc(mem_bytes); printf("INFO: Memory buffer\n"); printf("INFO: - base address = %p\n", mem); printf("INFO: - size = %u B\n", mem_bytes); @@ -293,30 +284,41 @@ int main(int argc, char * argv[]) // Alocate and populate page table ptable = aligned_malloc(NCHUNK(mem_bytes) * sizeof(unsigned *)); for (i = 0; i < NCHUNK(mem_bytes); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - //printf(" ptable = %p\n", ptable); - //printf(" nchunk = %lu\n", NCHUNK(mem_bytes)); + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + // printf(" ptable = %p\n", ptable); + // printf(" nchunk = %lu\n", NCHUNK(mem_bytes)); printf("INFO: Generate input...\n"); #ifdef SHA1_ALGO - sha1_init_buf(idx, mem, gold, sha1_raw_in_words, sha1_raw_out_words, sha1_raw_inputs, sha1_raw_outputs); + sha1_init_buf(idx, mem, gold, sha1_raw_in_words, sha1_raw_out_words, sha1_raw_inputs, + sha1_raw_outputs); #endif #ifdef SHA2_ALGO - sha2_init_buf(idx, mem, gold, sha2_raw_in_words, sha2_raw_out_words, sha2_raw_inputs, sha2_raw_outputs); + sha2_init_buf(idx, mem, gold, sha2_raw_in_words, sha2_raw_out_words, sha2_raw_inputs, + sha2_raw_outputs); #endif #if defined(AES_ALGO) && defined(AES_ECB_OPERATION_MODE) - aes_init_buf(idx, mem, gold, aes_ecb_raw_encrypt_key_words, NULL, aes_ecb_raw_encrypt_plaintext_words, aes_ecb_raw_encrypt_ciphertext_words, aes_ecb_raw_encrypt_key, NULL, aes_ecb_raw_encrypt_plaintext, aes_ecb_raw_encrypt_ciphertext); + aes_init_buf(idx, mem, gold, aes_ecb_raw_encrypt_key_words, NULL, + aes_ecb_raw_encrypt_plaintext_words, aes_ecb_raw_encrypt_ciphertext_words, + aes_ecb_raw_encrypt_key, NULL, aes_ecb_raw_encrypt_plaintext, + aes_ecb_raw_encrypt_ciphertext); #endif #if defined(AES_ALGO) && defined(AES_CTR_OPERATION_MODE) - aes_init_buf(idx, mem, gold, aes_ctr_raw_encrypt_key_words, aes_ctr_raw_encrypt_iv_words, aes_ctr_raw_encrypt_plaintext_words, aes_ctr_raw_encrypt_ciphertext_words, aes_ctr_raw_encrypt_key, aes_ctr_raw_encrypt_iv, aes_ctr_raw_encrypt_plaintext, aes_ctr_raw_encrypt_ciphertext); + aes_init_buf(idx, mem, gold, aes_ctr_raw_encrypt_key_words, aes_ctr_raw_encrypt_iv_words, + aes_ctr_raw_encrypt_plaintext_words, aes_ctr_raw_encrypt_ciphertext_words, + aes_ctr_raw_encrypt_key, aes_ctr_raw_encrypt_iv, aes_ctr_raw_encrypt_plaintext, + aes_ctr_raw_encrypt_ciphertext); #endif #if defined(AES_ALGO) && defined(AES_CBC_OPERATION_MODE) - aes_init_buf(idx, mem, gold, aes_cbc_raw_encrypt_key_words, aes_cbc_raw_encrypt_iv_words, aes_cbc_raw_encrypt_plaintext_words, aes_cbc_raw_encrypt_ciphertext_words, aes_cbc_raw_encrypt_key, aes_cbc_raw_encrypt_iv, aes_cbc_raw_encrypt_plaintext, aes_cbc_raw_encrypt_ciphertext); + aes_init_buf(idx, mem, gold, aes_cbc_raw_encrypt_key_words, aes_cbc_raw_encrypt_iv_words, + aes_cbc_raw_encrypt_plaintext_words, aes_cbc_raw_encrypt_ciphertext_words, + aes_cbc_raw_encrypt_key, aes_cbc_raw_encrypt_iv, aes_cbc_raw_encrypt_plaintext, + aes_cbc_raw_encrypt_ciphertext); #endif printf("INFO: Input ready!\n"); @@ -340,13 +342,13 @@ int main(int argc, char * argv[]) // Pass common configuration parameters iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_bytes)); iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); // Use the following if input and output data are not allocated at the default offsets - //iowrite32(dev, SRC_OFFSET_REG, 0x0); - //iowrite32(dev, DST_OFFSET_REG, 0x0); + // iowrite32(dev, SRC_OFFSET_REG, 0x0); + // iowrite32(dev, DST_OFFSET_REG, 0x0); // Pass accelerator-specific configuration parameters /* <<--regs-config-->> */ @@ -360,7 +362,7 @@ int main(int argc, char * argv[]) #endif #ifdef AES_ALGO iowrite32(dev, CRYPTO_CXX_AES_OPER_MODE_REG, AES_OPERATION_MODE); - //iowrite32(dev, CRYPTO_CXX_AES_ENCRYPTION_REG, AES_ENCRYPTION_MODE); + // iowrite32(dev, CRYPTO_CXX_AES_ENCRYPTION_REG, AES_ENCRYPTION_MODE); iowrite32(dev, CRYPTO_CXX_ENCRYPTION_REG, AES_ENCRYPTION_MODE); iowrite32(dev, CRYPTO_CXX_AES_KEY_BYTES_REG, aes_key_bytes); iowrite32(dev, CRYPTO_CXX_AES_INPUT_BYTES_REG, aes_in_bytes); @@ -371,7 +373,7 @@ int main(int argc, char * argv[]) // Flush (customize coherence model here) esp_flush(ACC_COH_NONE); - //esp_flush(ACC_COH_RECALL); + // esp_flush(ACC_COH_RECALL); // Start accelerators printf("INFO: Accelerator start...\n"); @@ -406,16 +408,16 @@ int main(int argc, char * argv[]) aligned_free(mem); aligned_free(gold); return 1; - } else { + } + else { printf("INFO: Latency %lu clks\n", end - begin); printf("INFO: PASS\n"); - } + } } aligned_free(ptable); aligned_free(mem); aligned_free(gold); - } #if defined(SHA1_ALGO) printf("INFO: Crypto SHA1 DONE\n"); diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/app/crypto.c b/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/app/crypto.c index c9b0c1210d..39b12ded2b 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/app/crypto.c +++ b/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/app/crypto.c @@ -1,7 +1,7 @@ // Copyright (c) 2011-2021 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include "cfg.h" #include "aes_tests.h" +#include "cfg.h" #include "sha1_tests.h" #include "sha2_tests.h" @@ -17,35 +17,36 @@ static unsigned size; /* User-defined code */ static int validate_buffer(token_t *out, token_t *gold) { - int j; - unsigned errors = 0; + int j; + unsigned errors = 0; - for (j = 0; j < out_words_adj; j++) { + for (j = 0; j < out_words_adj; j++) { if (gold[j] != out[j]) { printf("[%d] - expected: %x, got: %x\n", j, gold[j], out[j]); errors++; } } - return errors; + return errors; } - /* User-defined code */ static void init_buffer(token_t *in, token_t *gold, int crypto_algo, int aes_oper_mode, int index) { - int i, j; + int i, j; if (crypto_algo == 1) { for (i = 0; i < sha1_raw_in_words[index]; i++) in[i] = sha1_raw_inputs[index][i]; for (i = 0; i < sha1_raw_out_words[index]; i++) gold[i] = sha1_raw_outputs[index][i]; - } else if (crypto_algo == 2) { + } + else if (crypto_algo == 2) { for (i = 0; i < sha2_raw_in_words[index]; i++) in[i] = sha2_raw_inputs[index][i]; for (i = 0; i < sha2_raw_out_words[index]; i++) gold[i] = sha2_raw_outputs[index][i]; - } else if (crypto_algo == 3 && aes_oper_mode == 1) { + } + else if (crypto_algo == 3 && aes_oper_mode == 1) { j = 0; for (i = 0; i < aes_ecb_raw_encrypt_key_words[index]; i++, j++) in[j] = aes_ecb_raw_encrypt_key[index][i]; @@ -53,7 +54,8 @@ static void init_buffer(token_t *in, token_t *gold, int crypto_algo, int aes_ope in[j] = aes_ecb_raw_encrypt_plaintext[index][i]; for (i = 0; i < aes_ecb_raw_encrypt_ciphertext_words[index]; i++) gold[i] = aes_ecb_raw_encrypt_ciphertext[index][i]; - } else if (crypto_algo == 3 && aes_oper_mode == 2) { + } + else if (crypto_algo == 3 && aes_oper_mode == 2) { j = 0; for (i = 0; i < aes_ctr_raw_encrypt_key_words[index]; i++, j++) in[j] = aes_ctr_raw_encrypt_key[index][i]; @@ -63,7 +65,8 @@ static void init_buffer(token_t *in, token_t *gold, int crypto_algo, int aes_ope in[j] = aes_ctr_raw_encrypt_plaintext[index][i]; for (i = 0; i < aes_ctr_raw_encrypt_ciphertext_words[index]; i++) gold[i] = aes_ctr_raw_encrypt_ciphertext[index][i]; - } else if (crypto_algo == 3 && aes_oper_mode == 3) { + } + else if (crypto_algo == 3 && aes_oper_mode == 3) { j = 0; for (i = 0; i < aes_cbc_raw_encrypt_key_words[index]; i++, j++) in[j] = aes_cbc_raw_encrypt_key[index][i]; @@ -76,82 +79,90 @@ static void init_buffer(token_t *in, token_t *gold, int crypto_algo, int aes_ope } } - /* User-defined code */ static void init_parameters(int crypto_algo, int aes_oper_mode, int index) { - int in_words = 0; + int in_words = 0; int out_words = 0; if (crypto_algo == 1) { - in_words = sha1_raw_in_words[index]; + in_words = sha1_raw_in_words[index]; out_words = sha1_raw_out_words[index]; - } else if (crypto_algo == 2) { - in_words = sha2_raw_in_words[index]; - out_words = sha2_raw_out_words[index]; - } else if (crypto_algo == 3 && aes_oper_mode == 1) { - in_words = aes_ecb_raw_encrypt_key_words[index] + aes_ecb_raw_encrypt_plaintext_words[index]; + } + else if (crypto_algo == 2) { + in_words = sha2_raw_in_words[index]; + out_words = sha2_raw_out_words[index]; + } + else if (crypto_algo == 3 && aes_oper_mode == 1) { + in_words = + aes_ecb_raw_encrypt_key_words[index] + aes_ecb_raw_encrypt_plaintext_words[index]; out_words = aes_ecb_raw_encrypt_ciphertext_words[index]; - } else if (crypto_algo == 3 && aes_oper_mode == 2) { + } + else if (crypto_algo == 3 && aes_oper_mode == 2) { in_words = aes_ctr_raw_encrypt_key_words[index] + aes_ctr_raw_encrypt_iv_words[index] + - aes_ctr_raw_encrypt_plaintext_words[index]; + aes_ctr_raw_encrypt_plaintext_words[index]; out_words = aes_ctr_raw_encrypt_ciphertext_words[index]; - } else if (crypto_algo == 3 && aes_oper_mode == 3) { + } + else if (crypto_algo == 3 && aes_oper_mode == 3) { in_words = aes_cbc_raw_encrypt_key_words[index] + aes_cbc_raw_encrypt_iv_words[index] + - aes_cbc_raw_encrypt_plaintext_words[index]; + aes_cbc_raw_encrypt_plaintext_words[index]; out_words = aes_cbc_raw_encrypt_ciphertext_words[index]; } if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = in_words; - out_words_adj = out_words; - } else { - in_words_adj = round_up(in_words, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(out_words, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - size = (out_offset * sizeof(token_t)) + out_size; + in_words_adj = in_words; + out_words_adj = out_words; + } + else { + in_words_adj = round_up(in_words, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(out_words, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + size = (out_offset * sizeof(token_t)) + out_size; } static void init_cfg(int crypto_algo, int aes_oper_mode, int index) { crypto_cfg_000[0].crypto_algo = crypto_algo; - if (crypto_algo == 1) { - crypto_cfg_000[0].sha1_in_bytes = sha1_raw_in_bytes[index]; - } else if (crypto_algo == 2) { - crypto_cfg_000[0].sha2_in_bytes = sha2_raw_in_bytes[index]; + if (crypto_algo == 1) { crypto_cfg_000[0].sha1_in_bytes = sha1_raw_in_bytes[index]; } + else if (crypto_algo == 2) { + crypto_cfg_000[0].sha2_in_bytes = sha2_raw_in_bytes[index]; crypto_cfg_000[0].sha2_out_bytes = sha2_raw_out_bytes[index]; - } else if (crypto_algo == 3) { + } + else if (crypto_algo == 3) { crypto_cfg_000[0].aes_oper_mode = aes_oper_mode; - crypto_cfg_000[0].encryption = AES_ENCRYPTION_MODE; + crypto_cfg_000[0].encryption = AES_ENCRYPTION_MODE; if (aes_oper_mode == 1) { - crypto_cfg_000[0].aes_key_bytes = aes_ecb_raw_encrypt_key_bytes[index]; + crypto_cfg_000[0].aes_key_bytes = aes_ecb_raw_encrypt_key_bytes[index]; crypto_cfg_000[0].aes_input_bytes = aes_ecb_raw_encrypt_plaintext_bytes[index]; - crypto_cfg_000[0].aes_iv_bytes = 0; - crypto_cfg_000[0].aes_aad_bytes = 0; - crypto_cfg_000[0].aes_tag_bytes = 0; - } else if (aes_oper_mode == 2) { - crypto_cfg_000[0].aes_key_bytes = aes_ctr_raw_encrypt_key_bytes[index]; + crypto_cfg_000[0].aes_iv_bytes = 0; + crypto_cfg_000[0].aes_aad_bytes = 0; + crypto_cfg_000[0].aes_tag_bytes = 0; + } + else if (aes_oper_mode == 2) { + crypto_cfg_000[0].aes_key_bytes = aes_ctr_raw_encrypt_key_bytes[index]; crypto_cfg_000[0].aes_input_bytes = aes_ctr_raw_encrypt_plaintext_bytes[index]; - crypto_cfg_000[0].aes_iv_bytes = aes_ctr_raw_encrypt_iv_bytes[index]; - crypto_cfg_000[0].aes_aad_bytes = 0; - crypto_cfg_000[0].aes_tag_bytes = 0; - } else if (aes_oper_mode == 3) { - crypto_cfg_000[0].aes_key_bytes = aes_cbc_raw_encrypt_key_bytes[index]; + crypto_cfg_000[0].aes_iv_bytes = aes_ctr_raw_encrypt_iv_bytes[index]; + crypto_cfg_000[0].aes_aad_bytes = 0; + crypto_cfg_000[0].aes_tag_bytes = 0; + } + else if (aes_oper_mode == 3) { + crypto_cfg_000[0].aes_key_bytes = aes_cbc_raw_encrypt_key_bytes[index]; crypto_cfg_000[0].aes_input_bytes = aes_cbc_raw_encrypt_plaintext_bytes[index]; - crypto_cfg_000[0].aes_iv_bytes = aes_cbc_raw_encrypt_iv_bytes[index]; - crypto_cfg_000[0].aes_aad_bytes = 0; - crypto_cfg_000[0].aes_tag_bytes = 0; + crypto_cfg_000[0].aes_iv_bytes = aes_cbc_raw_encrypt_iv_bytes[index]; + crypto_cfg_000[0].aes_aad_bytes = 0; + crypto_cfg_000[0].aes_tag_bytes = 0; } } } -void usage() { +void usage() +{ printf("usage: ./crypto crypto_algo [aes_mode]\n"); printf("crypto_algo: 1 - SHA1, 2 - SHA2, 3 - AES\n"); printf("aes_mode - required if crypto_algo == AES: 1 - ECB, 2 - CTR, 3 - CBC\n"); @@ -159,11 +170,11 @@ void usage() { int main(int argc, char **argv) { - int errors = 0; + int errors = 0; int fail_count = 0; - token_t *gold; - token_t *buf; + token_t *gold; + token_t *buf; if (argc < 2) { usage(); @@ -194,16 +205,20 @@ int main(int argc, char **argv) if (crypto_algo == 1) { N_TESTS = 13; printf("Starting %d tests for SHA1\n", N_TESTS); - } else if (crypto_algo == 2) { + } + else if (crypto_algo == 2) { N_TESTS = 12; printf("Starting %d tests for SHA2\n", N_TESTS); - } else if (crypto_algo == 3 && aes_oper_mode == 1) { + } + else if (crypto_algo == 3 && aes_oper_mode == 1) { N_TESTS = 10; printf("Starting %d tests for AES ECB\n", N_TESTS); - } else if (crypto_algo == 3 && aes_oper_mode == 2) { + } + else if (crypto_algo == 3 && aes_oper_mode == 2) { N_TESTS = 4; printf("Starting %d tests for AES CTR\n", N_TESTS); - } else if (crypto_algo == 3 && aes_oper_mode == 3) { + } + else if (crypto_algo == 3 && aes_oper_mode == 3) { N_TESTS = 10; printf("Starting %d tests for AES CBC\n", N_TESTS); } @@ -211,9 +226,9 @@ int main(int argc, char **argv) for (int i = 1; i < N_TESTS; i++) { init_parameters(crypto_algo, aes_oper_mode, i); - buf = (token_t *) esp_alloc(size); + buf = (token_t *)esp_alloc(size); cfg_000[0].hw_buf = buf; - gold = malloc(out_len * sizeof(float)); + gold = malloc(out_len * sizeof(float)); init_buffer(buf, gold, crypto_algo, aes_oper_mode, i); @@ -251,11 +266,9 @@ int main(int argc, char **argv) printf(" TEST %d PASS\n", i); printf("\n====== %s ======\n\n", cfg_000[0].devname); - } - if (fail_count == 0) - printf("ALL TESTS PASSED!\n"); + if (fail_count == 0) printf("ALL TESTS PASSED!\n"); else printf("%d/%d TESTS FAILED!\n", fail_count, N_TESTS - 1); diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/driver/crypto_cxx_catapult.c b/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/driver/crypto_cxx_catapult.c index 123a0c86c9..a7a2fefbb6 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/driver/crypto_cxx_catapult.c +++ b/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/driver/crypto_cxx_catapult.c @@ -1,65 +1,65 @@ // Copyright (c) 2011-2021 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "crypto_cxx_catapult.h" -#define DRV_NAME "crypto_cxx_catapult" +#define DRV_NAME "crypto_cxx_catapult" /* <<--regs-->> */ #define CRYPTO_CXX_CRYPTO_ALGO_REG 0x40 -#define CRYPTO_CXX_ENCRYPTION_REG 0x44 +#define CRYPTO_CXX_ENCRYPTION_REG 0x44 #define CRYPTO_CXX_SHA1_IN_BYTES_REG 0x48 -#define CRYPTO_CXX_SHA2_IN_BYTES_REG 0x4C +#define CRYPTO_CXX_SHA2_IN_BYTES_REG 0x4C #define CRYPTO_CXX_SHA2_OUT_BYTES_REG 0x50 #define CRYPTO_CXX_AES_OPER_MODE_REG 0x54 //#define CRYPTO_CXX_AES_ENCRYPTION_REG 0x54 -#define CRYPTO_CXX_AES_KEY_BYTES_REG 0x58 +#define CRYPTO_CXX_AES_KEY_BYTES_REG 0x58 #define CRYPTO_CXX_AES_INPUT_BYTES_REG 0x5C -#define CRYPTO_CXX_AES_IV_BYTES_REG 0x60 -#define CRYPTO_CXX_AES_AAD_BYTES_REG 0x64 -#define CRYPTO_CXX_AES_TAG_BYTES_REG 0x68 +#define CRYPTO_CXX_AES_IV_BYTES_REG 0x60 +#define CRYPTO_CXX_AES_AAD_BYTES_REG 0x64 +#define CRYPTO_CXX_AES_TAG_BYTES_REG 0x68 struct crypto_cxx_catapult_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver crypto_driver; static struct of_device_id crypto_device_ids[] = { - { - .name = "SLD_CRYPTO_CXX_CATAPULT", - }, - { - .name = "eb_091", - }, - { - .compatible = "sld,crypto_cxx_catapult", - }, - { }, + { + .name = "SLD_CRYPTO_CXX_CATAPULT", + }, + { + .name = "eb_091", + }, + { + .compatible = "sld,crypto_cxx_catapult", + }, + {}, }; static int crypto_devs; static inline struct crypto_cxx_catapult_device *to_crypto(struct esp_device *esp) { - return container_of(esp, struct crypto_cxx_catapult_device, esp); + return container_of(esp, struct crypto_cxx_catapult_device, esp); } static void crypto_prep_xfer(struct esp_device *esp, void *arg) { - struct crypto_cxx_catapult_access *a = arg; + struct crypto_cxx_catapult_access *a = arg; - /* <<--regs-config-->> */ + /* <<--regs-config-->> */ iowrite32be(a->crypto_algo, esp->iomem + CRYPTO_CXX_CRYPTO_ALGO_REG); iowrite32be(a->encryption, esp->iomem + CRYPTO_CXX_ENCRYPTION_REG); iowrite32be(a->sha1_in_bytes, esp->iomem + CRYPTO_CXX_SHA1_IN_BYTES_REG); @@ -72,81 +72,74 @@ static void crypto_prep_xfer(struct esp_device *esp, void *arg) iowrite32be(a->aes_aad_bytes, esp->iomem + CRYPTO_CXX_AES_AAD_BYTES_REG); iowrite32be(a->aes_tag_bytes, esp->iomem + CRYPTO_CXX_AES_TAG_BYTES_REG); iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool crypto_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct crypto_cxx_catapult_device *crypto = to_crypto(esp); */ - /* struct crypto_cxx_catapult_access *a = arg; */ + /* struct crypto_cxx_catapult_device *crypto = to_crypto(esp); */ + /* struct crypto_cxx_catapult_access *a = arg; */ - return true; + return true; } static int crypto_probe(struct platform_device *pdev) { - struct crypto_cxx_catapult_device *crypto; - struct esp_device *esp; - int rc; - - crypto = kzalloc(sizeof(*crypto), GFP_KERNEL); - if (crypto == NULL) - return -ENOMEM; - esp = &crypto->esp; - esp->module = THIS_MODULE; - esp->number = crypto_devs; - esp->driver = &crypto_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - crypto_devs++; - return 0; - err: - kfree(crypto); - return rc; + struct crypto_cxx_catapult_device *crypto; + struct esp_device *esp; + int rc; + + crypto = kzalloc(sizeof(*crypto), GFP_KERNEL); + if (crypto == NULL) return -ENOMEM; + esp = &crypto->esp; + esp->module = THIS_MODULE; + esp->number = crypto_devs; + esp->driver = &crypto_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + crypto_devs++; + return 0; +err: + kfree(crypto); + return rc; } static int __exit crypto_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct crypto_cxx_catapult_device *crypto = to_crypto(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct crypto_cxx_catapult_device *crypto = to_crypto(esp); - esp_device_unregister(esp); - kfree(crypto); - return 0; + esp_device_unregister(esp); + kfree(crypto); + return 0; } static struct esp_driver crypto_driver = { - .plat = { - .probe = crypto_probe, - .remove = crypto_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = crypto_device_ids, - }, - }, - .xfer_input_ok = crypto_xfer_input_ok, - .prep_xfer = crypto_prep_xfer, - .ioctl_cm = CRYPTO_CXX_CATAPULT_IOC_ACCESS, - .arg_size = sizeof(struct crypto_cxx_catapult_access), + .plat = + { + .probe = crypto_probe, + .remove = crypto_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = crypto_device_ids, + }, + }, + .xfer_input_ok = crypto_xfer_input_ok, + .prep_xfer = crypto_prep_xfer, + .ioctl_cm = CRYPTO_CXX_CATAPULT_IOC_ACCESS, + .arg_size = sizeof(struct crypto_cxx_catapult_access), }; -static int __init crypto_init(void) -{ - return esp_driver_register(&crypto_driver); -} +static int __init crypto_init(void) { return esp_driver_register(&crypto_driver); } -static void __exit crypto_exit(void) -{ - esp_driver_unregister(&crypto_driver); -} +static void __exit crypto_exit(void) { esp_driver_unregister(&crypto_driver); } -module_init(crypto_init) -module_exit(crypto_exit) +module_init(crypto_init) module_exit(crypto_exit) -MODULE_DEVICE_TABLE(of, crypto_device_ids); + MODULE_DEVICE_TABLE(of, crypto_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/include/crypto_cxx_catapult.h b/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/include/crypto_cxx_catapult.h index 7275a384cb..6a19594eb5 100644 --- a/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/include/crypto_cxx_catapult.h +++ b/accelerators/catapult_hls/crypto_cxx_catapult/sw/linux/include/crypto_cxx_catapult.h @@ -4,23 +4,23 @@ #define _CRYPTO_CXX_CATAPULT_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct crypto_cxx_catapult_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned crypto_algo; + struct esp_access esp; + /* <<--regs-->> */ + unsigned crypto_algo; unsigned encryption; unsigned sha1_in_bytes; unsigned sha2_in_bytes; @@ -32,10 +32,9 @@ struct crypto_cxx_catapult_access { unsigned aes_aad_bytes; unsigned aes_tag_bytes; unsigned src_offset; - unsigned dst_offset; - + unsigned dst_offset; }; -#define CRYPTO_CXX_CATAPULT_IOC_ACCESS _IOW ('S', 0, struct crypto_cxx_catapult_access) +#define CRYPTO_CXX_CATAPULT_IOC_ACCESS _IOW('S', 0, struct crypto_cxx_catapult_access) #endif /* _CRYPTO_CXX_CATAPULT_H_ */ diff --git a/accelerators/catapult_hls/mac_sysc_catapult/hw/inc/mac.hpp b/accelerators/catapult_hls/mac_sysc_catapult/hw/inc/mac.hpp old mode 100755 new mode 100644 index 6c87e99fdb..729eb7d074 --- a/accelerators/catapult_hls/mac_sysc_catapult/hw/inc/mac.hpp +++ b/accelerators/catapult_hls/mac_sysc_catapult/hw/inc/mac.hpp @@ -6,144 +6,135 @@ #pragma once -#include "mem_wrap.hpp" +#include "mac_conf_info.hpp" #include "mac_data_types.hpp" #include "mac_specs.hpp" -#include "mac_conf_info.hpp" +#include "mem_wrap.hpp" #define __round_mask(x, y) ((y)-1) -#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) +#define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1) SC_MODULE(mac_sysc_catapult) { -public: - sc_in CCS_INIT_S1(clk); - sc_in CCS_INIT_S1(rst); - sc_out CCS_INIT_S1(acc_done); - - Connections::In CCS_INIT_S1(conf_info); - Connections::In< ac_int > CCS_INIT_S1(dma_read_chnl); - Connections::Out< ac_int > CCS_INIT_S1(dma_write_chnl); - Connections::Out CCS_INIT_S1(dma_read_ctrl); - Connections::Out CCS_INIT_S1(dma_write_ctrl); - - void config(void); - void load(void); - void compute_dataReq(void); - void compute(void); - void store_dataReq(void); - void store(void); - - SC_CTOR(mac_sysc_catapult): plm_in_ping("plm_in_ping"), plm_in_pong("plm_in_pong"), plm_out_ping("plm_out_ping"), plm_out_pong("plm_out_pong"){ - - SC_THREAD(config); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(load); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(compute_dataReq); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(compute); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(store_dataReq); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(store); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - plm_in_ping.clk(clk); - plm_in_ping.rst(rst); - plm_in_ping.write_req(in_ping_w); - plm_in_ping.read_req(in_ping_ra); - plm_in_ping.read_rsp(in_ping_rd); - - plm_in_pong.clk(clk); - plm_in_pong.rst(rst); - plm_in_pong.write_req(in_pong_w); - plm_in_pong.read_req(in_pong_ra); - plm_in_pong.read_rsp(in_pong_rd); - - plm_out_ping.clk(clk); - plm_out_ping.rst(rst); - plm_out_ping.write_req(out_ping_w); - plm_out_ping.read_req(out_ping_ra); - plm_out_ping.read_rsp(out_ping_rd); - - plm_out_pong.clk(clk); - plm_out_pong.rst(rst); - plm_out_pong.write_req(out_pong_w); - plm_out_pong.read_req(out_pong_ra); - plm_out_pong.read_rsp(out_pong_rd); + public: + sc_in CCS_INIT_S1(clk); + sc_in CCS_INIT_S1(rst); + sc_out CCS_INIT_S1(acc_done); + + Connections::In CCS_INIT_S1(conf_info); + Connections::In> CCS_INIT_S1(dma_read_chnl); + Connections::Out> CCS_INIT_S1(dma_write_chnl); + Connections::Out CCS_INIT_S1(dma_read_ctrl); + Connections::Out CCS_INIT_S1(dma_write_ctrl); + + void config(void); + void load(void); + void compute_dataReq(void); + void compute(void); + void store_dataReq(void); + void store(void); + + SC_CTOR(mac_sysc_catapult) : + plm_in_ping("plm_in_ping"), plm_in_pong("plm_in_pong"), plm_out_ping("plm_out_ping"), + plm_out_pong("plm_out_pong") + { + + SC_THREAD(config); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(load); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(compute_dataReq); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(compute); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(store_dataReq); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(store); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + plm_in_ping.clk(clk); + plm_in_ping.rst(rst); + plm_in_ping.write_req(in_ping_w); + plm_in_ping.read_req(in_ping_ra); + plm_in_ping.read_rsp(in_ping_rd); + + plm_in_pong.clk(clk); + plm_in_pong.rst(rst); + plm_in_pong.write_req(in_pong_w); + plm_in_pong.read_req(in_pong_ra); + plm_in_pong.read_rsp(in_pong_rd); + + plm_out_ping.clk(clk); + plm_out_ping.rst(rst); + plm_out_ping.write_req(out_ping_w); + plm_out_ping.read_req(out_ping_ra); + plm_out_ping.read_rsp(out_ping_rd); + + plm_out_pong.clk(clk); + plm_out_pong.rst(rst); + plm_out_pong.write_req(out_pong_w); + plm_out_pong.read_req(out_pong_ra); + plm_out_pong.read_rsp(out_pong_rd); } - Connections::SyncChannel CCS_INIT_S1(sync12); - Connections::SyncChannel CCS_INIT_S1(sync12b); - Connections::SyncChannel CCS_INIT_S1(sync23); - Connections::SyncChannel CCS_INIT_S1(sync2b3); - Connections::SyncChannel CCS_INIT_S1(sync23b); - Connections::SyncChannel CCS_INIT_S1(sync2b3b); - - Connections::Combinational CCS_INIT_S1(sync01); - Connections::Combinational CCS_INIT_S1(sync02); - Connections::Combinational CCS_INIT_S1(sync02b); - Connections::Combinational CCS_INIT_S1(sync03); - Connections::Combinational CCS_INIT_S1(sync03b); - - Connections::Combinational CCS_INIT_S1(conf1); - Connections::Combinational CCS_INIT_S1(conf2); - Connections::Combinational CCS_INIT_S1(conf2b); - Connections::Combinational CCS_INIT_S1(conf3); - Connections::Combinational CCS_INIT_S1(conf3b); - - mem_wrap, - plm_RRq, - plm_RRs> CCS_INIT_S1(plm_in_ping); - mem_wrap, - plm_RRq, - plm_RRs> CCS_INIT_S1(plm_in_pong); - mem_wrap, - plm_RRq, - plm_RRs> CCS_INIT_S1(plm_out_ping); - mem_wrap, - plm_RRq, - plm_RRs> CCS_INIT_S1(plm_out_pong); - - Connections::Combinational> in_ping_w; - Connections::Combinational> in_ping_ra; - Connections::Combinational> in_ping_rd; - - Connections::Combinational> in_pong_w; - Connections::Combinational> in_pong_ra; - Connections::Combinational> in_pong_rd; - - Connections::Combinational> out_ping_w; - Connections::Combinational> out_ping_ra; - Connections::Combinational> out_ping_rd; - - Connections::Combinational> out_pong_w; - Connections::Combinational> out_pong_ra; - Connections::Combinational> out_pong_rd; + Connections::SyncChannel CCS_INIT_S1(sync12); + Connections::SyncChannel CCS_INIT_S1(sync12b); + Connections::SyncChannel CCS_INIT_S1(sync23); + Connections::SyncChannel CCS_INIT_S1(sync2b3); + Connections::SyncChannel CCS_INIT_S1(sync23b); + Connections::SyncChannel CCS_INIT_S1(sync2b3b); + + Connections::Combinational CCS_INIT_S1(sync01); + Connections::Combinational CCS_INIT_S1(sync02); + Connections::Combinational CCS_INIT_S1(sync02b); + Connections::Combinational CCS_INIT_S1(sync03); + Connections::Combinational CCS_INIT_S1(sync03b); + + Connections::Combinational CCS_INIT_S1(conf1); + Connections::Combinational CCS_INIT_S1(conf2); + Connections::Combinational CCS_INIT_S1(conf2b); + Connections::Combinational CCS_INIT_S1(conf3); + Connections::Combinational CCS_INIT_S1(conf3b); + + mem_wrap, + plm_RRq, plm_RRs> + CCS_INIT_S1(plm_in_ping); + mem_wrap, + plm_RRq, plm_RRs> + CCS_INIT_S1(plm_in_pong); + mem_wrap, + plm_RRq, plm_RRs> + CCS_INIT_S1(plm_out_ping); + mem_wrap, + plm_RRq, plm_RRs> + CCS_INIT_S1(plm_out_pong); + + Connections::Combinational> in_ping_w; + Connections::Combinational> in_ping_ra; + Connections::Combinational> in_ping_rd; + + Connections::Combinational> in_pong_w; + Connections::Combinational> in_pong_ra; + Connections::Combinational> in_pong_rd; + + Connections::Combinational> out_ping_w; + Connections::Combinational> out_ping_ra; + Connections::Combinational> out_ping_rd; + + Connections::Combinational> out_pong_w; + Connections::Combinational> out_pong_ra; + Connections::Combinational> out_pong_rd; }; #endif diff --git a/accelerators/catapult_hls/mac_sysc_catapult/hw/inc/mem_bank/DUAL_PORT_RBW.v b/accelerators/catapult_hls/mac_sysc_catapult/hw/inc/mem_bank/DUAL_PORT_RBW.v index 72683e00b2..1ca03c177c 100755 --- a/accelerators/catapult_hls/mac_sysc_catapult/hw/inc/mem_bank/DUAL_PORT_RBW.v +++ b/accelerators/catapult_hls/mac_sysc_catapult/hw/inc/mem_bank/DUAL_PORT_RBW.v @@ -2,32 +2,40 @@ // SPDX-License-Identifier: Apache-2.0 module DUAL_PORT_RBW #( - parameter AddressSz = 32 , - parameter data_width = 8 , - parameter Sz = 128 -)( clk,clk_en,din,qout,r_adr,w_adr,w_en); + parameter AddressSz = 32, + parameter data_width = 8, + parameter Sz = 128 +) ( + clk, + clk_en, + din, + qout, + r_adr, + w_adr, + w_en +); - input clk; - input clk_en; - input [data_width-1:0] din; - output [data_width-1:0] qout; - input [AddressSz-1:0] r_adr; - input [AddressSz-1:0] w_adr; - input w_en; + input clk; + input clk_en; + input [data_width-1:0] din; + output [data_width-1:0] qout; + input [AddressSz-1:0] r_adr; + input [AddressSz-1:0] w_adr; + input w_en; - (* ram_style = "block" *) - reg [data_width-1:0] out; - reg [data_width-1:0] arr [Sz-1:0]; + (* ram_style = "block" *) + reg [data_width-1:0] out; + reg [data_width-1:0] arr [Sz-1:0]; - always @(posedge clk) begin - if (clk_en) begin - out <= arr[r_adr]; - if (w_en) begin - arr[w_adr] <= din; - end - end - end + always @(posedge clk) begin + if (clk_en) begin + out <= arr[r_adr]; + if (w_en) begin + arr[w_adr] <= din; + end + end + end - assign qout = out; + assign qout = out; endmodule diff --git a/accelerators/catapult_hls/mac_sysc_catapult/hw/src/mac.cpp b/accelerators/catapult_hls/mac_sysc_catapult/hw/src/mac.cpp index 2b1effe21b..dbca92fc6a 100644 --- a/accelerators/catapult_hls/mac_sysc_catapult/hw/src/mac.cpp +++ b/accelerators/catapult_hls/mac_sysc_catapult/hw/src/mac.cpp @@ -1,10 +1,11 @@ -//Copyright (c) 2011-2024 Columbia University, System Level Design Group -//SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2011-2024 Columbia University, System Level Design Group +// SPDX-License-Identifier: Apache-2.0 #include "mac.hpp" #include -void mac_sysc_catapult:: config() { +void mac_sysc_catapult::config() +{ conf_info.Reset(); conf1.ResetWrite(); conf2.ResetWrite(); @@ -20,7 +21,7 @@ void mac_sysc_catapult:: config() { wait(); - while(1) { + while (1) { conf_info_t conf_di = conf_info.Pop(); conf1.Push(conf_di); @@ -34,13 +35,11 @@ void mac_sysc_catapult:: config() { sync02b.Push(1); sync03.Push(1); sync03b.Push(1); - } } - - -void mac_sysc_catapult:: load() { +void mac_sysc_catapult::load() +{ bool ping_pong = false; dma_read_chnl.Reset(); dma_read_ctrl.Reset(); @@ -56,32 +55,30 @@ void mac_sysc_catapult:: load() { wait(); - while(1) { + while (1) { sync01.Pop(); - bool ping = true; + bool ping = true; uint32_t offset = 0; - conf_info_t conf=conf1.Pop(); + conf_info_t conf = conf1.Pop(); /* <<--local-params-->> */ - uint32_t mac_n = conf.mac_n; + uint32_t mac_n = conf.mac_n; uint32_t mac_vec = conf.mac_vec; uint32_t mac_len = conf.mac_len; // Batching - for (uint16_t b = 0; b < mac_n; b++) - { + for (uint16_t b = 0; b < mac_n; b++) { wait(); #if (DMA_WORD_PER_BEAT == 0) - uint32_t len = mac_len*mac_vec; + uint32_t len = mac_len * mac_vec; #else - uint32_t len=round_up(mac_len*mac_vec, DMA_WORD_PER_BEAT); + uint32_t len = round_up(mac_len * mac_vec, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = len; rem > 0; rem -= PLM_IN_WORD) - { + for (int rem = len; rem > 0; rem -= PLM_IN_WORD) { uint32_t len1 = rem > PLM_IN_WORD ? PLM_IN_WORD : rem; #if (DMA_WORD_PER_BEAT == 0) @@ -90,50 +87,45 @@ void mac_sysc_catapult:: load() { dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len1 / DMA_WORD_PER_BEAT, DMA_SIZE); #endif - offset +=len1; + offset += len1; dma_read_ctrl.Push(dma_info); #if (DMA_WORD_PER_BEAT == 0) - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stallt_mode flush - for (uint32_t i =0; i < len1; i++) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stallt_mode flush + for (uint32_t i = 0; i < len1; i++) { ac_int dataBv; - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stallt_mode flush - for (uint32_t k=0; k< DMA_BEAT_PER_WORD; k++) - { - ac_int data_m=dma_read_chnl.Pop(); - dataBv.set_slc(k*DMA_WIDTH, data_m); + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stallt_mode flush + for (uint32_t k = 0; k < DMA_BEAT_PER_WORD; k++) { + ac_int data_m = dma_read_chnl.Pop(); + dataBv.set_slc(k * DMA_WIDTH, data_m); } - plm_WR wreq; - wreq.indx[0]=i; - wreq.data[0]=dataBv; + plm_WR wreq; + wreq.indx[0] = i; + wreq.data[0] = dataBv; - if (ping_pong) - in_ping_w.Push(wreq); + if (ping_pong) in_ping_w.Push(wreq); else in_pong_w.Push(wreq); } #else - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stallt_mode flush - for (uint32_t i=0; i < len1; i+= DMA_WORD_PER_BEAT) { - DMA_WORD data_dma=dma_read_chnl.Pop(); - - plm_WR wreq; - - #pragma hls_unroll yes - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { - wreq.indx[k]=i+k; - wreq.data[k]=data_dma.slc(k * DATA_WIDTH); + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stallt_mode flush + for (uint32_t i = 0; i < len1; i += DMA_WORD_PER_BEAT) { + DMA_WORD data_dma = dma_read_chnl.Pop(); + + plm_WR wreq; + + #pragma hls_unroll yes + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + wreq.indx[k] = i + k; + wreq.data[k] = data_dma.slc(k * DATA_WIDTH); } - if (ping_pong) - in_ping_w.Push(wreq); + if (ping_pong) in_ping_w.Push(wreq); else in_pong_w.Push(wreq); } @@ -149,7 +141,8 @@ void mac_sysc_catapult:: load() { } } -void mac_sysc_catapult::compute_dataReq() { +void mac_sysc_catapult::compute_dataReq() +{ bool ping_pong = false; sync12.reset_sync_in(); @@ -164,48 +157,44 @@ void mac_sysc_catapult::compute_dataReq() { wait(); - while(1) { + while (1) { sync02.Pop(); - conf_info_t conf=conf2.Pop(); + conf_info_t conf = conf2.Pop(); /* <<--local-params-->> */ - uint32_t mac_n = conf.mac_n; + uint32_t mac_n = conf.mac_n; uint32_t mac_vec = conf.mac_vec; uint32_t mac_len = conf.mac_len; // Batching - for (uint16_t b = 0; b < mac_n; b++) - { + for (uint16_t b = 0; b < mac_n; b++) { wait(); // Chunking - for (int in_rem = mac_len*mac_vec ; in_rem > 0; in_rem -= PLM_IN_WORD) - { + for (int in_rem = mac_len * mac_vec; in_rem > 0; in_rem -= PLM_IN_WORD) { - uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; + uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; sync12.sync_in(); - //Send read memory requests to input PLM - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i=0; i < in_len; i++) { +// Send read memory requests to input PLM +#pragma hls_pipeline_init_interval 1 +#pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < in_len; i++) { wait(); FPDATA_WORD op[2]; - plm_RRq rreq; + plm_RRq rreq; - rreq.indx[0]=i; + rreq.indx[0] = i; - if (ping_pong) - in_ping_ra.Push(rreq); + if (ping_pong) in_ping_ra.Push(rreq); else in_pong_ra.Push(rreq); - } sync23.sync_out(); @@ -216,9 +205,10 @@ void mac_sysc_catapult::compute_dataReq() { } } -void mac_sysc_catapult:: compute() { +void mac_sysc_catapult::compute() +{ - bool ping_pong = false; + bool ping_pong = false; bool out_ping_pong = false; sync12b.reset_sync_in(); sync2b3.reset_sync_out(); @@ -234,80 +224,78 @@ void mac_sysc_catapult:: compute() { wait(); - while(1) { + while (1) { sync02b.Pop(); - conf_info_t conf=conf2b.Pop(); + conf_info_t conf = conf2b.Pop(); /* <<--local-params-->> */ - uint32_t mac_n = conf.mac_n; + uint32_t mac_n = conf.mac_n; uint32_t mac_vec = conf.mac_vec; uint32_t mac_len = conf.mac_len; // Batching - for (uint16_t b = 0; b < mac_n; b++) - { + for (uint16_t b = 0; b < mac_n; b++) { wait(); - uint32_t in_length = mac_len*mac_vec; + uint32_t in_length = mac_len * mac_vec; // Chunking - for (int in_rem = in_length; in_rem > 0; in_rem -= PLM_IN_WORD) - { + for (int in_rem = in_length; in_rem > 0; in_rem -= PLM_IN_WORD) { - uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; + uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; sync12b.sync_in(); // Compute Kernel - FPDATA acc_fx=0; - uint32_t vec_indx=0; - uint32_t vec_num=0; + FPDATA acc_fx = 0; + uint32_t vec_indx = 0; + uint32_t vec_num = 0; #pragma hls_pipeline_init_interval 2 #pragma pipeline_stall_mode flush - for (uint32_t i=0; i < in_len; i+=2) { + for (uint32_t i = 0; i < in_len; i += 2) { FPDATA_WORD op[2]; if (ping_pong) { - op[0]=in_ping_rd.Pop().data[0]; - op[1]=in_ping_rd.Pop().data[0]; - } else { - op[0]=in_pong_rd.Pop().data[0]; - op[1]=in_pong_rd.Pop().data[0]; + op[0] = in_ping_rd.Pop().data[0]; + op[1] = in_ping_rd.Pop().data[0]; + } + else { + op[0] = in_pong_rd.Pop().data[0]; + op[1] = in_pong_rd.Pop().data[0]; } - FPDATA op0_fx=0; - FPDATA op1_fx=0; + FPDATA op0_fx = 0; + FPDATA op1_fx = 0; - int2fx(op[0],op0_fx); - int2fx(op[1],op1_fx); + int2fx(op[0], op0_fx); + int2fx(op[1], op1_fx); // Multiply and accumulate - acc_fx+=op0_fx * op1_fx; + acc_fx += op0_fx * op1_fx; - vec_indx+=2; + vec_indx += 2; // Write accumulated result if (vec_indx == mac_len) { - FPDATA_WORD acc=0; - fx2int(acc_fx,acc); + FPDATA_WORD acc = 0; + fx2int(acc_fx, acc); plm_WR wreq; - wreq.indx[0]=vec_num; - wreq.data[0]=acc; + wreq.indx[0] = vec_num; + wreq.data[0] = acc; - if (out_ping_pong) - out_ping_w.Push(wreq); + if (out_ping_pong) out_ping_w.Push(wreq); else out_pong_w.Push(wreq); vec_num++; - vec_indx=0; - acc_fx=0; + vec_indx = 0; + acc_fx = 0; } } @@ -324,7 +312,8 @@ void mac_sysc_catapult:: compute() { } } -void mac_sysc_catapult:: store_dataReq() { +void mac_sysc_catapult::store_dataReq() +{ bool ping_pong = false; sync23.reset_sync_in(); @@ -338,20 +327,19 @@ void mac_sysc_catapult:: store_dataReq() { wait(); - while(1) { + while (1) { sync03.Pop(); - conf_info_t conf=conf3.Pop(); + conf_info_t conf = conf3.Pop(); /* <<--local-params-->> */ - uint32_t mac_n = conf.mac_n; + uint32_t mac_n = conf.mac_n; uint32_t mac_vec = conf.mac_vec; uint32_t mac_len = conf.mac_len; // Batching - for (uint16_t b = 0; b < mac_n; b++) - { + for (uint16_t b = 0; b < mac_n; b++) { wait(); #if (DMA_WORD_PER_BEAT == 0) @@ -360,8 +348,7 @@ void mac_sysc_catapult:: store_dataReq() { uint32_t length = round_up(mac_vec, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) { sync23.sync_in(); sync2b3.sync_in(); @@ -369,36 +356,30 @@ void mac_sysc_catapult:: store_dataReq() { uint32_t len = rem > PLM_OUT_WORD ? PLM_OUT_WORD : rem; #if (DMA_WORD_PER_BEAT == 0) - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i = 0; i < len; i++) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < len; i++) { FPDATA_WORD dataBv; - plm_RRq rreq; - rreq.indx[0]=i; + plm_RRq rreq; + rreq.indx[0] = i; - if(ping_pong) - out_ping_ra.Push(rreq); + if (ping_pong) out_ping_ra.Push(rreq); else out_pong_ra.Push(rreq); - } #else - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { DMA_WORD dataBv; - plm_RRq rreq; - for (int k = 0; k < DMA_WORD_PER_BEAT; k++) - { - rreq.indx[k]=i+k; + plm_RRq rreq; + for (int k = 0; k < DMA_WORD_PER_BEAT; k++) { + rreq.indx[k] = i + k; } - if(ping_pong) - out_ping_ra.Push(rreq); + if (ping_pong) out_ping_ra.Push(rreq); else out_pong_ra.Push(rreq); } @@ -410,8 +391,8 @@ void mac_sysc_catapult:: store_dataReq() { } } - -void mac_sysc_catapult:: store() { +void mac_sysc_catapult::store() +{ bool ping_pong = false; dma_write_chnl.Reset(); @@ -430,38 +411,35 @@ void mac_sysc_catapult:: store() { wait(); - while(1) { + while (1) { sync03b.Pop(); - conf_info_t conf=conf3b.Pop(); + conf_info_t conf = conf3b.Pop(); /* <<--local-params-->> */ - uint32_t mac_n = conf.mac_n; + uint32_t mac_n = conf.mac_n; uint32_t mac_vec = conf.mac_vec; uint32_t mac_len = conf.mac_len; #if (DMA_WORD_PER_BEAT == 0) - uint32_t store_offset = mac_len*mac_vec * mac_n; + uint32_t store_offset = mac_len * mac_vec * mac_n; #else - uint32_t store_offset = round_up(mac_len*mac_vec, DMA_WORD_PER_BEAT) * mac_n; + uint32_t store_offset = round_up(mac_len * mac_vec, DMA_WORD_PER_BEAT) * mac_n; #endif uint32_t offset = store_offset; // Batching - for (uint16_t b = 0; b < mac_n; b++) - { + for (uint16_t b = 0; b < mac_n; b++) { wait(); - #if (DMA_WORD_PER_BEAT == 0) uint32_t length = mac_vec; #else uint32_t length = round_up(mac_vec, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) { sync23b.sync_in(); sync2b3b.sync_in(); @@ -478,41 +456,34 @@ void mac_sysc_catapult:: store() { dma_write_ctrl.Push(dma_info); #if (DMA_WORD_PER_BEAT == 0) - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i = 0; i < len; i++) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < len; i++) { FPDATA_WORD dataBv; - if(ping_pong) - dataBv=out_ping_rd.Pop().data[0]; + if (ping_pong) dataBv = out_ping_rd.Pop().data[0]; else - dataBv=out_pong_rd.Pop().data[0]; + dataBv = out_pong_rd.Pop().data[0]; - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode flush - for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) - { - dma_write_chnl.Push(dataBv.slc(k*DMA_WIDTH)); + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode flush + for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) { + dma_write_chnl.Push(dataBv.slc(k * DMA_WIDTH)); } - } #else - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { DMA_WORD dataBv; - if(ping_pong) - rrsp=out_ping_rd.Pop(); + if (ping_pong) rrsp = out_ping_rd.Pop(); else - rrsp=out_pong_rd.Pop(); + rrsp = out_pong_rd.Pop(); - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { - dataBv.set_slc(k *DATA_WIDTH,rrsp.data[k]); + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + dataBv.set_slc(k * DATA_WIDTH, rrsp.data[k]); } dma_write_chnl.Push(dataBv); @@ -524,10 +495,8 @@ void mac_sysc_catapult:: store() { } wait(); - acc_done.write(true); wait(); + acc_done.write(true); + wait(); acc_done.write(false); } } - - - diff --git a/accelerators/catapult_hls/mac_sysc_catapult/hw/tb/sc_main.cpp b/accelerators/catapult_hls/mac_sysc_catapult/hw/tb/sc_main.cpp old mode 100755 new mode 100644 index 3403dd8456..488a7b4de9 --- a/accelerators/catapult_hls/mac_sysc_catapult/hw/tb/sc_main.cpp +++ b/accelerators/catapult_hls/mac_sysc_catapult/hw/tb/sc_main.cpp @@ -1,13 +1,13 @@ -//Copyright (c) 2011-2024 Columbia University, System Level Design Group -//SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2011-2024 Columbia University, System Level Design Group +// SPDX-License-Identifier: Apache-2.0 #include "system.hpp" -#include #include +#include sc_trace_file *trace_file_ptr; -int sc_main (int argc, char *argv[]) +int sc_main(int argc, char *argv[]) { sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); sc_report_handler::set_actions(SC_ERROR, SC_DISPLAY); @@ -19,12 +19,10 @@ int sc_main (int argc, char *argv[]) sc_start(); int errcnt = sc_report_handler::get_count(SC_ERROR); - if (errcnt > 0) { - std::cout << "Simulation FAILED\n"; - } else { + if (errcnt > 0) { std::cout << "Simulation FAILED\n"; } + else { std::cout << "Simulation PASSED\n"; } return errcnt; // return 0 for passed } - diff --git a/accelerators/catapult_hls/mac_sysc_catapult/sw/baremetal/mac.c b/accelerators/catapult_hls/mac_sysc_catapult/sw/baremetal/mac.c index 5ab0e80d62..9b02956fe9 100644 --- a/accelerators/catapult_hls/mac_sysc_catapult/sw/baremetal/mac.c +++ b/accelerators/catapult_hls/mac_sysc_catapult/sw/baremetal/mac.c @@ -3,7 +3,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -12,17 +12,13 @@ typedef int32_t token_t; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } - -#define SLD_MAC 0x04a +#define SLD_MAC 0x04a #define DEV_NAME "sld,mac_sysc_catapult" /* <<--params-->> */ -const int32_t mac_n = 1; +const int32_t mac_n = 1; const int32_t mac_vec = 8; const int32_t mac_len = 16; @@ -37,193 +33,186 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ -#define MAC_MAC_N_REG 0x48 +#define MAC_MAC_N_REG 0x48 #define MAC_MAC_VEC_REG 0x44 #define MAC_MAC_LEN_REG 0x40 - static int validate_buf(token_t *out, token_t *gold) { - int i; - int j; - unsigned errors = 0; + int i; + int j; + unsigned errors = 0; - for (i = 0; i < mac_n; i++) - for (j = 0; j < mac_vec; j++) - if (gold[i * out_words_adj + j] != out[i * out_words_adj + j]) - errors++; + for (i = 0; i < mac_n; i++) + for (j = 0; j < mac_vec; j++) + if (gold[i * out_words_adj + j] != out[i * out_words_adj + j]) errors++; - return errors; + return errors; } +static void init_buf(token_t *in, token_t *gold) +{ + int i; + int j; + int k = 0; + float out_gold; + + for (i = 0; i < mac_n; i++) { + for (j = 0; j < mac_len * mac_vec; j++) { + float data = ((i * 8 + j + k) % 32) + 0.25; + token_t data_fxd = float_to_fixed32(data, 16); + in[i * in_words_adj + j] = data_fxd; + } + k++; + } + + for (i = 0; i < mac_n; i++) + for (j = 0; j < mac_vec; j++) { + out_gold = 0; + for (k = 0; k < mac_len; k += 2) { + float data1 = fixed32_to_float(in[i * in_words_adj + j * mac_len + k], 16); + float data2 = fixed32_to_float(in[i * in_words_adj + j * mac_len + k + 1], 16); + out_gold += data1 * data2; + } + gold[i * out_words_adj + j] = float_to_fixed32(out_gold, 16); + } +} -static void init_buf (token_t *in, token_t * gold) +int main(int argc, char *argv[]) { - int i; - int j; - int k=0; - float out_gold; - - for (i = 0; i < mac_n; i++){ - for (j = 0; j < mac_len * mac_vec ; j++){ - float data = ((i * 8 + j + k) % 32) + 0.25; - token_t data_fxd = float_to_fixed32(data, 16); - in[i * in_words_adj + j] = data_fxd; - } - k++; + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable; + token_t *mem; + token_t *gold; + unsigned errors = 0; + unsigned coherence; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = mac_len * mac_vec; + out_words_adj = mac_vec; + } + else { + in_words_adj = round_up(mac_len * mac_vec, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(mac_vec, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (mac_n); + out_len = out_words_adj * (mac_n); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_MAC, DEV_NAME); + if (ndev == 0) { + printf("mac not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + printf("**************** %s.%d ****************\n", DEV_NAME, n); + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; } - for (i = 0; i < mac_n; i++) - for (j = 0; j < mac_vec; j++) { - out_gold = 0; - for (k = 0; k < mac_len; k += 2){ - float data1=fixed32_to_float(in[i * in_words_adj + j * mac_len + k], 16); - float data2=fixed32_to_float(in[i * in_words_adj + j * mac_len + k + 1],16); - out_gold += data1*data2; - } - gold[i * out_words_adj + j]= float_to_fixed32(out_gold,16); - } -} + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + // Allocate memory + gold = aligned_malloc(out_size); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); -int main(int argc, char * argv[]) -{ - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable; - token_t *mem; - token_t *gold; - unsigned errors = 0; - unsigned coherence; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = mac_len*mac_vec; - out_words_adj = mac_vec; - } else { - in_words_adj = round_up(mac_len*mac_vec, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(mac_vec, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (mac_n); - out_len = out_words_adj * (mac_n); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_MAC, DEV_NAME); - if (ndev == 0) { - printf("mac not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - printf("**************** %s.%d ****************\n", DEV_NAME, n); - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_size); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - - // Alocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_RECALL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_RECALL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - printf(" --------------------\n"); - printf(" Generate input...\n"); - init_buf(mem, gold); + printf(" --------------------\n"); + printf(" Generate input...\n"); + init_buf(mem, gold); - // Pass common configuration parameters + // Pass common configuration parameters - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); #ifndef __sparc - iowrite32(dev, PT_ADDRESS_REG, (unsigned long long) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned long long)ptable); #else - iowrite32(dev, PT_ADDRESS_REG, (unsigned) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned)ptable); #endif - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - iowrite32(dev, MAC_MAC_N_REG, mac_n); - iowrite32(dev, MAC_MAC_VEC_REG, mac_vec); - iowrite32(dev, MAC_MAC_LEN_REG, mac_len); - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + iowrite32(dev, MAC_MAC_N_REG, mac_n); + iowrite32(dev, MAC_MAC_VEC_REG, mac_vec); + iowrite32(dev, MAC_MAC_LEN_REG, mac_len); + + // Flush (customize coherence model here) + esp_flush(coherence); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/app/mac.c b/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/app/mac.c index c1ac0d8107..13308fc675 100644 --- a/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/app/mac.c +++ b/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/app/mac.c @@ -1,7 +1,7 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include "libesp.h" #include "cfg.h" +#include "libesp.h" static unsigned in_words_adj; static unsigned out_words_adj; @@ -15,106 +15,102 @@ static unsigned size; /* User-defined code */ static int validate_buffer(token_t *out, token_t *gold) { - int i; - int j; - unsigned errors = 0; + int i; + int j; + unsigned errors = 0; - for (i = 0; i < mac_n; i++) - for (j = 0; j < mac_vec; j++) - if (gold[i * out_words_adj + j] != out[i * out_words_adj + j]) - errors++; + for (i = 0; i < mac_n; i++) + for (j = 0; j < mac_vec; j++) + if (gold[i * out_words_adj + j] != out[i * out_words_adj + j]) errors++; - return errors; + return errors; } - /* User-defined code */ -static void init_buffer(token_t *in, token_t * gold) +static void init_buffer(token_t *in, token_t *gold) { - int i; - int j; - int k=0; - float out_gold; - - for (i = 0; i < mac_n; i++){ - for (j = 0; j < mac_len * mac_vec ; j++){ - float data = ((i * 8 + j + k) % 32) + 0.25; - token_t data_fxd = float_to_fixed32(data, 16); - in[i * in_words_adj + j] = data_fxd; - } - k++; + int i; + int j; + int k = 0; + float out_gold; + + for (i = 0; i < mac_n; i++) { + for (j = 0; j < mac_len * mac_vec; j++) { + float data = ((i * 8 + j + k) % 32) + 0.25; + token_t data_fxd = float_to_fixed32(data, 16); + in[i * in_words_adj + j] = data_fxd; + } + k++; + } + + for (i = 0; i < mac_n; i++) + for (j = 0; j < mac_vec; j++) { + out_gold = 0; + for (k = 0; k < mac_len; k += 2) { + float data1 = fixed32_to_float(in[i * in_words_adj + j * mac_len + k], 16); + float data2 = fixed32_to_float(in[i * in_words_adj + j * mac_len + k + 1], 16); + out_gold += data1 * data2; + } + gold[i * out_words_adj + j] = float_to_fixed32(out_gold, 16); } - - for (i = 0; i < mac_n; i++) - for (j = 0; j < mac_vec; j++) { - out_gold = 0; - for (k = 0; k < mac_len; k += 2){ - float data1=fixed32_to_float(in[i * in_words_adj + j * mac_len + k], 16); - float data2=fixed32_to_float(in[i * in_words_adj + j * mac_len + k + 1],16); - out_gold += data1*data2; - } - gold[i * out_words_adj + j]= float_to_fixed32(out_gold,16); - } } - /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = mac_len*mac_vec; - out_words_adj = mac_vec; - } else { - in_words_adj = round_up(mac_len*mac_vec, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(mac_vec, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (mac_n); - out_len = out_words_adj * (mac_n); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = mac_len * mac_vec; + out_words_adj = mac_vec; + } + else { + in_words_adj = round_up(mac_len * mac_vec, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(mac_vec, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (mac_n); + out_len = out_words_adj * (mac_n); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + size = (out_offset * sizeof(token_t)) + out_size; } - int main(int argc, char **argv) { - int errors; + int errors; + + token_t *gold; + token_t *buf; - token_t *gold; - token_t *buf; + init_parameters(); - init_parameters(); + buf = (token_t *)esp_alloc(size); + cfg_000[0].hw_buf = buf; - buf = (token_t *) esp_alloc(size); - cfg_000[0].hw_buf = buf; - - gold = malloc(out_size); + gold = malloc(out_size); - init_buffer(buf, gold); + init_buffer(buf, gold); - printf("\n====== %s ======\n\n", cfg_000[0].devname); - /* <<--print-params-->> */ - printf(" .mac_n = %d\n", mac_n); - printf(" .mac_vec = %d\n", mac_vec); - printf(" .mac_len = %d\n", mac_len); - printf("\n ** START **\n"); + printf("\n====== %s ======\n\n", cfg_000[0].devname); + /* <<--print-params-->> */ + printf(" .mac_n = %d\n", mac_n); + printf(" .mac_vec = %d\n", mac_vec); + printf(" .mac_len = %d\n", mac_len); + printf("\n ** START **\n"); - esp_run(cfg_000, NACC); + esp_run(cfg_000, NACC); - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - errors = validate_buffer(&buf[out_offset], gold); + errors = validate_buffer(&buf[out_offset], gold); - free(gold); - esp_free(buf); + free(gold); + esp_free(buf); - if (!errors) - printf("+ Test PASSED\n"); - else - printf("+ Test FAILED\n"); + if (!errors) printf("+ Test PASSED\n"); + else + printf("+ Test FAILED\n"); - printf("\n====== %s ======\n\n", cfg_000[0].devname); + printf("\n====== %s ======\n\n", cfg_000[0].devname); - return errors; + return errors; } diff --git a/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/driver/mac_sysc_catapult.c b/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/driver/mac_sysc_catapult.c index fc50ed5d3b..64fba5e176 100644 --- a/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/driver/mac_sysc_catapult.c +++ b/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/driver/mac_sysc_catapult.c @@ -1,133 +1,125 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "mac_sysc_catapult.h" -#define DRV_NAME "mac_sysc_catapult" +#define DRV_NAME "mac_sysc_catapult" /* <<--regs-->> */ -#define MAC_MAC_N_REG 0x48 +#define MAC_MAC_N_REG 0x48 #define MAC_MAC_VEC_REG 0x44 #define MAC_MAC_LEN_REG 0x40 struct mac_sysc_catapult_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver mac_driver; static struct of_device_id mac_device_ids[] = { - { - .name = "SLD_MAC_SYSC_CATAPULT", - }, - { - .name = "eb_04a", - }, - { - .compatible = "sld,mac_sysc_catapult", - }, - { }, + { + .name = "SLD_MAC_SYSC_CATAPULT", + }, + { + .name = "eb_04a", + }, + { + .compatible = "sld,mac_sysc_catapult", + }, + {}, }; static int mac_devs; static inline struct mac_sysc_catapult_device *to_mac(struct esp_device *esp) { - return container_of(esp, struct mac_sysc_catapult_device, esp); + return container_of(esp, struct mac_sysc_catapult_device, esp); } static void mac_prep_xfer(struct esp_device *esp, void *arg) { - struct mac_sysc_catapult_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->mac_n, esp->iomem + MAC_MAC_N_REG); - iowrite32be(a->mac_vec, esp->iomem + MAC_MAC_VEC_REG); - iowrite32be(a->mac_len, esp->iomem + MAC_MAC_LEN_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); - + struct mac_sysc_catapult_access *a = arg; + + /* <<--regs-config-->> */ + iowrite32be(a->mac_n, esp->iomem + MAC_MAC_N_REG); + iowrite32be(a->mac_vec, esp->iomem + MAC_MAC_VEC_REG); + iowrite32be(a->mac_len, esp->iomem + MAC_MAC_LEN_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool mac_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct mac_sysc_catapult_device *mac = to_mac(esp); */ - /* struct mac_sysc_catapult_access *a = arg; */ + /* struct mac_sysc_catapult_device *mac = to_mac(esp); */ + /* struct mac_sysc_catapult_access *a = arg; */ - return true; + return true; } static int mac_probe(struct platform_device *pdev) { - struct mac_sysc_catapult_device *mac; - struct esp_device *esp; - int rc; - - mac = kzalloc(sizeof(*mac), GFP_KERNEL); - if (mac == NULL) - return -ENOMEM; - esp = &mac->esp; - esp->module = THIS_MODULE; - esp->number = mac_devs; - esp->driver = &mac_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - mac_devs++; - return 0; - err: - kfree(mac); - return rc; + struct mac_sysc_catapult_device *mac; + struct esp_device *esp; + int rc; + + mac = kzalloc(sizeof(*mac), GFP_KERNEL); + if (mac == NULL) return -ENOMEM; + esp = &mac->esp; + esp->module = THIS_MODULE; + esp->number = mac_devs; + esp->driver = &mac_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + mac_devs++; + return 0; +err: + kfree(mac); + return rc; } static int __exit mac_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct mac_sysc_catapult_device *mac = to_mac(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct mac_sysc_catapult_device *mac = to_mac(esp); - esp_device_unregister(esp); - kfree(mac); - return 0; + esp_device_unregister(esp); + kfree(mac); + return 0; } static struct esp_driver mac_driver = { - .plat = { - .probe = mac_probe, - .remove = mac_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = mac_device_ids, - }, - }, - .xfer_input_ok = mac_xfer_input_ok, - .prep_xfer = mac_prep_xfer, - .ioctl_cm = MAC_SYSC_CATAPULT_IOC_ACCESS, - .arg_size = sizeof(struct mac_sysc_catapult_access), + .plat = + { + .probe = mac_probe, + .remove = mac_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = mac_device_ids, + }, + }, + .xfer_input_ok = mac_xfer_input_ok, + .prep_xfer = mac_prep_xfer, + .ioctl_cm = MAC_SYSC_CATAPULT_IOC_ACCESS, + .arg_size = sizeof(struct mac_sysc_catapult_access), }; -static int __init mac_init(void) -{ - return esp_driver_register(&mac_driver); -} +static int __init mac_init(void) { return esp_driver_register(&mac_driver); } -static void __exit mac_exit(void) -{ - esp_driver_unregister(&mac_driver); -} +static void __exit mac_exit(void) { esp_driver_unregister(&mac_driver); } -module_init(mac_init) -module_exit(mac_exit) +module_init(mac_init) module_exit(mac_exit) -MODULE_DEVICE_TABLE(of, mac_device_ids); + MODULE_DEVICE_TABLE(of, mac_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/include/mac_sysc_catapult.h b/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/include/mac_sysc_catapult.h index 8185fbed7e..9e89c094e4 100644 --- a/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/include/mac_sysc_catapult.h +++ b/accelerators/catapult_hls/mac_sysc_catapult/sw/linux/include/mac_sysc_catapult.h @@ -4,29 +4,29 @@ #define _MAC_SYSC_CATAPULT_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct mac_sysc_catapult_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned mac_n; - unsigned mac_vec; - unsigned mac_len; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned mac_n; + unsigned mac_vec; + unsigned mac_len; + unsigned src_offset; + unsigned dst_offset; }; -#define MAC_SYSC_CATAPULT_IOC_ACCESS _IOW ('S', 0, struct mac_sysc_catapult_access) +#define MAC_SYSC_CATAPULT_IOC_ACCESS _IOW('S', 0, struct mac_sysc_catapult_access) #endif /* _MAC_SYSC_CATAPULT_H_ */ diff --git a/accelerators/chisel/adder_chisel/sw/baremetal/adder.c b/accelerators/chisel/adder_chisel/sw/baremetal/adder.c index ccc4e3567a..7cfc3e1e1a 100644 --- a/accelerators/chisel/adder_chisel/sw/baremetal/adder.c +++ b/accelerators/chisel/adder_chisel/sw/baremetal/adder.c @@ -3,7 +3,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -13,19 +13,15 @@ typedef int32_t token_t; const int ERR_TH = 0.05; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} - +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } #define SLD_ADDER 0x013 -#define DEV_NAME "sld,adder_chisel" +#define DEV_NAME "sld,adder_chisel" /* <<--params-->> */ -const int32_t readAddr = 0; +const int32_t readAddr = 0; const int32_t writeAddr = 0; -const int32_t size = 1024; +const int32_t size = 1024; static unsigned in_words_adj; static unsigned out_words_adj; @@ -38,147 +34,139 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ #define ADDER_WRITEADDR_REG 0x48 -#define ADDER_SIZE_REG 0x44 -#define ADDER_READADDR_REG 0x40 - +#define ADDER_SIZE_REG 0x44 +#define ADDER_READADDR_REG 0x40 static int validate_buf(token_t *out, int *gold) { - unsigned errors = 0; + unsigned errors = 0; - return errors; -} - - -static void init_buf(token_t *in, int *gold) -{ + return errors; } +static void init_buf(token_t *in, int *gold) {} -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable = NULL; - token_t *mem; - int *gold; - unsigned errors = 0; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * size; - out_words_adj = 2 * size; - } else { - in_words_adj = round_up(2 * size, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * size, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = 0; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_ADDER, DEV_NAME); - if (ndev == 0) { - printf("adder not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_len * sizeof(int)); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - - // Alocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); - - printf(" Generate input...\n"); - init_buf(mem, gold); - - // Pass common configuration parameters - - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); - - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - iowrite32(dev, ADDER_READADDR_REG, 0); - iowrite32(dev, ADDER_SIZE_REG, size); - iowrite32(dev, ADDER_WRITEADDR_REG, 0); - - // Flush (customize coherence model here) - esp_flush(ACC_COH_NONE); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - if (errors) - printf(" ... FAIL:\n"); - else - printf(" ... PASS:\n"); - - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable = NULL; + token_t *mem; + int *gold; + unsigned errors = 0; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * size; + out_words_adj = 2 * size; + } + else { + in_words_adj = round_up(2 * size, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * size, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = 0; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_ADDER, DEV_NAME); + if (ndev == 0) { + printf("adder not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_len * sizeof(int)); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); + + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); + + printf(" Generate input...\n"); + init_buf(mem, gold); + + // Pass common configuration parameters + + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); + + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + iowrite32(dev, ADDER_READADDR_REG, 0); + iowrite32(dev, ADDER_SIZE_REG, size); + iowrite32(dev, ADDER_WRITEADDR_REG, 0); + + // Flush (customize coherence model here) + esp_flush(ACC_COH_NONE); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + if (errors) printf(" ... FAIL:\n"); + else + printf(" ... PASS:\n"); + + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/accelerators/chisel/adder_chisel/sw/linux/app/adder.c b/accelerators/chisel/adder_chisel/sw/linux/app/adder.c index 9f3179dd06..33048f9e21 100644 --- a/accelerators/chisel/adder_chisel/sw/linux/app/adder.c +++ b/accelerators/chisel/adder_chisel/sw/linux/app/adder.c @@ -11,78 +11,72 @@ static unsigned out_size; static unsigned out_offset; static unsigned size; - /* User-defined code */ static int validate_buffer(token_t *out, int *gold) { - unsigned errors = 0; + unsigned errors = 0; - return errors; + return errors; } - /* User-defined code */ -static void init_buffer(token_t *in, int *gold) -{ -} - +static void init_buffer(token_t *in, int *gold) {} /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * SIZE; - out_words_adj = 2 * SIZE; - } else { - in_words_adj = round_up(2 * SIZE, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * SIZE, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = 0; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * SIZE; + out_words_adj = 2 * SIZE; + } + else { + in_words_adj = round_up(2 * SIZE, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * SIZE, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = 0; + size = (out_offset * sizeof(token_t)) + out_size; } - int main(int argc, char **argv) { - int errors; + int errors; - int *gold; - token_t *buf; + int *gold; + token_t *buf; - init_parameters(); + init_parameters(); - buf = (token_t *) esp_alloc(size); - cfg_000[0].hw_buf = buf; - gold = malloc(out_len * sizeof(int)); + buf = (token_t *)esp_alloc(size); + cfg_000[0].hw_buf = buf; + gold = malloc(out_len * sizeof(int)); - init_buffer(buf, gold); + init_buffer(buf, gold); - printf("\n====== %s ======\n\n", cfg_000[0].devname); - /* <<--print-params-->> */ - printf(" .readAddr = %d\n", readAddr); - printf(" .size = %d\n", SIZE); - printf(" .writeAddr = %d\n", writeAddr); - printf("\n ** START **\n"); + printf("\n====== %s ======\n\n", cfg_000[0].devname); + /* <<--print-params-->> */ + printf(" .readAddr = %d\n", readAddr); + printf(" .size = %d\n", SIZE); + printf(" .writeAddr = %d\n", writeAddr); + printf("\n ** START **\n"); - esp_run(cfg_000, NACC); + esp_run(cfg_000, NACC); - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - errors = validate_buffer(&buf[out_offset], gold); + errors = validate_buffer(&buf[out_offset], gold); - free(gold); - esp_free(buf); + free(gold); + esp_free(buf); - if (errors) - printf(" + TEST FAIL\n"); - else - printf(" + TEST PASS\n"); + if (errors) printf(" + TEST FAIL\n"); + else + printf(" + TEST PASS\n"); - printf("\n====== %s ======\n\n", cfg_000[0].devname); + printf("\n====== %s ======\n\n", cfg_000[0].devname); - return errors; + return errors; } diff --git a/accelerators/chisel/adder_chisel/sw/linux/driver/adder_chisel.c b/accelerators/chisel/adder_chisel/sw/linux/driver/adder_chisel.c index 368180c33f..620537ea57 100644 --- a/accelerators/chisel/adder_chisel/sw/linux/driver/adder_chisel.c +++ b/accelerators/chisel/adder_chisel/sw/linux/driver/adder_chisel.c @@ -1,134 +1,126 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "adder_chisel.h" -#define DRV_NAME "adder_chisel" +#define DRV_NAME "adder_chisel" /* <<--regs-->> */ #define ADDER_WRITEADDR_REG 0x48 -#define ADDER_SIZE_REG 0x44 -#define ADDER_READADDR_REG 0x40 +#define ADDER_SIZE_REG 0x44 +#define ADDER_READADDR_REG 0x40 struct adder_chisel_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver adder_driver; static struct of_device_id adder_device_ids[] = { - { - .name = "SLD_ADDER_CHISEL", - }, - { - .name = "eb_013", - }, - { - .compatible = "sld,adder_chisel", - }, - { }, + { + .name = "SLD_ADDER_CHISEL", + }, + { + .name = "eb_013", + }, + { + .compatible = "sld,adder_chisel", + }, + {}, }; static int adder_devs; static inline struct adder_chisel_device *to_adder(struct esp_device *esp) { - return container_of(esp, struct adder_chisel_device, esp); + return container_of(esp, struct adder_chisel_device, esp); } static void adder_prep_xfer(struct esp_device *esp, void *arg) { - struct adder_chisel_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->readAddr, esp->iomem + ADDER_READADDR_REG); - iowrite32be(a->size, esp->iomem + ADDER_SIZE_REG); - iowrite32be(a->writeAddr, esp->iomem + ADDER_WRITEADDR_REG); + struct adder_chisel_access *a = arg; - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); + /* <<--regs-config-->> */ + iowrite32be(a->readAddr, esp->iomem + ADDER_READADDR_REG); + iowrite32be(a->size, esp->iomem + ADDER_SIZE_REG); + iowrite32be(a->writeAddr, esp->iomem + ADDER_WRITEADDR_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool adder_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct adder_chisel_device *adder = to_adder(esp); */ - /* struct adder_chisel_access *a = arg; */ + /* struct adder_chisel_device *adder = to_adder(esp); */ + /* struct adder_chisel_access *a = arg; */ - return true; + return true; } static int adder_probe(struct platform_device *pdev) { - struct adder_chisel_device *adder; - struct esp_device *esp; - int rc; - - adder = kzalloc(sizeof(*adder), GFP_KERNEL); - if (adder == NULL) - return -ENOMEM; - esp = &adder->esp; - esp->module = THIS_MODULE; - esp->number = adder_devs; - esp->driver = &adder_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - adder_devs++; - return 0; - err: - kfree(adder); - return rc; + struct adder_chisel_device *adder; + struct esp_device *esp; + int rc; + + adder = kzalloc(sizeof(*adder), GFP_KERNEL); + if (adder == NULL) return -ENOMEM; + esp = &adder->esp; + esp->module = THIS_MODULE; + esp->number = adder_devs; + esp->driver = &adder_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + adder_devs++; + return 0; +err: + kfree(adder); + return rc; } static int __exit adder_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct adder_chisel_device *adder = to_adder(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct adder_chisel_device *adder = to_adder(esp); - esp_device_unregister(esp); - kfree(adder); - return 0; + esp_device_unregister(esp); + kfree(adder); + return 0; } static struct esp_driver adder_driver = { - .plat = { - .probe = adder_probe, - .remove = adder_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = adder_device_ids, - }, - }, - .xfer_input_ok = adder_xfer_input_ok, - .prep_xfer = adder_prep_xfer, - .ioctl_cm = ADDER_CHISEL_IOC_ACCESS, - .arg_size = sizeof(struct adder_chisel_access), + .plat = + { + .probe = adder_probe, + .remove = adder_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = adder_device_ids, + }, + }, + .xfer_input_ok = adder_xfer_input_ok, + .prep_xfer = adder_prep_xfer, + .ioctl_cm = ADDER_CHISEL_IOC_ACCESS, + .arg_size = sizeof(struct adder_chisel_access), }; -static int __init adder_init(void) -{ - return esp_driver_register(&adder_driver); -} +static int __init adder_init(void) { return esp_driver_register(&adder_driver); } -static void __exit adder_exit(void) -{ - esp_driver_unregister(&adder_driver); -} +static void __exit adder_exit(void) { esp_driver_unregister(&adder_driver); } -module_init(adder_init) -module_exit(adder_exit) +module_init(adder_init) module_exit(adder_exit) -MODULE_DEVICE_TABLE(of, adder_device_ids); + MODULE_DEVICE_TABLE(of, adder_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/chisel/adder_chisel/sw/linux/include/adder_chisel.h b/accelerators/chisel/adder_chisel/sw/linux/include/adder_chisel.h index 508f416d88..043e31bc05 100644 --- a/accelerators/chisel/adder_chisel/sw/linux/include/adder_chisel.h +++ b/accelerators/chisel/adder_chisel/sw/linux/include/adder_chisel.h @@ -4,29 +4,29 @@ #define _ADDER_CHISEL_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct adder_chisel_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned size; - unsigned readAddr; - unsigned writeAddr; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned size; + unsigned readAddr; + unsigned writeAddr; + unsigned src_offset; + unsigned dst_offset; }; -#define ADDER_CHISEL_IOC_ACCESS _IOW ('S', 0, struct adder_chisel_access) +#define ADDER_CHISEL_IOC_ACCESS _IOW('S', 0, struct adder_chisel_access) #endif /* _ADDER_CHISEL_H_ */ diff --git a/accelerators/chisel/counter_chisel/sw/baremetal/counter.c b/accelerators/chisel/counter_chisel/sw/baremetal/counter.c index 08638f837a..a9f0a0f0a9 100644 --- a/accelerators/chisel/counter_chisel/sw/baremetal/counter.c +++ b/accelerators/chisel/counter_chisel/sw/baremetal/counter.c @@ -6,60 +6,55 @@ * Select Scatter-Gather in ESP configuration */ -#include -#include #include #include +#include +#include -#define SLD_COUNTER 0x12 -#define DEV_NAME "sld,counter_chisel" +#define SLD_COUNTER 0x12 +#define DEV_NAME "sld,counter_chisel" // User defined registers -#define COUNTER_GITHASH_REG 0x40 -#define COUNTER_TICKS_REG 0x44 - +#define COUNTER_GITHASH_REG 0x40 +#define COUNTER_TICKS_REG 0x44 -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int n; - int ndev; - struct esp_device *espdevs = NULL; - - ndev = probe(&espdevs, VENDOR_SLD, SLD_COUNTER, DEV_NAME); - if (!ndev) { - printf("Error: %s device not found!\n", DEV_NAME); - exit(EXIT_FAILURE); - } - - for (n = 0; n < ndev; n++) { - struct esp_device *dev = &espdevs[n]; - const int test_ticks = 8; - unsigned done; - - - printf("******************** %s.%d ********************\n", DEV_NAME, n); - - - // Configure device - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - - iowrite32(dev, COUNTER_TICKS_REG, test_ticks); - - // Start accelerator - printf(" Start..\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - printf(" Done\n"); - - - printf("************************************************\n\n"); - } - return 0; + int n; + int ndev; + struct esp_device *espdevs = NULL; + + ndev = probe(&espdevs, VENDOR_SLD, SLD_COUNTER, DEV_NAME); + if (!ndev) { + printf("Error: %s device not found!\n", DEV_NAME); + exit(EXIT_FAILURE); + } + + for (n = 0; n < ndev; n++) { + struct esp_device *dev = &espdevs[n]; + const int test_ticks = 8; + unsigned done; + + printf("******************** %s.%d ********************\n", DEV_NAME, n); + + // Configure device + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + + iowrite32(dev, COUNTER_TICKS_REG, test_ticks); + + // Start accelerator + printf(" Start..\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + printf(" Done\n"); + + printf("************************************************\n\n"); + } + return 0; } - diff --git a/accelerators/chisel/counter_chisel/sw/linux/app/counter.c b/accelerators/chisel/counter_chisel/sw/linux/app/counter.c index eb3fa0868b..824a30c3a6 100644 --- a/accelerators/chisel/counter_chisel/sw/linux/app/counter.c +++ b/accelerators/chisel/counter_chisel/sw/linux/app/counter.c @@ -1,98 +1,86 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 +#include #include +#include #include #include #include -#include -#include +#include #include #include #include -#include #define DEVNAME "/dev/counter_chisel.0" -#define NAME "counter_chisel" +#define NAME "counter_chisel" static const char usage_str[] = "usage: counter_chisel \n" - " ticks: counter initialization\n" - "\n"; + " ticks: counter initialization\n" + "\n"; struct counter_test { - struct test_info info; - struct counter_chisel_access desc; - unsigned int ticks; + struct test_info info; + struct counter_chisel_access desc; + unsigned int ticks; }; static inline struct counter_test *to_counter(struct test_info *info) { - return container_of(info, struct counter_test, info); + return container_of(info, struct counter_test, info); } -static inline size_t counter_size() -{ - return 4096; -} +static inline size_t counter_size() { return 4096; } -static void counter_alloc_buf(struct test_info *info) -{ -} +static void counter_alloc_buf(struct test_info *info) {} static void counter_alloc_contig(struct test_info *info) { - if (contig_alloc(counter_size(), &info->contig) == NULL) - die_errno(__func__); - + if (contig_alloc(counter_size(), &info->contig) == NULL) die_errno(__func__); } -static void counter_init_bufs(struct test_info *info) -{ -} +static void counter_init_bufs(struct test_info *info) {} static void counter_set_access(struct test_info *info) { - struct counter_test *t = to_counter(info); + struct counter_test *t = to_counter(info); - t->desc.ticks = t->ticks; + t->desc.ticks = t->ticks; } -static bool counter_diff_ok(struct test_info *info) -{ - return true; -} +static bool counter_diff_ok(struct test_info *info) { return true; } static struct counter_test counter_test = { - .info = { - .name = NAME, - .devname = DEVNAME, - .alloc_buf = counter_alloc_buf, - .alloc_contig = counter_alloc_contig, - .init_bufs = counter_init_bufs, - .set_access = counter_set_access, - .diff_ok = counter_diff_ok, - .esp = &counter_test.desc.esp, - .cm = COUNTER_CHISEL_IOC_ACCESS, - }, + .info = + { + .name = NAME, + .devname = DEVNAME, + .alloc_buf = counter_alloc_buf, + .alloc_contig = counter_alloc_contig, + .init_bufs = counter_init_bufs, + .set_access = counter_set_access, + .diff_ok = counter_diff_ok, + .esp = &counter_test.desc.esp, + .cm = COUNTER_CHISEL_IOC_ACCESS, + }, }; static void NORETURN usage(void) { - fprintf(stderr, "%s", usage_str); - exit(1); + fprintf(stderr, "%s", usage_str); + exit(1); } int main(int argc, char *argv[]) { - if (argc != 2) - usage(); + if (argc != 2) usage(); - counter_test.ticks = strtoul(argv[1], NULL, 0); - printf(" ** Chisel3 counter Device Test - %d ticks **\n", counter_test.ticks); + counter_test.ticks = strtoul(argv[1], NULL, 0); + printf(" ** Chisel3 counter Device Test - %d ticks **\n", counter_test.ticks); - /* - * Set coherence to full because memory is not accessed - * Run hw-only test because no software comparison is required. - */ - return test_main(&counter_test.info, "full", "hw"); + /* + * Set coherence to full because memory is not accessed + * Run hw-only test because no software comparison is required. + */ + return test_main(&counter_test.info, "full", "hw"); } diff --git a/accelerators/chisel/counter_chisel/sw/linux/driver/counter_chisel.c b/accelerators/chisel/counter_chisel/sw/linux/driver/counter_chisel.c index dc09f02428..3751500af7 100644 --- a/accelerators/chisel/counter_chisel/sw/linux/driver/counter_chisel.c +++ b/accelerators/chisel/counter_chisel/sw/linux/driver/counter_chisel.c @@ -1,126 +1,118 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "counter_chisel.h" -#define DRV_NAME "counter_chisel" +#define DRV_NAME "counter_chisel" -#define COUNTER_GITHASH_REG 0x40 -#define COUNTER_TICKS_REG 0x44 +#define COUNTER_GITHASH_REG 0x40 +#define COUNTER_TICKS_REG 0x44 struct counter_chisel_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver counter_driver; static struct of_device_id counter_device_ids[] = { - { - .name = "SLD_COUNTER_CHISEL", - }, - { - .name = "eb_012", - }, - { - .compatible = "sld,counter_chisel", - }, - { }, + { + .name = "SLD_COUNTER_CHISEL", + }, + { + .name = "eb_012", + }, + { + .compatible = "sld,counter_chisel", + }, + {}, }; static int counter_devs; static inline struct counter_chisel_device *to_counter(struct esp_device *esp) { - return container_of(esp, struct counter_chisel_device, esp); + return container_of(esp, struct counter_chisel_device, esp); } static void counter_prep_xfer(struct esp_device *esp, void *arg) { - struct counter_chisel_access *a = arg; + struct counter_chisel_access *a = arg; - iowrite32be(a->ticks, esp->iomem + COUNTER_TICKS_REG); + iowrite32be(a->ticks, esp->iomem + COUNTER_TICKS_REG); } static bool counter_xfer_input_ok(struct esp_device *esp, void *arg) { - struct counter_chisel_access *a = arg; + struct counter_chisel_access *a = arg; - if (a->ticks >= (1<<16) || a->ticks < 1) - return false; - return true; + if (a->ticks >= (1 << 16) || a->ticks < 1) return false; + return true; } static int counter_probe(struct platform_device *pdev) { - struct counter_chisel_device *counter; - struct esp_device *esp; - int rc; - - counter = kzalloc(sizeof(*counter), GFP_KERNEL); - if (counter == NULL) - return -ENOMEM; - esp = &counter->esp; - esp->module = THIS_MODULE; - esp->number = counter_devs; - esp->driver = &counter_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - counter_devs++; - return 0; - err: - kfree(counter); - return rc; + struct counter_chisel_device *counter; + struct esp_device *esp; + int rc; + + counter = kzalloc(sizeof(*counter), GFP_KERNEL); + if (counter == NULL) return -ENOMEM; + esp = &counter->esp; + esp->module = THIS_MODULE; + esp->number = counter_devs; + esp->driver = &counter_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + counter_devs++; + return 0; +err: + kfree(counter); + return rc; } static int __exit counter_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct counter_chisel_device *counter = to_counter(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct counter_chisel_device *counter = to_counter(esp); - esp_device_unregister(esp); - kfree(counter); - return 0; + esp_device_unregister(esp); + kfree(counter); + return 0; } static struct esp_driver counter_driver = { - .plat = { - .probe = counter_probe, - .remove = counter_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = counter_device_ids, - }, - }, - .xfer_input_ok = counter_xfer_input_ok, - .prep_xfer = counter_prep_xfer, - .ioctl_cm = COUNTER_CHISEL_IOC_ACCESS, - .arg_size = sizeof(struct counter_chisel_access), + .plat = + { + .probe = counter_probe, + .remove = counter_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = counter_device_ids, + }, + }, + .xfer_input_ok = counter_xfer_input_ok, + .prep_xfer = counter_prep_xfer, + .ioctl_cm = COUNTER_CHISEL_IOC_ACCESS, + .arg_size = sizeof(struct counter_chisel_access), }; -static int __init counter_init(void) -{ - return esp_driver_register(&counter_driver); -} +static int __init counter_init(void) { return esp_driver_register(&counter_driver); } -static void __exit counter_exit(void) -{ - esp_driver_unregister(&counter_driver); -} +static void __exit counter_exit(void) { esp_driver_unregister(&counter_driver); } -module_init(counter_init) -module_exit(counter_exit) +module_init(counter_init) module_exit(counter_exit) -MODULE_DEVICE_TABLE(of, counter_device_ids); + MODULE_DEVICE_TABLE(of, counter_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/chisel/counter_chisel/sw/linux/include/counter_chisel.h b/accelerators/chisel/counter_chisel/sw/linux/include/counter_chisel.h index fd78b33909..232e9610cc 100644 --- a/accelerators/chisel/counter_chisel/sw/linux/include/counter_chisel.h +++ b/accelerators/chisel/counter_chisel/sw/linux/include/counter_chisel.h @@ -4,24 +4,24 @@ #define _COUNTER_CHISEL_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct counter_chisel_access { - struct esp_access esp; - unsigned int ticks; + struct esp_access esp; + unsigned int ticks; }; -#define COUNTER_CHISEL_IOC_ACCESS _IOW ('S', 0, struct counter_chisel_access) +#define COUNTER_CHISEL_IOC_ACCESS _IOW('S', 0, struct counter_chisel_access) #endif /* _COUNTER_CHISEL_H_ */ diff --git a/accelerators/chisel/fft_chisel/sw/baremetal/fft.c b/accelerators/chisel/fft_chisel/sw/baremetal/fft.c index b3381c301b..ab6d9199f8 100644 --- a/accelerators/chisel/fft_chisel/sw/baremetal/fft.c +++ b/accelerators/chisel/fft_chisel/sw/baremetal/fft.c @@ -3,28 +3,24 @@ #include #ifndef __riscv -#include + #include #endif +#include "utils/fft_utils.h" #include #include -#include "utils/fft_utils.h" typedef int32_t token_t; const float ERR_TH = 0.05; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} - +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } -#define SLD_FFT 0x013 +#define SLD_FFT 0x013 #define DEV_NAME "sld,fft_chisel" /* <<--params-->> */ -const int32_t len = 32; +const int32_t len = 32; const int32_t log_len = 5; static unsigned in_words_adj; @@ -38,175 +34,169 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ -#define FFT_STRIDE_REG 0x50 -#define FFT_COUNT_REG 0x4C +#define FFT_STRIDE_REG 0x50 +#define FFT_COUNT_REG 0x4C #define FFT_STARTADDR_REG 0x48 - static int validate_buf(token_t *out, float *gold) { - int j; - unsigned errors = 0; + int j; + unsigned errors = 0; - for (j = 0; j < 2 * len; j++) { - float val = fixed32_to_float(out[j], 12); - if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) - errors++; - } + for (j = 0; j < 2 * len; j++) { + float val = fixed32_to_float(out[j], 12); + if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) errors++; + } - printf(" + Relative error > %.02f for %d output values out of %ld\n", ERR_TH, errors, 2 * len); - return errors; + printf(" + Relative error > %.02f for %d output values out of %ld\n", ERR_TH, errors, 2 * len); + return errors; } - static void init_buf(token_t *in, float *gold) { - int j; - const float LO = -100.0; - const float HI = 100.0; + int j; + const float LO = -100.0; + const float HI = 100.0; - /* srand((unsigned int) time(NULL)); */ + /* srand((unsigned int) time(NULL)); */ - for (j = 0; j < 2 * len; j++) { - float scaling_factor = (float) rand () / (float) RAND_MAX; - gold[j] = LO + scaling_factor * (HI - LO); - } + for (j = 0; j < 2 * len; j++) { + float scaling_factor = (float)rand() / (float)RAND_MAX; + gold[j] = LO + scaling_factor * (HI - LO); + } - /* // preprocess with bitreverse (fast in software anyway) */ - /* fft_bit_reverse(gold, len, log_len); */ + /* // preprocess with bitreverse (fast in software anyway) */ + /* fft_bit_reverse(gold, len, log_len); */ - // convert input to fixed point - for (j = 0; j < 2 * len; j++) - in[j] = float_to_fixed32((float) gold[j], 12); + // convert input to fixed point + for (j = 0; j < 2 * len; j++) + in[j] = float_to_fixed32((float)gold[j], 12); - // Compute golden output - fft_comp(gold, len, log_len, -1, true); + // Compute golden output + fft_comp(gold, len, log_len, -1, true); } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable = NULL; - token_t *mem; - float *gold; - unsigned errors = 0; - const int ERROR_COUNT_TH = 0.001; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * len; - out_words_adj = 2 * len; - } else { - in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = 0; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_FFT, DEV_NAME); - if (ndev == 0) { - printf("fft not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_len * sizeof(float)); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - - // Alocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); - - printf(" Generate input...\n"); - init_buf(mem, gold); - - // Pass common configuration parameters - - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); - - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - iowrite32(dev, FFT_STARTADDR_REG, 0); - iowrite32(dev, FFT_COUNT_REG, 1); - iowrite32(dev, FFT_STRIDE_REG, len); - - // Flush (customize coherence model here) - esp_flush(ACC_COH_NONE); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - if ((errors / len) > ERROR_COUNT_TH) - printf(" ... FAIL: exceeding error count threshold\n"); - else - printf(" ... PASS: not exceeding error count threshold\n"); - - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable = NULL; + token_t *mem; + float *gold; + unsigned errors = 0; + const int ERROR_COUNT_TH = 0.001; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * len; + out_words_adj = 2 * len; + } + else { + in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = 0; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_FFT, DEV_NAME); + if (ndev == 0) { + printf("fft not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_len * sizeof(float)); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); + + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); + + printf(" Generate input...\n"); + init_buf(mem, gold); + + // Pass common configuration parameters + + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); + + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + iowrite32(dev, FFT_STARTADDR_REG, 0); + iowrite32(dev, FFT_COUNT_REG, 1); + iowrite32(dev, FFT_STRIDE_REG, len); + + // Flush (customize coherence model here) + esp_flush(ACC_COH_NONE); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + if ((errors / len) > ERROR_COUNT_TH) + printf(" ... FAIL: exceeding error count threshold\n"); + else + printf(" ... PASS: not exceeding error count threshold\n"); + + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/accelerators/chisel/fft_chisel/sw/linux/app/fft.c b/accelerators/chisel/fft_chisel/sw/linux/app/fft.c index 419f649173..5d81de4227 100644 --- a/accelerators/chisel/fft_chisel/sw/linux/app/fft.c +++ b/accelerators/chisel/fft_chisel/sw/linux/app/fft.c @@ -17,104 +17,100 @@ const float ERR_TH = 0.05; /* User-defined code */ static int validate_buffer(token_t *out, float *gold) { - int j; - unsigned errors = 0; + int j; + unsigned errors = 0; - for (j = 0; j < 2 * len; j++) { - float val = fixed32_to_float(out[j], 12); - if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) - errors++; - } + for (j = 0; j < 2 * len; j++) { + float val = fixed32_to_float(out[j], 12); + if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) errors++; + } - printf(" + Relative error > %.02f for %d output values out of %d\n", ERR_TH, errors, 2 * len); + printf(" + Relative error > %.02f for %d output values out of %d\n", ERR_TH, errors, 2 * len); - return errors; + return errors; } - /* User-defined code */ static void init_buffer(token_t *in, float *gold) { - int j; - const float LO = -100.0; - const float HI = 100.0; + int j; + const float LO = -100.0; + const float HI = 100.0; - /* srand((unsigned int) time(NULL)); */ + /* srand((unsigned int) time(NULL)); */ - for (j = 0; j < 2 * len; j++) { - float scaling_factor = (float) rand () / (float) RAND_MAX; - gold[j] = LO + scaling_factor * (HI - LO); - } + for (j = 0; j < 2 * len; j++) { + float scaling_factor = (float)rand() / (float)RAND_MAX; + gold[j] = LO + scaling_factor * (HI - LO); + } - /* // preprocess with bitreverse (fast in software anyway) */ - /* fft_bit_reverse(gold, len, log_len); */ + /* // preprocess with bitreverse (fast in software anyway) */ + /* fft_bit_reverse(gold, len, log_len); */ - // convert input to fixed point - for (j = 0; j < 2 * len; j++) - in[j] = float_to_fixed32((float) gold[j], 12); + // convert input to fixed point + for (j = 0; j < 2 * len; j++) + in[j] = float_to_fixed32((float)gold[j], 12); - // Compute golden output - fft_comp(gold, len, log_len, -1, true); + // Compute golden output + fft_comp(gold, len, log_len, -1, true); } - /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * len; - out_words_adj = 2 * len; - } else { - in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = 0; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * len; + out_words_adj = 2 * len; + } + else { + in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = 0; + size = (out_offset * sizeof(token_t)) + out_size; } - int main(int argc, char **argv) { - int errors; + int errors; - float *gold; - token_t *buf; + float *gold; + token_t *buf; - const int ERROR_COUNT_TH = 0.001; + const int ERROR_COUNT_TH = 0.001; - init_parameters(); + init_parameters(); - buf = (token_t *) esp_alloc(size); - cfg_000[0].hw_buf = buf; - gold = malloc(out_len * sizeof(float)); + buf = (token_t *)esp_alloc(size); + cfg_000[0].hw_buf = buf; + gold = malloc(out_len * sizeof(float)); - init_buffer(buf, gold); + init_buffer(buf, gold); - printf("\n====== %s ======\n\n", cfg_000[0].devname); - /* <<--print-params-->> */ - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); - printf("\n ** START **\n"); + printf("\n====== %s ======\n\n", cfg_000[0].devname); + /* <<--print-params-->> */ + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); + printf("\n ** START **\n"); - esp_run(cfg_000, NACC); + esp_run(cfg_000, NACC); - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - errors = validate_buffer(&buf[out_offset], gold); + errors = validate_buffer(&buf[out_offset], gold); - free(gold); - esp_free(buf); + free(gold); + esp_free(buf); - if ((errors / len) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + if ((errors / len) > ERROR_COUNT_TH) printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - printf("\n====== %s ======\n\n", cfg_000[0].devname); + printf("\n====== %s ======\n\n", cfg_000[0].devname); - return errors; + return errors; } diff --git a/accelerators/chisel/fft_chisel/sw/linux/driver/fft_chisel.c b/accelerators/chisel/fft_chisel/sw/linux/driver/fft_chisel.c index c272c4865c..7cbdb9d320 100644 --- a/accelerators/chisel/fft_chisel/sw/linux/driver/fft_chisel.c +++ b/accelerators/chisel/fft_chisel/sw/linux/driver/fft_chisel.c @@ -1,133 +1,125 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "fft_chisel.h" -#define DRV_NAME "fft_chisel" +#define DRV_NAME "fft_chisel" /* <<--regs-->> */ -#define FFT_STRIDE_REG 0x50 -#define FFT_COUNT_REG 0x4C +#define FFT_STRIDE_REG 0x50 +#define FFT_COUNT_REG 0x4C #define FFT_STARTADDR_REG 0x48 struct fft_chisel_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver fft_driver; static struct of_device_id fft_device_ids[] = { - { - .name = "SLD_FFT_CHISEL", - }, - { - .name = "eb_013", - }, - { - .compatible = "sld,fft_chisel", - }, - { }, + { + .name = "SLD_FFT_CHISEL", + }, + { + .name = "eb_013", + }, + { + .compatible = "sld,fft_chisel", + }, + {}, }; static int fft_devs; static inline struct fft_chisel_device *to_fft(struct esp_device *esp) { - return container_of(esp, struct fft_chisel_device, esp); + return container_of(esp, struct fft_chisel_device, esp); } static void fft_prep_xfer(struct esp_device *esp, void *arg) { - struct fft_chisel_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->stride, esp->iomem + FFT_STRIDE_REG); - iowrite32be(1, esp->iomem + FFT_COUNT_REG); - iowrite32be(0, esp->iomem + FFT_STARTADDR_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); - + struct fft_chisel_access *a = arg; + + /* <<--regs-config-->> */ + iowrite32be(a->stride, esp->iomem + FFT_STRIDE_REG); + iowrite32be(1, esp->iomem + FFT_COUNT_REG); + iowrite32be(0, esp->iomem + FFT_STARTADDR_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool fft_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct fft_chisel_device *fft = to_fft(esp); */ - /* struct fft_chisel_access *a = arg; */ + /* struct fft_chisel_device *fft = to_fft(esp); */ + /* struct fft_chisel_access *a = arg; */ - return true; + return true; } static int fft_probe(struct platform_device *pdev) { - struct fft_chisel_device *fft; - struct esp_device *esp; - int rc; - - fft = kzalloc(sizeof(*fft), GFP_KERNEL); - if (fft == NULL) - return -ENOMEM; - esp = &fft->esp; - esp->module = THIS_MODULE; - esp->number = fft_devs; - esp->driver = &fft_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - fft_devs++; - return 0; - err: - kfree(fft); - return rc; + struct fft_chisel_device *fft; + struct esp_device *esp; + int rc; + + fft = kzalloc(sizeof(*fft), GFP_KERNEL); + if (fft == NULL) return -ENOMEM; + esp = &fft->esp; + esp->module = THIS_MODULE; + esp->number = fft_devs; + esp->driver = &fft_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + fft_devs++; + return 0; +err: + kfree(fft); + return rc; } static int __exit fft_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct fft_chisel_device *fft = to_fft(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct fft_chisel_device *fft = to_fft(esp); - esp_device_unregister(esp); - kfree(fft); - return 0; + esp_device_unregister(esp); + kfree(fft); + return 0; } static struct esp_driver fft_driver = { - .plat = { - .probe = fft_probe, - .remove = fft_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = fft_device_ids, - }, - }, - .xfer_input_ok = fft_xfer_input_ok, - .prep_xfer = fft_prep_xfer, - .ioctl_cm = FFT_CHISEL_IOC_ACCESS, - .arg_size = sizeof(struct fft_chisel_access), + .plat = + { + .probe = fft_probe, + .remove = fft_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = fft_device_ids, + }, + }, + .xfer_input_ok = fft_xfer_input_ok, + .prep_xfer = fft_prep_xfer, + .ioctl_cm = FFT_CHISEL_IOC_ACCESS, + .arg_size = sizeof(struct fft_chisel_access), }; -static int __init fft_init(void) -{ - return esp_driver_register(&fft_driver); -} +static int __init fft_init(void) { return esp_driver_register(&fft_driver); } -static void __exit fft_exit(void) -{ - esp_driver_unregister(&fft_driver); -} +static void __exit fft_exit(void) { esp_driver_unregister(&fft_driver); } -module_init(fft_init) -module_exit(fft_exit) +module_init(fft_init) module_exit(fft_exit) -MODULE_DEVICE_TABLE(of, fft_device_ids); + MODULE_DEVICE_TABLE(of, fft_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/chisel/fft_chisel/sw/linux/include/fft_chisel.h b/accelerators/chisel/fft_chisel/sw/linux/include/fft_chisel.h index 2b4db3a3d0..0560b68864 100644 --- a/accelerators/chisel/fft_chisel/sw/linux/include/fft_chisel.h +++ b/accelerators/chisel/fft_chisel/sw/linux/include/fft_chisel.h @@ -4,27 +4,27 @@ #define _FFT_CHISEL_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct fft_chisel_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned stride; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned stride; + unsigned src_offset; + unsigned dst_offset; }; -#define FFT_CHISEL_IOC_ACCESS _IOW ('S', 0, struct fft_chisel_access) +#define FFT_CHISEL_IOC_ACCESS _IOW('S', 0, struct fft_chisel_access) #endif /* _FFT_CHISEL_H_ */ diff --git a/accelerators/stratus_hls/cholesky_stratus/hw/datagen/data.h b/accelerators/stratus_hls/cholesky_stratus/hw/datagen/data.h index 32480837cf..24b5e00c9f 100644 --- a/accelerators/stratus_hls/cholesky_stratus/hw/datagen/data.h +++ b/accelerators/stratus_hls/cholesky_stratus/hw/datagen/data.h @@ -1,512 +1,512 @@ -buf[0] = float2fx((float) 22.196868439858292, FX_IL); -buf[1] = float2fx((float) 3.139781259616778, FX_IL); -buf[2] = float2fx((float) 4.085870547472895, FX_IL); -buf[3] = float2fx((float) 5.328075306731808, FX_IL); -buf[4] = float2fx((float) 4.8037631898173085, FX_IL); -buf[5] = float2fx((float) 4.837594565141392, FX_IL); -buf[6] = float2fx((float) 3.792354108739337, FX_IL); -buf[7] = float2fx((float) 3.654460144405442, FX_IL); -buf[8] = float2fx((float) 4.769636420361318, FX_IL); -buf[9] = float2fx((float) 5.253027549287438, FX_IL); -buf[10] = float2fx((float) 3.7488158874541186, FX_IL); -buf[11] = float2fx((float) 5.064109564900953, FX_IL); -buf[12] = float2fx((float) 4.14227428005699, FX_IL); -buf[13] = float2fx((float) 3.9739040640452163, FX_IL); -buf[14] = float2fx((float) 5.007449404606732, FX_IL); -buf[15] = float2fx((float) 3.1389562700875153, FX_IL); -buf[16] = float2fx((float) 3.139781259616778, FX_IL); -buf[17] = float2fx((float) 18.8478132119287, FX_IL); -buf[18] = float2fx((float) 2.7873313228223098, FX_IL); -buf[19] = float2fx((float) 3.0177344093840572, FX_IL); -buf[20] = float2fx((float) 2.30965314000862, FX_IL); -buf[21] = float2fx((float) 3.202042252394584, FX_IL); -buf[22] = float2fx((float) 2.13235199356131, FX_IL); -buf[23] = float2fx((float) 2.8593288759248083, FX_IL); -buf[24] = float2fx((float) 2.4107525884962855, FX_IL); -buf[25] = float2fx((float) 2.757297464495678, FX_IL); -buf[26] = float2fx((float) 1.8788174001646278, FX_IL); -buf[27] = float2fx((float) 2.7683227522465703, FX_IL); -buf[28] = float2fx((float) 2.6360338139142367, FX_IL); -buf[29] = float2fx((float) 2.463851487558704, FX_IL); -buf[30] = float2fx((float) 3.201024110824123, FX_IL); -buf[31] = float2fx((float) 1.9053923712518486, FX_IL); -buf[32] = float2fx((float) 4.085870547472895, FX_IL); -buf[33] = float2fx((float) 2.7873313228223098, FX_IL); -buf[34] = float2fx((float) 21.22707300998566, FX_IL); -buf[35] = float2fx((float) 5.865495282498139, FX_IL); -buf[36] = float2fx((float) 3.8965483434484165, FX_IL); -buf[37] = float2fx((float) 4.764673434816277, FX_IL); -buf[38] = float2fx((float) 4.501929408861694, FX_IL); -buf[39] = float2fx((float) 3.6240905809288386, FX_IL); -buf[40] = float2fx((float) 4.680829677861098, FX_IL); -buf[41] = float2fx((float) 4.345119758397213, FX_IL); -buf[42] = float2fx((float) 3.5654929814575227, FX_IL); -buf[43] = float2fx((float) 5.213139321860575, FX_IL); -buf[44] = float2fx((float) 4.587010507204246, FX_IL); -buf[45] = float2fx((float) 4.398257917031813, FX_IL); -buf[46] = float2fx((float) 4.089076811287382, FX_IL); -buf[47] = float2fx((float) 3.493842571955116, FX_IL); -buf[48] = float2fx((float) 5.328075306731808, FX_IL); -buf[49] = float2fx((float) 3.0177344093840572, FX_IL); -buf[50] = float2fx((float) 5.865495282498139, FX_IL); -buf[51] = float2fx((float) 23.787335518557548, FX_IL); -buf[52] = float2fx((float) 4.7020895446698034, FX_IL); -buf[53] = float2fx((float) 5.523469708105416, FX_IL); -buf[54] = float2fx((float) 5.255142342270051, FX_IL); -buf[55] = float2fx((float) 4.410903793450839, FX_IL); -buf[56] = float2fx((float) 5.750824736330631, FX_IL); -buf[57] = float2fx((float) 5.321291013969316, FX_IL); -buf[58] = float2fx((float) 4.6009288946858575, FX_IL); -buf[59] = float2fx((float) 6.346100424411845, FX_IL); -buf[60] = float2fx((float) 5.1906326588526435, FX_IL); -buf[61] = float2fx((float) 5.403905881835056, FX_IL); -buf[62] = float2fx((float) 5.015878281671276, FX_IL); -buf[63] = float2fx((float) 4.052832467266238, FX_IL); -buf[64] = float2fx((float) 4.8037631898173085, FX_IL); -buf[65] = float2fx((float) 2.30965314000862, FX_IL); -buf[66] = float2fx((float) 3.8965483434484165, FX_IL); -buf[67] = float2fx((float) 4.7020895446698034, FX_IL); -buf[68] = float2fx((float) 20.931521866318462, FX_IL); -buf[69] = float2fx((float) 4.000974686663493, FX_IL); -buf[70] = float2fx((float) 3.6907034522605544, FX_IL); -buf[71] = float2fx((float) 2.874639419572023, FX_IL); -buf[72] = float2fx((float) 4.303816019833494, FX_IL); -buf[73] = float2fx((float) 4.838981984440691, FX_IL); -buf[74] = float2fx((float) 2.9136823263997655, FX_IL); -buf[75] = float2fx((float) 4.430648265633036, FX_IL); -buf[76] = float2fx((float) 3.0075640686034264, FX_IL); -buf[77] = float2fx((float) 4.090920543703864, FX_IL); -buf[78] = float2fx((float) 3.9445502474463896, FX_IL); -buf[79] = float2fx((float) 2.633254042355268, FX_IL); -buf[80] = float2fx((float) 4.837594565141392, FX_IL); -buf[81] = float2fx((float) 3.202042252394584, FX_IL); -buf[82] = float2fx((float) 4.764673434816277, FX_IL); -buf[83] = float2fx((float) 5.523469708105416, FX_IL); -buf[84] = float2fx((float) 4.000974686663493, FX_IL); -buf[85] = float2fx((float) 21.936736021639547, FX_IL); -buf[86] = float2fx((float) 3.847088774198843, FX_IL); -buf[87] = float2fx((float) 3.8905715723978265, FX_IL); -buf[88] = float2fx((float) 4.54972693132023, FX_IL); -buf[89] = float2fx((float) 3.808497489487739, FX_IL); -buf[90] = float2fx((float) 3.6422967718709263, FX_IL); -buf[91] = float2fx((float) 5.203722126960201, FX_IL); -buf[92] = float2fx((float) 4.210033077426458, FX_IL); -buf[93] = float2fx((float) 4.150069482934393, FX_IL); -buf[94] = float2fx((float) 5.262989869750008, FX_IL); -buf[95] = float2fx((float) 3.5209166845097077, FX_IL); -buf[96] = float2fx((float) 3.792354108739337, FX_IL); -buf[97] = float2fx((float) 2.13235199356131, FX_IL); -buf[98] = float2fx((float) 4.501929408861694, FX_IL); -buf[99] = float2fx((float) 5.255142342270051, FX_IL); -buf[100] = float2fx((float) 3.6907034522605544, FX_IL); -buf[101] = float2fx((float) 3.847088774198843, FX_IL); -buf[102] = float2fx((float) 21.285985041506976, FX_IL); -buf[103] = float2fx((float) 2.521953879593371, FX_IL); -buf[104] = float2fx((float) 3.5889100837833756, FX_IL); -buf[105] = float2fx((float) 4.012932927277644, FX_IL); -buf[106] = float2fx((float) 2.580047456823562, FX_IL); -buf[107] = float2fx((float) 4.429444108733627, FX_IL); -buf[108] = float2fx((float) 4.021980167475107, FX_IL); -buf[109] = float2fx((float) 3.621531989820876, FX_IL); -buf[110] = float2fx((float) 3.4717311087801597, FX_IL); -buf[111] = float2fx((float) 3.511459765272087, FX_IL); -buf[112] = float2fx((float) 3.654460144405442, FX_IL); -buf[113] = float2fx((float) 2.8593288759248083, FX_IL); -buf[114] = float2fx((float) 3.6240905809288386, FX_IL); -buf[115] = float2fx((float) 4.410903793450839, FX_IL); -buf[116] = float2fx((float) 2.874639419572023, FX_IL); -buf[117] = float2fx((float) 3.8905715723978265, FX_IL); -buf[118] = float2fx((float) 2.521953879593371, FX_IL); -buf[119] = float2fx((float) 19.75758627180919, FX_IL); -buf[120] = float2fx((float) 3.4457315301204803, FX_IL); -buf[121] = float2fx((float) 3.2501458389813767, FX_IL); -buf[122] = float2fx((float) 3.187359952152498, FX_IL); -buf[123] = float2fx((float) 3.7990180221608707, FX_IL); -buf[124] = float2fx((float) 2.9736024008233595, FX_IL); -buf[125] = float2fx((float) 3.230994708040832, FX_IL); -buf[126] = float2fx((float) 3.71011644188383, FX_IL); -buf[127] = float2fx((float) 2.5946369557722946, FX_IL); -buf[128] = float2fx((float) 4.769636420361318, FX_IL); -buf[129] = float2fx((float) 2.4107525884962855, FX_IL); -buf[130] = float2fx((float) 4.680829677861098, FX_IL); -buf[131] = float2fx((float) 5.750824736330631, FX_IL); -buf[132] = float2fx((float) 4.303816019833494, FX_IL); -buf[133] = float2fx((float) 4.54972693132023, FX_IL); -buf[134] = float2fx((float) 3.5889100837833756, FX_IL); -buf[135] = float2fx((float) 3.4457315301204803, FX_IL); -buf[136] = float2fx((float) 21.824054451502782, FX_IL); -buf[137] = float2fx((float) 4.81167800786811, FX_IL); -buf[138] = float2fx((float) 3.6539626761330117, FX_IL); -buf[139] = float2fx((float) 5.5266764785537665, FX_IL); -buf[140] = float2fx((float) 4.425440044399624, FX_IL); -buf[141] = float2fx((float) 5.0034397044217895, FX_IL); -buf[142] = float2fx((float) 4.23636980763111, FX_IL); -buf[143] = float2fx((float) 3.265732239494459, FX_IL); -buf[144] = float2fx((float) 5.253027549287438, FX_IL); -buf[145] = float2fx((float) 2.757297464495678, FX_IL); -buf[146] = float2fx((float) 4.345119758397213, FX_IL); -buf[147] = float2fx((float) 5.321291013969316, FX_IL); -buf[148] = float2fx((float) 4.838981984440691, FX_IL); -buf[149] = float2fx((float) 3.808497489487739, FX_IL); -buf[150] = float2fx((float) 4.012932927277644, FX_IL); -buf[151] = float2fx((float) 3.2501458389813767, FX_IL); -buf[152] = float2fx((float) 4.81167800786811, FX_IL); -buf[153] = float2fx((float) 22.048243446491337, FX_IL); -buf[154] = float2fx((float) 3.3299652011330756, FX_IL); -buf[155] = float2fx((float) 4.719404719219467, FX_IL); -buf[156] = float2fx((float) 3.961443582169512, FX_IL); -buf[157] = float2fx((float) 4.360565801596725, FX_IL); -buf[158] = float2fx((float) 3.938830628634233, FX_IL); -buf[159] = float2fx((float) 2.886095619751898, FX_IL); -buf[160] = float2fx((float) 3.7488158874541186, FX_IL); -buf[161] = float2fx((float) 1.8788174001646278, FX_IL); -buf[162] = float2fx((float) 3.5654929814575227, FX_IL); -buf[163] = float2fx((float) 4.6009288946858575, FX_IL); -buf[164] = float2fx((float) 2.9136823263997655, FX_IL); -buf[165] = float2fx((float) 3.6422967718709263, FX_IL); -buf[166] = float2fx((float) 2.580047456823562, FX_IL); -buf[167] = float2fx((float) 3.187359952152498, FX_IL); -buf[168] = float2fx((float) 3.6539626761330117, FX_IL); -buf[169] = float2fx((float) 3.3299652011330756, FX_IL); -buf[170] = float2fx((float) 20.208342848404044, FX_IL); -buf[171] = float2fx((float) 4.300881215976244, FX_IL); -buf[172] = float2fx((float) 3.237111508426725, FX_IL); -buf[173] = float2fx((float) 2.9011105946901266, FX_IL); -buf[174] = float2fx((float) 3.2652585766050093, FX_IL); -buf[175] = float2fx((float) 2.700108283848623, FX_IL); -buf[176] = float2fx((float) 5.064109564900953, FX_IL); -buf[177] = float2fx((float) 2.7683227522465703, FX_IL); -buf[178] = float2fx((float) 5.213139321860575, FX_IL); -buf[179] = float2fx((float) 6.346100424411845, FX_IL); -buf[180] = float2fx((float) 4.430648265633036, FX_IL); -buf[181] = float2fx((float) 5.203722126960201, FX_IL); -buf[182] = float2fx((float) 4.429444108733627, FX_IL); -buf[183] = float2fx((float) 3.7990180221608707, FX_IL); -buf[184] = float2fx((float) 5.5266764785537665, FX_IL); -buf[185] = float2fx((float) 4.719404719219467, FX_IL); -buf[186] = float2fx((float) 4.300881215976244, FX_IL); -buf[187] = float2fx((float) 22.446014844575057, FX_IL); -buf[188] = float2fx((float) 4.964871637408653, FX_IL); -buf[189] = float2fx((float) 4.773320978732786, FX_IL); -buf[190] = float2fx((float) 5.053823090270109, FX_IL); -buf[191] = float2fx((float) 4.146744124331975, FX_IL); -buf[192] = float2fx((float) 4.14227428005699, FX_IL); -buf[193] = float2fx((float) 2.6360338139142367, FX_IL); -buf[194] = float2fx((float) 4.587010507204246, FX_IL); -buf[195] = float2fx((float) 5.1906326588526435, FX_IL); -buf[196] = float2fx((float) 3.0075640686034264, FX_IL); -buf[197] = float2fx((float) 4.210033077426458, FX_IL); -buf[198] = float2fx((float) 4.021980167475107, FX_IL); -buf[199] = float2fx((float) 2.9736024008233595, FX_IL); -buf[200] = float2fx((float) 4.425440044399624, FX_IL); -buf[201] = float2fx((float) 3.961443582169512, FX_IL); -buf[202] = float2fx((float) 3.237111508426725, FX_IL); -buf[203] = float2fx((float) 4.964871637408653, FX_IL); -buf[204] = float2fx((float) 21.607609215545207, FX_IL); -buf[205] = float2fx((float) 3.5776256649904052, FX_IL); -buf[206] = float2fx((float) 3.759980283582321, FX_IL); -buf[207] = float2fx((float) 3.2876478295692895, FX_IL); -buf[208] = float2fx((float) 3.9739040640452163, FX_IL); -buf[209] = float2fx((float) 2.463851487558704, FX_IL); -buf[210] = float2fx((float) 4.398257917031813, FX_IL); -buf[211] = float2fx((float) 5.403905881835056, FX_IL); -buf[212] = float2fx((float) 4.090920543703864, FX_IL); -buf[213] = float2fx((float) 4.150069482934393, FX_IL); -buf[214] = float2fx((float) 3.621531989820876, FX_IL); -buf[215] = float2fx((float) 3.230994708040832, FX_IL); -buf[216] = float2fx((float) 5.0034397044217895, FX_IL); -buf[217] = float2fx((float) 4.360565801596725, FX_IL); -buf[218] = float2fx((float) 2.9011105946901266, FX_IL); -buf[219] = float2fx((float) 4.773320978732786, FX_IL); -buf[220] = float2fx((float) 3.5776256649904052, FX_IL); -buf[221] = float2fx((float) 21.517848743343308, FX_IL); -buf[222] = float2fx((float) 3.666909746433788, FX_IL); -buf[223] = float2fx((float) 2.7865511410264756, FX_IL); -buf[224] = float2fx((float) 5.007449404606732, FX_IL); -buf[225] = float2fx((float) 3.201024110824123, FX_IL); -buf[226] = float2fx((float) 4.089076811287382, FX_IL); -buf[227] = float2fx((float) 5.015878281671276, FX_IL); -buf[228] = float2fx((float) 3.9445502474463896, FX_IL); -buf[229] = float2fx((float) 5.262989869750008, FX_IL); -buf[230] = float2fx((float) 3.4717311087801597, FX_IL); -buf[231] = float2fx((float) 3.71011644188383, FX_IL); -buf[232] = float2fx((float) 4.23636980763111, FX_IL); -buf[233] = float2fx((float) 3.938830628634233, FX_IL); -buf[234] = float2fx((float) 3.2652585766050093, FX_IL); -buf[235] = float2fx((float) 5.053823090270109, FX_IL); -buf[236] = float2fx((float) 3.759980283582321, FX_IL); -buf[237] = float2fx((float) 3.666909746433788, FX_IL); -buf[238] = float2fx((float) 21.383008758223575, FX_IL); -buf[239] = float2fx((float) 3.59098277195599, FX_IL); -buf[240] = float2fx((float) 3.1389562700875153, FX_IL); -buf[241] = float2fx((float) 1.9053923712518486, FX_IL); -buf[242] = float2fx((float) 3.493842571955116, FX_IL); -buf[243] = float2fx((float) 4.052832467266238, FX_IL); -buf[244] = float2fx((float) 2.633254042355268, FX_IL); -buf[245] = float2fx((float) 3.5209166845097077, FX_IL); -buf[246] = float2fx((float) 3.511459765272087, FX_IL); -buf[247] = float2fx((float) 2.5946369557722946, FX_IL); -buf[248] = float2fx((float) 3.265732239494459, FX_IL); -buf[249] = float2fx((float) 2.886095619751898, FX_IL); -buf[250] = float2fx((float) 2.700108283848623, FX_IL); -buf[251] = float2fx((float) 4.146744124331975, FX_IL); -buf[252] = float2fx((float) 3.2876478295692895, FX_IL); -buf[253] = float2fx((float) 2.7865511410264756, FX_IL); -buf[254] = float2fx((float) 3.59098277195599, FX_IL); -buf[255] = float2fx((float) 19.8043235057756, FX_IL); -gold[0] = float2fx((float) 4.7113552657232605, FX_IL); -gold[1] = float2fx((float) 0.0, FX_IL); -gold[2] = float2fx((float) 0.0, FX_IL); -gold[3] = float2fx((float) 0.0, FX_IL); -gold[4] = float2fx((float) 0.0, FX_IL); -gold[5] = float2fx((float) 0.0, FX_IL); -gold[6] = float2fx((float) 0.0, FX_IL); -gold[7] = float2fx((float) 0.0, FX_IL); -gold[8] = float2fx((float) 0.0, FX_IL); -gold[9] = float2fx((float) 0.0, FX_IL); -gold[10] = float2fx((float) 0.0, FX_IL); -gold[11] = float2fx((float) 0.0, FX_IL); -gold[12] = float2fx((float) 0.0, FX_IL); -gold[13] = float2fx((float) 0.0, FX_IL); -gold[14] = float2fx((float) 0.0, FX_IL); -gold[15] = float2fx((float) 0.0, FX_IL); -gold[16] = float2fx((float) 0.666428465384424, FX_IL); -gold[17] = float2fx((float) 4.289951784397356, FX_IL); -gold[18] = float2fx((float) 0.0, FX_IL); -gold[19] = float2fx((float) 0.0, FX_IL); -gold[20] = float2fx((float) 0.0, FX_IL); -gold[21] = float2fx((float) 0.0, FX_IL); -gold[22] = float2fx((float) 0.0, FX_IL); -gold[23] = float2fx((float) 0.0, FX_IL); -gold[24] = float2fx((float) 0.0, FX_IL); -gold[25] = float2fx((float) 0.0, FX_IL); -gold[26] = float2fx((float) 0.0, FX_IL); -gold[27] = float2fx((float) 0.0, FX_IL); -gold[28] = float2fx((float) 0.0, FX_IL); -gold[29] = float2fx((float) 0.0, FX_IL); -gold[30] = float2fx((float) 0.0, FX_IL); -gold[31] = float2fx((float) 0.0, FX_IL); -gold[32] = float2fx((float) 0.8672388977326794, FX_IL); -gold[33] = float2fx((float) 0.5150124631051092, FX_IL); -gold[34] = float2fx((float) 4.495523536485097, FX_IL); -gold[35] = float2fx((float) 0.0, FX_IL); -gold[36] = float2fx((float) 0.0, FX_IL); -gold[37] = float2fx((float) 0.0, FX_IL); -gold[38] = float2fx((float) 0.0, FX_IL); -gold[39] = float2fx((float) 0.0, FX_IL); -gold[40] = float2fx((float) 0.0, FX_IL); -gold[41] = float2fx((float) 0.0, FX_IL); -gold[42] = float2fx((float) 0.0, FX_IL); -gold[43] = float2fx((float) 0.0, FX_IL); -gold[44] = float2fx((float) 0.0, FX_IL); -gold[45] = float2fx((float) 0.0, FX_IL); -gold[46] = float2fx((float) 0.0, FX_IL); -gold[47] = float2fx((float) 0.0, FX_IL); -gold[48] = float2fx((float) 1.1309007719064192, FX_IL); -gold[49] = float2fx((float) 0.5277611631195649, FX_IL); -gold[50] = float2fx((float) 1.0261164310758464, FX_IL); -gold[51] = float2fx((float) 4.601842260142981, FX_IL); -gold[52] = float2fx((float) 0.0, FX_IL); -gold[53] = float2fx((float) 0.0, FX_IL); -gold[54] = float2fx((float) 0.0, FX_IL); -gold[55] = float2fx((float) 0.0, FX_IL); -gold[56] = float2fx((float) 0.0, FX_IL); -gold[57] = float2fx((float) 0.0, FX_IL); -gold[58] = float2fx((float) 0.0, FX_IL); -gold[59] = float2fx((float) 0.0, FX_IL); -gold[60] = float2fx((float) 0.0, FX_IL); -gold[61] = float2fx((float) 0.0, FX_IL); -gold[62] = float2fx((float) 0.0, FX_IL); -gold[63] = float2fx((float) 0.0, FX_IL); -gold[64] = float2fx((float) 1.0196138730539697, FX_IL); -gold[65] = float2fx((float) 0.379993415598165, FX_IL); -gold[66] = float2fx((float) 0.6265339652385439, FX_IL); -gold[67] = float2fx((float) 0.5879308138541618, FX_IL); -gold[68] = float2fx((float) 4.359966395377335, FX_IL); -gold[69] = float2fx((float) 0.0, FX_IL); -gold[70] = float2fx((float) 0.0, FX_IL); -gold[71] = float2fx((float) 0.0, FX_IL); -gold[72] = float2fx((float) 0.0, FX_IL); -gold[73] = float2fx((float) 0.0, FX_IL); -gold[74] = float2fx((float) 0.0, FX_IL); -gold[75] = float2fx((float) 0.0, FX_IL); -gold[76] = float2fx((float) 0.0, FX_IL); -gold[77] = float2fx((float) 0.0, FX_IL); -gold[78] = float2fx((float) 0.0, FX_IL); -gold[79] = float2fx((float) 0.0, FX_IL); -gold[80] = float2fx((float) 1.0267946890646447, FX_IL); -gold[81] = float2fx((float) 0.5868963498968661, FX_IL); -gold[82] = float2fx((float) 0.7945544443793714, FX_IL); -gold[83] = float2fx((float) 0.7034618197751971, FX_IL); -gold[84] = float2fx((float) 0.4173476207051091, FX_IL); -gold[85] = float2fx((float) 4.3860719361580545, FX_IL); -gold[86] = float2fx((float) 0.0, FX_IL); -gold[87] = float2fx((float) 0.0, FX_IL); -gold[88] = float2fx((float) 0.0, FX_IL); -gold[89] = float2fx((float) 0.0, FX_IL); -gold[90] = float2fx((float) 0.0, FX_IL); -gold[91] = float2fx((float) 0.0, FX_IL); -gold[92] = float2fx((float) 0.0, FX_IL); -gold[93] = float2fx((float) 0.0, FX_IL); -gold[94] = float2fx((float) 0.0, FX_IL); -gold[95] = float2fx((float) 0.0, FX_IL); -gold[96] = float2fx((float) 0.8049391087804448, FX_IL); -gold[97] = float2fx((float) 0.3720129593002042, FX_IL); -gold[98] = float2fx((float) 0.8035245647427103, FX_IL); -gold[99] = float2fx((float) 0.7223177467099694, FX_IL); -gold[100] = float2fx((float) 0.4129631834875418, FX_IL); -gold[101] = float2fx((float) 0.3381915238139431, FX_IL); -gold[102] = float2fx((float) 4.364327861162876, FX_IL); -gold[103] = float2fx((float) 0.0, FX_IL); -gold[104] = float2fx((float) 0.0, FX_IL); -gold[105] = float2fx((float) 0.0, FX_IL); -gold[106] = float2fx((float) 0.0, FX_IL); -gold[107] = float2fx((float) 0.0, FX_IL); -gold[108] = float2fx((float) 0.0, FX_IL); -gold[109] = float2fx((float) 0.0, FX_IL); -gold[110] = float2fx((float) 0.0, FX_IL); -gold[111] = float2fx((float) 0.0, FX_IL); -gold[112] = float2fx((float) 0.7756706803651391, FX_IL); -gold[113] = float2fx((float) 0.5460200889167877, FX_IL); -gold[114] = float2fx((float) 0.5939667810693409, FX_IL); -gold[115] = float2fx((float) 0.5728249258628368, FX_IL); -gold[116] = float2fx((float) 0.2677426615474974, FX_IL); -gold[117] = float2fx((float) 0.4074303141764982, FX_IL); -gold[118] = float2fx((float) 0.1271842612125832, FX_IL); -gold[119] = float2fx((float) 4.233556066382498, FX_IL); -gold[120] = float2fx((float) 0.0, FX_IL); -gold[121] = float2fx((float) 0.0, FX_IL); -gold[122] = float2fx((float) 0.0, FX_IL); -gold[123] = float2fx((float) 0.0, FX_IL); -gold[124] = float2fx((float) 0.0, FX_IL); -gold[125] = float2fx((float) 0.0, FX_IL); -gold[126] = float2fx((float) 0.0, FX_IL); -gold[127] = float2fx((float) 0.0, FX_IL); -gold[128] = float2fx((float) 1.0123703587080501, FX_IL); -gold[129] = float2fx((float) 0.40468523918053356, FX_IL); -gold[130] = float2fx((float) 0.7995608860443478, FX_IL); -gold[131] = float2fx((float) 0.7761923158049819, FX_IL); -gold[132] = float2fx((float) 0.4955340942803781, FX_IL); -gold[133] = float2fx((float) 0.42967736771654924, FX_IL); -gold[134] = float2fx((float) 0.24525897040290623, FX_IL); -gold[135] = float2fx((float) 0.2789692735189202, FX_IL); -gold[136] = float2fx((float) 4.338832325273923, FX_IL); -gold[137] = float2fx((float) 0.0, FX_IL); -gold[138] = float2fx((float) 0.0, FX_IL); -gold[139] = float2fx((float) 0.0, FX_IL); -gold[140] = float2fx((float) 0.0, FX_IL); -gold[141] = float2fx((float) 0.0, FX_IL); -gold[142] = float2fx((float) 0.0, FX_IL); -gold[143] = float2fx((float) 0.0, FX_IL); -gold[144] = float2fx((float) 1.1149716489234065, FX_IL); -gold[145] = float2fx((float) 0.469527099787549, FX_IL); -gold[146] = float2fx((float) 0.6976630510264715, FX_IL); -gold[147] = float2fx((float) 0.6729233320437725, FX_IL); -gold[148] = float2fx((float) 0.6172025223853764, FX_IL); -gold[149] = float2fx((float) 0.2514303557061031, FX_IL); -gold[150] = float2fx((float) 0.3561169388512375, FX_IL); -gold[151] = float2fx((float) 0.24000711875270647, FX_IL); -gold[152] = float2fx((float) 0.4251343717367479, FX_IL); -gold[153] = float2fx((float) 4.340017088093879, FX_IL); -gold[154] = float2fx((float) 0.0, FX_IL); -gold[155] = float2fx((float) 0.0, FX_IL); -gold[156] = float2fx((float) 0.0, FX_IL); -gold[157] = float2fx((float) 0.0, FX_IL); -gold[158] = float2fx((float) 0.0, FX_IL); -gold[159] = float2fx((float) 0.0, FX_IL); -gold[160] = float2fx((float) 0.7956979841295457, FX_IL); -gold[161] = float2fx((float) 0.3143488974856008, FX_IL); -gold[162] = float2fx((float) 0.6036091495866338, FX_IL); -gold[163] = float2fx((float) 0.6336155955154056, FX_IL); -gold[164] = float2fx((float) 0.2826222115828139, FX_IL); -gold[165] = float2fx((float) 0.364223772545865, FX_IL); -gold[166] = float2fx((float) 0.146652739683869, FX_IL); -gold[167] = float2fx((float) 0.33879962383598183, FX_IL); -gold[168] = float2fx((float) 0.30417151518472907, FX_IL); -gold[169] = float2fx((float) 0.2117118383104633, FX_IL); -gold[170] = float2fx((float) 4.269005846036581, FX_IL); -gold[171] = float2fx((float) 0.0, FX_IL); -gold[172] = float2fx((float) 0.0, FX_IL); -gold[173] = float2fx((float) 0.0, FX_IL); -gold[174] = float2fx((float) 0.0, FX_IL); -gold[175] = float2fx((float) 0.0, FX_IL); -gold[176] = float2fx((float) 1.0748732114820765, FX_IL); -gold[177] = float2fx((float) 0.4783262727797774, FX_IL); -gold[178] = float2fx((float) 0.8974757751963219, FX_IL); -gold[179] = float2fx((float) 0.8599097028214742, FX_IL); -gold[180] = float2fx((float) 0.47822967808155553, FX_IL); -gold[181] = float2fx((float) 0.5247805059627888, FX_IL); -gold[182] = float2fx((float) 0.3824308495724978, FX_IL); -gold[183] = float2fx((float) 0.3042248514817513, FX_IL); -gold[184] = float2fx((float) 0.5113735039208481, FX_IL); -gold[185] = float2fx((float) 0.28521925138847504, FX_IL); -gold[186] = float2fx((float) 0.3530769202180989, FX_IL); -gold[187] = float2fx((float) 4.278614077437359, FX_IL); -gold[188] = float2fx((float) 0.0, FX_IL); -gold[189] = float2fx((float) 0.0, FX_IL); -gold[190] = float2fx((float) 0.0, FX_IL); -gold[191] = float2fx((float) 0.0, FX_IL); -gold[192] = float2fx((float) 0.8792107676942701, FX_IL); -gold[193] = float2fx((float) 0.4778847955136813, FX_IL); -gold[194] = float2fx((float) 0.795993631330028, FX_IL); -gold[195] = float2fx((float) 0.6795846460075454, FX_IL); -gold[196] = float2fx((float) 0.2365269828124798, FX_IL); -gold[197] = float2fx((float) 0.4143933825379465, FX_IL); -gold[198] = float2fx((float) 0.4051464517116269, FX_IL); -gold[199] = float2fx((float) 0.20902518651886834, FX_IL); -gold[200] = float2fx((float) 0.3975923176234901, FX_IL); -gold[201] = float2fx((float) 0.26047630109421926, FX_IL); -gold[202] = float2fx((float) 0.22303620881252617, FX_IL); -gold[203] = float2fx((float) 0.37091668052052085, FX_IL); -gold[204] = float2fx((float) 4.319957020354159, FX_IL); -gold[205] = float2fx((float) 0.0, FX_IL); -gold[206] = float2fx((float) 0.0, FX_IL); -gold[207] = float2fx((float) 0.0, FX_IL); -gold[208] = float2fx((float) 0.8434736588337421, FX_IL); -gold[209] = float2fx((float) 0.44330023438179506, FX_IL); -gold[210] = float2fx((float) 0.7648629970165093, FX_IL); -gold[211] = float2fx((float) 0.7456200234472112, FX_IL); -gold[212] = float2fx((float) 0.4919456026268953, FX_IL); -gold[213] = float2fx((float) 0.3844604251382818, FX_IL); -gold[214] = float2fx((float) 0.29588431539459287, FX_IL); -gold[215] = float2fx((float) 0.26627394047912795, FX_IL); -gold[216] = float2fx((float) 0.5125838901041916, FX_IL); -gold[217] = float2fx((float) 0.32007343400205907, FX_IL); -gold[218] = float2fx((float) 0.12184281646539429, FX_IL); -gold[219] = float2fx((float) 0.3037021069653235, FX_IL); -gold[220] = float2fx((float) 0.14593777182243525, FX_IL); -gold[221] = float2fx((float) 4.292677934857809, FX_IL); -gold[222] = float2fx((float) 0.0, FX_IL); -gold[223] = float2fx((float) 0.0, FX_IL); -gold[224] = float2fx((float) 1.0628469139310421, FX_IL); -gold[225] = float2fx((float) 0.5810584356916401, FX_IL); -gold[226] = float2fx((float) 0.6379862691721444, FX_IL); -gold[227] = float2fx((float) 0.6198812248597813, FX_IL); -gold[228] = float2fx((float) 0.43025356144972376, FX_IL); -gold[229] = float2fx((float) 0.6174318085502667, FX_IL); -gold[230] = float2fx((float) 0.2413120400163979, FX_IL); -gold[231] = float2fx((float) 0.33941982141781196, FX_IL); -gold[232] = float2fx((float) 0.2999885429539842, FX_IL); -gold[233] = float2fx((float) 0.20806443013458878, FX_IL); -gold[234] = float2fx((float) 0.19369216445097165, FX_IL); -gold[235] = float2fx((float) 0.3555784773605884, FX_IL); -gold[236] = float2fx((float) 0.17218700995768052, FX_IL); -gold[237] = float2fx((float) 0.13389609945586317, FX_IL); -gold[238] = float2fx((float) 4.247336391592764, FX_IL); -gold[239] = float2fx((float) 0.0, FX_IL); -gold[240] = float2fx((float) 0.6662533587574064, FX_IL); -gold[241] = float2fx((float) 0.34065235258191234, FX_IL); -gold[242] = float2fx((float) 0.6096290040720538, FX_IL); -gold[243] = float2fx((float) 0.5419639502654241, FX_IL); -gold[244] = float2fx((float) 0.2577764455696311, FX_IL); -gold[245] = float2fx((float) 0.3793067939881299, FX_IL); -gold[246] = float2fx((float) 0.396942384265811, FX_IL); -gold[247] = float2fx((float) 0.22327500060074562, FX_IL); -gold[248] = float2fx((float) 0.2523534349964289, FX_IL); -gold[249] = float2fx((float) 0.1466771999912062, FX_IL); -gold[250] = float2fx((float) 0.21054962518643558, FX_IL); -gold[251] = float2fx((float) 0.3429184563457259, FX_IL); -gold[252] = float2fx((float) 0.2192544137554851, FX_IL); -gold[253] = float2fx((float) 0.09680502540189236, FX_IL); -gold[254] = float2fx((float) 0.26456623566857135, FX_IL); -gold[255] = float2fx((float) 4.217430082498195, FX_IL); +buf[0] = float2fx((float)22.196868439858292, FX_IL); +buf[1] = float2fx((float)3.139781259616778, FX_IL); +buf[2] = float2fx((float)4.085870547472895, FX_IL); +buf[3] = float2fx((float)5.328075306731808, FX_IL); +buf[4] = float2fx((float)4.8037631898173085, FX_IL); +buf[5] = float2fx((float)4.837594565141392, FX_IL); +buf[6] = float2fx((float)3.792354108739337, FX_IL); +buf[7] = float2fx((float)3.654460144405442, FX_IL); +buf[8] = float2fx((float)4.769636420361318, FX_IL); +buf[9] = float2fx((float)5.253027549287438, FX_IL); +buf[10] = float2fx((float)3.7488158874541186, FX_IL); +buf[11] = float2fx((float)5.064109564900953, FX_IL); +buf[12] = float2fx((float)4.14227428005699, FX_IL); +buf[13] = float2fx((float)3.9739040640452163, FX_IL); +buf[14] = float2fx((float)5.007449404606732, FX_IL); +buf[15] = float2fx((float)3.1389562700875153, FX_IL); +buf[16] = float2fx((float)3.139781259616778, FX_IL); +buf[17] = float2fx((float)18.8478132119287, FX_IL); +buf[18] = float2fx((float)2.7873313228223098, FX_IL); +buf[19] = float2fx((float)3.0177344093840572, FX_IL); +buf[20] = float2fx((float)2.30965314000862, FX_IL); +buf[21] = float2fx((float)3.202042252394584, FX_IL); +buf[22] = float2fx((float)2.13235199356131, FX_IL); +buf[23] = float2fx((float)2.8593288759248083, FX_IL); +buf[24] = float2fx((float)2.4107525884962855, FX_IL); +buf[25] = float2fx((float)2.757297464495678, FX_IL); +buf[26] = float2fx((float)1.8788174001646278, FX_IL); +buf[27] = float2fx((float)2.7683227522465703, FX_IL); +buf[28] = float2fx((float)2.6360338139142367, FX_IL); +buf[29] = float2fx((float)2.463851487558704, FX_IL); +buf[30] = float2fx((float)3.201024110824123, FX_IL); +buf[31] = float2fx((float)1.9053923712518486, FX_IL); +buf[32] = float2fx((float)4.085870547472895, FX_IL); +buf[33] = float2fx((float)2.7873313228223098, FX_IL); +buf[34] = float2fx((float)21.22707300998566, FX_IL); +buf[35] = float2fx((float)5.865495282498139, FX_IL); +buf[36] = float2fx((float)3.8965483434484165, FX_IL); +buf[37] = float2fx((float)4.764673434816277, FX_IL); +buf[38] = float2fx((float)4.501929408861694, FX_IL); +buf[39] = float2fx((float)3.6240905809288386, FX_IL); +buf[40] = float2fx((float)4.680829677861098, FX_IL); +buf[41] = float2fx((float)4.345119758397213, FX_IL); +buf[42] = float2fx((float)3.5654929814575227, FX_IL); +buf[43] = float2fx((float)5.213139321860575, FX_IL); +buf[44] = float2fx((float)4.587010507204246, FX_IL); +buf[45] = float2fx((float)4.398257917031813, FX_IL); +buf[46] = float2fx((float)4.089076811287382, FX_IL); +buf[47] = float2fx((float)3.493842571955116, FX_IL); +buf[48] = float2fx((float)5.328075306731808, FX_IL); +buf[49] = float2fx((float)3.0177344093840572, FX_IL); +buf[50] = float2fx((float)5.865495282498139, FX_IL); +buf[51] = float2fx((float)23.787335518557548, FX_IL); +buf[52] = float2fx((float)4.7020895446698034, FX_IL); +buf[53] = float2fx((float)5.523469708105416, FX_IL); +buf[54] = float2fx((float)5.255142342270051, FX_IL); +buf[55] = float2fx((float)4.410903793450839, FX_IL); +buf[56] = float2fx((float)5.750824736330631, FX_IL); +buf[57] = float2fx((float)5.321291013969316, FX_IL); +buf[58] = float2fx((float)4.6009288946858575, FX_IL); +buf[59] = float2fx((float)6.346100424411845, FX_IL); +buf[60] = float2fx((float)5.1906326588526435, FX_IL); +buf[61] = float2fx((float)5.403905881835056, FX_IL); +buf[62] = float2fx((float)5.015878281671276, FX_IL); +buf[63] = float2fx((float)4.052832467266238, FX_IL); +buf[64] = float2fx((float)4.8037631898173085, FX_IL); +buf[65] = float2fx((float)2.30965314000862, FX_IL); +buf[66] = float2fx((float)3.8965483434484165, FX_IL); +buf[67] = float2fx((float)4.7020895446698034, FX_IL); +buf[68] = float2fx((float)20.931521866318462, FX_IL); +buf[69] = float2fx((float)4.000974686663493, FX_IL); +buf[70] = float2fx((float)3.6907034522605544, FX_IL); +buf[71] = float2fx((float)2.874639419572023, FX_IL); +buf[72] = float2fx((float)4.303816019833494, FX_IL); +buf[73] = float2fx((float)4.838981984440691, FX_IL); +buf[74] = float2fx((float)2.9136823263997655, FX_IL); +buf[75] = float2fx((float)4.430648265633036, FX_IL); +buf[76] = float2fx((float)3.0075640686034264, FX_IL); +buf[77] = float2fx((float)4.090920543703864, FX_IL); +buf[78] = float2fx((float)3.9445502474463896, FX_IL); +buf[79] = float2fx((float)2.633254042355268, FX_IL); +buf[80] = float2fx((float)4.837594565141392, FX_IL); +buf[81] = float2fx((float)3.202042252394584, FX_IL); +buf[82] = float2fx((float)4.764673434816277, FX_IL); +buf[83] = float2fx((float)5.523469708105416, FX_IL); +buf[84] = float2fx((float)4.000974686663493, FX_IL); +buf[85] = float2fx((float)21.936736021639547, FX_IL); +buf[86] = float2fx((float)3.847088774198843, FX_IL); +buf[87] = float2fx((float)3.8905715723978265, FX_IL); +buf[88] = float2fx((float)4.54972693132023, FX_IL); +buf[89] = float2fx((float)3.808497489487739, FX_IL); +buf[90] = float2fx((float)3.6422967718709263, FX_IL); +buf[91] = float2fx((float)5.203722126960201, FX_IL); +buf[92] = float2fx((float)4.210033077426458, FX_IL); +buf[93] = float2fx((float)4.150069482934393, FX_IL); +buf[94] = float2fx((float)5.262989869750008, FX_IL); +buf[95] = float2fx((float)3.5209166845097077, FX_IL); +buf[96] = float2fx((float)3.792354108739337, FX_IL); +buf[97] = float2fx((float)2.13235199356131, FX_IL); +buf[98] = float2fx((float)4.501929408861694, FX_IL); +buf[99] = float2fx((float)5.255142342270051, FX_IL); +buf[100] = float2fx((float)3.6907034522605544, FX_IL); +buf[101] = float2fx((float)3.847088774198843, FX_IL); +buf[102] = float2fx((float)21.285985041506976, FX_IL); +buf[103] = float2fx((float)2.521953879593371, FX_IL); +buf[104] = float2fx((float)3.5889100837833756, FX_IL); +buf[105] = float2fx((float)4.012932927277644, FX_IL); +buf[106] = float2fx((float)2.580047456823562, FX_IL); +buf[107] = float2fx((float)4.429444108733627, FX_IL); +buf[108] = float2fx((float)4.021980167475107, FX_IL); +buf[109] = float2fx((float)3.621531989820876, FX_IL); +buf[110] = float2fx((float)3.4717311087801597, FX_IL); +buf[111] = float2fx((float)3.511459765272087, FX_IL); +buf[112] = float2fx((float)3.654460144405442, FX_IL); +buf[113] = float2fx((float)2.8593288759248083, FX_IL); +buf[114] = float2fx((float)3.6240905809288386, FX_IL); +buf[115] = float2fx((float)4.410903793450839, FX_IL); +buf[116] = float2fx((float)2.874639419572023, FX_IL); +buf[117] = float2fx((float)3.8905715723978265, FX_IL); +buf[118] = float2fx((float)2.521953879593371, FX_IL); +buf[119] = float2fx((float)19.75758627180919, FX_IL); +buf[120] = float2fx((float)3.4457315301204803, FX_IL); +buf[121] = float2fx((float)3.2501458389813767, FX_IL); +buf[122] = float2fx((float)3.187359952152498, FX_IL); +buf[123] = float2fx((float)3.7990180221608707, FX_IL); +buf[124] = float2fx((float)2.9736024008233595, FX_IL); +buf[125] = float2fx((float)3.230994708040832, FX_IL); +buf[126] = float2fx((float)3.71011644188383, FX_IL); +buf[127] = float2fx((float)2.5946369557722946, FX_IL); +buf[128] = float2fx((float)4.769636420361318, FX_IL); +buf[129] = float2fx((float)2.4107525884962855, FX_IL); +buf[130] = float2fx((float)4.680829677861098, FX_IL); +buf[131] = float2fx((float)5.750824736330631, FX_IL); +buf[132] = float2fx((float)4.303816019833494, FX_IL); +buf[133] = float2fx((float)4.54972693132023, FX_IL); +buf[134] = float2fx((float)3.5889100837833756, FX_IL); +buf[135] = float2fx((float)3.4457315301204803, FX_IL); +buf[136] = float2fx((float)21.824054451502782, FX_IL); +buf[137] = float2fx((float)4.81167800786811, FX_IL); +buf[138] = float2fx((float)3.6539626761330117, FX_IL); +buf[139] = float2fx((float)5.5266764785537665, FX_IL); +buf[140] = float2fx((float)4.425440044399624, FX_IL); +buf[141] = float2fx((float)5.0034397044217895, FX_IL); +buf[142] = float2fx((float)4.23636980763111, FX_IL); +buf[143] = float2fx((float)3.265732239494459, FX_IL); +buf[144] = float2fx((float)5.253027549287438, FX_IL); +buf[145] = float2fx((float)2.757297464495678, FX_IL); +buf[146] = float2fx((float)4.345119758397213, FX_IL); +buf[147] = float2fx((float)5.321291013969316, FX_IL); +buf[148] = float2fx((float)4.838981984440691, FX_IL); +buf[149] = float2fx((float)3.808497489487739, FX_IL); +buf[150] = float2fx((float)4.012932927277644, FX_IL); +buf[151] = float2fx((float)3.2501458389813767, FX_IL); +buf[152] = float2fx((float)4.81167800786811, FX_IL); +buf[153] = float2fx((float)22.048243446491337, FX_IL); +buf[154] = float2fx((float)3.3299652011330756, FX_IL); +buf[155] = float2fx((float)4.719404719219467, FX_IL); +buf[156] = float2fx((float)3.961443582169512, FX_IL); +buf[157] = float2fx((float)4.360565801596725, FX_IL); +buf[158] = float2fx((float)3.938830628634233, FX_IL); +buf[159] = float2fx((float)2.886095619751898, FX_IL); +buf[160] = float2fx((float)3.7488158874541186, FX_IL); +buf[161] = float2fx((float)1.8788174001646278, FX_IL); +buf[162] = float2fx((float)3.5654929814575227, FX_IL); +buf[163] = float2fx((float)4.6009288946858575, FX_IL); +buf[164] = float2fx((float)2.9136823263997655, FX_IL); +buf[165] = float2fx((float)3.6422967718709263, FX_IL); +buf[166] = float2fx((float)2.580047456823562, FX_IL); +buf[167] = float2fx((float)3.187359952152498, FX_IL); +buf[168] = float2fx((float)3.6539626761330117, FX_IL); +buf[169] = float2fx((float)3.3299652011330756, FX_IL); +buf[170] = float2fx((float)20.208342848404044, FX_IL); +buf[171] = float2fx((float)4.300881215976244, FX_IL); +buf[172] = float2fx((float)3.237111508426725, FX_IL); +buf[173] = float2fx((float)2.9011105946901266, FX_IL); +buf[174] = float2fx((float)3.2652585766050093, FX_IL); +buf[175] = float2fx((float)2.700108283848623, FX_IL); +buf[176] = float2fx((float)5.064109564900953, FX_IL); +buf[177] = float2fx((float)2.7683227522465703, FX_IL); +buf[178] = float2fx((float)5.213139321860575, FX_IL); +buf[179] = float2fx((float)6.346100424411845, FX_IL); +buf[180] = float2fx((float)4.430648265633036, FX_IL); +buf[181] = float2fx((float)5.203722126960201, FX_IL); +buf[182] = float2fx((float)4.429444108733627, FX_IL); +buf[183] = float2fx((float)3.7990180221608707, FX_IL); +buf[184] = float2fx((float)5.5266764785537665, FX_IL); +buf[185] = float2fx((float)4.719404719219467, FX_IL); +buf[186] = float2fx((float)4.300881215976244, FX_IL); +buf[187] = float2fx((float)22.446014844575057, FX_IL); +buf[188] = float2fx((float)4.964871637408653, FX_IL); +buf[189] = float2fx((float)4.773320978732786, FX_IL); +buf[190] = float2fx((float)5.053823090270109, FX_IL); +buf[191] = float2fx((float)4.146744124331975, FX_IL); +buf[192] = float2fx((float)4.14227428005699, FX_IL); +buf[193] = float2fx((float)2.6360338139142367, FX_IL); +buf[194] = float2fx((float)4.587010507204246, FX_IL); +buf[195] = float2fx((float)5.1906326588526435, FX_IL); +buf[196] = float2fx((float)3.0075640686034264, FX_IL); +buf[197] = float2fx((float)4.210033077426458, FX_IL); +buf[198] = float2fx((float)4.021980167475107, FX_IL); +buf[199] = float2fx((float)2.9736024008233595, FX_IL); +buf[200] = float2fx((float)4.425440044399624, FX_IL); +buf[201] = float2fx((float)3.961443582169512, FX_IL); +buf[202] = float2fx((float)3.237111508426725, FX_IL); +buf[203] = float2fx((float)4.964871637408653, FX_IL); +buf[204] = float2fx((float)21.607609215545207, FX_IL); +buf[205] = float2fx((float)3.5776256649904052, FX_IL); +buf[206] = float2fx((float)3.759980283582321, FX_IL); +buf[207] = float2fx((float)3.2876478295692895, FX_IL); +buf[208] = float2fx((float)3.9739040640452163, FX_IL); +buf[209] = float2fx((float)2.463851487558704, FX_IL); +buf[210] = float2fx((float)4.398257917031813, FX_IL); +buf[211] = float2fx((float)5.403905881835056, FX_IL); +buf[212] = float2fx((float)4.090920543703864, FX_IL); +buf[213] = float2fx((float)4.150069482934393, FX_IL); +buf[214] = float2fx((float)3.621531989820876, FX_IL); +buf[215] = float2fx((float)3.230994708040832, FX_IL); +buf[216] = float2fx((float)5.0034397044217895, FX_IL); +buf[217] = float2fx((float)4.360565801596725, FX_IL); +buf[218] = float2fx((float)2.9011105946901266, FX_IL); +buf[219] = float2fx((float)4.773320978732786, FX_IL); +buf[220] = float2fx((float)3.5776256649904052, FX_IL); +buf[221] = float2fx((float)21.517848743343308, FX_IL); +buf[222] = float2fx((float)3.666909746433788, FX_IL); +buf[223] = float2fx((float)2.7865511410264756, FX_IL); +buf[224] = float2fx((float)5.007449404606732, FX_IL); +buf[225] = float2fx((float)3.201024110824123, FX_IL); +buf[226] = float2fx((float)4.089076811287382, FX_IL); +buf[227] = float2fx((float)5.015878281671276, FX_IL); +buf[228] = float2fx((float)3.9445502474463896, FX_IL); +buf[229] = float2fx((float)5.262989869750008, FX_IL); +buf[230] = float2fx((float)3.4717311087801597, FX_IL); +buf[231] = float2fx((float)3.71011644188383, FX_IL); +buf[232] = float2fx((float)4.23636980763111, FX_IL); +buf[233] = float2fx((float)3.938830628634233, FX_IL); +buf[234] = float2fx((float)3.2652585766050093, FX_IL); +buf[235] = float2fx((float)5.053823090270109, FX_IL); +buf[236] = float2fx((float)3.759980283582321, FX_IL); +buf[237] = float2fx((float)3.666909746433788, FX_IL); +buf[238] = float2fx((float)21.383008758223575, FX_IL); +buf[239] = float2fx((float)3.59098277195599, FX_IL); +buf[240] = float2fx((float)3.1389562700875153, FX_IL); +buf[241] = float2fx((float)1.9053923712518486, FX_IL); +buf[242] = float2fx((float)3.493842571955116, FX_IL); +buf[243] = float2fx((float)4.052832467266238, FX_IL); +buf[244] = float2fx((float)2.633254042355268, FX_IL); +buf[245] = float2fx((float)3.5209166845097077, FX_IL); +buf[246] = float2fx((float)3.511459765272087, FX_IL); +buf[247] = float2fx((float)2.5946369557722946, FX_IL); +buf[248] = float2fx((float)3.265732239494459, FX_IL); +buf[249] = float2fx((float)2.886095619751898, FX_IL); +buf[250] = float2fx((float)2.700108283848623, FX_IL); +buf[251] = float2fx((float)4.146744124331975, FX_IL); +buf[252] = float2fx((float)3.2876478295692895, FX_IL); +buf[253] = float2fx((float)2.7865511410264756, FX_IL); +buf[254] = float2fx((float)3.59098277195599, FX_IL); +buf[255] = float2fx((float)19.8043235057756, FX_IL); +gold[0] = float2fx((float)4.7113552657232605, FX_IL); +gold[1] = float2fx((float)0.0, FX_IL); +gold[2] = float2fx((float)0.0, FX_IL); +gold[3] = float2fx((float)0.0, FX_IL); +gold[4] = float2fx((float)0.0, FX_IL); +gold[5] = float2fx((float)0.0, FX_IL); +gold[6] = float2fx((float)0.0, FX_IL); +gold[7] = float2fx((float)0.0, FX_IL); +gold[8] = float2fx((float)0.0, FX_IL); +gold[9] = float2fx((float)0.0, FX_IL); +gold[10] = float2fx((float)0.0, FX_IL); +gold[11] = float2fx((float)0.0, FX_IL); +gold[12] = float2fx((float)0.0, FX_IL); +gold[13] = float2fx((float)0.0, FX_IL); +gold[14] = float2fx((float)0.0, FX_IL); +gold[15] = float2fx((float)0.0, FX_IL); +gold[16] = float2fx((float)0.666428465384424, FX_IL); +gold[17] = float2fx((float)4.289951784397356, FX_IL); +gold[18] = float2fx((float)0.0, FX_IL); +gold[19] = float2fx((float)0.0, FX_IL); +gold[20] = float2fx((float)0.0, FX_IL); +gold[21] = float2fx((float)0.0, FX_IL); +gold[22] = float2fx((float)0.0, FX_IL); +gold[23] = float2fx((float)0.0, FX_IL); +gold[24] = float2fx((float)0.0, FX_IL); +gold[25] = float2fx((float)0.0, FX_IL); +gold[26] = float2fx((float)0.0, FX_IL); +gold[27] = float2fx((float)0.0, FX_IL); +gold[28] = float2fx((float)0.0, FX_IL); +gold[29] = float2fx((float)0.0, FX_IL); +gold[30] = float2fx((float)0.0, FX_IL); +gold[31] = float2fx((float)0.0, FX_IL); +gold[32] = float2fx((float)0.8672388977326794, FX_IL); +gold[33] = float2fx((float)0.5150124631051092, FX_IL); +gold[34] = float2fx((float)4.495523536485097, FX_IL); +gold[35] = float2fx((float)0.0, FX_IL); +gold[36] = float2fx((float)0.0, FX_IL); +gold[37] = float2fx((float)0.0, FX_IL); +gold[38] = float2fx((float)0.0, FX_IL); +gold[39] = float2fx((float)0.0, FX_IL); +gold[40] = float2fx((float)0.0, FX_IL); +gold[41] = float2fx((float)0.0, FX_IL); +gold[42] = float2fx((float)0.0, FX_IL); +gold[43] = float2fx((float)0.0, FX_IL); +gold[44] = float2fx((float)0.0, FX_IL); +gold[45] = float2fx((float)0.0, FX_IL); +gold[46] = float2fx((float)0.0, FX_IL); +gold[47] = float2fx((float)0.0, FX_IL); +gold[48] = float2fx((float)1.1309007719064192, FX_IL); +gold[49] = float2fx((float)0.5277611631195649, FX_IL); +gold[50] = float2fx((float)1.0261164310758464, FX_IL); +gold[51] = float2fx((float)4.601842260142981, FX_IL); +gold[52] = float2fx((float)0.0, FX_IL); +gold[53] = float2fx((float)0.0, FX_IL); +gold[54] = float2fx((float)0.0, FX_IL); +gold[55] = float2fx((float)0.0, FX_IL); +gold[56] = float2fx((float)0.0, FX_IL); +gold[57] = float2fx((float)0.0, FX_IL); +gold[58] = float2fx((float)0.0, FX_IL); +gold[59] = float2fx((float)0.0, FX_IL); +gold[60] = float2fx((float)0.0, FX_IL); +gold[61] = float2fx((float)0.0, FX_IL); +gold[62] = float2fx((float)0.0, FX_IL); +gold[63] = float2fx((float)0.0, FX_IL); +gold[64] = float2fx((float)1.0196138730539697, FX_IL); +gold[65] = float2fx((float)0.379993415598165, FX_IL); +gold[66] = float2fx((float)0.6265339652385439, FX_IL); +gold[67] = float2fx((float)0.5879308138541618, FX_IL); +gold[68] = float2fx((float)4.359966395377335, FX_IL); +gold[69] = float2fx((float)0.0, FX_IL); +gold[70] = float2fx((float)0.0, FX_IL); +gold[71] = float2fx((float)0.0, FX_IL); +gold[72] = float2fx((float)0.0, FX_IL); +gold[73] = float2fx((float)0.0, FX_IL); +gold[74] = float2fx((float)0.0, FX_IL); +gold[75] = float2fx((float)0.0, FX_IL); +gold[76] = float2fx((float)0.0, FX_IL); +gold[77] = float2fx((float)0.0, FX_IL); +gold[78] = float2fx((float)0.0, FX_IL); +gold[79] = float2fx((float)0.0, FX_IL); +gold[80] = float2fx((float)1.0267946890646447, FX_IL); +gold[81] = float2fx((float)0.5868963498968661, FX_IL); +gold[82] = float2fx((float)0.7945544443793714, FX_IL); +gold[83] = float2fx((float)0.7034618197751971, FX_IL); +gold[84] = float2fx((float)0.4173476207051091, FX_IL); +gold[85] = float2fx((float)4.3860719361580545, FX_IL); +gold[86] = float2fx((float)0.0, FX_IL); +gold[87] = float2fx((float)0.0, FX_IL); +gold[88] = float2fx((float)0.0, FX_IL); +gold[89] = float2fx((float)0.0, FX_IL); +gold[90] = float2fx((float)0.0, FX_IL); +gold[91] = float2fx((float)0.0, FX_IL); +gold[92] = float2fx((float)0.0, FX_IL); +gold[93] = float2fx((float)0.0, FX_IL); +gold[94] = float2fx((float)0.0, FX_IL); +gold[95] = float2fx((float)0.0, FX_IL); +gold[96] = float2fx((float)0.8049391087804448, FX_IL); +gold[97] = float2fx((float)0.3720129593002042, FX_IL); +gold[98] = float2fx((float)0.8035245647427103, FX_IL); +gold[99] = float2fx((float)0.7223177467099694, FX_IL); +gold[100] = float2fx((float)0.4129631834875418, FX_IL); +gold[101] = float2fx((float)0.3381915238139431, FX_IL); +gold[102] = float2fx((float)4.364327861162876, FX_IL); +gold[103] = float2fx((float)0.0, FX_IL); +gold[104] = float2fx((float)0.0, FX_IL); +gold[105] = float2fx((float)0.0, FX_IL); +gold[106] = float2fx((float)0.0, FX_IL); +gold[107] = float2fx((float)0.0, FX_IL); +gold[108] = float2fx((float)0.0, FX_IL); +gold[109] = float2fx((float)0.0, FX_IL); +gold[110] = float2fx((float)0.0, FX_IL); +gold[111] = float2fx((float)0.0, FX_IL); +gold[112] = float2fx((float)0.7756706803651391, FX_IL); +gold[113] = float2fx((float)0.5460200889167877, FX_IL); +gold[114] = float2fx((float)0.5939667810693409, FX_IL); +gold[115] = float2fx((float)0.5728249258628368, FX_IL); +gold[116] = float2fx((float)0.2677426615474974, FX_IL); +gold[117] = float2fx((float)0.4074303141764982, FX_IL); +gold[118] = float2fx((float)0.1271842612125832, FX_IL); +gold[119] = float2fx((float)4.233556066382498, FX_IL); +gold[120] = float2fx((float)0.0, FX_IL); +gold[121] = float2fx((float)0.0, FX_IL); +gold[122] = float2fx((float)0.0, FX_IL); +gold[123] = float2fx((float)0.0, FX_IL); +gold[124] = float2fx((float)0.0, FX_IL); +gold[125] = float2fx((float)0.0, FX_IL); +gold[126] = float2fx((float)0.0, FX_IL); +gold[127] = float2fx((float)0.0, FX_IL); +gold[128] = float2fx((float)1.0123703587080501, FX_IL); +gold[129] = float2fx((float)0.40468523918053356, FX_IL); +gold[130] = float2fx((float)0.7995608860443478, FX_IL); +gold[131] = float2fx((float)0.7761923158049819, FX_IL); +gold[132] = float2fx((float)0.4955340942803781, FX_IL); +gold[133] = float2fx((float)0.42967736771654924, FX_IL); +gold[134] = float2fx((float)0.24525897040290623, FX_IL); +gold[135] = float2fx((float)0.2789692735189202, FX_IL); +gold[136] = float2fx((float)4.338832325273923, FX_IL); +gold[137] = float2fx((float)0.0, FX_IL); +gold[138] = float2fx((float)0.0, FX_IL); +gold[139] = float2fx((float)0.0, FX_IL); +gold[140] = float2fx((float)0.0, FX_IL); +gold[141] = float2fx((float)0.0, FX_IL); +gold[142] = float2fx((float)0.0, FX_IL); +gold[143] = float2fx((float)0.0, FX_IL); +gold[144] = float2fx((float)1.1149716489234065, FX_IL); +gold[145] = float2fx((float)0.469527099787549, FX_IL); +gold[146] = float2fx((float)0.6976630510264715, FX_IL); +gold[147] = float2fx((float)0.6729233320437725, FX_IL); +gold[148] = float2fx((float)0.6172025223853764, FX_IL); +gold[149] = float2fx((float)0.2514303557061031, FX_IL); +gold[150] = float2fx((float)0.3561169388512375, FX_IL); +gold[151] = float2fx((float)0.24000711875270647, FX_IL); +gold[152] = float2fx((float)0.4251343717367479, FX_IL); +gold[153] = float2fx((float)4.340017088093879, FX_IL); +gold[154] = float2fx((float)0.0, FX_IL); +gold[155] = float2fx((float)0.0, FX_IL); +gold[156] = float2fx((float)0.0, FX_IL); +gold[157] = float2fx((float)0.0, FX_IL); +gold[158] = float2fx((float)0.0, FX_IL); +gold[159] = float2fx((float)0.0, FX_IL); +gold[160] = float2fx((float)0.7956979841295457, FX_IL); +gold[161] = float2fx((float)0.3143488974856008, FX_IL); +gold[162] = float2fx((float)0.6036091495866338, FX_IL); +gold[163] = float2fx((float)0.6336155955154056, FX_IL); +gold[164] = float2fx((float)0.2826222115828139, FX_IL); +gold[165] = float2fx((float)0.364223772545865, FX_IL); +gold[166] = float2fx((float)0.146652739683869, FX_IL); +gold[167] = float2fx((float)0.33879962383598183, FX_IL); +gold[168] = float2fx((float)0.30417151518472907, FX_IL); +gold[169] = float2fx((float)0.2117118383104633, FX_IL); +gold[170] = float2fx((float)4.269005846036581, FX_IL); +gold[171] = float2fx((float)0.0, FX_IL); +gold[172] = float2fx((float)0.0, FX_IL); +gold[173] = float2fx((float)0.0, FX_IL); +gold[174] = float2fx((float)0.0, FX_IL); +gold[175] = float2fx((float)0.0, FX_IL); +gold[176] = float2fx((float)1.0748732114820765, FX_IL); +gold[177] = float2fx((float)0.4783262727797774, FX_IL); +gold[178] = float2fx((float)0.8974757751963219, FX_IL); +gold[179] = float2fx((float)0.8599097028214742, FX_IL); +gold[180] = float2fx((float)0.47822967808155553, FX_IL); +gold[181] = float2fx((float)0.5247805059627888, FX_IL); +gold[182] = float2fx((float)0.3824308495724978, FX_IL); +gold[183] = float2fx((float)0.3042248514817513, FX_IL); +gold[184] = float2fx((float)0.5113735039208481, FX_IL); +gold[185] = float2fx((float)0.28521925138847504, FX_IL); +gold[186] = float2fx((float)0.3530769202180989, FX_IL); +gold[187] = float2fx((float)4.278614077437359, FX_IL); +gold[188] = float2fx((float)0.0, FX_IL); +gold[189] = float2fx((float)0.0, FX_IL); +gold[190] = float2fx((float)0.0, FX_IL); +gold[191] = float2fx((float)0.0, FX_IL); +gold[192] = float2fx((float)0.8792107676942701, FX_IL); +gold[193] = float2fx((float)0.4778847955136813, FX_IL); +gold[194] = float2fx((float)0.795993631330028, FX_IL); +gold[195] = float2fx((float)0.6795846460075454, FX_IL); +gold[196] = float2fx((float)0.2365269828124798, FX_IL); +gold[197] = float2fx((float)0.4143933825379465, FX_IL); +gold[198] = float2fx((float)0.4051464517116269, FX_IL); +gold[199] = float2fx((float)0.20902518651886834, FX_IL); +gold[200] = float2fx((float)0.3975923176234901, FX_IL); +gold[201] = float2fx((float)0.26047630109421926, FX_IL); +gold[202] = float2fx((float)0.22303620881252617, FX_IL); +gold[203] = float2fx((float)0.37091668052052085, FX_IL); +gold[204] = float2fx((float)4.319957020354159, FX_IL); +gold[205] = float2fx((float)0.0, FX_IL); +gold[206] = float2fx((float)0.0, FX_IL); +gold[207] = float2fx((float)0.0, FX_IL); +gold[208] = float2fx((float)0.8434736588337421, FX_IL); +gold[209] = float2fx((float)0.44330023438179506, FX_IL); +gold[210] = float2fx((float)0.7648629970165093, FX_IL); +gold[211] = float2fx((float)0.7456200234472112, FX_IL); +gold[212] = float2fx((float)0.4919456026268953, FX_IL); +gold[213] = float2fx((float)0.3844604251382818, FX_IL); +gold[214] = float2fx((float)0.29588431539459287, FX_IL); +gold[215] = float2fx((float)0.26627394047912795, FX_IL); +gold[216] = float2fx((float)0.5125838901041916, FX_IL); +gold[217] = float2fx((float)0.32007343400205907, FX_IL); +gold[218] = float2fx((float)0.12184281646539429, FX_IL); +gold[219] = float2fx((float)0.3037021069653235, FX_IL); +gold[220] = float2fx((float)0.14593777182243525, FX_IL); +gold[221] = float2fx((float)4.292677934857809, FX_IL); +gold[222] = float2fx((float)0.0, FX_IL); +gold[223] = float2fx((float)0.0, FX_IL); +gold[224] = float2fx((float)1.0628469139310421, FX_IL); +gold[225] = float2fx((float)0.5810584356916401, FX_IL); +gold[226] = float2fx((float)0.6379862691721444, FX_IL); +gold[227] = float2fx((float)0.6198812248597813, FX_IL); +gold[228] = float2fx((float)0.43025356144972376, FX_IL); +gold[229] = float2fx((float)0.6174318085502667, FX_IL); +gold[230] = float2fx((float)0.2413120400163979, FX_IL); +gold[231] = float2fx((float)0.33941982141781196, FX_IL); +gold[232] = float2fx((float)0.2999885429539842, FX_IL); +gold[233] = float2fx((float)0.20806443013458878, FX_IL); +gold[234] = float2fx((float)0.19369216445097165, FX_IL); +gold[235] = float2fx((float)0.3555784773605884, FX_IL); +gold[236] = float2fx((float)0.17218700995768052, FX_IL); +gold[237] = float2fx((float)0.13389609945586317, FX_IL); +gold[238] = float2fx((float)4.247336391592764, FX_IL); +gold[239] = float2fx((float)0.0, FX_IL); +gold[240] = float2fx((float)0.6662533587574064, FX_IL); +gold[241] = float2fx((float)0.34065235258191234, FX_IL); +gold[242] = float2fx((float)0.6096290040720538, FX_IL); +gold[243] = float2fx((float)0.5419639502654241, FX_IL); +gold[244] = float2fx((float)0.2577764455696311, FX_IL); +gold[245] = float2fx((float)0.3793067939881299, FX_IL); +gold[246] = float2fx((float)0.396942384265811, FX_IL); +gold[247] = float2fx((float)0.22327500060074562, FX_IL); +gold[248] = float2fx((float)0.2523534349964289, FX_IL); +gold[249] = float2fx((float)0.1466771999912062, FX_IL); +gold[250] = float2fx((float)0.21054962518643558, FX_IL); +gold[251] = float2fx((float)0.3429184563457259, FX_IL); +gold[252] = float2fx((float)0.2192544137554851, FX_IL); +gold[253] = float2fx((float)0.09680502540189236, FX_IL); +gold[254] = float2fx((float)0.26456623566857135, FX_IL); +gold[255] = float2fx((float)4.217430082498195, FX_IL); diff --git a/accelerators/stratus_hls/cholesky_stratus/hw/datagen/datagen.py b/accelerators/stratus_hls/cholesky_stratus/hw/datagen/datagen.py index 59835e8355..62554bc10f 100755 --- a/accelerators/stratus_hls/cholesky_stratus/hw/datagen/datagen.py +++ b/accelerators/stratus_hls/cholesky_stratus/hw/datagen/datagen.py @@ -5,22 +5,24 @@ n = input("Enter Number of Rows in the Matrix : ") K = np.random.randint(5, size=(n, n)) A = np.random.rand(n, n) -B=A.transpose() +B = A.transpose() C = np.dot(A, B) -D= np.identity(n) -E= n*D -F = np.add(C,E) -np.savetxt('input.txt',F,fmt='%.6f') +D = np.identity(n) +E = n * D +F = np.add(C, E) +np.savetxt('input.txt', F, fmt='%.6f') L = np.linalg.cholesky(F) -np.savetxt('output.txt',L,fmt='%.8f') +np.savetxt('output.txt', L, fmt='%.8f') out = open("data.h", "w") -for i in range(0,n): - for j in range(0,n): - index = i*n+j - out.write("buf[" + str(index) + "] = float2fx((float) " + str(F[i][j]) + ", FX_IL);\n") +for i in range(0, n): + for j in range(0, n): + index = i * n + j + out.write( + "buf[" + str(index) + "] = float2fx((float) " + str(F[i][j]) + ", FX_IL);\n") -for i in range(0,n): - for j in range(0,n): - index = i*n+j - out.write("gold[" + str(index) + "] = float2fx((float) " + str(L[i][j]) + ", FX_IL);\n") +for i in range(0, n): + for j in range(0, n): + index = i * n + j + out.write( + "gold[" + str(index) + "] = float2fx((float) " + str(L[i][j]) + ", FX_IL);\n") out.close() diff --git a/accelerators/stratus_hls/cholesky_stratus/hw/src/cholesky.cpp b/accelerators/stratus_hls/cholesky_stratus/hw/src/cholesky.cpp index 2098f5e0f8..c384b29f38 100644 --- a/accelerators/stratus_hls/cholesky_stratus/hw/src/cholesky.cpp +++ b/accelerators/stratus_hls/cholesky_stratus/hw/src/cholesky.cpp @@ -46,35 +46,33 @@ void cholesky::load_input() wait(); bool ping = true; - bool fetch_ping ; - uint32_t offset = 0; + bool fetch_ping; + uint32_t offset = 0; uint32_t fetch_offset = 0; bool even_rows; - uint32_t start_fetching_output = 0; + uint32_t start_fetching_output = 0; uint32_t start_fetching_output_thresh = 3; sc_dt::sc_bv rows_bv(rows); even_rows = (rows_bv.range(0, 0) == 0); // Batching - for (uint16_t b = 0; b < 1; b++) - { + for (uint16_t b = 0; b < 1; b++) { wait(); uint32_t length = rows * rows; // Chunking - for (int rem = length; rem > 0; rem -= rows) - { + for (int rem = length; rem > 0; rem -= rows) { wait(); // Configure DMA transaction uint32_t len = rem > rows ? rows : rem; - len = (DMA_WORD_PER_BEAT==2 && !even_rows) ? len+1 : len; - //ESP_REPORT_INFO("Load offset: %d, adjusted: %d\n", offset, offset / DMA_WORD_PER_BEAT); + len = (DMA_WORD_PER_BEAT == 2 && !even_rows) ? len + 1 : len; + // ESP_REPORT_INFO("Load offset: %d, adjusted: %d\n", offset, offset / + // DMA_WORD_PER_BEAT); dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len / DMA_WORD_PER_BEAT, DMA_SIZE); - offset += (DMA_WORD_PER_BEAT==2 && !even_rows) ? ((ping) ? (len-2) : len) : len; + offset += (DMA_WORD_PER_BEAT == 2 && !even_rows) ? ((ping) ? (len - 2) : len) : len; this->dma_read_ctrl.put(dma_info); - for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { HLS_BREAK_DEP(plm_in_ping); HLS_BREAK_DEP(plm_in_pong); @@ -83,113 +81,151 @@ void cholesky::load_input() dataBv = this->dma_read_chnl.get(); wait(); #if (DMA_WORD_PER_BEAT == 2) - if(!even_rows) { - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { - HLS_UNROLL_SIMPLE; - if (ping) { - plm_in_ping[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + if (!even_rows) { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + HLS_UNROLL_SIMPLE; + if (ping) { + plm_in_ping[i + k] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_int64(); } else { - if(i == 0 && k == 0) - plm_in_pong[i ] = dataBv.range(2 * DATA_WIDTH - 1, DATA_WIDTH).to_int64(); - else if(i != 0) - plm_in_pong[i + k-1] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + if (i == 0 && k == 0) + plm_in_pong[i] = + dataBv.range(2 * DATA_WIDTH - 1, DATA_WIDTH).to_int64(); + else if (i != 0) + plm_in_pong[i + k - 1] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_int64(); } - } - } else { - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { - HLS_UNROLL_SIMPLE; - if (ping) - plm_in_ping[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); - else - plm_in_pong[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); - } - } + } + } + else { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + HLS_UNROLL_SIMPLE; + if (ping) + plm_in_ping[i + k] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_int64(); + else + plm_in_pong[i + k] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_int64(); + } + } #else for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; if (ping) - plm_in_ping[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + plm_in_ping[i + k] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); else - plm_in_pong[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); - } + plm_in_pong[i + k] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + } #endif - } //for(i) + } // for(i) - if(start_fetching_output >= start_fetching_output_thresh) { - fetch_ping = true; - bool skip = false; + if (start_fetching_output >= start_fetching_output_thresh) { + fetch_ping = true; + bool skip = false; int fetch_time = start_fetching_output - 2; - fetch_offset = (rows * rows) + rows; - for (int fetch_index = 0; fetch_index < fetch_time+1; fetch_index++) { - wait(); - - if(skip) { - uint32_t fetch_len = rows; - fetch_len = (DMA_WORD_PER_BEAT == 2 && !even_rows) ? fetch_len + 1 : fetch_len; - - dma_info_t dma_info(fetch_offset / DMA_WORD_PER_BEAT, fetch_len / DMA_WORD_PER_BEAT, DMA_SIZE); - fetch_offset += (DMA_WORD_PER_BEAT == 2 && !even_rows) ? (fetch_ping ? fetch_len : fetch_len - 2) : fetch_len; - this->dma_read_ctrl.put(dma_info); - - for (uint16_t i = 0; i < fetch_len; i += DMA_WORD_PER_BEAT) - { + fetch_offset = (rows * rows) + rows; + for (int fetch_index = 0; fetch_index < fetch_time + 1; fetch_index++) { + wait(); + + if (skip) { + uint32_t fetch_len = rows; + fetch_len = + (DMA_WORD_PER_BEAT == 2 && !even_rows) ? fetch_len + 1 : fetch_len; + + dma_info_t dma_info(fetch_offset / DMA_WORD_PER_BEAT, + fetch_len / DMA_WORD_PER_BEAT, DMA_SIZE); + fetch_offset += (DMA_WORD_PER_BEAT == 2 && !even_rows) ? + (fetch_ping ? fetch_len : fetch_len - 2) : + fetch_len; + this->dma_read_ctrl.put(dma_info); + + for (uint16_t i = 0; i < fetch_len; i += DMA_WORD_PER_BEAT) { HLS_BREAK_DEP(plm_fetch_outdata_ping); HLS_BREAK_DEP(plm_fetch_outdata_pong); sc_dt::sc_bv data_Bv; data_Bv = this->dma_read_chnl.get(); wait(); #if (DMA_WORD_PER_BEAT == 2) - if (!even_rows) { - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { - HLS_UNROLL_SIMPLE; - if (fetch_ping) { - if (i == 0 && k == 0) - plm_fetch_outdata_ping[i] = data_Bv.range(2 * DATA_WIDTH - 1, DATA_WIDTH).to_int64(); - else if(i != 0) - plm_fetch_outdata_ping[i+k-1] = data_Bv.range((k+1)*DATA_WIDTH-1, k*DATA_WIDTH).to_int64(); - } else { - if(i == (fetch_len - 2) && k == 0) - plm_fetch_outdata_pong[i] = data_Bv.range(DATA_WIDTH - 1, 0).to_int64(); - else if (i!=(fetch_len-2)) - plm_fetch_outdata_pong[i+k] = data_Bv.range((k+1)*DATA_WIDTH-1, k * DATA_WIDTH).to_int64(); - } + if (!even_rows) { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + HLS_UNROLL_SIMPLE; + if (fetch_ping) { + if (i == 0 && k == 0) + plm_fetch_outdata_ping[i] = + data_Bv.range(2 * DATA_WIDTH - 1, DATA_WIDTH) + .to_int64(); + else if (i != 0) + plm_fetch_outdata_ping[i + k - 1] = + data_Bv + .range((k + 1) * DATA_WIDTH - 1, + k * DATA_WIDTH) + .to_int64(); + } + else { + if (i == (fetch_len - 2) && k == 0) + plm_fetch_outdata_pong[i] = + data_Bv.range(DATA_WIDTH - 1, 0).to_int64(); + else if (i != (fetch_len - 2)) + plm_fetch_outdata_pong[i + k] = + data_Bv + .range((k + 1) * DATA_WIDTH - 1, + k * DATA_WIDTH) + .to_int64(); + } } - } else { // DMA Proper Even Align// - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { - HLS_UNROLL_SIMPLE; - if (fetch_ping) - plm_fetch_outdata_ping[i+k] = data_Bv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); - else - plm_fetch_outdata_pong[i+k] = data_Bv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); - } - } + } + else { // DMA Proper Even Align// + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + HLS_UNROLL_SIMPLE; + if (fetch_ping) + plm_fetch_outdata_ping[i + k] = + data_Bv + .range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_int64(); + else + plm_fetch_outdata_pong[i + k] = + data_Bv + .range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_int64(); + } + } #else for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; if (fetch_ping) - plm_fetch_outdata_ping[i+k] = data_Bv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + plm_fetch_outdata_ping[i + k] = + data_Bv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_int64(); else - plm_fetch_outdata_pong[i+k] = data_Bv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + plm_fetch_outdata_pong[i + k] = + data_Bv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_int64(); } #endif - } //for(i) + } // for(i) fetch_ping = !fetch_ping; - } //skip + } // skip skip = true; - this->load_compute_handshake(); - } //for(fetch-index) - } //if(start_fetching) + this->load_compute_handshake(); + } // for(fetch-index) + } // if(start_fetching) - if(start_fetching_output < start_fetching_output_thresh) - this->load_compute_handshake(); + if (start_fetching_output < start_fetching_output_thresh) + this->load_compute_handshake(); ping = !ping; - start_fetching_output++; - } //for(rem) - } //for(b) + start_fetching_output++; + } // for(rem) + } // for(b) } // Conclude @@ -198,8 +234,6 @@ void cholesky::load_input() } } - - void cholesky::store_output() { // Reset @@ -242,82 +276,89 @@ void cholesky::store_output() even_rows = (rows_bv.range(0, 0) == 0); uint32_t store_offset = (rows * rows) * 1; - uint32_t offset = (DMA_WORD_PER_BEAT == 2 && !even_rows) ? store_offset + 1 : store_offset; + uint32_t offset = (DMA_WORD_PER_BEAT == 2 && !even_rows) ? store_offset + 1 : store_offset; wait(); // Batching - for (uint16_t b = 0; b < 1; b++) - { - //HLS_BREAK_DEP(plm_out_ping); - //HLS_BREAK_DEP(plm_out_pong); + for (uint16_t b = 0; b < 1; b++) { + // HLS_BREAK_DEP(plm_out_ping); + // HLS_BREAK_DEP(plm_out_pong); wait(); uint32_t length = rows * rows; // Chunking - for (int rem = length; rem > 0; rem -= rows) - { + for (int rem = length; rem > 0; rem -= rows) { this->store_compute_handshake(); // Configure DMA transaction uint32_t len = rem > rows ? rows : rem; - len = (DMA_WORD_PER_BEAT==2 && !even_rows) ? len+1 : len; - //ESP_REPORT_INFO("Store offset: %d, adjusted: %d\n", offset, offset / DMA_WORD_PER_BEAT); + len = (DMA_WORD_PER_BEAT == 2 && !even_rows) ? len + 1 : len; + // ESP_REPORT_INFO("Store offset: %d, adjusted: %d\n", offset, offset / + // DMA_WORD_PER_BEAT); dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len / DMA_WORD_PER_BEAT, DMA_SIZE); - offset += (DMA_WORD_PER_BEAT==2 && !even_rows) ? (ping ? (len - 2) : len) : len; + offset += (DMA_WORD_PER_BEAT == 2 && !even_rows) ? (ping ? (len - 2) : len) : len; this->dma_write_ctrl.put(dma_info); - for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { sc_dt::sc_bv dataBv; // Read from PLM wait(); #if (DMA_WORD_PER_BEAT == 2) - if(!even_rows) { - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { + if (!even_rows) { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; - if (ping) { - if(i == (len - 2) && k != 1) { - dataBv.range(DATA_WIDTH - 1, 0) = plm_out_ping[i]; - dma_rem_data = plm_out_ping[i]; - } else { - if(i != (len - 2)) - dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_ping[i + k]; + if (ping) { + if (i == (len - 2) && k != 1) { + dataBv.range(DATA_WIDTH - 1, 0) = plm_out_ping[i]; + dma_rem_data = plm_out_ping[i]; } - } else { - if(i == 0) { - if(k == 0) - dataBv.range(DATA_WIDTH - 1, 0) = dma_rem_data; + else { + if (i != (len - 2)) + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = + plm_out_ping[i + k]; + } + } + else { + if (i == 0) { + if (k == 0) dataBv.range(DATA_WIDTH - 1, 0) = dma_rem_data; else - dataBv.range(2 * DATA_WIDTH - 1, DATA_WIDTH) = plm_out_pong[i]; - } else - dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_pong[i + k - 1]; + dataBv.range(2 * DATA_WIDTH - 1, DATA_WIDTH) = + plm_out_pong[i]; + } + else + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = + plm_out_pong[i + k - 1]; } - } //for(k) - } else { + } // for(k) + } + else { for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; - if (ping) - dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_ping[i + k]; + if (ping) + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = + plm_out_ping[i + k]; else - dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_pong[i + k]; + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = + plm_out_pong[i + k]; } - } + } #else - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; if (ping) - dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_ping[i + k]; + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = + plm_out_ping[i + k]; else - dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_pong[i + k]; + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = + plm_out_pong[i + k]; } #endif wait(); this->dma_write_chnl.put(dataBv); - } //for(i) + } // for(i) ping = !ping; } @@ -331,7 +372,6 @@ void cholesky::store_output() } } - void cholesky::compute_kernel() { // Reset @@ -362,123 +402,129 @@ void cholesky::compute_kernel() } // Compute - bool ping = true; - FPDATA sum; - FPDATA index_sqrt; - int index_sqrt_data; - int output_data; - FPDATA plm_in_data; - FPDATA plm_out_data; - FPDATA plm_diag_data; - FPDATA plm_temp_data; - FPDATA plm_fetch_data; + bool ping = true; + FPDATA sum; + FPDATA index_sqrt; + int index_sqrt_data; + int output_data; + FPDATA plm_in_data; + FPDATA plm_out_data; + FPDATA plm_diag_data; + FPDATA plm_temp_data; + FPDATA plm_fetch_data; uint32_t start_fetching_output_thresh = 3; { for (uint16_t b = 0; b < 1; b++) { uint32_t in_length = rows * rows; - int i = 0; + int i = 0; int fill; for (int in_rem = in_length; in_rem > 0; in_rem -= rows) { - //HLS_BREAK_DEP(plm_temp_ping); - //HLS_BREAK_DEP(plm_temp_pong); - //HLS_BREAK_DEP(plm_diag); + // HLS_BREAK_DEP(plm_temp_ping); + // HLS_BREAK_DEP(plm_temp_pong); + // HLS_BREAK_DEP(plm_diag); - if(i < start_fetching_output_thresh) - this->compute_load_handshake(); + if (i < start_fetching_output_thresh) this->compute_load_handshake(); // Computing phase implementation - int iters = 0; - bool fetch_out_ping = true; - int iters_thresh = (i >= start_fetching_output_thresh) ? i - 1 : 0; - int plm_out_data_int; - int plm_temp_data_int; - fill = 0; + int iters = 0; + bool fetch_out_ping = true; + int iters_thresh = (i >= start_fetching_output_thresh) ? i - 1 : 0; + int plm_out_data_int; + int plm_temp_data_int; + fill = 0; for (int j = 0; j < i + 1; j++) { - if(i >= start_fetching_output_thresh && iters < iters_thresh) - this->compute_load_handshake(); + if (i >= start_fetching_output_thresh && iters < iters_thresh) + this->compute_load_handshake(); - plm_in_data = ping ? int2fp(plm_in_ping[j]) : int2fp(plm_in_pong[j]); - plm_diag_data = int2fp(plm_diag[j]); + plm_in_data = ping ? int2fp(plm_in_ping[j]) : + int2fp(plm_in_pong[j]); + plm_diag_data = int2fp(plm_diag[j]); sum = 0; for (int k = 0; k < j; k++) { - plm_out_data_int = ping ? plm_out_ping[k] : plm_out_pong[k]; + plm_out_data_int = ping ? plm_out_ping[k] : plm_out_pong[k]; plm_temp_data_int = ping ? plm_temp_pong[k] : plm_temp_ping[k]; - plm_out_data = int2fp(plm_out_data_int); - plm_temp_data = int2fp(plm_temp_data_int); - - if(i >= start_fetching_output_thresh) { - if(j < (i - 1)) { - if (fetch_out_ping) - plm_fetch_data = int2fp(plm_fetch_outdata_ping[k]); - else - plm_fetch_data = int2fp(plm_fetch_outdata_pong[k]); - - sum += plm_out_data * plm_fetch_data; - } else if(j == (i - 1)) { + plm_out_data = int2fp(plm_out_data_int); + plm_temp_data = int2fp(plm_temp_data_int); + + if (i >= start_fetching_output_thresh) { + if (j < (i - 1)) { + if (fetch_out_ping) + plm_fetch_data = + int2fp(plm_fetch_outdata_ping[k]); + else + plm_fetch_data = + int2fp(plm_fetch_outdata_pong[k]); + + sum += plm_out_data * plm_fetch_data; + } + else if (j == (i - 1)) { sum += plm_out_data * plm_temp_data; - } else { + } + else { sum += plm_out_data * plm_out_data; } - } else { - if(i != j) - sum += plm_out_data * plm_temp_data; + } + else { + if (i != j) sum += plm_out_data * plm_temp_data; else sum += plm_out_data * plm_out_data; } - } //for(k) + } // for(k) - if(i == j) { - index_sqrt = plm_in_data - sum; - index_sqrt_data =fp2int(sqrt(index_sqrt)); + if (i == j) { + index_sqrt = plm_in_data - sum; + index_sqrt_data = fp2int(sqrt(index_sqrt)); - if(ping) - plm_out_ping[j] =index_sqrt_data; - else - plm_out_pong[j] =index_sqrt_data; + if (ping) plm_out_ping[j] = index_sqrt_data; + else + plm_out_pong[j] = index_sqrt_data; - plm_diag[ j] = index_sqrt_data; - } else { - if( plm_diag_data != 0) { - output_data = fp2int((1.0 /plm_diag_data) * (plm_in_data - sum)); + plm_diag[j] = index_sqrt_data; + } + else { + if (plm_diag_data != 0) { + output_data = fp2int((1.0 / plm_diag_data) * + (plm_in_data - sum)); - if(ping) { - plm_out_ping[j] = output_data; + if (ping) { + plm_out_ping[j] = output_data; plm_temp_ping[fill] = output_data; - } else { - plm_out_pong[j] = output_data; + } + else { + plm_out_pong[j] = output_data; plm_temp_pong[fill] = output_data; - } - } else { - if(ping) { - plm_out_ping[j] = 0; - plm_temp_ping[fill] = 0; - } else { - plm_out_pong[j] = 0; + } + } + else { + if (ping) { + plm_out_ping[j] = 0; + plm_temp_ping[fill] = 0; + } + else { + plm_out_pong[j] = 0; plm_temp_pong[fill] = 0; - } - } + } + } fill++; - } //if(i==j) + } // if(i==j) iters++; - if(j > 0) - fetch_out_ping= !fetch_out_ping; - } //for(j) + if (j > 0) fetch_out_ping = !fetch_out_ping; + } // for(j) - for (int z =(i+1) ; z < rows ; z++) { - if(ping) - plm_out_ping[z] = 0; + for (int z = (i + 1); z < rows; z++) { + if (ping) plm_out_ping[z] = 0; else plm_out_pong[z] = 0; } wait(); this->compute_store_handshake(); ping = !ping; - i++; + i++; } } diff --git a/accelerators/stratus_hls/cholesky_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/cholesky_stratus/hw/tb/sc_main.cpp index c465ccc433..cffde7e61b 100644 --- a/accelerators/stratus_hls/cholesky_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/cholesky_stratus/hw/tb/sc_main.cpp @@ -5,44 +5,44 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; extern void esc_elaborate() { - // Creating the whole system - testbench = new system_t("testbench"); + // Creating the whole system + testbench = new system_t("testbench"); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); - esc_cleanup(); + esc_log_pass(); + esc_cleanup(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/cholesky_stratus/sw/baremetal/cholesky.c b/accelerators/stratus_hls/cholesky_stratus/sw/baremetal/cholesky.c index 57b7b95723..41230e524c 100644 --- a/accelerators/stratus_hls/cholesky_stratus/sw/baremetal/cholesky.c +++ b/accelerators/stratus_hls/cholesky_stratus/sw/baremetal/cholesky.c @@ -1,28 +1,25 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 #ifndef __riscv -#include -#include + #include + #include #endif #include #include -#include #include +#include #define fx2float fixed32_to_float #define float2fx float_to_fixed32 -#define FX_IL 12 +#define FX_IL 12 typedef int32_t token_t; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } #define SLD_CHOLESKY 0x062 -#define DEV_NAME "sld,cholesky_stratus" +#define DEV_NAME "sld,cholesky_stratus" /* <<--params-->> */ const int32_t rows = 16; @@ -38,10 +35,8 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ @@ -49,103 +44,104 @@ static unsigned mem_size; static int validate_buf(token_t *out, token_t *gold) { - int i; - int j; - unsigned errors = 0; - const float ERR_TH = 0.2f; - float out_fl, gold_fl; - for (i = 0; i < 1; i++) { - for (j = 0; j < rows * rows; j++) { - out_fl = fx2float(out[j], FX_IL); - gold_fl = fx2float(gold[j], FX_IL); - if ((fabs(gold[j] - out[j]) / fabs(gold[j])) > ERR_TH) { - printf("ERR: GOLD = %f and OUT = %f and Element = %d\n", gold_fl, out_fl, j); - errors++; } + int i; + int j; + unsigned errors = 0; + const float ERR_TH = 0.2f; + float out_fl, gold_fl; + for (i = 0; i < 1; i++) { + for (j = 0; j < rows * rows; j++) { + out_fl = fx2float(out[j], FX_IL); + gold_fl = fx2float(gold[j], FX_IL); + if ((fabs(gold[j] - out[j]) / fabs(gold[j])) > ERR_TH) { + printf("ERR: GOLD = %f and OUT = %f and Element = %d\n", gold_fl, out_fl, j); + errors++; } } + } - return errors; + return errors; } -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; int coherence; - unsigned **ptable; - token_t *buf; - token_t *gold; - unsigned errors = 0; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = rows * rows; - out_words_adj = rows * rows; - } else { - in_words_adj = round_up(rows * rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(rows * rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (1); - out_len = out_words_adj * (1); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_CHOLESKY, DEV_NAME); - if (ndev == 0) { - printf("cholesky not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_size); - buf = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", buf); - // Alocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &buf[i * (CHUNK_SIZE / sizeof(token_t))]; + unsigned **ptable; + token_t *buf; + token_t *gold; + unsigned errors = 0; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = rows * rows; + out_words_adj = rows * rows; + } + else { + in_words_adj = round_up(rows * rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(rows * rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (1); + out_len = out_words_adj * (1); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_CHOLESKY, DEV_NAME); + if (ndev == 0) { + printf("cholesky not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_size); + buf = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", buf); + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&buf[i * (CHUNK_SIZE / sizeof(token_t))]; printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { printf(" Generate input...\n"); - //data generated in hw/datagen/ - #include "data.h" +// data generated in hw/datagen/ +#include "data.h" // Pass common configuration parameters iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); iowrite32(dev, COHERENCE_REG, coherence); #ifndef __sparc - iowrite32(dev, PT_ADDRESS_REG, (unsigned long long) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned long long)ptable); #else - iowrite32(dev, PT_ADDRESS_REG, (unsigned) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned)ptable); #endif iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); @@ -179,16 +175,17 @@ int main(int argc, char * argv[]) /* Validation */ errors = validate_buf(&buf[out_offset], gold); - if (errors){ + if (errors) { printf(" ... FAIL\n"); - printf(" ERRORS = %d \n",errors);} + printf(" ERRORS = %d \n", errors); + } else printf(" ... PASS\n"); } - aligned_free(ptable); - aligned_free(buf); - aligned_free(gold); - } + aligned_free(ptable); + aligned_free(buf); + aligned_free(gold); + } - return 0; + return 0; } diff --git a/accelerators/stratus_hls/cholesky_stratus/sw/linux/app/cholesky.c b/accelerators/stratus_hls/cholesky_stratus/sw/linux/app/cholesky.c index 278059a173..6e62e01c36 100644 --- a/accelerators/stratus_hls/cholesky_stratus/sw/linux/app/cholesky.c +++ b/accelerators/stratus_hls/cholesky_stratus/sw/linux/app/cholesky.c @@ -1,7 +1,7 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include "libesp.h" #include "cfg.h" +#include "libesp.h" #include static unsigned in_words_adj; @@ -15,19 +15,19 @@ static unsigned size; #define fx2float fixed32_to_float #define float2fx float_to_fixed32 -#define FX_IL 12 +#define FX_IL 12 /* User-defined code */ static int validate_buffer(token_t *out, token_t *gold) { - int i; - int j; - unsigned errors = 0; + int i; + int j; + unsigned errors = 0; const float ERR_TH = 0.2f; float out_fl, gold_fl; for (i = 0; i < 1; i++) for (j = 0; j < rows * rows; j++) { - out_fl = fx2float(out[j], FX_IL); + out_fl = fx2float(out[j], FX_IL); gold_fl = fx2float(gold[j], FX_IL); if ((fabs(gold_fl - out_fl) / fabs(gold_fl)) > ERR_TH) { printf(" GOLD = %f and OUT = %f and J = %d \n", gold_fl, out_fl, j); @@ -41,28 +41,28 @@ static int validate_buffer(token_t *out, token_t *gold) /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = rows * rows; - out_words_adj = rows * rows; - } else { - in_words_adj = round_up(rows * rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(rows * rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (1); - out_len = out_words_adj * (1); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = rows * rows; + out_words_adj = rows * rows; + } + else { + in_words_adj = round_up(rows * rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(rows * rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (1); + out_len = out_words_adj * (1); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + size = (out_offset * sizeof(token_t)) + out_size; } int main(int argc, char **argv) { - int errors; + int errors; - if (argc >= 2){ - if (!strcmp(argv[1], "non-coh")) - cholesky_cfg_000[0].esp.coherence = ACC_COH_NONE; + if (argc >= 2) { + if (!strcmp(argv[1], "non-coh")) cholesky_cfg_000[0].esp.coherence = ACC_COH_NONE; else if (!strcmp(argv[1], "llc-coh")) cholesky_cfg_000[0].esp.coherence = ACC_COH_LLC; else if (!strcmp(argv[1], "coh-dma")) @@ -87,20 +87,20 @@ int main(int argc, char **argv) } cholesky_cfg_000[0].rows = rows; } - token_t *gold; - token_t *buf; + token_t *gold; + token_t *buf; - init_parameters(); + init_parameters(); - cholesky_cfg_000[0].esp.footprint = size; + cholesky_cfg_000[0].esp.footprint = size; cholesky_cfg_000[0].esp.alloc_policy = CONTIG_ALLOC_PREFERRED; - buf = (token_t *) esp_alloc(size); + buf = (token_t *)esp_alloc(size); cfg_000[0].hw_buf = buf; gold = malloc(out_size); - #include "data.h" +#include "data.h" if (argc >= 3) { for (int i = 1; i < cholesky_cfg_000[0].rows * cholesky_cfg_000[0].rows; i++) buf[i] = rand(); @@ -108,26 +108,24 @@ int main(int argc, char **argv) printf("\n====== %s ======\n\n", cfg_000[0].devname); /* <<--print-params-->> */ - printf(" .rows = %d\n", rows); - printf("\n ** START **\n"); + printf(" .rows = %d\n", rows); + printf("\n ** START **\n"); - esp_run(cfg_000, NACC); + esp_run(cfg_000, NACC); - printf("\n ** DONE **\n"); - if (argc < 3) - errors = validate_buffer(&buf[out_offset], gold); + printf("\n ** DONE **\n"); + if (argc < 3) errors = validate_buffer(&buf[out_offset], gold); else errors = 0; free(gold); - esp_free(buf); + esp_free(buf); - if (!errors) - printf("+ Test PASSED\n"); - else - printf("+ Test FAILED with %d errors\n", errors); + if (!errors) printf("+ Test PASSED\n"); + else + printf("+ Test FAILED with %d errors\n", errors); - printf("\n====== %s ======\n\n", cfg_000[0].devname); + printf("\n====== %s ======\n\n", cfg_000[0].devname); - return errors; + return errors; } diff --git a/accelerators/stratus_hls/cholesky_stratus/sw/linux/driver/cholesky_stratus.c b/accelerators/stratus_hls/cholesky_stratus/sw/linux/driver/cholesky_stratus.c index b89df586d2..c21d251db7 100644 --- a/accelerators/stratus_hls/cholesky_stratus/sw/linux/driver/cholesky_stratus.c +++ b/accelerators/stratus_hls/cholesky_stratus/sw/linux/driver/cholesky_stratus.c @@ -1,132 +1,123 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "cholesky_stratus.h" -#define DRV_NAME "cholesky_stratus" +#define DRV_NAME "cholesky_stratus" /* <<--regs-->> */ #define CHOLESKY_ROWS_REG 0x40 struct cholesky_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver cholesky_driver; static struct of_device_id cholesky_device_ids[] = { - { - .name = "SLD_CHOLESKY_STRATUS", - }, - { - .name = "eb_062", - }, - { - .compatible = "sld,cholesky_stratus", - }, - { }, + { + .name = "SLD_CHOLESKY_STRATUS", + }, + { + .name = "eb_062", + }, + { + .compatible = "sld,cholesky_stratus", + }, + {}, }; static int cholesky_devs; static inline struct cholesky_stratus_device *to_cholesky(struct esp_device *esp) { - return container_of(esp, struct cholesky_stratus_device, esp); + return container_of(esp, struct cholesky_stratus_device, esp); } static void cholesky_prep_xfer(struct esp_device *esp, void *arg) { - struct cholesky_stratus_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->rows, esp->iomem + CHOLESKY_ROWS_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); + struct cholesky_stratus_access *a = arg; + /* <<--regs-config-->> */ + iowrite32be(a->rows, esp->iomem + CHOLESKY_ROWS_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool cholesky_xfer_input_ok(struct esp_device *esp, void *arg) { - struct cholesky_stratus_device *cholesky = to_cholesky(esp); - struct cholesky_stratus_access *a = arg; + struct cholesky_stratus_device *cholesky = to_cholesky(esp); + struct cholesky_stratus_access *a = arg; - if (a->rows > 2048) - return false; + if (a->rows > 2048) return false; return true; } static int cholesky_probe(struct platform_device *pdev) { - struct cholesky_stratus_device *cholesky; - struct esp_device *esp; - int rc; - - cholesky = kzalloc(sizeof(*cholesky), GFP_KERNEL); - if (cholesky == NULL) - return -ENOMEM; - esp = &cholesky->esp; - esp->module = THIS_MODULE; - esp->number = cholesky_devs; - esp->driver = &cholesky_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - cholesky_devs++; - return 0; - err: - kfree(cholesky); - return rc; + struct cholesky_stratus_device *cholesky; + struct esp_device *esp; + int rc; + + cholesky = kzalloc(sizeof(*cholesky), GFP_KERNEL); + if (cholesky == NULL) return -ENOMEM; + esp = &cholesky->esp; + esp->module = THIS_MODULE; + esp->number = cholesky_devs; + esp->driver = &cholesky_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + cholesky_devs++; + return 0; +err: + kfree(cholesky); + return rc; } static int __exit cholesky_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct cholesky_stratus_device *cholesky = to_cholesky(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct cholesky_stratus_device *cholesky = to_cholesky(esp); - esp_device_unregister(esp); - kfree(cholesky); - return 0; + esp_device_unregister(esp); + kfree(cholesky); + return 0; } static struct esp_driver cholesky_driver = { - .plat = { - .probe = cholesky_probe, - .remove = cholesky_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = cholesky_device_ids, - }, - }, - .xfer_input_ok = cholesky_xfer_input_ok, - .prep_xfer = cholesky_prep_xfer, - .ioctl_cm = CHOLESKY_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct cholesky_stratus_access), + .plat = + { + .probe = cholesky_probe, + .remove = cholesky_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = cholesky_device_ids, + }, + }, + .xfer_input_ok = cholesky_xfer_input_ok, + .prep_xfer = cholesky_prep_xfer, + .ioctl_cm = CHOLESKY_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct cholesky_stratus_access), }; -static int __init cholesky_init(void) -{ - return esp_driver_register(&cholesky_driver); -} +static int __init cholesky_init(void) { return esp_driver_register(&cholesky_driver); } -static void __exit cholesky_exit(void) -{ - esp_driver_unregister(&cholesky_driver); -} +static void __exit cholesky_exit(void) { esp_driver_unregister(&cholesky_driver); } -module_init(cholesky_init) -module_exit(cholesky_exit) +module_init(cholesky_init) module_exit(cholesky_exit) -MODULE_DEVICE_TABLE(of, cholesky_device_ids); + MODULE_DEVICE_TABLE(of, cholesky_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/cholesky_stratus/sw/linux/include/cholesky_stratus.h b/accelerators/stratus_hls/cholesky_stratus/sw/linux/include/cholesky_stratus.h index 3fd324fe68..ad3d695e6e 100644 --- a/accelerators/stratus_hls/cholesky_stratus/sw/linux/include/cholesky_stratus.h +++ b/accelerators/stratus_hls/cholesky_stratus/sw/linux/include/cholesky_stratus.h @@ -4,27 +4,27 @@ #define _CHOLESKY_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct cholesky_stratus_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned rows; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned rows; + unsigned src_offset; + unsigned dst_offset; }; -#define CHOLESKY_STRATUS_IOC_ACCESS _IOW ('S', 0, struct cholesky_stratus_access) +#define CHOLESKY_STRATUS_IOC_ACCESS _IOW('S', 0, struct cholesky_stratus_access) #endif /* _CHOLESKY_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/common/utils/common.hpp b/accelerators/stratus_hls/common/utils/common.hpp index f512d172cb..a6e64e13b4 100644 --- a/accelerators/stratus_hls/common/utils/common.hpp +++ b/accelerators/stratus_hls/common/utils/common.hpp @@ -13,85 +13,140 @@ * the massive ternary operator construction * */ -#define ilog2(n) \ - ( \ - (n) < 2 ? 0 : \ - (n) & (1ULL << 63) ? 63 : \ - (n) & (1ULL << 62) ? 62 : \ - (n) & (1ULL << 61) ? 61 : \ - (n) & (1ULL << 60) ? 60 : \ - (n) & (1ULL << 59) ? 59 : \ - (n) & (1ULL << 58) ? 58 : \ - (n) & (1ULL << 57) ? 57 : \ - (n) & (1ULL << 56) ? 56 : \ - (n) & (1ULL << 55) ? 55 : \ - (n) & (1ULL << 54) ? 54 : \ - (n) & (1ULL << 53) ? 53 : \ - (n) & (1ULL << 52) ? 52 : \ - (n) & (1ULL << 51) ? 51 : \ - (n) & (1ULL << 50) ? 50 : \ - (n) & (1ULL << 49) ? 49 : \ - (n) & (1ULL << 48) ? 48 : \ - (n) & (1ULL << 47) ? 47 : \ - (n) & (1ULL << 46) ? 46 : \ - (n) & (1ULL << 45) ? 45 : \ - (n) & (1ULL << 44) ? 44 : \ - (n) & (1ULL << 43) ? 43 : \ - (n) & (1ULL << 42) ? 42 : \ - (n) & (1ULL << 41) ? 41 : \ - (n) & (1ULL << 40) ? 40 : \ - (n) & (1ULL << 39) ? 39 : \ - (n) & (1ULL << 38) ? 38 : \ - (n) & (1ULL << 37) ? 37 : \ - (n) & (1ULL << 36) ? 36 : \ - (n) & (1ULL << 35) ? 35 : \ - (n) & (1ULL << 34) ? 34 : \ - (n) & (1ULL << 33) ? 33 : \ - (n) & (1ULL << 32) ? 32 : \ - (n) & (1ULL << 31) ? 31 : \ - (n) & (1ULL << 30) ? 30 : \ - (n) & (1ULL << 29) ? 29 : \ - (n) & (1ULL << 28) ? 28 : \ - (n) & (1ULL << 27) ? 27 : \ - (n) & (1ULL << 26) ? 26 : \ - (n) & (1ULL << 25) ? 25 : \ - (n) & (1ULL << 24) ? 24 : \ - (n) & (1ULL << 23) ? 23 : \ - (n) & (1ULL << 22) ? 22 : \ - (n) & (1ULL << 21) ? 21 : \ - (n) & (1ULL << 20) ? 20 : \ - (n) & (1ULL << 19) ? 19 : \ - (n) & (1ULL << 18) ? 18 : \ - (n) & (1ULL << 17) ? 17 : \ - (n) & (1ULL << 16) ? 16 : \ - (n) & (1ULL << 15) ? 15 : \ - (n) & (1ULL << 14) ? 14 : \ - (n) & (1ULL << 13) ? 13 : \ - (n) & (1ULL << 12) ? 12 : \ - (n) & (1ULL << 11) ? 11 : \ - (n) & (1ULL << 10) ? 10 : \ - (n) & (1ULL << 9) ? 9 : \ - (n) & (1ULL << 8) ? 8 : \ - (n) & (1ULL << 7) ? 7 : \ - (n) & (1ULL << 6) ? 6 : \ - (n) & (1ULL << 5) ? 5 : \ - (n) & (1ULL << 4) ? 4 : \ - (n) & (1ULL << 3) ? 3 : \ - (n) & (1ULL << 2) ? 2 : \ - 1 ) +#define ilog2(n) \ + ((n) < 2 ? 0 : \ + (n) & (1ULL << 63) ? \ + 63 : \ + (n) & (1ULL << 62) ? \ + 62 : \ + (n) & (1ULL << 61) ? \ + 61 : \ + (n) & (1ULL << 60) ? \ + 60 : \ + (n) & (1ULL << 59) ? \ + 59 : \ + (n) & (1ULL << 58) ? \ + 58 : \ + (n) & (1ULL << 57) ? \ + 57 : \ + (n) & (1ULL << 56) ? \ + 56 : \ + (n) & (1ULL << 55) ? \ + 55 : \ + (n) & (1ULL << 54) ? \ + 54 : \ + (n) & (1ULL << 53) ? \ + 53 : \ + (n) & (1ULL << 52) ? \ + 52 : \ + (n) & (1ULL << 51) ? \ + 51 : \ + (n) & (1ULL << 50) ? \ + 50 : \ + (n) & (1ULL << 49) ? \ + 49 : \ + (n) & (1ULL << 48) ? \ + 48 : \ + (n) & (1ULL << 47) ? \ + 47 : \ + (n) & (1ULL << 46) ? \ + 46 : \ + (n) & (1ULL << 45) ? \ + 45 : \ + (n) & (1ULL << 44) ? \ + 44 : \ + (n) & (1ULL << 43) ? \ + 43 : \ + (n) & (1ULL << 42) ? \ + 42 : \ + (n) & (1ULL << 41) ? \ + 41 : \ + (n) & (1ULL << 40) ? \ + 40 : \ + (n) & (1ULL << 39) ? \ + 39 : \ + (n) & (1ULL << 38) ? \ + 38 : \ + (n) & (1ULL << 37) ? \ + 37 : \ + (n) & (1ULL << 36) ? \ + 36 : \ + (n) & (1ULL << 35) ? \ + 35 : \ + (n) & (1ULL << 34) ? \ + 34 : \ + (n) & (1ULL << 33) ? \ + 33 : \ + (n) & (1ULL << 32) ? \ + 32 : \ + (n) & (1ULL << 31) ? \ + 31 : \ + (n) & (1ULL << 30) ? \ + 30 : \ + (n) & (1ULL << 29) ? \ + 29 : \ + (n) & (1ULL << 28) ? \ + 28 : \ + (n) & (1ULL << 27) ? \ + 27 : \ + (n) & (1ULL << 26) ? \ + 26 : \ + (n) & (1ULL << 25) ? \ + 25 : \ + (n) & (1ULL << 24) ? \ + 24 : \ + (n) & (1ULL << 23) ? \ + 23 : \ + (n) & (1ULL << 22) ? \ + 22 : \ + (n) & (1ULL << 21) ? \ + 21 : \ + (n) & (1ULL << 20) ? \ + 20 : \ + (n) & (1ULL << 19) ? \ + 19 : \ + (n) & (1ULL << 18) ? \ + 18 : \ + (n) & (1ULL << 17) ? \ + 17 : \ + (n) & (1ULL << 16) ? \ + 16 : \ + (n) & (1ULL << 15) ? \ + 15 : \ + (n) & (1ULL << 14) ? \ + 14 : \ + (n) & (1ULL << 13) ? \ + 13 : \ + (n) & (1ULL << 12) ? \ + 12 : \ + (n) & (1ULL << 11) ? \ + 11 : \ + (n) & (1ULL << 10) ? \ + 10 : \ + (n) & (1ULL << 9) ? \ + 9 : \ + (n) & (1ULL << 8) ? \ + 8 : \ + (n) & (1ULL << 7) ? \ + 7 : \ + (n) & (1ULL << 6) ? \ + 6 : \ + (n) & (1ULL << 5) ? \ + 5 : \ + (n) & (1ULL << 4) ? 4 : (n) & (1ULL << 3) ? 3 : (n) & (1ULL << 2) ? 2 : 1) -inline int min(int a, int b){ - if (a < b) - return a; +inline int min(int a, int b) +{ + if (a < b) return a; else - return b; + return b; } -inline int max(int a, int b){ - if (a > b) - return a; +inline int max(int a, int b) +{ + if (a > b) return a; else - return b; + return b; } #endif /* __COMMON_HPP__ */ diff --git a/accelerators/stratus_hls/conv2d_stratus/hw/src/conv2d.cpp b/accelerators/stratus_hls/conv2d_stratus/hw/src/conv2d.cpp index 478c10e64c..0dc753e54f 100644 --- a/accelerators/stratus_hls/conv2d_stratus/hw/src/conv2d.cpp +++ b/accelerators/stratus_hls/conv2d_stratus/hw/src/conv2d.cpp @@ -21,8 +21,8 @@ void conv2d::load_input() HLS_PROTO("load-reset"); this->reset_load_input(); - load_compute_cfg_done.req.reset_req(); - load_store_cfg_done.req.reset_req(); + load_compute_cfg_done.req.reset_req(); + load_store_cfg_done.req.reset_req(); // explicit PLM ports reset if any @@ -51,20 +51,20 @@ void conv2d::load_input() // User-defined config code /* <<--local-params-->> */ n_channels = config.n_channels; - n_filters = config.n_filters; + n_filters = config.n_filters; filter_dim = config.filter_dim; - stride = config.stride; - is_padded = config.is_padded; - height = config.feature_map_height; - width = config.feature_map_width; - pool_type = config.pool_type; + stride = config.stride; + is_padded = config.is_padded; + height = config.feature_map_height; + width = config.feature_map_width; + pool_type = config.pool_type; batch_size = config.batch_size; } // Precompute sizes - bool ping_input = true; + bool ping_input = true; bool ping_weights = true; - bool ping_bias = true; + bool ping_bias = true; uint4_t pad; uint16_t output_w; uint16_t feature_size; @@ -91,42 +91,37 @@ void conv2d::load_input() uint12_t loadable_chan, chan_iters, chan_rem; uint16_t loadable_chan_sz, chan_rem_sz; - compute_dimensions(height, width, n_channels, (bool) is_padded, - stride, (uint8_t) filter_dim, n_filters, pool_type, batch_size, - &output_w, &pad, &feature_size, &filter_size, &filters_size, - &max_cacheable_rows, &max_cacheable_rows_init, - &max_cacheable_size, &max_cacheable_size_init, - &max_cacheable_filters, - &max_cacheable_filters_size, &max_cacheable_bias_chunks, - &max_cacheable_bias_size, &total_input_chunks, - &total_filters_chunks, - &feature_offset_incr, &feature_offset_incr_init, - &channel_offset_incr, &out_channel_offset_incr, - &out_channel_pool_offset_incr, &filters_offset_start_base, - &bias_offset_start_base, &feature_offset_start_base, - &loadable_chan, &chan_iters, &chan_rem, - &loadable_chan_sz, &chan_rem_sz); + compute_dimensions( + height, width, n_channels, (bool)is_padded, stride, (uint8_t)filter_dim, n_filters, + pool_type, batch_size, &output_w, &pad, &feature_size, &filter_size, &filters_size, + &max_cacheable_rows, &max_cacheable_rows_init, &max_cacheable_size, + &max_cacheable_size_init, &max_cacheable_filters, &max_cacheable_filters_size, + &max_cacheable_bias_chunks, &max_cacheable_bias_size, &total_input_chunks, + &total_filters_chunks, &feature_offset_incr, &feature_offset_incr_init, + &channel_offset_incr, &out_channel_offset_incr, &out_channel_pool_offset_incr, + &filters_offset_start_base, &bias_offset_start_base, &feature_offset_start_base, + &loadable_chan, &chan_iters, &chan_rem, &loadable_chan_sz, &chan_rem_sz); { - HLS_DEFINE_PROTOCOL("load-config-sig"); - pad_sig.write(pad); - output_w_sig.write(output_w); - filter_size_sig.write(filter_size); - total_filters_chunks_sig.write(total_filters_chunks); - total_input_chunks_sig.write(total_input_chunks); - max_cacheable_rows_sig.write(max_cacheable_rows); - max_cacheable_rows_init_sig.write(max_cacheable_rows_init); - max_cacheable_filters_sig.write(max_cacheable_filters); - max_cacheable_bias_chunks_sig.write(max_cacheable_bias_chunks); - out_channel_offset_incr_sig.write(out_channel_offset_incr); - out_channel_pool_offset_incr_sig.write(out_channel_pool_offset_incr); - feature_offset_start_base_sig.write(feature_offset_start_base); - loadable_chan_sig.write(loadable_chan); - chan_iters_sig.write(chan_iters); - chan_rem_sig.write(chan_rem); - loadable_chan_sz_sig.write(loadable_chan_sz); - chan_rem_sz_sig.write(chan_rem_sz); - wait(); + HLS_DEFINE_PROTOCOL("load-config-sig"); + pad_sig.write(pad); + output_w_sig.write(output_w); + filter_size_sig.write(filter_size); + total_filters_chunks_sig.write(total_filters_chunks); + total_input_chunks_sig.write(total_input_chunks); + max_cacheable_rows_sig.write(max_cacheable_rows); + max_cacheable_rows_init_sig.write(max_cacheable_rows_init); + max_cacheable_filters_sig.write(max_cacheable_filters); + max_cacheable_bias_chunks_sig.write(max_cacheable_bias_chunks); + out_channel_offset_incr_sig.write(out_channel_offset_incr); + out_channel_pool_offset_incr_sig.write(out_channel_pool_offset_incr); + feature_offset_start_base_sig.write(feature_offset_start_base); + loadable_chan_sig.write(loadable_chan); + chan_iters_sig.write(chan_iters); + chan_rem_sig.write(chan_rem); + loadable_chan_sz_sig.write(loadable_chan_sz); + chan_rem_sz_sig.write(chan_rem_sz); + wait(); } load_compute_cfg_handshake(); @@ -135,294 +130,276 @@ void conv2d::load_input() // Load { #ifndef STRATUS_HLS - ESP_REPORT_INFO("output_w %u", output_w); - ESP_REPORT_INFO("pad %u", (uint32_t) pad); - ESP_REPORT_INFO("feature_size %u", feature_size); - ESP_REPORT_INFO("filter_size %u", filter_size); - ESP_REPORT_INFO("filters_size %u", filters_size); - ESP_REPORT_INFO("max_cacheable_rows %u", max_cacheable_rows); - ESP_REPORT_INFO("max_cacheable_rows_init %u", max_cacheable_rows_init); - ESP_REPORT_INFO("max_cacheable_size %u", max_cacheable_size); - ESP_REPORT_INFO("max_cacheable_size_init %u", max_cacheable_size_init); - ESP_REPORT_INFO("max_cacheable_filters %u", max_cacheable_filters); - ESP_REPORT_INFO("max_cacheable_filters_size %u", max_cacheable_filters_size); - ESP_REPORT_INFO("max_cacheable_bias_chunks %u", max_cacheable_bias_chunks); - ESP_REPORT_INFO("max_cacheable_bias_size %u", max_cacheable_bias_size); - ESP_REPORT_INFO("total_input_chunks %u", total_input_chunks); - ESP_REPORT_INFO("total_filters_chunks %u", total_filters_chunks); - ESP_REPORT_INFO("feature_offset_incr %u", feature_offset_incr); - ESP_REPORT_INFO("feature_offset_incr_init %u", feature_offset_incr_init); - ESP_REPORT_INFO("channel_offset_incr %u", channel_offset_incr); - ESP_REPORT_INFO("filters_offset_start_base %u", filters_offset_start_base); - ESP_REPORT_INFO("bias_offset_start_base %u", bias_offset_start_base); - ESP_REPORT_INFO("feature_offset_start_base %u", feature_offset_start_base); - ESP_REPORT_INFO("loadable_chan %u", (unsigned) loadable_chan); - ESP_REPORT_INFO("chan_iters %u", (unsigned) chan_iters); - ESP_REPORT_INFO("chan_rem %u", (unsigned) chan_rem); - ESP_REPORT_INFO("loadable_chan_sz %u", (unsigned) loadable_chan_sz); - ESP_REPORT_INFO("chan_rem_sz %u", (unsigned) chan_rem_sz); + ESP_REPORT_INFO("output_w %u", output_w); + ESP_REPORT_INFO("pad %u", (uint32_t)pad); + ESP_REPORT_INFO("feature_size %u", feature_size); + ESP_REPORT_INFO("filter_size %u", filter_size); + ESP_REPORT_INFO("filters_size %u", filters_size); + ESP_REPORT_INFO("max_cacheable_rows %u", max_cacheable_rows); + ESP_REPORT_INFO("max_cacheable_rows_init %u", max_cacheable_rows_init); + ESP_REPORT_INFO("max_cacheable_size %u", max_cacheable_size); + ESP_REPORT_INFO("max_cacheable_size_init %u", max_cacheable_size_init); + ESP_REPORT_INFO("max_cacheable_filters %u", max_cacheable_filters); + ESP_REPORT_INFO("max_cacheable_filters_size %u", max_cacheable_filters_size); + ESP_REPORT_INFO("max_cacheable_bias_chunks %u", max_cacheable_bias_chunks); + ESP_REPORT_INFO("max_cacheable_bias_size %u", max_cacheable_bias_size); + ESP_REPORT_INFO("total_input_chunks %u", total_input_chunks); + ESP_REPORT_INFO("total_filters_chunks %u", total_filters_chunks); + ESP_REPORT_INFO("feature_offset_incr %u", feature_offset_incr); + ESP_REPORT_INFO("feature_offset_incr_init %u", feature_offset_incr_init); + ESP_REPORT_INFO("channel_offset_incr %u", channel_offset_incr); + ESP_REPORT_INFO("filters_offset_start_base %u", filters_offset_start_base); + ESP_REPORT_INFO("bias_offset_start_base %u", bias_offset_start_base); + ESP_REPORT_INFO("feature_offset_start_base %u", feature_offset_start_base); + ESP_REPORT_INFO("loadable_chan %u", (unsigned)loadable_chan); + ESP_REPORT_INFO("chan_iters %u", (unsigned)chan_iters); + ESP_REPORT_INFO("chan_rem %u", (unsigned)chan_rem); + ESP_REPORT_INFO("loadable_chan_sz %u", (unsigned)loadable_chan_sz); + ESP_REPORT_INFO("chan_rem_sz %u", (unsigned)chan_rem_sz); #endif - // Chunking - uint32_t infeature_offset_incr = channel_offset_incr * n_channels; - bool single_chunk_done = false; - uint32_t filters_offset_start_phys = filters_offset_start_base; - uint32_t filters_offset_start_virt = 0; - uint32_t bias_offset_start_phys = bias_offset_start_base; - uint32_t bias_offset_start_virt = 0; - uint16_t bias_chunk = 0; - uint16_t plm_bias_i = 0; - for (uint16_t filter_chunk = 0; filter_chunk < total_filters_chunks; - filter_chunk++) - { - uint16_t plm_weights_index = 0; - uint16_t n_words_to_load = min(filters_size - filters_offset_start_virt, - max_cacheable_filters_size); - bool misaligned = filters_offset_start_phys & 1 & (DMA_WORD_PER_BEAT - 1); - uint16_t adj_words_to_load = n_words_to_load + misaligned; - - dma_info_t dma_info(filters_offset_start_phys >> DMA_WORD_PER_BEAT_LOG2, - (n_words_to_load + misaligned + DMA_WORD_PER_BEAT_LOG2) >> - DMA_WORD_PER_BEAT_LOG2, DMA_SIZE); + // Chunking + uint32_t infeature_offset_incr = channel_offset_incr * n_channels; + bool single_chunk_done = false; + uint32_t filters_offset_start_phys = filters_offset_start_base; + uint32_t filters_offset_start_virt = 0; + uint32_t bias_offset_start_phys = bias_offset_start_base; + uint32_t bias_offset_start_virt = 0; + uint16_t bias_chunk = 0; + uint16_t plm_bias_i = 0; + for (uint16_t filter_chunk = 0; filter_chunk < total_filters_chunks; filter_chunk++) { + uint16_t plm_weights_index = 0; + uint16_t n_words_to_load = + min(filters_size - filters_offset_start_virt, max_cacheable_filters_size); + bool misaligned = filters_offset_start_phys & 1 & (DMA_WORD_PER_BEAT - 1); + uint16_t adj_words_to_load = n_words_to_load + misaligned; + + dma_info_t dma_info(filters_offset_start_phys >> DMA_WORD_PER_BEAT_LOG2, + (n_words_to_load + misaligned + DMA_WORD_PER_BEAT_LOG2) >> + DMA_WORD_PER_BEAT_LOG2, + DMA_SIZE); #ifndef STRATUS_HLS - ESP_REPORT_INFO("load_input load filters dma_info. offset: %u len %u", - filters_offset_start_phys, n_words_to_load); + ESP_REPORT_INFO("load_input load filters dma_info. offset: %u len %u", + filters_offset_start_phys, n_words_to_load); #endif - this->dma_read_ctrl.put(dma_info); + this->dma_read_ctrl.put(dma_info); - for (uint16_t i = 0; i < adj_words_to_load; i += DMA_WORD_PER_BEAT) - { - HLS_PROTO("load-dma-filters"); - HLS_BREAK_DEP(plm_weights_ping); - HLS_BREAK_DEP(plm_weights_pong); + for (uint16_t i = 0; i < adj_words_to_load; i += DMA_WORD_PER_BEAT) { + HLS_PROTO("load-dma-filters"); + HLS_BREAK_DEP(plm_weights_ping); + HLS_BREAK_DEP(plm_weights_pong); - sc_dt::sc_bv dataBv; + sc_dt::sc_bv dataBv; - dataBv = this->dma_read_chnl.get(); - wait(); + dataBv = this->dma_read_chnl.get(); + wait(); #if (DMA_WORD_PER_BEAT == 2) - if (!(!i && misaligned)) { - if (ping_weights) { - plm_weights_ping[plm_weights_index++] = - dataBv.range(31,0).to_int(); - if (i + 1 < adj_words_to_load) - plm_weights_ping[plm_weights_index++] = - dataBv.range(63,32).to_int(); - } else { - plm_weights_pong[plm_weights_index++] = - dataBv.range(31,0).to_int(); - if (i + 1 < adj_words_to_load) - plm_weights_pong[plm_weights_index++] = - dataBv.range(63,32).to_int(); - } - } + if (!(!i && misaligned)) { + if (ping_weights) { + plm_weights_ping[plm_weights_index++] = dataBv.range(31, 0).to_int(); + if (i + 1 < adj_words_to_load) + plm_weights_ping[plm_weights_index++] = dataBv.range(63, 32).to_int(); + } + else { + plm_weights_pong[plm_weights_index++] = dataBv.range(31, 0).to_int(); + if (i + 1 < adj_words_to_load) + plm_weights_pong[plm_weights_index++] = dataBv.range(63, 32).to_int(); + } + } #else - if (ping_weights) { - plm_weights_ping[plm_weights_index++] = dataBv.to_int(); - } else { + if (ping_weights) { plm_weights_ping[plm_weights_index++] = dataBv.to_int(); } + else { plm_weights_pong[plm_weights_index++] = dataBv.to_int(); } #endif - } + } - for (uint8_t i = 0; i < PARALLELISM; i += DMA_WORD_PER_BEAT) { - if (ping_weights) { - plm_weights_ping[plm_weights_index++] = 0; + for (uint8_t i = 0; i < PARALLELISM; i += DMA_WORD_PER_BEAT) { + if (ping_weights) { + plm_weights_ping[plm_weights_index++] = 0; #if (DMA_WORD_PER_BEAT == 2) - plm_weights_ping[plm_weights_index++] = 0; + plm_weights_ping[plm_weights_index++] = 0; #endif - } else { - plm_weights_pong[plm_weights_index++] = 0; + } + else { + plm_weights_pong[plm_weights_index++] = 0; #if (DMA_WORD_PER_BEAT == 2) - plm_weights_pong[plm_weights_index++] = 0; + plm_weights_pong[plm_weights_index++] = 0; #endif - } - } + } + } - filters_offset_start_phys += n_words_to_load; - filters_offset_start_virt += n_words_to_load; + filters_offset_start_phys += n_words_to_load; + filters_offset_start_virt += n_words_to_load; - ping_weights = !ping_weights; + ping_weights = !ping_weights; - if (!bias_chunk) { - uint16_t n_words_to_load = min(n_filters - bias_offset_start_virt, - max_cacheable_bias_size); - bool misaligned = bias_offset_start_phys & 1 & (DMA_WORD_PER_BEAT - 1); - uint16_t adj_words_to_load = n_words_to_load + misaligned; + if (!bias_chunk) { + uint16_t n_words_to_load = + min(n_filters - bias_offset_start_virt, max_cacheable_bias_size); + bool misaligned = bias_offset_start_phys & 1 & (DMA_WORD_PER_BEAT - 1); + uint16_t adj_words_to_load = n_words_to_load + misaligned; - dma_info_t dma_info(bias_offset_start_phys >> DMA_WORD_PER_BEAT_LOG2, - (n_words_to_load + misaligned + DMA_WORD_PER_BEAT_LOG2) >> DMA_WORD_PER_BEAT_LOG2, - DMA_SIZE); + dma_info_t dma_info(bias_offset_start_phys >> DMA_WORD_PER_BEAT_LOG2, + (n_words_to_load + misaligned + DMA_WORD_PER_BEAT_LOG2) >> + DMA_WORD_PER_BEAT_LOG2, + DMA_SIZE); #ifndef STRATUS_HLS - ESP_REPORT_INFO("load_input load bias dma_info. offset: %u len %u", - bias_offset_start_phys, n_words_to_load); + ESP_REPORT_INFO("load_input load bias dma_info. offset: %u len %u", + bias_offset_start_phys, n_words_to_load); #endif - this->dma_read_ctrl.put(dma_info); + this->dma_read_ctrl.put(dma_info); - for (uint16_t i = 0; i < adj_words_to_load; i += DMA_WORD_PER_BEAT) - { - HLS_PROTO("load-dma-biases"); - HLS_BREAK_DEP(plm_bias_ping); - HLS_BREAK_DEP(plm_bias_pong); + for (uint16_t i = 0; i < adj_words_to_load; i += DMA_WORD_PER_BEAT) { + HLS_PROTO("load-dma-biases"); + HLS_BREAK_DEP(plm_bias_ping); + HLS_BREAK_DEP(plm_bias_pong); - sc_dt::sc_bv dataBv; + sc_dt::sc_bv dataBv; - dataBv = this->dma_read_chnl.get(); - wait(); + dataBv = this->dma_read_chnl.get(); + wait(); - // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) + // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) #if (DMA_WORD_PER_BEAT == 2) - if (!(!i && misaligned)) { - if (ping_bias) { - plm_bias_ping[plm_bias_i++] = - dataBv.range(31, 0).to_int(); - if (i + 1 < adj_words_to_load) - plm_bias_ping[plm_bias_i++] = - dataBv.range(63, 32).to_int(); - } else { - plm_bias_pong[plm_bias_i++] = - dataBv.range(31, 0).to_int(); - if (i + 1 < adj_words_to_load) - plm_bias_pong[plm_bias_i++] = - dataBv.range(63, 32).to_int(); - } - } + if (!(!i && misaligned)) { + if (ping_bias) { + plm_bias_ping[plm_bias_i++] = dataBv.range(31, 0).to_int(); + if (i + 1 < adj_words_to_load) + plm_bias_ping[plm_bias_i++] = dataBv.range(63, 32).to_int(); + } + else { + plm_bias_pong[plm_bias_i++] = dataBv.range(31, 0).to_int(); + if (i + 1 < adj_words_to_load) + plm_bias_pong[plm_bias_i++] = dataBv.range(63, 32).to_int(); + } + } #else - if (ping_bias) { - plm_bias_ping[plm_bias_i++] = dataBv.to_int(); - } else { + if (ping_bias) { plm_bias_ping[plm_bias_i++] = dataBv.to_int(); } + else { plm_bias_pong[plm_bias_i++] = dataBv.to_int(); } #endif - } - - bias_offset_start_phys += n_words_to_load; - bias_offset_start_virt += n_words_to_load; - } - - bias_chunk++; - if (bias_chunk == max_cacheable_bias_chunks) { - bias_chunk = 0; - ping_bias = !ping_bias; - plm_bias_i = 0; - } - - // Batching - uint32_t infeature_offset_start_base = 0; - for (uint16_t b = 0; b < batch_size; b++) - { - uint32_t infeature_offset_start_virt = 0; - uint32_t infeature_offset_start = infeature_offset_start_base; - for (uint16_t input_chunk = 0; input_chunk < total_input_chunks; - input_chunk++) - { - uint32_t channel_offset = 0; - uint16_t max_cacheable_size_i; - uint16_t feature_offset_incr_i; - - if (single_chunk_done) { - this->load_compute_handshake(); - break; - } - - if (total_input_chunks == 1 && batch_size == 1) { - // optimize if multiple batches all fit in PLM - single_chunk_done = true; - } - - if (!input_chunk) { - max_cacheable_size_i = max_cacheable_size_init; - feature_offset_incr_i = feature_offset_incr_init; - } else { - max_cacheable_size_i = max_cacheable_size; - feature_offset_incr_i = feature_offset_incr; - } - - for (uint12_t in_i = 0; in_i < chan_iters; in_i++) - { - uint12_t channels; - uint16_t plm_in_index = 0; - - if (in_i < chan_iters - 1) - channels = loadable_chan; - else - channels = chan_rem; - - for (uint16_t ch = 0; ch < channels; ch++) - { - wait(); - - // Configure DMA transaction - uint32_t offset_start = channel_offset + infeature_offset_start; - uint16_t n_words_to_load = - min(feature_size - infeature_offset_start_virt, - max_cacheable_size_i); - bool misaligned = offset_start & 1 & (DMA_WORD_PER_BEAT - 1); - uint16_t adj_words_to_load = n_words_to_load + misaligned; - - dma_info_t dma_info(offset_start >> DMA_WORD_PER_BEAT_LOG2, - (n_words_to_load + DMA_WORD_PER_BEAT_LOG2) >> - DMA_WORD_PER_BEAT_LOG2, DMA_SIZE); + } + + bias_offset_start_phys += n_words_to_load; + bias_offset_start_virt += n_words_to_load; + } + + bias_chunk++; + if (bias_chunk == max_cacheable_bias_chunks) { + bias_chunk = 0; + ping_bias = !ping_bias; + plm_bias_i = 0; + } + + // Batching + uint32_t infeature_offset_start_base = 0; + for (uint16_t b = 0; b < batch_size; b++) { + uint32_t infeature_offset_start_virt = 0; + uint32_t infeature_offset_start = infeature_offset_start_base; + for (uint16_t input_chunk = 0; input_chunk < total_input_chunks; input_chunk++) { + uint32_t channel_offset = 0; + uint16_t max_cacheable_size_i; + uint16_t feature_offset_incr_i; + + if (single_chunk_done) { + this->load_compute_handshake(); + break; + } + + if (total_input_chunks == 1 && batch_size == 1) { + // optimize if multiple batches all fit in PLM + single_chunk_done = true; + } + + if (!input_chunk) { + max_cacheable_size_i = max_cacheable_size_init; + feature_offset_incr_i = feature_offset_incr_init; + } + else { + max_cacheable_size_i = max_cacheable_size; + feature_offset_incr_i = feature_offset_incr; + } + + for (uint12_t in_i = 0; in_i < chan_iters; in_i++) { + uint12_t channels; + uint16_t plm_in_index = 0; + + if (in_i < chan_iters - 1) channels = loadable_chan; + else + channels = chan_rem; + + for (uint16_t ch = 0; ch < channels; ch++) { + wait(); + + // Configure DMA transaction + uint32_t offset_start = channel_offset + infeature_offset_start; + uint16_t n_words_to_load = min( + feature_size - infeature_offset_start_virt, max_cacheable_size_i); + bool misaligned = offset_start & 1 & (DMA_WORD_PER_BEAT - 1); + uint16_t adj_words_to_load = n_words_to_load + misaligned; + + dma_info_t dma_info(offset_start >> DMA_WORD_PER_BEAT_LOG2, + (n_words_to_load + DMA_WORD_PER_BEAT_LOG2) >> + DMA_WORD_PER_BEAT_LOG2, + DMA_SIZE); #ifndef STRATUS_HLS - ESP_REPORT_INFO("load_input load features dma_info. offset: %u len %u", offset_start, n_words_to_load); + ESP_REPORT_INFO("load_input load features dma_info. offset: %u len %u", + offset_start, n_words_to_load); #endif - this->dma_read_ctrl.put(dma_info); + this->dma_read_ctrl.put(dma_info); - for (uint16_t i = 0; i < adj_words_to_load; - i += DMA_WORD_PER_BEAT) - { - HLS_PROTO("load-dma-in-features"); - HLS_BREAK_DEP(plm_in_ping); - HLS_BREAK_DEP(plm_in_pong); + for (uint16_t i = 0; i < adj_words_to_load; i += DMA_WORD_PER_BEAT) { + HLS_PROTO("load-dma-in-features"); + HLS_BREAK_DEP(plm_in_ping); + HLS_BREAK_DEP(plm_in_pong); - sc_dt::sc_bv dataBv; + sc_dt::sc_bv dataBv; - dataBv = this->dma_read_chnl.get(); - wait(); + dataBv = this->dma_read_chnl.get(); + wait(); - // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) + // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) #if (DMA_WORD_PER_BEAT == 2) - if (!(!i && misaligned)) { - if (ping_input) { - plm_in_ping[plm_in_index++] = - dataBv.range(31, 0).to_int(); - if (i + 1 < adj_words_to_load) - plm_in_ping[plm_in_index++] = - dataBv.range(63, 32).to_int(); - } else { - plm_in_pong[plm_in_index++] = - dataBv.range(31, 0).to_int(); - if (i + 1 < adj_words_to_load) - plm_in_pong[plm_in_index++] = - dataBv.range(63, 32).to_int(); - } - } + if (!(!i && misaligned)) { + if (ping_input) { + plm_in_ping[plm_in_index++] = dataBv.range(31, 0).to_int(); + if (i + 1 < adj_words_to_load) + plm_in_ping[plm_in_index++] = + dataBv.range(63, 32).to_int(); + } + else { + plm_in_pong[plm_in_index++] = dataBv.range(31, 0).to_int(); + if (i + 1 < adj_words_to_load) + plm_in_pong[plm_in_index++] = + dataBv.range(63, 32).to_int(); + } + } #else - if (ping_input) { - plm_in_ping[plm_in_index++] = dataBv.to_int(); - } else { + if (ping_input) { plm_in_ping[plm_in_index++] = dataBv.to_int(); } + else { plm_in_pong[plm_in_index++] = dataBv.to_int(); } #endif - } - channel_offset += channel_offset_incr; - } - - ping_input = !ping_input; - - this->load_compute_handshake(); - } - infeature_offset_start += feature_offset_incr_i; - infeature_offset_start_virt += feature_offset_incr_i; - } - infeature_offset_start_base += infeature_offset_incr; - } - } - } + } + channel_offset += channel_offset_incr; + } + + ping_input = !ping_input; + this->load_compute_handshake(); + } + infeature_offset_start += feature_offset_incr_i; + infeature_offset_start_virt += feature_offset_incr_i; + } + infeature_offset_start_base += infeature_offset_incr; + } + } + } // Conclude { @@ -430,8 +407,6 @@ void conv2d::load_input() } } - - void conv2d::store_output() { // Reset @@ -439,7 +414,7 @@ void conv2d::store_output() HLS_PROTO("store-reset"); this->reset_store_output(); - load_store_cfg_done.ack.reset_ack(); + load_store_cfg_done.ack.reset_ack(); // explicit PLM ports reset if any // User-defined reset code @@ -464,12 +439,12 @@ void conv2d::store_output() // User-defined config code /* <<--local-params-->> */ - n_filters = config.n_filters; + n_filters = config.n_filters; filter_dim = config.filter_dim; - stride = config.stride; - height = config.feature_map_height; - pool_type = config.pool_type; - batch_size = config.batch_size; + stride = config.stride; + height = config.feature_map_height; + pool_type = config.pool_type; + batch_size = config.batch_size; } store_load_cfg_handshake(); @@ -486,177 +461,166 @@ void conv2d::store_output() uint32_t feature_offset_start_base; { - HLS_DEFINE_PROTOCOL("store-config-sig"); - pad = pad_sig.read(); - output_w = output_w_sig.read(); - total_filters_chunks = total_filters_chunks_sig.read(); - total_input_chunks = total_input_chunks_sig.read(); - max_cacheable_rows = max_cacheable_rows_sig.read(); - max_cacheable_rows_init = max_cacheable_rows_init_sig.read(); - max_cacheable_filters = max_cacheable_filters_sig.read(); - out_channel_offset_incr = out_channel_offset_incr_sig.read(); - out_channel_pool_offset_incr = out_channel_pool_offset_incr_sig.read(); - feature_offset_start_base = feature_offset_start_base_sig.read(); - wait(); + HLS_DEFINE_PROTOCOL("store-config-sig"); + pad = pad_sig.read(); + output_w = output_w_sig.read(); + total_filters_chunks = total_filters_chunks_sig.read(); + total_input_chunks = total_input_chunks_sig.read(); + max_cacheable_rows = max_cacheable_rows_sig.read(); + max_cacheable_rows_init = max_cacheable_rows_init_sig.read(); + max_cacheable_filters = max_cacheable_filters_sig.read(); + out_channel_offset_incr = out_channel_offset_incr_sig.read(); + out_channel_pool_offset_incr = out_channel_pool_offset_incr_sig.read(); + feature_offset_start_base = feature_offset_start_base_sig.read(); + wait(); } bool ping_output = true; - bool is_pool = pool_type ? true : false; + bool is_pool = pool_type ? true : false; // Store uint32_t out_channel_offset_base = 0; - for (uint16_t filter_chunk = 0; filter_chunk < total_filters_chunks; filter_chunk++) - { - wait(); - uint32_t feature_offset_start_base_tmp = feature_offset_start_base; - for (uint16_t b = 0; b < batch_size; b++) - { - uint32_t feature_offset_start_phys = feature_offset_start_base_tmp; - uint32_t feature_offset_start_virt = 0; - uint16_t first_row_to_load = 0; - for (uint16_t input_chunk = 0; input_chunk < total_input_chunks; - input_chunk++) - { - uint16_t max_cacheable_rows_i; - if (!input_chunk) { - max_cacheable_rows_i = max_cacheable_rows_init; - } else { - max_cacheable_rows_i = max_cacheable_rows; - } - - bool no_first_row = (input_chunk != 0); - bool no_last_row = (input_chunk != total_input_chunks - 1); - uint16_t loadable_rows = min(height - first_row_to_load, - max_cacheable_rows_i); - uint16_t rows_to_load = loadable_rows - (no_first_row * pad) - - (no_last_row * pad); - uint16_t rows_to_load_adj = (uint16_t) (rows_to_load + stride - 1) - >> ilog2(stride); - uint16_t rows_to_load_adj_pool = (uint16_t) rows_to_load_adj >> is_pool; - uint16_t n_words_to_store = rows_to_load_adj_pool * - ((uint16_t) output_w >> is_pool); - - uint16_t plm_out_index = 0; - uint16_t cached_filters = min(max_cacheable_filters, n_filters - - filter_chunk * max_cacheable_filters); - uint32_t out_channel_offset = out_channel_offset_base; - - this->store_compute_handshake(); - - // pooling step - for (uint16_t filter_i = 0; filter_i < cached_filters; filter_i++) - { - uint32_t offset_start = out_channel_offset + - feature_offset_start_phys; - - if (pool_type) { - uint16_t pool_i_in1_base = filter_i * - round_up(rows_to_load_adj * output_w, DMA_WORD_PER_BEAT); - uint16_t pool_i_in2_base = pool_i_in1_base + output_w; - uint16_t pool_i_out = filter_i * - round_up(n_words_to_store, DMA_WORD_PER_BEAT); - - for (uint16_t out_h = 0; out_h < rows_to_load_adj - 1; - out_h += 2) { - uint16_t pool_i_in1 = pool_i_in1_base; - uint16_t pool_i_in2 = pool_i_in2_base; - for (uint16_t out_w = 0; out_w < output_w - 1; out_w += 2) { - FPDATA a, b, c, d, res; - if (ping_output) { - a = INT2FP(plm_out_ping[pool_i_in1]); - b = INT2FP(plm_out_ping[pool_i_in1 + 1]); - c = INT2FP(plm_out_ping[pool_i_in2]); - d = INT2FP(plm_out_ping[pool_i_in2 + 1]); - } else { - a = INT2FP(plm_out_pong[pool_i_in1]); - b = INT2FP(plm_out_pong[pool_i_in1 + 1]); - c = INT2FP(plm_out_pong[pool_i_in2]); - d = INT2FP(plm_out_pong[pool_i_in2 + 1]); - } - pool_i_in1 += 2; - pool_i_in2 += 2; - - if (pool_type == 1) { - if (a >= b && a >= c && a >= d) { - res = a; - } else if (b >= c && b >= d) { - res = b; - } else if (c >= d) { - res = c; - } else { - res = d; - } - } else { // pool_type == 2 - res = (a + b + c + d) * 0.25; - } - - if (ping_output) { - plm_out_ping[pool_i_out++] = FP2INT(res); - } else { - plm_out_pong[pool_i_out++] = FP2INT(res); - } - } - pool_i_in1_base += (output_w << 1); - pool_i_in2_base += (output_w << 1); - } - } - - { - HLS_DEFINE_PROTOCOL(); - - dma_info_t dma_info(offset_start >> DMA_WORD_PER_BEAT_LOG2, - (n_words_to_store + DMA_WORD_PER_BEAT_LOG2) >> - DMA_WORD_PER_BEAT_LOG2, DMA_SIZE); + for (uint16_t filter_chunk = 0; filter_chunk < total_filters_chunks; filter_chunk++) { + wait(); + uint32_t feature_offset_start_base_tmp = feature_offset_start_base; + for (uint16_t b = 0; b < batch_size; b++) { + uint32_t feature_offset_start_phys = feature_offset_start_base_tmp; + uint32_t feature_offset_start_virt = 0; + uint16_t first_row_to_load = 0; + for (uint16_t input_chunk = 0; input_chunk < total_input_chunks; input_chunk++) { + uint16_t max_cacheable_rows_i; + if (!input_chunk) { max_cacheable_rows_i = max_cacheable_rows_init; } + else { + max_cacheable_rows_i = max_cacheable_rows; + } + + bool no_first_row = (input_chunk != 0); + bool no_last_row = (input_chunk != total_input_chunks - 1); + uint16_t loadable_rows = min(height - first_row_to_load, max_cacheable_rows_i); + uint16_t rows_to_load = loadable_rows - (no_first_row * pad) - (no_last_row * pad); + uint16_t rows_to_load_adj = (uint16_t)(rows_to_load + stride - 1) >> ilog2(stride); + uint16_t rows_to_load_adj_pool = (uint16_t)rows_to_load_adj >> is_pool; + uint16_t n_words_to_store = rows_to_load_adj_pool * ((uint16_t)output_w >> is_pool); + + uint16_t plm_out_index = 0; + uint16_t cached_filters = + min(max_cacheable_filters, n_filters - filter_chunk * max_cacheable_filters); + uint32_t out_channel_offset = out_channel_offset_base; + + this->store_compute_handshake(); + + // pooling step + for (uint16_t filter_i = 0; filter_i < cached_filters; filter_i++) { + uint32_t offset_start = out_channel_offset + feature_offset_start_phys; + + if (pool_type) { + uint16_t pool_i_in1_base = + filter_i * round_up(rows_to_load_adj * output_w, DMA_WORD_PER_BEAT); + uint16_t pool_i_in2_base = pool_i_in1_base + output_w; + uint16_t pool_i_out = + filter_i * round_up(n_words_to_store, DMA_WORD_PER_BEAT); + + for (uint16_t out_h = 0; out_h < rows_to_load_adj - 1; out_h += 2) { + uint16_t pool_i_in1 = pool_i_in1_base; + uint16_t pool_i_in2 = pool_i_in2_base; + for (uint16_t out_w = 0; out_w < output_w - 1; out_w += 2) { + FPDATA a, b, c, d, res; + if (ping_output) { + a = INT2FP(plm_out_ping[pool_i_in1]); + b = INT2FP(plm_out_ping[pool_i_in1 + 1]); + c = INT2FP(plm_out_ping[pool_i_in2]); + d = INT2FP(plm_out_ping[pool_i_in2 + 1]); + } + else { + a = INT2FP(plm_out_pong[pool_i_in1]); + b = INT2FP(plm_out_pong[pool_i_in1 + 1]); + c = INT2FP(plm_out_pong[pool_i_in2]); + d = INT2FP(plm_out_pong[pool_i_in2 + 1]); + } + pool_i_in1 += 2; + pool_i_in2 += 2; + + if (pool_type == 1) { + if (a >= b && a >= c && a >= d) { res = a; } + else if (b >= c && b >= d) { + res = b; + } + else if (c >= d) { + res = c; + } + else { + res = d; + } + } + else { // pool_type == 2 + res = (a + b + c + d) * 0.25; + } + + if (ping_output) { plm_out_ping[pool_i_out++] = FP2INT(res); } + else { + plm_out_pong[pool_i_out++] = FP2INT(res); + } + } + pool_i_in1_base += (output_w << 1); + pool_i_in2_base += (output_w << 1); + } + } + + { + HLS_DEFINE_PROTOCOL(); + + dma_info_t dma_info(offset_start >> DMA_WORD_PER_BEAT_LOG2, + (n_words_to_store + DMA_WORD_PER_BEAT_LOG2) >> + DMA_WORD_PER_BEAT_LOG2, + DMA_SIZE); #ifndef STRATUS_HLS - ESP_REPORT_INFO("store dma info. offset: %u len %u", - offset_start, n_words_to_store); + ESP_REPORT_INFO("store dma info. offset: %u len %u", offset_start, + n_words_to_store); #endif - this->dma_write_ctrl.put(dma_info); + this->dma_write_ctrl.put(dma_info); - for (uint16_t i = 0; i < n_words_to_store; - i += DMA_WORD_PER_BEAT) - { - HLS_PROTO("store-dma-out-features"); - HLS_BREAK_DEP(plm_out_ping); - HLS_BREAK_DEP(plm_out_pong); + for (uint16_t i = 0; i < n_words_to_store; i += DMA_WORD_PER_BEAT) { + HLS_PROTO("store-dma-out-features"); + HLS_BREAK_DEP(plm_out_ping); + HLS_BREAK_DEP(plm_out_pong); - wait(); + wait(); - sc_dt::sc_bv dataBv; + sc_dt::sc_bv dataBv; - // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) - if (ping_output) { - std::cout << "store ping " << - INT2FP(plm_out_ping[plm_out_index]) << std::endl; - dataBv.range(31, 0) = plm_out_ping[plm_out_index++]; + // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) + if (ping_output) { + std::cout << "store ping " << INT2FP(plm_out_ping[plm_out_index]) + << std::endl; + dataBv.range(31, 0) = plm_out_ping[plm_out_index++]; #if (DMA_WORD_PER_BEAT == 2) - dataBv.range(63, 32) = plm_out_ping[plm_out_index++]; + dataBv.range(63, 32) = plm_out_ping[plm_out_index++]; #endif - } else { - std::cout << "store pong " << - INT2FP(plm_out_pong[plm_out_index]) << std::endl; - dataBv.range(31, 0) = plm_out_pong[plm_out_index++]; + } + else { + std::cout << "store pong " << INT2FP(plm_out_pong[plm_out_index]) + << std::endl; + dataBv.range(31, 0) = plm_out_pong[plm_out_index++]; #if (DMA_WORD_PER_BEAT == 2) - dataBv.range(63, 32) = plm_out_pong[plm_out_index++]; + dataBv.range(63, 32) = plm_out_pong[plm_out_index++]; #endif - } - - this->dma_write_chnl.put(dataBv); - - wait(); - } - } - out_channel_offset += out_channel_pool_offset_incr; - } - ping_output = !ping_output; - feature_offset_start_phys += n_words_to_store; - feature_offset_start_virt += n_words_to_store; - first_row_to_load += max_cacheable_rows_i - (filter_dim - 1); - } - feature_offset_start_base_tmp += (n_filters * out_channel_pool_offset_incr); - } - out_channel_offset_base += - (out_channel_pool_offset_incr * max_cacheable_filters); + } + + this->dma_write_chnl.put(dataBv); + + wait(); + } + } + out_channel_offset += out_channel_pool_offset_incr; + } + ping_output = !ping_output; + feature_offset_start_phys += n_words_to_store; + feature_offset_start_virt += n_words_to_store; + first_row_to_load += max_cacheable_rows_i - (filter_dim - 1); + } + feature_offset_start_base_tmp += (n_filters * out_channel_pool_offset_incr); + } + out_channel_offset_base += (out_channel_pool_offset_incr * max_cacheable_filters); } // Conclude @@ -666,7 +630,6 @@ void conv2d::store_output() } } - void conv2d::compute_kernel() { // Reset @@ -674,7 +637,7 @@ void conv2d::compute_kernel() HLS_PROTO("compute-reset"); this->reset_compute_kernel(); - load_compute_cfg_done.ack.reset_ack(); + load_compute_cfg_done.ack.reset_ack(); // explicit PLM ports reset if any @@ -703,13 +666,13 @@ void conv2d::compute_kernel() // User-defined config code /* <<--local-params-->> */ n_channels = config.n_channels; - n_filters = config.n_filters; + n_filters = config.n_filters; filter_dim = config.filter_dim; - stride = config.stride; - height = config.feature_map_height; - width = config.feature_map_width; - do_relu = config.do_relu; - batch_size = config.batch_size; + stride = config.stride; + height = config.feature_map_height; + width = config.feature_map_width; + do_relu = config.do_relu; + batch_size = config.batch_size; } compute_load_cfg_handshake(); @@ -727,243 +690,236 @@ void conv2d::compute_kernel() uint16_t loadable_chan_sz, chan_rem_sz; { - HLS_DEFINE_PROTOCOL("compute-config-sig"); - pad = pad_sig.read(); - output_w = output_w_sig.read(); - filter_size = filter_size_sig.read(); - total_filters_chunks = total_filters_chunks_sig.read(); - total_input_chunks = total_input_chunks_sig.read(); - max_cacheable_rows = max_cacheable_rows_sig.read(); - max_cacheable_rows_init = max_cacheable_rows_init_sig.read(); - max_cacheable_filters = max_cacheable_filters_sig.read(); - max_cacheable_bias_chunks = max_cacheable_bias_chunks_sig.read(); - loadable_chan = loadable_chan_sig.read(); - chan_iters = chan_iters_sig.read(); - chan_rem = chan_rem_sig.read(); - loadable_chan_sz = loadable_chan_sz_sig.read(); - chan_rem_sz = chan_rem_sz_sig.read(); - wait(); + HLS_DEFINE_PROTOCOL("compute-config-sig"); + pad = pad_sig.read(); + output_w = output_w_sig.read(); + filter_size = filter_size_sig.read(); + total_filters_chunks = total_filters_chunks_sig.read(); + total_input_chunks = total_input_chunks_sig.read(); + max_cacheable_rows = max_cacheable_rows_sig.read(); + max_cacheable_rows_init = max_cacheable_rows_init_sig.read(); + max_cacheable_filters = max_cacheable_filters_sig.read(); + max_cacheable_bias_chunks = max_cacheable_bias_chunks_sig.read(); + loadable_chan = loadable_chan_sig.read(); + chan_iters = chan_iters_sig.read(); + chan_rem = chan_rem_sig.read(); + loadable_chan_sz = loadable_chan_sz_sig.read(); + chan_rem_sz = chan_rem_sz_sig.read(); + wait(); } // Compute - bool ping_input = true; + bool ping_input = true; bool ping_weights = true; - bool ping_bias = true; - bool ping_output = true; + bool ping_bias = true; + bool ping_output = true; uint16_t bias_chunk = 0; uint16_t plm_bias_i = 0; - for (uint16_t filter_chunk = 0; filter_chunk < total_filters_chunks; filter_chunk++) - { - uint16_t loadable_filters = min(n_filters - filter_chunk * - max_cacheable_filters, max_cacheable_filters); - - for (uint16_t b = 0; b < batch_size; b++) - { - uint16_t first_row_to_load = 0; - for (uint16_t input_chunk = 0; input_chunk < total_input_chunks; - input_chunk++) - { - uint16_t max_cacheable_rows_i; - if (!input_chunk) { - max_cacheable_rows_i = max_cacheable_rows_init; - } else { - max_cacheable_rows_i = max_cacheable_rows; - } - - bool no_first_row = (input_chunk != 0); - bool no_last_row = (input_chunk != total_input_chunks - 1); - uint16_t loadable_rows = min(height - first_row_to_load, - max_cacheable_rows_i); - uint16_t rows_to_load = loadable_rows - (no_first_row * pad) - - (no_last_row * pad); - uint16_t loadable_out_size = - round_up(((uint16_t) (rows_to_load + stride - 1) >> - ilog2(stride)) * output_w, DMA_WORD_PER_BEAT); - - uint16_t start_addr_base = 0; - for (uint12_t in_i = 0; in_i < chan_iters; in_i++) - { - uint16_t out_plm_offset = 0; - uint16_t start_addr_base = in_i * loadable_chan_sz; - wait(); - this->compute_load_handshake(); + for (uint16_t filter_chunk = 0; filter_chunk < total_filters_chunks; filter_chunk++) { + uint16_t loadable_filters = + min(n_filters - filter_chunk * max_cacheable_filters, max_cacheable_filters); + + for (uint16_t b = 0; b < batch_size; b++) { + uint16_t first_row_to_load = 0; + for (uint16_t input_chunk = 0; input_chunk < total_input_chunks; input_chunk++) { + uint16_t max_cacheable_rows_i; + if (!input_chunk) { max_cacheable_rows_i = max_cacheable_rows_init; } + else { + max_cacheable_rows_i = max_cacheable_rows; + } + + bool no_first_row = (input_chunk != 0); + bool no_last_row = (input_chunk != total_input_chunks - 1); + uint16_t loadable_rows = min(height - first_row_to_load, max_cacheable_rows_i); + uint16_t rows_to_load = loadable_rows - (no_first_row * pad) - (no_last_row * pad); + uint16_t loadable_out_size = + round_up(((uint16_t)(rows_to_load + stride - 1) >> ilog2(stride)) * output_w, + DMA_WORD_PER_BEAT); + + uint16_t start_addr_base = 0; + for (uint12_t in_i = 0; in_i < chan_iters; in_i++) { + uint16_t out_plm_offset = 0; + uint16_t start_addr_base = in_i * loadable_chan_sz; + wait(); + this->compute_load_handshake(); #ifndef STRATUS_HLS - ESP_REPORT_INFO("compute_load_handshake %u %u %u %u", - filter_chunk, b, input_chunk, (unsigned) in_i); + ESP_REPORT_INFO("compute_load_handshake %u %u %u %u", filter_chunk, b, + input_chunk, (unsigned)in_i); #endif - uint12_t channels; - uint16_t filt_sz_loc; - if (in_i < chan_iters - 1) { - channels = loadable_chan; - filt_sz_loc = loadable_chan_sz; - } else { - channels = chan_rem; - filt_sz_loc = chan_rem_sz; - } - - for (uint16_t out_r = 0; out_r < rows_to_load; out_r += stride) - { - for (uint16_t out_c = 0; out_c < (output_w << ilog2(stride)); out_c += stride) - { - uint16_t ch = 0, ch_base = 0, ch_size = loadable_rows * width; - uint16_t k_r = 0, k_c = 0; - int16_t in_r_base = out_r + (no_first_row * pad) - pad, in_c_base = out_c - pad; - int16_t out_r_i = out_r + (no_first_row * pad); - uint16_t start_addr_base1 = start_addr_base; - uint16_t compute_iters = ((uint16_t) (filt_sz_loc - 1) >> (uint4_t) PARAL_LOG2) + 1; - for (uint16_t i = 0; i < compute_iters; i++) { - - // patch extractor - for (uint16_t j = 0; j < PARALLELISM; j++) { - HLS_BREAK_ARRAY_DEPENDENCY(plm_in_ping); - HLS_BREAK_ARRAY_DEPENDENCY(plm_in_pong); - HLS_PIPELINE_LOOP(HARD_STALL, 1, "patch-pipeline"); - - FPDATA_WORD val; - int16_t in_r = in_r_base + k_r; - int16_t in_c = in_c_base + k_c; - uint16_t plm_i = (uint16_t) ch_base + - ((int16_t) in_r * width) + in_c; - - if (in_r >= 0 && in_r < loadable_rows && - in_c >= 0 && in_c < width && ch < channels) { - if (ping_input) - val = plm_in_ping[plm_i]; - else - val = plm_in_pong[plm_i]; - } else { - val = 0; - } - - reg_patch[j] = INT2FP(val); - - k_c++; - if (k_c == filter_dim) { - k_c = 0; - k_r++; - if (k_r == filter_dim) { - k_r = 0; - ch++; - ch_base += ch_size; - } - } - wait(); - } - - // multiply and accumulate (MAC) - uint16_t start_addr_base2 = 0; - uint16_t out_plm_addr = out_plm_offset; - for (uint16_t f = 0; f < loadable_filters; f++) { - HLS_BREAK_ARRAY_DEPENDENCY(plm_weights_ping); - HLS_BREAK_ARRAY_DEPENDENCY(plm_weights_pong); - HLS_PIPELINE_LOOP(HARD_STALL, 2, "mac-pipeline"); - HLS_CONSTRAIN_ARRAY_MAX_DISTANCE(plm_out_ping, 13); - HLS_CONSTRAIN_ARRAY_MAX_DISTANCE(plm_out_pong, 13); - - FPDATA bias, res_relu, res_bias, res_partial, res_mac = 0; - uint16_t start_addr = start_addr_base1 + start_addr_base2; - if (ping_weights) { - reg_w[0] = INT2FP(plm_weights_ping[start_addr]); - reg_w[1] = INT2FP(plm_weights_ping[start_addr+1]); - reg_w[2] = INT2FP(plm_weights_ping[start_addr+2]); - reg_w[3] = INT2FP(plm_weights_ping[start_addr+3]); - reg_w[4] = INT2FP(plm_weights_ping[start_addr+4]); - reg_w[5] = INT2FP(plm_weights_ping[start_addr+5]); - reg_w[6] = INT2FP(plm_weights_ping[start_addr+6]); - reg_w[7] = INT2FP(plm_weights_ping[start_addr+7]); - } else { - reg_w[0] = INT2FP(plm_weights_pong[start_addr]); - reg_w[1] = INT2FP(plm_weights_pong[start_addr+1]); - reg_w[2] = INT2FP(plm_weights_pong[start_addr+2]); - reg_w[3] = INT2FP(plm_weights_pong[start_addr+3]); - reg_w[4] = INT2FP(plm_weights_pong[start_addr+4]); - reg_w[5] = INT2FP(plm_weights_pong[start_addr+5]); - reg_w[6] = INT2FP(plm_weights_pong[start_addr+6]); - reg_w[7] = INT2FP(plm_weights_pong[start_addr+7]); - } - - if (!i && !in_i) { - res_partial = FPDATA(0.0); - } else { - if (ping_output) { - res_partial = INT2FP(plm_out_ping[out_plm_addr]); - } else { - res_partial = INT2FP(plm_out_pong[out_plm_addr]); - } - } - - reg_mac[0] = reg_patch[0] * reg_w[0]; - reg_mac[1] = reg_patch[1] * reg_w[1]; - reg_mac[2] = reg_patch[2] * reg_w[2]; - reg_mac[3] = reg_patch[3] * reg_w[3]; - reg_mac[4] = reg_patch[4] * reg_w[4]; - reg_mac[5] = reg_patch[5] * reg_w[5]; - reg_mac[6] = reg_patch[6] * reg_w[6]; - reg_mac[7] = reg_patch[7] * reg_w[7]; - - res_mac = ((reg_mac[0] + reg_mac[1]) + - (reg_mac[2] + reg_mac[3])) + - ((reg_mac[4] + reg_mac[5]) + - (reg_mac[6] + reg_mac[7])) + - res_partial; - - if (i + 1 == compute_iters && in_i + 1 == chan_iters) { - if (ping_bias) - bias = INT2FP(plm_bias_ping[plm_bias_i + f]); - else - bias = INT2FP(plm_bias_pong[plm_bias_i + f]); - res_bias = res_mac + bias; - if (do_relu && res_bias < 0) - res_relu = FPDATA(0); - else - res_relu = res_bias; - } else { - res_bias = FPDATA(0); - res_relu = res_mac; - } - - if (ping_output) { - plm_out_ping[out_plm_addr] = FP2INT(res_relu); - } else { - plm_out_pong[out_plm_addr] = FP2INT(res_relu); - } - - out_plm_addr += loadable_out_size; - start_addr_base2 += filter_size; - - wait(); - } - start_addr_base1 += PARALLELISM; - } - - out_plm_offset++; - wait(); - } - } - start_addr_base += loadable_chan_sz; - if (total_input_chunks != 1 || batch_size != 1) - ping_input = !ping_input; - } - first_row_to_load += max_cacheable_rows_i - (filter_dim - 1); - ping_output = !ping_output; - - this->compute_store_handshake(); - } - } - ping_weights = !ping_weights; - bias_chunk++; - plm_bias_i += loadable_filters; - if (bias_chunk == max_cacheable_bias_chunks) { - bias_chunk = 0; - plm_bias_i = 0; - ping_bias = !ping_bias; - } + uint12_t channels; + uint16_t filt_sz_loc; + if (in_i < chan_iters - 1) { + channels = loadable_chan; + filt_sz_loc = loadable_chan_sz; + } + else { + channels = chan_rem; + filt_sz_loc = chan_rem_sz; + } + + for (uint16_t out_r = 0; out_r < rows_to_load; out_r += stride) { + for (uint16_t out_c = 0; out_c < (output_w << ilog2(stride)); + out_c += stride) { + uint16_t ch = 0, ch_base = 0, ch_size = loadable_rows * width; + uint16_t k_r = 0, k_c = 0; + int16_t in_r_base = out_r + (no_first_row * pad) - pad, + in_c_base = out_c - pad; + int16_t out_r_i = out_r + (no_first_row * pad); + uint16_t start_addr_base1 = start_addr_base; + uint16_t compute_iters = + ((uint16_t)(filt_sz_loc - 1) >> (uint4_t)PARAL_LOG2) + 1; + for (uint16_t i = 0; i < compute_iters; i++) { + + // patch extractor + for (uint16_t j = 0; j < PARALLELISM; j++) { + HLS_BREAK_ARRAY_DEPENDENCY(plm_in_ping); + HLS_BREAK_ARRAY_DEPENDENCY(plm_in_pong); + HLS_PIPELINE_LOOP(HARD_STALL, 1, "patch-pipeline"); + + FPDATA_WORD val; + int16_t in_r = in_r_base + k_r; + int16_t in_c = in_c_base + k_c; + uint16_t plm_i = + (uint16_t)ch_base + ((int16_t)in_r * width) + in_c; + + if (in_r >= 0 && in_r < loadable_rows && in_c >= 0 && + in_c < width && ch < channels) { + if (ping_input) val = plm_in_ping[plm_i]; + else + val = plm_in_pong[plm_i]; + } + else { + val = 0; + } + + reg_patch[j] = INT2FP(val); + + k_c++; + if (k_c == filter_dim) { + k_c = 0; + k_r++; + if (k_r == filter_dim) { + k_r = 0; + ch++; + ch_base += ch_size; + } + } + wait(); + } + + // multiply and accumulate (MAC) + uint16_t start_addr_base2 = 0; + uint16_t out_plm_addr = out_plm_offset; + for (uint16_t f = 0; f < loadable_filters; f++) { + HLS_BREAK_ARRAY_DEPENDENCY(plm_weights_ping); + HLS_BREAK_ARRAY_DEPENDENCY(plm_weights_pong); + HLS_PIPELINE_LOOP(HARD_STALL, 2, "mac-pipeline"); + HLS_CONSTRAIN_ARRAY_MAX_DISTANCE(plm_out_ping, 13); + HLS_CONSTRAIN_ARRAY_MAX_DISTANCE(plm_out_pong, 13); + + FPDATA bias, res_relu, res_bias, res_partial, res_mac = 0; + uint16_t start_addr = start_addr_base1 + start_addr_base2; + if (ping_weights) { + reg_w[0] = INT2FP(plm_weights_ping[start_addr]); + reg_w[1] = INT2FP(plm_weights_ping[start_addr + 1]); + reg_w[2] = INT2FP(plm_weights_ping[start_addr + 2]); + reg_w[3] = INT2FP(plm_weights_ping[start_addr + 3]); + reg_w[4] = INT2FP(plm_weights_ping[start_addr + 4]); + reg_w[5] = INT2FP(plm_weights_ping[start_addr + 5]); + reg_w[6] = INT2FP(plm_weights_ping[start_addr + 6]); + reg_w[7] = INT2FP(plm_weights_ping[start_addr + 7]); + } + else { + reg_w[0] = INT2FP(plm_weights_pong[start_addr]); + reg_w[1] = INT2FP(plm_weights_pong[start_addr + 1]); + reg_w[2] = INT2FP(plm_weights_pong[start_addr + 2]); + reg_w[3] = INT2FP(plm_weights_pong[start_addr + 3]); + reg_w[4] = INT2FP(plm_weights_pong[start_addr + 4]); + reg_w[5] = INT2FP(plm_weights_pong[start_addr + 5]); + reg_w[6] = INT2FP(plm_weights_pong[start_addr + 6]); + reg_w[7] = INT2FP(plm_weights_pong[start_addr + 7]); + } + + if (!i && !in_i) { res_partial = FPDATA(0.0); } + else { + if (ping_output) { + res_partial = INT2FP(plm_out_ping[out_plm_addr]); + } + else { + res_partial = INT2FP(plm_out_pong[out_plm_addr]); + } + } + + reg_mac[0] = reg_patch[0] * reg_w[0]; + reg_mac[1] = reg_patch[1] * reg_w[1]; + reg_mac[2] = reg_patch[2] * reg_w[2]; + reg_mac[3] = reg_patch[3] * reg_w[3]; + reg_mac[4] = reg_patch[4] * reg_w[4]; + reg_mac[5] = reg_patch[5] * reg_w[5]; + reg_mac[6] = reg_patch[6] * reg_w[6]; + reg_mac[7] = reg_patch[7] * reg_w[7]; + + res_mac = + ((reg_mac[0] + reg_mac[1]) + (reg_mac[2] + reg_mac[3])) + + ((reg_mac[4] + reg_mac[5]) + (reg_mac[6] + reg_mac[7])) + + res_partial; + + if (i + 1 == compute_iters && in_i + 1 == chan_iters) { + if (ping_bias) bias = INT2FP(plm_bias_ping[plm_bias_i + f]); + else + bias = INT2FP(plm_bias_pong[plm_bias_i + f]); + res_bias = res_mac + bias; + if (do_relu && res_bias < 0) res_relu = FPDATA(0); + else + res_relu = res_bias; + } + else { + res_bias = FPDATA(0); + res_relu = res_mac; + } + + if (ping_output) { + plm_out_ping[out_plm_addr] = FP2INT(res_relu); + } + else { + plm_out_pong[out_plm_addr] = FP2INT(res_relu); + } + + out_plm_addr += loadable_out_size; + start_addr_base2 += filter_size; + + wait(); + } + start_addr_base1 += PARALLELISM; + } + + out_plm_offset++; + wait(); + } + } + start_addr_base += loadable_chan_sz; + if (total_input_chunks != 1 || batch_size != 1) ping_input = !ping_input; + } + first_row_to_load += max_cacheable_rows_i - (filter_dim - 1); + ping_output = !ping_output; + + this->compute_store_handshake(); + } + } + ping_weights = !ping_weights; + bias_chunk++; + plm_bias_i += loadable_filters; + if (bias_chunk == max_cacheable_bias_chunks) { + bias_chunk = 0; + plm_bias_i = 0; + ping_bias = !ping_bias; + } } // Conclude { - this->process_done(); + this->process_done(); } } diff --git a/accelerators/stratus_hls/conv2d_stratus/hw/src/sizes.h b/accelerators/stratus_hls/conv2d_stratus/hw/src/sizes.h index 90013aa905..bdec00950a 100644 --- a/accelerators/stratus_hls/conv2d_stratus/hw/src/sizes.h +++ b/accelerators/stratus_hls/conv2d_stratus/hw/src/sizes.h @@ -4,191 +4,229 @@ #ifndef __SIZES_H__ #define __SIZES_H__ -#define features_size(H, W, C) (H) * (W) * (C) -#define weights_size(H, W, CI, CO) (H) * (W) * (CI) * (CO) +#define features_size(H, W, C) (H) * (W) * (C) +#define weights_size(H, W, CI, CO) (H) * (W) * (CI) * (CO) #define patches_size(H, W, HW, WW, CI) (H) * (W) * (HW) * (WW) * (CI) /* conv1_1 */ -#define CONV1_1_F_HEIGHT 224 -#define CONV1_1_F_WIDTH 224 -#define CONV1_1_F_CHANNELS 3 +#define CONV1_1_F_HEIGHT 224 +#define CONV1_1_F_WIDTH 224 +#define CONV1_1_F_CHANNELS 3 -#define CONV1_1_W_HEIGHT 3 -#define CONV1_1_W_WIDTH 3 -#define CONV1_1_W_IN_CHANNELS 3 -#define CONV1_1_W_OUT_CHANNELS 64 +#define CONV1_1_W_HEIGHT 3 +#define CONV1_1_W_WIDTH 3 +#define CONV1_1_W_IN_CHANNELS 3 +#define CONV1_1_W_OUT_CHANNELS 64 #define CONV1_1_F_SIZE features_size(CONV1_1_F_HEIGHT, CONV1_1_F_WIDTH, CONV1_1_F_CHANNELS) -#define CONV1_1_W_SIZE weights_size(CONV1_1_W_HEIGHT, CONV1_1_W_WIDTH, CONV1_1_W_IN_CHANNELS, CONV1_1_W_OUT_CHANNELS) -#define CONV1_1_P_SIZE patches_size(CONV1_1_F_HEIGHT, CONV1_1_F_WIDTH, CONV1_1_W_HEIGHT, CONV1_1_W_WIDTH, CONV1_1_W_IN_CHANNELS) +#define CONV1_1_W_SIZE \ + weights_size(CONV1_1_W_HEIGHT, CONV1_1_W_WIDTH, CONV1_1_W_IN_CHANNELS, CONV1_1_W_OUT_CHANNELS) +#define CONV1_1_P_SIZE \ + patches_size(CONV1_1_F_HEIGHT, CONV1_1_F_WIDTH, CONV1_1_W_HEIGHT, CONV1_1_W_WIDTH, \ + CONV1_1_W_IN_CHANNELS) /* conv1_2 */ /* biggest features */ -#define CONV1_2_F_HEIGHT 224 -#define CONV1_2_F_WIDTH 224 -#define CONV1_2_F_CHANNELS 64 +#define CONV1_2_F_HEIGHT 224 +#define CONV1_2_F_WIDTH 224 +#define CONV1_2_F_CHANNELS 64 -#define CONV1_2_W_HEIGHT 3 -#define CONV1_2_W_WIDTH 3 -#define CONV1_2_W_IN_CHANNELS 64 -#define CONV1_2_W_OUT_CHANNELS 64 +#define CONV1_2_W_HEIGHT 3 +#define CONV1_2_W_WIDTH 3 +#define CONV1_2_W_IN_CHANNELS 64 +#define CONV1_2_W_OUT_CHANNELS 64 #define CONV1_2_F_SIZE features_size(CONV1_2_F_HEIGHT, CONV1_2_F_WIDTH, CONV1_2_F_CHANNELS) -#define CONV1_2_W_SIZE weights_size(CONV1_2_W_HEIGHT, CONV1_2_W_WIDTH, CONV1_2_W_IN_CHANNELS, CONV1_2_W_OUT_CHANNELS) -#define CONV1_2_P_SIZE patches_size(CONV1_2_F_HEIGHT, CONV1_2_F_WIDTH, CONV1_2_W_HEIGHT, CONV1_2_W_WIDTH, CONV1_2_W_IN_CHANNELS) +#define CONV1_2_W_SIZE \ + weights_size(CONV1_2_W_HEIGHT, CONV1_2_W_WIDTH, CONV1_2_W_IN_CHANNELS, CONV1_2_W_OUT_CHANNELS) +#define CONV1_2_P_SIZE \ + patches_size(CONV1_2_F_HEIGHT, CONV1_2_F_WIDTH, CONV1_2_W_HEIGHT, CONV1_2_W_WIDTH, \ + CONV1_2_W_IN_CHANNELS) /* conv2_1 */ -#define CONV2_1_F_HEIGHT 112 -#define CONV2_1_F_WIDTH 112 -#define CONV2_1_F_CHANNELS 64 +#define CONV2_1_F_HEIGHT 112 +#define CONV2_1_F_WIDTH 112 +#define CONV2_1_F_CHANNELS 64 -#define CONV2_1_W_HEIGHT 3 -#define CONV2_1_W_WIDTH 3 -#define CONV2_1_W_IN_CHANNELS 64 +#define CONV2_1_W_HEIGHT 3 +#define CONV2_1_W_WIDTH 3 +#define CONV2_1_W_IN_CHANNELS 64 #define CONV2_1_W_OUT_CHANNELS 128 #define CONV2_1_F_SIZE features_size(CONV2_1_F_HEIGHT, CONV2_1_F_WIDTH, CONV2_1_F_CHANNELS) -#define CONV2_1_W_SIZE weights_size(CONV2_1_W_HEIGHT, CONV2_1_W_WIDTH, CONV2_1_W_IN_CHANNELS, CONV2_1_W_OUT_CHANNELS) -#define CONV2_1_P_SIZE patches_size(CONV2_1_F_HEIGHT, CONV2_1_F_WIDTH, CONV2_1_W_HEIGHT, CONV2_1_W_WIDTH, CONV2_1_W_IN_CHANNELS) +#define CONV2_1_W_SIZE \ + weights_size(CONV2_1_W_HEIGHT, CONV2_1_W_WIDTH, CONV2_1_W_IN_CHANNELS, CONV2_1_W_OUT_CHANNELS) +#define CONV2_1_P_SIZE \ + patches_size(CONV2_1_F_HEIGHT, CONV2_1_F_WIDTH, CONV2_1_W_HEIGHT, CONV2_1_W_WIDTH, \ + CONV2_1_W_IN_CHANNELS) /* conv2_2 */ -#define CONV2_2_F_HEIGHT 112 -#define CONV2_2_F_WIDTH 112 -#define CONV2_2_F_CHANNELS 128 +#define CONV2_2_F_HEIGHT 112 +#define CONV2_2_F_WIDTH 112 +#define CONV2_2_F_CHANNELS 128 -#define CONV2_2_W_HEIGHT 3 -#define CONV2_2_W_WIDTH 3 +#define CONV2_2_W_HEIGHT 3 +#define CONV2_2_W_WIDTH 3 #define CONV2_2_W_IN_CHANNELS 128 #define CONV2_2_W_OUT_CHANNELS 128 #define CONV2_2_F_SIZE features_size(CONV2_2_F_HEIGHT, CONV2_2_F_WIDTH, CONV2_2_F_CHANNELS) -#define CONV2_2_W_SIZE weights_size(CONV2_2_W_HEIGHT, CONV2_2_W_WIDTH, CONV2_2_W_IN_CHANNELS, CONV2_2_W_OUT_CHANNELS) -#define CONV2_2_P_SIZE patches_size(CONV2_2_F_HEIGHT, CONV2_2_F_WIDTH, CONV2_2_W_HEIGHT, CONV2_2_W_WIDTH, CONV2_2_W_IN_CHANNELS) +#define CONV2_2_W_SIZE \ + weights_size(CONV2_2_W_HEIGHT, CONV2_2_W_WIDTH, CONV2_2_W_IN_CHANNELS, CONV2_2_W_OUT_CHANNELS) +#define CONV2_2_P_SIZE \ + patches_size(CONV2_2_F_HEIGHT, CONV2_2_F_WIDTH, CONV2_2_W_HEIGHT, CONV2_2_W_WIDTH, \ + CONV2_2_W_IN_CHANNELS) /* conv3_1 */ -#define CONV3_1_F_HEIGHT 56 -#define CONV3_1_F_WIDTH 56 -#define CONV3_1_F_CHANNELS 128 +#define CONV3_1_F_HEIGHT 56 +#define CONV3_1_F_WIDTH 56 +#define CONV3_1_F_CHANNELS 128 -#define CONV3_1_W_HEIGHT 3 -#define CONV3_1_W_WIDTH 3 -#define CONV3_1_W_IN_CHANNELS 128 -#define CONV3_1_W_OUT_CHANNELS 256 +#define CONV3_1_W_HEIGHT 3 +#define CONV3_1_W_WIDTH 3 +#define CONV3_1_W_IN_CHANNELS 128 +#define CONV3_1_W_OUT_CHANNELS 256 #define CONV3_1_F_SIZE features_size(CONV3_1_F_HEIGHT, CONV3_1_F_WIDTH, CONV3_1_F_CHANNELS) -#define CONV3_1_W_SIZE weights_size(CONV3_1_W_HEIGHT, CONV3_1_W_WIDTH, CONV3_1_W_IN_CHANNELS, CONV3_1_W_OUT_CHANNELS) -#define CONV3_1_P_SIZE patches_size(CONV3_1_F_HEIGHT, CONV3_1_F_WIDTH, CONV3_1_W_HEIGHT, CONV3_1_W_WIDTH, CONV3_1_W_IN_CHANNELS) +#define CONV3_1_W_SIZE \ + weights_size(CONV3_1_W_HEIGHT, CONV3_1_W_WIDTH, CONV3_1_W_IN_CHANNELS, CONV3_1_W_OUT_CHANNELS) +#define CONV3_1_P_SIZE \ + patches_size(CONV3_1_F_HEIGHT, CONV3_1_F_WIDTH, CONV3_1_W_HEIGHT, CONV3_1_W_WIDTH, \ + CONV3_1_W_IN_CHANNELS) /* conv3_2 */ -#define CONV3_2_F_HEIGHT 56 -#define CONV3_2_F_WIDTH 56 -#define CONV3_2_F_CHANNELS 256 +#define CONV3_2_F_HEIGHT 56 +#define CONV3_2_F_WIDTH 56 +#define CONV3_2_F_CHANNELS 256 -#define CONV3_2_W_HEIGHT 3 -#define CONV3_2_W_WIDTH 3 +#define CONV3_2_W_HEIGHT 3 +#define CONV3_2_W_WIDTH 3 #define CONV3_2_W_IN_CHANNELS 256 #define CONV3_2_W_OUT_CHANNELS 256 #define CONV3_2_F_SIZE features_size(CONV3_2_F_HEIGHT, CONV3_2_F_WIDTH, CONV3_2_F_CHANNELS) -#define CONV3_2_W_SIZE weights_size(CONV3_2_W_HEIGHT, CONV3_2_W_WIDTH, CONV3_2_W_IN_CHANNELS, CONV3_2_W_OUT_CHANNELS) -#define CONV3_2_P_SIZE patches_size(CONV3_2_F_HEIGHT, CONV3_2_F_WIDTH, CONV3_2_W_HEIGHT, CONV3_2_W_WIDTH, CONV3_2_W_IN_CHANNELS) +#define CONV3_2_W_SIZE \ + weights_size(CONV3_2_W_HEIGHT, CONV3_2_W_WIDTH, CONV3_2_W_IN_CHANNELS, CONV3_2_W_OUT_CHANNELS) +#define CONV3_2_P_SIZE \ + patches_size(CONV3_2_F_HEIGHT, CONV3_2_F_WIDTH, CONV3_2_W_HEIGHT, CONV3_2_W_WIDTH, \ + CONV3_2_W_IN_CHANNELS) /* conv3_3 */ -#define CONV3_3_F_HEIGHT 56 -#define CONV3_3_F_WIDTH 56 -#define CONV3_3_F_CHANNELS 256 +#define CONV3_3_F_HEIGHT 56 +#define CONV3_3_F_WIDTH 56 +#define CONV3_3_F_CHANNELS 256 -#define CONV3_3_W_HEIGHT 3 -#define CONV3_3_W_WIDTH 3 +#define CONV3_3_W_HEIGHT 3 +#define CONV3_3_W_WIDTH 3 #define CONV3_3_W_IN_CHANNELS 256 #define CONV3_3_W_OUT_CHANNELS 256 #define CONV3_3_F_SIZE features_size(CONV3_3_F_HEIGHT, CONV3_3_F_WIDTH, CONV3_3_F_CHANNELS) -#define CONV3_3_W_SIZE weights_size(CONV3_3_W_HEIGHT, CONV3_3_W_WIDTH, CONV3_3_W_IN_CHANNELS, CONV3_3_W_OUT_CHANNELS) -#define CONV3_3_P_SIZE patches_size(CONV3_3_F_HEIGHT, CONV3_3_F_WIDTH, CONV3_3_W_HEIGHT, CONV3_3_W_WIDTH, CONV3_3_W_IN_CHANNELS) +#define CONV3_3_W_SIZE \ + weights_size(CONV3_3_W_HEIGHT, CONV3_3_W_WIDTH, CONV3_3_W_IN_CHANNELS, CONV3_3_W_OUT_CHANNELS) +#define CONV3_3_P_SIZE \ + patches_size(CONV3_3_F_HEIGHT, CONV3_3_F_WIDTH, CONV3_3_W_HEIGHT, CONV3_3_W_WIDTH, \ + CONV3_3_W_IN_CHANNELS) /* conv4_1 */ -#define CONV4_1_F_HEIGHT 28 -#define CONV4_1_F_WIDTH 28 -#define CONV4_1_F_CHANNELS 256 +#define CONV4_1_F_HEIGHT 28 +#define CONV4_1_F_WIDTH 28 +#define CONV4_1_F_CHANNELS 256 -#define CONV4_1_W_HEIGHT 3 -#define CONV4_1_W_WIDTH 3 +#define CONV4_1_W_HEIGHT 3 +#define CONV4_1_W_WIDTH 3 #define CONV4_1_W_IN_CHANNELS 256 #define CONV4_1_W_OUT_CHANNELS 512 #define CONV4_1_F_SIZE features_size(CONV4_1_F_HEIGHT, CONV4_1_F_WIDTH, CONV4_1_F_CHANNELS) -#define CONV4_1_W_SIZE weights_size(CONV4_1_W_HEIGHT, CONV4_1_W_WIDTH, CONV4_1_W_IN_CHANNELS, CONV4_1_W_OUT_CHANNELS) -#define CONV4_1_P_SIZE patches_size(CONV4_1_F_HEIGHT, CONV4_1_F_WIDTH, CONV4_1_W_HEIGHT, CONV4_1_W_WIDTH, CONV4_1_W_IN_CHANNELS) +#define CONV4_1_W_SIZE \ + weights_size(CONV4_1_W_HEIGHT, CONV4_1_W_WIDTH, CONV4_1_W_IN_CHANNELS, CONV4_1_W_OUT_CHANNELS) +#define CONV4_1_P_SIZE \ + patches_size(CONV4_1_F_HEIGHT, CONV4_1_F_WIDTH, CONV4_1_W_HEIGHT, CONV4_1_W_WIDTH, \ + CONV4_1_W_IN_CHANNELS) /* conv4_2 */ /* biggest weights */ -#define CONV4_2_F_HEIGHT 28 -#define CONV4_2_F_WIDTH 28 -#define CONV4_2_F_CHANNELS 512 +#define CONV4_2_F_HEIGHT 28 +#define CONV4_2_F_WIDTH 28 +#define CONV4_2_F_CHANNELS 512 -#define CONV4_2_W_HEIGHT 3 -#define CONV4_2_W_WIDTH 3 +#define CONV4_2_W_HEIGHT 3 +#define CONV4_2_W_WIDTH 3 #define CONV4_2_W_IN_CHANNELS 512 #define CONV4_2_W_OUT_CHANNELS 512 #define CONV4_2_F_SIZE features_size(CONV4_2_F_HEIGHT, CONV4_2_F_WIDTH, CONV4_2_F_CHANNELS) -#define CONV4_2_W_SIZE weights_size(CONV4_2_W_HEIGHT, CONV4_2_W_WIDTH, CONV4_2_W_IN_CHANNELS, CONV4_2_W_OUT_CHANNELS) -#define CONV4_2_P_SIZE patches_size(CONV4_2_F_HEIGHT, CONV4_2_F_WIDTH, CONV4_2_W_HEIGHT, CONV4_2_W_WIDTH, CONV4_2_W_IN_CHANNELS) +#define CONV4_2_W_SIZE \ + weights_size(CONV4_2_W_HEIGHT, CONV4_2_W_WIDTH, CONV4_2_W_IN_CHANNELS, CONV4_2_W_OUT_CHANNELS) +#define CONV4_2_P_SIZE \ + patches_size(CONV4_2_F_HEIGHT, CONV4_2_F_WIDTH, CONV4_2_W_HEIGHT, CONV4_2_W_WIDTH, \ + CONV4_2_W_IN_CHANNELS) /* conv4_3 */ /* biggest weights */ -#define CONV4_3_F_HEIGHT 28 -#define CONV4_3_F_WIDTH 28 -#define CONV4_3_F_CHANNELS 512 +#define CONV4_3_F_HEIGHT 28 +#define CONV4_3_F_WIDTH 28 +#define CONV4_3_F_CHANNELS 512 -#define CONV4_3_W_HEIGHT 3 -#define CONV4_3_W_WIDTH 3 +#define CONV4_3_W_HEIGHT 3 +#define CONV4_3_W_WIDTH 3 #define CONV4_3_W_IN_CHANNELS 512 #define CONV4_3_W_OUT_CHANNELS 512 #define CONV4_3_F_SIZE features_size(CONV4_3_F_HEIGHT, CONV4_3_F_WIDTH, CONV4_3_F_CHANNELS) -#define CONV4_3_W_SIZE weights_size(CONV4_3_W_HEIGHT, CONV4_3_W_WIDTH, CONV4_3_W_IN_CHANNELS, CONV4_3_W_OUT_CHANNELS) -#define CONV4_3_P_SIZE patches_size(CONV4_3_F_HEIGHT, CONV4_3_F_WIDTH, CONV4_3_W_HEIGHT, CONV4_3_W_WIDTH, CONV4_3_W_IN_CHANNELS) +#define CONV4_3_W_SIZE \ + weights_size(CONV4_3_W_HEIGHT, CONV4_3_W_WIDTH, CONV4_3_W_IN_CHANNELS, CONV4_3_W_OUT_CHANNELS) +#define CONV4_3_P_SIZE \ + patches_size(CONV4_3_F_HEIGHT, CONV4_3_F_WIDTH, CONV4_3_W_HEIGHT, CONV4_3_W_WIDTH, \ + CONV4_3_W_IN_CHANNELS) /* conv5_1 */ /* biggest weights */ -#define CONV5_1_F_HEIGHT 14 -#define CONV5_1_F_WIDTH 14 -#define CONV5_1_F_CHANNELS 512 +#define CONV5_1_F_HEIGHT 14 +#define CONV5_1_F_WIDTH 14 +#define CONV5_1_F_CHANNELS 512 -#define CONV5_1_W_HEIGHT 3 -#define CONV5_1_W_WIDTH 3 +#define CONV5_1_W_HEIGHT 3 +#define CONV5_1_W_WIDTH 3 #define CONV5_1_W_IN_CHANNELS 512 #define CONV5_1_W_OUT_CHANNELS 512 #define CONV5_1_F_SIZE features_size(CONV5_1_F_HEIGHT, CONV5_1_F_WIDTH, CONV5_1_F_CHANNELS) -#define CONV5_1_W_SIZE weights_size(CONV5_1_W_HEIGHT, CONV5_1_W_WIDTH, CONV5_1_W_IN_CHANNELS, CONV5_1_W_OUT_CHANNELS) -#define CONV5_1_P_SIZE patches_size(CONV5_1_F_HEIGHT, CONV5_1_F_WIDTH, CONV5_1_W_HEIGHT, CONV5_1_W_WIDTH, CONV5_1_W_IN_CHANNELS) +#define CONV5_1_W_SIZE \ + weights_size(CONV5_1_W_HEIGHT, CONV5_1_W_WIDTH, CONV5_1_W_IN_CHANNELS, CONV5_1_W_OUT_CHANNELS) +#define CONV5_1_P_SIZE \ + patches_size(CONV5_1_F_HEIGHT, CONV5_1_F_WIDTH, CONV5_1_W_HEIGHT, CONV5_1_W_WIDTH, \ + CONV5_1_W_IN_CHANNELS) /* conv5_2 */ /* biggest weights */ -#define CONV5_2_F_HEIGHT 14 -#define CONV5_2_F_WIDTH 14 -#define CONV5_2_F_CHANNELS 512 +#define CONV5_2_F_HEIGHT 14 +#define CONV5_2_F_WIDTH 14 +#define CONV5_2_F_CHANNELS 512 -#define CONV5_2_W_HEIGHT 3 -#define CONV5_2_W_WIDTH 3 +#define CONV5_2_W_HEIGHT 3 +#define CONV5_2_W_WIDTH 3 #define CONV5_2_W_IN_CHANNELS 512 #define CONV5_2_W_OUT_CHANNELS 512 #define CONV5_2_F_SIZE features_size(CONV5_2_F_HEIGHT, CONV5_2_F_WIDTH, CONV5_2_F_CHANNELS) -#define CONV5_2_W_SIZE weights_size(CONV5_2_W_HEIGHT, CONV5_2_W_WIDTH, CONV5_2_W_IN_CHANNELS, CONV5_2_W_OUT_CHANNELS) -#define CONV5_2_P_SIZE patches_size(CONV5_2_F_HEIGHT, CONV5_2_F_WIDTH, CONV5_2_W_HEIGHT, CONV5_2_W_WIDTH, CONV5_2_W_IN_CHANNELS) +#define CONV5_2_W_SIZE \ + weights_size(CONV5_2_W_HEIGHT, CONV5_2_W_WIDTH, CONV5_2_W_IN_CHANNELS, CONV5_2_W_OUT_CHANNELS) +#define CONV5_2_P_SIZE \ + patches_size(CONV5_2_F_HEIGHT, CONV5_2_F_WIDTH, CONV5_2_W_HEIGHT, CONV5_2_W_WIDTH, \ + CONV5_2_W_IN_CHANNELS) /* conv5_3 */ /* biggest weights */ -#define CONV5_3_F_HEIGHT 14 -#define CONV5_3_F_WIDTH 14 -#define CONV5_3_F_CHANNELS 512 +#define CONV5_3_F_HEIGHT 14 +#define CONV5_3_F_WIDTH 14 +#define CONV5_3_F_CHANNELS 512 -#define CONV5_3_W_HEIGHT 3 -#define CONV5_3_W_WIDTH 3 +#define CONV5_3_W_HEIGHT 3 +#define CONV5_3_W_WIDTH 3 #define CONV5_3_W_IN_CHANNELS 512 #define CONV5_3_W_OUT_CHANNELS 512 #define CONV5_3_F_SIZE features_size(CONV5_3_F_HEIGHT, CONV5_3_F_WIDTH, CONV5_3_F_CHANNELS) -#define CONV5_3_W_SIZE weights_size(CONV5_3_W_HEIGHT, CONV5_3_W_WIDTH, CONV5_3_W_IN_CHANNELS, CONV5_3_W_OUT_CHANNELS) -#define CONV5_3_P_SIZE patches_size(CONV5_3_F_HEIGHT, CONV5_3_F_WIDTH, CONV5_3_W_HEIGHT, CONV5_3_W_WIDTH, CONV5_3_W_IN_CHANNELS) - +#define CONV5_3_W_SIZE \ + weights_size(CONV5_3_W_HEIGHT, CONV5_3_W_WIDTH, CONV5_3_W_IN_CHANNELS, CONV5_3_W_OUT_CHANNELS) +#define CONV5_3_P_SIZE \ + patches_size(CONV5_3_F_HEIGHT, CONV5_3_F_WIDTH, CONV5_3_W_HEIGHT, CONV5_3_W_WIDTH, \ + CONV5_3_W_IN_CHANNELS) #endif /* __SIZES_H__ */ diff --git a/accelerators/stratus_hls/conv2d_stratus/hw/tb/golden.cpp b/accelerators/stratus_hls/conv2d_stratus/hw/tb/golden.cpp index 116c6c914c..7de022c19d 100644 --- a/accelerators/stratus_hls/conv2d_stratus/hw/tb/golden.cpp +++ b/accelerators/stratus_hls/conv2d_stratus/hw/tb/golden.cpp @@ -4,24 +4,18 @@ #include "golden.hpp" #include -inline float max_of_4(float a, float b, float c, float d) { - if (a >= b && a >= c && a >= d) { - return a; - } - if (b >= c && b >= d) { - return b; - } - if (c >= d) { - return c; - } +inline float max_of_4(float a, float b, float c, float d) +{ + if (a >= b && a >= c && a >= d) { return a; } + if (b >= c && b >= d) { return b; } + if (c >= d) { return c; } return d; } -inline float avg_of_4(float a, float b, float c, float d) { - return (a + b + c + d) / 4; -} +inline float avg_of_4(float a, float b, float c, float d) { return (a + b + c + d) / 4; } -inline void pooling_2x2(float *in, float *out, unsigned size, bool type) { +inline void pooling_2x2(float *in, float *out, unsigned size, bool type) +{ assert(type >= 1 && type <= 2); @@ -29,86 +23,90 @@ inline void pooling_2x2(float *in, float *out, unsigned size, bool type) { float a, b, c, d; for (i = 0; i < size - 1; i += 2) { for (j = 0; j < size - 1; j += 2) { - a = in[i * size + j]; - b = in[(i + 1) * size + j]; - c = in[i * size + (j + 1)]; - d = in[(i + 1) * size + (j + 1)]; - out_i = (i / 2) * (size/2) + (j / 2); - // std::cout << "out_i " << out_i << std::endl; - if (type == 1) - out[out_i] = max_of_4(a, b, c, d); - else - out[out_i] = avg_of_4(a, b, c, d); + a = in[i * size + j]; + b = in[(i + 1) * size + j]; + c = in[i * size + (j + 1)]; + d = in[(i + 1) * size + (j + 1)]; + out_i = (i / 2) * (size / 2) + (j / 2); + // std::cout << "out_i " << out_i << std::endl; + if (type == 1) out[out_i] = max_of_4(a, b, c, d); + else + out[out_i] = avg_of_4(a, b, c, d); - // std::cout << - // " a " << a << - // " b " << b << - // " c " << c << - // " d " << d << - // " out " << out[out_i] << - // " i " << i << - // " j " << j << - // std::endl; - } + // std::cout << + // " a " << a << + // " b " << b << + // " c " << c << + // " d " << d << + // " out " << out[out_i] << + // " i " << i << + // " j " << j << + // std::endl; + } } } -void sw_conv_layer ( - const float* input, const int channels, const int height, const int width, - const int kernel_h, const int kernel_w, const int pad_h, const int pad_w, - const int stride_h, const int stride_w, const int dilation_h, const int dilation_w, - const int num_filters, const float* weights, const float* biases, float* output, - const bool do_relu, const int pool_type, const int batch_size) +void sw_conv_layer(const float *input, const int channels, const int height, const int width, + const int kernel_h, const int kernel_w, const int pad_h, const int pad_w, + const int stride_h, const int stride_w, const int dilation_h, + const int dilation_w, const int num_filters, const float *weights, + const float *biases, float *output, const bool do_relu, const int pool_type, + const int batch_size) { const int channel_size = round_up(height * width, DMA_WORD_PER_BEAT); - const int filter_size = channels * kernel_w * kernel_h; + const int filter_size = channels * kernel_w * kernel_h; const int output_h = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1; const int output_w = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1; - const int out_channel_size = round_up(output_w * output_h, DMA_WORD_PER_BEAT); - const int pool_channel_size = round_up((output_w/2) * (output_h/2), DMA_WORD_PER_BEAT); + const int out_channel_size = round_up(output_w * output_h, DMA_WORD_PER_BEAT); + const int pool_channel_size = round_up((output_w / 2) * (output_h / 2), DMA_WORD_PER_BEAT); - for (int batch_i = 0; batch_i < batch_size; batch_i++) { - for (int num_filter = 0; num_filter < num_filters; num_filter++) { - for (int output_row = 0; output_row < output_h; output_row++) { - for (int output_col = 0; output_col< output_w; output_col++) { - int k = 0; - float out_value = 0; - for (int channel = 0; channel < channels; channel++) { - for (int kernel_row = 0; kernel_row < kernel_h; kernel_row++) { - for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) { - int input_row = (output_row * stride_h) - pad_h + kernel_row * dilation_h; - int input_col = (output_col * stride_w) - pad_w + kernel_col * dilation_w; - if (!(!sw_is_a_ge_zero_and_a_lt_b(input_row, height) || - (sw_is_a_ge_zero_and_a_lt_b(input_row, height) && - !sw_is_a_ge_zero_and_a_lt_b(input_col, width)))) { - out_value += input[batch_i * channels * channel_size + channel * channel_size + - input_row * width + input_col] * - weights[num_filter * filter_size + k]; - } - k++; - } - } - } - out_value += biases[num_filter]; + for (int batch_i = 0; batch_i < batch_size; batch_i++) { + for (int num_filter = 0; num_filter < num_filters; num_filter++) { + for (int output_row = 0; output_row < output_h; output_row++) { + for (int output_col = 0; output_col < output_w; output_col++) { + int k = 0; + float out_value = 0; + for (int channel = 0; channel < channels; channel++) { + for (int kernel_row = 0; kernel_row < kernel_h; kernel_row++) { + for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) { + int input_row = + (output_row * stride_h) - pad_h + kernel_row * dilation_h; + int input_col = + (output_col * stride_w) - pad_w + kernel_col * dilation_w; + if (!(!sw_is_a_ge_zero_and_a_lt_b(input_row, height) || + (sw_is_a_ge_zero_and_a_lt_b(input_row, height) && + !sw_is_a_ge_zero_and_a_lt_b(input_col, width)))) { + out_value += input[batch_i * channels * channel_size + + channel * channel_size + input_row * width + + input_col] * + weights[num_filter * filter_size + k]; + } + k++; + } + } + } + out_value += biases[num_filter]; - if (do_relu && out_value < 0) - out_value = 0; + if (do_relu && out_value < 0) out_value = 0; - output[batch_i * num_filters * out_channel_size + num_filter * out_channel_size + - output_row * output_w + output_col] = out_value; + output[batch_i * num_filters * out_channel_size + + num_filter * out_channel_size + output_row * output_w + output_col] = + out_value; - // std::cout << "out_value[" << num_filter << "," << output_row << - // "," << output_col << "]: " << out_value << std::endl; - } - } + // std::cout << "out_value[" << num_filter << "," << output_row << + // "," << output_col << "]: " << out_value << std::endl; + } + } - // std::cout << "pool_channel_size " << pool_channel_size << std::endl; + // std::cout << "pool_channel_size " << pool_channel_size << std::endl; - if (pool_type) - pooling_2x2(&output[batch_i * num_filters * out_channel_size + num_filter * out_channel_size], - &output[batch_i * num_filters * pool_channel_size + num_filter * pool_channel_size], - output_w, pool_type); - } + if (pool_type) + pooling_2x2(&output[batch_i * num_filters * out_channel_size + + num_filter * out_channel_size], + &output[batch_i * num_filters * pool_channel_size + + num_filter * pool_channel_size], + output_w, pool_type); + } } } diff --git a/accelerators/stratus_hls/conv2d_stratus/sw/baremetal/conv2d.c b/accelerators/stratus_hls/conv2d_stratus/sw/baremetal/conv2d.c index d1057dc60c..9352c3829f 100644 --- a/accelerators/stratus_hls/conv2d_stratus/sw/baremetal/conv2d.c +++ b/accelerators/stratus_hls/conv2d_stratus/sw/baremetal/conv2d.c @@ -3,7 +3,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -20,51 +20,51 @@ // Define bit width (decomment the one needed) #ifndef __riscv -#define BITWIDTH 32 + #define BITWIDTH 32 // #define BITWIDTH 64 #else -#define BITWIDTH 32 + #define BITWIDTH 32 //#define BITWIDTH 64 #endif /* End of user defined */ #ifdef __UINT -#if (BITWIDTH == 32) + #if (BITWIDTH == 32) typedef unsigned token_t; -#elif (BITWIDTH == 64) + #elif (BITWIDTH == 64) typedef long long unsigned token_t; -#endif + #endif #endif #ifdef __INT -#if (BITWIDTH == 32) + #if (BITWIDTH == 32) typedef int token_t; -#elif (BITWIDTH == 64) + #elif (BITWIDTH == 64) typedef long long token_t; -#endif + #endif #endif #ifdef __FIXED -#if (BITWIDTH == 32) + #if (BITWIDTH == 32) typedef int token_t; -#define fx2float fixed32_to_float -#define float2fx float_to_fixed32 -#define FX_IL 16 -#elif (BITWIDTH == 64) + #define fx2float fixed32_to_float + #define float2fx float_to_fixed32 + #define FX_IL 16 + #elif (BITWIDTH == 64) typedef long long token_t; -#define fx2float fixed64_to_double -#define float2fx double_to_fixed64 -#define FX_IL 32 -#endif + #define fx2float fixed64_to_double + #define float2fx double_to_fixed64 + #define FX_IL 32 + #endif #endif #ifdef __FLOAT -#if (BITWIDTH == 32) + #if (BITWIDTH == 32) typedef float token_t; -#elif (BITWIDTH == 64) + #elif (BITWIDTH == 64) typedef double token_t; -#endif + #endif #endif #if (BITWIDTH == 32) @@ -73,33 +73,30 @@ typedef float native_t; typedef double native_t; #endif -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } -#define MAX_PRINTED_ERRORS 10 +#define MAX_PRINTED_ERRORS 10 #define REL_ERROR_THRESHOLD 0.01 -#define SLD_CONV2D 0x052 -#define DEV_NAME "sld,conv2d_stratus" +#define SLD_CONV2D 0x052 +#define DEV_NAME "sld,conv2d_stratus" /* <<--params-->> */ -const int32_t n_channels = 2; +const int32_t n_channels = 2; const int32_t feature_map_height = 6; -const int32_t feature_map_width = 6; -const int32_t n_filters = 2; -const int32_t filter_height = 3; -const int32_t filter_width = 3; -const int32_t pad_h = 1; -const int32_t pad_w = 1; -const int32_t is_padded = 1; -const int32_t stride_h = 1; -const int32_t stride_w = 1; -const int32_t dilation_h = 1; -const int32_t dilation_w = 1; -const int32_t do_relu = 0; -const int32_t pool_type = 0; -const int32_t batch_size = 1; +const int32_t feature_map_width = 6; +const int32_t n_filters = 2; +const int32_t filter_height = 3; +const int32_t filter_width = 3; +const int32_t pad_h = 1; +const int32_t pad_w = 1; +const int32_t is_padded = 1; +const int32_t stride_h = 1; +const int32_t stride_w = 1; +const int32_t dilation_h = 1; +const int32_t dilation_w = 1; +const int32_t do_relu = 0; +const int32_t pool_type = 0; +const int32_t batch_size = 1; static unsigned in_words_adj; static unsigned weights_words_adj; @@ -120,212 +117,202 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ -#define CONV2D_N_CHANNELS_REG 0x40 +#define CONV2D_N_CHANNELS_REG 0x40 #define CONV2D_FEATURE_MAP_HEIGHT_REG 0x44 -#define CONV2D_FEATURE_MAP_WIDTH_REG 0x48 -#define CONV2D_N_FILTERS_REG 0x4c -#define CONV2D_FILTER_DIM_REG 0x50 -#define CONV2D_IS_PADDED_REG 0x54 -#define CONV2D_STRIDE_REG 0x58 -#define CONV2D_DO_RELU_REG 0x5c -#define CONV2D_POOL_TYPE_REG 0x60 -#define CONV2D_BATCH_SIZE_REG 0x64 +#define CONV2D_FEATURE_MAP_WIDTH_REG 0x48 +#define CONV2D_N_FILTERS_REG 0x4c +#define CONV2D_FILTER_DIM_REG 0x50 +#define CONV2D_IS_PADDED_REG 0x54 +#define CONV2D_STRIDE_REG 0x58 +#define CONV2D_DO_RELU_REG 0x5c +#define CONV2D_POOL_TYPE_REG 0x60 +#define CONV2D_BATCH_SIZE_REG 0x64 static int validate_buf(token_t *out, native_t *gold) { - int j; - native_t val; - unsigned errors = 0; + int j; + native_t val; + unsigned errors = 0; - for (j = 0; j < out_len; j++) { + for (j = 0; j < out_len; j++) { #ifdef __FIXED - val = fx2float(out[j], FX_IL); + val = fx2float(out[j], FX_IL); #else - val = out[j]; + val = out[j]; #endif - if (!gold[j] && val || - (((gold[j] - val) / gold[j]) > REL_ERROR_THRESHOLD || - ((gold[j] - val) / gold[j]) < -REL_ERROR_THRESHOLD)) - { - errors++; - if (errors <= MAX_PRINTED_ERRORS) { - printf("%d : %d\n", (int) val, (int) gold[j]); - } - } - } - - return errors; + if (!gold[j] && val || + (((gold[j] - val) / gold[j]) > REL_ERROR_THRESHOLD || + ((gold[j] - val) / gold[j]) < -REL_ERROR_THRESHOLD)) { + errors++; + if (errors <= MAX_PRINTED_ERRORS) { printf("%d : %d\n", (int)val, (int)gold[j]); } + } + } + + return errors; } - -static void init_buf (token_t *in, native_t * gold) +static void init_buf(token_t *in, native_t *gold) { -#include "input.h" #include "gold.h" +#include "input.h" - int i, size; + int i, size; size = (n_channels * feature_map_height * feature_map_width) + - (n_channels * n_filters * filter_height * filter_width) + - n_filters; + (n_channels * n_filters * filter_height * filter_width) + n_filters; } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable; - token_t *mem; - native_t *gold; - unsigned errors = 0; - unsigned coherence; - - // Input data and golden output (aligned to DMA_WIDTH makes your life easier) - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = n_channels * feature_map_height * feature_map_width; - weights_words_adj = n_filters * n_channels * filter_height * filter_width; - bias_words_adj = n_filters; - out_words_adj = n_filters * feature_map_height * feature_map_width; - } else { - in_words_adj = round_up(n_channels * feature_map_height * feature_map_width, - DMA_WORD_PER_BEAT(sizeof(token_t))); - weights_words_adj = round_up(n_filters * n_channels * filter_height * filter_width, - DMA_WORD_PER_BEAT(sizeof(token_t))); - bias_words_adj = round_up(n_filters, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(n_filters * feature_map_height * feature_map_width, - DMA_WORD_PER_BEAT(sizeof(token_t))); - } - - in_len = in_words_adj * (1); - weights_len = weights_words_adj * (1); - bias_len = bias_words_adj * (1); - out_len = out_words_adj * (1); - in_size = in_len * sizeof(token_t); - weights_size = weights_len * sizeof(token_t); - bias_size = bias_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - weights_offset = in_len; - bias_offset = in_len + weights_len; - out_offset = in_len + weights_len + bias_len; - mem_size = in_size + weights_size + bias_len + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_CONV2D, DEV_NAME); - if (ndev == 0) { - printf("conv2d not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_size); - mem = aligned_malloc(mem_size); - - printf(" memory buffer base-address = %p\n", mem); - - // Allocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable; + token_t *mem; + native_t *gold; + unsigned errors = 0; + unsigned coherence; + + // Input data and golden output (aligned to DMA_WIDTH makes your life easier) + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = n_channels * feature_map_height * feature_map_width; + weights_words_adj = n_filters * n_channels * filter_height * filter_width; + bias_words_adj = n_filters; + out_words_adj = n_filters * feature_map_height * feature_map_width; + } + else { + in_words_adj = round_up(n_channels * feature_map_height * feature_map_width, + DMA_WORD_PER_BEAT(sizeof(token_t))); + weights_words_adj = round_up(n_filters * n_channels * filter_height * filter_width, + DMA_WORD_PER_BEAT(sizeof(token_t))); + bias_words_adj = round_up(n_filters, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(n_filters * feature_map_height * feature_map_width, + DMA_WORD_PER_BEAT(sizeof(token_t))); + } + + in_len = in_words_adj * (1); + weights_len = weights_words_adj * (1); + bias_len = bias_words_adj * (1); + out_len = out_words_adj * (1); + in_size = in_len * sizeof(token_t); + weights_size = weights_len * sizeof(token_t); + bias_size = bias_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + weights_offset = in_len; + bias_offset = in_len + weights_len; + out_offset = in_len + weights_len + bias_len; + mem_size = in_size + weights_size + bias_len + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_CONV2D, DEV_NAME); + if (ndev == 0) { + printf("conv2d not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_size); + mem = aligned_malloc(mem_size); + + printf(" memory buffer base-address = %p\n", mem); + + // Allocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - - printf(" Generate input...\n"); - - init_buf(mem, gold); - - // Pass common configuration parameters - - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); - - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - iowrite32(dev, CONV2D_N_CHANNELS_REG, n_channels); - iowrite32(dev, CONV2D_FEATURE_MAP_HEIGHT_REG, feature_map_height); - iowrite32(dev, CONV2D_FEATURE_MAP_WIDTH_REG, feature_map_width); - iowrite32(dev, CONV2D_N_FILTERS_REG, n_filters); - iowrite32(dev, CONV2D_FILTER_DIM_REG, filter_height); - iowrite32(dev, CONV2D_IS_PADDED_REG, is_padded); - iowrite32(dev, CONV2D_STRIDE_REG, stride_w); - iowrite32(dev, CONV2D_DO_RELU_REG, do_relu); - iowrite32(dev, CONV2D_POOL_TYPE_REG, pool_type); - iowrite32(dev, CONV2D_BATCH_SIZE_REG, batch_size); - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + + printf(" Generate input...\n"); + + init_buf(mem, gold); + + // Pass common configuration parameters + + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); + + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + iowrite32(dev, CONV2D_N_CHANNELS_REG, n_channels); + iowrite32(dev, CONV2D_FEATURE_MAP_HEIGHT_REG, feature_map_height); + iowrite32(dev, CONV2D_FEATURE_MAP_WIDTH_REG, feature_map_width); + iowrite32(dev, CONV2D_N_FILTERS_REG, n_filters); + iowrite32(dev, CONV2D_FILTER_DIM_REG, filter_height); + iowrite32(dev, CONV2D_IS_PADDED_REG, is_padded); + iowrite32(dev, CONV2D_STRIDE_REG, stride_w); + iowrite32(dev, CONV2D_DO_RELU_REG, do_relu); + iowrite32(dev, CONV2D_POOL_TYPE_REG, pool_type); + iowrite32(dev, CONV2D_BATCH_SIZE_REG, batch_size); + + // Flush (customize coherence model here) + esp_flush(coherence); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/accelerators/stratus_hls/conv2d_stratus/sw/linux/app/conv2d.c b/accelerators/stratus_hls/conv2d_stratus/sw/linux/app/conv2d.c index 861ab4781b..9915327b71 100644 --- a/accelerators/stratus_hls/conv2d_stratus/sw/linux/app/conv2d.c +++ b/accelerators/stratus_hls/conv2d_stratus/sw/linux/app/conv2d.c @@ -1,7 +1,7 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include "libesp.h" #include "cfg.h" +#include "libesp.h" /* User-defined code */ static void validate_buffer(token_t *acc_buf, native_t *sw_buf, unsigned len) @@ -15,21 +15,21 @@ static void validate_buffer(token_t *acc_buf, native_t *sw_buf, unsigned len) for (i = 0; i < len; i++) { #ifdef __FIXED - val = fx2float(acc_buf[i], FX_IL); + val = fx2float(acc_buf[i], FX_IL); #else - val = acc_buf[i]; + val = acc_buf[i]; #endif - if (sw_buf[i] != val) { - errors++; - if (errors <= MAX_PRINTED_ERRORS) - printf("index %d : output %d : expected %d <-- ERROR\n", i, (int) val, (int) sw_buf[i]); - } + if (sw_buf[i] != val) { + errors++; + if (errors <= MAX_PRINTED_ERRORS) + printf("index %d : output %d : expected %d <-- ERROR\n", i, (int)val, + (int)sw_buf[i]); + } } - if (!errors) - printf("\n ** Test PASSED! **\n"); + if (!errors) printf("\n ** Test PASSED! **\n"); else - printf("\n ** Test FAILED! **\n"); + printf("\n ** Test FAILED! **\n"); } /* User-defined code */ @@ -40,22 +40,24 @@ static void init_buffer(token_t *acc_buf, native_t *sw_buf, unsigned in_len) printf(" Initialize inputs\n"); for (i = 0; i < in_len; i++) { - native_t val = i % 17 - 8; + native_t val = i % 17 - 8; #ifdef __FIXED acc_buf[i] = float2fx(val, FX_IL); #else acc_buf[i] = val; #endif - sw_buf[i] = val; + sw_buf[i] = val; } } -static void init_parameters(int test, int32_t n_channels, int32_t feature_map_height, int32_t feature_map_width, - int32_t n_filters, int32_t filter_dim, int32_t is_padded, - int32_t stride, int32_t do_relu, int32_t pool_type, int32_t batch_size, - unsigned *in_len, unsigned *weights_len, unsigned *bias_len, unsigned *out_len, - unsigned *in_size, unsigned *weights_size, unsigned *bias_size, unsigned *out_size, - unsigned *weights_offset, unsigned *bias_offset, unsigned *out_offset, unsigned *size) +static void init_parameters(int test, int32_t n_channels, int32_t feature_map_height, + int32_t feature_map_width, int32_t n_filters, int32_t filter_dim, + int32_t is_padded, int32_t stride, int32_t do_relu, int32_t pool_type, + int32_t batch_size, unsigned *in_len, unsigned *weights_len, + unsigned *bias_len, unsigned *out_len, unsigned *in_size, + unsigned *weights_size, unsigned *bias_size, unsigned *out_size, + unsigned *weights_offset, unsigned *bias_offset, unsigned *out_offset, + unsigned *size) { int32_t output_h; // int32_t output_w; @@ -63,38 +65,43 @@ static void init_parameters(int test, int32_t n_channels, int32_t feature_map_he // int32_t output_pool_w; int32_t pad_dim = 0; - if (is_padded) { - pad_dim = filter_dim / 2; - } + if (is_padded) { pad_dim = filter_dim / 2; } - output_h = (feature_map_height + 2 * pad_dim - ((filter_dim - 1) + 1)) / stride + 1; + output_h = (feature_map_height + 2 * pad_dim - ((filter_dim - 1) + 1)) / stride + 1; output_pool_h = pool_type ? output_h / 2 : output_h; // Input data and golden output (aligned to DMA_WIDTH makes your life easier) - *in_len = round_up(batch_size * round_up(n_channels * round_up(feature_map_height * feature_map_width, DMA_RATIO), DMA_RATIO), DMA_RATIO); + *in_len = round_up( + batch_size * + round_up(n_channels * round_up(feature_map_height * feature_map_width, DMA_RATIO), + DMA_RATIO), + DMA_RATIO); *weights_len = round_up(n_filters * n_channels * filter_dim * filter_dim, DMA_RATIO); - *bias_len = round_up(n_filters, DMA_RATIO); - *out_len = round_up(batch_size * round_up(n_filters * round_up(output_pool_h * output_pool_h, DMA_RATIO), DMA_RATIO), DMA_RATIO); - - *in_size = *in_len * sizeof(token_t); - *weights_size = *weights_len * sizeof(token_t); - *bias_size = *bias_len * sizeof(token_t); - *out_size = *out_len * sizeof(token_t); + *bias_len = round_up(n_filters, DMA_RATIO); + *out_len = round_up( + batch_size * + round_up(n_filters * round_up(output_pool_h * output_pool_h, DMA_RATIO), DMA_RATIO), + DMA_RATIO); + + *in_size = *in_len * sizeof(token_t); + *weights_size = *weights_len * sizeof(token_t); + *bias_size = *bias_len * sizeof(token_t); + *out_size = *out_len * sizeof(token_t); *weights_offset = *in_len; - *bias_offset = *in_len + *weights_len; - *out_offset = *in_len + *weights_len + *bias_len; - *size = *in_size + *weights_size + *bias_size + *out_size; + *bias_offset = *in_len + *weights_len; + *out_offset = *in_len + *weights_len + *bias_len; + *size = *in_size + *weights_size + *bias_size + *out_size; - conv2d_cfg_000[0].n_channels = n_channels; + conv2d_cfg_000[0].n_channels = n_channels; conv2d_cfg_000[0].feature_map_height = feature_map_height; - conv2d_cfg_000[0].feature_map_width = feature_map_width; - conv2d_cfg_000[0].n_filters = n_filters; - conv2d_cfg_000[0].filter_dim = filter_dim; - conv2d_cfg_000[0].is_padded = is_padded; - conv2d_cfg_000[0].stride = stride; - conv2d_cfg_000[0].do_relu = do_relu; - conv2d_cfg_000[0].pool_type = pool_type; - conv2d_cfg_000[0].batch_size = batch_size; + conv2d_cfg_000[0].feature_map_width = feature_map_width; + conv2d_cfg_000[0].n_filters = n_filters; + conv2d_cfg_000[0].filter_dim = filter_dim; + conv2d_cfg_000[0].is_padded = is_padded; + conv2d_cfg_000[0].stride = stride; + conv2d_cfg_000[0].do_relu = do_relu; + conv2d_cfg_000[0].pool_type = pool_type; + conv2d_cfg_000[0].batch_size = batch_size; // print test info printf(" Prepare test %d parameters\n", test); @@ -110,28 +117,20 @@ static void init_parameters(int test, int32_t n_channels, int32_t feature_map_he printf(" .batch_size = %d\n", batch_size); } -inline bool sw_is_a_ge_zero_and_a_lt_b(int a, int b) { - return (a >= 0 && a < b); -} +inline bool sw_is_a_ge_zero_and_a_lt_b(int a, int b) { return (a >= 0 && a < b); } -inline float max_of_4(float a, float b, float c, float d) { - if (a >= b && a >= c && a >= d) { - return a; - } - if (b >= c && b >= d) { - return b; - } - if (c >= d) { - return c; - } +inline float max_of_4(float a, float b, float c, float d) +{ + if (a >= b && a >= c && a >= d) { return a; } + if (b >= c && b >= d) { return b; } + if (c >= d) { return c; } return d; } -inline float avg_of_4(float a, float b, float c, float d) { - return (a + b + c + d) / 4; -} +inline float avg_of_4(float a, float b, float c, float d) { return (a + b + c + d) / 4; } -inline void pooling_2x2(float *in, float *out, unsigned size, unsigned type) { +inline void pooling_2x2(float *in, float *out, unsigned size, unsigned type) +{ assert(type >= 1 && type <= 2); @@ -139,91 +138,93 @@ inline void pooling_2x2(float *in, float *out, unsigned size, unsigned type) { float a, b, c, d; for (i = 0; i < size - 1; i += 2) { for (j = 0; j < size - 1; j += 2) { - a = in[i * size + j]; - b = in[(i + 1) * size + j]; - c = in[i * size + (j + 1)]; - d = in[(i + 1) * size + (j + 1)]; - out_i = (i / 2) * (size/2) + (j / 2); - if (type == 1) - out[out_i] = max_of_4(a, b, c, d); - else - out[out_i] = avg_of_4(a, b, c, d); - } + a = in[i * size + j]; + b = in[(i + 1) * size + j]; + c = in[i * size + (j + 1)]; + d = in[(i + 1) * size + (j + 1)]; + out_i = (i / 2) * (size / 2) + (j / 2); + if (type == 1) out[out_i] = max_of_4(a, b, c, d); + else + out[out_i] = avg_of_4(a, b, c, d); + } } } -void sw_conv_layer ( - const float* input, const int channels, const int height, const int width, - const int kernel_h, const int kernel_w, const int pad_h, const int pad_w, - const int stride_h, const int stride_w, const int dilation_h, const int dilation_w, - const int num_filters, const float* weights, const float* biases, float* output, - const bool do_relu, const int pool_type, const int batch_size) +void sw_conv_layer(const float *input, const int channels, const int height, const int width, + const int kernel_h, const int kernel_w, const int pad_h, const int pad_w, + const int stride_h, const int stride_w, const int dilation_h, + const int dilation_w, const int num_filters, const float *weights, + const float *biases, float *output, const bool do_relu, const int pool_type, + const int batch_size) { const int channel_size = round_up(height * width, DMA_RATIO); - const int filter_size = channels * kernel_w * kernel_h; + const int filter_size = channels * kernel_w * kernel_h; const int output_h = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1; const int output_w = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1; - const int out_channel_size = round_up(output_w * output_h, DMA_RATIO); - const int pool_channel_size = round_up((output_w/2) * (output_h/2), DMA_RATIO); - - for (int batch_i = 0; batch_i < batch_size; batch_i++) { - for (int num_filter = 0; num_filter < num_filters; num_filter++) { - for (int output_row = 0; output_row < output_h; output_row++) { - for (int output_col = 0; output_col< output_w; output_col++) { - int k = 0; - float out_value = 0; - for (int channel = 0; channel < channels; channel++) { - for (int kernel_row = 0; kernel_row < kernel_h; kernel_row++) { - for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) { - int input_row = (output_row * stride_h) - pad_h + kernel_row * dilation_h; - int input_col = (output_col * stride_w) - pad_w + kernel_col * dilation_w; - if (!(!sw_is_a_ge_zero_and_a_lt_b(input_row, height) || - (sw_is_a_ge_zero_and_a_lt_b(input_row, height) && - !sw_is_a_ge_zero_and_a_lt_b(input_col, width)))) { - out_value += input[batch_i * channels * channel_size + channel * channel_size + - input_row * width + input_col] * - weights[num_filter * filter_size + k]; - } - k++; - } - } - } - out_value += biases[num_filter]; - - if (do_relu && out_value < 0) - out_value = 0; - - output[batch_i * num_filters * out_channel_size + num_filter * out_channel_size + - output_row * output_w + output_col] = out_value; - } - } - - if (pool_type) - pooling_2x2(&output[batch_i * num_filters * out_channel_size + num_filter * out_channel_size], - &output[batch_i * num_filters * pool_channel_size + num_filter * pool_channel_size], - output_w, pool_type); - } + const int out_channel_size = round_up(output_w * output_h, DMA_RATIO); + const int pool_channel_size = round_up((output_w / 2) * (output_h / 2), DMA_RATIO); + + for (int batch_i = 0; batch_i < batch_size; batch_i++) { + for (int num_filter = 0; num_filter < num_filters; num_filter++) { + for (int output_row = 0; output_row < output_h; output_row++) { + for (int output_col = 0; output_col < output_w; output_col++) { + int k = 0; + float out_value = 0; + for (int channel = 0; channel < channels; channel++) { + for (int kernel_row = 0; kernel_row < kernel_h; kernel_row++) { + for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) { + int input_row = + (output_row * stride_h) - pad_h + kernel_row * dilation_h; + int input_col = + (output_col * stride_w) - pad_w + kernel_col * dilation_w; + if (!(!sw_is_a_ge_zero_and_a_lt_b(input_row, height) || + (sw_is_a_ge_zero_and_a_lt_b(input_row, height) && + !sw_is_a_ge_zero_and_a_lt_b(input_col, width)))) { + out_value += input[batch_i * channels * channel_size + + channel * channel_size + input_row * width + + input_col] * + weights[num_filter * filter_size + k]; + } + k++; + } + } + } + out_value += biases[num_filter]; + + if (do_relu && out_value < 0) out_value = 0; + + output[batch_i * num_filters * out_channel_size + + num_filter * out_channel_size + output_row * output_w + output_col] = + out_value; + } + } + + if (pool_type) + pooling_2x2(&output[batch_i * num_filters * out_channel_size + + num_filter * out_channel_size], + &output[batch_i * num_filters * pool_channel_size + + num_filter * pool_channel_size], + output_w, pool_type); + } } } static void sw_run(int32_t n_channels, int32_t feature_map_height, int32_t feature_map_width, - int32_t n_filters, int32_t filter_dim, int32_t is_padded, int32_t stride, - int32_t do_relu, int32_t pool_type, int32_t batch_size, - native_t *in, native_t *weights, native_t *bias, native_t *out) + int32_t n_filters, int32_t filter_dim, int32_t is_padded, int32_t stride, + int32_t do_relu, int32_t pool_type, int32_t batch_size, native_t *in, + native_t *weights, native_t *bias, native_t *out) { struct timespec th_start, th_end; int32_t pad_dim = 0; - if (is_padded) { - pad_dim = filter_dim / 2; - } + if (is_padded) { pad_dim = filter_dim / 2; } gettime(&th_start); sw_conv_layer(in, n_channels, feature_map_height, feature_map_width, filter_dim, filter_dim, - pad_dim, pad_dim, stride, stride, 1, 1, n_filters, weights, bias, out, - do_relu, pool_type, batch_size); + pad_dim, pad_dim, stride, stride, 1, 1, n_filters, weights, bias, out, do_relu, + pool_type, batch_size); gettime(&th_end); @@ -242,80 +243,77 @@ int main(int argc, char **argv) token_t *acc_buf; native_t *sw_buf; - int32_t n_channels [MAX_TESTS] = {16, 2, 2, 2, 64, 3, 4, 2, 4, 2}; - int32_t feature_map_height [MAX_TESTS] = { 8, 6, 14, 14, 32, 220, 32, 64, 8, 6}; - int32_t feature_map_width [MAX_TESTS] = { 8, 6, 14, 14, 32, 220, 32, 64, 8, 6}; - int32_t n_filters [MAX_TESTS] = {16, 2, 128, 16, 128, 2, 2, 2, 2, 4}; - int32_t filter_dim [MAX_TESTS] = { 3, 5, 1, 1, 1, 3, 3, 3, 3, 3}; - int32_t is_padded [MAX_TESTS] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - int32_t stride [MAX_TESTS] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - int32_t do_relu [MAX_TESTS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int32_t pool_type [MAX_TESTS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int32_t batch_size [MAX_TESTS] = { 1, 1, 1, 1, 1, 1, 4, 8, 12, 16}; + int32_t n_channels[MAX_TESTS] = {16, 2, 2, 2, 64, 3, 4, 2, 4, 2}; + int32_t feature_map_height[MAX_TESTS] = {8, 6, 14, 14, 32, 220, 32, 64, 8, 6}; + int32_t feature_map_width[MAX_TESTS] = {8, 6, 14, 14, 32, 220, 32, 64, 8, 6}; + int32_t n_filters[MAX_TESTS] = {16, 2, 128, 16, 128, 2, 2, 2, 2, 4}; + int32_t filter_dim[MAX_TESTS] = {3, 5, 1, 1, 1, 3, 3, 3, 3, 3}; + int32_t is_padded[MAX_TESTS] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + int32_t stride[MAX_TESTS] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + int32_t do_relu[MAX_TESTS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int32_t pool_type[MAX_TESTS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int32_t batch_size[MAX_TESTS] = {1, 1, 1, 1, 1, 1, 4, 8, 12, 16}; printf("\n====== %s ======\n\n", cfg_000[0].devname); // command line arguments - if (argc < 3) { - n_tests = 1; - } else if (argc == 3) { - n_tests = strtol(argv[1], NULL, 10); - if (n_tests > MAX_TESTS) { - printf("Wrong input arguments!"); - return 1; - } - start_test = strtol(argv[2], NULL, 10); - if (start_test > MAX_TESTS) { - printf("Wrong input arguments!"); - return 1; - } - - } else { - printf("Wrong input arguments!"); - return 1; + if (argc < 3) { n_tests = 1; } + else if (argc == 3) { + n_tests = strtol(argv[1], NULL, 10); + if (n_tests > MAX_TESTS) { + printf("Wrong input arguments!"); + return 1; + } + start_test = strtol(argv[2], NULL, 10); + if (start_test > MAX_TESTS) { + printf("Wrong input arguments!"); + return 1; + } + } + else { + printf("Wrong input arguments!"); + return 1; } printf(" Executing %d tests\n", n_tests); // allocations printf(" Allocations\n"); - acc_buf = (token_t *) esp_alloc(MAX_SIZE); + acc_buf = (token_t *)esp_alloc(MAX_SIZE); cfg_000[0].hw_buf = acc_buf; sw_buf = malloc(MAX_SIZE); for (test = start_test - 1; test < n_tests + start_test - 1; ++test) { - printf("\n\n-------------------\n"); - printf("TEST #%d\n", test + 1); - - // calculate test parameters - init_parameters(test, - n_channels[test], feature_map_height[test], feature_map_width[test], - n_filters[test], filter_dim[test], is_padded[test], stride[test], - do_relu[test], pool_type[test], batch_size[test], - &in_len, &weights_len, &bias_len, &out_len, - &in_size, &weights_size, &bias_size, &out_size, - &weights_offset, &bias_offset, &out_offset, &size); - - // initialize input data - init_buffer(acc_buf, sw_buf, out_offset); - - // hardware execution - printf("\n Start accelerator execution\n"); - esp_run(cfg_000, NACC); - printf(" Completed accelerator execution\n"); - - // software execution - printf("\n Start software execution\n"); - sw_run(n_channels[test], feature_map_height[test], feature_map_width[test], - n_filters[test], filter_dim[test], is_padded[test], stride[test], - do_relu[test], pool_type[test], batch_size[test], - sw_buf, &sw_buf[weights_offset], &sw_buf[bias_offset], &sw_buf[out_offset]); - printf(" Completed software execution\n"); - - // validation - validate_buffer(&acc_buf[out_offset], &sw_buf[out_offset], out_len); - /* validate_buffer(acc_buf, sw_buf, out_len + out_offset); */ + printf("\n\n-------------------\n"); + printf("TEST #%d\n", test + 1); + + // calculate test parameters + init_parameters(test, n_channels[test], feature_map_height[test], feature_map_width[test], + n_filters[test], filter_dim[test], is_padded[test], stride[test], + do_relu[test], pool_type[test], batch_size[test], &in_len, &weights_len, + &bias_len, &out_len, &in_size, &weights_size, &bias_size, &out_size, + &weights_offset, &bias_offset, &out_offset, &size); + + // initialize input data + init_buffer(acc_buf, sw_buf, out_offset); + + // hardware execution + printf("\n Start accelerator execution\n"); + esp_run(cfg_000, NACC); + printf(" Completed accelerator execution\n"); + + // software execution + printf("\n Start software execution\n"); + sw_run(n_channels[test], feature_map_height[test], feature_map_width[test], n_filters[test], + filter_dim[test], is_padded[test], stride[test], do_relu[test], pool_type[test], + batch_size[test], sw_buf, &sw_buf[weights_offset], &sw_buf[bias_offset], + &sw_buf[out_offset]); + printf(" Completed software execution\n"); + + // validation + validate_buffer(&acc_buf[out_offset], &sw_buf[out_offset], out_len); + /* validate_buffer(acc_buf, sw_buf, out_len + out_offset); */ } // free @@ -325,5 +323,4 @@ int main(int argc, char **argv) printf("\n====== %s ======\n\n", cfg_000[0].devname); return 0; - } diff --git a/accelerators/stratus_hls/conv2d_stratus/sw/linux/driver/conv2d_stratus.c b/accelerators/stratus_hls/conv2d_stratus/sw/linux/driver/conv2d_stratus.c index cd622b1ad2..a8bfcd32ba 100644 --- a/accelerators/stratus_hls/conv2d_stratus/sw/linux/driver/conv2d_stratus.c +++ b/accelerators/stratus_hls/conv2d_stratus/sw/linux/driver/conv2d_stratus.c @@ -1,144 +1,137 @@ -#include #include +#include #include -#include #include +#include #include "conv2d_stratus.h" -#define DRV_NAME "conv2d_stratus" +#define DRV_NAME "conv2d_stratus" /* <<--regs-->> */ -#define CONV2D_N_CHANNELS_REG 0x40 +#define CONV2D_N_CHANNELS_REG 0x40 #define CONV2D_FEATURE_MAP_HEIGHT_REG 0x44 -#define CONV2D_FEATURE_MAP_WIDTH_REG 0x48 -#define CONV2D_N_FILTERS_REG 0x4c -#define CONV2D_FILTER_DIM_REG 0x50 -#define CONV2D_IS_PADDED_REG 0x54 -#define CONV2D_STRIDE_REG 0x58 -#define CONV2D_DO_RELU_REG 0x5c -#define CONV2D_POOL_TYPE_REG 0x60 -#define CONV2D_BATCH_SIZE_REG 0x64 +#define CONV2D_FEATURE_MAP_WIDTH_REG 0x48 +#define CONV2D_N_FILTERS_REG 0x4c +#define CONV2D_FILTER_DIM_REG 0x50 +#define CONV2D_IS_PADDED_REG 0x54 +#define CONV2D_STRIDE_REG 0x58 +#define CONV2D_DO_RELU_REG 0x5c +#define CONV2D_POOL_TYPE_REG 0x60 +#define CONV2D_BATCH_SIZE_REG 0x64 struct conv2d_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver conv2d_driver; static struct of_device_id conv2d_device_ids[] = { - { - .name = "SLD_CONV2D_STRATUS", - }, - { - .name = "eb_052", - }, - { - .compatible = "sld,conv2d_stratus", - }, - { }, + { + .name = "SLD_CONV2D_STRATUS", + }, + { + .name = "eb_052", + }, + { + .compatible = "sld,conv2d_stratus", + }, + {}, }; static int conv2d_devs; static inline struct conv2d_stratus_device *to_conv2d(struct esp_device *esp) { - return container_of(esp, struct conv2d_stratus_device, esp); + return container_of(esp, struct conv2d_stratus_device, esp); } static void conv2d_prep_xfer(struct esp_device *esp, void *arg) { - struct conv2d_stratus_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->n_channels, esp->iomem + CONV2D_N_CHANNELS_REG); - iowrite32be(a->feature_map_height, esp->iomem + CONV2D_FEATURE_MAP_HEIGHT_REG); - iowrite32be(a->feature_map_width, esp->iomem + CONV2D_FEATURE_MAP_WIDTH_REG); - iowrite32be(a->n_filters, esp->iomem + CONV2D_N_FILTERS_REG); - iowrite32be(a->filter_dim, esp->iomem + CONV2D_FILTER_DIM_REG); - iowrite32be(a->is_padded, esp->iomem + CONV2D_IS_PADDED_REG); - iowrite32be(a->stride, esp->iomem + CONV2D_STRIDE_REG); - iowrite32be(a->do_relu, esp->iomem + CONV2D_DO_RELU_REG); - iowrite32be(a->pool_type, esp->iomem + CONV2D_POOL_TYPE_REG); - iowrite32be(a->batch_size, esp->iomem + CONV2D_BATCH_SIZE_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); + struct conv2d_stratus_access *a = arg; + + /* <<--regs-config-->> */ + iowrite32be(a->n_channels, esp->iomem + CONV2D_N_CHANNELS_REG); + iowrite32be(a->feature_map_height, esp->iomem + CONV2D_FEATURE_MAP_HEIGHT_REG); + iowrite32be(a->feature_map_width, esp->iomem + CONV2D_FEATURE_MAP_WIDTH_REG); + iowrite32be(a->n_filters, esp->iomem + CONV2D_N_FILTERS_REG); + iowrite32be(a->filter_dim, esp->iomem + CONV2D_FILTER_DIM_REG); + iowrite32be(a->is_padded, esp->iomem + CONV2D_IS_PADDED_REG); + iowrite32be(a->stride, esp->iomem + CONV2D_STRIDE_REG); + iowrite32be(a->do_relu, esp->iomem + CONV2D_DO_RELU_REG); + iowrite32be(a->pool_type, esp->iomem + CONV2D_POOL_TYPE_REG); + iowrite32be(a->batch_size, esp->iomem + CONV2D_BATCH_SIZE_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool conv2d_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct conv2d_stratus_device *conv2d = to_conv2d(esp); */ - /* struct conv2d_stratus_access *a = arg; */ + /* struct conv2d_stratus_device *conv2d = to_conv2d(esp); */ + /* struct conv2d_stratus_access *a = arg; */ - return true; + return true; } static int conv2d_probe(struct platform_device *pdev) { - struct conv2d_stratus_device *conv2d; - struct esp_device *esp; - int rc; - - conv2d = kzalloc(sizeof(*conv2d), GFP_KERNEL); - if (conv2d == NULL) - return -ENOMEM; - esp = &conv2d->esp; - esp->module = THIS_MODULE; - esp->number = conv2d_devs; - esp->driver = &conv2d_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - conv2d_devs++; - return 0; - err: - kfree(conv2d); - return rc; + struct conv2d_stratus_device *conv2d; + struct esp_device *esp; + int rc; + + conv2d = kzalloc(sizeof(*conv2d), GFP_KERNEL); + if (conv2d == NULL) return -ENOMEM; + esp = &conv2d->esp; + esp->module = THIS_MODULE; + esp->number = conv2d_devs; + esp->driver = &conv2d_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + conv2d_devs++; + return 0; +err: + kfree(conv2d); + return rc; } static int __exit conv2d_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct conv2d_stratus_device *conv2d = to_conv2d(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct conv2d_stratus_device *conv2d = to_conv2d(esp); - esp_device_unregister(esp); - kfree(conv2d); - return 0; + esp_device_unregister(esp); + kfree(conv2d); + return 0; } static struct esp_driver conv2d_driver = { - .plat = { - .probe = conv2d_probe, - .remove = conv2d_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = conv2d_device_ids, - }, - }, - .xfer_input_ok = conv2d_xfer_input_ok, - .prep_xfer = conv2d_prep_xfer, - .ioctl_cm = CONV2D_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct conv2d_stratus_access), + .plat = + { + .probe = conv2d_probe, + .remove = conv2d_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = conv2d_device_ids, + }, + }, + .xfer_input_ok = conv2d_xfer_input_ok, + .prep_xfer = conv2d_prep_xfer, + .ioctl_cm = CONV2D_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct conv2d_stratus_access), }; -static int __init conv2d_init(void) -{ - return esp_driver_register(&conv2d_driver); -} +static int __init conv2d_init(void) { return esp_driver_register(&conv2d_driver); } -static void __exit conv2d_exit(void) -{ - esp_driver_unregister(&conv2d_driver); -} +static void __exit conv2d_exit(void) { esp_driver_unregister(&conv2d_driver); } -module_init(conv2d_init) -module_exit(conv2d_exit) +module_init(conv2d_init) module_exit(conv2d_exit) -MODULE_DEVICE_TABLE(of, conv2d_device_ids); + MODULE_DEVICE_TABLE(of, conv2d_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/conv2d_stratus/sw/linux/include/conv2d_stratus.h b/accelerators/stratus_hls/conv2d_stratus/sw/linux/include/conv2d_stratus.h index 5b0edc4558..8af43e63d6 100644 --- a/accelerators/stratus_hls/conv2d_stratus/sw/linux/include/conv2d_stratus.h +++ b/accelerators/stratus_hls/conv2d_stratus/sw/linux/include/conv2d_stratus.h @@ -4,36 +4,36 @@ #define _CONV2D_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct conv2d_stratus_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned n_channels; - unsigned feature_map_height; - unsigned feature_map_width; - unsigned n_filters; - unsigned filter_dim; - unsigned is_padded; - unsigned stride; - unsigned do_relu; - unsigned pool_type; - unsigned batch_size; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned n_channels; + unsigned feature_map_height; + unsigned feature_map_width; + unsigned n_filters; + unsigned filter_dim; + unsigned is_padded; + unsigned stride; + unsigned do_relu; + unsigned pool_type; + unsigned batch_size; + unsigned src_offset; + unsigned dst_offset; }; -#define CONV2D_STRATUS_IOC_ACCESS _IOW ('S', 0, struct conv2d_stratus_access) +#define CONV2D_STRATUS_IOC_ACCESS _IOW('S', 0, struct conv2d_stratus_access) #endif /* _CONV2D_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/dummy_stratus/hw/src/dummy.cpp b/accelerators/stratus_hls/dummy_stratus/hw/src/dummy.cpp index 74f849e032..a5e023e36c 100644 --- a/accelerators/stratus_hls/dummy_stratus/hw/src/dummy.cpp +++ b/accelerators/stratus_hls/dummy_stratus/hw/src/dummy.cpp @@ -22,7 +22,6 @@ void dummy::load_input() wait(); } - // Config uint32_t tokens; uint32_t batch; @@ -33,15 +32,14 @@ void dummy::load_input() conf_info_t config = this->conf_info.read(); tokens = config.tokens; - batch = config.batch; + batch = config.batch; } // Load - bool ping = true; + bool ping = true; uint32_t offset = 0; for (int n = 0; n < batch; n++) - for (int b = tokens; b > 0; b -= PLM_SIZE) - { + for (int b = tokens; b > 0; b -= PLM_SIZE) { HLS_PROTO("load-dma"); uint32_t len = b > PLM_SIZE ? PLM_SIZE : b; @@ -57,11 +55,11 @@ void dummy::load_input() for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { sc_dt::sc_bv<64> data_bv; for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) { - data_bv.range((k+1)*DMA_WIDTH-1, k * DMA_WIDTH) = this->dma_read_chnl.get(); + data_bv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH) = + this->dma_read_chnl.get(); wait(); } - if (ping) - plm0[i] = data_bv.to_int64(); + if (ping) plm0[i] = data_bv.to_int64(); else plm1[i] = data_bv.to_int64(); } @@ -73,15 +71,13 @@ void dummy::load_input() uint64_t data; sc_dt::sc_bv data_bv; - data_bv = this->dma_read_chnl.get(); wait(); for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; - if (ping) - plm0[i+k] = data_bv.range((k+1)*64 - 1, k*64).to_int64(); + if (ping) plm0[i + k] = data_bv.range((k + 1) * 64 - 1, k * 64).to_int64(); else - plm1[i+k] = data_bv.range((k+1)*64 - 1, k*64).to_int64(); + plm1[i + k] = data_bv.range((k + 1) * 64 - 1, k * 64).to_int64(); } } #endif @@ -95,8 +91,6 @@ void dummy::load_input() } } - - void dummy::store_output() { // Reset @@ -118,15 +112,14 @@ void dummy::store_output() conf_info_t config = this->conf_info.read(); tokens = config.tokens; - batch = config.batch; + batch = config.batch; } // Store - bool ping = true; + bool ping = true; uint32_t offset = 0; for (int n = 0; n < batch; n++) - for (int b = tokens; b > 0; b -= PLM_SIZE) - { + for (int b = tokens; b > 0; b -= PLM_SIZE) { HLS_PROTO("store-dma"); this->store_compute_handshake(); @@ -143,15 +136,14 @@ void dummy::store_output() for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { sc_dt::sc_int<64> data; wait(); - if (ping) - data = plm0[i]; + if (ping) data = plm0[i]; else data = plm1[i]; sc_dt::sc_bv data_bv(data); for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) { - this->dma_write_chnl.put(data_bv.range((k+1)*DMA_WIDTH - 1, k*DMA_WIDTH)); + this->dma_write_chnl.put(data_bv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); wait(); } } @@ -161,10 +153,9 @@ void dummy::store_output() wait(); for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; - if (ping) - data_bv.range((k+1)*64 - 1, k*64) = plm0[i + k]; + if (ping) data_bv.range((k + 1) * 64 - 1, k * 64) = plm0[i + k]; else - data_bv.range((k+1)*64 - 1, k*64) = plm1[i + k]; + data_bv.range((k + 1) * 64 - 1, k * 64) = plm1[i + k]; } this->dma_write_chnl.put(data_bv); } @@ -179,7 +170,6 @@ void dummy::store_output() } } - void dummy::compute_kernel() { // Reset @@ -199,7 +189,6 @@ void dummy::compute_kernel() conf_info_t config = this->conf_info.read(); } - // Compute (dummy does nothing) while (true) { this->compute_load_handshake(); diff --git a/accelerators/stratus_hls/dummy_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/dummy_stratus/hw/tb/sc_main.cpp index c465ccc433..cffde7e61b 100644 --- a/accelerators/stratus_hls/dummy_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/dummy_stratus/hw/tb/sc_main.cpp @@ -5,44 +5,44 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; extern void esc_elaborate() { - // Creating the whole system - testbench = new system_t("testbench"); + // Creating the whole system + testbench = new system_t("testbench"); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); - esc_cleanup(); + esc_log_pass(); + esc_cleanup(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/dummy_stratus/sw/baremetal/dummy.c b/accelerators/stratus_hls/dummy_stratus/sw/baremetal/dummy.c index 4eea09444f..380f11768a 100644 --- a/accelerators/stratus_hls/dummy_stratus/sw/baremetal/dummy.c +++ b/accelerators/stratus_hls/dummy_stratus/sw/baremetal/dummy.c @@ -8,7 +8,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -20,143 +20,137 @@ typedef unsigned u32; typedef u64 token_t; #define mask 0xFEED0BAC00000000LL -#define SLD_DUMMY 0x42 -#define DEV_NAME "sld,dummy_stratus" +#define SLD_DUMMY 0x42 +#define DEV_NAME "sld,dummy_stratus" #define TOKENS 64 -#define BATCH 4 +#define BATCH 4 static unsigned out_offset; static unsigned size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK ((size % CHUNK_SIZE == 0) ? \ - (size / CHUNK_SIZE) : \ - (size / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK ((size % CHUNK_SIZE == 0) ? (size / CHUNK_SIZE) : (size / CHUNK_SIZE) + 1) // User defined registers -#define TOKENS_REG 0x40 -#define BATCH_REG 0x44 - +#define TOKENS_REG 0x40 +#define BATCH_REG 0x44 static int validate_dummy(token_t *mem) { - int i, j; - int rtn = 0; - for (j = 0; j < BATCH; j++) - for (i = 0; i < TOKENS; i++) - if (mem[i + j * TOKENS] != (mask | (token_t) i)) { - printf("[%d, %d]: %llu\n", j, i, mem[i + j * TOKENS]); - rtn++; - } - return rtn; + int i, j; + int rtn = 0; + for (j = 0; j < BATCH; j++) + for (i = 0; i < TOKENS; i++) + if (mem[i + j * TOKENS] != (mask | (token_t)i)) { + printf("[%d, %d]: %llu\n", j, i, mem[i + j * TOKENS]); + rtn++; + } + return rtn; } -static void init_buf (token_t *mem) +static void init_buf(token_t *mem) { - int i, j; - for (j = 0; j < BATCH; j++) - for (i = 0; i < TOKENS; i++) - mem[i + j * TOKENS] = (mask | (token_t) i); + int i, j; + for (j = 0; j < BATCH; j++) + for (i = 0; i < TOKENS; i++) + mem[i + j * TOKENS] = (mask | (token_t)i); - for (i = 0; i < BATCH * TOKENS; i++) - mem[i + BATCH * TOKENS] = 0xFFFFFFFFFFFFFFFFLL; + for (i = 0; i < BATCH * TOKENS; i++) + mem[i + BATCH * TOKENS] = 0xFFFFFFFFFFFFFFFFLL; } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - struct esp_device *srcs[4]; - unsigned all_done; - unsigned **ptable = NULL; - token_t *mem; - unsigned errors = 0; - - out_offset = BATCH * TOKENS * sizeof(u64); - size = 2 * out_offset; - - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_DUMMY, DEV_NAME); - if (ndev < 1) { - printf("This test requires a dummy device!\n"); - return 0; - } - - // Check DMA capabilities - dev = &espdevs[0]; - - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - mem = aligned_malloc(size); - printf(" memory buffer base-address = %p\n", mem); - - //Alocate and populate page table - ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); - for (i = 0; i < NCHUNK; i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK); - - printf(" Generate random input...\n"); - init_buf(mem); - - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - iowrite32(dev, TOKENS_REG, TOKENS); - iowrite32(dev, BATCH_REG, BATCH); - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, out_offset); - - // Flush for non-coherent DMA - esp_flush(ACC_COH_NONE); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - all_done = 0; - while (!all_done) { - all_done = ioread32(dev, STATUS_REG); - all_done &= STATUS_MASK_DONE; - } - - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - - /* Validation */ - printf(" validating...\n"); - errors = validate_dummy(&mem[BATCH * TOKENS]); - - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - - aligned_free(ptable); - aligned_free(mem); - - return 0; + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + struct esp_device *srcs[4]; + unsigned all_done; + unsigned **ptable = NULL; + token_t *mem; + unsigned errors = 0; + + out_offset = BATCH * TOKENS * sizeof(u64); + size = 2 * out_offset; + + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_DUMMY, DEV_NAME); + if (ndev < 1) { + printf("This test requires a dummy device!\n"); + return 0; + } + + // Check DMA capabilities + dev = &espdevs[0]; + + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + mem = aligned_malloc(size); + printf(" memory buffer base-address = %p\n", mem); + + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); + for (i = 0; i < NCHUNK; i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK); + + printf(" Generate random input...\n"); + init_buf(mem); + + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + iowrite32(dev, TOKENS_REG, TOKENS); + iowrite32(dev, BATCH_REG, BATCH); + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, out_offset); + + // Flush for non-coherent DMA + esp_flush(ACC_COH_NONE); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + all_done = 0; + while (!all_done) { + all_done = ioread32(dev, STATUS_REG); + all_done &= STATUS_MASK_DONE; + } + + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + + /* Validation */ + printf(" validating...\n"); + errors = validate_dummy(&mem[BATCH * TOKENS]); + + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + + aligned_free(ptable); + aligned_free(mem); + + return 0; } - diff --git a/accelerators/stratus_hls/dummy_stratus/sw/linux/app/dummy.c b/accelerators/stratus_hls/dummy_stratus/sw/linux/app/dummy.c index 30b7492412..3f9735e2ea 100644 --- a/accelerators/stratus_hls/dummy_stratus/sw/linux/app/dummy.c +++ b/accelerators/stratus_hls/dummy_stratus/sw/linux/app/dummy.c @@ -1,20 +1,20 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 +#include +#include #include +#include #include #include #include -#include -#include -#include +#include #include #include #include -#include #define TOKENS 8 -#define BATCH 2 +#define BATCH 2 typedef unsigned long long u64; @@ -22,284 +22,274 @@ static unsigned out_offset; static unsigned size; struct accelerator_thread_info { - int fd; - struct dummy_stratus_access desc; - unsigned long long hw_ns; + int fd; + struct dummy_stratus_access desc; + unsigned long long hw_ns; }; typedef struct accelerator_thread_info accelerator_thread_info_t; -void *accelerator_thread( void *ptr ) +void *accelerator_thread(void *ptr) { - accelerator_thread_info_t *info = (accelerator_thread_info_t *) ptr; - struct timespec th_start; - struct timespec th_end; - int rc; - - gettime(&th_start); - rc = ioctl(info->fd, DUMMY_STRATUS_IOC_ACCESS, info->desc); - gettime(&th_end); - if(rc < 0) { - perror("ioctl"); - exit(1); - } - info->hw_ns = ts_subtract(&th_start, &th_end); - - return NULL; + accelerator_thread_info_t *info = (accelerator_thread_info_t *)ptr; + struct timespec th_start; + struct timespec th_end; + int rc; + + gettime(&th_start); + rc = ioctl(info->fd, DUMMY_STRATUS_IOC_ACCESS, info->desc); + gettime(&th_end); + if (rc < 0) { + perror("ioctl"); + exit(1); + } + info->hw_ns = ts_subtract(&th_start, &th_end); + + return NULL; } -static void prepare_dummy(int *fd, contig_handle_t *mem, accelerator_thread_info_t *info, struct dummy_stratus_access *desc, const char *device_name, unsigned id, unsigned do_p2p) +static void prepare_dummy(int *fd, contig_handle_t *mem, accelerator_thread_info_t *info, + struct dummy_stratus_access *desc, const char *device_name, unsigned id, + unsigned do_p2p) { - *fd = open(device_name, O_RDWR, 0); - if (*fd < 0) { - perror("open"); - exit(1); - } - - desc->esp.p2p_store = 0; - desc->esp.p2p_nsrcs = 0; - desc->esp.contig = contig_to_khandle(*mem); - desc->esp.run = true; - desc->esp.coherence = ACC_COH_NONE; - desc->tokens = TOKENS; - switch(id) { - case 0 : - desc->batch = BATCH / 2; - desc->src_offset = 0; - desc->dst_offset = out_offset; - if (do_p2p) - desc->esp.p2p_store = 1; - break; - case 1 : - desc->batch = BATCH / 2; - desc->src_offset = out_offset / 2; - desc->dst_offset = 3 * out_offset / 2; - if (do_p2p) - desc->esp.p2p_store = 1; - break; - default : - desc->batch = BATCH; - desc->src_offset = out_offset; - desc->dst_offset = 2 * out_offset; - if (do_p2p) { - desc->esp.p2p_nsrcs = 2; - strncpy(desc->esp.p2p_srcs[0], "dummy_stratus.0", 63); - desc->esp.p2p_srcs[0][63] = '\0'; - strncpy(desc->esp.p2p_srcs[1], "dummy_stratus.1", 63); - desc->esp.p2p_srcs[1][63] = '\0'; - } - break; - } - - info->fd = *fd; - info->desc = *desc; + *fd = open(device_name, O_RDWR, 0); + if (*fd < 0) { + perror("open"); + exit(1); + } + + desc->esp.p2p_store = 0; + desc->esp.p2p_nsrcs = 0; + desc->esp.contig = contig_to_khandle(*mem); + desc->esp.run = true; + desc->esp.coherence = ACC_COH_NONE; + desc->tokens = TOKENS; + switch (id) { + case 0: + desc->batch = BATCH / 2; + desc->src_offset = 0; + desc->dst_offset = out_offset; + if (do_p2p) desc->esp.p2p_store = 1; + break; + case 1: + desc->batch = BATCH / 2; + desc->src_offset = out_offset / 2; + desc->dst_offset = 3 * out_offset / 2; + if (do_p2p) desc->esp.p2p_store = 1; + break; + default: + desc->batch = BATCH; + desc->src_offset = out_offset; + desc->dst_offset = 2 * out_offset; + if (do_p2p) { + desc->esp.p2p_nsrcs = 2; + strncpy(desc->esp.p2p_srcs[0], "dummy_stratus.0", 63); + desc->esp.p2p_srcs[0][63] = '\0'; + strncpy(desc->esp.p2p_srcs[1], "dummy_stratus.1", 63); + desc->esp.p2p_srcs[1][63] = '\0'; + } + break; + } + + info->fd = *fd; + info->desc = *desc; } static void init_buffer(contig_handle_t *hwbuf) { - int i, j; - for (j = 0; j < BATCH; j++) - for (i = 0; i < TOKENS; i++) - contig_write64(0xFEED0BAC00000000L | (u64) i, *hwbuf, (j * TOKENS + i) * sizeof(u64)); + int i, j; + for (j = 0; j < BATCH; j++) + for (i = 0; i < TOKENS; i++) + contig_write64(0xFEED0BAC00000000L | (u64)i, *hwbuf, (j * TOKENS + i) * sizeof(u64)); - for (i = 0; i < 2 * BATCH * TOKENS; i++) - contig_write64(0xFFFFFFFFFFFFFFFFL, *hwbuf, out_offset + i * sizeof(u64)); + for (i = 0; i < 2 * BATCH * TOKENS; i++) + contig_write64(0xFFFFFFFFFFFFFFFFL, *hwbuf, out_offset + i * sizeof(u64)); } static void validate_buffer(contig_handle_t *hwbuf) { - int i, j; - int err = 0; - - for (j = 0; j < BATCH; j++) - for (i = 0; i < TOKENS; i++) { - u64 token = contig_read64(*hwbuf, 2 * out_offset + (j * TOKENS + i) * sizeof(u64)); - if (token != (0xFEED0BAC00000000L | (u64) i)) { - /* Only print first few errors to debug */ - if (err < 8) - printf(" !! %d.%d: 0x%016llx !!\n", j, i, token); - err++; - } - } - - if (!err) - printf(" + Test PASSED\n"); - else - printf(" + Test FAILED\n"); + int i, j; + int err = 0; + + for (j = 0; j < BATCH; j++) + for (i = 0; i < TOKENS; i++) { + u64 token = contig_read64(*hwbuf, 2 * out_offset + (j * TOKENS + i) * sizeof(u64)); + if (token != (0xFEED0BAC00000000L | (u64)i)) { + /* Only print first few errors to debug */ + if (err < 8) printf(" !! %d.%d: 0x%016llx !!\n", j, i, token); + err++; + } + } + + if (!err) printf(" + Test PASSED\n"); + else + printf(" + Test FAILED\n"); } static void print_time_info(accelerator_thread_info_t *info, unsigned long long hw_ns, int nthreads) { - int i; - for (i = 0; i < nthreads; i++) - printf(" * ACC.%d time: %llu ns\n", i, info[i].hw_ns); - printf(" Test time: %llu ns\n", hw_ns); + int i; + for (i = 0; i < nthreads; i++) + printf(" * ACC.%d time: %llu ns\n", i, info[i].hw_ns); + printf(" Test time: %llu ns\n", hw_ns); } - int main(int argc, char *argv[]) { - int i; - int rc = 0; - int fd[3]; - contig_handle_t hwbuf; - char device_name[60]; - - struct timespec th_start; - struct timespec th_end; - - pthread_t thread[3]; - accelerator_thread_info_t info[3]; - struct dummy_stratus_access desc[3]; - - void *rp; - - out_offset = BATCH * TOKENS * sizeof(u64); - size = 3 * out_offset; - - printf("=== Point-to-point test w/ dummy accelerator ===\n"); - - printf(" - Config: {tokens = %d, batch = %d}\n", TOKENS, BATCH); - - printf(" - Allocate %u B\n", size); - contig_alloc(size, &hwbuf); - - printf("\n"); - printf(" * Virtual memory layout *\n"); - printf(" |_______________|\n"); - printf(" ACC0 src --> | |\n"); - printf(" | batch 0 |\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" ...\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" | batch B/2 - 1 |\n"); - printf(" |_______________|\n"); - printf(" ACC1 src --> | |\n"); - printf(" | batch B/2 |\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" ...\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" | batch B |\n"); - printf(" |_______________|\n"); - printf(" ACC2 src --> | | <-- ACC0 dst\n"); - printf(" | batch 0 |\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" ...\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" | batch B/2 - 1 |\n"); - printf(" |_______________|\n"); - printf(" | | <-- ACC1 dst\n"); - printf(" | batch B/2 |\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" ...\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" | batch B |\n"); - printf(" |_______________|\n"); - printf(" ACC2 dst --> | |\n"); - printf(" | batch 0 |\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" ...\n"); - printf(" |_______________|\n"); - printf(" | |\n"); - printf(" | batch B |\n"); - printf(" |_______________|\n"); - printf("\n"); - printf("\n"); - - /* Simple DMA */ - printf(" --> Start simple DMA test\n"); - - printf(" - Initialize input and clear output\n"); - init_buffer(&hwbuf); - - printf(" - Configure devices\n"); - for (i = 0; i < 3; i++) { - sprintf(device_name, "/dev/dummy_stratus.%d", i); - prepare_dummy(&fd[i], &hwbuf, &info[i], &desc[i], device_name, i, 0); - } - printf(" MEM ==> ACC.0 ==> MEM\n"); - printf(" MEM ==> ACC.1 ==> MEM\n"); - printf(" MEM ==> ACC.2 ==> MEM\n"); - - gettime(&th_start); - for (i = 0; i < 2; i++) { - rc = pthread_create(&thread[i], NULL, accelerator_thread, (void*) &info[i]); - if(rc != 0) { - perror("pthread_create"); - goto free_and_exit; - } - } - for (i = 0; i < 2; i++) { - rc = pthread_join(thread[i], NULL); - if(rc != 0) { - perror("pthread_join"); - goto free_and_exit; - } - } - rp = accelerator_thread((void*) &info[i]); - if(rp != NULL) { - perror("accelerator_thread"); - goto free_and_exit; - } - gettime(&th_end); - - validate_buffer(&hwbuf); - - print_time_info(info, ts_subtract(&th_start, &th_end), 3); - - - /* P2P Test */ - printf(" --> Start P2P Test 1\n"); - - printf(" - Initialize input and clear output\n"); - init_buffer(&hwbuf); - - printf(" - Configure devices\n"); - for (i = 0; i < 3; i++) { - sprintf(device_name, "/dev/dummy_stratus.%d", i); - prepare_dummy(&fd[i], &hwbuf, &info[i], &desc[i], device_name, i, 1); - } - printf(" MEM ==> ACC.0 ==> ACC.2\n"); - printf(" MEM ==> ACC.1 ==> ACC.2\n"); - printf(" ACC.0, ACC.1 ==> ACC.2 ==> MEM\n"); - - gettime(&th_start); - for (i = 0; i < 3; i++) { - rc = pthread_create(&thread[i], NULL, accelerator_thread, (void*) &info[i]); - if(rc != 0) { - perror("pthread_create"); - goto free_and_exit; - } - } - for (i = 0; i < 3; i++) { - rc = pthread_join(thread[i], NULL); - if(rc != 0) { - perror("pthread_join"); - goto free_and_exit; - } - } - gettime(&th_end); - - validate_buffer(&hwbuf); - - print_time_info(info, ts_subtract(&th_start, &th_end), 3); - - - + int i; + int rc = 0; + int fd[3]; + contig_handle_t hwbuf; + char device_name[60]; + + struct timespec th_start; + struct timespec th_end; + + pthread_t thread[3]; + accelerator_thread_info_t info[3]; + struct dummy_stratus_access desc[3]; + + void *rp; + + out_offset = BATCH * TOKENS * sizeof(u64); + size = 3 * out_offset; + + printf("=== Point-to-point test w/ dummy accelerator ===\n"); + + printf(" - Config: {tokens = %d, batch = %d}\n", TOKENS, BATCH); + + printf(" - Allocate %u B\n", size); + contig_alloc(size, &hwbuf); + + printf("\n"); + printf(" * Virtual memory layout *\n"); + printf(" |_______________|\n"); + printf(" ACC0 src --> | |\n"); + printf(" | batch 0 |\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" ...\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" | batch B/2 - 1 |\n"); + printf(" |_______________|\n"); + printf(" ACC1 src --> | |\n"); + printf(" | batch B/2 |\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" ...\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" | batch B |\n"); + printf(" |_______________|\n"); + printf(" ACC2 src --> | | <-- ACC0 dst\n"); + printf(" | batch 0 |\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" ...\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" | batch B/2 - 1 |\n"); + printf(" |_______________|\n"); + printf(" | | <-- ACC1 dst\n"); + printf(" | batch B/2 |\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" ...\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" | batch B |\n"); + printf(" |_______________|\n"); + printf(" ACC2 dst --> | |\n"); + printf(" | batch 0 |\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" ...\n"); + printf(" |_______________|\n"); + printf(" | |\n"); + printf(" | batch B |\n"); + printf(" |_______________|\n"); + printf("\n"); + printf("\n"); + + /* Simple DMA */ + printf(" --> Start simple DMA test\n"); + + printf(" - Initialize input and clear output\n"); + init_buffer(&hwbuf); + + printf(" - Configure devices\n"); + for (i = 0; i < 3; i++) { + sprintf(device_name, "/dev/dummy_stratus.%d", i); + prepare_dummy(&fd[i], &hwbuf, &info[i], &desc[i], device_name, i, 0); + } + printf(" MEM ==> ACC.0 ==> MEM\n"); + printf(" MEM ==> ACC.1 ==> MEM\n"); + printf(" MEM ==> ACC.2 ==> MEM\n"); + + gettime(&th_start); + for (i = 0; i < 2; i++) { + rc = pthread_create(&thread[i], NULL, accelerator_thread, (void *)&info[i]); + if (rc != 0) { + perror("pthread_create"); + goto free_and_exit; + } + } + for (i = 0; i < 2; i++) { + rc = pthread_join(thread[i], NULL); + if (rc != 0) { + perror("pthread_join"); + goto free_and_exit; + } + } + rp = accelerator_thread((void *)&info[i]); + if (rp != NULL) { + perror("accelerator_thread"); + goto free_and_exit; + } + gettime(&th_end); + + validate_buffer(&hwbuf); + + print_time_info(info, ts_subtract(&th_start, &th_end), 3); + + /* P2P Test */ + printf(" --> Start P2P Test 1\n"); + + printf(" - Initialize input and clear output\n"); + init_buffer(&hwbuf); + + printf(" - Configure devices\n"); + for (i = 0; i < 3; i++) { + sprintf(device_name, "/dev/dummy_stratus.%d", i); + prepare_dummy(&fd[i], &hwbuf, &info[i], &desc[i], device_name, i, 1); + } + printf(" MEM ==> ACC.0 ==> ACC.2\n"); + printf(" MEM ==> ACC.1 ==> ACC.2\n"); + printf(" ACC.0, ACC.1 ==> ACC.2 ==> MEM\n"); + + gettime(&th_start); + for (i = 0; i < 3; i++) { + rc = pthread_create(&thread[i], NULL, accelerator_thread, (void *)&info[i]); + if (rc != 0) { + perror("pthread_create"); + goto free_and_exit; + } + } + for (i = 0; i < 3; i++) { + rc = pthread_join(thread[i], NULL); + if (rc != 0) { + perror("pthread_join"); + goto free_and_exit; + } + } + gettime(&th_end); + + validate_buffer(&hwbuf); + + print_time_info(info, ts_subtract(&th_start, &th_end), 3); free_and_exit: - contig_free(hwbuf); - return rc; - + contig_free(hwbuf); + return rc; } - - diff --git a/accelerators/stratus_hls/dummy_stratus/sw/linux/driver/dummy_stratus.c b/accelerators/stratus_hls/dummy_stratus/sw/linux/driver/dummy_stratus.c index 9896f9ca60..43aec1aab8 100644 --- a/accelerators/stratus_hls/dummy_stratus/sw/linux/driver/dummy_stratus.c +++ b/accelerators/stratus_hls/dummy_stratus/sw/linux/driver/dummy_stratus.c @@ -1,129 +1,121 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "dummy_stratus.h" -#define DRV_NAME "dummy_stratus" +#define DRV_NAME "dummy_stratus" -#define DUMMY_LEN_REG 0x40 -#define DUMMY_BATCH_REG 0x44 +#define DUMMY_LEN_REG 0x40 +#define DUMMY_BATCH_REG 0x44 struct dummy_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver dummy_driver; static struct of_device_id dummy_device_ids[] = { - { - .name = "SLD_DUMMY_STRATUS", - }, - { - .name = "eb_042", - }, - { - .compatible = "sld,dummy_stratus", - }, - { }, + { + .name = "SLD_DUMMY_STRATUS", + }, + { + .name = "eb_042", + }, + { + .compatible = "sld,dummy_stratus", + }, + {}, }; static int dummy_devs; static inline struct dummy_stratus_device *to_dummy(struct esp_device *esp) { - return container_of(esp, struct dummy_stratus_device, esp); + return container_of(esp, struct dummy_stratus_device, esp); } static void dummy_prep_xfer(struct esp_device *esp, void *arg) { - struct dummy_stratus_access *a = arg; - - iowrite32be(a->tokens, esp->iomem + DUMMY_LEN_REG); - iowrite32be(a->batch, esp->iomem + DUMMY_BATCH_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); + struct dummy_stratus_access *a = arg; + iowrite32be(a->tokens, esp->iomem + DUMMY_LEN_REG); + iowrite32be(a->batch, esp->iomem + DUMMY_BATCH_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool dummy_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct dummy_stratus_device *dummy = to_dummy(esp); */ - /* struct dummy_stratus_access *a = arg; */ + /* struct dummy_stratus_device *dummy = to_dummy(esp); */ + /* struct dummy_stratus_access *a = arg; */ - return true; + return true; } static int dummy_probe(struct platform_device *pdev) { - struct dummy_stratus_device *dummy; - struct esp_device *esp; - int rc; - - dummy = kzalloc(sizeof(*dummy), GFP_KERNEL); - if (dummy == NULL) - return -ENOMEM; - esp = &dummy->esp; - esp->module = THIS_MODULE; - esp->number = dummy_devs; - esp->driver = &dummy_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - dummy_devs++; - return 0; - err: - kfree(dummy); - return rc; + struct dummy_stratus_device *dummy; + struct esp_device *esp; + int rc; + + dummy = kzalloc(sizeof(*dummy), GFP_KERNEL); + if (dummy == NULL) return -ENOMEM; + esp = &dummy->esp; + esp->module = THIS_MODULE; + esp->number = dummy_devs; + esp->driver = &dummy_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + dummy_devs++; + return 0; +err: + kfree(dummy); + return rc; } static int __exit dummy_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct dummy_stratus_device *dummy = to_dummy(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct dummy_stratus_device *dummy = to_dummy(esp); - esp_device_unregister(esp); - kfree(dummy); - return 0; + esp_device_unregister(esp); + kfree(dummy); + return 0; } static struct esp_driver dummy_driver = { - .plat = { - .probe = dummy_probe, - .remove = dummy_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = dummy_device_ids, - }, - }, - .xfer_input_ok = dummy_xfer_input_ok, - .prep_xfer = dummy_prep_xfer, - .ioctl_cm = DUMMY_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct dummy_stratus_access), + .plat = + { + .probe = dummy_probe, + .remove = dummy_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = dummy_device_ids, + }, + }, + .xfer_input_ok = dummy_xfer_input_ok, + .prep_xfer = dummy_prep_xfer, + .ioctl_cm = DUMMY_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct dummy_stratus_access), }; -static int __init dummy_init(void) -{ - return esp_driver_register(&dummy_driver); -} +static int __init dummy_init(void) { return esp_driver_register(&dummy_driver); } -static void __exit dummy_exit(void) -{ - esp_driver_unregister(&dummy_driver); -} +static void __exit dummy_exit(void) { esp_driver_unregister(&dummy_driver); } -module_init(dummy_init) -module_exit(dummy_exit) +module_init(dummy_init) module_exit(dummy_exit) -MODULE_DEVICE_TABLE(of, dummy_device_ids); + MODULE_DEVICE_TABLE(of, dummy_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/dummy_stratus/sw/linux/include/dummy_stratus.h b/accelerators/stratus_hls/dummy_stratus/sw/linux/include/dummy_stratus.h index 7b9383e1ca..bba15da44d 100644 --- a/accelerators/stratus_hls/dummy_stratus/sw/linux/include/dummy_stratus.h +++ b/accelerators/stratus_hls/dummy_stratus/sw/linux/include/dummy_stratus.h @@ -4,27 +4,27 @@ #define _DUMMY_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct dummy_stratus_access { - struct esp_access esp; - unsigned tokens; - unsigned batch; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + unsigned tokens; + unsigned batch; + unsigned src_offset; + unsigned dst_offset; }; -#define DUMMY_STRATUS_IOC_ACCESS _IOW ('S', 0, struct dummy_stratus_access) +#define DUMMY_STRATUS_IOC_ACCESS _IOW('S', 0, struct dummy_stratus_access) #endif /* _DUMMY_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/fft2_stratus/hw/src/fft2.cpp b/accelerators/stratus_hls/fft2_stratus/hw/src/fft2.cpp index f29c6843c8..45f3c175db 100644 --- a/accelerators/stratus_hls/fft2_stratus/hw/src/fft2.cpp +++ b/accelerators/stratus_hls/fft2_stratus/hw/src/fft2.cpp @@ -29,11 +29,11 @@ void fft2::load_input() // Config /* <<--params-->> */ - //int32_t scale_factor; - //int32_t do_inverse; + // int32_t scale_factor; + // int32_t do_inverse; int32_t logn_samples; int32_t num_samples; - //int32_t do_shift; + // int32_t do_shift; int32_t num_ffts; { HLS_PROTO("load-config"); @@ -44,11 +44,11 @@ void fft2::load_input() // User-defined config code /* <<--local-params-->> */ logn_samples = config.logn_samples; - num_samples = 1 << logn_samples; - num_ffts = config.num_ffts; - //do_inverse = config.do_inverse; - //do_shift = config.do_shift; - //scale_factor = config.scale_factor; + num_samples = 1 << logn_samples; + num_ffts = config.num_ffts; + // do_inverse = config.do_inverse; + // do_shift = config.do_shift; + // scale_factor = config.scale_factor; } // Load @@ -64,8 +64,7 @@ void fft2::load_input() uint32_t length = round_up(2 * num_ffts * num_samples, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_IN_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_IN_WORD) { wait(); // Configure DMA transaction uint32_t len = rem > PLM_IN_WORD ? PLM_IN_WORD : rem; @@ -73,7 +72,8 @@ void fft2::load_input() // data word is wider than NoC links dma_info_t dma_info(offset * DMA_BEAT_PER_WORD, len * DMA_BEAT_PER_WORD, DMA_SIZE); #else - printf("LOAD DMA INFO : rem %u : off = %u , len %u\n", rem, (offset/DMA_WORD_PER_BEAT), (len/DMA_WORD_PER_BEAT)); + printf("LOAD DMA INFO : rem %u : off = %u , len %u\n", rem, + (offset / DMA_WORD_PER_BEAT), (len / DMA_WORD_PER_BEAT)); dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len / DMA_WORD_PER_BEAT, DMA_SIZE); #endif offset += len; @@ -82,13 +82,12 @@ void fft2::load_input() #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - for (uint16_t i = 0; i < len; i++) - { + for (uint16_t i = 0; i < len; i++) { sc_dt::sc_bv dataBv; - for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) - { - dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH) = this->dma_read_chnl.get(); + for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) { + dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH) = + this->dma_read_chnl.get(); wait(); } @@ -96,8 +95,7 @@ void fft2::load_input() A0[i] = dataBv.to_int64(); } #else - for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { HLS_BREAK_DEP(A0); sc_dt::sc_bv dataBv; @@ -106,10 +104,9 @@ void fft2::load_input() wait(); // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; - A0[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + A0[i + k] = dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); } } #endif @@ -118,17 +115,15 @@ void fft2::load_input() this->load_to_store_handshake(); loads_done++; } // for (rem = length downto 0 ) - } // Load scope + } // Load scope - //printf("LOAD process is done -- did %u loads\n", loads_done); + // printf("LOAD process is done -- did %u loads\n", loads_done); // Conclude { this->process_done(); } } - - void fft2::store_output() { // Reset @@ -150,9 +145,9 @@ void fft2::store_output() int32_t logn_samples; int32_t num_samples; int32_t num_ffts; - //int32_t scale_factor; - //int32_t do_inverse; - //int32_t do_shift; + // int32_t scale_factor; + // int32_t do_inverse; + // int32_t do_shift; { HLS_PROTO("store-config"); @@ -162,11 +157,11 @@ void fft2::store_output() // User-defined config code /* <<--local-params-->> */ logn_samples = config.logn_samples; - num_samples = 1 << logn_samples; - num_ffts = config.num_ffts; - //do_inverse = config.do_inverse; - //do_shift = config.do_shift; - //scale_factor = config.scale_factor; + num_samples = 1 << logn_samples; + num_ffts = config.num_ffts; + // do_inverse = config.do_inverse; + // do_shift = config.do_shift; + // scale_factor = config.scale_factor; } // Store @@ -186,11 +181,10 @@ void fft2::store_output() #if (DMA_WORD_PER_BEAT == 0) uint32_t length = 2 * num_ffts * num_samples; #else - uint32_t length = round_up(2 * num_ffts * num_samples, DMA_WORD_PER_BEAT); + uint32_t length = round_up(2 * num_ffts * num_samples, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) { printf("STORE hit the store-compute handshake...\n"); this->store_compute_handshake(); @@ -200,7 +194,8 @@ void fft2::store_output() // data word is wider than NoC links dma_info_t dma_info(offset * DMA_BEAT_PER_WORD, len * DMA_BEAT_PER_WORD, DMA_SIZE); #else - printf("STORE DMA INFO : rem %u : off = %u , len = %u\n", rem, (offset/DMA_WORD_PER_BEAT), (len/DMA_WORD_PER_BEAT)); + printf("STORE DMA INFO : rem %u : off = %u , len = %u\n", rem, + (offset / DMA_WORD_PER_BEAT), (len / DMA_WORD_PER_BEAT)); dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len / DMA_WORD_PER_BEAT, DMA_SIZE); #endif offset += len; @@ -209,8 +204,7 @@ void fft2::store_output() #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - for (uint16_t i = 0; i < len; i++) - { + for (uint16_t i = 0; i < len; i++) { // Read from PLM sc_dt::sc_int data; wait(); @@ -218,36 +212,33 @@ void fft2::store_output() sc_dt::sc_bv dataBv(data); uint16_t k = 0; - for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) - { - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) { + this->dma_write_chnl.put(dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); wait(); } // Last beat on the bus does not require wait(), which is // placed before accessing the PLM - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + this->dma_write_chnl.put(dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); } #else - for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { sc_dt::sc_bv dataBv; // Read from PLM wait(); - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; - dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH) = A0[i + k]; + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = A0[i + k]; } this->dma_write_chnl.put(dataBv); } #endif stores_done++; - //rem = 0; + // rem = 0; this->store_to_load_handshake(); } // for (rem = length downto 0 - } // Store scope - //printf("STORE process is done - did %u stores!\n", stores_done); + } // Store scope + // printf("STORE process is done - did %u stores!\n", stores_done); // Conclude { this->accelerator_done(); @@ -255,7 +246,6 @@ void fft2::store_output() } } - void fft2::compute_kernel() { // Reset @@ -278,7 +268,7 @@ void fft2::compute_kernel() int32_t num_ffts; int32_t do_inverse; int32_t do_shift; - //int32_t scale_factor; + // int32_t scale_factor; { HLS_PROTO("compute-config"); @@ -292,42 +282,46 @@ void fft2::compute_kernel() sc_assert(logn_samples < MAX_LOGN_SAMPLES); #endif num_samples = 1 << logn_samples; - num_ffts = config.num_ffts; - do_inverse = config.do_inverse; - do_shift = config.do_shift; - //scale_factor = config.scale_factor; + num_ffts = config.num_ffts; + do_inverse = config.do_inverse; + do_shift = config.do_shift; + // scale_factor = config.scale_factor; } - //printf("COMPUTE: logn_samples %u num_samples %u num_ffts %u inverse %u shift %u\n", logn_samples, num_samples, num_ffts, do_inverse, do_shift); + // printf("COMPUTE: logn_samples %u num_samples %u num_ffts %u inverse %u shift %u\n", + // logn_samples, num_samples, num_ffts, do_inverse, do_shift); // Compute // Loop through the num_ffts successive FFT computations { - uint32_t in_length = 2 * num_ffts * num_samples; - uint32_t out_length = in_length; - uint32_t out_rem = out_length; + uint32_t in_length = 2 * num_ffts * num_samples; + uint32_t out_length = in_length; + uint32_t out_rem = out_length; unsigned max_in_ffts = 1 << (MAX_LOGN_SAMPLES - logn_samples); - unsigned ffts_done = 0; - printf("COMPUTE: in_len %u : max_in_ffts %u >> %u = %u\n", in_length, MAX_LOGN_SAMPLES, logn_samples, max_in_ffts); + unsigned ffts_done = 0; + printf("COMPUTE: in_len %u : max_in_ffts %u >> %u = %u\n", in_length, MAX_LOGN_SAMPLES, + logn_samples, max_in_ffts); // Chunking : Load/Store Memory transfers (refill memory) - for (int in_rem = in_length; in_rem > 0; in_rem -= PLM_IN_WORD) - { - uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; + for (int in_rem = in_length; in_rem > 0; in_rem -= PLM_IN_WORD) { + uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; uint32_t out_len = out_rem > PLM_OUT_WORD ? PLM_OUT_WORD : out_rem; // Compute FFT(s) in the PLM - printf("COMPUTE INFO : in_rem %u : in_len %u :: out_rem %u : out_len %u\n", in_rem, in_len, out_rem, out_len); + printf("COMPUTE INFO : in_rem %u : in_len %u :: out_rem %u : out_len %u\n", in_rem, + in_len, out_rem, out_len); printf("COMPUTE hit the compute-load handshake...\n"); this->compute_load_handshake(); - unsigned rem_ffts = (num_ffts - ffts_done); - unsigned in_ffts = (rem_ffts > max_in_ffts) ? max_in_ffts : rem_ffts; - printf("COMPUTE has %u rem_ffts : proceeding to the next %u FFT computations...\n", rem_ffts, in_ffts); + unsigned rem_ffts = (num_ffts - ffts_done); + unsigned in_ffts = (rem_ffts > max_in_ffts) ? max_in_ffts : rem_ffts; + printf("COMPUTE has %u rem_ffts : proceeding to the next %u FFT computations...\n", + rem_ffts, in_ffts); for (unsigned fftn = 0; fftn < in_ffts; fftn++) { - unsigned offset = fftn * num_samples; // Offset into Mem for start of this FFT - printf("COMPUTE: starting FFT %u of %u = %u : offset = %u\n", fftn, in_ffts, ffts_done, offset); + unsigned offset = fftn * num_samples; // Offset into Mem for start of this FFT + printf("COMPUTE: starting FFT %u of %u = %u : offset = %u\n", fftn, in_ffts, + ffts_done, offset); int sin_sign = (do_inverse) ? -1 : 1; // This modifes the mySin // values used below if (do_inverse && do_shift) { - //printf("ACCEL: Calling Inverse-Do-Shift\n"); + // printf("ACCEL: Calling Inverse-Do-Shift\n"); fft2_do_shift(offset, num_samples, logn_samples); } @@ -335,38 +329,40 @@ void fft2::compute_kernel() fft2_bit_reverse(offset, num_samples, logn_samples); // Computing phase implementation - int m = 1; // iterative FFT + int m = 1; // iterative FFT - FFT2_SINGLE_L1: - for(unsigned s = 1; s <= logn_samples; s++) { - //printf(" L1 : FFT %u = %u : s %u\n", fftn, ffts_done, s); +FFT2_SINGLE_L1: + for (unsigned s = 1; s <= logn_samples; s++) { + // printf(" L1 : FFT %u = %u : s %u\n", fftn, ffts_done, s); m = 1 << s; - CompNum wm(myCos(s), sin_sign*mySin(s)); + CompNum wm(myCos(s), sin_sign * mySin(s)); // printf("s: %d\n", s); // printf("wm.re: %.15g, wm.im: %.15g\n", wm.re, wm.im); - FFT2_SINGLE_L2: - for(unsigned k = 0; k < num_samples; k +=m) { +FFT2_SINGLE_L2: + for (unsigned k = 0; k < num_samples; k += m) { // if (k < 2) { // printf(" L2 : FFT %u = %u : s %u : k %u\n", fftn, ffts_done, s, k); // } - CompNum w((FPDATA) 1, (FPDATA) 0); + CompNum w((FPDATA)1, (FPDATA)0); int md2 = m / 2; - FFT2_SINGLE_L3: - for(int j = 0; j < md2; j++) { +FFT2_SINGLE_L3: + for (int j = 0; j < md2; j++) { - int kj = offset + k + j; + int kj = offset + k + j; int kjm = offset + k + j + md2; // if ((k == 0) && (j == 0)) { - // printf(" L3 : FFT %u = %u : k %u j %u md2 %u : kj %u kjm %u : kji %u kjmi %u\n", fftn, ffts_done, k, j, md2, kj, kjm, 2*kj, 2*kjm); + // printf(" L3 : FFT %u = %u : k %u j %u md2 %u : kj %u kjm %u : + // kji %u kjmi %u\n", fftn, ffts_done, k, j, md2, kj, kjm, 2*kj, + // 2*kjm); // } CompNum akj, akjm; CompNum bkj, bkjm; - akj.re = int2fp(A0[2 * kj]); - akj.im = int2fp(A0[2 * kj + 1]); + akj.re = int2fp(A0[2 * kj]); + akj.im = int2fp(A0[2 * kj + 1]); akjm.re = int2fp(A0[2 * kjm]); akjm.im = int2fp(A0[2 * kjm + 1]); @@ -378,39 +374,42 @@ void fft2::compute_kernel() CompNum wwm; wwm.re = w.re - (wm.im * w.im + wm.re * w.re); wwm.im = w.im + (wm.im * w.re - wm.re * w.im); - w = wwm; + w = wwm; { HLS_PROTO("compute_write_A0"); HLS_BREAK_DEP(A0); wait(); - A0[2 * kj] = fp2int(bkj.re); + A0[2 * kj] = fp2int(bkj.re); A0[2 * kj + 1] = fp2int(bkj.im); wait(); - A0[2 * kjm] = fp2int(bkjm.re); + A0[2 * kjm] = fp2int(bkjm.re); A0[2 * kjm + 1] = fp2int(bkjm.im); - // cout << "DFT: A0 " << kj << ": " << A0[kj].re.to_hex() << " " << A0[kj].im.to_hex() << endl; - // cout << "DFT: A0 " << kjm << ": " << A0[kjm].re.to_hex() << " " << A0[kjm].im.to_hex() << endl; - // if ((k == 0) && (j == 0)) { - // printf(" L3 : WROTE A0 %u and %u and %u and %u\n", 2*kj, 2*kj + 1, 2*kjm, 2*kjm + 1); + // cout << "DFT: A0 " << kj << ": " << A0[kj].re.to_hex() << " " << + // A0[kj].im.to_hex() << endl; cout << "DFT: A0 " << kjm << ": " << + // A0[kjm].re.to_hex() << " " << A0[kjm].im.to_hex() << endl; if ((k + // == 0) && (j == 0)) { + // printf(" L3 : WROTE A0 %u and %u and %u and %u\n", 2*kj, + // 2*kj + 1, 2*kjm, 2*kjm + 1); // } } } // for (j = 0 .. md2) - } // for (k = 0 .. num_samples) - } // for (s = 1 .. logn_samples) + } // for (k = 0 .. num_samples) + } // for (s = 1 .. logn_samples) if ((!do_inverse) && (do_shift)) { - //printf("ACCEL: Calling Non-Inverse Do-Shift\n"); + // printf("ACCEL: Calling Non-Inverse Do-Shift\n"); fft2_do_shift(offset, num_samples, logn_samples); } - //printf("COMPUTE: done with FF %u = %u\n", fftn, ffts_done); - /*cout << "ACCEL-END : FFT " << ffts_done << " : A0[0] = " << A0[0].to_double() << endl; - cout << "ACCEL-END : FFT " << ffts_done << " : A0[1] = " << A0[1].to_double() << endl; - cout << "ACCEL-END : FFT " << ffts_done << " : A0[2] = " << A0[2].to_double() << endl; - cout << "ACCEL-END : FFT " << ffts_done << " : A0[3] = " << A0[3].to_double() << endl;*/ + // printf("COMPUTE: done with FF %u = %u\n", fftn, ffts_done); + /*cout << "ACCEL-END : FFT " << ffts_done << " : A0[0] = " << A0[0].to_double() << + endl; cout << "ACCEL-END : FFT " << ffts_done << " : A0[1] = " << + A0[1].to_double() << endl; cout << "ACCEL-END : FFT " << ffts_done << " : A0[2] = + " << A0[2].to_double() << endl; cout << "ACCEL-END : FFT " << ffts_done << " : + A0[3] = " << A0[3].to_double() << endl;*/ ffts_done++; - offset += num_samples; // Offset into Mem for start of this FFT - } // for( n = 0 .. mnum_ffts) + offset += num_samples; // Offset into Mem for start of this FFT + } // for( n = 0 .. mnum_ffts) out_rem -= PLM_OUT_WORD; printf("COMPUTE hit the compute-store handshake...\n"); this->compute_store_handshake(); diff --git a/accelerators/stratus_hls/fft2_stratus/hw/tb/BAK/fft2_test.cpp b/accelerators/stratus_hls/fft2_stratus/hw/tb/BAK/fft2_test.cpp index 8df7ad8f27..ddac29a2cc 100644 --- a/accelerators/stratus_hls/fft2_stratus/hw/tb/BAK/fft2_test.cpp +++ b/accelerators/stratus_hls/fft2_stratus/hw/tb/BAK/fft2_test.cpp @@ -1,13 +1,13 @@ +#include #include #include -#include #include "fft2_test.hpp" unsigned int fft2_rev(unsigned int v) { unsigned int r = v; - int s = sizeof(v) * CHAR_BIT - 1; + int s = sizeof(v) * CHAR_BIT - 1; for (v >>= 1; v; v >>= 1) { r <<= 1; @@ -22,7 +22,7 @@ void fft2_bit_reverse(float *w, unsigned int offset, unsigned int n, unsigned in { unsigned int i, s, shift; - s = sizeof(i) * CHAR_BIT - 1; + s = sizeof(i) * CHAR_BIT - 1; shift = s - bits + 1; for (i = 0; i < n; i++) { @@ -33,30 +33,29 @@ void fft2_bit_reverse(float *w, unsigned int offset, unsigned int n, unsigned in r >>= shift; if (i < r) { - t_real = w[2 * (offset + i)]; - t_imag = w[2 * (offset + i) + 1]; - w[2 * (offset + i)] = w[2 * (offset + r)]; + t_real = w[2 * (offset + i)]; + t_imag = w[2 * (offset + i) + 1]; + w[2 * (offset + i)] = w[2 * (offset + r)]; w[2 * (offset + i) + 1] = w[2 * (offset + r) + 1]; - w[2 * (offset + r)] = t_real; + w[2 * (offset + r)] = t_real; w[2 * (offset + r) + 1] = t_imag; } } - } - void fft2_do_shift(float *A0, unsigned int offset, unsigned int num_samples, unsigned int bits) { - int md = (num_samples/2); + int md = (num_samples / 2); /* shift: */ - for(unsigned oi = 0; oi < md; oi++) { - unsigned int iidx = 2*(offset + oi); - unsigned int midx = 2*(offset + md + oi); - //printf("TEST: DO_SHIFT: offset %u : iidx %u %u midx %u %u\n", offset, iidx, (iidx+1), midx, (midx+1)); + for (unsigned oi = 0; oi < md; oi++) { + unsigned int iidx = 2 * (offset + oi); + unsigned int midx = 2 * (offset + md + oi); + // printf("TEST: DO_SHIFT: offset %u : iidx %u %u midx %u %u\n", offset, iidx, (iidx+1), + // midx, (midx+1)); float swap_rl, swap_im; - swap_rl = A0[iidx]; - swap_im = A0[iidx + 1]; + swap_rl = A0[iidx]; + swap_im = A0[iidx + 1]; A0[iidx] = A0[midx]; A0[iidx + 1] = A0[midx + 1]; A0[midx] = swap_rl; @@ -64,41 +63,43 @@ void fft2_do_shift(float *A0, unsigned int offset, unsigned int num_samples, uns } } - -int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, int do_inverse, int do_shift) +int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, int do_inverse, + int do_shift) { for (int nf = 0; nf < nffts; nf++) { - unsigned int transform_length; - unsigned int a, b, i, j, bit; - float theta, t_real, t_imag, w_real, w_imag, s, t, s2, z_real, z_imag; + unsigned int transform_length; + unsigned int a, b, i, j, bit; + float theta, t_real, t_imag, w_real, w_imag, s, t, s2, z_real, z_imag; - unsigned int offset = nf * n; // This is the offset for start of nf=th FFT + unsigned int offset = nf * n; // This is the offset for start of nf=th FFT int sign; - //printf("TEST : Doing computation of FFT %u : data[%u] = %.15g\n", nf, 2*offset, data[2*offset]); + // printf("TEST : Doing computation of FFT %u : data[%u] = %.15g\n", nf, 2*offset, + // data[2*offset]); if (do_inverse) { sign = 1; if (do_shift) { - //printf("TEST: Calling Inverse-Do-Shift\n"); + // printf("TEST: Calling Inverse-Do-Shift\n"); fft2_do_shift(data, offset, n, logn); } - } else { + } + else { sign = -1; } - transform_length = 1; + transform_length = 1; // Do the bit-reverse fft2_bit_reverse(data, offset, n, logn); - /* calculation */ - for (bit = 0; bit < logn; bit++) { + /* calculation */ + for (bit = 0; bit < logn; bit++) { w_real = 1.0; w_imag = 0.0; - theta = 1.0 * sign * M_PI / (float) transform_length; + theta = 1.0 * sign * M_PI / (float)transform_length; - s = sin(theta); - t = sin(0.5 * theta); + s = sin(theta); + t = sin(0.5 * theta); s2 = 2.0 * t * t; for (a = 0; a < transform_length; a++) { @@ -113,10 +114,10 @@ int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, in t_imag = w_real * z_imag + w_imag * z_real; /* write the result */ - data[2*j] = data[2*i] - t_real; - data[2*j + 1] = data[2*i + 1] - t_imag; - data[2*i] += t_real; - data[2*i + 1] += t_imag; + data[2 * j] = data[2 * i] - t_real; + data[2 * j + 1] = data[2 * i + 1] - t_imag; + data[2 * i] += t_real; + data[2 * i + 1] += t_imag; } // for (b = 0 .. n by 2*transform_length /* adjust w */ @@ -127,10 +128,10 @@ int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, in } // for (a = 0 .. transform_length) transform_length *= 2; - } // for (bit = 0 .. logn ) + } // for (bit = 0 .. logn ) if ((!do_inverse) && do_shift) { - //printf("TEST: Calling Non-Inverse Do-Shift\n"); + // printf("TEST: Calling Non-Inverse Do-Shift\n"); fft2_do_shift(data, offset, n, logn); } diff --git a/accelerators/stratus_hls/fft2_stratus/hw/tb/fft2_test.cpp b/accelerators/stratus_hls/fft2_stratus/hw/tb/fft2_test.cpp index 8df7ad8f27..ddac29a2cc 100644 --- a/accelerators/stratus_hls/fft2_stratus/hw/tb/fft2_test.cpp +++ b/accelerators/stratus_hls/fft2_stratus/hw/tb/fft2_test.cpp @@ -1,13 +1,13 @@ +#include #include #include -#include #include "fft2_test.hpp" unsigned int fft2_rev(unsigned int v) { unsigned int r = v; - int s = sizeof(v) * CHAR_BIT - 1; + int s = sizeof(v) * CHAR_BIT - 1; for (v >>= 1; v; v >>= 1) { r <<= 1; @@ -22,7 +22,7 @@ void fft2_bit_reverse(float *w, unsigned int offset, unsigned int n, unsigned in { unsigned int i, s, shift; - s = sizeof(i) * CHAR_BIT - 1; + s = sizeof(i) * CHAR_BIT - 1; shift = s - bits + 1; for (i = 0; i < n; i++) { @@ -33,30 +33,29 @@ void fft2_bit_reverse(float *w, unsigned int offset, unsigned int n, unsigned in r >>= shift; if (i < r) { - t_real = w[2 * (offset + i)]; - t_imag = w[2 * (offset + i) + 1]; - w[2 * (offset + i)] = w[2 * (offset + r)]; + t_real = w[2 * (offset + i)]; + t_imag = w[2 * (offset + i) + 1]; + w[2 * (offset + i)] = w[2 * (offset + r)]; w[2 * (offset + i) + 1] = w[2 * (offset + r) + 1]; - w[2 * (offset + r)] = t_real; + w[2 * (offset + r)] = t_real; w[2 * (offset + r) + 1] = t_imag; } } - } - void fft2_do_shift(float *A0, unsigned int offset, unsigned int num_samples, unsigned int bits) { - int md = (num_samples/2); + int md = (num_samples / 2); /* shift: */ - for(unsigned oi = 0; oi < md; oi++) { - unsigned int iidx = 2*(offset + oi); - unsigned int midx = 2*(offset + md + oi); - //printf("TEST: DO_SHIFT: offset %u : iidx %u %u midx %u %u\n", offset, iidx, (iidx+1), midx, (midx+1)); + for (unsigned oi = 0; oi < md; oi++) { + unsigned int iidx = 2 * (offset + oi); + unsigned int midx = 2 * (offset + md + oi); + // printf("TEST: DO_SHIFT: offset %u : iidx %u %u midx %u %u\n", offset, iidx, (iidx+1), + // midx, (midx+1)); float swap_rl, swap_im; - swap_rl = A0[iidx]; - swap_im = A0[iidx + 1]; + swap_rl = A0[iidx]; + swap_im = A0[iidx + 1]; A0[iidx] = A0[midx]; A0[iidx + 1] = A0[midx + 1]; A0[midx] = swap_rl; @@ -64,41 +63,43 @@ void fft2_do_shift(float *A0, unsigned int offset, unsigned int num_samples, uns } } - -int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, int do_inverse, int do_shift) +int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, int do_inverse, + int do_shift) { for (int nf = 0; nf < nffts; nf++) { - unsigned int transform_length; - unsigned int a, b, i, j, bit; - float theta, t_real, t_imag, w_real, w_imag, s, t, s2, z_real, z_imag; + unsigned int transform_length; + unsigned int a, b, i, j, bit; + float theta, t_real, t_imag, w_real, w_imag, s, t, s2, z_real, z_imag; - unsigned int offset = nf * n; // This is the offset for start of nf=th FFT + unsigned int offset = nf * n; // This is the offset for start of nf=th FFT int sign; - //printf("TEST : Doing computation of FFT %u : data[%u] = %.15g\n", nf, 2*offset, data[2*offset]); + // printf("TEST : Doing computation of FFT %u : data[%u] = %.15g\n", nf, 2*offset, + // data[2*offset]); if (do_inverse) { sign = 1; if (do_shift) { - //printf("TEST: Calling Inverse-Do-Shift\n"); + // printf("TEST: Calling Inverse-Do-Shift\n"); fft2_do_shift(data, offset, n, logn); } - } else { + } + else { sign = -1; } - transform_length = 1; + transform_length = 1; // Do the bit-reverse fft2_bit_reverse(data, offset, n, logn); - /* calculation */ - for (bit = 0; bit < logn; bit++) { + /* calculation */ + for (bit = 0; bit < logn; bit++) { w_real = 1.0; w_imag = 0.0; - theta = 1.0 * sign * M_PI / (float) transform_length; + theta = 1.0 * sign * M_PI / (float)transform_length; - s = sin(theta); - t = sin(0.5 * theta); + s = sin(theta); + t = sin(0.5 * theta); s2 = 2.0 * t * t; for (a = 0; a < transform_length; a++) { @@ -113,10 +114,10 @@ int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, in t_imag = w_real * z_imag + w_imag * z_real; /* write the result */ - data[2*j] = data[2*i] - t_real; - data[2*j + 1] = data[2*i + 1] - t_imag; - data[2*i] += t_real; - data[2*i + 1] += t_imag; + data[2 * j] = data[2 * i] - t_real; + data[2 * j + 1] = data[2 * i + 1] - t_imag; + data[2 * i] += t_real; + data[2 * i + 1] += t_imag; } // for (b = 0 .. n by 2*transform_length /* adjust w */ @@ -127,10 +128,10 @@ int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, in } // for (a = 0 .. transform_length) transform_length *= 2; - } // for (bit = 0 .. logn ) + } // for (bit = 0 .. logn ) if ((!do_inverse) && do_shift) { - //printf("TEST: Calling Non-Inverse Do-Shift\n"); + // printf("TEST: Calling Non-Inverse Do-Shift\n"); fft2_do_shift(data, offset, n, logn); } diff --git a/accelerators/stratus_hls/fft2_stratus/sw/baremetal/fft2.c b/accelerators/stratus_hls/fft2_stratus/sw/baremetal/fft2.c index 691e5b9231..bccc3c4e1d 100644 --- a/accelerators/stratus_hls/fft2_stratus/sw/baremetal/fft2.c +++ b/accelerators/stratus_hls/fft2_stratus/sw/baremetal/fft2.c @@ -3,44 +3,40 @@ #include #ifndef __riscv -#include + #include #endif +#include "utils/fft2_utils.h" #include #include -#include "utils/fft2_utils.h" #if (FFT2_FX_WIDTH == 64) typedef long long token_t; typedef double native_t; -#define fx2float fixed64_to_double -#define float2fx double_to_fixed64 -#define FX_IL 42 + #define fx2float fixed64_to_double + #define float2fx double_to_fixed64 + #define FX_IL 42 #else // (FFT2_FX_WIDTH == 32) typedef int token_t; typedef float native_t; -#define fx2float fixed32_to_float -#define float2fx float_to_fixed32 -#define FX_IL 14 + #define fx2float fixed32_to_float + #define float2fx float_to_fixed32 + #define FX_IL 14 #endif /* FFT2_FX_WIDTH */ const float ERR_TH = 0.05; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} - +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } #define SLD_FFT2 0x057 #define DEV_NAME "sld,fft2_stratus" /* <<--params-->> */ const int32_t logn_samples = 3; -const int32_t num_samples = (1 << logn_samples); -const int32_t num_ffts = 1; -const int32_t do_inverse = 0; -const int32_t do_shift = 0; +const int32_t num_samples = (1 << logn_samples); +const int32_t num_ffts = 1; +const int32_t do_inverse = 0; +const int32_t do_shift = 0; const int32_t scale_factor = 1; int32_t len; @@ -55,201 +51,198 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ #define FFT2_LOGN_SAMPLES_REG 0x40 -#define FFT2_NUM_FFTS_REG 0x44 -#define FFT2_DO_INVERSE_REG 0x48 -#define FFT2_DO_SHIFT_REG 0x4c +#define FFT2_NUM_FFTS_REG 0x44 +#define FFT2_DO_INVERSE_REG 0x48 +#define FFT2_DO_SHIFT_REG 0x4c #define FFT2_SCALE_FACTOR_REG 0x50 - static int validate_buf(token_t *out, float *gold) { - int j; - unsigned errors = 0; - - for (j = 0; j < 2 * len; j++) { - native_t val = fx2float(out[j], FX_IL); - uint32_t ival = *((uint32_t*)&val); - printf(" GOLD[%u] = 0x%08x : OUT[%u] = 0x%08x\n", j, ((uint32_t*)gold)[j], j, ival); - if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) - errors++; - } - - //printf(" %u errors\n", errors); - return errors; + int j; + unsigned errors = 0; + + for (j = 0; j < 2 * len; j++) { + native_t val = fx2float(out[j], FX_IL); + uint32_t ival = *((uint32_t *)&val); + printf(" GOLD[%u] = 0x%08x : OUT[%u] = 0x%08x\n", j, ((uint32_t *)gold)[j], j, ival); + if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) errors++; + } + + // printf(" %u errors\n", errors); + return errors; } - static void init_buf(token_t *in, float *gold) { - int j; - const float LO = -10.0; - const float HI = 10.0; + int j; + const float LO = -10.0; + const float HI = 10.0; - /* srand((unsigned int) time(NULL)); */ + /* srand((unsigned int) time(NULL)); */ - for (j = 0; j < 2 * len; j++) { - float scaling_factor = (float) rand () / (float) RAND_MAX; - gold[j] = LO + scaling_factor * (HI - LO); - uint32_t ig = ((uint32_t*)gold)[j]; - printf(" IN[%u] = 0x%08x\n", j, ig); - } + for (j = 0; j < 2 * len; j++) { + float scaling_factor = (float)rand() / (float)RAND_MAX; + gold[j] = LO + scaling_factor * (HI - LO); + uint32_t ig = ((uint32_t *)gold)[j]; + printf(" IN[%u] = 0x%08x\n", j, ig); + } - // convert input to fixed point - for (j = 0; j < 2 * len; j++) - in[j] = float2fx((native_t) gold[j], FX_IL); + // convert input to fixed point + for (j = 0; j < 2 * len; j++) + in[j] = float2fx((native_t)gold[j], FX_IL); - // Compute golden output - fft2_comp(gold, num_ffts, num_samples, logn_samples, do_inverse, do_shift); + // Compute golden output + fft2_comp(gold, num_ffts, num_samples, logn_samples, do_inverse, do_shift); } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned spin_ct; - unsigned **ptable = NULL; - token_t *mem; - float *gold; - unsigned errors = 0; - unsigned coherence; - const float ERROR_COUNT_TH = 0.001; - - len = num_ffts * (1 << logn_samples); - printf("logn %u nsmp %u nfft %u inv %u shft %u len %u\n", logn_samples, num_samples, num_ffts, do_inverse, do_shift, len); - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * len; - out_words_adj = 2 * len; - } else { - in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = 0; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - printf("ilen %u isize %u o_off %u olen %u osize %u msize %u\n", in_len, out_len, in_size, out_size, out_offset, mem_size); - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_FFT2, DEV_NAME); - if (ndev == 0) { - printf("%s not found\n", DEV_NAME); - return 0; - } - - for (n = 0; n < ndev; n++) { - - printf("**************** %s.%d ****************\n", DEV_NAME, n); - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_len * sizeof(float)); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - - // Allocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned spin_ct; + unsigned **ptable = NULL; + token_t *mem; + float *gold; + unsigned errors = 0; + unsigned coherence; + const float ERROR_COUNT_TH = 0.001; + + len = num_ffts * (1 << logn_samples); + printf("logn %u nsmp %u nfft %u inv %u shft %u len %u\n", logn_samples, num_samples, num_ffts, + do_inverse, do_shift, len); + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * len; + out_words_adj = 2 * len; + } + else { + in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = 0; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + printf("ilen %u isize %u o_off %u olen %u osize %u msize %u\n", in_len, out_len, in_size, + out_size, out_offset, mem_size); + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_FFT2, DEV_NAME); + if (ndev == 0) { + printf("%s not found\n", DEV_NAME); + return 0; + } + + for (n = 0; n < ndev; n++) { + + printf("**************** %s.%d ****************\n", DEV_NAME, n); + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_len * sizeof(float)); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); + + // Allocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - printf(" --------------------\n"); - printf(" Generate input...\n"); - init_buf(mem, gold); + printf(" --------------------\n"); + printf(" Generate input...\n"); + init_buf(mem, gold); - // Pass common configuration parameters + // Pass common configuration parameters - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); #ifndef __sparc - iowrite32(dev, PT_ADDRESS_REG, (unsigned long long) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned long long)ptable); #else - iowrite32(dev, PT_ADDRESS_REG, (unsigned) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned)ptable); #endif - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - iowrite32(dev, FFT2_LOGN_SAMPLES_REG, logn_samples); - iowrite32(dev, FFT2_NUM_FFTS_REG, num_ffts); - iowrite32(dev, FFT2_SCALE_FACTOR_REG, scale_factor); - iowrite32(dev, FFT2_DO_SHIFT_REG, do_shift); - iowrite32(dev, FFT2_DO_INVERSE_REG, do_inverse); - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - spin_ct = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - spin_ct++; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done : spin_count = %u\n", spin_ct); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - if ((float)((float)errors / (2.0 * (float)len)) > ERROR_COUNT_TH) - printf(" ... FAIL : %u errors out of %u\n", errors, 2*len); - else - printf(" ... PASS : %u errors out of %u\n", errors, 2*len); - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + iowrite32(dev, FFT2_LOGN_SAMPLES_REG, logn_samples); + iowrite32(dev, FFT2_NUM_FFTS_REG, num_ffts); + iowrite32(dev, FFT2_SCALE_FACTOR_REG, scale_factor); + iowrite32(dev, FFT2_DO_SHIFT_REG, do_shift); + iowrite32(dev, FFT2_DO_INVERSE_REG, do_inverse); + + // Flush (customize coherence model here) + esp_flush(coherence); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + spin_ct = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + spin_ct++; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done : spin_count = %u\n", spin_ct); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + if ((float)((float)errors / (2.0 * (float)len)) > ERROR_COUNT_TH) + printf(" ... FAIL : %u errors out of %u\n", errors, 2 * len); + else + printf(" ... PASS : %u errors out of %u\n", errors, 2 * len); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/accelerators/stratus_hls/fft2_stratus/sw/linux/app/fft2.c b/accelerators/stratus_hls/fft2_stratus/sw/linux/app/fft2.c index 6c35d43e0a..cc42060407 100644 --- a/accelerators/stratus_hls/fft2_stratus/sw/linux/app/fft2.c +++ b/accelerators/stratus_hls/fft2_stratus/sw/linux/app/fft2.c @@ -15,114 +15,111 @@ const float ERR_TH = 0.05; /* User-defined code */ static int validate_buffer(token_t *out, float *gold) { - int j; - unsigned errors = 0; - const unsigned num_samples = 1< ERR_TH) { - if (errors < 2) { - printf(" GOLD[%u] = %f vs %f = out[%u]\n", j, gold[j], val, j); - } - errors++; - } - } - printf(" + Relative error > %.02f for %d values out of %d\n", ERR_TH, errors, 2 * num_ffts * num_samples); - - return errors; + int j; + unsigned errors = 0; + const unsigned num_samples = 1 << logn_samples; + + for (j = 0; j < 2 * num_ffts * num_samples; j++) { + native_t val = fx2float(out[j], FX_IL); + + if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) { + if (errors < 2) { printf(" GOLD[%u] = %f vs %f = out[%u]\n", j, gold[j], val, j); } + errors++; + } + } + printf(" + Relative error > %.02f for %d values out of %d\n", ERR_TH, errors, + 2 * num_ffts * num_samples); + + return errors; } - /* User-defined code */ static void init_buffer(token_t *in, float *gold) { - int j; - const float LO = -2.0; - const float HI = 2.0; - const unsigned num_samples = (1 << logn_samples); + int j; + const float LO = -2.0; + const float HI = 2.0; + const unsigned num_samples = (1 << logn_samples); - srand((unsigned int) time(NULL)); + srand((unsigned int)time(NULL)); - for (j = 0; j < 2 * num_ffts * num_samples; j++) { - float scaling_factor = (float) rand () / (float) RAND_MAX; - gold[j] = LO + scaling_factor * (HI - LO); - } + for (j = 0; j < 2 * num_ffts * num_samples; j++) { + float scaling_factor = (float)rand() / (float)RAND_MAX; + gold[j] = LO + scaling_factor * (HI - LO); + } - // convert input to fixed point - for (j = 0; j < 2 * num_ffts * num_samples; j++) { - in[j] = float2fx((native_t) gold[j], FX_IL); - } + // convert input to fixed point + for (j = 0; j < 2 * num_ffts * num_samples; j++) { + in[j] = float2fx((native_t)gold[j], FX_IL); + } - // Compute golden output - fft2_comp(gold, num_ffts, (1<> */ - printf(" .logn_samples = %d\n", logn_samples); - printf(" num_samples = %d\n", (1 << logn_samples)); - printf(" .num_ffts = %d\n", num_ffts); - printf(" .do_inverse = %d\n", do_inverse); - printf(" .do_shift = %d\n", do_shift); - printf(" .scale_factor = %d\n", scale_factor); - printf("\n ** START **\n"); - init_buffer(buf, gold); + printf("\n====== %s ======\n\n", cfg_000[0].devname); + /* <<--print-params-->> */ + printf(" .logn_samples = %d\n", logn_samples); + printf(" num_samples = %d\n", (1 << logn_samples)); + printf(" .num_ffts = %d\n", num_ffts); + printf(" .do_inverse = %d\n", do_inverse); + printf(" .do_shift = %d\n", do_shift); + printf(" .scale_factor = %d\n", scale_factor); + printf("\n ** START **\n"); + init_buffer(buf, gold); - esp_run(cfg_000, NACC); + esp_run(cfg_000, NACC); - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - errors = validate_buffer(&buf[out_offset], gold); + errors = validate_buffer(&buf[out_offset], gold); - free(gold); - esp_free(buf); + free(gold); + esp_free(buf); - if ((float)(errors / (float)(2.0 * (float)num_ffts * (float)num_samples)) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + if ((float)(errors / (float)(2.0 * (float)num_ffts * (float)num_samples)) > ERROR_COUNT_TH) + printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - printf("\n====== %s ======\n\n", cfg_000[0].devname); + printf("\n====== %s ======\n\n", cfg_000[0].devname); - return errors; + return errors; } diff --git a/accelerators/stratus_hls/fft2_stratus/sw/linux/driver/fft2_stratus.c b/accelerators/stratus_hls/fft2_stratus/sw/linux/driver/fft2_stratus.c index ed4cbcf7f1..8a6fc740eb 100644 --- a/accelerators/stratus_hls/fft2_stratus/sw/linux/driver/fft2_stratus.c +++ b/accelerators/stratus_hls/fft2_stratus/sw/linux/driver/fft2_stratus.c @@ -1,135 +1,127 @@ -#include #include +#include #include -#include #include +#include #include "fft2_stratus.h" -#define DRV_NAME "fft2_stratus" +#define DRV_NAME "fft2_stratus" /* <<--regs-->> */ #define FFT2_LOGN_SAMPLES_REG 0x40 -#define FFT2_NUM_FFTS_REG 0x44 -#define FFT2_DO_INVERSE_REG 0x48 -#define FFT2_DO_SHIFT_REG 0x4c +#define FFT2_NUM_FFTS_REG 0x44 +#define FFT2_DO_INVERSE_REG 0x48 +#define FFT2_DO_SHIFT_REG 0x4c #define FFT2_SCALE_FACTOR_REG 0x50 struct fft2_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver fft2_driver; static struct of_device_id fft2_device_ids[] = { - { - .name = "SLD_FFT2_STRATUS", - }, - { - .name = "eb_057", - }, - { - .compatible = "sld,fft2_stratus", - }, - { }, + { + .name = "SLD_FFT2_STRATUS", + }, + { + .name = "eb_057", + }, + { + .compatible = "sld,fft2_stratus", + }, + {}, }; static int fft2_devs; static inline struct fft2_stratus_device *to_fft2(struct esp_device *esp) { - return container_of(esp, struct fft2_stratus_device, esp); + return container_of(esp, struct fft2_stratus_device, esp); } static void fft2_prep_xfer(struct esp_device *esp, void *arg) { - struct fft2_stratus_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->scale_factor, esp->iomem + FFT2_SCALE_FACTOR_REG); - iowrite32be(a->do_inverse, esp->iomem + FFT2_DO_INVERSE_REG); - iowrite32be(a->logn_samples, esp->iomem + FFT2_LOGN_SAMPLES_REG); - iowrite32be(a->do_shift, esp->iomem + FFT2_DO_SHIFT_REG); - iowrite32be(a->num_ffts, esp->iomem + FFT2_NUM_FFTS_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); - + struct fft2_stratus_access *a = arg; + + /* <<--regs-config-->> */ + iowrite32be(a->scale_factor, esp->iomem + FFT2_SCALE_FACTOR_REG); + iowrite32be(a->do_inverse, esp->iomem + FFT2_DO_INVERSE_REG); + iowrite32be(a->logn_samples, esp->iomem + FFT2_LOGN_SAMPLES_REG); + iowrite32be(a->do_shift, esp->iomem + FFT2_DO_SHIFT_REG); + iowrite32be(a->num_ffts, esp->iomem + FFT2_NUM_FFTS_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool fft2_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct fft2_stratus_device *fft2 = to_fft2(esp); */ - /* struct fft2_stratus_access *a = arg; */ + /* struct fft2_stratus_device *fft2 = to_fft2(esp); */ + /* struct fft2_stratus_access *a = arg; */ - return true; + return true; } static int fft2_probe(struct platform_device *pdev) { - struct fft2_stratus_device *fft2; - struct esp_device *esp; - int rc; - - fft2 = kzalloc(sizeof(*fft2), GFP_KERNEL); - if (fft2 == NULL) - return -ENOMEM; - esp = &fft2->esp; - esp->module = THIS_MODULE; - esp->number = fft2_devs; - esp->driver = &fft2_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - fft2_devs++; - return 0; - err: - kfree(fft2); - return rc; + struct fft2_stratus_device *fft2; + struct esp_device *esp; + int rc; + + fft2 = kzalloc(sizeof(*fft2), GFP_KERNEL); + if (fft2 == NULL) return -ENOMEM; + esp = &fft2->esp; + esp->module = THIS_MODULE; + esp->number = fft2_devs; + esp->driver = &fft2_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + fft2_devs++; + return 0; +err: + kfree(fft2); + return rc; } static int __exit fft2_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct fft2_stratus_device *fft2 = to_fft2(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct fft2_stratus_device *fft2 = to_fft2(esp); - esp_device_unregister(esp); - kfree(fft2); - return 0; + esp_device_unregister(esp); + kfree(fft2); + return 0; } static struct esp_driver fft2_driver = { - .plat = { - .probe = fft2_probe, - .remove = fft2_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = fft2_device_ids, - }, - }, - .xfer_input_ok = fft2_xfer_input_ok, - .prep_xfer = fft2_prep_xfer, - .ioctl_cm = FFT2_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct fft2_stratus_access), + .plat = + { + .probe = fft2_probe, + .remove = fft2_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = fft2_device_ids, + }, + }, + .xfer_input_ok = fft2_xfer_input_ok, + .prep_xfer = fft2_prep_xfer, + .ioctl_cm = FFT2_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct fft2_stratus_access), }; -static int __init fft2_init(void) -{ - return esp_driver_register(&fft2_driver); -} +static int __init fft2_init(void) { return esp_driver_register(&fft2_driver); } -static void __exit fft2_exit(void) -{ - esp_driver_unregister(&fft2_driver); -} +static void __exit fft2_exit(void) { esp_driver_unregister(&fft2_driver); } -module_init(fft2_init) -module_exit(fft2_exit) +module_init(fft2_init) module_exit(fft2_exit) -MODULE_DEVICE_TABLE(of, fft2_device_ids); + MODULE_DEVICE_TABLE(of, fft2_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/fft2_stratus/sw/linux/include/fft2_stratus.h b/accelerators/stratus_hls/fft2_stratus/sw/linux/include/fft2_stratus.h index 5ba04b2fca..660fbb765d 100644 --- a/accelerators/stratus_hls/fft2_stratus/sw/linux/include/fft2_stratus.h +++ b/accelerators/stratus_hls/fft2_stratus/sw/linux/include/fft2_stratus.h @@ -2,31 +2,31 @@ #define _FFT2_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct fft2_stratus_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned scale_factor; - unsigned do_inverse; - unsigned logn_samples; - unsigned do_shift; - unsigned num_ffts; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned scale_factor; + unsigned do_inverse; + unsigned logn_samples; + unsigned do_shift; + unsigned num_ffts; + unsigned src_offset; + unsigned dst_offset; }; -#define FFT2_STRATUS_IOC_ACCESS _IOW ('S', 0, struct fft2_stratus_access) +#define FFT2_STRATUS_IOC_ACCESS _IOW('S', 0, struct fft2_stratus_access) #endif /* _FFT2_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/fft_stratus/hw/src/fft.cpp b/accelerators/stratus_hls/fft_stratus/hw/src/fft.cpp index 2690b68c80..344e66b514 100644 --- a/accelerators/stratus_hls/fft_stratus/hw/src/fft.cpp +++ b/accelerators/stratus_hls/fft_stratus/hw/src/fft.cpp @@ -41,9 +41,9 @@ void fft::load_input() // User-defined config code /* <<--local-params-->> */ batch_size = config.batch_size; - log_len = config.log_len; - len = 1 << log_len; - pingpong = 0; + log_len = config.log_len; + len = 1 << log_len; + pingpong = 0; } // Load @@ -72,25 +72,21 @@ void fft::load_input() #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - for (uint16_t i = 0; i < length; i++) - { + for (uint16_t i = 0; i < length; i++) { sc_dt::sc_bv dataBv; - for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) - { - dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH) = this->dma_read_chnl.get(); + for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) { + dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH) = this->dma_read_chnl.get(); wait(); } // Write to PLM - if (!pingpong) - PLM_IN_PING[i] = dataBv.to_int64(); + if (!pingpong) PLM_IN_PING[i] = dataBv.to_int64(); else PLM_IN_PONG[i] = dataBv.to_int64(); } #else - for (uint16_t i = 0; i < length; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < length; i += DMA_WORD_PER_BEAT) { HLS_BREAK_DEP(PLM_IN_PING); HLS_BREAK_DEP(PLM_IN_PONG); @@ -100,15 +96,14 @@ void fft::load_input() wait(); // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; if (!pingpong) PLM_IN_PING[i + k] = - dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); else PLM_IN_PONG[i + k] = - dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); } } #endif @@ -122,8 +117,6 @@ void fft::load_input() } } - - void fft::store_output() { // Reset @@ -154,9 +147,9 @@ void fft::store_output() // User-defined config code /* <<--local-params-->> */ batch_size = config.batch_size; - log_len = config.log_len; - len = 1 << log_len; - pingpong = 0; + log_len = config.log_len; + len = 1 << log_len; + pingpong = 0; } // Store @@ -173,7 +166,7 @@ void fft::store_output() #if (DMA_WORD_PER_BEAT == 0) uint32_t length = 2 * len; #else - uint32_t length = round_up(2 * len, DMA_WORD_PER_BEAT); + uint32_t length = round_up(2 * len, DMA_WORD_PER_BEAT); #endif this->store_compute_handshake(); @@ -190,42 +183,37 @@ void fft::store_output() #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - for (uint16_t i = 0; i < length; i++) - { + for (uint16_t i = 0; i < length; i++) { // Read from PLM sc_dt::sc_int data; wait(); - if (!pingpong) - data = PLM_OUT_PING[i]; + if (!pingpong) data = PLM_OUT_PING[i]; else data = PLM_OUT_PONG[i]; sc_dt::sc_bv dataBv(data); uint16_t k = 0; - for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) - { - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) { + this->dma_write_chnl.put(dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); wait(); } // Last beat on the bus does not require wait(), which is // placed before accessing the PLM - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + this->dma_write_chnl.put(dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); } #else - for (uint16_t i = 0; i < length; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < length; i += DMA_WORD_PER_BEAT) { sc_dt::sc_bv dataBv; // Read from PLM wait(); - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; if (!pingpong) - dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH) = PLM_OUT_PING[i + k]; + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = PLM_OUT_PING[i + k]; else - dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH) = PLM_OUT_PONG[i + k]; + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = PLM_OUT_PONG[i + k]; } this->dma_write_chnl.put(dataBv); } @@ -233,14 +221,13 @@ void fft::store_output() pingpong = !pingpong; } -// Conclude + // Conclude { this->accelerator_done(); this->process_done(); } } - void fft::compute_kernel() { // Reset @@ -273,14 +260,14 @@ void fft::compute_kernel() // User-defined config code /* <<--local-params-->> */ batch_size = config.batch_size; - log_len = config.log_len; + log_len = config.log_len; #ifndef STRATUS_HLS sc_assert(log_len < LOG_LEN_MAX); #endif - len = 1 << log_len; - do_peak = config.do_peak; + len = 1 << log_len; + do_peak = config.do_peak; do_bitrev = config.do_bitrev; - pingpong = 0; + pingpong = 0; } // Compute FFT single pass (FIXME: assume vector fits in the PLM) @@ -289,43 +276,43 @@ void fft::compute_kernel() this->compute_load_handshake(); // Optional step: bit reverse - if (do_bitrev) - fft_bit_reverse(len, log_len, pingpong); + if (do_bitrev) fft_bit_reverse(len, log_len, pingpong); // Computing phase implementation - int m = 1; // iterative FFT + int m = 1; // iterative FFT - FFT_SINGLE_L1: - for(unsigned s = 1; s <= log_len; s++) { +FFT_SINGLE_L1: + for (unsigned s = 1; s <= log_len; s++) { m = 1 << s; CompNum wm(myCos(s), mySin(s)); // printf("s: %d\n", s); // printf("wm.re: %.15g, wm.im: %.15g\n", wm.re, wm.im); - FFT_SINGLE_L2: - for(unsigned k = 0; k < len; k +=m) { +FFT_SINGLE_L2: + for (unsigned k = 0; k < len; k += m) { - CompNum w((FPDATA) 1, (FPDATA) 0); + CompNum w((FPDATA)1, (FPDATA)0); int md2 = m / 2; - FFT_SINGLE_L3: - for(int j = 0; j < md2; j++) { +FFT_SINGLE_L3: + for (int j = 0; j < md2; j++) { - int kj = k + j; + int kj = k + j; int kjm = k + j + md2; CompNum akj, akjm; CompNum bkj, bkjm; if (!pingpong) { - akj.re = int2fp(PLM_IN_PING[2 * kj]); - akj.im = int2fp(PLM_IN_PING[2 * kj + 1]); + akj.re = int2fp(PLM_IN_PING[2 * kj]); + akj.im = int2fp(PLM_IN_PING[2 * kj + 1]); akjm.re = int2fp(PLM_IN_PING[2 * kjm]); akjm.im = int2fp(PLM_IN_PING[2 * kjm + 1]); - } else { - akj.re = int2fp(PLM_IN_PONG[2 * kj]); - akj.im = int2fp(PLM_IN_PONG[2 * kj + 1]); + } + else { + akj.re = int2fp(PLM_IN_PONG[2 * kj]); + akj.im = int2fp(PLM_IN_PONG[2 * kj + 1]); akjm.re = int2fp(PLM_IN_PONG[2 * kjm]); akjm.im = int2fp(PLM_IN_PONG[2 * kjm + 1]); } @@ -338,45 +325,46 @@ void fft::compute_kernel() CompNum wwm; wwm.re = w.re - (wm.im * w.im + wm.re * w.re); wwm.im = w.im + (wm.im * w.re - wm.re * w.im); - w = wwm; + w = wwm; { HLS_CONSTRAIN_LATENCY(0, HLS_ACHIEVABLE); - //HLS_PROTO("compute_write_A0"); + // HLS_PROTO("compute_write_A0"); HLS_BREAK_DEP(PLM_IN_PING); HLS_BREAK_DEP(PLM_IN_PONG); if (!pingpong) { wait(); - PLM_IN_PING[2 * kj] = fp2int(bkj.re); + PLM_IN_PING[2 * kj] = fp2int(bkj.re); PLM_IN_PING[2 * kj + 1] = fp2int(bkj.im); wait(); - PLM_IN_PING[2 * kjm] = fp2int(bkjm.re); + PLM_IN_PING[2 * kjm] = fp2int(bkjm.re); PLM_IN_PING[2 * kjm + 1] = fp2int(bkjm.im); - } else { + } + else { wait(); - PLM_IN_PONG[2 * kj] = fp2int(bkj.re); + PLM_IN_PONG[2 * kj] = fp2int(bkj.re); PLM_IN_PONG[2 * kj + 1] = fp2int(bkj.im); wait(); - PLM_IN_PONG[2 * kjm] = fp2int(bkjm.re); + PLM_IN_PONG[2 * kjm] = fp2int(bkjm.re); PLM_IN_PONG[2 * kjm + 1] = fp2int(bkjm.im); } - // cout << "DFT: A0 " << kj << ": " << A0[kj].re.to_hex() << " " << A0[kj].im.to_hex() << endl; - // cout << "DFT: A0 " << kjm << ": " << A0[kjm].re.to_hex() << " " << A0[kjm].im.to_hex() << endl; + // cout << "DFT: A0 " << kj << ": " << A0[kj].re.to_hex() << " " << + // A0[kj].im.to_hex() << endl; cout << "DFT: A0 " << kjm << ": " << + // A0[kjm].re.to_hex() << " " << A0[kjm].im.to_hex() << endl; } } } } - for (int p = 0; p < len*2; p++) { + for (int p = 0; p < len * 2; p++) { HLS_BREAK_DEP(PLM_IN_PING); HLS_BREAK_DEP(PLM_IN_PONG); HLS_BREAK_DEP(PLM_OUT_PING); HLS_BREAK_DEP(PLM_OUT_PONG); - if (!pingpong) - PLM_OUT_PING[p] = PLM_IN_PING[p]; + if (!pingpong) PLM_OUT_PING[p] = PLM_IN_PING[p]; else PLM_OUT_PONG[p] = PLM_IN_PONG[p]; } @@ -390,5 +378,4 @@ void fft::compute_kernel() { this->process_done(); } - } diff --git a/accelerators/stratus_hls/fft_stratus/hw/tb/fft_test.cpp b/accelerators/stratus_hls/fft_stratus/hw/tb/fft_test.cpp index e28a2fa46e..5f666a60fd 100644 --- a/accelerators/stratus_hls/fft_stratus/hw/tb/fft_test.cpp +++ b/accelerators/stratus_hls/fft_stratus/hw/tb/fft_test.cpp @@ -1,100 +1,97 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 +#include #include #include -#include #include "fft_test.hpp" unsigned int fft_rev(unsigned int v) { - unsigned int r = v; - int s = sizeof(v) * CHAR_BIT - 1; - - for (v >>= 1; v; v >>= 1) { - r <<= 1; - r |= v & 1; - s--; - } - r <<= s; - return r; + unsigned int r = v; + int s = sizeof(v) * CHAR_BIT - 1; + + for (v >>= 1; v; v >>= 1) { + r <<= 1; + r |= v & 1; + s--; + } + r <<= s; + return r; } void fft_bit_reverse(float *w, unsigned int n, unsigned int bits) { - unsigned int i, s, shift; - - s = sizeof(i) * CHAR_BIT - 1; - shift = s - bits + 1; - - for (i = 0; i < n; i++) { - unsigned int r; - float t_real, t_imag; - - r = fft_rev(i); - r >>= shift; - - if (i < r) { - t_real = w[2 * i]; - t_imag = w[2 * i + 1]; - w[2 * i] = w[2 * r]; - w[2 * i + 1] = w[2 * r + 1]; - w[2 * r] = t_real; - w[2 * r + 1] = t_imag; - } - } - + unsigned int i, s, shift; + + s = sizeof(i) * CHAR_BIT - 1; + shift = s - bits + 1; + + for (i = 0; i < n; i++) { + unsigned int r; + float t_real, t_imag; + + r = fft_rev(i); + r >>= shift; + + if (i < r) { + t_real = w[2 * i]; + t_imag = w[2 * i + 1]; + w[2 * i] = w[2 * r]; + w[2 * i + 1] = w[2 * r + 1]; + w[2 * r] = t_real; + w[2 * r + 1] = t_imag; + } + } } int fft_comp(float *data, unsigned int n, unsigned int logn, int sign, bool rev) { - unsigned int transform_length; - unsigned int a, b, i, j, bit; - float theta, t_real, t_imag, w_real, w_imag, s, t, s2, z_real, z_imag; - - if (rev) - fft_bit_reverse(data, n, logn); + unsigned int transform_length; + unsigned int a, b, i, j, bit; + float theta, t_real, t_imag, w_real, w_imag, s, t, s2, z_real, z_imag; - transform_length = 1; + if (rev) fft_bit_reverse(data, n, logn); - /* calculation */ - for (bit = 0; bit < logn; bit++) { - w_real = 1.0; - w_imag = 0.0; + transform_length = 1; - theta = 1.0 * sign * M_PI / (float) transform_length; + /* calculation */ + for (bit = 0; bit < logn; bit++) { + w_real = 1.0; + w_imag = 0.0; - s = sin(theta); - t = sin(0.5 * theta); - s2 = 2.0 * t * t; + theta = 1.0 * sign * M_PI / (float)transform_length; - for (a = 0; a < transform_length; a++) { - for (b = 0; b < n; b += 2 * transform_length) { - i = b + a; - j = b + a + transform_length; + s = sin(theta); + t = sin(0.5 * theta); + s2 = 2.0 * t * t; - z_real = data[2 * j]; - z_imag = data[2 * j + 1]; + for (a = 0; a < transform_length; a++) { + for (b = 0; b < n; b += 2 * transform_length) { + i = b + a; + j = b + a + transform_length; - t_real = w_real * z_real - w_imag * z_imag; - t_imag = w_real * z_imag + w_imag * z_real; + z_real = data[2 * j]; + z_imag = data[2 * j + 1]; - /* write the result */ - data[2*j] = data[2*i] - t_real; - data[2*j + 1] = data[2*i + 1] - t_imag; - data[2*i] += t_real; - data[2*i + 1] += t_imag; - } + t_real = w_real * z_real - w_imag * z_imag; + t_imag = w_real * z_imag + w_imag * z_real; - /* adjust w */ - t_real = w_real - (s * w_imag + s2 * w_real); - t_imag = w_imag + (s * w_real - s2 * w_imag); - w_real = t_real; - w_imag = t_imag; + /* write the result */ + data[2 * j] = data[2 * i] - t_real; + data[2 * j + 1] = data[2 * i + 1] - t_imag; + data[2 * i] += t_real; + data[2 * i + 1] += t_imag; + } - } - transform_length *= 2; - } + /* adjust w */ + t_real = w_real - (s * w_imag + s2 * w_real); + t_imag = w_imag + (s * w_real - s2 * w_imag); + w_real = t_real; + w_imag = t_imag; + } + transform_length *= 2; + } - return 0; + return 0; } diff --git a/accelerators/stratus_hls/fft_stratus/sw/baremetal/fft.c b/accelerators/stratus_hls/fft_stratus/sw/baremetal/fft.c index a7ef65e6a3..918253998f 100644 --- a/accelerators/stratus_hls/fft_stratus/sw/baremetal/fft.c +++ b/accelerators/stratus_hls/fft_stratus/sw/baremetal/fft.c @@ -3,40 +3,36 @@ #include #ifndef __riscv -#include + #include #endif +#include "utils/fft_utils.h" #include #include -#include "utils/fft_utils.h" #if (FFT_FX_WIDTH == 64) typedef long long token_t; typedef double native_t; -#define fx2float fixed64_to_double -#define float2fx double_to_fixed64 -#define FX_IL 42 + #define fx2float fixed64_to_double + #define float2fx double_to_fixed64 + #define FX_IL 42 #else // (FFT_FX_WIDTH == 32) typedef int token_t; typedef float native_t; -#define fx2float fixed32_to_float -#define float2fx float_to_fixed32 -#define FX_IL 12 + #define fx2float fixed32_to_float + #define float2fx float_to_fixed32 + #define FX_IL 12 #endif /* FFT_FX_WIDTH */ const float ERR_TH = 0.05; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} - +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } -#define SLD_FFT 0x059 +#define SLD_FFT 0x059 #define DEV_NAME "sld,fft_stratus" /* <<--params-->> */ -const int32_t log_len = 3; +const int32_t log_len = 3; const int32_t batch_size = 1; int32_t len; int32_t do_bitrev = 1; @@ -52,189 +48,180 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ -#define FFT_DO_PEAK_REG 0x4c -#define FFT_DO_BITREV_REG 0x48 -#define FFT_LOG_LEN_REG 0x44 +#define FFT_DO_PEAK_REG 0x4c +#define FFT_DO_BITREV_REG 0x48 +#define FFT_LOG_LEN_REG 0x44 #define FFT_BATCH_SIZE_REG 0x40 static int validate_buf(token_t *out, float *gold) { - int j; - unsigned errors = 0; - - for (j = 0; j < 2 * len * batch_size; j++) { - native_t val = fx2float(out[j], FX_IL); - if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH){ - errors++; - } - } - - printf(" %u errors\n", errors); - return errors; -} + int j; + unsigned errors = 0; + + for (j = 0; j < 2 * len * batch_size; j++) { + native_t val = fx2float(out[j], FX_IL); + if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) { errors++; } + } + printf(" %u errors\n", errors); + return errors; +} static void init_buf(token_t *in, float *gold) { - int j; - const float LO = -10.0; - const float HI = 10.0; + int j; + const float LO = -10.0; + const float HI = 10.0; - /* srand((unsigned int) time(NULL)); */ + /* srand((unsigned int) time(NULL)); */ - for (j = 0; j < 2 * len * batch_size; j++) { - float scaling_factor = (float) rand () / (float) RAND_MAX; - gold[j] = LO + scaling_factor * (HI - LO); - } + for (j = 0; j < 2 * len * batch_size; j++) { + float scaling_factor = (float)rand() / (float)RAND_MAX; + gold[j] = LO + scaling_factor * (HI - LO); + } - // preprocess with bitreverse (fast in software anyway) - if (!do_bitrev) - fft_bit_reverse(gold, len, log_len); + // preprocess with bitreverse (fast in software anyway) + if (!do_bitrev) fft_bit_reverse(gold, len, log_len); - // convert input to fixed point - for (j = 0; j < 2 * len * batch_size; j++) - in[j] = float2fx((native_t) gold[j], FX_IL); + // convert input to fixed point + for (j = 0; j < 2 * len * batch_size; j++) + in[j] = float2fx((native_t)gold[j], FX_IL); - - // Compute golden output - for (j = 0; j < batch_size; j++) - fft_comp(&gold[j * 2 * len], len, log_len, -1, do_bitrev); + // Compute golden output + for (j = 0; j < batch_size; j++) + fft_comp(&gold[j * 2 * len], len, log_len, -1, do_bitrev); } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable = NULL; - token_t *mem; - float *gold; - unsigned errors = 0; - unsigned coherence; - const float ERROR_COUNT_TH = 0.01; - - len = 1 << log_len; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * len * batch_size; - out_words_adj = 2 * len * batch_size; - } else { - in_words_adj = round_up(2 * len * batch_size, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * len * batch_size, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = 0; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_FFT, DEV_NAME); - if (ndev == 0) { - printf("fft not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - printf("**************** %s.%d ****************\n", DEV_NAME, n); - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_len * sizeof(float)); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - - // Allocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); - - for (coherence = ACC_COH_NONE; coherence < ACC_COH_FULL; coherence++) { - printf(" --------------------\n"); - printf(" Generate input...\n"); - init_buf(mem, gold); - - // Pass common configuration parameters - - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); - - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - iowrite32(dev, FFT_DO_PEAK_REG, 0); - iowrite32(dev, FFT_DO_BITREV_REG, do_bitrev); - iowrite32(dev, FFT_LOG_LEN_REG, log_len); - iowrite32(dev, FFT_BATCH_SIZE_REG, batch_size); - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - if (((float) errors / (float) len) > ERROR_COUNT_TH) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable = NULL; + token_t *mem; + float *gold; + unsigned errors = 0; + unsigned coherence; + const float ERROR_COUNT_TH = 0.01; + + len = 1 << log_len; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * len * batch_size; + out_words_adj = 2 * len * batch_size; + } + else { + in_words_adj = round_up(2 * len * batch_size, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * len * batch_size, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = 0; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_FFT, DEV_NAME); + if (ndev == 0) { + printf("fft not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + printf("**************** %s.%d ****************\n", DEV_NAME, n); + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_len * sizeof(float)); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); + + // Allocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); + + for (coherence = ACC_COH_NONE; coherence < ACC_COH_FULL; coherence++) { + printf(" --------------------\n"); + printf(" Generate input...\n"); + init_buf(mem, gold); + + // Pass common configuration parameters + + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); + + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + iowrite32(dev, FFT_DO_PEAK_REG, 0); + iowrite32(dev, FFT_DO_BITREV_REG, do_bitrev); + iowrite32(dev, FFT_LOG_LEN_REG, log_len); + iowrite32(dev, FFT_BATCH_SIZE_REG, batch_size); + + // Flush (customize coherence model here) + esp_flush(coherence); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + if (((float)errors / (float)len) > ERROR_COUNT_TH) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/accelerators/stratus_hls/fft_stratus/sw/linux/app/fft.c b/accelerators/stratus_hls/fft_stratus/sw/linux/app/fft.c index 311644e992..e3138a1cd9 100644 --- a/accelerators/stratus_hls/fft_stratus/sw/linux/app/fft.c +++ b/accelerators/stratus_hls/fft_stratus/sw/linux/app/fft.c @@ -17,115 +17,112 @@ const float ERR_TH = 0.05; /* User-defined code */ static int validate_buffer(token_t *out, float *gold) { - int j; - unsigned errors = 0; + int j; + unsigned errors = 0; - for (j = 0; j < 2 * len * num_batches; j++) { - native_t val = fx2float(out[j], FX_IL); - if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) { - errors++; - } - } + for (j = 0; j < 2 * len * num_batches; j++) { + native_t val = fx2float(out[j], FX_IL); + if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) { errors++; } + } - printf(" + Relative error > %.02f for %d output values out of %d\n", ERR_TH, errors, 2 * len * num_batches); + printf(" + Relative error > %.02f for %d output values out of %d\n", ERR_TH, errors, + 2 * len * num_batches); - return errors; + return errors; } - /* User-defined code */ static void init_buffer(token_t *in, float *gold) { - int j, b; - const float LO = -1.0; - const float HI = 1.0; - - srand((unsigned int) time(NULL)); - - for (j = 0; j < 2 * len * num_batches; j++) { - float scaling_factor = (float) rand () / (float) RAND_MAX; - gold[j] = LO + scaling_factor * (HI - LO); - } - // preprocess with bitreverse (fast in software anyway) - if (!do_bitrev) - fft_bit_reverse(gold, len, log_len); - - // convert input to fixed point - for (j = 0; j < in_len; j++) - in[j] = float2fx((native_t) gold[j], FX_IL); - - // Compute golden output - for (b = 0; b < num_batches; b++) - fft_comp(&gold[b*2*len], len, log_len, -1, do_bitrev); + int j, b; + const float LO = -1.0; + const float HI = 1.0; + + srand((unsigned int)time(NULL)); + + for (j = 0; j < 2 * len * num_batches; j++) { + float scaling_factor = (float)rand() / (float)RAND_MAX; + gold[j] = LO + scaling_factor * (HI - LO); + } + // preprocess with bitreverse (fast in software anyway) + if (!do_bitrev) fft_bit_reverse(gold, len, log_len); + + // convert input to fixed point + for (j = 0; j < in_len; j++) + in[j] = float2fx((native_t)gold[j], FX_IL); + + // Compute golden output + for (b = 0; b < num_batches; b++) + fft_comp(&gold[b * 2 * len], len, log_len, -1, do_bitrev); } - /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * len * num_batches; - out_words_adj = 2 * len * num_batches; - } else { - in_words_adj = round_up(2 * len * num_batches, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * len * num_batches, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * len * num_batches; + out_words_adj = 2 * len * num_batches; + } + else { + in_words_adj = round_up(2 * len * num_batches, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * len * num_batches, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + size = (out_offset * sizeof(token_t)) + out_size; } int main(int argc, char **argv) { - int errors; + int errors; - float *gold; - token_t *buf; + float *gold; + token_t *buf; - const float ERROR_COUNT_TH = 0.01; + const float ERROR_COUNT_TH = 0.01; - //set parameters - init_parameters(); + // set parameters + init_parameters(); - //allocate buffers - buf = (token_t *) esp_alloc(size); - cfg_000[0].hw_buf = buf; - gold = malloc(out_len * sizeof(float) * num_batches); + // allocate buffers + buf = (token_t *)esp_alloc(size); + cfg_000[0].hw_buf = buf; + gold = malloc(out_len * sizeof(float) * num_batches); - printf("\n====== %s ======\n\n", cfg_000[0].devname); - printf(" .len = %d\n", len); - printf(" .batch_size = %d\n", fft_cfg_000[0].batch_size); + printf("\n====== %s ======\n\n", cfg_000[0].devname); + printf(" .len = %d\n", len); + printf(" .batch_size = %d\n", fft_cfg_000[0].batch_size); - unsigned coherence; - for (coherence = ACC_COH_NONE; coherence < ACC_COH_FULL; coherence++) { - init_buffer(buf, gold); + unsigned coherence; + for (coherence = ACC_COH_NONE; coherence < ACC_COH_FULL; coherence++) { + init_buffer(buf, gold); - //set coherence mode - fft_cfg_000[0].esp.coherence = coherence; + // set coherence mode + fft_cfg_000[0].esp.coherence = coherence; - //run accelerator - printf(" ** START **\n"); - esp_run(cfg_000, NACC); - printf(" ** DONE **\n"); + // run accelerator + printf(" ** START **\n"); + esp_run(cfg_000, NACC); + printf(" ** DONE **\n"); - //validate output - errors = validate_buffer(buf, gold); - float err_rate = (float) errors / (float) (2 * len * num_batches); + // validate output + errors = validate_buffer(buf, gold); + float err_rate = (float)errors / (float)(2 * len * num_batches); - if (err_rate > ERROR_COUNT_TH) - printf("\n + TEST FAIL: exceeding error count threshold\n"); - else - printf("\n + TEST PASS: not exceeding error count threshold\n"); - } + if (err_rate > ERROR_COUNT_TH) printf("\n + TEST FAIL: exceeding error count " + "threshold\n"); + else + printf("\n + TEST PASS: not exceeding error count threshold\n"); + } - printf("\n====== %s ======\n\n", cfg_000[0].devname); + printf("\n====== %s ======\n\n", cfg_000[0].devname); - //cleanup - free(gold); - esp_free(buf); + // cleanup + free(gold); + esp_free(buf); - return errors; + return errors; } diff --git a/accelerators/stratus_hls/fft_stratus/sw/linux/driver/fft_stratus.c b/accelerators/stratus_hls/fft_stratus/sw/linux/driver/fft_stratus.c index 20e8e21531..38e597c553 100644 --- a/accelerators/stratus_hls/fft_stratus/sw/linux/driver/fft_stratus.c +++ b/accelerators/stratus_hls/fft_stratus/sw/linux/driver/fft_stratus.c @@ -1,134 +1,127 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "fft_stratus.h" -#define DRV_NAME "fft_stratus" +#define DRV_NAME "fft_stratus" /* <<--regs-->> */ -#define FFT_DO_PEAK_REG 0x4c -#define FFT_DO_BITREV_REG 0x48 -#define FFT_LOG_LEN_REG 0x44 +#define FFT_DO_PEAK_REG 0x4c +#define FFT_DO_BITREV_REG 0x48 +#define FFT_LOG_LEN_REG 0x44 #define FFT_BATCH_SIZE_REG 0x40 struct fft_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver fft_driver; static struct of_device_id fft_device_ids[] = { - { - .name = "SLD_FFT_STRATUS", - }, - { - .name = "eb_059", - }, - { - .compatible = "sld,fft_stratus", - }, - { }, + { + .name = "SLD_FFT_STRATUS", + }, + { + .name = "eb_059", + }, + { + .compatible = "sld,fft_stratus", + }, + {}, }; static int fft_devs; static inline struct fft_stratus_device *to_fft(struct esp_device *esp) { - return container_of(esp, struct fft_stratus_device, esp); + return container_of(esp, struct fft_stratus_device, esp); } static void fft_prep_xfer(struct esp_device *esp, void *arg) { - struct fft_stratus_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(0, esp->iomem + FFT_DO_PEAK_REG); - iowrite32be(a->batch_size, esp->iomem + FFT_BATCH_SIZE_REG); - iowrite32be(a->do_bitrev, esp->iomem + FFT_DO_BITREV_REG); - iowrite32be(a->log_len, esp->iomem + FFT_LOG_LEN_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); + struct fft_stratus_access *a = arg; + + /* <<--regs-config-->> */ + iowrite32be(0, esp->iomem + FFT_DO_PEAK_REG); + iowrite32be(a->batch_size, esp->iomem + FFT_BATCH_SIZE_REG); + iowrite32be(a->do_bitrev, esp->iomem + FFT_DO_BITREV_REG); + iowrite32be(a->log_len, esp->iomem + FFT_LOG_LEN_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool fft_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct fft_stratus_device *fft = to_fft(esp); */ - /* struct fft_stratus_access *a = arg; */ + /* struct fft_stratus_device *fft = to_fft(esp); */ + /* struct fft_stratus_access *a = arg; */ - return true; + return true; } static int fft_probe(struct platform_device *pdev) { - struct fft_stratus_device *fft; - struct esp_device *esp; - int rc; - - fft = kzalloc(sizeof(*fft), GFP_KERNEL); - if (fft == NULL) - return -ENOMEM; - esp = &fft->esp; - esp->module = THIS_MODULE; - esp->number = fft_devs; - esp->driver = &fft_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - fft_devs++; - return 0; - err: - kfree(fft); - return rc; + struct fft_stratus_device *fft; + struct esp_device *esp; + int rc; + + fft = kzalloc(sizeof(*fft), GFP_KERNEL); + if (fft == NULL) return -ENOMEM; + esp = &fft->esp; + esp->module = THIS_MODULE; + esp->number = fft_devs; + esp->driver = &fft_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + fft_devs++; + return 0; +err: + kfree(fft); + return rc; } static int __exit fft_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct fft_stratus_device *fft = to_fft(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct fft_stratus_device *fft = to_fft(esp); - esp_device_unregister(esp); - kfree(fft); - return 0; + esp_device_unregister(esp); + kfree(fft); + return 0; } static struct esp_driver fft_driver = { - .plat = { - .probe = fft_probe, - .remove = fft_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = fft_device_ids, - }, - }, - .xfer_input_ok = fft_xfer_input_ok, - .prep_xfer = fft_prep_xfer, - .ioctl_cm = FFT_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct fft_stratus_access), + .plat = + { + .probe = fft_probe, + .remove = fft_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = fft_device_ids, + }, + }, + .xfer_input_ok = fft_xfer_input_ok, + .prep_xfer = fft_prep_xfer, + .ioctl_cm = FFT_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct fft_stratus_access), }; -static int __init fft_init(void) -{ - return esp_driver_register(&fft_driver); -} +static int __init fft_init(void) { return esp_driver_register(&fft_driver); } -static void __exit fft_exit(void) -{ - esp_driver_unregister(&fft_driver); -} +static void __exit fft_exit(void) { esp_driver_unregister(&fft_driver); } -module_init(fft_init) -module_exit(fft_exit) +module_init(fft_init) module_exit(fft_exit) -MODULE_DEVICE_TABLE(of, fft_device_ids); + MODULE_DEVICE_TABLE(of, fft_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/fft_stratus/sw/linux/include/fft_stratus.h b/accelerators/stratus_hls/fft_stratus/sw/linux/include/fft_stratus.h index 84d336d7a8..4dc82737e5 100644 --- a/accelerators/stratus_hls/fft_stratus/sw/linux/include/fft_stratus.h +++ b/accelerators/stratus_hls/fft_stratus/sw/linux/include/fft_stratus.h @@ -4,30 +4,29 @@ #define _FFT_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct fft_stratus_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned batch_size; - unsigned log_len; - unsigned do_bitrev; - unsigned src_offset; - unsigned dst_offset; - + struct esp_access esp; + /* <<--regs-->> */ + unsigned batch_size; + unsigned log_len; + unsigned do_bitrev; + unsigned src_offset; + unsigned dst_offset; }; -#define FFT_STRATUS_IOC_ACCESS _IOW ('S', 0, struct fft_stratus_access) +#define FFT_STRATUS_IOC_ACCESS _IOW('S', 0, struct fft_stratus_access) #endif /* _FFT_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/gemm_stratus/hw/datagen/generator/generator.py b/accelerators/stratus_hls/gemm_stratus/hw/datagen/generator/generator.py index b6c45a581c..71daeac2c1 100755 --- a/accelerators/stratus_hls/gemm_stratus/hw/datagen/generator/generator.py +++ b/accelerators/stratus_hls/gemm_stratus/hw/datagen/generator/generator.py @@ -6,6 +6,7 @@ import sys import random + def gen(is_transposed, batch_size, rowsA, colsA, colsB, name): # define range of random matrix elements values @@ -19,7 +20,7 @@ def gen(is_transposed, batch_size, rowsA, colsA, colsB, name): matrixA.write("0 ") # is_transposed matrixA.write(str(batch_size) + " ") # batch_size matrixA.write(str(rowsA) + " ") # rowsA - matrixA.write(str(colsA) + "\n") # colsA + matrixA.write(str(colsA) + "\n") # colsA for i in range(0, batch_size * rowsA * colsA): val = random.randint(-value_range, value_range) @@ -35,7 +36,7 @@ def gen(is_transposed, batch_size, rowsA, colsA, colsB, name): matrixB.write(str(is_transposed) + " ") # is_transposed matrixB.write(str(batch_size) + " ") # batch_size matrixB.write(str(colsA) + " ") # colsA - matrixB.write(str(colsB) + "\n") # colsB + matrixB.write(str(colsB) + "\n") # colsB for i in range(0, batch_size * colsA * colsB): val = random.randint(-value_range, value_range) @@ -45,6 +46,7 @@ def gen(is_transposed, batch_size, rowsA, colsA, colsB, name): matrixB.close() + def main(): # Generate small sized matrices @@ -57,7 +59,7 @@ def main(): # Generate medium sized matrices gen(1, - random.randint( 1, 1), + random.randint(1, 1), random.randint(32, 32) * 2, random.randint(32, 32) * 2, random.randint(32, 32) * 2, @@ -65,7 +67,7 @@ def main(): # Generate large sized matrices gen(1, - random.randint( 1, 1), + random.randint(1, 1), random.randint(128, 128) * 2, random.randint(128, 128) * 2, random.randint(128, 128) * 2, @@ -82,9 +84,9 @@ def main(): # Generate matrices with single column matrix A and single row matrix B gen(1, random.randint(1, 1), - random.randint(64,64) * 2, + random.randint(64, 64) * 2, 1, - random.randint(64,64) * 2, + random.randint(64, 64) * 2, "testC") # Generate matrices with non-transposed matrix B @@ -113,5 +115,6 @@ def main(): print("Info: input successfully generated") + if __name__ == "__main__": main() diff --git a/accelerators/stratus_hls/gemm_stratus/hw/src/gemm.cpp b/accelerators/stratus_hls/gemm_stratus/hw/src/gemm.cpp index 00f2ecc445..d02a60df9b 100644 --- a/accelerators/stratus_hls/gemm_stratus/hw/src/gemm.cpp +++ b/accelerators/stratus_hls/gemm_stratus/hw/src/gemm.cpp @@ -43,306 +43,295 @@ void gemm::load_input() // Reset { - HLS_DEFINE_PROTOCOL("load-reset"); - - this->reset_load_input(); - load_compute_cfg_done.req.reset_req(); - load_store_cfg_done.req.reset_req(); - - // PLM memories reset - - // User-defined reset code - i = 0; - ninputs = 0; - length1 = 0; - length2 = 0; - index_d1 = 0; - index_d1_n = 0; - index_d2 = 0; - index_d1_tmp = 0; - index_d2_tmp = 0; - matrix_d1 = 0; - matrix_d2 = 0; - matrix_d3 = 0; + HLS_DEFINE_PROTOCOL("load-reset"); + + this->reset_load_input(); + load_compute_cfg_done.req.reset_req(); + load_store_cfg_done.req.reset_req(); + + // PLM memories reset + + // User-defined reset code + i = 0; + ninputs = 0; + length1 = 0; + length2 = 0; + index_d1 = 0; + index_d1_n = 0; + index_d2 = 0; + index_d1_tmp = 0; + index_d2_tmp = 0; + matrix_d1 = 0; + matrix_d2 = 0; + matrix_d3 = 0; size_matrix_out = 0; - size_matrix1 = 0; - size_matrix2 = 0; - matrix_chk_in = 0; - matrix_rem_in1 = 0; - matrix_rem_in2 = 0; - matrix_chk_out = 0; - matrix_rem_out = 0; - load_cfg = 0; - loadable_rows = 0; - loadable_chunk = 0; - index_d1_incr = 0; - ld_offset1 = 0; - ld_offset2 = 0; - transpose = 0; - pingpong_m1 = false; - pingpong_m2 = false; - m2_loop_iters = 0; - length_m2_dma = 0; - index_m2_incr = 0; - m2_plm_incr = 0; - - wait(); + size_matrix1 = 0; + size_matrix2 = 0; + matrix_chk_in = 0; + matrix_rem_in1 = 0; + matrix_rem_in2 = 0; + matrix_chk_out = 0; + matrix_rem_out = 0; + load_cfg = 0; + loadable_rows = 0; + loadable_chunk = 0; + index_d1_incr = 0; + ld_offset1 = 0; + ld_offset2 = 0; + transpose = 0; + pingpong_m1 = false; + pingpong_m2 = false; + m2_loop_iters = 0; + length_m2_dma = 0; + index_m2_incr = 0; + m2_plm_incr = 0; + + wait(); } // Config { - HLS_DEFINE_PROTOCOL("load-config"); + HLS_DEFINE_PROTOCOL("load-config"); - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); - // User-defined config code - ninputs = config.ninputs; - matrix_d1 = config.d1; - matrix_d2 = config.d2; - matrix_d3 = config.d3; + // User-defined config code + ninputs = config.ninputs; + matrix_d1 = config.d1; + matrix_d2 = config.d2; + matrix_d3 = config.d3; ld_offset1 = config.ld_offset1; ld_offset2 = config.ld_offset2; - transpose = config.transpose; + transpose = config.transpose; } { - calculate_config(ninputs, matrix_d1, matrix_d2, matrix_d3, transpose, - size_matrix1, size_matrix2, size_matrix_out, - matrix_chk_in, matrix_rem_in1, matrix_rem_in2, - matrix_chk_out, matrix_rem_out, - load_cfg, loadable_rows, loadable_chunk, index_d1_incr, - m2_loop_iters, m2_plm_incr); - - { - HLS_DEFINE_PROTOCOL("load-config-sig"); - size_matrix_out_sig.write(size_matrix_out); - size_matrix1_sig.write(size_matrix1); - size_matrix2_sig.write(size_matrix2); - matrix_chk_in_sig.write(matrix_chk_in); - matrix_rem_in1_sig.write(matrix_rem_in1); - matrix_rem_in2_sig.write(matrix_rem_in2); - matrix_chk_out_sig.write(matrix_chk_out); - matrix_rem_out_sig.write(matrix_rem_out); - load_cfg_sig.write(load_cfg); - loadable_rows_sig.write(loadable_rows); - loadable_chunk_sig.write(loadable_chunk); - index_d1_incr_sig.write(index_d1_incr); - wait(); - } - - index_d1_n = ld_offset1; - index_d2 = ld_offset2; - index_m2_incr = matrix_d3; - length_m2_dma = 1; + calculate_config(ninputs, matrix_d1, matrix_d2, matrix_d3, transpose, size_matrix1, + size_matrix2, size_matrix_out, matrix_chk_in, matrix_rem_in1, + matrix_rem_in2, matrix_chk_out, matrix_rem_out, load_cfg, loadable_rows, + loadable_chunk, index_d1_incr, m2_loop_iters, m2_plm_incr); + + { + HLS_DEFINE_PROTOCOL("load-config-sig"); + size_matrix_out_sig.write(size_matrix_out); + size_matrix1_sig.write(size_matrix1); + size_matrix2_sig.write(size_matrix2); + matrix_chk_in_sig.write(matrix_chk_in); + matrix_rem_in1_sig.write(matrix_rem_in1); + matrix_rem_in2_sig.write(matrix_rem_in2); + matrix_chk_out_sig.write(matrix_chk_out); + matrix_rem_out_sig.write(matrix_rem_out); + load_cfg_sig.write(load_cfg); + loadable_rows_sig.write(loadable_rows); + loadable_chunk_sig.write(loadable_chunk); + index_d1_incr_sig.write(index_d1_incr); + wait(); + } + + index_d1_n = ld_offset1; + index_d2 = ld_offset2; + index_m2_incr = matrix_d3; + length_m2_dma = 1; // ESP_REPORT_INFO("WORDS_PER_DMA %d", WORDS_PER_DMA); // ESP_REPORT_INFO("LOAD %u %u %u %u %u %u %u %u %u %u %u", - // (unsigned) size_matrix1, (unsigned) size_matrix2, - // (unsigned) matrix_chk_in, (unsigned) matrix_rem_in1, (unsigned) matrix_rem_in2, - // (unsigned) matrix_chk_out, (unsigned) matrix_rem_out, - // (unsigned) load_cfg, (unsigned) loadable_rows, - // (unsigned) loadable_chunk, (unsigned) index_d1_incr); - - load_compute_cfg_handshake(); - load_store_cfg_handshake(); + // (unsigned) size_matrix1, (unsigned) size_matrix2, + // (unsigned) matrix_chk_in, (unsigned) matrix_rem_in1, (unsigned) matrix_rem_in2, + // (unsigned) matrix_chk_out, (unsigned) matrix_rem_out, + // (unsigned) load_cfg, (unsigned) loadable_rows, + // (unsigned) loadable_chunk, (unsigned) index_d1_incr); + + load_compute_cfg_handshake(); + load_store_cfg_handshake(); } - + // Load - for (uint24_t a = 0; a < ninputs; a++) - { - index_d1 = index_d1_n; - - for (uint24_t d1 = 0; d1 < matrix_d1; d1 += loadable_rows) - { - index_d2_tmp = index_d2; - - for (uint24_t d2 = 0; d2 < matrix_d3; d2 += loadable_rows) - { - index_d1_tmp = index_d1; - - length1 = loadable_chunk; - length2 = loadable_chunk; - - uint32_t index_m2_dma = index_d2_tmp; - - for (uint24_t chk = 0; chk < matrix_chk_in; ++chk) - { - // If true the next is the last (smaller) chunk - if (load_cfg == LESS_THAN_ROW && chk == matrix_chk_in - 1 && - matrix_rem_in2 != 0) { - length1 = matrix_rem_in1; - length2 = matrix_rem_in2; - } else if (load_cfg != LESS_THAN_ROW) { - if (d1 + loadable_rows > matrix_d1) - length1 = matrix_rem_in1; - if (d2 + loadable_rows > matrix_d3) - length2 = matrix_rem_in2; - } - - // - // 1. Load chunks of the first matrix in PLMs input0 and input1 - // - - if (!(d2 && load_cfg == LESS_THAN_MATRIX2)) { - - { - HLS_DEFINE_PROTOCOL("load-matrix1-info"); - dma_info_t dma_info(index_d1_tmp >> WORDS_PER_DMA_LOG, - round_up(length1, WORDS_PER_DMA) >> WORDS_PER_DMA_LOG, - SIZE_WORD); - this->dma_read_ctrl.put(dma_info); + for (uint24_t a = 0; a < ninputs; a++) { + index_d1 = index_d1_n; + + for (uint24_t d1 = 0; d1 < matrix_d1; d1 += loadable_rows) { + index_d2_tmp = index_d2; + + for (uint24_t d2 = 0; d2 < matrix_d3; d2 += loadable_rows) { + index_d1_tmp = index_d1; + + length1 = loadable_chunk; + length2 = loadable_chunk; + + uint32_t index_m2_dma = index_d2_tmp; + + for (uint24_t chk = 0; chk < matrix_chk_in; ++chk) { + // If true the next is the last (smaller) chunk + if (load_cfg == LESS_THAN_ROW && chk == matrix_chk_in - 1 && + matrix_rem_in2 != 0) { + length1 = matrix_rem_in1; + length2 = matrix_rem_in2; + } + else if (load_cfg != LESS_THAN_ROW) { + if (d1 + loadable_rows > matrix_d1) length1 = matrix_rem_in1; + if (d2 + loadable_rows > matrix_d3) length2 = matrix_rem_in2; + } + + // + // 1. Load chunks of the first matrix in PLMs input0 and input1 + // + + if (!(d2 && load_cfg == LESS_THAN_MATRIX2)) { + + { + HLS_DEFINE_PROTOCOL("load-matrix1-info"); + dma_info_t dma_info( + index_d1_tmp >> WORDS_PER_DMA_LOG, + round_up(length1, WORDS_PER_DMA) >> WORDS_PER_DMA_LOG, SIZE_WORD); + this->dma_read_ctrl.put(dma_info); // ESP_REPORT_INFO("load m1 %u %u", - // (unsigned) index_d1_tmp, (unsigned) round_up(length1, WORDS_PER_DMA)); - } - - i = 0; - - bool misaligned = index_d1_tmp & 1 & (WORDS_PER_DMA - 1); - - for (uint16_t k = 0; k < round_up(length1 + misaligned, WORDS_PER_DMA) >> WORDS_PER_DMA_LOG; ++k) - { - sc_dt::sc_bv data = this->dma_read_chnl.get(); - - { - // This ensures the maximum throughput - HLS_CONSTRAIN_LATENCY(0, HLS_ACHIEVABLE, "load-matrix1"); - HLS_BREAK_ARRAY_DEPENDENCY(input0); - HLS_BREAK_ARRAY_DEPENDENCY(input1); - -#if (WORDS_PER_DMA == 2) - if (pingpong_m1) { - - if (!(misaligned && !k)) - input0[i++] = data.range(31,0).to_uint(); - if (i < DMA_CHUNK) - input0[i++] = data.range(63,32).to_uint(); - } else { - if (!(misaligned && !k)) - input1[i++] = data.range(31,0).to_uint(); - if (i < DMA_CHUNK) - input1[i++] = data.range(63,32).to_uint(); - } + // (unsigned) index_d1_tmp, (unsigned) round_up(length1, + // WORDS_PER_DMA)); + } + + i = 0; + + bool misaligned = index_d1_tmp & 1 & (WORDS_PER_DMA - 1); + + for (uint16_t k = 0; + k > WORDS_PER_DMA_LOG; + ++k) { + sc_dt::sc_bv data = this->dma_read_chnl.get(); + + { + // This ensures the maximum throughput + HLS_CONSTRAIN_LATENCY(0, HLS_ACHIEVABLE, "load-matrix1"); + HLS_BREAK_ARRAY_DEPENDENCY(input0); + HLS_BREAK_ARRAY_DEPENDENCY(input1); + +#if (WORDS_PER_DMA == 2) + if (pingpong_m1) { + + if (!(misaligned && !k)) + input0[i++] = data.range(31, 0).to_uint(); + if (i < DMA_CHUNK) input0[i++] = data.range(63, 32).to_uint(); + } + else { + if (!(misaligned && !k)) + input1[i++] = data.range(31, 0).to_uint(); + if (i < DMA_CHUNK) input1[i++] = data.range(63, 32).to_uint(); + } #else - if (pingpong_m1) { - input0[i++] = data.to_uint(); - } else { + if (pingpong_m1) { input0[i++] = data.to_uint(); } + else { input1[i++] = data.to_uint(); - } + } #endif - // i+=2; - } - wait(); // Only considered in behavioral simulation - } - pingpong_m1 = !pingpong_m1; - } - - // - // 2. Load chunks of the second matrix in PLMs input2 and input3 - // - - // TODO - // This does not work when WORDS_PER_DMA != 1 - if (transpose || matrix_d3 == 1) { - length_m2_dma = length2; - index_m2_incr = length2; - } else { - if (load_cfg == LESS_THAN_ROW) { - m2_loop_iters = length2; - } else if (load_cfg == LESS_THAN_MATRIX2) { - length_m2_dma = min(loadable_rows, matrix_d3 - d2); - // ESP_REPORT_INFO("here1 %d", length_m2_dma); - } - } - - int16_t base_i = 0; - i = 0; - for (uint16_t t = 0; t < m2_loop_iters; ++t) - { - i = base_i; - { - HLS_DEFINE_PROTOCOL("load-matrix2-info"); - - dma_info_t dma_info(index_m2_dma >> WORDS_PER_DMA_LOG, - round_up(length_m2_dma, WORDS_PER_DMA) >> WORDS_PER_DMA_LOG, SIZE_WORD); - this->dma_read_ctrl.put(dma_info); - - // ESP_REPORT_INFO("load m2 %u %u", - // (unsigned) index_m2_dma, (unsigned) round_up(length_m2_dma, WORDS_PER_DMA)); - } - - bool misaligned = index_m2_dma & 1 & (WORDS_PER_DMA - 1); - - for (uint16_t k = 0; k < round_up(length_m2_dma + misaligned, - WORDS_PER_DMA) >> WORDS_PER_DMA_LOG; ++k) - { - sc_dt::sc_bv data = this->dma_read_chnl.get(); - - { - // This ensures the maximum throughput - HLS_DEFINE_PROTOCOL("protocol-load-matrix2"); - HLS_BREAK_ARRAY_DEPENDENCY(input2); - HLS_BREAK_ARRAY_DEPENDENCY(input3); + // i+=2; + } + wait(); // Only considered in behavioral simulation + } + pingpong_m1 = !pingpong_m1; + } + + // + // 2. Load chunks of the second matrix in PLMs input2 and input3 + // + + // TODO + // This does not work when WORDS_PER_DMA != 1 + if (transpose || matrix_d3 == 1) { + length_m2_dma = length2; + index_m2_incr = length2; + } + else { + if (load_cfg == LESS_THAN_ROW) { m2_loop_iters = length2; } + else if (load_cfg == LESS_THAN_MATRIX2) { + length_m2_dma = min(loadable_rows, matrix_d3 - d2); + // ESP_REPORT_INFO("here1 %d", length_m2_dma); + } + } + + int16_t base_i = 0; + i = 0; + for (uint16_t t = 0; t < m2_loop_iters; ++t) { + i = base_i; + { + HLS_DEFINE_PROTOCOL("load-matrix2-info"); + + dma_info_t dma_info(index_m2_dma >> WORDS_PER_DMA_LOG, + round_up(length_m2_dma, WORDS_PER_DMA) >> + WORDS_PER_DMA_LOG, + SIZE_WORD); + this->dma_read_ctrl.put(dma_info); + + // ESP_REPORT_INFO("load m2 %u %u", + // (unsigned) index_m2_dma, (unsigned) round_up(length_m2_dma, + // WORDS_PER_DMA)); + } + + bool misaligned = index_m2_dma & 1 & (WORDS_PER_DMA - 1); + + for (uint16_t k = 0; + k > + WORDS_PER_DMA_LOG; + ++k) { + sc_dt::sc_bv data = this->dma_read_chnl.get(); + + { + // This ensures the maximum throughput + HLS_DEFINE_PROTOCOL("protocol-load-matrix2"); + HLS_BREAK_ARRAY_DEPENDENCY(input2); + HLS_BREAK_ARRAY_DEPENDENCY(input3); #if (WORDS_PER_DMA != 2) - if (pingpong_m2) - input2[i] = data.to_uint(); + if (pingpong_m2) input2[i] = data.to_uint(); else input3[i] = data.to_uint(); i += m2_plm_incr; -#else - if (!(misaligned && !k)) { - if (pingpong_m2) - input2[i] = data.range(31,0).to_uint(); - else - input3[i] = data.range(31,0).to_uint(); - i += m2_plm_incr; - } - if (i < DMA_CHUNK) { - if (m2_plm_incr != 1) { - wait(); - } - if (pingpong_m2) - input2[i] = data.range(63,32).to_uint(); - else - input3[i] = data.range(63,32).to_uint(); - i += m2_plm_incr; - } +#else + if (!(misaligned && !k)) { + if (pingpong_m2) input2[i] = data.range(31, 0).to_uint(); + else + input3[i] = data.range(31, 0).to_uint(); + i += m2_plm_incr; + } + if (i < DMA_CHUNK) { + if (m2_plm_incr != 1) { wait(); } + if (pingpong_m2) input2[i] = data.range(63, 32).to_uint(); + else + input3[i] = data.range(63, 32).to_uint(); + i += m2_plm_incr; + } #endif - wait(); - } - } - - index_m2_dma += index_m2_incr; - base_i++; - } - - // Call the compute_kernel process - load_compute_handshake(); - - // Change pingpong buffer - pingpong_m2 = !pingpong_m2; - - // Update the indices - index_d1_tmp += length1; - if (transpose) - index_d2_tmp += length_m2_dma; - } - if (!transpose) - index_d2_tmp += loadable_rows; - } - index_d1 += index_d1_incr; - } - index_d2 += size_matrix2; - index_d1_n += size_matrix1; + wait(); + } + } + + index_m2_dma += index_m2_incr; + base_i++; + } + + // Call the compute_kernel process + load_compute_handshake(); + + // Change pingpong buffer + pingpong_m2 = !pingpong_m2; + + // Update the indices + index_d1_tmp += length1; + if (transpose) index_d2_tmp += length_m2_dma; + } + if (!transpose) index_d2_tmp += loadable_rows; + } + index_d1 += index_d1_incr; + } + index_d2 += size_matrix2; + index_d1_n += size_matrix1; } // Conclude { - HLS_DEFINE_PROTOCOL("load-done"); - this->process_done(); + HLS_DEFINE_PROTOCOL("load-done"); + this->process_done(); } } @@ -363,166 +352,162 @@ void gemm::store_output() // Reset { - HLS_DEFINE_PROTOCOL("store-reset"); + HLS_DEFINE_PROTOCOL("store-reset"); - this->reset_store_output(); + this->reset_store_output(); output_done.req.reset_req(); - load_store_cfg_done.ack.reset_ack(); - - // PLM memories reset - - // User-defined reset code - i = 0; - pingpong = false; - ninputs = 0; - matrix_d1 = 0; - matrix_d2 = 0; - matrix_d3 = 0; - st_offset = 0; - matrix_chk_out = 0; - matrix_rem_out = 0; + load_store_cfg_done.ack.reset_ack(); + + // PLM memories reset + + // User-defined reset code + i = 0; + pingpong = false; + ninputs = 0; + matrix_d1 = 0; + matrix_d2 = 0; + matrix_d3 = 0; + st_offset = 0; + matrix_chk_out = 0; + matrix_rem_out = 0; size_matrix_out = 0; - load_cfg = 0; - loadable_rows = 0; + load_cfg = 0; + loadable_rows = 0; - wait(); + wait(); } // Config { - HLS_DEFINE_PROTOCOL("store-config"); + HLS_DEFINE_PROTOCOL("store-config"); - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); - // User-defined config code - ninputs = config.ninputs; + // User-defined config code + ninputs = config.ninputs; matrix_d1 = config.d1; matrix_d2 = config.d2; matrix_d3 = config.d3; st_offset = config.st_offset; - store_load_cfg_handshake(); + store_load_cfg_handshake(); // Calculating number of outputs to generate - { - HLS_DEFINE_PROTOCOL("store-config-sig"); - matrix_chk_out = matrix_chk_out_sig.read(); - matrix_rem_out = matrix_rem_out_sig.read(); - size_matrix_out = size_matrix_out_sig.read(); - load_cfg = load_cfg_sig.read(); - loadable_rows = loadable_rows_sig.read(); - wait(); - } - - if (load_cfg == LESS_THAN_MATRIX2 && loadable_rows != 1) { - matrix_chk_out = 1; - } else { - ninputs = 1; - matrix_d1 = 1; - matrix_d3 = 1; - loadable_rows = 1; - } - - // ESP_REPORT_INFO("STORE %u %u %u", (unsigned) size_matrix_out, - // (unsigned) matrix_chk_out, (unsigned) matrix_rem_out); + { + HLS_DEFINE_PROTOCOL("store-config-sig"); + matrix_chk_out = matrix_chk_out_sig.read(); + matrix_rem_out = matrix_rem_out_sig.read(); + size_matrix_out = size_matrix_out_sig.read(); + load_cfg = load_cfg_sig.read(); + loadable_rows = loadable_rows_sig.read(); + wait(); + } + + if (load_cfg == LESS_THAN_MATRIX2 && loadable_rows != 1) { matrix_chk_out = 1; } + else { + ninputs = 1; + matrix_d1 = 1; + matrix_d3 = 1; + loadable_rows = 1; + } + + // ESP_REPORT_INFO("STORE %u %u %u", (unsigned) size_matrix_out, + // (unsigned) matrix_chk_out, (unsigned) matrix_rem_out); } // Store - uint32_t index = 0; + uint32_t index = 0; uint32_t index_simple = st_offset; - uint16_t length = OUT_DMA_CHUNK; - uint32_t index_a = st_offset; - - for (uint24_t a = 0; a < ninputs; a++) - { - uint32_t index_d1 = index_a; - for (uint24_t d1 = 0; d1 < matrix_d1; d1 += loadable_rows) - { - uint16_t loaded_rows_d1 = min(loadable_rows, matrix_d1 - d1); - uint32_t index_d2 = index_d1; - for (uint24_t d2 = 0; d2 < matrix_d3; d2 += loadable_rows) - { - uint16_t loaded_rows_d3 = min(loadable_rows, matrix_d3 - d2); - uint32_t index_d1i = index_d2; - for (uint16_t d1i = 0; d1i < loaded_rows_d1; d1i++) - { - for (uint24_t chk = 0; chk < matrix_chk_out; ++chk) - { - // If true the next is the last (smaller) chunk - if (load_cfg == LESS_THAN_MATRIX2 && loadable_rows != 1) { - length = loaded_rows_d3; - index = index_d1i; - } else { - index = index_simple; - if (chk == matrix_chk_out - 1 && matrix_rem_out != 0) - length = matrix_rem_out; - } - - // Wait the compute_process - // ESP_REPORT_INFO("STORE: before compute hs %u %u %u %u", - // (unsigned) d1, (unsigned) d2, (unsigned) d1i, (unsigned) chk); - store_compute_handshake(); - // ESP_REPORT_INFO("STORE: after compute hs %u %u %u %u", - // (unsigned) d1, (unsigned) d2, (unsigned) d1i, (unsigned) chk); - - { - HLS_DEFINE_PROTOCOL("store-matrix-info"); - dma_info_t dma_info(index >> WORDS_PER_DMA_LOG, - round_up(length, WORDS_PER_DMA) >> WORDS_PER_DMA_LOG, - SIZE_WORD); - this->dma_write_ctrl.put(dma_info); - - // ESP_REPORT_INFO("STORE index %u length %u", - // (unsigned) index, (unsigned) length); - } - - i = 0; - for (uint16_t k = 0; k < round_up(length, WORDS_PER_DMA) >> WORDS_PER_DMA_LOG; ++k) - { - sc_dt::sc_bv data = 0; - - { - // This ensures the maximum throughput - HLS_CONSTRAIN_LATENCY(0, HLS_ACHIEVABLE, "store-matrix"); - - if (pingpong) { - data.range(31,0) = output0[i++]; + uint16_t length = OUT_DMA_CHUNK; + uint32_t index_a = st_offset; + + for (uint24_t a = 0; a < ninputs; a++) { + uint32_t index_d1 = index_a; + for (uint24_t d1 = 0; d1 < matrix_d1; d1 += loadable_rows) { + uint16_t loaded_rows_d1 = min(loadable_rows, matrix_d1 - d1); + uint32_t index_d2 = index_d1; + for (uint24_t d2 = 0; d2 < matrix_d3; d2 += loadable_rows) { + uint16_t loaded_rows_d3 = min(loadable_rows, matrix_d3 - d2); + uint32_t index_d1i = index_d2; + for (uint16_t d1i = 0; d1i < loaded_rows_d1; d1i++) { + for (uint24_t chk = 0; chk < matrix_chk_out; ++chk) { + // If true the next is the last (smaller) chunk + if (load_cfg == LESS_THAN_MATRIX2 && loadable_rows != 1) { + length = loaded_rows_d3; + index = index_d1i; + } + else { + index = index_simple; + if (chk == matrix_chk_out - 1 && matrix_rem_out != 0) + length = matrix_rem_out; + } + + // Wait the compute_process + // ESP_REPORT_INFO("STORE: before compute hs %u %u %u %u", + // (unsigned) d1, (unsigned) d2, (unsigned) d1i, (unsigned) chk); + store_compute_handshake(); + // ESP_REPORT_INFO("STORE: after compute hs %u %u %u %u", + // (unsigned) d1, (unsigned) d2, (unsigned) d1i, (unsigned) chk); + + { + HLS_DEFINE_PROTOCOL("store-matrix-info"); + dma_info_t dma_info( + index >> WORDS_PER_DMA_LOG, + round_up(length, WORDS_PER_DMA) >> WORDS_PER_DMA_LOG, SIZE_WORD); + this->dma_write_ctrl.put(dma_info); + + // ESP_REPORT_INFO("STORE index %u length %u", + // (unsigned) index, (unsigned) length); + } + + i = 0; + for (uint16_t k = 0; k > WORDS_PER_DMA_LOG; + ++k) { + sc_dt::sc_bv data = 0; + + { + // This ensures the maximum throughput + HLS_CONSTRAIN_LATENCY(0, HLS_ACHIEVABLE, "store-matrix"); + + if (pingpong) { + data.range(31, 0) = output0[i++]; #if (WORDS_PER_DMA == 2) - data.range(63,32) = output0[i++]; + data.range(63, 32) = output0[i++]; #endif - } else { - data.range(31,0) = output1[i++]; + } + else { + data.range(31, 0) = output1[i++]; #if (WORDS_PER_DMA == 2) - data.range(63,32) = output1[i++]; + data.range(63, 32) = output1[i++]; #endif - } - - wait(); // Only considered in behavioral simulation - } - - this->dma_write_chnl.put(data); - } - - // toggle pingpong - pingpong = !pingpong; - - // update the index - index_simple += length; - } - index_d1i += matrix_d3; - } - index_d2 += loadable_rows; - } - index_d1 += (loadable_rows * matrix_d3); - } - index_a += (size_matrix_out / ninputs); + } + + wait(); // Only considered in behavioral simulation + } + + this->dma_write_chnl.put(data); + } + + // toggle pingpong + pingpong = !pingpong; + + // update the index + index_simple += length; + } + index_d1i += matrix_d3; + } + index_d2 += loadable_rows; + } + index_d1 += (loadable_rows * matrix_d3); + } + index_a += (size_matrix_out / ninputs); } // Conclude { - this->accelerator_done(); - this->process_done(); + this->accelerator_done(); + this->process_done(); } } @@ -544,361 +529,341 @@ void gemm::compute_kernel() // Reset { - HLS_DEFINE_PROTOCOL("compute-reset"); - - this->reset_compute_kernel(); - output_done.ack.reset_ack(); - load_compute_cfg_done.ack.reset_ack(); - - // PLM memories reset - - // User-defined reset code - pingpong_m1 = true; - pingpong_m2 = true; - pingpong_out = false; - ninputs = 0; - matrix_d1 = 0; - matrix_d2 = 0; - matrix_d3 = 0; - do_relu = 0; - matrix_chk_in = 0; + HLS_DEFINE_PROTOCOL("compute-reset"); + + this->reset_compute_kernel(); + output_done.ack.reset_ack(); + load_compute_cfg_done.ack.reset_ack(); + + // PLM memories reset + + // User-defined reset code + pingpong_m1 = true; + pingpong_m2 = true; + pingpong_out = false; + ninputs = 0; + matrix_d1 = 0; + matrix_d2 = 0; + matrix_d3 = 0; + do_relu = 0; + matrix_chk_in = 0; matrix_rem_in1 = 0; matrix_rem_in2 = 0; - store_count = 0; - load_cfg = 0; - loadable_rows = 0; + store_count = 0; + load_cfg = 0; + loadable_rows = 0; - wait(); + wait(); } // Config { - HLS_DEFINE_PROTOCOL("compute-config"); + HLS_DEFINE_PROTOCOL("compute-config"); - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); - // User-defined config code - ninputs = config.ninputs; + // User-defined config code + ninputs = config.ninputs; matrix_d1 = config.d1; matrix_d2 = config.d2; matrix_d3 = config.d3; - do_relu = config.do_relu; + do_relu = config.do_relu; - compute_load_cfg_handshake(); + compute_load_cfg_handshake(); - matrix_chk_in = matrix_chk_in_sig.read(); - matrix_rem_in1 = matrix_rem_in1_sig.read(); - matrix_rem_in2 = matrix_rem_in2_sig.read(); - load_cfg = load_cfg_sig.read(); - loadable_rows = loadable_rows_sig.read(); + matrix_chk_in = matrix_chk_in_sig.read(); + matrix_rem_in1 = matrix_rem_in1_sig.read(); + matrix_rem_in2 = matrix_rem_in2_sig.read(); + load_cfg = load_cfg_sig.read(); + loadable_rows = loadable_rows_sig.read(); - wait(); + wait(); // ESP_REPORT_INFO("COMPUTE %u %u %u %u %u", - // (unsigned) matrix_chk_in, (unsigned) matrix_rem_in1, (unsigned) matrix_rem_in2, - // (unsigned) load_cfg, (unsigned) loadable_rows); + // (unsigned) matrix_chk_in, (unsigned) matrix_rem_in1, (unsigned) matrix_rem_in2, + // (unsigned) load_cfg, (unsigned) loadable_rows); } // Compute - for (uint24_t a = 0; a < ninputs; a++) - { - uint16_t plm_offset_m1 = 0; - uint16_t plm_offset_m2 = 0; - - for (uint24_t d1 = 0; d1 < matrix_d1; d1 += loadable_rows) - { - uint16_t loaded_rows_d1 = min(loadable_rows, matrix_d1 - d1); - - for (uint24_t d2 = 0; d2 < matrix_d3; d2 += loadable_rows) - { - uint16_t loaded_rows_d3 = min(loadable_rows, matrix_d3 - d2); - - if (load_cfg != LESS_THAN_ROW) - compute_load_handshake(); - - for (uint16_t d1i = 0; d1i < loaded_rows_d1; d1i++) - { - plm_offset_m1 = d1i * matrix_d2; - - for (uint16_t d2i = 0; d2i < loaded_rows_d3; d2i++) - { - plm_offset_m2 = d2i * matrix_d2; - - // reset accumulator register - accumulator = 0; - - for (uint24_t chk = 0; chk < matrix_chk_in; ++chk) - { - // If true the next is the last (smaller) chunk - if (load_cfg == LESS_THAN_ROW) { - if (chk == matrix_chk_in - 1 && matrix_rem_in2 != 0) { - length = matrix_rem_in2; - } else { - length = DMA_CHUNK; - } - pingpong_m1 = !pingpong_m1; - pingpong_m2 = !pingpong_m2; - compute_load_handshake(); - } else if (load_cfg == LESS_THAN_MATRIX2) { - length = matrix_d2; - if (!d1i && !d2i) { - if (!d2) - pingpong_m1 = !pingpong_m1; - pingpong_m2 = !pingpong_m2; - } - } else { // load_cfg == MORE_THAN_MATRIX2 - length = matrix_d2; - if (!d1i && !d2i) { - pingpong_m1 = !pingpong_m1; - pingpong_m2 = !pingpong_m2; - } - } - - uint16_t plm_i_row = plm_offset_m1; - uint16_t plm_i_col = plm_offset_m2; - for (uint16_t k = 0; k < (length + PARALLELISM - 1) / PARALLELISM; ++k) - { - //HLS_CONSTRAIN_LATENCY(0, HLS_ACHIEVABLE, "constrain-mac"); + for (uint24_t a = 0; a < ninputs; a++) { + uint16_t plm_offset_m1 = 0; + uint16_t plm_offset_m2 = 0; + + for (uint24_t d1 = 0; d1 < matrix_d1; d1 += loadable_rows) { + uint16_t loaded_rows_d1 = min(loadable_rows, matrix_d1 - d1); + + for (uint24_t d2 = 0; d2 < matrix_d3; d2 += loadable_rows) { + uint16_t loaded_rows_d3 = min(loadable_rows, matrix_d3 - d2); + + if (load_cfg != LESS_THAN_ROW) compute_load_handshake(); + + for (uint16_t d1i = 0; d1i < loaded_rows_d1; d1i++) { + plm_offset_m1 = d1i * matrix_d2; + + for (uint16_t d2i = 0; d2i < loaded_rows_d3; d2i++) { + plm_offset_m2 = d2i * matrix_d2; + + // reset accumulator register + accumulator = 0; + + for (uint24_t chk = 0; chk < matrix_chk_in; ++chk) { + // If true the next is the last (smaller) chunk + if (load_cfg == LESS_THAN_ROW) { + if (chk == matrix_chk_in - 1 && matrix_rem_in2 != 0) { + length = matrix_rem_in2; + } + else { + length = DMA_CHUNK; + } + pingpong_m1 = !pingpong_m1; + pingpong_m2 = !pingpong_m2; + compute_load_handshake(); + } + else if (load_cfg == LESS_THAN_MATRIX2) { + length = matrix_d2; + if (!d1i && !d2i) { + if (!d2) pingpong_m1 = !pingpong_m1; + pingpong_m2 = !pingpong_m2; + } + } + else { // load_cfg == MORE_THAN_MATRIX2 + length = matrix_d2; + if (!d1i && !d2i) { + pingpong_m1 = !pingpong_m1; + pingpong_m2 = !pingpong_m2; + } + } + + uint16_t plm_i_row = plm_offset_m1; + uint16_t plm_i_col = plm_offset_m2; + for (uint16_t k = 0; k < (length + PARALLELISM - 1) / PARALLELISM; + ++k) { + // HLS_CONSTRAIN_LATENCY(0, HLS_ACHIEVABLE, "constrain-mac"); #ifdef FIXED_POINT - HLS_PIPELINE_LOOP(HARD_STALL, 2, "pipeline-mac-fixed"); + HLS_PIPELINE_LOOP(HARD_STALL, 2, "pipeline-mac-fixed"); #else - HLS_PIPELINE_LOOP(HARD_STALL, 2, "pipeline-mac-float"); + HLS_PIPELINE_LOOP(HARD_STALL, 2, "pipeline-mac-float"); #endif - HLS_BREAK_ARRAY_DEPENDENCY(input0); - HLS_BREAK_ARRAY_DEPENDENCY(input1); - HLS_BREAK_ARRAY_DEPENDENCY(input2); - HLS_BREAK_ARRAY_DEPENDENCY(input3); - - if (pingpong_m1) { - row[0] = INT2FP(input0[plm_i_row++]); - row[1] = INT2FP(input0[plm_i_row++]); + HLS_BREAK_ARRAY_DEPENDENCY(input0); + HLS_BREAK_ARRAY_DEPENDENCY(input1); + HLS_BREAK_ARRAY_DEPENDENCY(input2); + HLS_BREAK_ARRAY_DEPENDENCY(input3); + + if (pingpong_m1) { + row[0] = INT2FP(input0[plm_i_row++]); + row[1] = INT2FP(input0[plm_i_row++]); #if (PARALLELISM >= 4) - row[2] = INT2FP(input0[plm_i_row++]); - row[3] = INT2FP(input0[plm_i_row++]); + row[2] = INT2FP(input0[plm_i_row++]); + row[3] = INT2FP(input0[plm_i_row++]); #endif #if (PARALLELISM >= 8) - row[4] = INT2FP(input0[plm_i_row++]); - row[5] = INT2FP(input0[plm_i_row++]); - row[6] = INT2FP(input0[plm_i_row++]); - row[7] = INT2FP(input0[plm_i_row++]); + row[4] = INT2FP(input0[plm_i_row++]); + row[5] = INT2FP(input0[plm_i_row++]); + row[6] = INT2FP(input0[plm_i_row++]); + row[7] = INT2FP(input0[plm_i_row++]); #endif #if (PARALLELISM >= 16) - row[8] = INT2FP(input0[plm_i_row++]); - row[9] = INT2FP(input0[plm_i_row++]); - row[10] = INT2FP(input0[plm_i_row++]); - row[11] = INT2FP(input0[plm_i_row++]); - row[12] = INT2FP(input0[plm_i_row++]); - row[13] = INT2FP(input0[plm_i_row++]); - row[14] = INT2FP(input0[plm_i_row++]); - row[15] = INT2FP(input0[plm_i_row++]); + row[8] = INT2FP(input0[plm_i_row++]); + row[9] = INT2FP(input0[plm_i_row++]); + row[10] = INT2FP(input0[plm_i_row++]); + row[11] = INT2FP(input0[plm_i_row++]); + row[12] = INT2FP(input0[plm_i_row++]); + row[13] = INT2FP(input0[plm_i_row++]); + row[14] = INT2FP(input0[plm_i_row++]); + row[15] = INT2FP(input0[plm_i_row++]); #endif - } else { - row[0] = INT2FP(input1[plm_i_row++]); - row[1] = INT2FP(input1[plm_i_row++]); + } + else { + row[0] = INT2FP(input1[plm_i_row++]); + row[1] = INT2FP(input1[plm_i_row++]); #if (PARALLELISM >= 4) - row[2] = INT2FP(input1[plm_i_row++]); - row[3] = INT2FP(input1[plm_i_row++]); + row[2] = INT2FP(input1[plm_i_row++]); + row[3] = INT2FP(input1[plm_i_row++]); #endif #if (PARALLELISM >= 8) - row[4] = INT2FP(input1[plm_i_row++]); - row[5] = INT2FP(input1[plm_i_row++]); - row[6] = INT2FP(input1[plm_i_row++]); - row[7] = INT2FP(input1[plm_i_row++]); + row[4] = INT2FP(input1[plm_i_row++]); + row[5] = INT2FP(input1[plm_i_row++]); + row[6] = INT2FP(input1[plm_i_row++]); + row[7] = INT2FP(input1[plm_i_row++]); #endif #if (PARALLELISM >= 16) - row[8] = INT2FP(input1[plm_i_row++]); - row[9] = INT2FP(input1[plm_i_row++]); - row[10] = INT2FP(input1[plm_i_row++]); - row[11] = INT2FP(input1[plm_i_row++]); - row[12] = INT2FP(input1[plm_i_row++]); - row[13] = INT2FP(input1[plm_i_row++]); - row[14] = INT2FP(input1[plm_i_row++]); - row[15] = INT2FP(input1[plm_i_row++]); + row[8] = INT2FP(input1[plm_i_row++]); + row[9] = INT2FP(input1[plm_i_row++]); + row[10] = INT2FP(input1[plm_i_row++]); + row[11] = INT2FP(input1[plm_i_row++]); + row[12] = INT2FP(input1[plm_i_row++]); + row[13] = INT2FP(input1[plm_i_row++]); + row[14] = INT2FP(input1[plm_i_row++]); + row[15] = INT2FP(input1[plm_i_row++]); #endif - - } - if (pingpong_m2) { - col[0] = INT2FP(input2[plm_i_col++]); - col[1] = INT2FP(input2[plm_i_col++]); + } + if (pingpong_m2) { + col[0] = INT2FP(input2[plm_i_col++]); + col[1] = INT2FP(input2[plm_i_col++]); #if (PARALLELISM >= 4) - col[2] = INT2FP(input2[plm_i_col++]); - col[3] = INT2FP(input2[plm_i_col++]); + col[2] = INT2FP(input2[plm_i_col++]); + col[3] = INT2FP(input2[plm_i_col++]); #endif #if (PARALLELISM >= 8) - col[4] = INT2FP(input2[plm_i_col++]); - col[5] = INT2FP(input2[plm_i_col++]); - col[6] = INT2FP(input2[plm_i_col++]); - col[7] = INT2FP(input2[plm_i_col++]); + col[4] = INT2FP(input2[plm_i_col++]); + col[5] = INT2FP(input2[plm_i_col++]); + col[6] = INT2FP(input2[plm_i_col++]); + col[7] = INT2FP(input2[plm_i_col++]); #endif #if (PARALLELISM >= 16) - col[8] = INT2FP(input2[plm_i_col++]); - col[9] = INT2FP(input2[plm_i_col++]); - col[10] = INT2FP(input2[plm_i_col++]); - col[11] = INT2FP(input2[plm_i_col++]); - col[12] = INT2FP(input2[plm_i_col++]); - col[13] = INT2FP(input2[plm_i_col++]); - col[14] = INT2FP(input2[plm_i_col++]); - col[15] = INT2FP(input2[plm_i_col++]); + col[8] = INT2FP(input2[plm_i_col++]); + col[9] = INT2FP(input2[plm_i_col++]); + col[10] = INT2FP(input2[plm_i_col++]); + col[11] = INT2FP(input2[plm_i_col++]); + col[12] = INT2FP(input2[plm_i_col++]); + col[13] = INT2FP(input2[plm_i_col++]); + col[14] = INT2FP(input2[plm_i_col++]); + col[15] = INT2FP(input2[plm_i_col++]); #endif - } else { - col[0] = INT2FP(input3[plm_i_col++]); - col[1] = INT2FP(input3[plm_i_col++]); + } + else { + col[0] = INT2FP(input3[plm_i_col++]); + col[1] = INT2FP(input3[plm_i_col++]); #if (PARALLELISM >= 4) - col[2] = INT2FP(input3[plm_i_col++]); - col[3] = INT2FP(input3[plm_i_col++]); + col[2] = INT2FP(input3[plm_i_col++]); + col[3] = INT2FP(input3[plm_i_col++]); #endif #if (PARALLELISM >= 8) - col[4] = INT2FP(input3[plm_i_col++]); - col[5] = INT2FP(input3[plm_i_col++]); - col[6] = INT2FP(input3[plm_i_col++]); - col[7] = INT2FP(input3[plm_i_col++]); + col[4] = INT2FP(input3[plm_i_col++]); + col[5] = INT2FP(input3[plm_i_col++]); + col[6] = INT2FP(input3[plm_i_col++]); + col[7] = INT2FP(input3[plm_i_col++]); #endif #if (PARALLELISM >= 16) - col[8] = INT2FP(input3[plm_i_col++]); - col[9] = INT2FP(input3[plm_i_col++]); - col[10] = INT2FP(input3[plm_i_col++]); - col[11] = INT2FP(input3[plm_i_col++]); - col[12] = INT2FP(input3[plm_i_col++]); - col[13] = INT2FP(input3[plm_i_col++]); - col[14] = INT2FP(input3[plm_i_col++]); - col[15] = INT2FP(input3[plm_i_col++]); + col[8] = INT2FP(input3[plm_i_col++]); + col[9] = INT2FP(input3[plm_i_col++]); + col[10] = INT2FP(input3[plm_i_col++]); + col[11] = INT2FP(input3[plm_i_col++]); + col[12] = INT2FP(input3[plm_i_col++]); + col[13] = INT2FP(input3[plm_i_col++]); + col[14] = INT2FP(input3[plm_i_col++]); + col[15] = INT2FP(input3[plm_i_col++]); #endif - } - - uint16_t plm_i = k * PARALLELISM + 1; - mult_out[0] = row[0] * col[0]; - if (plm_i < length) - mult_out[1] = row[1] * col[1]; - else - mult_out[1] = 0; + } + + uint16_t plm_i = k * PARALLELISM + 1; + mult_out[0] = row[0] * col[0]; + if (plm_i < length) mult_out[1] = row[1] * col[1]; + else + mult_out[1] = 0; #if (PARALLELISM >= 4) - if (plm_i + 1 < length) - mult_out[2] = row[2] * col[2]; - else - mult_out[2] = 0; - if (plm_i + 2 < length) - mult_out[3] = row[3] * col[3]; - else - mult_out[3] = 0; + if (plm_i + 1 < length) mult_out[2] = row[2] * col[2]; + else + mult_out[2] = 0; + if (plm_i + 2 < length) mult_out[3] = row[3] * col[3]; + else + mult_out[3] = 0; #endif #if (PARALLELISM >= 8) - if (plm_i + 3 < length) - mult_out[4] = row[4] * col[4]; - else - mult_out[4] = 0; - if (plm_i + 4 < length) - mult_out[5] = row[5] * col[5]; - else - mult_out[5] = 0; - if (plm_i + 5 < length) - mult_out[6] = row[6] * col[6]; - else - mult_out[6] = 0; - if (plm_i + 6 < length) - mult_out[7] = row[7] * col[7]; - else - mult_out[7] = 0; + if (plm_i + 3 < length) mult_out[4] = row[4] * col[4]; + else + mult_out[4] = 0; + if (plm_i + 4 < length) mult_out[5] = row[5] * col[5]; + else + mult_out[5] = 0; + if (plm_i + 5 < length) mult_out[6] = row[6] * col[6]; + else + mult_out[6] = 0; + if (plm_i + 6 < length) mult_out[7] = row[7] * col[7]; + else + mult_out[7] = 0; #endif #if (PARALLELISM >= 16) - if (plm_i + 7 < length) - mult_out[8] = row[8] * col[8]; - else - mult_out[8] = 0; - if (plm_i + 8 < length) - mult_out[9] = row[9] * col[9]; - else - mult_out[9] = 0; - if (plm_i + 9 < length) - mult_out[10] = row[10] * col[10]; - else - mult_out[10] = 0; - if (plm_i + 10 < length) - mult_out[11] = row[11] * col[11]; - else - mult_out[11] = 0; - if (plm_i + 11 < length) - mult_out[12] = row[12] * col[12]; - else - mult_out[12] = 0; - if (plm_i + 12 < length) - mult_out[13] = row[13] * col[13]; - else - mult_out[13] = 0; - if (plm_i + 13 < length) - mult_out[14] = row[14] * col[14]; - else - mult_out[14] = 0; - if (plm_i + 14 < length) - mult_out[15] = row[15] * col[15]; - else - mult_out[15] = 0; + if (plm_i + 7 < length) mult_out[8] = row[8] * col[8]; + else + mult_out[8] = 0; + if (plm_i + 8 < length) mult_out[9] = row[9] * col[9]; + else + mult_out[9] = 0; + if (plm_i + 9 < length) mult_out[10] = row[10] * col[10]; + else + mult_out[10] = 0; + if (plm_i + 10 < length) mult_out[11] = row[11] * col[11]; + else + mult_out[11] = 0; + if (plm_i + 11 < length) mult_out[12] = row[12] * col[12]; + else + mult_out[12] = 0; + if (plm_i + 12 < length) mult_out[13] = row[13] * col[13]; + else + mult_out[13] = 0; + if (plm_i + 13 < length) mult_out[14] = row[14] * col[14]; + else + mult_out[14] = 0; + if (plm_i + 14 < length) mult_out[15] = row[15] * col[15]; + else + mult_out[15] = 0; #endif #if (PARALLELISM == 2) - accumulator += mult_out[0] + mult_out[1]; + accumulator += mult_out[0] + mult_out[1]; #elif (PARALLELISM == 4) - FPDATA add_tmp0 = mult_out[0] + mult_out[1]; - FPDATA add_tmp1 = mult_out[2] + mult_out[3]; - accumulator += add_tmp0 + add_tmp1; + FPDATA add_tmp0 = mult_out[0] + mult_out[1]; + FPDATA add_tmp1 = mult_out[2] + mult_out[3]; + accumulator += add_tmp0 + add_tmp1; #elif (PARALLELISM == 8) - FPDATA add_tmp0 = mult_out[0] + mult_out[1]; - FPDATA add_tmp1 = mult_out[2] + mult_out[3]; - FPDATA add_tmp2 = mult_out[4] + mult_out[5]; - FPDATA add_tmp3 = mult_out[6] + mult_out[7]; - FPDATA add_tmp4 = add_tmp0 + add_tmp1; - FPDATA add_tmp5 = add_tmp2 + add_tmp3; - accumulator += add_tmp4 + add_tmp5; + FPDATA add_tmp0 = mult_out[0] + mult_out[1]; + FPDATA add_tmp1 = mult_out[2] + mult_out[3]; + FPDATA add_tmp2 = mult_out[4] + mult_out[5]; + FPDATA add_tmp3 = mult_out[6] + mult_out[7]; + FPDATA add_tmp4 = add_tmp0 + add_tmp1; + FPDATA add_tmp5 = add_tmp2 + add_tmp3; + accumulator += add_tmp4 + add_tmp5; #elif (PARALLELISM == 16) - FPDATA add_tmp0 = mult_out[0] + mult_out[1]; - FPDATA add_tmp1 = mult_out[2] + mult_out[3]; - FPDATA add_tmp2 = mult_out[4] + mult_out[5]; - FPDATA add_tmp3 = mult_out[6] + mult_out[7]; - FPDATA add_tmp4 = mult_out[8] + mult_out[9]; - FPDATA add_tmp5 = mult_out[10] + mult_out[11]; - FPDATA add_tmp6 = mult_out[12] + mult_out[13]; - FPDATA add_tmp7 = mult_out[14] + mult_out[15]; - FPDATA add_tmp8 = add_tmp0 + add_tmp1; - FPDATA add_tmp9 = add_tmp2 + add_tmp3; - FPDATA add_tmp10 = add_tmp4 + add_tmp5; - FPDATA add_tmp11 = add_tmp6 + add_tmp7; - FPDATA add_tmp12 = add_tmp8 + add_tmp9; - FPDATA add_tmp13 = add_tmp10 + add_tmp11; - accumulator += add_tmp12 + add_tmp13; + FPDATA add_tmp0 = mult_out[0] + mult_out[1]; + FPDATA add_tmp1 = mult_out[2] + mult_out[3]; + FPDATA add_tmp2 = mult_out[4] + mult_out[5]; + FPDATA add_tmp3 = mult_out[6] + mult_out[7]; + FPDATA add_tmp4 = mult_out[8] + mult_out[9]; + FPDATA add_tmp5 = mult_out[10] + mult_out[11]; + FPDATA add_tmp6 = mult_out[12] + mult_out[13]; + FPDATA add_tmp7 = mult_out[14] + mult_out[15]; + FPDATA add_tmp8 = add_tmp0 + add_tmp1; + FPDATA add_tmp9 = add_tmp2 + add_tmp3; + FPDATA add_tmp10 = add_tmp4 + add_tmp5; + FPDATA add_tmp11 = add_tmp6 + add_tmp7; + FPDATA add_tmp12 = add_tmp8 + add_tmp9; + FPDATA add_tmp13 = add_tmp10 + add_tmp11; + accumulator += add_tmp12 + add_tmp13; #endif - } - - } - - // ReLU - accumulator = (do_relu && accumulator < (FPDATA) 0) ? (FPDATA) 0 : accumulator; - - // Write to output PLM - if (pingpong_out) { - output0[store_count] = FP2INT(accumulator); - } else { - output1[store_count] = FP2INT(accumulator); - } - - // Call the store_output process and wait for the store_output process - // -> output PLM is not in pingpong - - sync_compute_store(store_count, loaded_rows_d3, load_cfg, - loadable_rows, pingpong_out); - } - } - } - } + } + } + + // ReLU + accumulator = + (do_relu && accumulator < (FPDATA)0) ? (FPDATA)0 : accumulator; + + // Write to output PLM + if (pingpong_out) { output0[store_count] = FP2INT(accumulator); } + else { + output1[store_count] = FP2INT(accumulator); + } + + // Call the store_output process and wait for the store_output process + // -> output PLM is not in pingpong + + sync_compute_store(store_count, loaded_rows_d3, load_cfg, loadable_rows, + pingpong_out); + } + } + } + } } // Force to store the last chunk if (store_count) { - store_count = OUT_DMA_CHUNK - 1; - sync_compute_store(store_count, 1, load_cfg, loadable_rows, pingpong_out); + store_count = OUT_DMA_CHUNK - 1; + sync_compute_store(store_count, 1, load_cfg, loadable_rows, pingpong_out); } // Conclude { - this->process_done(); + this->process_done(); } } diff --git a/accelerators/stratus_hls/gemm_stratus/hw/tb/gemm_pv.c b/accelerators/stratus_hls/gemm_stratus/hw/tb/gemm_pv.c index 2d505180e0..d2dc20e327 100644 --- a/accelerators/stratus_hls/gemm_stratus/hw/tb/gemm_pv.c +++ b/accelerators/stratus_hls/gemm_stratus/hw/tb/gemm_pv.c @@ -4,51 +4,52 @@ #include #if defined(USE_CBLAS) -#include "cblas.h" + #include "cblas.h" #endif // USE_CBLAS #include "gemm_pv.h" -void _gemm_pv(double *mtx_inA, double *mtx_inB, double *mtx_out, - size_t is_trans, size_t rowsA, size_t colsA, size_t colsB) +void _gemm_pv(double *mtx_inA, double *mtx_inB, double *mtx_out, size_t is_trans, size_t rowsA, + size_t colsA, size_t colsB) { #if defined(USE_CBLAS) if (is_trans) { - // Perform the following operation: C := alpha * A * B^T + beta * C - cblas_dgemm(CblasRowMajor, // row-major order representation - CblasNoTrans, // matrix_in1 no transposed - CblasTrans, // matrix_in2 is transposed - rowsA, // mtx_in1 rows - colsA, // mtx_in1 cols - colsB, // mtx_in2 cols - (double) 1.0, // alpha coeff -> 1.0 - mtx_inA, // mtx_in1 val - colsA, // matrix_in1 ld - mtx_inB, // mtx_in2 val - colsA, // matrix_in2 ld - (double) 0.0, // beta coeff -> 0.0 - mtx_out, // mtx_out val - colsB); // mtx_out ld - } else { - - // Perform the following operation: C := alpha * A * B^T + beta * C - cblas_dgemm(CblasRowMajor, // row-major order representation - CblasNoTrans, // matrix_in1 no transposed - CblasNoTrans, // matrix_in2 is transposed - rowsA, // mtx_in1 rows - colsA, // mtx_in1 cols - colsB, // mtx_in2 cols - (double) 1.0, // alpha coeff -> 1.0 - mtx_inA, // mtx_in1 val - colsA, // matrix_in1 ld - mtx_inB, // mtx_in2 val - colsA, // matrix_in2 ld - (double) 0.0, // beta coeff -> 0.0 - mtx_out, // mtx_out val - colsB); // mtx_out ld + // Perform the following operation: C := alpha * A * B^T + beta * C + cblas_dgemm(CblasRowMajor, // row-major order representation + CblasNoTrans, // matrix_in1 no transposed + CblasTrans, // matrix_in2 is transposed + rowsA, // mtx_in1 rows + colsA, // mtx_in1 cols + colsB, // mtx_in2 cols + (double)1.0, // alpha coeff -> 1.0 + mtx_inA, // mtx_in1 val + colsA, // matrix_in1 ld + mtx_inB, // mtx_in2 val + colsA, // matrix_in2 ld + (double)0.0, // beta coeff -> 0.0 + mtx_out, // mtx_out val + colsB); // mtx_out ld + } + else { + + // Perform the following operation: C := alpha * A * B^T + beta * C + cblas_dgemm(CblasRowMajor, // row-major order representation + CblasNoTrans, // matrix_in1 no transposed + CblasNoTrans, // matrix_in2 is transposed + rowsA, // mtx_in1 rows + colsA, // mtx_in1 cols + colsB, // mtx_in2 cols + (double)1.0, // alpha coeff -> 1.0 + mtx_inA, // mtx_in1 val + colsA, // matrix_in1 ld + mtx_inB, // mtx_in2 val + colsA, // matrix_in2 ld + (double)0.0, // beta coeff -> 0.0 + mtx_out, // mtx_out val + colsB); // mtx_out ld } #else // Inefficient implementation @@ -56,36 +57,33 @@ void _gemm_pv(double *mtx_inA, double *mtx_inB, double *mtx_out, unsigned d1, d2, d3, mtx_inA_i, mtx_inB_i; double accumulator; - for (d1 = 0; d1 < rowsA; ++d1) - { - for (d2 = 0; d2 < colsB; ++d2) - { - accumulator = 0.0; + for (d1 = 0; d1 < rowsA; ++d1) { + for (d2 = 0; d2 < colsB; ++d2) { + accumulator = 0.0; - for (d3 = 0; d3 < colsA; ++d3) - { - mtx_inA_i = d1 * colsA + d3; - mtx_inB_i = is_trans ? (d2 * colsA + d3) : (d3 * colsB + d2); + for (d3 = 0; d3 < colsA; ++d3) { + mtx_inA_i = d1 * colsA + d3; + mtx_inB_i = is_trans ? (d2 * colsA + d3) : (d3 * colsB + d2); - accumulator += mtx_inA[mtx_inA_i] * mtx_inB[mtx_inB_i]; - } + accumulator += mtx_inA[mtx_inA_i] * mtx_inB[mtx_inB_i]; + } - mtx_out[d1 * colsB + d2] = accumulator; - } - } + mtx_out[d1 * colsB + d2] = accumulator; + } + } #endif } void gemm_pv(double_matrix_t *mtx_inA, double_matrix_t *mtx_inB, double_matrix_t **mtx_out) { int i; - unsigned batch_size = mtx_inA->dims[0]; - unsigned rowsA = mtx_inA->dims[1]; - unsigned colsA = mtx_inA->dims[2]; - unsigned colsB = mtx_inB->dims[2]; - unsigned size_inA = rowsA * colsA; - unsigned size_inB = colsA * colsB; - unsigned size_out = rowsA * colsB; + unsigned batch_size = mtx_inA->dims[0]; + unsigned rowsA = mtx_inA->dims[1]; + unsigned colsA = mtx_inA->dims[2]; + unsigned colsB = mtx_inB->dims[2]; + unsigned size_inA = rowsA * colsA; + unsigned size_inB = colsA * colsB; + unsigned size_out = rowsA * colsB; size_t out_sizes[M_DIMS] = {batch_size, rowsA, colsB}; assert(mtx_inA->dim == M_DIMS); @@ -96,11 +94,8 @@ void gemm_pv(double_matrix_t *mtx_inA, double_matrix_t *mtx_inB, double_matrix_t create_double_matrix_t(mtx_out, out_sizes, M_DIMS); for (i = 0; i < batch_size; ++i) { - - _gemm_pv(&(mtx_inA->data[i * size_inA]), - &(mtx_inB->data[i * size_inB]), - &((*mtx_out)->data[i * size_out]), - mtx_inB->is_transposed, - rowsA, colsA, colsB); + + _gemm_pv(&(mtx_inA->data[i * size_inA]), &(mtx_inB->data[i * size_inB]), + &((*mtx_out)->data[i * size_out]), mtx_inB->is_transposed, rowsA, colsA, colsB); } } diff --git a/accelerators/stratus_hls/gemm_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/gemm_stratus/hw/tb/sc_main.cpp index 75896b080a..0ca146195e 100644 --- a/accelerators/stratus_hls/gemm_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/gemm_stratus/hw/tb/sc_main.cpp @@ -5,43 +5,43 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; extern void esc_elaborate() { - // Creating the whole system - testbench = new system_t("testbench"); + // Creating the whole system + testbench = new system_t("testbench"); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); + esc_log_pass(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/gemm_stratus/sw/baremetal/gemm.c b/accelerators/stratus_hls/gemm_stratus/sw/baremetal/gemm.c index 0f6a07bdfe..b99560a957 100644 --- a/accelerators/stratus_hls/gemm_stratus/sw/baremetal/gemm.c +++ b/accelerators/stratus_hls/gemm_stratus/sw/baremetal/gemm.c @@ -3,7 +3,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -20,59 +20,56 @@ // Define bit width (decomment the one needed) #ifndef __riscv -#define BITWIDTH 32 + #define BITWIDTH 32 // #define BITWIDTH 64 #else -#define BITWIDTH 32 + #define BITWIDTH 32 // #define BITWIDTH 64 #endif /* End of user defined */ #ifdef __UINT -#if (BITWIDTH == 32) + #if (BITWIDTH == 32) typedef unsigned token_t; -#elif (BITWIDTH == 64) + #elif (BITWIDTH == 64) typedef long long unsigned token_t; -#endif + #endif #endif #ifdef __INT -#if (BITWIDTH == 32) + #if (BITWIDTH == 32) typedef int token_t; -#elif (BITWIDTH == 64) + #elif (BITWIDTH == 64) typedef long long token_t; -#endif + #endif #endif #ifdef __FIXED -#if (BITWIDTH == 32) + #if (BITWIDTH == 32) typedef int token_t; -#define fx2float fixed32_to_float -#define float2fx float_to_fixed32 -#define FX_IL 16 -#elif (BITWIDTH == 64) + #define fx2float fixed32_to_float + #define float2fx float_to_fixed32 + #define FX_IL 16 + #elif (BITWIDTH == 64) typedef long long token_t; -#define fx2float fixed64_to_double -#define float2fx double_to_fixed64 -#define FX_IL 32 -#endif + #define fx2float fixed64_to_double + #define float2fx double_to_fixed64 + #define FX_IL 32 + #endif #endif #ifdef __FLOAT -#if (BITWIDTH == 32) + #if (BITWIDTH == 32) typedef float token_t; -#elif (BITWIDTH == 64) + #elif (BITWIDTH == 64) typedef double token_t; -#endif + #endif #endif typedef float native_t; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } #define MAX_PRINTED_ERRORS 10 @@ -80,12 +77,12 @@ static unsigned DMA_WORD_PER_BEAT(unsigned _st) #define DEV_NAME "sld,gemm_stratus" /* <<--params-->> */ -const int32_t do_relu = 0; +const int32_t do_relu = 0; const int32_t transpose = 1; -const int32_t ninputs = 2; -const int32_t d3 = 8; -const int32_t d2 = 8; -const int32_t d1 = 8; +const int32_t ninputs = 2; +const int32_t d3 = 8; +const int32_t d2 = 8; +const int32_t d1 = 8; int32_t st_offset; const int32_t ld_offset1 = 0; int32_t ld_offset2; @@ -101,56 +98,53 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ -#define GEMM_TRANSPOSE_REG 0x60 -#define GEMM_DO_RELU_REG 0x5c -#define GEMM_ST_OFFSET_REG 0x58 +#define GEMM_TRANSPOSE_REG 0x60 +#define GEMM_DO_RELU_REG 0x5c +#define GEMM_ST_OFFSET_REG 0x58 #define GEMM_LD_OFFSET2_REG 0x54 #define GEMM_LD_OFFSET1_REG 0x50 -#define GEMM_D3_REG 0x4c -#define GEMM_D2_REG 0x48 -#define GEMM_D1_REG 0x44 -#define GEMM_NINPUTS_REG 0x40 +#define GEMM_D3_REG 0x4c +#define GEMM_D2_REG 0x48 +#define GEMM_D1_REG 0x44 +#define GEMM_NINPUTS_REG 0x40 static int validate_buf(token_t *out, native_t *gold) { - int j; - native_t val; - unsigned errors = 0; + int j; + native_t val; + unsigned errors = 0; - for (j = 0; j < out_len; j++) { + for (j = 0; j < out_len; j++) { #ifdef __FIXED - val = fx2float(out[j], FX_IL); + val = fx2float(out[j], FX_IL); #else - val = out[j]; + val = out[j]; #endif - if (gold[j] != val) { - errors++; - if (errors <= MAX_PRINTED_ERRORS) { - printf("%d : %d : %d\n", j, (int) val, (int) gold[j]); - } + if (gold[j] != val) { + errors++; + if (errors <= MAX_PRINTED_ERRORS) { + printf("%d : %d : %d\n", j, (int)val, (int)gold[j]); } - } + } + } - return errors; + return errors; } - -static void init_buf (token_t *in, native_t * gold) +static void init_buf(token_t *in, native_t *gold) { int i; #include "input.h" #ifdef __FIXED - for (i = 0; i < ninputs * (d1*d2 + d2*d3); i++) { + for (i = 0; i < ninputs * (d1 * d2 + d2 * d3); i++) { in[i] = float2fx(in[i], FX_IL); } #endif @@ -158,145 +152,144 @@ static void init_buf (token_t *in, native_t * gold) #include "gold.h" } -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable; - token_t *mem; - native_t *gold; - unsigned errors = 0; - unsigned coherence; - - st_offset = ninputs * (d1 * d2 + d2 * d3); - ld_offset2 = ninputs * (d1 * d2); - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) <= 1) { - in_words_adj = ninputs * (d1*d2 + d2*d3); - out_words_adj = ninputs * d1 * d3; - } else { - in_words_adj = round_up(ninputs * (d1*d2 + d2*d3), DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(ninputs * d1 * d3, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_GEMM, DEV_NAME); - if (ndev == 0) { - printf("gemm not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_size); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - printf(" memory buffer base-address for gold = %p\n", gold); - - // Allocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable; + token_t *mem; + native_t *gold; + unsigned errors = 0; + unsigned coherence; + + st_offset = ninputs * (d1 * d2 + d2 * d3); + ld_offset2 = ninputs * (d1 * d2); + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) <= 1) { + in_words_adj = ninputs * (d1 * d2 + d2 * d3); + out_words_adj = ninputs * d1 * d3; + } + else { + in_words_adj = round_up(ninputs * (d1 * d2 + d2 * d3), DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(ninputs * d1 * d3, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_GEMM, DEV_NAME); + if (ndev == 0) { + printf("gemm not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_size); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); + printf(" memory buffer base-address for gold = %p\n", gold); + + // Allocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - - printf(" Generate input...\n"); - init_buf(mem, gold); + printf(" Generate input...\n"); - // Pass common configuration parameters + init_buf(mem, gold); - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); + // Pass common configuration parameters - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0); - iowrite32(dev, DST_OFFSET_REG, 0); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - // Pass accelerator-specific configuration parametxers - /* <<--regs-config-->> */ - iowrite32(dev, GEMM_DO_RELU_REG, do_relu); - iowrite32(dev, GEMM_TRANSPOSE_REG, transpose); - iowrite32(dev, GEMM_NINPUTS_REG, ninputs); - iowrite32(dev, GEMM_D3_REG, d3); - iowrite32(dev, GEMM_D2_REG, d2); - iowrite32(dev, GEMM_D1_REG, d1); - iowrite32(dev, GEMM_ST_OFFSET_REG, st_offset); - iowrite32(dev, GEMM_LD_OFFSET1_REG, ld_offset1); - iowrite32(dev, GEMM_LD_OFFSET2_REG, ld_offset2); + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0); + iowrite32(dev, DST_OFFSET_REG, 0); - // Flush (customize coherence model here) - esp_flush(coherence); + // Pass accelerator-specific configuration parametxers + /* <<--regs-config-->> */ + iowrite32(dev, GEMM_DO_RELU_REG, do_relu); + iowrite32(dev, GEMM_TRANSPOSE_REG, transpose); + iowrite32(dev, GEMM_NINPUTS_REG, ninputs); + iowrite32(dev, GEMM_D3_REG, d3); + iowrite32(dev, GEMM_D2_REG, d2); + iowrite32(dev, GEMM_D1_REG, d1); + iowrite32(dev, GEMM_ST_OFFSET_REG, st_offset); + iowrite32(dev, GEMM_LD_OFFSET1_REG, ld_offset1); + iowrite32(dev, GEMM_LD_OFFSET2_REG, ld_offset2); - // Start accelerators - printf(" Start...\n"); + // Flush (customize coherence model here) + esp_flush(coherence); - iowrite32(dev, CMD_REG, CMD_MASK_START); + // Start accelerators + printf(" Start...\n"); - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); + iowrite32(dev, CMD_REG, CMD_MASK_START); - printf(" Done\n"); - printf(" validating...\n"); + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); + printf(" Done\n"); + printf(" validating...\n"); - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } - return 0; + return 0; } diff --git a/accelerators/stratus_hls/gemm_stratus/sw/linux/app/gemm.c b/accelerators/stratus_hls/gemm_stratus/sw/linux/app/gemm.c index 964454e5d2..93e9b8a473 100644 --- a/accelerators/stratus_hls/gemm_stratus/sw/linux/app/gemm.c +++ b/accelerators/stratus_hls/gemm_stratus/sw/linux/app/gemm.c @@ -1,8 +1,8 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include "libesp.h" #include "cfg.h" +#include "libesp.h" static void validate_buffer(token_t *acc_buf, native_t *sw_buf, unsigned len) { @@ -15,24 +15,23 @@ static void validate_buffer(token_t *acc_buf, native_t *sw_buf, unsigned len) for (i = 0; i < len; i++) { #ifdef __FIXED - val = fx2float(acc_buf[i], FX_IL); + val = fx2float(acc_buf[i], FX_IL); #else - val = acc_buf[i]; + val = acc_buf[i]; #endif - if (sw_buf[i] != val) { - errors++; - if (errors <= MAX_PRINTED_ERRORS) - printf("index %d : output %d : expected %d <-- ERROR\n", i, (int) val, (int) sw_buf[i]); - } + if (sw_buf[i] != val) { + errors++; + if (errors <= MAX_PRINTED_ERRORS) + printf("index %d : output %d : expected %d <-- ERROR\n", i, (int)val, + (int)sw_buf[i]); + } } - if (!errors) - printf("\n ** Test PASSED! **\n"); + if (!errors) printf("\n ** Test PASSED! **\n"); else - printf("\n ** Test FAILED! **\n"); + printf("\n ** Test FAILED! **\n"); } - /* User-defined code */ static void init_buffer(token_t *acc_buf, native_t *sw_buf, unsigned in_len) { @@ -41,47 +40,46 @@ static void init_buffer(token_t *acc_buf, native_t *sw_buf, unsigned in_len) printf(" Initialize inputs\n"); for (i = 0; i < in_len; i++) { - native_t val = i % 17 - 8; + native_t val = i % 17 - 8; #ifdef __FIXED acc_buf[i] = float2fx(val, FX_IL); #else acc_buf[i] = val; #endif - sw_buf[i] = val; + sw_buf[i] = val; } } - /* User-defined code */ static void init_parameters(int test, int32_t do_relu, int32_t transpose, int32_t ninputs, - int32_t d3, int32_t d2, int32_t d1, - unsigned *in_len, unsigned *in1_len, unsigned *out_len, - unsigned *in_size, unsigned *out_size, unsigned *size) + int32_t d3, int32_t d2, int32_t d1, unsigned *in_len, unsigned *in1_len, + unsigned *out_len, unsigned *in_size, unsigned *out_size, + unsigned *size) { int32_t ld_offset1, ld_offset2, st_offset; unsigned in2_len; - - *in1_len = round_up(ninputs * d1 * d2, DMA_WORD_PER_BEAT(sizeof(token_t))); - in2_len = round_up(ninputs * d2 * d3, DMA_WORD_PER_BEAT(sizeof(token_t))); - *in_len = *in1_len + in2_len; - *out_len = round_up(ninputs * d1 * d3, DMA_WORD_PER_BEAT(sizeof(token_t))); - *in_size = *in_len * sizeof(token_t); + + *in1_len = round_up(ninputs * d1 * d2, DMA_WORD_PER_BEAT(sizeof(token_t))); + in2_len = round_up(ninputs * d2 * d3, DMA_WORD_PER_BEAT(sizeof(token_t))); + *in_len = *in1_len + in2_len; + *out_len = round_up(ninputs * d1 * d3, DMA_WORD_PER_BEAT(sizeof(token_t))); + *in_size = *in_len * sizeof(token_t); *out_size = *out_len * sizeof(token_t); - *size = *in_size + *out_size; + *size = *in_size + *out_size; ld_offset1 = 0; ld_offset2 = *in1_len; - st_offset = *in_len; - - gemm_cfg_000[0].do_relu = do_relu; - gemm_cfg_000[0].transpose = transpose; - gemm_cfg_000[0].ninputs = ninputs; - gemm_cfg_000[0].d1 = d1; - gemm_cfg_000[0].d2 = d2; - gemm_cfg_000[0].d3 = d3; + st_offset = *in_len; + + gemm_cfg_000[0].do_relu = do_relu; + gemm_cfg_000[0].transpose = transpose; + gemm_cfg_000[0].ninputs = ninputs; + gemm_cfg_000[0].d1 = d1; + gemm_cfg_000[0].d2 = d2; + gemm_cfg_000[0].d3 = d3; gemm_cfg_000[0].ld_offset1 = ld_offset1; gemm_cfg_000[0].ld_offset2 = ld_offset2; - gemm_cfg_000[0].st_offset = st_offset; + gemm_cfg_000[0].st_offset = st_offset; // print test info printf(" Prepare test %d parameters\n", test); @@ -96,9 +94,8 @@ static void init_parameters(int test, int32_t do_relu, int32_t transpose, int32_ printf(" .ld_offset2 = %d\n", ld_offset2); } -static void sw_run(int32_t do_relu, int32_t transpose, int32_t ninputs, - int32_t d3, int32_t d2, int32_t d1, - native_t *in1, native_t *in2, native_t *out) +static void sw_run(int32_t do_relu, int32_t transpose, int32_t ninputs, int32_t d3, int32_t d2, + int32_t d1, native_t *in1, native_t *in2, native_t *out) { int i, j, k, l; struct timespec th_start, th_end; @@ -106,29 +103,25 @@ static void sw_run(int32_t do_relu, int32_t transpose, int32_t ninputs, gettime(&th_start); - for (l = 0; l < ninputs; ++l) - { - in1_l = &in1[l * d1 * d2]; - in2_l = &in2[l * d2 * d3]; - out_l = &out[l * d1 * d3]; - - for (i = 0; i < d1; ++i) - { - for (j = 0; j < d3; ++j) - { - native_t accumulator = 0.0; - - for (k = 0; k < d2; ++k) - { - int mtx_in1_i = i * d2 + k; - int mtx_in2_i = transpose ? (j * d2 + k) : (k * d3 + j); - - accumulator += in1_l[mtx_in1_i] * in2_l[mtx_in2_i]; - } - - out_l[i * d3 + j] = accumulator; - } - } + for (l = 0; l < ninputs; ++l) { + in1_l = &in1[l * d1 * d2]; + in2_l = &in2[l * d2 * d3]; + out_l = &out[l * d1 * d3]; + + for (i = 0; i < d1; ++i) { + for (j = 0; j < d3; ++j) { + native_t accumulator = 0.0; + + for (k = 0; k < d2; ++k) { + int mtx_in1_i = i * d2 + k; + int mtx_in2_i = transpose ? (j * d2 + k) : (k * d3 + j); + + accumulator += in1_l[mtx_in1_i] * in2_l[mtx_in2_i]; + } + + out_l[i * d3 + j] = accumulator; + } + } } gettime(&th_end); @@ -151,88 +144,80 @@ int main(int argc, char **argv) token_t *acc_buf; native_t *sw_buf; - int32_t do_relu [MAX_TESTS] = { 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}; + int32_t do_relu[MAX_TESTS] = {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}; - int32_t transpose[MAX_TESTS] = { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, - 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 1, 0, 0, 1, 1, 1}; + int32_t transpose[MAX_TESTS] = {1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1}; - int32_t ninputs [MAX_TESTS] = { 2, 32, 4, 1, 8, 1, 1, 128, 1, 1, - 1, 2, 1, 1, 1, 1, 4, 8, 2, 2, - 2, 2, 2, 1, 128, 1, 4, 2, 2, 2}; + int32_t ninputs[MAX_TESTS] = {2, 32, 4, 1, 8, 1, 1, 128, 1, 1, 1, 2, 1, 1, 1, + 1, 4, 8, 2, 2, 2, 2, 2, 1, 128, 1, 4, 2, 2, 2}; - int32_t d3 [MAX_TESTS] = { 8, 8, 8, 32, 32, 32, 128, 128, 128, 1, - 1, 20, 2, 2, 64, 64, 11, 18, 18, 21, - 11, 18, 18, 21, 128, 8, 8, 8, 8, 21}; + int32_t d3[MAX_TESTS] = {8, 8, 8, 32, 32, 32, 128, 128, 128, 1, 1, 20, 2, 2, 64, + 64, 11, 18, 18, 21, 11, 18, 18, 21, 128, 8, 8, 8, 8, 21}; - int32_t d2 [MAX_TESTS] = { 8, 8, 8, 32, 32, 32, 128, 128, 128, 2048, - 2048, 16, 64, 2048, 1, 2, 246, 25, 14, 14, - 26, 25, 14, 14, 128, 8, 8, 8, 8, 14}; + int32_t d2[MAX_TESTS] = {8, 8, 8, 32, 32, 32, 128, 128, 128, 2048, 2048, 16, 64, 2048, 1, + 2, 246, 25, 14, 14, 26, 25, 14, 14, 128, 8, 8, 8, 8, 14}; - int32_t d1 [MAX_TESTS] = { 8, 8, 8, 32, 32, 32, 128, 128, 128, 1, - 8, 1, 10, 1, 64, 64, 21, 22, 31, 22, - 21,22, 31, 22, 128, 8, 8, 8, 8, 11}; + int32_t d1[MAX_TESTS] = {8, 8, 8, 32, 32, 32, 128, 128, 128, 1, 8, 1, 10, 1, 64, + 64, 21, 22, 31, 22, 21, 22, 31, 22, 128, 8, 8, 8, 8, 11}; printf("\n====== %s ======\n\n", cfg_000[0].devname); // command line arguments - if (argc < 3) { - n_tests = 1; - } else if (argc == 3) { - n_tests = strtol(argv[1], NULL, 10); - if (n_tests > MAX_TESTS) { - printf("Wrong input arguments!"); - return 1; - } - start_test = strtol(argv[2], NULL, 10); - if (start_test > MAX_TESTS) { - printf("Wrong input arguments!"); - return 1; - } - - } else { - printf("Wrong input arguments!"); - return 1; + if (argc < 3) { n_tests = 1; } + else if (argc == 3) { + n_tests = strtol(argv[1], NULL, 10); + if (n_tests > MAX_TESTS) { + printf("Wrong input arguments!"); + return 1; + } + start_test = strtol(argv[2], NULL, 10); + if (start_test > MAX_TESTS) { + printf("Wrong input arguments!"); + return 1; + } + } + else { + printf("Wrong input arguments!"); + return 1; } printf(" Executing %d tests\n", n_tests); // allocations printf(" Allocations\n"); - acc_buf = (token_t *) esp_alloc(MAX_SIZE); + acc_buf = (token_t *)esp_alloc(MAX_SIZE); cfg_000[0].hw_buf = acc_buf; sw_buf = malloc(MAX_SIZE); for (test = start_test - 1; test < n_tests + start_test - 1; ++test) { - printf("\n\n-------------------\n"); - printf("TEST #%d\n", test + 1); + printf("\n\n-------------------\n"); + printf("TEST #%d\n", test + 1); - // calculate test parameters - init_parameters(test, - do_relu[test], transpose[test], ninputs[test], d3[test], d2[test], d1[test], - &in_len, &in1_len, &out_len, &in_size, &out_size, &size); + // calculate test parameters + init_parameters(test, do_relu[test], transpose[test], ninputs[test], d3[test], d2[test], + d1[test], &in_len, &in1_len, &out_len, &in_size, &out_size, &size); - // initialize input data - init_buffer(acc_buf, sw_buf, in_len); + // initialize input data + init_buffer(acc_buf, sw_buf, in_len); - // hardware execution - printf(" Start accelerator execution\n"); - esp_run(cfg_000, NACC); - printf(" Completed accelerator execution\n"); + // hardware execution + printf(" Start accelerator execution\n"); + esp_run(cfg_000, NACC); + printf(" Completed accelerator execution\n"); - // software execution - printf(" Start software execution\n"); - sw_run(do_relu[test], transpose[test], ninputs[test], d3[test], d2[test], d1[test], - sw_buf, &sw_buf[in1_len], &sw_buf[in_len]); - printf(" Completed software execution\n"); + // software execution + printf(" Start software execution\n"); + sw_run(do_relu[test], transpose[test], ninputs[test], d3[test], d2[test], d1[test], sw_buf, + &sw_buf[in1_len], &sw_buf[in_len]); + printf(" Completed software execution\n"); - // validation - // errors = print_input(buf, gold); - validate_buffer(&acc_buf[in_len], &sw_buf[in_len], out_len); + // validation + // errors = print_input(buf, gold); + validate_buffer(&acc_buf[in_len], &sw_buf[in_len], out_len); } // free diff --git a/accelerators/stratus_hls/gemm_stratus/sw/linux/driver/gemm_stratus.c b/accelerators/stratus_hls/gemm_stratus/sw/linux/driver/gemm_stratus.c index bb79e230f9..9de25e8131 100644 --- a/accelerators/stratus_hls/gemm_stratus/sw/linux/driver/gemm_stratus.c +++ b/accelerators/stratus_hls/gemm_stratus/sw/linux/driver/gemm_stratus.c @@ -1,142 +1,135 @@ -#include #include +#include #include -#include #include +#include #include "gemm_stratus.h" -#define DRV_NAME "gemm_stratus" +#define DRV_NAME "gemm_stratus" /* <<--regs-->> */ -#define GEMM_TRANSPOSE_REG 0x60 -#define GEMM_DO_RELU_REG 0x5c -#define GEMM_ST_OFFSET_REG 0x58 +#define GEMM_TRANSPOSE_REG 0x60 +#define GEMM_DO_RELU_REG 0x5c +#define GEMM_ST_OFFSET_REG 0x58 #define GEMM_LD_OFFSET2_REG 0x54 #define GEMM_LD_OFFSET1_REG 0x50 -#define GEMM_D3_REG 0x4c -#define GEMM_D2_REG 0x48 -#define GEMM_D1_REG 0x44 -#define GEMM_NINPUTS_REG 0x40 +#define GEMM_D3_REG 0x4c +#define GEMM_D2_REG 0x48 +#define GEMM_D1_REG 0x44 +#define GEMM_NINPUTS_REG 0x40 struct gemm_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver gemm_driver; static struct of_device_id gemm_device_ids[] = { - { - .name = "SLD_GEMM_STRATUS", - }, - { - .name = "eb_051", - }, - { - .compatible = "sld,gemm_stratus", - }, - { }, + { + .name = "SLD_GEMM_STRATUS", + }, + { + .name = "eb_051", + }, + { + .compatible = "sld,gemm_stratus", + }, + {}, }; static int gemm_devs; static inline struct gemm_stratus_device *to_gemm(struct esp_device *esp) { - return container_of(esp, struct gemm_stratus_device, esp); + return container_of(esp, struct gemm_stratus_device, esp); } static void gemm_prep_xfer(struct esp_device *esp, void *arg) { - struct gemm_stratus_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->do_relu, esp->iomem + GEMM_DO_RELU_REG); - iowrite32be(a->transpose, esp->iomem + GEMM_TRANSPOSE_REG); - iowrite32be(a->ninputs, esp->iomem + GEMM_NINPUTS_REG); - iowrite32be(a->d3, esp->iomem + GEMM_D3_REG); - iowrite32be(a->d2, esp->iomem + GEMM_D2_REG); - iowrite32be(a->d1, esp->iomem + GEMM_D1_REG); - iowrite32be(a->st_offset, esp->iomem + GEMM_ST_OFFSET_REG); - iowrite32be(a->ld_offset1, esp->iomem + GEMM_LD_OFFSET1_REG); - iowrite32be(a->ld_offset2, esp->iomem + GEMM_LD_OFFSET2_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); + struct gemm_stratus_access *a = arg; + + /* <<--regs-config-->> */ + iowrite32be(a->do_relu, esp->iomem + GEMM_DO_RELU_REG); + iowrite32be(a->transpose, esp->iomem + GEMM_TRANSPOSE_REG); + iowrite32be(a->ninputs, esp->iomem + GEMM_NINPUTS_REG); + iowrite32be(a->d3, esp->iomem + GEMM_D3_REG); + iowrite32be(a->d2, esp->iomem + GEMM_D2_REG); + iowrite32be(a->d1, esp->iomem + GEMM_D1_REG); + iowrite32be(a->st_offset, esp->iomem + GEMM_ST_OFFSET_REG); + iowrite32be(a->ld_offset1, esp->iomem + GEMM_LD_OFFSET1_REG); + iowrite32be(a->ld_offset2, esp->iomem + GEMM_LD_OFFSET2_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool gemm_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct gemm_stratus_device *gemm = to_gemm(esp); */ - /* struct gemm_stratus_access *a = arg; */ + /* struct gemm_stratus_device *gemm = to_gemm(esp); */ + /* struct gemm_stratus_access *a = arg; */ - return true; + return true; } static int gemm_probe(struct platform_device *pdev) { - struct gemm_stratus_device *gemm; - struct esp_device *esp; - int rc; - - gemm = kzalloc(sizeof(*gemm), GFP_KERNEL); - if (gemm == NULL) - return -ENOMEM; - esp = &gemm->esp; - esp->module = THIS_MODULE; - esp->number = gemm_devs; - esp->driver = &gemm_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - gemm_devs++; - return 0; - err: - kfree(gemm); - return rc; + struct gemm_stratus_device *gemm; + struct esp_device *esp; + int rc; + + gemm = kzalloc(sizeof(*gemm), GFP_KERNEL); + if (gemm == NULL) return -ENOMEM; + esp = &gemm->esp; + esp->module = THIS_MODULE; + esp->number = gemm_devs; + esp->driver = &gemm_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + gemm_devs++; + return 0; +err: + kfree(gemm); + return rc; } static int __exit gemm_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct gemm_stratus_device *gemm = to_gemm(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct gemm_stratus_device *gemm = to_gemm(esp); - esp_device_unregister(esp); - kfree(gemm); - return 0; + esp_device_unregister(esp); + kfree(gemm); + return 0; } static struct esp_driver gemm_driver = { - .plat = { - .probe = gemm_probe, - .remove = gemm_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = gemm_device_ids, - }, - }, - .xfer_input_ok = gemm_xfer_input_ok, - .prep_xfer = gemm_prep_xfer, - .ioctl_cm = GEMM_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct gemm_stratus_access), + .plat = + { + .probe = gemm_probe, + .remove = gemm_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = gemm_device_ids, + }, + }, + .xfer_input_ok = gemm_xfer_input_ok, + .prep_xfer = gemm_prep_xfer, + .ioctl_cm = GEMM_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct gemm_stratus_access), }; -static int __init gemm_init(void) -{ - return esp_driver_register(&gemm_driver); -} +static int __init gemm_init(void) { return esp_driver_register(&gemm_driver); } -static void __exit gemm_exit(void) -{ - esp_driver_unregister(&gemm_driver); -} +static void __exit gemm_exit(void) { esp_driver_unregister(&gemm_driver); } -module_init(gemm_init) -module_exit(gemm_exit) +module_init(gemm_init) module_exit(gemm_exit) -MODULE_DEVICE_TABLE(of, gemm_device_ids); + MODULE_DEVICE_TABLE(of, gemm_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/gemm_stratus/sw/linux/include/gemm_stratus.h b/accelerators/stratus_hls/gemm_stratus/sw/linux/include/gemm_stratus.h index e148d6e63f..a16718be07 100644 --- a/accelerators/stratus_hls/gemm_stratus/sw/linux/include/gemm_stratus.h +++ b/accelerators/stratus_hls/gemm_stratus/sw/linux/include/gemm_stratus.h @@ -4,35 +4,35 @@ #define _GEMM_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct gemm_stratus_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned do_relu; - unsigned transpose; - unsigned ninputs; - unsigned d3; - unsigned d2; - unsigned d1; - unsigned st_offset; - unsigned ld_offset1; - unsigned ld_offset2; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned do_relu; + unsigned transpose; + unsigned ninputs; + unsigned d3; + unsigned d2; + unsigned d1; + unsigned st_offset; + unsigned ld_offset1; + unsigned ld_offset2; + unsigned src_offset; + unsigned dst_offset; }; -#define GEMM_STRATUS_IOC_ACCESS _IOW ('S', 0, struct gemm_stratus_access) +#define GEMM_STRATUS_IOC_ACCESS _IOW('S', 0, struct gemm_stratus_access) #endif /* _GEMM_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/mriq_stratus/common/helper.h b/accelerators/stratus_hls/mriq_stratus/common/helper.h index 446ee05ebe..d813e3b34f 100644 --- a/accelerators/stratus_hls/mriq_stratus/common/helper.h +++ b/accelerators/stratus_hls/mriq_stratus/common/helper.h @@ -7,152 +7,126 @@ ***************************************************************************/ #include -#include -#include -#include #include +#include #include - +#include +#include #include - #define Pix2 6.2831853071795864769252867665590058f #ifdef __cplusplus extern "C" { #endif +void inputData(const char *fName, int *_numK, int *_numX, float **kx, float **ky, float **kz, + float **x, float **y, float **z, float **phiR, float **phiI); - void inputData(const char* fName, int* _numK, int* _numX, - float** kx, float** ky, float** kz, - float** x, float** y, float** z, - float** phiR, float** phiI); - - void outputData(const char* fName, float** outR, float** outI, int* numX); - - void ComputeQ(int numK, int numX, - float *plm_kx, float *plm_ky, float *plm_kz, - float* plm_x, float* plm_y, float* plm_z, - float *plm_phiR, float *plm_phiI, - float *plm_Qr, float *plm_Qi); - void createDataStructsforCompute(int numX, float** Qr, float** Qi); +void outputData(const char *fName, float **outR, float **outI, int *numX); +void ComputeQ(int numK, int numX, float *plm_kx, float *plm_ky, float *plm_kz, float *plm_x, + float *plm_y, float *plm_z, float *plm_phiR, float *plm_phiI, float *plm_Qr, + float *plm_Qi); +void createDataStructsforCompute(int numX, float **Qr, float **Qi); #ifdef __cplusplus } #endif -void inputData(const char* fName, int * _numK, int* _numX, - float** kx, float** ky, float** kz, - float** x, float** y, float** z, - float** phiR, float** phiI) +void inputData(const char *fName, int *_numK, int *_numX, float **kx, float **ky, float **kz, + float **x, float **y, float **z, float **phiR, float **phiI) { + FILE *fid = fopen(fName, "r"); + int numK, numX; - FILE* fid = fopen(fName, "r"); - int numK, numX; - - if (fid == NULL) - { - fprintf(stderr, "Cannot open input file\n"); - exit(-1); + if (fid == NULL) { + fprintf(stderr, "Cannot open input file\n"); + exit(-1); } - fread (&numK, sizeof (int), 1, fid); - *_numK = numK; - - fread (&numX, sizeof (int), 1, fid); - *_numX = numX; - - - *kx = (float *) memalign(16, numK * sizeof (float)); - fread (*kx, sizeof (float), numK, fid); - *ky = (float *) memalign(16, numK * sizeof (float)); - fread (*ky, sizeof (float), numK, fid); - *kz = (float *) memalign(16, numK * sizeof (float)); - fread (*kz, sizeof (float), numK, fid); - *x = (float *) memalign(16, numX * sizeof (float)); - fread (*x, sizeof (float), numX, fid); - *y = (float *) memalign(16, numX * sizeof (float)); - fread (*y, sizeof (float), numX, fid); - *z = (float *) memalign(16, numX * sizeof (float)); - fread (*z, sizeof (float), numX, fid); - *phiR = (float *) memalign(16, numK * sizeof (float)); - fread (*phiR, sizeof (float), numK, fid); - *phiI = (float *) memalign(16, numK * sizeof (float)); - fread (*phiI, sizeof (float), numK, fid); - fclose (fid); - - + fread(&numK, sizeof(int), 1, fid); + *_numK = numK; + + fread(&numX, sizeof(int), 1, fid); + *_numX = numX; + + *kx = (float *)memalign(16, numK * sizeof(float)); + fread(*kx, sizeof(float), numK, fid); + *ky = (float *)memalign(16, numK * sizeof(float)); + fread(*ky, sizeof(float), numK, fid); + *kz = (float *)memalign(16, numK * sizeof(float)); + fread(*kz, sizeof(float), numK, fid); + *x = (float *)memalign(16, numX * sizeof(float)); + fread(*x, sizeof(float), numX, fid); + *y = (float *)memalign(16, numX * sizeof(float)); + fread(*y, sizeof(float), numX, fid); + *z = (float *)memalign(16, numX * sizeof(float)); + fread(*z, sizeof(float), numX, fid); + *phiR = (float *)memalign(16, numK * sizeof(float)); + fread(*phiR, sizeof(float), numK, fid); + *phiI = (float *)memalign(16, numK * sizeof(float)); + fread(*phiI, sizeof(float), numK, fid); + fclose(fid); } - - - - -void outputData(const char* fName, float** outR, float** outI, int* _numX) +void outputData(const char *fName, float **outR, float **outI, int *_numX) { - int numX; - FILE* fid = fopen(fName, "r"); + int numX; + FILE *fid = fopen(fName, "r"); - if (fid == NULL) - { - fprintf(stderr, "Cannot open output file\n"); - exit(-1); + if (fid == NULL) { + fprintf(stderr, "Cannot open output file\n"); + exit(-1); } + fread(&numX, sizeof(int), 1, fid); + *_numX = numX; - fread(&numX, sizeof(int), 1, fid); - *_numX = numX; + *outR = (float *)memalign(16, numX * sizeof(float)); + fread(*outR, sizeof(float), numX, fid); - - *outR = (float *) memalign(16, numX * sizeof (float)); - fread(*outR, sizeof(float), numX, fid); - - *outI = (float *) memalign(16, numX * sizeof (float)); - fread(*outI, sizeof(float), numX, fid); - fclose (fid); + *outI = (float *)memalign(16, numX * sizeof(float)); + fread(*outI, sizeof(float), numX, fid); + fclose(fid); } - -void ComputeQ(int numK, int numX, - float *plm_kx, float *plm_ky, float *plm_kz, - float* plm_x, float* plm_y, float* plm_z, - float *plm_phiR, float *plm_phiI, - float *plm_Qr, float *plm_Qi) { - float expArg; - float cosArg; - float sinArg; - float phiMag; - int indexK, indexX; - for (indexX = 0; indexX < numX; indexX++) { - // Sum the contributions to this point over all frequencies - float Qracc = 0.0f; - float Qiacc = 0.0f; - for (indexK = 0; indexK < numK; indexK++) { - phiMag = plm_phiR[indexK]*plm_phiR[indexK] + plm_phiI[indexK]*plm_phiI[indexK]; - - - expArg = Pix2 * (plm_kx[indexK] * plm_x[indexX] + - plm_ky[indexK] * plm_y[indexX] + - plm_kz[indexK] * plm_z[indexX]); - cosArg = cosf(expArg); - sinArg = sinf(expArg); - - Qracc += phiMag * cosArg; - Qiacc += phiMag * sinArg; +void ComputeQ(int numK, int numX, float *plm_kx, float *plm_ky, float *plm_kz, float *plm_x, + float *plm_y, float *plm_z, float *plm_phiR, float *plm_phiI, float *plm_Qr, + float *plm_Qi) +{ + float expArg; + float cosArg; + float sinArg; + float phiMag; + int indexK, indexX; + for (indexX = 0; indexX < numX; indexX++) { + // Sum the contributions to this point over all frequencies + float Qracc = 0.0f; + float Qiacc = 0.0f; + for (indexK = 0; indexK < numK; indexK++) { + phiMag = plm_phiR[indexK] * plm_phiR[indexK] + plm_phiI[indexK] * plm_phiI[indexK]; + + expArg = Pix2 * + (plm_kx[indexK] * plm_x[indexX] + plm_ky[indexK] * plm_y[indexX] + + plm_kz[indexK] * plm_z[indexX]); + cosArg = cosf(expArg); + sinArg = sinf(expArg); + + Qracc += phiMag * cosArg; + Qiacc += phiMag * sinArg; + } + plm_Qr[indexX] = Qracc; + plm_Qi[indexX] = Qiacc; } - plm_Qr[indexX] = Qracc; - plm_Qi[indexX] = Qiacc; - } } - -void createDataStructsforCompute(int numX, float** Qr, float** Qi) +void createDataStructsforCompute(int numX, float **Qr, float **Qi) { - *Qr = (float*) memalign(16, numX * sizeof (float)); - memset((void *)*Qr, 0, numX * sizeof(float)); - *Qi = (float*) memalign(16, numX * sizeof (float)); - memset((void *)*Qi, 0, numX * sizeof(float)); + *Qr = (float *)memalign(16, numX * sizeof(float)); + memset((void *)*Qr, 0, numX * sizeof(float)); + *Qi = (float *)memalign(16, numX * sizeof(float)); + memset((void *)*Qi, 0, numX * sizeof(float)); } diff --git a/accelerators/stratus_hls/mriq_stratus/hw/data/genData.c b/accelerators/stratus_hls/mriq_stratus/hw/data/genData.c index a3b2343756..b47f3b9b5b 100644 --- a/accelerators/stratus_hls/mriq_stratus/hw/data/genData.c +++ b/accelerators/stratus_hls/mriq_stratus/hw/data/genData.c @@ -5,176 +5,128 @@ * e.g. $./genData 4 16 */ - -#include #include +#include #include "../../common/helper.h" - - #define PI 3.1415926535897932384626433832795029f #define PIx2 6.2831853071795864769252867665590058f +int main(int argc, char **argv) +{ -int main (int argc, char **argv) { - - if(argc<=1) { - printf("Please specify 2 arguments in the following order:\n \ + if (argc <= 1) { + printf("Please specify 2 arguments in the following order:\n \ 1. numX\n \ 2. numK\n"); - exit(1); - } - - // read data out from original data file provided by Parboil benchmark. - - // input file provided by parboil benchmark - char *in_Parboil = "32_32_32_dataset.bin"; + exit(1); + } - printf("*** Reading data from %s ***\n", in_Parboil); + // read data out from original data file provided by Parboil benchmark. - int numX, numK; /* Number of X and K values */ - float *kx, *ky, *kz; /* K trajectory (3D vectors) */ - float *x, *y, *z; /* X coordinates (3D vectors) */ - float *phiR, *phiI; /* Phi values (complex) */ - float *Qr, *Qi; /* Q signal (complex) */ + // input file provided by parboil benchmark + char *in_Parboil = "32_32_32_dataset.bin"; + printf("*** Reading data from %s ***\n", in_Parboil); - // read out data into different variables. - inputData(in_Parboil, &numK, &numX, - &kx, &ky, &kz, - &x, &y, &z, - &phiR, &phiI); + int numX, numK; /* Number of X and K values */ + float *kx, *ky, *kz; /* K trajectory (3D vectors) */ + float *x, *y, *z; /* X coordinates (3D vectors) */ + float *phiR, *phiI; /* Phi values (complex) */ + float *Qr, *Qi; /* Q signal (complex) */ - printf("original numK = %d\n", numK); - printf("original numX = %d\n", numX); - + // read out data into different variables. + inputData(in_Parboil, &numK, &numX, &kx, &ky, &kz, &x, &y, &z, &phiR, &phiI); - // set the numX and numK you want for new files. - numX = atoi(argv[1]); - numK = atoi(argv[2]); + printf("original numK = %d\n", numK); + printf("original numX = %d\n", numX); - char inputName[100]; - char goldenName[100]; - sprintf(inputName, "test_32_x%d_k%d.bin", numX, numK); - sprintf(goldenName, "test_32_x%d_k%d.out", numX, numK); + // set the numX and numK you want for new files. + numX = atoi(argv[1]); + numK = atoi(argv[2]); - printf("*** Writing data into %s and %s ***\n", inputName, goldenName); + char inputName[100]; + char goldenName[100]; + sprintf(inputName, "test_32_x%d_k%d.bin", numX, numK); + sprintf(goldenName, "test_32_x%d_k%d.out", numX, numK); - printf("new numK = %d\n", numK); - printf("new numX = %d\n", numX); + printf("*** Writing data into %s and %s ***\n", inputName, goldenName); - // input file extracted from original parboil benchmark - // with new numX and numK + printf("new numK = %d\n", numK); + printf("new numX = %d\n", numX); + // input file extracted from original parboil benchmark + // with new numX and numK - FILE* fid = fopen(inputName, "wr"); - if (fid == NULL) - { - fprintf(stderr, "Cannot open file\n"); - exit(-1); + FILE *fid = fopen(inputName, "wr"); + if (fid == NULL) { + fprintf(stderr, "Cannot open file\n"); + exit(-1); } - // write numK, numX to the bin file - int ret; - ret = fwrite(&numK,sizeof(int),1, fid); - ret = fwrite(&numX,sizeof(int),1, fid); - - - // write kx, ky, kz to the bin file - ret = fwrite(kx,sizeof(float),numK, fid); - if(ret!=numK){ - printf("not writing correctly!\n"); - } - ret = fwrite(ky,sizeof(float),numK, fid); - if(ret!=numK){ - printf("not writing correctly!\n"); - } - ret = fwrite(kz,sizeof(float),numK, fid); - if(ret!=numK){ - printf("not writing correctly!\n"); - } - - // writing x, y, z to the bin file - ret = fwrite(x,sizeof(float),numX, fid); - if(ret!=numX){ - printf("not writing correctly!\n"); - } - ret = fwrite(y,sizeof(float),numX, fid); - if(ret!=numX){ - printf("not writing correctly!\n"); - } - ret = fwrite(z,sizeof(float),numX, fid); - if(ret!=numX){ - printf("not writing correctly!\n"); - } - // write phiR and phiI - ret = fwrite(phiR,sizeof(float),numK, fid); - if(ret!=numK){ - printf("not writing correctly!\n"); - } - ret = fwrite(phiI,sizeof(float),numK, fid); - if(ret!=numK){ - printf("not writing correctly!\n"); - } - - fclose(fid); - - - - // compute golden output - - createDataStructsforCompute(numX, &Qr, &Qi); - - ComputeQ(numK, numX, - kx, - ky, - kz, - x, - y, - z, - phiR, - phiI, - Qr,Qi); - - FILE *fout = fopen(goldenName, "wr"); - if(fout == NULL){ - printf("can't open file"); - } - // write numX to the golden output file - ret = fwrite(&numX, sizeof(float), 1, fout); - - if(ret!= 1){ - printf("not writing correctly!\n"); - } - - // write Qr to the golden output file - ret = fwrite(Qr, sizeof(float), numX, fout); - if(ret!=numX){ - printf("not writing correctly!\n"); - } - - // write Qi to the golden output file - ret = fwrite(Qi, sizeof(float), numX, fout); - if(ret!=numX){ - printf("not writing correctly!\n"); - } - - fclose(fout); - - - // free memory - free(Qr); - free(Qi); - free(x); - free(y); - free(z); - free(kx); - free(ky); - free(kz); - free(phiR); - free(phiI); - - return 0; - + // write numK, numX to the bin file + int ret; + ret = fwrite(&numK, sizeof(int), 1, fid); + ret = fwrite(&numX, sizeof(int), 1, fid); + + // write kx, ky, kz to the bin file + ret = fwrite(kx, sizeof(float), numK, fid); + if (ret != numK) { printf("not writing correctly!\n"); } + ret = fwrite(ky, sizeof(float), numK, fid); + if (ret != numK) { printf("not writing correctly!\n"); } + ret = fwrite(kz, sizeof(float), numK, fid); + if (ret != numK) { printf("not writing correctly!\n"); } + + // writing x, y, z to the bin file + ret = fwrite(x, sizeof(float), numX, fid); + if (ret != numX) { printf("not writing correctly!\n"); } + ret = fwrite(y, sizeof(float), numX, fid); + if (ret != numX) { printf("not writing correctly!\n"); } + ret = fwrite(z, sizeof(float), numX, fid); + if (ret != numX) { printf("not writing correctly!\n"); } + // write phiR and phiI + ret = fwrite(phiR, sizeof(float), numK, fid); + if (ret != numK) { printf("not writing correctly!\n"); } + ret = fwrite(phiI, sizeof(float), numK, fid); + if (ret != numK) { printf("not writing correctly!\n"); } + + fclose(fid); + + // compute golden output + + createDataStructsforCompute(numX, &Qr, &Qi); + + ComputeQ(numK, numX, kx, ky, kz, x, y, z, phiR, phiI, Qr, Qi); + + FILE *fout = fopen(goldenName, "wr"); + if (fout == NULL) { printf("can't open file"); } + // write numX to the golden output file + ret = fwrite(&numX, sizeof(float), 1, fout); + + if (ret != 1) { printf("not writing correctly!\n"); } + + // write Qr to the golden output file + ret = fwrite(Qr, sizeof(float), numX, fout); + if (ret != numX) { printf("not writing correctly!\n"); } + + // write Qi to the golden output file + ret = fwrite(Qi, sizeof(float), numX, fout); + if (ret != numX) { printf("not writing correctly!\n"); } + + fclose(fout); + + // free memory + free(Qr); + free(Qi); + free(x); + free(y); + free(z); + free(kx); + free(ky); + free(kz); + free(phiR); + free(phiI); + + return 0; } diff --git a/accelerators/stratus_hls/mriq_stratus/hw/src/mriq.cpp b/accelerators/stratus_hls/mriq_stratus/hw/src/mriq.cpp index 66dc7053df..3ed10a4bb5 100644 --- a/accelerators/stratus_hls/mriq_stratus/hw/src/mriq.cpp +++ b/accelerators/stratus_hls/mriq_stratus/hw/src/mriq.cpp @@ -29,7 +29,6 @@ void mriq::load_input() // Config /* <<--params-->> */ - int32_t num_batch_k; int32_t batch_size_k; int32_t num_batch_x; @@ -43,10 +42,9 @@ void mriq::load_input() // User-defined config code /* <<--local-params-->> */ - - num_batch_k = config.num_batch_k; + num_batch_k = config.num_batch_k; batch_size_k = config.batch_size_k; - num_batch_x = config.num_batch_x; + num_batch_x = config.num_batch_x; batch_size_x = config.batch_size_x; } @@ -55,116 +53,144 @@ void mriq::load_input() HLS_PROTO("load-dma"); wait(); - bool pingpong_x = true; + bool pingpong_x = true; int32_t dma_index = 0; - const int32_t dma_length_k = batch_size_k >> (DMA_WORD_PER_BEAT - 1); - const int32_t dma_length_x = batch_size_x >> (DMA_WORD_PER_BEAT - 1); - -#if(ARCH == 0) // loading the whole k-space data into PLM - - // for A0, dma_length_k = batch_size_k/DMA_WORD_PER_BEAT, batch_size_k = numK - - dma_read(plm_kx, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_ky, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_kz, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_phiR, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_phiI, dma_index, dma_length_k); dma_index += dma_length_k; - - // finish loading 5 k-space variables. - - for(int l=0; l < num_batch_x; l++) { - - if(pingpong_x) { - dma_read(plm_x_ping, dma_index, dma_length_x); dma_index += dma_length_x; - dma_read(plm_y_ping, dma_index, dma_length_x); dma_index += dma_length_x; - dma_read(plm_z_ping, dma_index, dma_length_x); dma_index += dma_length_x; - } else { - dma_read(plm_x_pong, dma_index, dma_length_x); dma_index += dma_length_x; - dma_read(plm_y_pong, dma_index, dma_length_x); dma_index += dma_length_x; - dma_read(plm_z_pong, dma_index, dma_length_x); dma_index += dma_length_x; - } - this->load_compute_handshake(); - pingpong_x = !pingpong_x; - } // use ping-pong buffer to load 3 x-space variables. + const int32_t dma_length_k = batch_size_k >> (DMA_WORD_PER_BEAT - 1); + const int32_t dma_length_x = batch_size_x >> (DMA_WORD_PER_BEAT - 1); + +#if (ARCH == 0) // loading the whole k-space data into PLM + + // for A0, dma_length_k = batch_size_k/DMA_WORD_PER_BEAT, batch_size_k = numK + + dma_read(plm_kx, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_ky, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_kz, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_phiR, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_phiI, dma_index, dma_length_k); + dma_index += dma_length_k; + + // finish loading 5 k-space variables. + + for (int l = 0; l < num_batch_x; l++) { + + if (pingpong_x) { + dma_read(plm_x_ping, dma_index, dma_length_x); + dma_index += dma_length_x; + dma_read(plm_y_ping, dma_index, dma_length_x); + dma_index += dma_length_x; + dma_read(plm_z_ping, dma_index, dma_length_x); + dma_index += dma_length_x; + } + else { + dma_read(plm_x_pong, dma_index, dma_length_x); + dma_index += dma_length_x; + dma_read(plm_y_pong, dma_index, dma_length_x); + dma_index += dma_length_x; + dma_read(plm_z_pong, dma_index, dma_length_x); + dma_index += dma_length_x; + } + this->load_compute_handshake(); + pingpong_x = !pingpong_x; + } // use ping-pong buffer to load 3 x-space variables. #else bool pingpong_k = true; - // each x-space data point needs num_batch_k loading - const int32_t total_loading = num_batch_k * batch_size_x * num_batch_x; + // each x-space data point needs num_batch_k loading + const int32_t total_loading = num_batch_k * batch_size_x * num_batch_x; - // address offset of the first x-space data - int32_t dma_index_x = ( 5 * batch_size_k * num_batch_k ) >> (DMA_WORD_PER_BEAT - 1); + // address offset of the first x-space data + int32_t dma_index_x = (5 * batch_size_k * num_batch_k) >> (DMA_WORD_PER_BEAT - 1); - // after every counter_x_init number of loadings, reverse pingpong_x + // after every counter_x_init number of loadings, reverse pingpong_x const int32_t counter_x_ini = num_batch_k * batch_size_x; - //counter_x indicates when to reverse pingpong_x - int counter_x = counter_x_ini; + // counter_x indicates when to reverse pingpong_x + int counter_x = counter_x_ini; - // counter_k indicates when to load k from the beginning. - int counter_k = num_batch_k; + // counter_k indicates when to load k from the beginning. + int counter_k = num_batch_k; + for (int l = 0; l < total_loading; l++) { + // in if statement, counter_x == XXX, this number is the initialized value. - - for(int l=0; l < total_loading; l++) { - // in if statement, counter_x == XXX, this number is the initialized value. + if (counter_x == counter_x_ini && pingpong_x == true) { - if(counter_x == counter_x_ini && pingpong_x == true) { - - dma_read(plm_x_ping, dma_index_x, dma_length_x); dma_index_x += dma_length_x; - dma_read(plm_y_ping, dma_index_x, dma_length_x); dma_index_x += dma_length_x; - dma_read(plm_z_ping, dma_index_x, dma_length_x); dma_index_x += dma_length_x; + dma_read(plm_x_ping, dma_index_x, dma_length_x); + dma_index_x += dma_length_x; + dma_read(plm_y_ping, dma_index_x, dma_length_x); + dma_index_x += dma_length_x; + dma_read(plm_z_ping, dma_index_x, dma_length_x); + dma_index_x += dma_length_x; pingpong_x = !pingpong_x; + } + else if (counter_x == 0 && pingpong_x == false) { - } else if (counter_x == 0 && pingpong_x == false) { - - dma_read(plm_x_pong, dma_index_x, dma_length_x); dma_index_x += dma_length_x; - dma_read(plm_y_pong, dma_index_x, dma_length_x); dma_index_x += dma_length_x; - dma_read(plm_z_pong, dma_index_x, dma_length_x); dma_index_x += dma_length_x; + dma_read(plm_x_pong, dma_index_x, dma_length_x); + dma_index_x += dma_length_x; + dma_read(plm_y_pong, dma_index_x, dma_length_x); + dma_index_x += dma_length_x; + dma_read(plm_z_pong, dma_index_x, dma_length_x); + dma_index_x += dma_length_x; counter_x = counter_x_ini << 1; // counter_x = initial value * 2; pingpong_x = !pingpong_x; - } - - if(pingpong_k) { - //HLS_PROTO("load ping"); - dma_read(plm_kx_ping, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_ky_ping, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_kz_ping, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_phiR_ping, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_phiI_ping, dma_index, dma_length_k); dma_index += dma_length_k; - - counter_x -= 1; counter_k -= 1; - - } else { - dma_read(plm_kx_pong, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_ky_pong, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_kz_pong, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_phiR_pong, dma_index, dma_length_k); dma_index += dma_length_k; - dma_read(plm_phiI_pong, dma_index, dma_length_k); dma_index += dma_length_k; - - counter_x -= 1; counter_k -= 1; - } - - if(counter_k == 0) { // loading finished for one x-space data point + } + + if (pingpong_k) { + // HLS_PROTO("load ping"); + dma_read(plm_kx_ping, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_ky_ping, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_kz_ping, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_phiR_ping, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_phiI_ping, dma_index, dma_length_k); + dma_index += dma_length_k; + + counter_x -= 1; + counter_k -= 1; + } + else { + dma_read(plm_kx_pong, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_ky_pong, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_kz_pong, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_phiR_pong, dma_index, dma_length_k); + dma_index += dma_length_k; + dma_read(plm_phiI_pong, dma_index, dma_length_k); + dma_index += dma_length_k; + + counter_x -= 1; + counter_k -= 1; + } + + if (counter_k == 0) { // loading finished for one x-space data point dma_index = 0; - counter_k = num_batch_k; - } - pingpong_k = !pingpong_k; - - this->load_compute_handshake(); - } // end of for-total_loading - + counter_k = num_batch_k; + } + pingpong_k = !pingpong_k; + + this->load_compute_handshake(); + } // end of for-total_loading + #endif - // Conclude - { - this->process_done(); - } + // Conclude + { + this->process_done(); + } } } @@ -199,9 +225,9 @@ void mriq::store_output() // User-defined config code /* <<--local-params-->> */ - num_batch_k = config.num_batch_k; + num_batch_k = config.num_batch_k; batch_size_k = config.batch_size_k; - num_batch_x = config.num_batch_x; + num_batch_x = config.num_batch_x; batch_size_x = config.batch_size_x; } @@ -210,25 +236,31 @@ void mriq::store_output() HLS_PROTO("store-dma"); wait(); - const uint32_t store_offset = round_up(3 * batch_size_x * num_batch_x + 5 * batch_size_k * num_batch_k, DMA_WORD_PER_BEAT); - const uint32_t dma_length_x = batch_size_x >> (DMA_WORD_PER_BEAT - 1); - - uint32_t dma_index = store_offset >> (DMA_WORD_PER_BEAT - 1); - bool pingpong_x = true; - wait(); - - for(int i = 0; i < num_batch_x; i++) { - - this->store_compute_handshake(); - if(pingpong_x) { - dma_write(plm_Qr_ping, dma_index, dma_length_x); dma_index += dma_length_x; - dma_write(plm_Qi_ping, dma_index, dma_length_x); dma_index += dma_length_x; - } else { - dma_write(plm_Qr_pong, dma_index, dma_length_x); dma_index += dma_length_x; - dma_write(plm_Qi_pong, dma_index, dma_length_x); dma_index += dma_length_x; - } - pingpong_x = !pingpong_x; - } + const uint32_t store_offset = round_up( + 3 * batch_size_x * num_batch_x + 5 * batch_size_k * num_batch_k, DMA_WORD_PER_BEAT); + const uint32_t dma_length_x = batch_size_x >> (DMA_WORD_PER_BEAT - 1); + + uint32_t dma_index = store_offset >> (DMA_WORD_PER_BEAT - 1); + bool pingpong_x = true; + wait(); + + for (int i = 0; i < num_batch_x; i++) { + + this->store_compute_handshake(); + if (pingpong_x) { + dma_write(plm_Qr_ping, dma_index, dma_length_x); + dma_index += dma_length_x; + dma_write(plm_Qi_ping, dma_index, dma_length_x); + dma_index += dma_length_x; + } + else { + dma_write(plm_Qr_pong, dma_index, dma_length_x); + dma_index += dma_length_x; + dma_write(plm_Qi_pong, dma_index, dma_length_x); + dma_index += dma_length_x; + } + pingpong_x = !pingpong_x; + } } // store process // Conclude @@ -239,7 +271,6 @@ void mriq::store_output() } } - void mriq::compute_kernel() { // Reset @@ -271,38 +302,36 @@ void mriq::compute_kernel() // User-defined config code /* <<--local-params-->> */ - num_batch_k = config.num_batch_k; + num_batch_k = config.num_batch_k; batch_size_k = config.batch_size_k; - num_batch_x = config.num_batch_x; + num_batch_x = config.num_batch_x; batch_size_x = config.batch_size_x; } - // Compute FPDATA_S sin_table[20]; HLS_FLATTEN_ARRAY(sin_table); - sin_table[0] = 0.000000000000; - sin_table[1] = 0.078459098935; - sin_table[2] = 0.156434476376; - sin_table[3] = 0.233445376158; - sin_table[4] = 0.309017002583; - sin_table[5] = 0.382683455944; - sin_table[6] = 0.453990519047; - sin_table[7] = 0.522498548031; - sin_table[8] = 0.587785243988; - sin_table[9] = 0.649448037148; - sin_table[10]= 0.707106769085; - sin_table[11]= 0.760405957699; - sin_table[12]= 0.809017002583; - sin_table[13]= 0.852640211582; - sin_table[14]= 0.891006529331; - sin_table[15]= 0.923879504204; - sin_table[16]= 0.951056540012; - sin_table[17]= 0.972369909286; - sin_table[18]= 0.987688362598; - sin_table[19]= 0.996917307377; - + sin_table[0] = 0.000000000000; + sin_table[1] = 0.078459098935; + sin_table[2] = 0.156434476376; + sin_table[3] = 0.233445376158; + sin_table[4] = 0.309017002583; + sin_table[5] = 0.382683455944; + sin_table[6] = 0.453990519047; + sin_table[7] = 0.522498548031; + sin_table[8] = 0.587785243988; + sin_table[9] = 0.649448037148; + sin_table[10] = 0.707106769085; + sin_table[11] = 0.760405957699; + sin_table[12] = 0.809017002583; + sin_table[13] = 0.852640211582; + sin_table[14] = 0.891006529331; + sin_table[15] = 0.923879504204; + sin_table[16] = 0.951056540012; + sin_table[17] = 0.972369909286; + sin_table[18] = 0.987688362598; + sin_table[19] = 0.996917307377; FPDATA_L Qr; FPDATA_L Qi; @@ -312,97 +341,100 @@ void mriq::compute_kernel() bool pingpong_x = true; bool pingpong_k = true; - +#if (ARCH == 0) -#if(ARCH==0) + // ESP_REPORT_INFO("compute_kernel: come into if-SK part"); - //ESP_REPORT_INFO("compute_kernel: come into if-SK part"); + for (int i = 0; i < num_batch_x; i++) { - for(int i = 0; i < num_batch_x; i++) { + this->compute_load_handshake(); - this->compute_load_handshake(); + for (int r = 0; r < batch_size_x; r++) { - for(int r = 0; r < batch_size_x; r++) { + if (pingpong_x) { + x = int2fp(plm_x_ping[r]); + y = int2fp(plm_y_ping[r]); + z = int2fp(plm_z_ping[r]); + } + else { + x = int2fp(plm_x_pong[r]); + y = int2fp(plm_y_pong[r]); + z = int2fp(plm_z_pong[r]); + } - if(pingpong_x) { - x = int2fp(plm_x_ping[r]); - y = int2fp(plm_y_ping[r]); - z = int2fp(plm_z_ping[r]); - } else { - x = int2fp(plm_x_pong[r]); - y = int2fp(plm_y_pong[r]); - z = int2fp(plm_z_pong[r]); - } + Qr = 0; + Qi = 0; - Qr=0; Qi=0; + ComputeQ(x, y, z, batch_size_k, pingpong_k, sin_table, &Qr, &Qi); - ComputeQ(x, y, z, batch_size_k, pingpong_k, sin_table, &Qr, &Qi); - - if(pingpong_x) { - plm_Qr_ping[r] = fp2int(Qr); - plm_Qi_ping[r] = fp2int(Qi); - } else { - plm_Qr_pong[r] = fp2int(Qr); - plm_Qi_pong[r] = fp2int(Qi); - } - } // end of batch_size_x + if (pingpong_x) { + plm_Qr_ping[r] = fp2int(Qr); + plm_Qi_ping[r] = fp2int(Qi); + } + else { + plm_Qr_pong[r] = fp2int(Qr); + plm_Qi_pong[r] = fp2int(Qi); + } + } // end of batch_size_x - pingpong_x = !pingpong_x; - this->compute_store_handshake(); + pingpong_x = !pingpong_x; + this->compute_store_handshake(); } // end of num_batch_x for-loop #else - //ESP_REPORT_INFO("compute_kernel: come into else part"); + // ESP_REPORT_INFO("compute_kernel: come into else part"); FPDATA_L Qr_p; FPDATA_L Qi_p; - for (int i=0; i < num_batch_x; i++) { - - for(int r=0; r < batch_size_x; r++) { - - Qr = 0; Qi = 0; - - for(int j=0; j< num_batch_k; j++) { - - this->compute_load_handshake(); - - if(pingpong_x) { - x = int2fp(plm_x_ping[r]); - y = int2fp(plm_y_ping[r]); - z = int2fp(plm_z_ping[r]); - } else { - x = int2fp(plm_x_pong[r]); - y = int2fp(plm_y_pong[r]); - z = int2fp(plm_z_pong[r]); - } - // ComputeQ only compute one pair of output - ComputeQ(x, y, z, batch_size_k, pingpong_k, sin_table, &Qr_p, &Qi_p); - - Qr += Qr_p; - Qi += Qi_p; - pingpong_k = !pingpong_k; - } - if(pingpong_x) { - plm_Qr_ping[r] = fp2int(Qr); - plm_Qi_ping[r] = fp2int(Qi); - } else { - plm_Qr_pong[r] = fp2int(Qr); - plm_Qi_pong[r] = fp2int(Qi); - } - } // end of num_batch_k - - //counter_pingpong -= 1; - - pingpong_x = !pingpong_x; - this->compute_store_handshake(); - //ESP_REPORT_INFO("compute finished!"); + for (int i = 0; i < num_batch_x; i++) { + + for (int r = 0; r < batch_size_x; r++) { + + Qr = 0; + Qi = 0; + + for (int j = 0; j < num_batch_k; j++) { + + this->compute_load_handshake(); + + if (pingpong_x) { + x = int2fp(plm_x_ping[r]); + y = int2fp(plm_y_ping[r]); + z = int2fp(plm_z_ping[r]); + } + else { + x = int2fp(plm_x_pong[r]); + y = int2fp(plm_y_pong[r]); + z = int2fp(plm_z_pong[r]); + } + // ComputeQ only compute one pair of output + ComputeQ(x, y, z, batch_size_k, pingpong_k, sin_table, &Qr_p, &Qi_p); + + Qr += Qr_p; + Qi += Qi_p; + pingpong_k = !pingpong_k; + } + if (pingpong_x) { + plm_Qr_ping[r] = fp2int(Qr); + plm_Qi_ping[r] = fp2int(Qi); + } + else { + plm_Qr_pong[r] = fp2int(Qr); + plm_Qi_pong[r] = fp2int(Qi); + } + } // end of num_batch_k + + // counter_pingpong -= 1; + + pingpong_x = !pingpong_x; + this->compute_store_handshake(); + // ESP_REPORT_INFO("compute finished!"); } // end of num_batch_x for-loop #endif - // Conclude - { - this->process_done(); - } + // Conclude + { + this->process_done(); + } } - diff --git a/accelerators/stratus_hls/mriq_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/mriq_stratus/hw/tb/sc_main.cpp index c465ccc433..cffde7e61b 100644 --- a/accelerators/stratus_hls/mriq_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/mriq_stratus/hw/tb/sc_main.cpp @@ -5,44 +5,44 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; extern void esc_elaborate() { - // Creating the whole system - testbench = new system_t("testbench"); + // Creating the whole system + testbench = new system_t("testbench"); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); - esc_cleanup(); + esc_log_pass(); + esc_cleanup(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/mriq_stratus/sw/baremetal/mriq.c b/accelerators/stratus_hls/mriq_stratus/sw/baremetal/mriq.c index c317bae51b..02e131a614 100644 --- a/accelerators/stratus_hls/mriq_stratus/sw/baremetal/mriq.c +++ b/accelerators/stratus_hls/mriq_stratus/sw/baremetal/mriq.c @@ -3,7 +3,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -12,27 +12,22 @@ #include "../../common/utils.h" -//typedef int32_t token_t; defined in utils.h file5 - -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} +// typedef int32_t token_t; defined in utils.h file5 +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } #define fx2float fixed32_to_float #define float2fx float_to_fixed32 -#define FX_IL 12 - +#define FX_IL 12 #define SLD_MRIQ 0x079 #define DEV_NAME "sld,mriq_stratus" /* <<--params-->> */ -const int32_t num_batch_k = 1; +const int32_t num_batch_k = 1; const int32_t batch_size_k = 16; -const int32_t num_batch_x = 1; +const int32_t num_batch_x = 1; const int32_t batch_size_x = 4; static unsigned in_words_adj; @@ -44,23 +39,19 @@ static unsigned out_len; static unsigned out_offset; static unsigned mem_size; - /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ -#define MRIQ_NUM_BATCH_K_REG 0x4c +#define MRIQ_NUM_BATCH_K_REG 0x4c #define MRIQ_BATCH_SIZE_K_REG 0x48 -#define MRIQ_NUM_BATCH_X_REG 0x44 +#define MRIQ_NUM_BATCH_X_REG 0x44 #define MRIQ_BATCH_SIZE_X_REG 0x40 - static int validate_buf(token_t *out, float *gold) { float *out_fp; @@ -68,7 +59,7 @@ static int validate_buf(token_t *out, float *gold) out_fp = aligned_malloc(out_len * sizeof(float)); for (int i = 0; i < out_len; i++) { - out_fp[i] = fx2float(out[i], FX_IL); + out_fp[i] = fx2float(out[i], FX_IL); } ret = validate_buffer(out_fp, gold, out_len); @@ -77,147 +68,137 @@ static int validate_buf(token_t *out, float *gold) return ret; } - - -static void init_buf (token_t *in, float * gold) +static void init_buf(token_t *in, float *gold) { #include "../../hw/data/test_32_x4_k16_bm.h" } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable; - token_t *mem; - float *gold; - unsigned errors = 0; - unsigned coherence; - - // init corresponding parameters - init_parameters(batch_size_x, num_batch_x, - batch_size_k, num_batch_k, - &in_words_adj, &out_words_adj, - &in_len, &out_len, - &in_size, &out_size, - &out_offset, - &mem_size, - DMA_WORD_PER_BEAT(sizeof(token_t))); - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_MRIQ, DEV_NAME); - if (ndev == 0) { - printf("mriq not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - printf("**************** %s.%d ****************\n", DEV_NAME, n); - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_len * sizeof(float)); - - mem = aligned_malloc(mem_size); - - printf(" memory buffer base-address = %p\n", mem); - - // Alocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable; + token_t *mem; + float *gold; + unsigned errors = 0; + unsigned coherence; + + // init corresponding parameters + init_parameters(batch_size_x, num_batch_x, batch_size_k, num_batch_k, &in_words_adj, + &out_words_adj, &in_len, &out_len, &in_size, &out_size, &out_offset, &mem_size, + DMA_WORD_PER_BEAT(sizeof(token_t))); + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_MRIQ, DEV_NAME); + if (ndev == 0) { + printf("mriq not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + printf("**************** %s.%d ****************\n", DEV_NAME, n); + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_len * sizeof(float)); + + mem = aligned_malloc(mem_size); + + printf(" memory buffer base-address = %p\n", mem); + + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); #ifndef __riscv // for leon3, skip ACC_COH_FULL - for (coherence = ACC_COH_NONE; coherence < ACC_COH_FULL; coherence++) { + for (coherence = ACC_COH_NONE; coherence < ACC_COH_FULL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - printf(" --------------------\n"); - printf(" Generate input...\n"); + printf(" --------------------\n"); + printf(" Generate input...\n"); - init_buf(mem, gold); + init_buf(mem, gold); - // Pass common configuration parameters + // Pass common configuration parameters - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); #ifndef __sparc - iowrite32(dev, PT_ADDRESS_REG, (unsigned long long) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned long long)ptable); #else - iowrite32(dev, PT_ADDRESS_REG, (unsigned) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned)ptable); #endif - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - - iowrite32(dev, MRIQ_NUM_BATCH_K_REG, num_batch_k); - iowrite32(dev, MRIQ_BATCH_SIZE_K_REG, batch_size_k); - iowrite32(dev, MRIQ_NUM_BATCH_X_REG, num_batch_x); - iowrite32(dev, MRIQ_BATCH_SIZE_X_REG, batch_size_x); - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + + iowrite32(dev, MRIQ_NUM_BATCH_K_REG, num_batch_k); + iowrite32(dev, MRIQ_BATCH_SIZE_K_REG, batch_size_k); + iowrite32(dev, MRIQ_NUM_BATCH_X_REG, num_batch_x); + iowrite32(dev, MRIQ_BATCH_SIZE_X_REG, batch_size_x); + + // Flush (customize coherence model here) + esp_flush(coherence); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/accelerators/stratus_hls/mriq_stratus/sw/linux/app/mriq.c b/accelerators/stratus_hls/mriq_stratus/sw/linux/app/mriq.c index 79c1177dd5..72f918a298 100644 --- a/accelerators/stratus_hls/mriq_stratus/sw/linux/app/mriq.c +++ b/accelerators/stratus_hls/mriq_stratus/sw/linux/app/mriq.c @@ -1,19 +1,17 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include "libesp.h" -#include "cfg.h" -#include "../../../common/utils.h" // init_parameters() and validate_buffer() -#include "../../../common/sw_exec.h" // sw_exec() #include "../../../common/init_buff.h" // init_buffer() +#include "../../../common/sw_exec.h" // sw_exec() +#include "../../../common/utils.h" // init_parameters() and validate_buffer() +#include "cfg.h" +#include "libesp.h" #include #include // for fabs function - #define fx2float fixed32_to_float #define float2fx float_to_fixed32 -#define FX_IL 12 - +#define FX_IL 12 static unsigned in_words_adj; static unsigned out_words_adj; @@ -24,28 +22,25 @@ static unsigned out_size; static unsigned out_offset; static unsigned mem_size; - /* User-defined code */ -void file2be(const char* in_file_name, const char* out_file_name) +void file2be(const char *in_file_name, const char *out_file_name) { - FILE* in_file = fopen(in_file_name, "r"); - FILE* out_file = fopen(out_file_name, "w"); + FILE *in_file = fopen(in_file_name, "r"); + FILE *out_file = fopen(out_file_name, "w"); - uint8_t rd_data[4]; - int i; + uint8_t rd_data[4]; + int i; - while(fread(rd_data, sizeof(uint8_t), 4, in_file) == 4){ - for (i = 3; i>= 0; i--) - fwrite(&rd_data[i], sizeof(uint8_t), 1, out_file); - } + while (fread(rd_data, sizeof(uint8_t), 4, in_file) == 4) { + for (i = 3; i >= 0; i--) + fwrite(&rd_data[i], sizeof(uint8_t), 1, out_file); + } - fclose(in_file); - fclose(out_file); + fclose(in_file); + fclose(out_file); } - - static int validate_buf(token_t *out, float *gold) { float *out_fp; @@ -54,7 +49,7 @@ static int validate_buf(token_t *out, float *gold) out_fp = malloc(out_len * sizeof(float)); for (int i = 0; i < out_len; i++) { - out_fp[i] = fx2float(out[i], FX_IL); + out_fp[i] = fx2float(out[i], FX_IL); } ret = validate_buffer(out_fp, gold, out_len); @@ -63,137 +58,109 @@ static int validate_buf(token_t *out, float *gold) return ret; } - - - /* User-defined code */ -static void init_buf(token_t *in, float *in_fp, float *gold, - const char* inputFile, - const char* goldFile) +static void init_buf(token_t *in, float *in_fp, float *gold, const char *inputFile, + const char *goldFile) { - #ifdef __sparc - const char* be_inputFile = "be_inputFile.bin"; - const char* be_goldFile = "be_goldFile.bin"; + const char *be_inputFile = "be_inputFile.bin"; + const char *be_goldFile = "be_goldFile.bin"; - file2be(inputFile, be_inputFile); - file2be(goldFile, be_goldFile); + file2be(inputFile, be_inputFile); + file2be(goldFile, be_goldFile); - init_buffer(in_fp, gold, be_inputFile, be_goldFile, - batch_size_x, num_batch_x, - batch_size_k, num_batch_k); + init_buffer(in_fp, gold, be_inputFile, be_goldFile, batch_size_x, num_batch_x, batch_size_k, + num_batch_k); #else - - init_buffer(in_fp, gold, inputFile, goldFile, - batch_size_x, num_batch_x, - batch_size_k, num_batch_k); + init_buffer(in_fp, gold, inputFile, goldFile, batch_size_x, num_batch_x, batch_size_k, + num_batch_k); #endif - for(int i=0; i < in_len; i++) { - in[i] = float2fx(in_fp[i], FX_IL); - } - + for (int i = 0; i < in_len; i++) { + in[i] = float2fx(in_fp[i], FX_IL); + } } - - - int main(int argc, char **argv) { - if (argc < 3) { - printf("please pass 3 arguments: inputName, goldName, run_sw\n"); - exit(1); - } - - int errors; - float *gold; - token_t *buf; - float *in_fp; - - const char* inputFile = argv[1]; - const char* goldFile = argv[2]; - int run_sw = atoi(argv[3]); - - // printf("\n before init parameters \n"); - - init_parameters(batch_size_x, num_batch_x, - batch_size_k, num_batch_k, - &in_words_adj, &out_words_adj, - &in_len, &out_len, - &in_size, &out_size, - &out_offset, - &mem_size, - DMA_WORD_PER_BEAT(sizeof(token_t))); + if (argc < 3) { + printf("please pass 3 arguments: inputName, goldName, run_sw\n"); + exit(1); + } - buf = (token_t *) esp_alloc(mem_size); + int errors; + float *gold; + token_t *buf; + float *in_fp; - cfg_000[0].hw_buf = buf; - - gold = malloc(out_len * sizeof(float)); + const char *inputFile = argv[1]; + const char *goldFile = argv[2]; + int run_sw = atoi(argv[3]); - in_fp = malloc(in_len * sizeof(float)); - - printf("\n====== %s ======\n\n", cfg_000[0].devname); - /* <<--print-params-->> */ - printf(" .num_batch_k = %d\n", num_batch_k); - printf(" .batch_size_k = %d\n", batch_size_k); - printf(" .num_batch_x = %d\n", num_batch_x); - printf(" .batch_size_x = %d\n", batch_size_x); + // printf("\n before init parameters \n"); - init_buf(buf, in_fp, gold, inputFile, goldFile); + init_parameters(batch_size_x, num_batch_x, batch_size_k, num_batch_k, &in_words_adj, + &out_words_adj, &in_len, &out_len, &in_size, &out_size, &out_offset, &mem_size, + DMA_WORD_PER_BEAT(sizeof(token_t))); - printf("\n ** START HW TESTING **\n"); + buf = (token_t *)esp_alloc(mem_size); - esp_run(cfg_000, NACC); + cfg_000[0].hw_buf = buf; - printf("\n ** DONE **\n"); + gold = malloc(out_len * sizeof(float)); - errors = validate_buf(&buf[out_offset], gold); + in_fp = malloc(in_len * sizeof(float)); - if (!errors) - printf("+ HW Test PASSED\n"); - else - printf("+ HW Test FAILED\n"); + printf("\n====== %s ======\n\n", cfg_000[0].devname); + /* <<--print-params-->> */ + printf(" .num_batch_k = %d\n", num_batch_k); + printf(" .batch_size_k = %d\n", batch_size_k); + printf(" .num_batch_x = %d\n", num_batch_x); + printf(" .batch_size_x = %d\n", batch_size_x); + init_buf(buf, in_fp, gold, inputFile, goldFile); - if(run_sw) { - - float *out_sw = malloc(out_len * sizeof(float)); + printf("\n ** START HW TESTING **\n"); - sw_exec(out_sw, in_fp, - batch_size_x, num_batch_x, - batch_size_k, num_batch_k); + esp_run(cfg_000, NACC); - int ret; + printf("\n ** DONE **\n"); - ret = validate_buffer(out_sw, gold, out_len); + errors = validate_buf(&buf[out_offset], gold); - if (ret) - printf("+ SW Test FAILED!\n"); - else - printf("+ SW Test PASSED!\n"); + if (!errors) printf("+ HW Test PASSED\n"); + else + printf("+ HW Test FAILED\n"); - free(out_sw); + if (run_sw) { - } + float *out_sw = malloc(out_len * sizeof(float)); + sw_exec(out_sw, in_fp, batch_size_x, num_batch_x, batch_size_k, num_batch_k); + int ret; - free(gold); + ret = validate_buffer(out_sw, gold, out_len); - free(in_fp); + if (ret) printf("+ SW Test FAILED!\n"); + else + printf("+ SW Test PASSED!\n"); - esp_free(buf); + free(out_sw); + } + free(gold); - printf("\n====== %s ======\n\n", cfg_000[0].devname); + free(in_fp); + esp_free(buf); - return errors; + printf("\n====== %s ======\n\n", cfg_000[0].devname); + return errors; } diff --git a/accelerators/stratus_hls/mriq_stratus/sw/linux/driver/mriq_stratus.c b/accelerators/stratus_hls/mriq_stratus/sw/linux/driver/mriq_stratus.c index 18b8a239f1..234b0578c6 100644 --- a/accelerators/stratus_hls/mriq_stratus/sw/linux/driver/mriq_stratus.c +++ b/accelerators/stratus_hls/mriq_stratus/sw/linux/driver/mriq_stratus.c @@ -1,137 +1,129 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "mriq_stratus.h" -#define DRV_NAME "mriq_stratus" +#define DRV_NAME "mriq_stratus" /* <<--regs-->> */ -#define MRIQ_NUM_BATCH_K_REG 0x4c +#define MRIQ_NUM_BATCH_K_REG 0x4c #define MRIQ_BATCH_SIZE_K_REG 0x48 -#define MRIQ_NUM_BATCH_X_REG 0x44 +#define MRIQ_NUM_BATCH_X_REG 0x44 #define MRIQ_BATCH_SIZE_X_REG 0x40 struct mriq_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver mriq_driver; static struct of_device_id mriq_device_ids[] = { - { - .name = "SLD_MRIQ_STRATUS", - }, - { - .name = "eb_079", - }, - { - .compatible = "sld,mriq_stratus", - }, - { }, + { + .name = "SLD_MRIQ_STRATUS", + }, + { + .name = "eb_079", + }, + { + .compatible = "sld,mriq_stratus", + }, + {}, }; static int mriq_devs; static inline struct mriq_stratus_device *to_mriq(struct esp_device *esp) { - return container_of(esp, struct mriq_stratus_device, esp); + return container_of(esp, struct mriq_stratus_device, esp); } static void mriq_prep_xfer(struct esp_device *esp, void *arg) { - struct mriq_stratus_access *a = arg; - - /* <<--regs-config-->> */ + struct mriq_stratus_access *a = arg; - iowrite32be(a->num_batch_k, esp->iomem + MRIQ_NUM_BATCH_K_REG); - iowrite32be(a->batch_size_k, esp->iomem + MRIQ_BATCH_SIZE_K_REG); - iowrite32be(a->num_batch_x, esp->iomem + MRIQ_NUM_BATCH_X_REG); - iowrite32be(a->batch_size_x, esp->iomem + MRIQ_BATCH_SIZE_X_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); + /* <<--regs-config-->> */ + iowrite32be(a->num_batch_k, esp->iomem + MRIQ_NUM_BATCH_K_REG); + iowrite32be(a->batch_size_k, esp->iomem + MRIQ_BATCH_SIZE_K_REG); + iowrite32be(a->num_batch_x, esp->iomem + MRIQ_NUM_BATCH_X_REG); + iowrite32be(a->batch_size_x, esp->iomem + MRIQ_BATCH_SIZE_X_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool mriq_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct mriq_stratus_device *mriq = to_mriq(esp); */ - /* struct mriq_stratus_access *a = arg; */ + /* struct mriq_stratus_device *mriq = to_mriq(esp); */ + /* struct mriq_stratus_access *a = arg; */ - return true; + return true; } static int mriq_probe(struct platform_device *pdev) { - struct mriq_stratus_device *mriq; - struct esp_device *esp; - int rc; - - mriq = kzalloc(sizeof(*mriq), GFP_KERNEL); - if (mriq == NULL) - return -ENOMEM; - esp = &mriq->esp; - esp->module = THIS_MODULE; - esp->number = mriq_devs; - esp->driver = &mriq_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - mriq_devs++; - return 0; - err: - kfree(mriq); - return rc; + struct mriq_stratus_device *mriq; + struct esp_device *esp; + int rc; + + mriq = kzalloc(sizeof(*mriq), GFP_KERNEL); + if (mriq == NULL) return -ENOMEM; + esp = &mriq->esp; + esp->module = THIS_MODULE; + esp->number = mriq_devs; + esp->driver = &mriq_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + mriq_devs++; + return 0; +err: + kfree(mriq); + return rc; } static int __exit mriq_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct mriq_stratus_device *mriq = to_mriq(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct mriq_stratus_device *mriq = to_mriq(esp); - esp_device_unregister(esp); - kfree(mriq); - return 0; + esp_device_unregister(esp); + kfree(mriq); + return 0; } static struct esp_driver mriq_driver = { - .plat = { - .probe = mriq_probe, - .remove = mriq_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = mriq_device_ids, - }, - }, - .xfer_input_ok = mriq_xfer_input_ok, - .prep_xfer = mriq_prep_xfer, - .ioctl_cm = MRIQ_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct mriq_stratus_access), + .plat = + { + .probe = mriq_probe, + .remove = mriq_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = mriq_device_ids, + }, + }, + .xfer_input_ok = mriq_xfer_input_ok, + .prep_xfer = mriq_prep_xfer, + .ioctl_cm = MRIQ_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct mriq_stratus_access), }; -static int __init mriq_init(void) -{ - return esp_driver_register(&mriq_driver); -} +static int __init mriq_init(void) { return esp_driver_register(&mriq_driver); } -static void __exit mriq_exit(void) -{ - esp_driver_unregister(&mriq_driver); -} +static void __exit mriq_exit(void) { esp_driver_unregister(&mriq_driver); } -module_init(mriq_init) -module_exit(mriq_exit) +module_init(mriq_init) module_exit(mriq_exit) -MODULE_DEVICE_TABLE(of, mriq_device_ids); + MODULE_DEVICE_TABLE(of, mriq_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/mriq_stratus/sw/linux/include/mriq_stratus.h b/accelerators/stratus_hls/mriq_stratus/sw/linux/include/mriq_stratus.h index 92714f2603..0fb2466f22 100644 --- a/accelerators/stratus_hls/mriq_stratus/sw/linux/include/mriq_stratus.h +++ b/accelerators/stratus_hls/mriq_stratus/sw/linux/include/mriq_stratus.h @@ -4,30 +4,30 @@ #define _MRIQ_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct mriq_stratus_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned num_batch_k; - unsigned batch_size_k; - unsigned num_batch_x; - unsigned batch_size_x; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned num_batch_k; + unsigned batch_size_k; + unsigned num_batch_x; + unsigned batch_size_x; + unsigned src_offset; + unsigned dst_offset; }; -#define MRIQ_STRATUS_IOC_ACCESS _IOW ('S', 0, struct mriq_stratus_access) +#define MRIQ_STRATUS_IOC_ACCESS _IOW('S', 0, struct mriq_stratus_access) #endif /* _MRIQ_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/nightvision_stratus/hw/sim/show.py b/accelerators/stratus_hls/nightvision_stratus/hw/sim/show.py index 7225c6eead..25d5467370 100644 --- a/accelerators/stratus_hls/nightvision_stratus/hw/sim/show.py +++ b/accelerators/stratus_hls/nightvision_stratus/hw/sim/show.py @@ -6,11 +6,12 @@ from matplotlib import pyplot as plt -def load_yuv_img_from_txt_YUV_ONLY(filename, n_rows = 32, n_cols = 32): +def load_yuv_img_from_txt_YUV_ONLY(filename, n_rows=32, n_cols=32): with open(filename) as f: content = [int(line.rstrip('\n')) for line in open(filename)] return np.asarray(content).reshape((n_rows, n_cols)) + def main(): # Set the parameters below corresponding to the txt image to be visualized @@ -21,13 +22,16 @@ def main(): plt.imshow(y_img, cmap=plt.cm.binary, vmin=0, vmax=256) plt.show() - y_img = load_yuv_img_from_txt_YUV_ONLY('./svhn_0_gold_32x32.txt', size, size) + y_img = load_yuv_img_from_txt_YUV_ONLY( + './svhn_0_gold_32x32.txt', size, size) plt.imshow(y_img, cmap=plt.cm.binary, vmin=0, vmax=256) plt.show() - y_img = load_yuv_img_from_txt_YUV_ONLY('./svhn_0_out_32x32.txt', size, size) + y_img = load_yuv_img_from_txt_YUV_ONLY( + './svhn_0_out_32x32.txt', size, size) plt.imshow(y_img, cmap=plt.cm.binary, vmin=0, vmax=256) plt.show() + if __name__ == '__main__': main() diff --git a/accelerators/stratus_hls/nightvision_stratus/hw/src/nightvision.cpp b/accelerators/stratus_hls/nightvision_stratus/hw/src/nightvision.cpp index 8dff010222..686353e206 100644 --- a/accelerators/stratus_hls/nightvision_stratus/hw/src/nightvision.cpp +++ b/accelerators/stratus_hls/nightvision_stratus/hw/src/nightvision.cpp @@ -69,7 +69,8 @@ void nightvision::load_input() HLS_UNROLL_SIMPLE; // Write to PLM mem_buff_1[i + k] = - data.range(((k + 1) << MAX_PXL_WIDTH_LOG) - 1, k << MAX_PXL_WIDTH_LOG).to_uint(); + data.range(((k + 1) << MAX_PXL_WIDTH_LOG) - 1, k << MAX_PXL_WIDTH_LOG) + .to_uint(); mem_buff_2[i + k] = 0; } } @@ -169,7 +170,7 @@ void nightvision::compute_kernel() uint32_t n_Cols; uint32_t plm_size; uint32_t index_last_row; - bool do_dwt; + bool do_dwt; // Reset { @@ -209,8 +210,7 @@ void nightvision::compute_kernel() kernel_nf(n_Rows, n_Cols); kernel_hist(n_Rows, n_Cols); kernel_histEq(n_Rows, n_Cols); - if (do_dwt) - kernel_dwt(n_Rows, n_Cols); + if (do_dwt) kernel_dwt(n_Rows, n_Cols); this->compute_store_handshake(); } diff --git a/accelerators/stratus_hls/nightvision_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/nightvision_stratus/hw/tb/sc_main.cpp index 04351bff93..bf1e7fd682 100644 --- a/accelerators/stratus_hls/nightvision_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/nightvision_stratus/hw/tb/sc_main.cpp @@ -48,17 +48,17 @@ system_t *testbench = NULL; std::string image_A_path = "../../data/lena-480x640.txt"; std::string image_out_path = "../../data/out-480x640.txt"; std::string image_gold_path = "../../data/gold-480x640.txt"; -uint32_t n_Images = 1; -uint32_t n_Rows = 480; -uint32_t n_Cols = 640; -bool do_validation = true; -bool do_dwt = true; +uint32_t n_Images = 1; +uint32_t n_Rows = 480; +uint32_t n_Cols = 640; +bool do_validation = true; +bool do_dwt = true; extern void esc_elaborate() { // Creating the whole system - testbench = new system_t("testbench", image_A_path, image_out_path, n_Images, n_Rows, n_Cols, image_gold_path, - do_validation, do_dwt); + testbench = new system_t("testbench", image_A_path, image_out_path, n_Images, n_Rows, n_Cols, + image_gold_path, do_validation, do_dwt); } extern void esc_cleanup() @@ -90,13 +90,14 @@ int sc_main(int argc, char *argv[]) if (argc == 7) { do_validation = true; image_gold_path = argv[6]; - } else { + } + else { do_validation = false; } do_dwt = false; - - } else { + } + else { fprintf(stderr, "Wrong arguments.\n"); fprintf(stderr, "Expected arguments: image_A_path (string), image_out_path (string),\n"); fprintf(stderr, "n_Images, n_Rows, n_Cols, [optional: image_gold_path (string)].\n"); @@ -106,7 +107,7 @@ int sc_main(int argc, char *argv[]) esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); sc_signal rst("rst"); testbench->clk(clk); diff --git a/accelerators/stratus_hls/nightvision_stratus/sw/baremetal/create_data_header_file.py b/accelerators/stratus_hls/nightvision_stratus/sw/baremetal/create_data_header_file.py index 9bf8aab6dd..8a7a572b76 100644 --- a/accelerators/stratus_hls/nightvision_stratus/sw/baremetal/create_data_header_file.py +++ b/accelerators/stratus_hls/nightvision_stratus/sw/baremetal/create_data_header_file.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # coding=utf-8 -#with open('../../data/lena-480x640.txt', 'r') as fileA: +# with open('../../data/lena-480x640.txt', 'r') as fileA: with open('../../data/lena-120x160.txt', 'r') as fileA: lines = fileA.readlines() @@ -17,7 +17,7 @@ print("") -#with open('gold-480x640.txt', 'r') as fileG: +# with open('gold-480x640.txt', 'r') as fileG: with open('gold-120x160.txt', 'r') as fileG: lines = fileG.readlines() @@ -30,4 +30,3 @@ print(" = %s" % (l.rstrip('\n')), end='') print(";") i += 1 - diff --git a/accelerators/stratus_hls/nightvision_stratus/sw/baremetal/nightvision.c b/accelerators/stratus_hls/nightvision_stratus/sw/baremetal/nightvision.c index a8c7cff862..3385f93339 100644 --- a/accelerators/stratus_hls/nightvision_stratus/sw/baremetal/nightvision.c +++ b/accelerators/stratus_hls/nightvision_stratus/sw/baremetal/nightvision.c @@ -46,9 +46,9 @@ typedef short pixel; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 10 #define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK \ - ((NIGHTVISION_BUF_SIZE % CHUNK_SIZE == 0) ? (NIGHTVISION_BUF_SIZE / CHUNK_SIZE) \ - : (NIGHTVISION_BUF_SIZE / CHUNK_SIZE) + 1) +#define NCHUNK \ + ((NIGHTVISION_BUF_SIZE % CHUNK_SIZE == 0) ? (NIGHTVISION_BUF_SIZE / CHUNK_SIZE) : \ + (NIGHTVISION_BUF_SIZE / CHUNK_SIZE) + 1) // User defined registers #define NIGHTVISION_NIMAGES_REG 0x40 @@ -58,10 +58,10 @@ typedef short pixel; int main(int argc, char *argv[]) { - int n; - int ndev; + int n; + int ndev; struct esp_device *espdevs = NULL; - unsigned coherence; + unsigned coherence; ndev = probe(&espdevs, VENDOR_SLD, SLD_NIGHTVISION, DEV_NAME); if (ndev <= 0) { @@ -78,13 +78,13 @@ int main(int argc, char *argv[]) coherence = ACC_COH_NONE; #endif struct esp_device *dev = &espdevs[n]; - int done; - int i, j; - unsigned ** ptable = NULL; - pixel * mem; - pixel gold[COLS * ROWS]; - unsigned errors = 0; - int scatter_gather = 1; + int done; + int i, j; + unsigned **ptable = NULL; + pixel *mem; + pixel gold[COLS * ROWS]; + unsigned errors = 0; + int scatter_gather = 1; printf("******************** %s.%d ********************\n", DEV_NAME, n); printf("*** CHUNK_SIZE: %d\n", CHUNK_SIZE); @@ -98,7 +98,8 @@ int main(int argc, char *argv[]) if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { printf(" -> scatter-gather DMA is disabled; revert to contiguous buffer.\n"); scatter_gather = 0; - } else { + } + else { printf(" -> scatter-gather DMA is enabled.\n"); scatter_gather = 1; } @@ -144,7 +145,8 @@ int main(int argc, char *argv[]) iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); iowrite32(dev, SRC_OFFSET_REG, 0); iowrite32(dev, DST_OFFSET_REG, 0); - } else { + } + else { iowrite32(dev, SRC_OFFSET_REG, (uintptr_t)mem); iowrite32(dev, DST_OFFSET_REG, (uintptr_t)mem); } @@ -188,14 +190,12 @@ int main(int argc, char *argv[]) } } - if (errors) { - printf(" ... FAIL: %d mismatches\n", errors); - } else { + if (errors) { printf(" ... FAIL: %d mismatches\n", errors); } + else { printf(" ... PASS\n"); } - if (scatter_gather) - aligned_free(ptable); + if (scatter_gather) aligned_free(ptable); aligned_free(mem); printf("**************************************************\n\n"); diff --git a/accelerators/stratus_hls/nightvision_stratus/sw/linux/app/nightvision.c b/accelerators/stratus_hls/nightvision_stratus/sw/linux/app/nightvision.c index 6938b209bc..e23d344428 100644 --- a/accelerators/stratus_hls/nightvision_stratus/sw/linux/app/nightvision.c +++ b/accelerators/stratus_hls/nightvision_stratus/sw/linux/app/nightvision.c @@ -50,9 +50,9 @@ typedef short pixel_t; #define MEDIAN_NELEM (3 * 3) #define USE_SHIFT -typedef float fltPixel_t; +typedef float fltPixel_t; typedef unsigned short senPixel_t; -typedef int algPixel_t; +typedef int algPixel_t; #define ODD(A) ((A)&0x01) #define EVEN(A) (!ODD(A)) @@ -167,7 +167,7 @@ int dwt53_row_transpose_inverse(algPixel_t *data, algPixel_t *data2, int nrows, int dwt53_inverse(algPixel_t *data, int nrows, int ncols) { - int err = 0; + int err = 0; algPixel_t *data2 = (algPixel_t *)calloc(nrows * ncols, sizeof(algPixel_t)); if (!data2) { perror("Could not allocate temp space for dwt53_inverse op"); @@ -184,7 +184,7 @@ int dwt53_inverse(algPixel_t *data, int nrows, int ncols) int dwt53(algPixel_t *data, int nrows, int ncols) { - int err = 0; + int err = 0; algPixel_t *data2 = (algPixel_t *)calloc(nrows * ncols, sizeof(algPixel_t)); if (!data2) { fprintf(stderr, "File %s, Line %d, Memory Allocation Error", __FILE__, __LINE__); @@ -220,9 +220,11 @@ int hist(algPixel_t *streamA, int *h, int nRows, int nCols, int nBpp) for (i = 0; i < nPxls; i++) { if (streamA[i] >= nBins) { - fprintf(stderr, "File %s, Line %d, Range Error in hist() -- using max val ---", __FILE__, __LINE__); + fprintf(stderr, "File %s, Line %d, Range Error in hist() -- using max val ---", + __FILE__, __LINE__); h[nBins - 1]++; - } else { + } + else { h[(int)streamA[i]]++; } } @@ -230,12 +232,13 @@ int hist(algPixel_t *streamA, int *h, int nRows, int nCols, int nBpp) return 0; } -int histEq(algPixel_t *streamA, algPixel_t *out, int *h, int nRows, int nCols, int nInpBpp, int nOutBpp) +int histEq(algPixel_t *streamA, algPixel_t *out, int *h, int nRows, int nCols, int nInpBpp, + int nOutBpp) { - int nOutBins = (1 << nOutBpp); - int nInpBins = (1 << nInpBpp); - int *CDF = (int *)calloc(nInpBins, sizeof(int)); - int *LUT = (int *)calloc(nInpBins, sizeof(int)); + int nOutBins = (1 << nOutBpp); + int nInpBins = (1 << nInpBpp); + int *CDF = (int *)calloc(nInpBins, sizeof(int)); + int *LUT = (int *)calloc(nInpBins, sizeof(int)); if (!(CDF && LUT)) { // Ok to call free() on potentially NULL pointer free(CDF); @@ -277,8 +280,7 @@ int comparePxls(const void *arg1, const void *arg2) algPixel_t *p1 = (algPixel_t *)arg1; algPixel_t *p2 = (algPixel_t *)arg2; - if (*p1 < *p2) - return -1; + if (*p1 < *p2) return -1; else if (*p1 == *p2) return 0; else @@ -287,8 +289,8 @@ int comparePxls(const void *arg1, const void *arg2) int slowMedian3x3(algPixel_t *src, algPixel_t *dst, int nRows, int nCols) { - int i = 0, j = 0, k = 0; - int r = 0, c = 0; + int i = 0, j = 0, k = 0; + int r = 0, c = 0; algPixel_t *pxlList = (algPixel_t *)calloc(MEDIAN_NELEM, sizeof(algPixel_t)); if (!pxlList) { @@ -325,10 +327,10 @@ int nf(algPixel_t *streamA, algPixel_t *out, int nRows, int nCols) int readFrame(FILE *fp, void *image, int nPxls, int nBytesPerPxl, bool bSwap) { /* __int64 *p64 = (__int64 *)image; */ - unsigned long * p32 = (unsigned long *)image; - unsigned short *p16 = (unsigned short *)image; - int nPxlsRead = 0; - int i = 0; + unsigned long *p32 = (unsigned long *)image; + unsigned short *p16 = (unsigned short *)image; + int nPxlsRead = 0; + int i = 0; if (fp == (FILE *)NULL) { fprintf(stderr, "File %s, Line %d, NULL fp passed to readFrame()\n", __FILE__, __LINE__); @@ -345,7 +347,8 @@ int readFrame(FILE *fp, void *image, int nPxls, int nBytesPerPxl, bool bSwap) if (nBytesPerPxl == sizeof(unsigned short)) { *p16 = _byteswap_ushort(*p16); p16++; - } else if (nBytesPerPxl == sizeof(unsigned long)) { + } + else if (nBytesPerPxl == sizeof(unsigned long)) { *p32 = _byteswap_ulong(*p32); p32++; } @@ -362,25 +365,27 @@ int readFrame(FILE *fp, void *image, int nPxls, int nBytesPerPxl, bool bSwap) // Supply "." for srcDir if files reside in current working directory -int readImage(void *image, char *srcDir, char *fileName, int nRows, int nCols, int nFrames, int nBytesPerPxl, - bool bSwap) +int readImage(void *image, char *srcDir, char *fileName, int nRows, int nCols, int nFrames, + int nBytesPerPxl, bool bSwap) { - char * origDir = NULL; - __int64 * p64 = (__int64 *)image; - unsigned long * p32 = (unsigned long *)image; - unsigned short *p16 = (unsigned short *)image; - int nPxlsRead = 0; - int i = 0; + char *origDir = NULL; + __int64 *p64 = (__int64 *)image; + unsigned long *p32 = (unsigned long *)image; + unsigned short *p16 = (unsigned short *)image; + int nPxlsRead = 0; + int i = 0; origDir = _getcwd(NULL, MAX_PATH); if (_chdir(srcDir) == -1) { - fprintf(stderr, "File %s, Line %d, Could not change to directory=%s\n", __FILE__, __LINE__, srcDir); + fprintf(stderr, "File %s, Line %d, Could not change to directory=%s\n", __FILE__, __LINE__, + srcDir); return -1; } FILE *fp = fopen(fileName, "rb"); if (fp == (FILE *)NULL) { - fprintf(stderr, "File %s, Line %d, Could not open %s for reading\n", __FILE__, __LINE__, fileName); + fprintf(stderr, "File %s, Line %d, Could not open %s for reading\n", __FILE__, __LINE__, + fileName); return -2; } nPxlsRead = fread(image, nBytesPerPxl, nRows * nCols * nFrames, fp); @@ -391,10 +396,12 @@ int readImage(void *image, char *srcDir, char *fileName, int nRows, int nCols, i if (nBytesPerPxl == sizeof(unsigned short)) { *p16 = _byteswap_ushort(*p16); p16++; - } else if (nBytesPerPxl == sizeof(unsigned long)) { + } + else if (nBytesPerPxl == sizeof(unsigned long)) { *p32 = _byteswap_ulong(*p32); p32++; - } else if (nBytesPerPxl == sizeof(unsigned __int64)) { + } + else if (nBytesPerPxl == sizeof(unsigned __int64)) { *p64 = _byteswap_uint64(*p64); p64++; } @@ -407,23 +414,24 @@ int readImage(void *image, char *srcDir, char *fileName, int nRows, int nCols, i return nPxlsRead; } -int saveFrame(void *image, char *dstDir, char *baseFileName, int nRows, int nCols, int frameNo, int nBytesPerPxl, - bool bSwap) +int saveFrame(void *image, char *dstDir, char *baseFileName, int nRows, int nCols, int frameNo, + int nBytesPerPxl, bool bSwap) { // char *origDir = NULL; - __int64 * p64 = (__int64 *)image; - unsigned long * p32 = (unsigned long *)image; + __int64 *p64 = (__int64 *)image; + unsigned long *p32 = (unsigned long *)image; unsigned short *p16 = (unsigned short *)image; char fullFileName[MAX_PATH]; - int nPxlsToWrite = nRows * nCols; + int nPxlsToWrite = nRows * nCols; // int err = 0; int i = 0; // origDir = _getcwd(NULL, MAX_PATH); if (_chdir(dstDir) == -1) { - fprintf(stderr, "File %s, Line %d, Could not change to directory=%s\n", __FILE__, __LINE__, dstDir); + fprintf(stderr, "File %s, Line %d, Could not change to directory=%s\n", __FILE__, __LINE__, + dstDir); return -1; } @@ -433,10 +441,12 @@ int saveFrame(void *image, char *dstDir, char *baseFileName, int nRows, int nCol if (nBytesPerPxl == sizeof(unsigned short)) { *p16 = _byteswap_ushort(*p16); p16++; - } else if (nBytesPerPxl == sizeof(unsigned long)) { + } + else if (nBytesPerPxl == sizeof(unsigned long)) { *p32 = _byteswap_ulong(*p32); p32++; - } else if (nBytesPerPxl == sizeof(unsigned __int64)) { + } + else if (nBytesPerPxl == sizeof(unsigned __int64)) { *p64 = _byteswap_uint64(*p64); p64++; } @@ -444,12 +454,14 @@ int saveFrame(void *image, char *dstDir, char *baseFileName, int nRows, int nCol } FILE *fp = fopen(fullFileName, "wb"); if (fp == (FILE *)NULL) { - fprintf(stderr, "File %s, Line %d, Failed fopen() on file: %s\n", __FILE__, __LINE__, fullFileName); + fprintf(stderr, "File %s, Line %d, Failed fopen() on file: %s\n", __FILE__, __LINE__, + fullFileName); return -1; } if (fwrite((void *)image, nBytesPerPxl, nPxlsToWrite, fp) != (size_t)nPxlsToWrite) { fclose(fp); - fprintf(stderr, "File %s, Line %d, Failed fwrite() on file: %s\n", __FILE__, __LINE__, fullFileName); + fprintf(stderr, "File %s, Line %d, Failed fwrite() on file: %s\n", __FILE__, __LINE__, + fullFileName); return -1; } fclose(fp); @@ -464,12 +476,12 @@ int ensemble_1(algPixel_t *streamA, algPixel_t *out, int nRows, int nCols, int n // HE // DWT - int err = 0; - int i = 0; - int nHistBins = 1 << nInpBpp; - int * h = (int *)calloc(nHistBins, sizeof(int)); - algPixel_t *wrkBuf1 = (algPixel_t *)calloc(nRows * nCols, sizeof(algPixel_t)); - algPixel_t *wrkBuf2 = (algPixel_t *)calloc(nRows * nCols, sizeof(algPixel_t)); + int err = 0; + int i = 0; + int nHistBins = 1 << nInpBpp; + int *h = (int *)calloc(nHistBins, sizeof(int)); + algPixel_t *wrkBuf1 = (algPixel_t *)calloc(nRows * nCols, sizeof(algPixel_t)); + algPixel_t *wrkBuf2 = (algPixel_t *)calloc(nRows * nCols, sizeof(algPixel_t)); if (!(h && wrkBuf1 && wrkBuf2)) { free(h); @@ -510,9 +522,7 @@ int ensemble_1(algPixel_t *streamA, algPixel_t *out, int nRows, int nCols, int n } fclose(fileHistEq); - if (DEFAULT_DO_DWT) { - err = dwt53(out, nRows, nCols); - } + if (DEFAULT_DO_DWT) { err = dwt53(out, nRows, nCols); } FILE *fileDWT = fopen("AfterDWT.txt", "w"); for (i = 0; i < nRows * nCols; i++) { fprintf(fileDWT, "%d\n", out[i]); @@ -531,36 +541,37 @@ int ensemble_1(algPixel_t *streamA, algPixel_t *out, int nRows, int nCols, int n return err; } -static const char usage_str[] = "usage: ./nightvision_stratus.exe coherence infile [nimages] [ncols] [nrows] [-v]\n" - " coherence: none|llc-coh-dma|coh-dma|coh\n" - " infile : input file name (includes the path)\n\n" - "Optional arguments:.\n" - " nimages : number of images to be processed. Default: 1\n" - " ncols: number of columns of input image. Default: 160\n" - " nrows: number of rows of input image. Default: 120\n\n\n" - "The remaining option is only optional for 'test':\n" - " -v: enable verbose output for output-to-gold comparison\n" - "Notice:\n" - " The ordering of the argument is important. For now nimages, nrows\n" - " and ncols should either be all present or not at all.\n"; +static const char usage_str[] = + "usage: ./nightvision_stratus.exe coherence infile [nimages] [ncols] [nrows] [-v]\n" + " coherence: none|llc-coh-dma|coh-dma|coh\n" + " infile : input file name (includes the path)\n\n" + "Optional arguments:.\n" + " nimages : number of images to be processed. Default: 1\n" + " ncols: number of columns of input image. Default: 160\n" + " nrows: number of rows of input image. Default: 120\n\n\n" + "The remaining option is only optional for 'test':\n" + " -v: enable verbose output for output-to-gold comparison\n" + "Notice:\n" + " The ordering of the argument is important. For now nimages, nrows\n" + " and ncols should either be all present or not at all.\n"; struct nightvision_test { - struct test_info info; + struct test_info info; struct nightvision_stratus_access desc; - char * infile; - bool infile_is_raw; - unsigned nimages; - unsigned rows; - unsigned cols; - unsigned nbytespp; - unsigned swapbytes; - unsigned do_dwt; - unsigned nbpp_in; - unsigned nbpp_out; - pixel_t * hbuf; - int * sbuf_in; - int * sbuf_out; - bool verbose; + char *infile; + bool infile_is_raw; + unsigned nimages; + unsigned rows; + unsigned cols; + unsigned nbytespp; + unsigned swapbytes; + unsigned do_dwt; + unsigned nbpp_in; + unsigned nbpp_out; + pixel_t *hbuf; + int *sbuf_in; + int *sbuf_out; + bool verbose; }; static inline struct nightvision_test *to_nightvision(struct test_info *info) @@ -574,8 +585,7 @@ static int check_gold(int *gold, pixel_t *array, unsigned len, bool verbose) int rtn = 0; for (i = 0; i < len; i++) { if (((int)array[i]) != gold[i]) { - if (verbose) - printf("A[%d]: array=%d; gold=%d\n", i, (int)array[i], gold[i]); + if (verbose) printf("A[%d]: array=%d; gold=%d\n", i, (int)array[i], gold[i]); rtn++; } } @@ -593,9 +603,9 @@ static void init_buf(struct nightvision_test *t) printf("init buffers\n"); - int i = 0, j = 0, hbuf_i = 0; - unsigned nPxls; - FILE * fd = NULL; + int i = 0, j = 0, hbuf_i = 0; + unsigned nPxls; + FILE *fd = NULL; unsigned short *rawBuf; // open input file @@ -604,7 +614,8 @@ static void init_buf(struct nightvision_test *t) printf("[ERROR] Could not open %s\n", t->infile); exit(1); } - } else { + } + else { if ((fd = fopen(t->infile, "r")) == (FILE *)NULL) { printf("[ERROR] Could not open %s\n", t->infile); exit(1); @@ -627,9 +638,10 @@ static void init_buf(struct nightvision_test *t) printf("[ERROR] readFrame returns wrong number of pixels\n"); exit(1); } - } else { + } + else { // read txt image file - int i = 0; + int i = 0; uint16_t val = 0; fscanf(fd, "%hu", &val); @@ -682,8 +694,7 @@ static void nightvision_alloc_contig(struct test_info *info) struct nightvision_test *t = to_nightvision(info); printf("HW buf size: %zu B\n", nightvision_size(t)); - if (contig_alloc(nightvision_size(t), &info->contig) == NULL) - die_errno(__func__); + if (contig_alloc(nightvision_size(t), &info->contig) == NULL) die_errno(__func__); } static void nightvision_init_bufs(struct test_info *info) @@ -708,9 +719,9 @@ static void nightvision_set_access(struct test_info *info) static void nightvision_comp(struct test_info *info) { - struct nightvision_test *t = to_nightvision(info); - int i = 0; - int algErr = 0, numOut = 0; + struct nightvision_test *t = to_nightvision(info); + int i = 0; + int algErr = 0, numOut = 0; int *buf_in = NULL; int *buf_out = NULL; @@ -728,7 +739,8 @@ static void nightvision_comp(struct test_info *info) // save raw output image numOut = saveFrame(buf_out, ".", "ensemble1", t->rows, t->cols, 0, sizeof(int), false); assert(numOut == t->rows * t->cols * sizeof(int)); - } else { + } + else { // save txt output image FILE *fileOut = NULL; @@ -774,9 +786,9 @@ static void nightvision_comp(struct test_info *info) static bool nightvision_diff_ok(struct test_info *info) { - struct nightvision_test *t = to_nightvision(info); - int total_err = 0; - int i; + struct nightvision_test *t = to_nightvision(info); + int total_err = 0; + int i; contig_copy_from(t->hbuf, info->contig, 0, nightvision_size_opt(t)); @@ -796,8 +808,7 @@ static bool nightvision_diff_ok(struct test_info *info) } fclose(fileHBUF); - if (err) - printf("%d mismatches\n", err); + if (err) printf("%d mismatches\n", err); total_err += err; @@ -809,8 +820,7 @@ static bool nightvision_diff_ok(struct test_info *info) printf("\n"); } */ - if (total_err) - printf("%d mismatches in total\n", total_err); + if (total_err) printf("%d mismatches in total\n", total_err); return !total_err; } @@ -847,10 +857,8 @@ static void NORETURN usage(void) int main(int argc, char *argv[]) { printf("=== Helloo from nightvision\n"); - if (argc < 3 || argc == 5 || argc > 7) { - usage(); - - } else { + if (argc < 3 || argc == 5 || argc > 7) { usage(); } + else { printf("\nCommand line arguments received:\n"); printf("\tcoherence: %s\n", argv[1]); @@ -864,7 +872,8 @@ int main(int argc, char *argv[]) printf("\tnimages: %u\n", nightvision_test.nimages); printf("\tncols: %u\n", nightvision_test.cols); printf("\tnrows: %u\n", nightvision_test.rows); - } else { + } + else { nightvision_test.nimages = DEFAULT_NIMAGES; nightvision_test.rows = DEFAULT_NROWS; nightvision_test.cols = DEFAULT_NCOLS; @@ -873,7 +882,8 @@ int main(int argc, char *argv[]) if (argc == 4 || argc == 7) { if ((strcmp(argv[3], "-v") && argc == 4) || (strcmp(argv[6], "-v") && argc == 7)) { usage(); - } else { + } + else { nightvision_test.verbose = true; printf("\tverbose enabled\n"); } diff --git a/accelerators/stratus_hls/nightvision_stratus/sw/linux/driver/nightvision_stratus.c b/accelerators/stratus_hls/nightvision_stratus/sw/linux/driver/nightvision_stratus.c index de625a28ac..1d67de1281 100644 --- a/accelerators/stratus_hls/nightvision_stratus/sw/linux/driver/nightvision_stratus.c +++ b/accelerators/stratus_hls/nightvision_stratus/sw/linux/driver/nightvision_stratus.c @@ -60,17 +60,13 @@ static bool nightvision_xfer_input_ok(struct esp_device *esp, void *arg) { struct nightvision_stratus_access *a = arg; - if (a->nimages > MAX_NIMAGES) - return false; + if (a->nimages > MAX_NIMAGES) return false; - if (a->rows > MAX_ROWS) - return false; + if (a->rows > MAX_ROWS) return false; - if (a->cols > MAX_COLS) - return false; + if (a->cols > MAX_COLS) return false; - if (a->do_dwt != 0 && a->do_dwt != 1) - return false; + if (a->do_dwt != 0 && a->do_dwt != 1) return false; return true; } @@ -78,19 +74,17 @@ static bool nightvision_xfer_input_ok(struct esp_device *esp, void *arg) static int nightvision_probe(struct platform_device *pdev) { struct nightvision_stratus_device *nightvision; - struct esp_device * esp; - int rc; + struct esp_device *esp; + int rc; nightvision = kzalloc(sizeof(*nightvision), GFP_KERNEL); - if (nightvision == NULL) - return -ENOMEM; + if (nightvision == NULL) return -ENOMEM; esp = &nightvision->esp; esp->module = THIS_MODULE; esp->number = nightvision_devs; esp->driver = &nightvision_driver; rc = esp_device_register(esp, pdev); - if (rc) - goto err; + if (rc) goto err; nightvision_devs++; return 0; @@ -101,7 +95,7 @@ static int nightvision_probe(struct platform_device *pdev) static int __exit nightvision_remove(struct platform_device *pdev) { - struct esp_device * esp = platform_get_drvdata(pdev); + struct esp_device *esp = platform_get_drvdata(pdev); struct nightvision_stratus_device *nightvision = to_nightvision(esp); esp_device_unregister(esp); diff --git a/accelerators/stratus_hls/nightvision_stratus/sw/linux/include/nightvision_stratus.h b/accelerators/stratus_hls/nightvision_stratus/sw/linux/include/nightvision_stratus.h index ab217a17d5..1244abc7d5 100644 --- a/accelerators/stratus_hls/nightvision_stratus/sw/linux/include/nightvision_stratus.h +++ b/accelerators/stratus_hls/nightvision_stratus/sw/linux/include/nightvision_stratus.h @@ -7,8 +7,8 @@ #include #include #else - #include #include + #include #ifndef __user #define __user #endif diff --git a/accelerators/stratus_hls/sinkhorn_stratus/hw/src/sinkhorn.cpp b/accelerators/stratus_hls/sinkhorn_stratus/hw/src/sinkhorn.cpp index 6f66215088..1275651deb 100644 --- a/accelerators/stratus_hls/sinkhorn_stratus/hw/src/sinkhorn.cpp +++ b/accelerators/stratus_hls/sinkhorn_stratus/hw/src/sinkhorn.cpp @@ -8,10 +8,10 @@ #include "sinkhorn_functions.hpp" -//Inputs: inputX[m*p], inputY[m*q], p, q, m, gamma, maxiter -//Outputs: P[p*q], CP_sum -//Memories: P[q*p], C[q*p], K[q*p], x_a[p], y_b[q], inputX[m*p], inputY[m*q] -//Config Registers: Inputs dimensions - rows, q_cols, m_rows +// Inputs: inputX[m*p], inputY[m*q], p, q, m, gamma, maxiter +// Outputs: P[p*q], CP_sum +// Memories: P[q*p], C[q*p], K[q*p], x_a[p], y_b[q], inputX[m*p], inputY[m*q] +// Config Registers: Inputs dimensions - rows, q_cols, m_rows // Sinkhorn Algorithm constants - gamma, maxiter // P2P feature support - p2p_in, p2p_out, p2p_iter, store_state @@ -28,28 +28,28 @@ void sinkhorn::load_input() accel_ready.ack.reset_ack(); // User-defined reset code for the registers - p_rows = 0; - q_cols = 0; - m_rows = 0; - gamma = 0; + p_rows = 0; + q_cols = 0; + m_rows = 0; + gamma = 0; maxiter = 0; - p2p_in = 0; //Expect input to come directly from P2P - p2p_out = 0; //Expect output to be sent in P2P - p2p_iter = 1; //How many iterations of P2P + p2p_in = 0; // Expect input to come directly from P2P + p2p_out = 0; // Expect output to be sent in P2P + p2p_iter = 1; // How many iterations of P2P store_state = 0; - //The store_state configuration register is used to control executions - //of the processes while using the P2P feature from ESP. As for the current - //P2P feature (2021). Executions of the first and last iterations of the - //algorithm require disabling P2P and sending/receiving data to/from - //memory: - //0 - accelerator expects regular source/destination interactions - //1 - accelerator loads data from source in the first iteration, stops + // The store_state configuration register is used to control executions + // of the processes while using the P2P feature from ESP. As for the current + // P2P feature (2021). Executions of the first and last iterations of the + // algorithm require disabling P2P and sending/receiving data to/from + // memory: + // 0 - accelerator expects regular source/destination interactions + // 1 - accelerator loads data from source in the first iteration, stops // when norm check converges (or p2p_iter) - no final store to // destination (used if N Sinkhorn x N SVD) - //2 - if p2p_iter == 1 the accelrator only stores the data - allows to + // 2 - if p2p_iter == 1 the accelrator only stores the data - allows to // run only one iteration and then only store to memory/P2P - //3 - accelerator doesn't load from source in the first iteration, + // 3 - accelerator doesn't load from source in the first iteration, // doesn't stop on norm check (only when p2p_iter finishes), doesn't // store in the last iteration of p2p_iter (used if N Sinkhorn x 1 SVD) @@ -63,16 +63,16 @@ void sinkhorn::load_input() cfg.wait_for_config(); // config process conf_info_t config = this->conf_info.read(); - p_rows = config.p_rows; - q_cols = config.q_cols; - m_rows = config.m_rows; - gamma = config.gamma; - maxiter = config.maxiter; - p2p_in = config.p2p_in; - p2p_out = config.p2p_out; - p2p_iter = config.p2p_iter > 0 ? config.p2p_iter : 1; + p_rows = config.p_rows; + q_cols = config.q_cols; + m_rows = config.m_rows; + gamma = config.gamma; + maxiter = config.maxiter; + p2p_in = config.p2p_in; + p2p_out = config.p2p_out; + p2p_iter = config.p2p_iter > 0 ? config.p2p_iter : 1; store_state = config.store_state; - //wait(); + // wait(); } #ifndef STRATUS_HLS @@ -84,154 +84,154 @@ void sinkhorn::load_input() HLS_PROTO("load-dma"); wait(); - //bool ping = true; - uint32_t offset = 0; + // bool ping = true; + uint32_t offset = 0; uint32_t length_X = p_rows * m_rows; uint32_t length_Y = q_cols * m_rows; // Batching - for (uint16_t b = 0; b < p2p_iter; b++) - { + for (uint16_t b = 0; b < p2p_iter; b++) { wait(); - if((store_state == 2 && p2p_iter == 1) || (store_state == 3 && b == 0)) - { - //Do not load new data + if ((store_state == 2 && p2p_iter == 1) || (store_state == 3 && b == 0)) { + // Do not load new data this->load_compute_handshake(); this->load_compute_handshake(); } - else - { + else { #if (DMA_WORD_PER_BEAT == 0) - uint32_t length = length_X + length_Y; - if(p2p_in == 1) length = length + 1; + uint32_t length = length_X + length_Y; + if (p2p_in == 1) length = length + 1; #else - // uint32_t length_X = round_up(p_rows * m_rows, DMA_WORD_PER_BEAT); - // uint32_t length_Y = round_up(q_cols * m_rows, DMA_WORD_PER_BEAT); - uint32_t length = round_up(length_X+length_Y, DMA_WORD_PER_BEAT); - if(p2p_in == 1)length = round_up(length_X+length_Y+1, DMA_WORD_PER_BEAT); + // uint32_t length_X = round_up(p_rows * m_rows, DMA_WORD_PER_BEAT); + // uint32_t length_Y = round_up(q_cols * m_rows, DMA_WORD_PER_BEAT); + uint32_t length = round_up(length_X + length_Y, DMA_WORD_PER_BEAT); + if (p2p_in == 1) length = round_up(length_X + length_Y + 1, DMA_WORD_PER_BEAT); #endif - wait(); - offset = 0; - // Chunking - for (int rem = length; rem > 0; rem -= PLM_TOTAL_IN_WORD) - { wait(); - // Configure DMA transaction - uint32_t len = rem > PLM_TOTAL_IN_WORD ? PLM_TOTAL_IN_WORD : rem; + offset = 0; + // Chunking + for (int rem = length; rem > 0; rem -= PLM_TOTAL_IN_WORD) { + wait(); + // Configure DMA transaction + uint32_t len = rem > PLM_TOTAL_IN_WORD ? PLM_TOTAL_IN_WORD : rem; #if (DMA_WORD_PER_BEAT == 0) - // data word is wider than NoC links - dma_info_t dma_info(offset * DMA_BEAT_PER_WORD, len * DMA_BEAT_PER_WORD, DMA_SIZE); + // data word is wider than NoC links + dma_info_t dma_info(offset * DMA_BEAT_PER_WORD, len * DMA_BEAT_PER_WORD, + DMA_SIZE); #else - dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len / DMA_WORD_PER_BEAT, DMA_SIZE); - // dma_info_t dma_info(offset >> LOG_DMA_WORD_PER_BEAT, len >> LOG_DMA_WORD_PER_BEAT, DMA_SIZE); + dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len / DMA_WORD_PER_BEAT, + DMA_SIZE); + // dma_info_t dma_info(offset >> LOG_DMA_WORD_PER_BEAT, len >> + // LOG_DMA_WORD_PER_BEAT, DMA_SIZE); #endif - offset += len; + offset += len; - this->dma_read_ctrl.put(dma_info); + this->dma_read_ctrl.put(dma_info); #ifndef STRATUS_HLS - ESP_REPORT_INFO("DMA INFO LOAD: index = %d, length = %d, size = %d \n", dma_info.index, dma_info.length, DMA_SIZE.to_uint()); + ESP_REPORT_INFO("DMA INFO LOAD: index = %d, length = %d, size = %d \n", + dma_info.index, dma_info.length, DMA_SIZE.to_uint()); #endif #if (DMA_WORD_PER_BEAT == 0) - // data word is wider than NoC links - for (uint16_t i = 0; i < len; i++) - { - sc_dt::sc_bv dataBv; - - for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) - { - dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH) = this->dma_read_chnl.get(); - wait(); - } - - // Write to PLM - if(i < length_X) - inputX[i] = dataBv.to_uint(); - else - inputY[i] = dataBv.to_uint(); - } -#else - for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { - HLS_BREAK_DEP(inputX); - HLS_BREAK_DEP(inputY); - - sc_dt::sc_bv dataBv; + // data word is wider than NoC links + for (uint16_t i = 0; i < len; i++) { + sc_dt::sc_bv dataBv; - dataBv = this->dma_read_chnl.get(); - wait(); + for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) { + dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH) = + this->dma_read_chnl.get(); + wait(); + } - // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { - HLS_UNROLL_SIMPLE; - if(i+k < length_X) - { - inputX[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_uint(); - // inputX[i + k] = dataBv.range(((k+1) << LOG_DATA_WIDTH) - 1, k << LOG_DATA_WIDTH).to_uint(); + // Write to PLM + if (i < length_X) inputX[i] = dataBv.to_uint(); + else + inputY[i] = dataBv.to_uint(); + } +#else + for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { + HLS_BREAK_DEP(inputX); + HLS_BREAK_DEP(inputY); -#ifndef STRATUS_HLS - FPDATA data_fp; - FPDATA_WORD data_word = inputX[i+k]; - cynw_interpret(data_word, data_fp); - float data_float; - fp2native(data_fp, data_float); - //ESP_REPORT_INFO("DMA read inputX = %.20f, offset is %d", data_float, i+k); -#endif + sc_dt::sc_bv dataBv; - } - else - { - inputY[i + k - length_X] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_uint(); - // inputY[i + k - length_X] = dataBv.range(((k+1) << LOG_DATA_WIDTH) - 1, k << LOG_DATA_WIDTH).to_uint(); - - // if(i + k - length_X == length_Y) - // { - // FPDATA data_fp = 1.0; - // FPDATA_WORD data_word; - // cynw_interpret(data_fp, data_word); - // inputY[i + k - length_X] = data_word; - // } + dataBv = this->dma_read_chnl.get(); + wait(); -#ifndef STRATUS_HLS - FPDATA data_fp; - FPDATA_WORD data_word = inputY[i+k]; - cynw_interpret(data_word, data_fp); - float data_float; - fp2native(data_fp, data_float); - //ESP_REPORT_INFO("DMA read inputY = %.20f, offset is %d", data_float, i+k); -#endif + // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + HLS_UNROLL_SIMPLE; + if (i + k < length_X) { + inputX[i + k] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_uint(); + // inputX[i + k] = dataBv.range(((k+1) << LOG_DATA_WIDTH) - 1, k << + // LOG_DATA_WIDTH).to_uint(); + + #ifndef STRATUS_HLS + FPDATA data_fp; + FPDATA_WORD data_word = inputX[i + k]; + cynw_interpret(data_word, data_fp); + float data_float; + fp2native(data_fp, data_float); + // ESP_REPORT_INFO("DMA read inputX = %.20f, offset is %d", + // data_float, i+k); + #endif + } + else { + inputY[i + k - length_X] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) + .to_uint(); + // inputY[i + k - length_X] = dataBv.range(((k+1) << LOG_DATA_WIDTH) + // - 1, k << LOG_DATA_WIDTH).to_uint(); + + // if(i + k - length_X == length_Y) + // { + // FPDATA data_fp = 1.0; + // FPDATA_WORD data_word; + // cynw_interpret(data_fp, data_word); + // inputY[i + k - length_X] = data_word; + // } + + #ifndef STRATUS_HLS + FPDATA data_fp; + FPDATA_WORD data_word = inputY[i + k]; + cynw_interpret(data_word, data_fp); + float data_float; + fp2native(data_fp, data_float); + // ESP_REPORT_INFO("DMA read inputY = %.20f, offset is %d", + // data_float, i+k); + #endif + } } } - } #endif - wait(); - } + wait(); + } #ifndef STRATUS_HLS - ESP_REPORT_INFO("DMA read inputX and inputY complete, offset is %d", offset); + ESP_REPORT_INFO("DMA read inputX and inputY complete, offset is %d", offset); #endif - //Check if SVD accelerator signaled that norm check converged - wait(); - FPDATA data_fp, tmp = 1.0; - FPDATA_WORD data_word = inputY[length_Y]; - //wait(); - cynw_interpret(data_word, data_fp); - //wait(); - if(p2p_in == 1 && data_fp == tmp && store_state != 3) - b = p2p_iter - 1;//Finish if norm check succeeded - - this->load_compute_handshake(); // loaded input is ready - this->load_compute_handshake(); // waiting for next compute + // Check if SVD accelerator signaled that norm check converged + wait(); + FPDATA data_fp, tmp = 1.0; + FPDATA_WORD data_word = inputY[length_Y]; + // wait(); + cynw_interpret(data_word, data_fp); + // wait(); + if (p2p_in == 1 && data_fp == tmp && store_state != 3) + b = p2p_iter - 1; // Finish if norm check succeeded + + this->load_compute_handshake(); // loaded input is ready + this->load_compute_handshake(); // waiting for next compute } } } - #ifndef STRATUS_HLS ESP_REPORT_INFO("Load is done"); #else @@ -245,7 +245,6 @@ void sinkhorn::load_input() } } - void sinkhorn::compute_kernel() { @@ -262,7 +261,7 @@ void sinkhorn::compute_kernel() // m_rows = 0; // gamma = 0; // maxiter = 0; - //unsigned compute_iter = 1; + // unsigned compute_iter = 1; wait(); } @@ -283,69 +282,62 @@ void sinkhorn::compute_kernel() cfg.wait_for_config(); // config process conf_info_t config = this->conf_info.read(); - p_rows = config.p_rows; - q_cols = config.q_cols; - m_rows = config.m_rows; - gamma = config.gamma; - maxiter = config.maxiter; - p2p_in = config.p2p_in; - p2p_iter = config.p2p_iter > 0 ? config.p2p_iter : 1; + p_rows = config.p_rows; + q_cols = config.q_cols; + m_rows = config.m_rows; + gamma = config.gamma; + maxiter = config.maxiter; + p2p_in = config.p2p_in; + p2p_iter = config.p2p_iter > 0 ? config.p2p_iter : 1; store_state = config.store_state; wait(); } - uint32_t length_Y = m_rows*q_cols; - - for(int b = 0; b < p2p_iter; b++) - { + uint32_t length_Y = m_rows * q_cols; - this->compute_load_handshake(); + for (int b = 0; b < p2p_iter; b++) { - //Check if SVD accelerator signaled that norm check converged - FPDATA data_fp, tmp = 1.0; - FPDATA_WORD data_word = inputY[length_Y]; - cynw_interpret(data_word, data_fp); + this->compute_load_handshake(); - if(p2p_in == 1 && data_fp == tmp && store_state != 3) - b = p2p_iter - 1;//Finish if norm check succeeded + // Check if SVD accelerator signaled that norm check converged + FPDATA data_fp, tmp = 1.0; + FPDATA_WORD data_word = inputY[length_Y]; + cynw_interpret(data_word, data_fp); - if((store_state == 2 && p2p_iter == 1) || (store_state == 3 && b == 0)) - { - //Do nothing - P2P related - } - else - { + if (p2p_in == 1 && data_fp == tmp && store_state != 3) + b = p2p_iter - 1; // Finish if norm check succeeded + if ((store_state == 2 && p2p_iter == 1) || (store_state == 3 && b == 0)) { + // Do nothing - P2P related + } + else { - // Compute + // Compute #ifndef STRATUS_HLS - ESP_REPORT_INFO("START COMPUTING"); + ESP_REPORT_INFO("START COMPUTING"); #else - printf("START COMPUTING\n"); + printf("START COMPUTING\n"); #endif - compute_C(p_rows, q_cols, m_rows, gamma); + compute_C(p_rows, q_cols, m_rows, gamma); #ifndef STRATUS_HLS - ESP_REPORT_INFO("Compute C is done"); + ESP_REPORT_INFO("Compute C is done"); #else - printf("Compute C is done\n"); + printf("Compute C is done\n"); #endif - compute_P(p_rows, q_cols, maxiter); + compute_P(p_rows, q_cols, maxiter); #ifndef STRATUS_HLS - ESP_REPORT_INFO("Compute K is done"); + ESP_REPORT_INFO("Compute K is done"); #else - printf("Compute K is done\n"); + printf("Compute K is done\n"); #endif - - - } + } this->compute_store_handshake(); this->compute_store_handshake(); this->compute_load_handshake(); - } #ifndef STRATUS_HLS @@ -353,7 +345,6 @@ void sinkhorn::compute_kernel() #else printf("Compute is done\n"); #endif - } void sinkhorn::store_output() @@ -386,13 +377,14 @@ void sinkhorn::store_output() cfg.wait_for_config(); // config process conf_info_t config = this->conf_info.read(); - p_rows = config.p_rows; - q_cols = config.q_cols; - m_rows = config.m_rows; - p2p_in = config.p2p_in; - p2p_out = config.p2p_out; + p_rows = config.p_rows; + q_cols = config.q_cols; + m_rows = config.m_rows; + p2p_in = config.p2p_in; + p2p_out = config.p2p_out; p2p_iter = config.p2p_iter > 0 ? config.p2p_iter : 1; - store_state = config.store_state;//0 - store, 1 - don't store on the last iteration if p2p_out + store_state = + config.store_state; // 0 - store, 1 - don't store on the last iteration if p2p_out } // Store @@ -401,22 +393,21 @@ void sinkhorn::store_output() HLS_PROTO("store-dma"); wait(); - uint32_t length_Y = m_rows*q_cols; - uint32_t length_X = m_rows*p_rows; - uint32_t length_P = p_rows*q_cols; + uint32_t length_Y = m_rows * q_cols; + uint32_t length_X = m_rows * p_rows; + uint32_t length_P = p_rows * q_cols; #if (DMA_WORD_PER_BEAT == 0) - uint32_t store_offset = length_X+length_Y; + uint32_t store_offset = length_X + length_Y; #else - uint32_t store_offset = round_up(length_X+length_Y, DMA_WORD_PER_BEAT) * 1; + uint32_t store_offset = round_up(length_X + length_Y, DMA_WORD_PER_BEAT) * 1; #endif uint32_t offset = store_offset; wait(); // Batching - for (uint16_t b = 0; b < p2p_iter; b++) - { + for (uint16_t b = 0; b < p2p_iter; b++) { this->store_compute_handshake(); this->store_computeP_handshake(); @@ -426,34 +417,29 @@ void sinkhorn::store_output() FPDATA_WORD data_word = inputY[length_Y]; cynw_interpret(data_word, data_fp); - if(p2p_in == 1 && data_fp == tmp && store_state != 3) - b = p2p_iter - 1;//Finish if norm check succeeded + if (p2p_in == 1 && data_fp == tmp && store_state != 3) + b = p2p_iter - 1; // Finish if norm check succeeded - //When we are in the last iteration, don't store - //the data if store state is 1 or 3 - if((store_state == 1 || store_state == 3) && b == p2p_iter - 1) - { + // When we are in the last iteration, don't store + // the data if store state is 1 or 3 + if ((store_state == 1 || store_state == 3) && b == p2p_iter - 1) { this->store_compute_handshake(); } - else - { + else { wait(); bool pingpong = false; #if (DMA_WORD_PER_BEAT == 0) uint32_t length = length_P + 1; - offset = store_offset; - if(p2p_out == 1) - length = length_P; + offset = store_offset; + if (p2p_out == 1) length = length_P; #else uint32_t length = round_up(length_P + 1, DMA_WORD_PER_BEAT); offset = store_offset; - if(p2p_out == 1) - length = round_up(length_P, DMA_WORD_PER_BEAT); + if (p2p_out == 1) length = round_up(length_P, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) { #ifndef STRATUS_HLS ESP_REPORT_INFO("DMA write start offset is %d", offset); @@ -462,35 +448,38 @@ void sinkhorn::store_output() uint32_t len = rem > PLM_OUT_WORD ? PLM_OUT_WORD : rem; #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - dma_info_t dma_info(offset * DMA_BEAT_PER_WORD, len * DMA_BEAT_PER_WORD, DMA_SIZE); + dma_info_t dma_info(offset * DMA_BEAT_PER_WORD, len * DMA_BEAT_PER_WORD, + DMA_SIZE); #else - dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len / DMA_WORD_PER_BEAT, DMA_SIZE); - // dma_info_t dma_info(offset >> LOG_DMA_WORD_PER_BEAT, len >> LOG_DMA_WORD_PER_BEAT, DMA_SIZE); + dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len / DMA_WORD_PER_BEAT, + DMA_SIZE); + // dma_info_t dma_info(offset >> LOG_DMA_WORD_PER_BEAT, len >> + // LOG_DMA_WORD_PER_BEAT, DMA_SIZE); #endif #ifndef STRATUS_HLS - ESP_REPORT_INFO("DMA INFO STORE: index = %d, length = %d, size = %d \n", dma_info.index, dma_info.length, DMA_SIZE.to_uint()); + ESP_REPORT_INFO("DMA INFO STORE: index = %d, length = %d, size = %d \n", + dma_info.index, dma_info.length, DMA_SIZE.to_uint()); #endif offset += len; this->dma_write_ctrl.put(dma_info); -// sc_bv data; - -// // Load inputs X - Every DMA brings one 32 bit word -// for (uint32_t i = plm_addr; i < /*PLM_OUTPUT_SIZE*/(plm_addr + p_rows * q_cols); i++) { -// wait(); -// data = sc_bv(P[i]); -// wait(); -// this->dma_write_chnl.put(data); -// // ESP_REPORT_INFO("Value sent to memory: %d : %d", i, P[i]) -// } + // sc_bv data; + // // Load inputs X - Every DMA brings one 32 bit word + // for (uint32_t i = plm_addr; i < /*PLM_OUTPUT_SIZE*/(plm_addr + p_rows * + // q_cols); i++) { + // wait(); + // data = sc_bv(P[i]); + // wait(); + // this->dma_write_chnl.put(data); + // // ESP_REPORT_INFO("Value sent to memory: %d : %d", i, P[i]) + // } #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - for (uint16_t i = 0; i < len; i++) - { + for (uint16_t i = 0; i < len; i++) { // Read from PLM sc_dt::sc_int data; @@ -501,95 +490,88 @@ void sinkhorn::store_output() sc_dt::sc_bv dataBv(data); uint16_t k = 0; - for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) - { - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) { + this->dma_write_chnl.put( + dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); wait(); } // Last beat on the bus does not require wait(), which is // placed before accessing the PLM - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + this->dma_write_chnl.put( + dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); } #else - //wait(); - //compute_store_P(p_rows, q_cols); + // wait(); + // compute_store_P(p_rows, q_cols); uint16_t h = 0; sc_dt::sc_bv dataBv; -#ifndef STRATUS_HLS + #ifndef STRATUS_HLS ESP_REPORT_INFO("len = %d, size = %d", len, len / DMA_WORD_PER_BEAT); -#endif + #endif - for (uint16_t i = 0; i < length_P; i += q_cols) - { + for (uint16_t i = 0; i < length_P; i += q_cols) { wait(); this->store_computeP_handshake(); - for(uint16_t k = 0; k < q_cols; k++) - { + for (uint16_t k = 0; k < q_cols; k++) { wait(); - if(pingpong == false) - { - dataBv.range((h+1) * DATA_WIDTH - 1, h * DATA_WIDTH) = Ping[k]; - // dataBv.range(((h+1) << LOG_DATA_WIDTH) - 1, h << LOG_DATA_WIDTH) = Ping[k]; + if (pingpong == false) { + dataBv.range((h + 1) * DATA_WIDTH - 1, h * DATA_WIDTH) = Ping[k]; + // dataBv.range(((h+1) << LOG_DATA_WIDTH) - 1, h << LOG_DATA_WIDTH) + // = Ping[k]; } - //this->dma_write_chnl.put(dataBv_ping); - else - { - dataBv.range((h+1) * DATA_WIDTH - 1, h * DATA_WIDTH) = Pong[k]; - // dataBv.range(((h+1) << LOG_DATA_WIDTH) - 1, h << LOG_DATA_WIDTH) = Pong[k]; + // this->dma_write_chnl.put(dataBv_ping); + else { + dataBv.range((h + 1) * DATA_WIDTH - 1, h * DATA_WIDTH) = Pong[k]; + // dataBv.range(((h+1) << LOG_DATA_WIDTH) - 1, h << LOG_DATA_WIDTH) + // = Pong[k]; } - //this->dma_write_chnl.put(dataBv_pong); + // this->dma_write_chnl.put(dataBv_pong); h = h + 1; - if(h == DMA_WORD_PER_BEAT) - { + if (h == DMA_WORD_PER_BEAT) { h = 0; this->dma_write_chnl.put(dataBv); } - } pingpong = !pingpong; -#ifndef STRATUS_HLS - //ESP_REPORT_INFO("store pingpong is %d", pingpong); -#endif + #ifndef STRATUS_HLS + // ESP_REPORT_INFO("store pingpong is %d", pingpong); + #endif } this->store_computeP_handshake(); wait(); - //Store CP_sum - if(pingpong == false) - { - dataBv.range((h+1) * DATA_WIDTH - 1, h * DATA_WIDTH) = Ping[0]; - // dataBv.range(((h+1) << LOG_DATA_WIDTH) - 1, h << LOG_DATA_WIDTH) = Ping[0]; + // Store CP_sum + if (pingpong == false) { + dataBv.range((h + 1) * DATA_WIDTH - 1, h * DATA_WIDTH) = Ping[0]; + // dataBv.range(((h+1) << LOG_DATA_WIDTH) - 1, h << LOG_DATA_WIDTH) = + // Ping[0]; } - //this->dma_write_chnl.put(dataBv_ping); - else - { - dataBv.range((h+1) * DATA_WIDTH - 1, h * DATA_WIDTH) = Pong[0]; - // dataBv.range(((h+1) << LOG_DATA_WIDTH) - 1, h << LOG_DATA_WIDTH) = Pong[0]; + // this->dma_write_chnl.put(dataBv_ping); + else { + dataBv.range((h + 1) * DATA_WIDTH - 1, h * DATA_WIDTH) = Pong[0]; + // dataBv.range(((h+1) << LOG_DATA_WIDTH) - 1, h << LOG_DATA_WIDTH) = + // Pong[0]; } - //this->dma_write_chnl.put(dataBv_pong); + // this->dma_write_chnl.put(dataBv_pong); - if(!(p2p_out == 1 && h == 0)) - this->dma_write_chnl.put(dataBv); + if (!(p2p_out == 1 && h == 0)) this->dma_write_chnl.put(dataBv); pingpong = !pingpong; - //ESP_REPORT_INFO("counter = %d", counter) + // ESP_REPORT_INFO("counter = %d", counter) #endif - - } - this->store_compute_handshake(); // Store is done, compute next batch } } @@ -599,8 +581,6 @@ void sinkhorn::store_output() ESP_REPORT_INFO("DMA write complete"); #endif - - #ifndef STRATUS_HLS ESP_REPORT_INFO("Store is done"); #else @@ -615,7 +595,6 @@ void sinkhorn::store_output() } } - void sinkhorn::compute_store_P() { @@ -636,8 +615,8 @@ void sinkhorn::compute_store_P() uint32_t p2p_iter; uint32_t p2p_in; uint32_t store_state; - //uint32_t gamma; - //sc_dt::sc_bv dataBv; + // uint32_t gamma; + // sc_dt::sc_bv dataBv; { HLS_PROTO("computeP-config"); @@ -648,31 +627,30 @@ void sinkhorn::compute_store_P() p_rows = config.p_rows; q_cols = config.q_cols; m_rows = config.m_rows; - //gamma = config.gamma; - p2p_iter = config.p2p_iter > 0 ? config.p2p_iter : 1; - p2p_in = config.p2p_in; + // gamma = config.gamma; + p2p_iter = config.p2p_iter > 0 ? config.p2p_iter : 1; + p2p_in = config.p2p_in; store_state = config.store_state; wait(); } - //Compute P + // Compute P { - //HLS_PROTO("computeP-dma"); - //wait(); + // HLS_PROTO("computeP-dma"); + // wait(); #ifndef STRATUS_HLS float sum = 0; #endif - uint32_t length_Y = m_rows*q_cols; + uint32_t length_Y = m_rows * q_cols; // FPDATA gamma_fp; // cynw_interpret(gamma, gamma_fp); // gamma_fp = 1 / gamma_fp; - for (uint16_t b = 0; b < p2p_iter; b++) - { - //Handshake from store to start computing P + for (uint16_t b = 0; b < p2p_iter; b++) { + // Handshake from store to start computing P this->computeP_store_handshake(); // wait(); @@ -681,54 +659,49 @@ void sinkhorn::compute_store_P() FPDATA_WORD data_word = inputY[length_Y]; cynw_interpret(data_word, data_fp); - if(p2p_in == 1 && data_fp == tmp && store_state != 3) - b = p2p_iter - 1;//Finish if norm check succeeded + if (p2p_in == 1 && data_fp == tmp && store_state != 3) + b = p2p_iter - 1; // Finish if norm check succeeded - //The no-store states - if((store_state == 1 || store_state == 3) && b == p2p_iter - 1){ - //Do nothing - Skip P computation + // The no-store states + if ((store_state == 1 || store_state == 3) && b == p2p_iter - 1) { + // Do nothing - Skip P computation } - else - { + else { FPDATA_WORD CP_word; - //sc_dt::sc_bv CP_bv; + // sc_dt::sc_bv CP_bv; FPDATA CP_fp_total = 0; uint32_t i = 0, j = 0; - //uint16_t h = 0; + // uint16_t h = 0; bool pingpong = false; - //Create diagonal matrices from x_a and b_y and do P = x_a @ K @ b_y - for(i = 0; i < P_MAX; i++) - { + // Create diagonal matrices from x_a and b_y and do P = x_a @ K @ b_y + for (i = 0; i < P_MAX; i++) { HLS_BREAK_DEP(x_a); - //wait(); + // wait(); - if(i >= p_rows){} - else - { + if (i >= p_rows) {} + else { FPDATA_WORD a_word = x_a[i]; - FPDATA a_fp = 0; - //wait(); + FPDATA a_fp = 0; + // wait(); cynw_interpret(a_word, a_fp); -// #ifndef STRATUS_HLS -// ESP_REPORT_INFO("i is %d", i); -// #endif - for(j = 0; j < Q_MAX; j++) - { + // #ifndef STRATUS_HLS + // ESP_REPORT_INFO("i is %d", i); + // #endif + for (j = 0; j < Q_MAX; j++) { HLS_PIPELINE_LOOP(SOFT_STALL, 1, "store P loop"); HLS_BREAK_DEP(y_b); HLS_BREAK_DEP(K); HLS_BREAK_DEP(C); HLS_BREAK_DEP(Ping); HLS_BREAK_DEP(Pong); - //wait(); + // wait(); - if(j >= q_cols){} - else - { - //wait(); + if (j >= q_cols) {} + else { + // wait(); FPDATA CP_fp; FPDATA_WORD b_word = y_b[j]; FPDATA b_fp; @@ -738,20 +711,20 @@ void sinkhorn::compute_store_P() FPDATA P_fp; FPDATA_WORD C_word = C[i * q_cols + j]; FPDATA C_fp; - //sc_dt::sc_bv P_bv; + // sc_dt::sc_bv P_bv; - //wait(); + // wait(); - //cynw_interpret(C_word, C_fp); - //cynw_interpret(b_word, b_fp); - //K_fp = neg_exp(C_fp * gamma_fp); + // cynw_interpret(C_word, C_fp); + // cynw_interpret(b_word, b_fp); + // K_fp = neg_exp(C_fp * gamma_fp); cynw_interpret(b_word, b_fp); cynw_interpret(K_word, K_fp); - //wait(); + // wait(); cynw_interpret(C_word, C_fp); - //P[i * q + j] = x_a[i] * K[i * q + j] * y_b[j]; + // P[i * q + j] = x_a[i] * K[i * q + j] * y_b[j]; P_fp = a_fp * K_fp * b_fp; #ifndef STRATUS_HLS @@ -759,46 +732,42 @@ void sinkhorn::compute_store_P() #endif cynw_interpret(P_fp, P_word); - //wait(); - if(pingpong == false) - Ping[j] = P_word; + // wait(); + if (pingpong == false) Ping[j] = P_word; else Pong[j] = P_word; ////wait(); CP_fp = C_fp * P_fp; CP_fp_total += CP_fp; - //wait(); + // wait(); } } pingpong = !pingpong; this->computeP_store_handshake(); - //wait(); - + // wait(); } } - //wait(); + // wait(); cynw_interpret(CP_fp_total, CP_word); - if(pingpong == false) - Ping[0] = CP_word; + if (pingpong == false) Ping[0] = CP_word; else Pong[0] = CP_word; pingpong = !pingpong; this->computeP_store_handshake(); - //wait(); + // wait(); #ifndef STRATUS_HLS float sum_CP = CP_fp_total; ESP_REPORT_INFO("P sum is %f", sum); ESP_REPORT_INFO("CP sum is %f", sum_CP); ESP_REPORT_INFO("Compute P finished"); - sum =0; + sum = 0; sum_CP = 0; #endif - } } } @@ -808,6 +777,4 @@ void sinkhorn::compute_store_P() HLS_PROTO("computeP-done"); this->process_done(); } - } - diff --git a/accelerators/stratus_hls/sinkhorn_stratus/hw/tb/input.h b/accelerators/stratus_hls/sinkhorn_stratus/hw/tb/input.h index 9fbdc004f6..a9a39cb459 100644 --- a/accelerators/stratus_hls/sinkhorn_stratus/hw/tb/input.h +++ b/accelerators/stratus_hls/sinkhorn_stratus/hw/tb/input.h @@ -1,10718 +1,7008 @@ - //pre-saved inputs -float inputX[229*3] = {1.51120281e+00, 1.36194446e+00, 1.61312625e+00, - 1.58690408e+00, 1.32373133e+00, 1.07425133e+00, - 8.02394070e-01, 6.29378573e-01, 4.35005816e-01, - 4.93205246e-01, 1.06200780e+00, 9.26704545e-01, - 6.34436776e-01, 5.12154012e-01, 3.88417107e-01, - 6.12649144e-01, 1.07713427e+00, 1.07541979e+00, - 8.11425303e-01, 1.45720489e+00, 1.14820754e+00, - 6.84273413e-01, 9.34918854e-01, 6.19397984e-01, - 4.67314085e-01, 7.91461222e-01, 6.99750610e-01, - 1.54311610e+00, 1.21924389e+00, 7.43194652e-01, - 3.62519451e-01, 4.71780883e-01, 9.71792460e-01, - 8.88699304e-01, 4.54071857e-01, 5.02880311e-01, - 3.83912392e-01, 5.45780692e-01, 1.04203159e+00, - 8.50741050e-01, 1.41111665e+00, 1.09091158e+00, - 7.27334096e-01, 1.08170264e+00, 8.90309901e-01, - 4.14675687e-01, 9.61184854e-01, 1.03147000e+00, - 9.70825840e-01, 6.25900612e-01, 3.27430358e-01, - 2.07226694e-01, 2.86372753e-01, 3.21928024e-01, - 4.36299683e-01, 1.01855059e+00, 9.25725535e-01, - 5.57625034e-01, 6.95951355e-01, 1.99792911e-01, - -3.08895420e-01, -1.14008817e-01, 2.83036223e-01, - 4.88584432e-01, 1.14042563e+00, 1.47874593e+00, - 8.38077420e-01, 5.40483538e-01, 8.41219152e-01, - 7.13772252e-01, 8.16783774e-01, 9.32215499e-01, - 4.38294042e-01, 7.58422528e-01, 8.28786603e-01, - 4.56830659e-01, 4.01284325e-01, 1.09382762e+00, - 9.43319134e-01, 6.59471692e-01, 6.41635505e-01, - 1.35811162e+00, 1.28872162e+00, 1.52204544e+00, - 2.11533259e+00, 1.72678980e+00, 1.01165142e+00, - 6.44749147e-01, 5.05284728e-01, 5.53484047e-01, - 9.80134025e-01, 9.83556712e-01, 9.19750953e-01, - 8.67798898e-01, 4.95676335e-01, 3.01009066e-01, - 5.32933344e-01, 5.41011181e-01, 1.05081837e+00, - 9.40409890e-01, 2.80026590e-01, 4.09561533e-02, - 5.14300669e-01, 5.07025640e-01, 1.03733849e+00, - 9.92242809e-01, 1.04862066e+00, 1.30449816e+00, - 1.24417637e+00, 9.37715766e-01, 1.09339115e+00, - 6.75838719e-01, 4.29105793e-01, 1.10882844e+00, - 7.60288245e-01, 8.13736130e-01, 8.94787698e-01, - 5.38706802e-01, 2.65789662e-01, 3.27883898e-01, - 5.98142909e-01, 4.72640645e-01, 8.91383091e-01, - 6.73896793e-01, 8.46630726e-01, 7.15034263e-01, - 6.51548414e-01, 8.82947850e-01, 1.10954511e+00, - 8.38224271e-01, 1.54119217e+00, 1.23472443e+00, - 4.30501421e-01, 3.58350045e-01, 8.69510082e-01, - 7.76359871e-01, 5.83012790e-01, 8.67601291e-01, - 8.53014644e-01, 1.22551459e+00, 1.06951213e+00, - 1.08007844e+00, 9.93194691e-01, 8.81091943e-01, - 8.40211464e-01, 1.06594058e+00, 9.18008159e-01, - 8.16516979e-01, 8.30411648e-01, 7.22438187e-01, - 6.00629284e-01, 1.02310984e+00, 1.01917509e+00, - 6.08587182e-01, 6.76332335e-01, 8.60473445e-01, - 9.21097632e-01, 1.01093818e+00, 1.00052097e+00, - 6.29570162e-01, 4.16585415e-01, 6.23429195e-01, - 4.89664157e-01, 1.40814604e+00, 1.18699734e+00, - 8.52996832e-01, 4.44797579e-01, 2.39917608e-01, - 6.18409448e-01, 9.21789861e-01, 8.06761526e-01, - 1.21172323e+00, 9.13011650e-01, 1.26516812e+00, - 1.19539464e+00, 7.52316426e-01, 5.75879059e-01, - 7.19668392e-01, 7.68234535e-01, 6.33714693e-01, - 7.85323820e-01, 7.93833503e-01, 1.02619782e+00, - 9.56737352e-01, 8.25493242e-01, 9.65633284e-01, - 6.49548970e-01, 1.01823318e+00, 1.00562630e+00, - 8.83237663e-01, 7.58214202e-01, 8.41575974e-01, - 1.11554021e+00, 5.92033184e-01, 3.35099375e-01, - 6.69525697e-01, 7.04578221e-01, 1.07034331e+00, - 1.19305651e+00, 8.37189956e-01, 8.37676286e-01, - 1.17931865e+00, 8.56658788e-01, 6.92921445e-01, - 8.45998841e-01, 9.74460305e-01, 9.78870568e-01, - 1.11788221e+00, 5.25942392e-01, 7.59510958e-01, - 9.29405965e-01, 4.70311282e-01, 3.62745715e-01, - 9.09054814e-01, 9.52045725e-01, 1.44758241e+00, - 1.23433700e+00, 4.89668060e-01, 5.15972684e-01, - 8.82986706e-01, 1.03874095e+00, 1.75938726e+00, - 1.53805514e+00, 8.34061594e-01, 6.40737257e-01, - 8.21486389e-01, 8.22409159e-01, 1.07932736e+00, - 1.07341242e+00, - -4.56006193e-02, 6.17578891e-02, 2.74879318e-02, - 6.17359478e-03, -2.23948504e-02, -9.01332267e-02, - -8.58045120e-02, -9.48352707e-02, -1.09325286e-01, - -1.24532311e-01, 1.84304537e-02, 6.87509700e-02, - 5.13892169e-02, 3.40147295e-02, -6.31939287e-03, - -9.46725688e-02, -1.39352387e-01, -1.37685290e-01, - -1.60044633e-01, -5.48693657e-02, 1.76405110e-02, - -4.26615372e-03, -5.80056311e-02, -4.69608236e-02, - -8.13368270e-02, -1.13387618e-01, -1.23151147e-01, - -3.89528580e-02, 3.99693721e-02, 6.71696126e-02, - 2.12673913e-02, -3.59193756e-02, -1.19592821e-01, - -9.38124079e-02, -2.41755983e-02, -7.53442895e-02, - -9.96879921e-02, -1.06975996e-01, -1.35374132e-02, - 4.53922533e-02, -2.83580097e-03, -2.30708909e-02, - -6.96463570e-02, -1.42850344e-01, -1.32497311e-01, - -1.11130246e-01, -3.97844151e-02, -2.28006665e-02, - 3.24078702e-02, 4.33573119e-02, 2.94319116e-02, - 5.50806247e-03, -7.25101086e-02, -9.42463724e-02, - -8.85002052e-02, 3.06405079e-02, 1.72459681e-02, - 9.03374690e-04, -1.28881125e-02, 4.85035001e-03, - -1.68364351e-02, -6.25608141e-02, -1.25558670e-01, - -1.18386767e-01, 2.09429545e-02, 3.59976917e-02, - 3.49925348e-02, 2.24653263e-02, -2.39264368e-02, - -7.53379953e-02, -1.10654683e-01, -1.15032659e-01, - -9.41261930e-02, -2.85069079e-03, 5.22824252e-02, - 2.99480561e-02, -3.83502628e-02, -1.08366134e-01, - -1.47414857e-01, -1.24544714e-01, -1.12467213e-01, - -4.18808626e-02, -1.87576522e-02, 1.99719996e-03, - -7.16639202e-02, -1.19794062e-01, -1.12915600e-01, - -1.15217713e-01, -1.04834488e-01, -1.19802636e-01, - -2.03995614e-03, 2.12796727e-02, -2.41602152e-02, - -4.58317798e-02, -4.98793058e-02, -7.87390239e-02, - -1.21177115e-01, -1.39518490e-01, 1.11720343e-02, - -2.89920176e-03, -2.27672647e-02, -4.48420125e-02, - -1.06812926e-01, -1.27648421e-01, 1.85502371e-02, - 5.41592711e-02, 1.01568178e-02, -5.08150915e-02, - -1.17506184e-01, -1.34137663e-01, -1.62510846e-01, - -1.53074258e-01, -1.27735985e-01, -5.48175880e-02, - -2.14740857e-02, -2.03068494e-02, -5.65967212e-02, - -6.46223980e-02, -6.36516558e-02, -1.01374704e-01, - -1.47131936e-01, -1.42390983e-01, 5.92325861e-04, - 5.01438333e-02, -1.59422995e-02, -2.32997337e-02, - -5.41577092e-02, -1.39962364e-01, -1.72967770e-01, - -1.41917572e-01, -5.46970950e-02, -5.14210771e-03, - 7.99966940e-02, 3.26869876e-02, -1.09858184e-01, - -1.39479222e-01, -9.72225881e-02, -1.32840748e-01, - -1.51837935e-01, -5.23948029e-02, 3.29313396e-03, - -5.62764931e-03, -4.05753318e-02, -8.30633715e-02, - -1.40995493e-01, -1.66922836e-01, -1.37905257e-01, - -2.64451826e-02, -1.38318705e-02, -2.80115511e-02, - -2.44231760e-02, -8.51267360e-02, -1.61565614e-01, - -1.36919011e-01, -1.36429754e-01, 4.91731913e-03, - -9.21322079e-03, -4.31417314e-02, -3.72606097e-02, - -5.43990812e-02, -8.35859753e-02, -1.04743468e-01, - -8.95626391e-02, -7.41266214e-02, -1.34554806e-02, - 8.71362116e-03, -7.07675308e-03, -1.52102203e-02, - -6.97762054e-02, -1.41623034e-01, -1.32980545e-01, - -4.89909328e-02, 1.43998286e-02, -5.09041865e-02, - -5.27126995e-02, -3.96452765e-02, -1.04813653e-01, - -1.26873653e-01, -1.15806969e-01, -3.30684510e-03, - 3.59664035e-02, 4.39015008e-03, -4.12251474e-03, - -1.80469809e-02, -1.10104610e-01, -1.37542050e-01, - -1.04148345e-01, -1.25145160e-02, 1.56884735e-03, - 1.62235788e-02, -2.83018324e-02, -8.19212212e-02, - -8.54047876e-02, -8.32636308e-02, -9.05552703e-02, - -1.22030592e-01, -1.40113655e-01, 1.91012045e-02, - 2.80022134e-02, 4.64804074e-02, 2.09501603e-03, - -1.22993883e-01, -1.31186330e-01, -1.41189975e-01, - -1.66236864e-01, -2.30251680e-02, 2.74993767e-02, - 2.48102796e-02, 4.14216230e-03, -2.52994219e-02, - -8.13468198e-02, -1.13773135e-01, -1.06691188e-01, - -4.33114129e-02, -2.41679923e-02, -3.47873741e-02, - -2.37014183e-02, 1.40245196e-02, -1.98930225e-02, - -1.21214445e-01, -1.51083119e-01, -5.91557174e-02, - 1.20087089e-02, 3.85210883e-02, -2.71195013e-02, - -1.00313604e-01, -1.32336777e-01, -1.52041899e-01, - -1.55895308e-01, - 5.40869668e-01, 1.49498612e+00, 1.32343229e+00, - 1.09750661e+00, 6.45675885e-01, -1.80905096e-01, - -3.16159122e-01, -5.17686592e-01, -7.86648343e-01, - -8.97579417e-01, 8.74555217e-01, 1.27906200e+00, - 9.17995692e-01, 6.67888758e-01, 1.91924982e-01, - -5.27025382e-01, -6.61159114e-01, -6.45949069e-01, - -1.03749405e+00, 4.14788159e-01, 9.23148120e-01, - 4.05378182e-01, 4.27555338e-02, -5.52432989e-02, - -4.91367482e-01, -5.93500553e-01, -7.49073823e-01, - 6.26844529e-01, 1.18829760e+00, 1.14364889e+00, - 4.45233941e-01, -4.35510001e-02, -5.36439781e-01, - -3.38202453e-01, 5.99152311e-02, -4.09423852e-01, - -7.25633162e-01, -6.91244638e-01, 5.48352038e-01, - 1.00060447e+00, 8.94376960e-01, 4.86907350e-01, - -2.06929282e-01, -6.92438781e-01, -7.16097113e-01, - -8.17614869e-01, 2.38410456e-01, 4.50709705e-01, - 9.51887497e-01, 8.33738925e-01, 5.02280946e-01, - 1.89376859e-01, -5.23147266e-01, -7.12834870e-01, - -5.81805772e-01, 9.65762696e-01, 7.73892714e-01, - 3.73253622e-01, 3.28551194e-01, 1.78076150e-01, - -3.66786493e-01, -6.87333382e-01, -1.04497748e+00, - -8.40398958e-01, 9.50412564e-01, 1.31897498e+00, - 8.90455949e-01, 5.73266994e-01, 3.15354238e-01, - -2.71545658e-01, -5.50181306e-01, -5.17632918e-01, - -6.35613174e-01, 4.67699660e-01, 1.05375170e+00, - 5.91899232e-01, -1.13432385e-01, -3.46716899e-01, - -8.27584296e-01, -7.89046860e-01, -6.82394652e-01, - 4.77263312e-01, 6.58426306e-01, 1.01421103e+00, - 6.80355349e-01, -4.50251443e-02, -4.44983898e-01, - -7.07303086e-01, -6.96730839e-01, -8.11856949e-01, - 6.20528452e-01, 8.51198132e-01, 3.64384237e-01, - 1.18144930e-01, -1.64683294e-01, -5.74599350e-01, - -8.38750745e-01, -1.01313923e+00, 7.96141422e-01, - 5.86152039e-01, -4.00265723e-02, -4.12496025e-01, - -7.10219245e-01, -9.19072483e-01, 8.59607341e-01, - 1.17895438e+00, 7.84760431e-01, 3.54709890e-01, - -3.37998489e-01, -7.01186144e-01, -8.77389548e-01, - -1.05781905e+00, -9.70850354e-01, 1.87633573e-01, - 2.86488995e-01, 3.32850789e-01, 3.03313920e-02, - -2.80982628e-01, -4.49823101e-01, -7.78770017e-01, - -1.05038333e+00, -1.08595713e+00, 5.88315428e-01, - 9.31583109e-01, 3.97101184e-01, 2.39032238e-01, - -1.04732005e-01, -7.94033874e-01, -9.69266322e-01, - -8.42413148e-01, 4.71360832e-01, 7.56513790e-01, - 1.06495659e+00, 5.54372635e-01, -5.07922703e-01, - -8.58955703e-01, -5.71371871e-01, -7.34301269e-01, - -9.29925013e-01, 2.87620197e-01, 7.31178025e-01, - 6.50697389e-01, 2.51581068e-01, -2.37879071e-01, - -8.32082087e-01, -9.38547016e-01, -7.50971302e-01, - 2.74538551e-01, 4.07175330e-01, 1.97714925e-01, - 1.53264368e-01, -1.65283456e-01, -9.16630027e-01, - -9.43514927e-01, -8.94451270e-01, 6.10482673e-01, - 5.11681125e-01, 2.38036545e-01, 2.88838896e-01, - -1.21459069e-01, -5.46550411e-01, -6.18632576e-01, - -5.57339753e-01, 1.94089483e-01, 6.43888819e-01, - 6.42784335e-01, 2.21350359e-01, 7.78929084e-03, - -2.79382805e-01, -7.84918358e-01, -7.75429084e-01, - 3.11951052e-01, 7.37704234e-01, 3.28135211e-01, - 2.64822970e-01, 1.03279238e-01, -6.50393804e-01, - -7.72522376e-01, -6.32378374e-01, 3.81735518e-01, - 8.65521571e-01, 5.61769887e-01, 6.30230649e-01, - 4.48438254e-01, -5.39101353e-01, -7.16290704e-01, - -5.95733802e-01, 5.42819963e-01, 6.72538387e-01, - 7.36112103e-01, 2.18250804e-01, -2.52514298e-01, - -1.07604521e-01, -4.28738811e-01, -6.68070406e-01, - -7.57848949e-01, -9.12079294e-01, 8.86572915e-01, - 1.05395716e+00, 1.00240819e+00, 5.67938334e-01, - -4.34138656e-01, -7.25245874e-01, -9.30240275e-01, - -1.07555793e+00, 4.11255073e-01, 9.09062358e-01, - 9.73563886e-01, 3.84275533e-01, 2.48509052e-01, - -1.89491274e-01, -8.07146411e-01, -8.08066922e-01, - 1.69794261e-01, 3.85412482e-01, 6.05217857e-01, - 5.74458467e-01, 4.57375472e-01, 1.42318017e-01, - -6.10358773e-01, -8.01160086e-01, 5.70274433e-01, - 1.12274338e+00, 9.22396419e-01, 1.53062175e-01, - -4.45809678e-01, -7.58897273e-01, -7.84029085e-01, - -8.25641441e-01}; +// pre-saved inputs +float inputX[229 * 3] = { + 1.51120281e+00, 1.36194446e+00, 1.61312625e+00, 1.58690408e+00, 1.32373133e+00, + 1.07425133e+00, 8.02394070e-01, 6.29378573e-01, 4.35005816e-01, 4.93205246e-01, + 1.06200780e+00, 9.26704545e-01, 6.34436776e-01, 5.12154012e-01, 3.88417107e-01, + 6.12649144e-01, 1.07713427e+00, 1.07541979e+00, 8.11425303e-01, 1.45720489e+00, + 1.14820754e+00, 6.84273413e-01, 9.34918854e-01, 6.19397984e-01, 4.67314085e-01, + 7.91461222e-01, 6.99750610e-01, 1.54311610e+00, 1.21924389e+00, 7.43194652e-01, + 3.62519451e-01, 4.71780883e-01, 9.71792460e-01, 8.88699304e-01, 4.54071857e-01, + 5.02880311e-01, 3.83912392e-01, 5.45780692e-01, 1.04203159e+00, 8.50741050e-01, + 1.41111665e+00, 1.09091158e+00, 7.27334096e-01, 1.08170264e+00, 8.90309901e-01, + 4.14675687e-01, 9.61184854e-01, 1.03147000e+00, 9.70825840e-01, 6.25900612e-01, + 3.27430358e-01, 2.07226694e-01, 2.86372753e-01, 3.21928024e-01, 4.36299683e-01, + 1.01855059e+00, 9.25725535e-01, 5.57625034e-01, 6.95951355e-01, 1.99792911e-01, + -3.08895420e-01, -1.14008817e-01, 2.83036223e-01, 4.88584432e-01, 1.14042563e+00, + 1.47874593e+00, 8.38077420e-01, 5.40483538e-01, 8.41219152e-01, 7.13772252e-01, + 8.16783774e-01, 9.32215499e-01, 4.38294042e-01, 7.58422528e-01, 8.28786603e-01, + 4.56830659e-01, 4.01284325e-01, 1.09382762e+00, 9.43319134e-01, 6.59471692e-01, + 6.41635505e-01, 1.35811162e+00, 1.28872162e+00, 1.52204544e+00, 2.11533259e+00, + 1.72678980e+00, 1.01165142e+00, 6.44749147e-01, 5.05284728e-01, 5.53484047e-01, + 9.80134025e-01, 9.83556712e-01, 9.19750953e-01, 8.67798898e-01, 4.95676335e-01, + 3.01009066e-01, 5.32933344e-01, 5.41011181e-01, 1.05081837e+00, 9.40409890e-01, + 2.80026590e-01, 4.09561533e-02, 5.14300669e-01, 5.07025640e-01, 1.03733849e+00, + 9.92242809e-01, 1.04862066e+00, 1.30449816e+00, 1.24417637e+00, 9.37715766e-01, + 1.09339115e+00, 6.75838719e-01, 4.29105793e-01, 1.10882844e+00, 7.60288245e-01, + 8.13736130e-01, 8.94787698e-01, 5.38706802e-01, 2.65789662e-01, 3.27883898e-01, + 5.98142909e-01, 4.72640645e-01, 8.91383091e-01, 6.73896793e-01, 8.46630726e-01, + 7.15034263e-01, 6.51548414e-01, 8.82947850e-01, 1.10954511e+00, 8.38224271e-01, + 1.54119217e+00, 1.23472443e+00, 4.30501421e-01, 3.58350045e-01, 8.69510082e-01, + 7.76359871e-01, 5.83012790e-01, 8.67601291e-01, 8.53014644e-01, 1.22551459e+00, + 1.06951213e+00, 1.08007844e+00, 9.93194691e-01, 8.81091943e-01, 8.40211464e-01, + 1.06594058e+00, 9.18008159e-01, 8.16516979e-01, 8.30411648e-01, 7.22438187e-01, + 6.00629284e-01, 1.02310984e+00, 1.01917509e+00, 6.08587182e-01, 6.76332335e-01, + 8.60473445e-01, 9.21097632e-01, 1.01093818e+00, 1.00052097e+00, 6.29570162e-01, + 4.16585415e-01, 6.23429195e-01, 4.89664157e-01, 1.40814604e+00, 1.18699734e+00, + 8.52996832e-01, 4.44797579e-01, 2.39917608e-01, 6.18409448e-01, 9.21789861e-01, + 8.06761526e-01, 1.21172323e+00, 9.13011650e-01, 1.26516812e+00, 1.19539464e+00, + 7.52316426e-01, 5.75879059e-01, 7.19668392e-01, 7.68234535e-01, 6.33714693e-01, + 7.85323820e-01, 7.93833503e-01, 1.02619782e+00, 9.56737352e-01, 8.25493242e-01, + 9.65633284e-01, 6.49548970e-01, 1.01823318e+00, 1.00562630e+00, 8.83237663e-01, + 7.58214202e-01, 8.41575974e-01, 1.11554021e+00, 5.92033184e-01, 3.35099375e-01, + 6.69525697e-01, 7.04578221e-01, 1.07034331e+00, 1.19305651e+00, 8.37189956e-01, + 8.37676286e-01, 1.17931865e+00, 8.56658788e-01, 6.92921445e-01, 8.45998841e-01, + 9.74460305e-01, 9.78870568e-01, 1.11788221e+00, 5.25942392e-01, 7.59510958e-01, + 9.29405965e-01, 4.70311282e-01, 3.62745715e-01, 9.09054814e-01, 9.52045725e-01, + 1.44758241e+00, 1.23433700e+00, 4.89668060e-01, 5.15972684e-01, 8.82986706e-01, + 1.03874095e+00, 1.75938726e+00, 1.53805514e+00, 8.34061594e-01, 6.40737257e-01, + 8.21486389e-01, 8.22409159e-01, 1.07932736e+00, 1.07341242e+00, -4.56006193e-02, + 6.17578891e-02, 2.74879318e-02, 6.17359478e-03, -2.23948504e-02, -9.01332267e-02, + -8.58045120e-02, -9.48352707e-02, -1.09325286e-01, -1.24532311e-01, 1.84304537e-02, + 6.87509700e-02, 5.13892169e-02, 3.40147295e-02, -6.31939287e-03, -9.46725688e-02, + -1.39352387e-01, -1.37685290e-01, -1.60044633e-01, -5.48693657e-02, 1.76405110e-02, + -4.26615372e-03, -5.80056311e-02, -4.69608236e-02, -8.13368270e-02, -1.13387618e-01, + -1.23151147e-01, -3.89528580e-02, 3.99693721e-02, 6.71696126e-02, 2.12673913e-02, + -3.59193756e-02, -1.19592821e-01, -9.38124079e-02, -2.41755983e-02, -7.53442895e-02, + -9.96879921e-02, -1.06975996e-01, -1.35374132e-02, 4.53922533e-02, -2.83580097e-03, + -2.30708909e-02, -6.96463570e-02, -1.42850344e-01, -1.32497311e-01, -1.11130246e-01, + -3.97844151e-02, -2.28006665e-02, 3.24078702e-02, 4.33573119e-02, 2.94319116e-02, + 5.50806247e-03, -7.25101086e-02, -9.42463724e-02, -8.85002052e-02, 3.06405079e-02, + 1.72459681e-02, 9.03374690e-04, -1.28881125e-02, 4.85035001e-03, -1.68364351e-02, + -6.25608141e-02, -1.25558670e-01, -1.18386767e-01, 2.09429545e-02, 3.59976917e-02, + 3.49925348e-02, 2.24653263e-02, -2.39264368e-02, -7.53379953e-02, -1.10654683e-01, + -1.15032659e-01, -9.41261930e-02, -2.85069079e-03, 5.22824252e-02, 2.99480561e-02, + -3.83502628e-02, -1.08366134e-01, -1.47414857e-01, -1.24544714e-01, -1.12467213e-01, + -4.18808626e-02, -1.87576522e-02, 1.99719996e-03, -7.16639202e-02, -1.19794062e-01, + -1.12915600e-01, -1.15217713e-01, -1.04834488e-01, -1.19802636e-01, -2.03995614e-03, + 2.12796727e-02, -2.41602152e-02, -4.58317798e-02, -4.98793058e-02, -7.87390239e-02, + -1.21177115e-01, -1.39518490e-01, 1.11720343e-02, -2.89920176e-03, -2.27672647e-02, + -4.48420125e-02, -1.06812926e-01, -1.27648421e-01, 1.85502371e-02, 5.41592711e-02, + 1.01568178e-02, -5.08150915e-02, -1.17506184e-01, -1.34137663e-01, -1.62510846e-01, + -1.53074258e-01, -1.27735985e-01, -5.48175880e-02, -2.14740857e-02, -2.03068494e-02, + -5.65967212e-02, -6.46223980e-02, -6.36516558e-02, -1.01374704e-01, -1.47131936e-01, + -1.42390983e-01, 5.92325861e-04, 5.01438333e-02, -1.59422995e-02, -2.32997337e-02, + -5.41577092e-02, -1.39962364e-01, -1.72967770e-01, -1.41917572e-01, -5.46970950e-02, + -5.14210771e-03, 7.99966940e-02, 3.26869876e-02, -1.09858184e-01, -1.39479222e-01, + -9.72225881e-02, -1.32840748e-01, -1.51837935e-01, -5.23948029e-02, 3.29313396e-03, + -5.62764931e-03, -4.05753318e-02, -8.30633715e-02, -1.40995493e-01, -1.66922836e-01, + -1.37905257e-01, -2.64451826e-02, -1.38318705e-02, -2.80115511e-02, -2.44231760e-02, + -8.51267360e-02, -1.61565614e-01, -1.36919011e-01, -1.36429754e-01, 4.91731913e-03, + -9.21322079e-03, -4.31417314e-02, -3.72606097e-02, -5.43990812e-02, -8.35859753e-02, + -1.04743468e-01, -8.95626391e-02, -7.41266214e-02, -1.34554806e-02, 8.71362116e-03, + -7.07675308e-03, -1.52102203e-02, -6.97762054e-02, -1.41623034e-01, -1.32980545e-01, + -4.89909328e-02, 1.43998286e-02, -5.09041865e-02, -5.27126995e-02, -3.96452765e-02, + -1.04813653e-01, -1.26873653e-01, -1.15806969e-01, -3.30684510e-03, 3.59664035e-02, + 4.39015008e-03, -4.12251474e-03, -1.80469809e-02, -1.10104610e-01, -1.37542050e-01, + -1.04148345e-01, -1.25145160e-02, 1.56884735e-03, 1.62235788e-02, -2.83018324e-02, + -8.19212212e-02, -8.54047876e-02, -8.32636308e-02, -9.05552703e-02, -1.22030592e-01, + -1.40113655e-01, 1.91012045e-02, 2.80022134e-02, 4.64804074e-02, 2.09501603e-03, + -1.22993883e-01, -1.31186330e-01, -1.41189975e-01, -1.66236864e-01, -2.30251680e-02, + 2.74993767e-02, 2.48102796e-02, 4.14216230e-03, -2.52994219e-02, -8.13468198e-02, + -1.13773135e-01, -1.06691188e-01, -4.33114129e-02, -2.41679923e-02, -3.47873741e-02, + -2.37014183e-02, 1.40245196e-02, -1.98930225e-02, -1.21214445e-01, -1.51083119e-01, + -5.91557174e-02, 1.20087089e-02, 3.85210883e-02, -2.71195013e-02, -1.00313604e-01, + -1.32336777e-01, -1.52041899e-01, -1.55895308e-01, 5.40869668e-01, 1.49498612e+00, + 1.32343229e+00, 1.09750661e+00, 6.45675885e-01, -1.80905096e-01, -3.16159122e-01, + -5.17686592e-01, -7.86648343e-01, -8.97579417e-01, 8.74555217e-01, 1.27906200e+00, + 9.17995692e-01, 6.67888758e-01, 1.91924982e-01, -5.27025382e-01, -6.61159114e-01, + -6.45949069e-01, -1.03749405e+00, 4.14788159e-01, 9.23148120e-01, 4.05378182e-01, + 4.27555338e-02, -5.52432989e-02, -4.91367482e-01, -5.93500553e-01, -7.49073823e-01, + 6.26844529e-01, 1.18829760e+00, 1.14364889e+00, 4.45233941e-01, -4.35510001e-02, + -5.36439781e-01, -3.38202453e-01, 5.99152311e-02, -4.09423852e-01, -7.25633162e-01, + -6.91244638e-01, 5.48352038e-01, 1.00060447e+00, 8.94376960e-01, 4.86907350e-01, + -2.06929282e-01, -6.92438781e-01, -7.16097113e-01, -8.17614869e-01, 2.38410456e-01, + 4.50709705e-01, 9.51887497e-01, 8.33738925e-01, 5.02280946e-01, 1.89376859e-01, + -5.23147266e-01, -7.12834870e-01, -5.81805772e-01, 9.65762696e-01, 7.73892714e-01, + 3.73253622e-01, 3.28551194e-01, 1.78076150e-01, -3.66786493e-01, -6.87333382e-01, + -1.04497748e+00, -8.40398958e-01, 9.50412564e-01, 1.31897498e+00, 8.90455949e-01, + 5.73266994e-01, 3.15354238e-01, -2.71545658e-01, -5.50181306e-01, -5.17632918e-01, + -6.35613174e-01, 4.67699660e-01, 1.05375170e+00, 5.91899232e-01, -1.13432385e-01, + -3.46716899e-01, -8.27584296e-01, -7.89046860e-01, -6.82394652e-01, 4.77263312e-01, + 6.58426306e-01, 1.01421103e+00, 6.80355349e-01, -4.50251443e-02, -4.44983898e-01, + -7.07303086e-01, -6.96730839e-01, -8.11856949e-01, 6.20528452e-01, 8.51198132e-01, + 3.64384237e-01, 1.18144930e-01, -1.64683294e-01, -5.74599350e-01, -8.38750745e-01, + -1.01313923e+00, 7.96141422e-01, 5.86152039e-01, -4.00265723e-02, -4.12496025e-01, + -7.10219245e-01, -9.19072483e-01, 8.59607341e-01, 1.17895438e+00, 7.84760431e-01, + 3.54709890e-01, -3.37998489e-01, -7.01186144e-01, -8.77389548e-01, -1.05781905e+00, + -9.70850354e-01, 1.87633573e-01, 2.86488995e-01, 3.32850789e-01, 3.03313920e-02, + -2.80982628e-01, -4.49823101e-01, -7.78770017e-01, -1.05038333e+00, -1.08595713e+00, + 5.88315428e-01, 9.31583109e-01, 3.97101184e-01, 2.39032238e-01, -1.04732005e-01, + -7.94033874e-01, -9.69266322e-01, -8.42413148e-01, 4.71360832e-01, 7.56513790e-01, + 1.06495659e+00, 5.54372635e-01, -5.07922703e-01, -8.58955703e-01, -5.71371871e-01, + -7.34301269e-01, -9.29925013e-01, 2.87620197e-01, 7.31178025e-01, 6.50697389e-01, + 2.51581068e-01, -2.37879071e-01, -8.32082087e-01, -9.38547016e-01, -7.50971302e-01, + 2.74538551e-01, 4.07175330e-01, 1.97714925e-01, 1.53264368e-01, -1.65283456e-01, + -9.16630027e-01, -9.43514927e-01, -8.94451270e-01, 6.10482673e-01, 5.11681125e-01, + 2.38036545e-01, 2.88838896e-01, -1.21459069e-01, -5.46550411e-01, -6.18632576e-01, + -5.57339753e-01, 1.94089483e-01, 6.43888819e-01, 6.42784335e-01, 2.21350359e-01, + 7.78929084e-03, -2.79382805e-01, -7.84918358e-01, -7.75429084e-01, 3.11951052e-01, + 7.37704234e-01, 3.28135211e-01, 2.64822970e-01, 1.03279238e-01, -6.50393804e-01, + -7.72522376e-01, -6.32378374e-01, 3.81735518e-01, 8.65521571e-01, 5.61769887e-01, + 6.30230649e-01, 4.48438254e-01, -5.39101353e-01, -7.16290704e-01, -5.95733802e-01, + 5.42819963e-01, 6.72538387e-01, 7.36112103e-01, 2.18250804e-01, -2.52514298e-01, + -1.07604521e-01, -4.28738811e-01, -6.68070406e-01, -7.57848949e-01, -9.12079294e-01, + 8.86572915e-01, 1.05395716e+00, 1.00240819e+00, 5.67938334e-01, -4.34138656e-01, + -7.25245874e-01, -9.30240275e-01, -1.07555793e+00, 4.11255073e-01, 9.09062358e-01, + 9.73563886e-01, 3.84275533e-01, 2.48509052e-01, -1.89491274e-01, -8.07146411e-01, + -8.08066922e-01, 1.69794261e-01, 3.85412482e-01, 6.05217857e-01, 5.74458467e-01, + 4.57375472e-01, 1.42318017e-01, -6.10358773e-01, -8.01160086e-01, 5.70274433e-01, + 1.12274338e+00, 9.22396419e-01, 1.53062175e-01, -4.45809678e-01, -7.58897273e-01, + -7.84029085e-01, -8.25641441e-01}; - float inputY[177*3] = {6.72627056e-01, 1.15215940e+00, 1.26133188e+00, - 1.03926143e+00, 6.69471981e-01, 2.86739218e-01, - 7.97118828e-02, 6.25216534e-02, 7.27962929e-02, - 6.06863800e-01, 9.07325017e-01, 8.17160253e-01, - 6.42560918e-01, 6.13720682e-01, 5.55894742e-01, - 3.06250586e-01, 9.42240879e-02, 1.14860784e-01, - 1.46597026e-01, 5.37887505e-02, 7.95424459e-01, - 1.09991851e+00, 1.05607977e+00, 7.34281050e-01, - 5.51383869e-01, 4.93172896e-01, 2.16817664e-01, - -3.44049948e-02, -1.12275706e-01, 1.06670605e+00, - 1.61324796e+00, 1.39111547e+00, 6.28650320e-01, - 1.28246316e-01, 4.77769435e-02, 2.93244898e-02, - -1.95407143e-02, -2.84829409e-02, 5.80357284e-01, - 1.13767723e+00, 1.29169850e+00, 8.21477202e-01, - 4.12533011e-01, 3.96345158e-01, 4.16216096e-01, - 2.20823661e-01, 1.80966938e-03, 1.46324725e-01, - 5.77625692e-01, 1.27408737e+00, 1.60142562e+00, - 1.27556382e+00, 6.40444807e-01, 5.06182121e-02, - -1.51261027e-01, -8.59675180e-02, 1.00560926e+00, - 1.45819710e+00, 1.34885700e+00, 8.59588359e-01, - 2.96212323e-01, -8.88367997e-02, -1.85995627e-01, - -6.75487786e-02, 1.16589455e+00, 1.56360293e+00, - 1.36520189e+00, 7.95497934e-01, 1.04566338e-01, - -1.93481979e-01, -1.09909015e-01, -2.10671441e-03, - 1.27338566e+00, 1.74028739e+00, 1.23715331e+00, - 6.25294537e-01, 3.39160685e-01, 1.87771210e-01, - 6.46105379e-02, 8.61382871e-01, 1.15895000e+00, - 1.20580628e+00, 1.04195045e+00, 5.36684279e-01, - 7.27011981e-02, -2.55125254e-02, 2.01436646e-02, - 7.80878674e-01, 1.06780232e+00, 1.04868227e+00, - 8.35316907e-01, 6.39974154e-01, 4.64459638e-01, - 1.65867218e-01, 3.40941159e-02, 7.04609207e-01, - 1.06865641e+00, 1.05507003e+00, 9.28564181e-01, - 8.05337648e-01, 5.03009198e-01, 1.75321450e-01, - 5.67295094e-03, 1.49232863e-02, 5.43436937e-01, - 1.15235436e+00, 1.67352530e+00, 1.52125445e+00, - 8.81241613e-01, 1.50786852e-01, -5.03902739e-02, - 1.64457512e-01, 9.72215636e-01, 1.28083555e+00, - 1.03216298e+00, 6.03713399e-01, 4.79213588e-01, - 3.51295656e-01, 1.07750479e-01, 3.85669759e-02, - 5.25723185e-01, 1.01161423e+00, 1.30942611e+00, - 9.99592908e-01, 6.13815801e-01, 2.52563454e-01, - 4.29922074e-02, 4.39238415e-02, 6.74477255e-01, - 1.06886010e+00, 1.12801321e+00, 8.63440139e-01, - 5.52385103e-01, 2.99290500e-01, 3.88777957e-02, - 9.51386231e-02, 2.00186927e-01, 6.72780758e-01, - 1.26631429e+00, 1.51707019e+00, 1.06149439e+00, - 4.41678872e-01, 9.69401895e-02, -1.12514563e-01, - -1.36401109e-01, -2.36885591e-02, 8.60562569e-01, - 1.15911633e+00, 1.16576111e+00, 7.62400183e-01, - 2.76009568e-01, 2.81602963e-01, 1.45604564e-01, - -6.58073308e-02, 7.97702828e-01, 1.08526832e+00, - 1.10315886e+00, 9.90231311e-01, 7.55266483e-01, - 3.09795369e-01, 9.18225171e-02, 1.47032928e-01, - 1.02967528e+00, 1.47570579e+00, 1.24550916e+00, - 5.90302383e-01, 4.77998886e-02, 3.23521397e-02, - 9.88247362e-02, 6.51701265e-01, 1.03579992e+00, - 1.25333100e+00, 1.12108717e+00, 6.97954362e-01, - 3.79107058e-01, 1.76541250e-01, -2.19222391e-02, - 3.69826234e-02, 1.19119133e-01, 1.41772359e-01, - -1.38062725e-01, -3.40943350e-01, -2.04505737e-01, - -1.08727196e-01, -1.96070999e-02, 1.08099000e-01, - 9.24637637e-02, 1.44802465e-01, 1.56276642e-01, - 7.22695627e-03, -1.85895311e-02, -6.87998425e-03, - -1.76437465e-01, -2.02196315e-01, -4.03664102e-02, - 7.17329777e-02, 8.51139218e-02, -5.00716464e-02, - 1.91582157e-02, 1.57635014e-01, -7.06803390e-02, - -1.76039969e-01, 2.97078018e-02, 8.92895660e-02, - 1.75576126e-02, 4.46752427e-03, 4.05612685e-02, - 1.60113585e-01, 1.43755896e-01, -3.50178553e-01, - -5.45858366e-01, -1.72507255e-01, 9.84828117e-02, - 8.83423794e-02, 7.06939587e-02, -4.62535874e-01, - -3.55028644e-01, -2.24629412e-02, -1.87262404e-01, - -2.19745085e-01, 1.09935539e-01, 3.39313358e-01, - 2.70167726e-01, 1.69525018e-01, -3.64138454e-01, - -3.95789820e-01, 4.42597532e-02, 3.52360115e-01, - 1.51691007e-01, -5.37033181e-02, -7.50426111e-02, - 6.33963934e-02, 1.18603696e-01, 1.83002834e-01, - 4.52440515e-02, -7.66694087e-02, -2.71236768e-01, - -3.23490988e-01, -2.36814414e-01, -1.04198585e-01, - 4.42778897e-02, 3.46311834e-01, 6.13127395e-02, - -1.61421143e-01, -2.51493707e-01, -3.11870789e-01, - -1.41476337e-01, 7.77108219e-02, 9.45970584e-02, - 1.46627910e-02, 3.18033866e-02, -2.90909806e-01, - -5.22313572e-01, -1.63375447e-01, 2.95181046e-01, - 2.93939388e-01, -1.32420884e-01, -3.16485442e-01, - -1.94282835e-01, 9.99080854e-02, 1.86332787e-01, - 6.30315868e-02, 7.33264056e-02, 9.50710745e-02, - -1.41926397e-01, -2.49872816e-01, -2.14032294e-01, - -1.75150351e-01, 5.81841766e-02, 2.97691394e-01, - 1.94150002e-01, 9.62950893e-02, -1.40590121e-01, - -9.25513357e-02, -6.89795939e-02, -2.16795100e-01, - -9.29064623e-02, 1.22844210e-01, 1.69975948e-01, - 1.07148867e-01, 9.48304027e-02, -7.74917305e-01, - -7.50890482e-01, -1.08152516e-03, 3.84514866e-01, - 4.90289337e-01, 3.11460219e-01, 1.51941642e-01, - 3.77258994e-01, -1.12334433e-01, -3.29402626e-01, - -3.22065484e-01, -3.09468587e-01, -1.18515053e-01, - 1.20509801e-01, 9.51154181e-02, 6.68281091e-02, - -7.29188671e-01, -4.20698102e-01, 5.57457503e-02, - 3.69927823e-02, 2.61042412e-03, 1.24423731e-01, - 1.55613237e-01, 7.75618996e-02, -8.71903455e-02, - -1.32566013e-01, -1.25094390e-01, -2.79594396e-01, - -2.71398995e-01, -6.32828080e-02, 2.80746528e-02, - 1.66658971e-01, 3.17497470e-01, -3.30384836e-01, - -1.46317528e-01, 2.50897986e-01, 1.29118198e-01, - -1.80109579e-01, -1.75369396e-01, -3.65201242e-03, - 5.60400564e-02, 9.31352935e-02, -4.96950146e-01, - -7.03482276e-01, -3.64952676e-01, -1.55661264e-01, - 5.83734613e-02, 5.74772645e-01, 5.33480925e-01, - 2.18900211e-01, 5.01155500e-02, -3.22798807e-01, - -4.12369566e-01, -1.76224875e-01, 2.65592962e-02, - -8.30913302e-02, -3.13541397e-02, 1.93290913e-01, - -5.18922713e-01, -5.15449056e-01, -4.05494447e-02, - 1.57311902e-01, 6.63999906e-02, 8.34236682e-02, - 1.73567769e-01, -3.66158984e-01, -4.22703631e-01, - -1.90572209e-01, 2.36499076e-02, 2.23505587e-01, - 3.04306594e-01, 1.99562284e-01, 4.89746500e-02, - -9.02181788e-17, -1.56858856e-16, -1.72195174e-16, - -1.31267156e-16, -7.40678875e-17, -2.92891456e-17, - -5.98245477e-18, -7.42648175e-18, -1.40979143e-17, - -8.38578843e-17, -1.25649422e-16, -1.14239900e-16, - -8.50154612e-17, -8.01383666e-17, -7.30021612e-17, - -3.30300810e-17, -4.00429538e-18, -1.34625397e-17, - -2.23136881e-17, -1.06350331e-17, -1.02783302e-16, - -1.45809760e-16, -1.45795360e-16, -9.38642075e-17, - -6.53647532e-17, -6.62562494e-17, -3.23024455e-17, - 3.80493710e-18, 1.46163170e-17, -1.42322144e-16, - -2.19355040e-16, -1.89388292e-16, -6.83015086e-17, - 5.81805570e-18, 8.83193541e-19, -7.96628164e-18, - -1.10176246e-18, 8.11934726e-19, -5.72567906e-17, - -1.35209174e-16, -1.69361011e-16, -1.00506356e-16, - -4.52392061e-17, -5.68307292e-17, -6.90002636e-17, - -4.03611583e-17, -7.29648164e-18, -4.13099457e-18, - -5.96755231e-17, -1.69817067e-16, -2.25800263e-16, - -1.74484445e-16, -8.21997430e-17, -3.54917737e-18, - 1.73026950e-17, 6.39599948e-18, -1.40197527e-16, - -1.94130887e-16, -1.74639931e-16, -1.02034757e-16, - -2.55843139e-17, 2.15715340e-17, 2.88596120e-17, - 7.06212489e-18, -1.68128480e-16, -2.08696477e-16, - -1.73266325e-16, -9.44071106e-17, -8.01689846e-19, - 3.13986033e-17, 1.12549300e-17, -3.66064662e-18, - -1.68492334e-16, -2.30761803e-16, -1.50993482e-16, - -6.06925258e-17, -3.79127308e-17, -3.70449453e-17, - -2.07558731e-17, -1.08050716e-16, -1.39618437e-16, - -1.50883627e-16, -1.41529199e-16, -7.85135708e-17, - -1.22090691e-17, 3.10720543e-19, -6.61384887e-18, - -9.70413778e-17, -1.30374927e-16, -1.29346320e-16, - -1.02835234e-16, -8.67959453e-17, -7.36277809e-17, - -2.99508831e-17, -8.50402205e-18, -8.70417224e-17, - -1.37037353e-16, -1.36227509e-16, -1.13395049e-16, - -1.02306889e-16, -7.14306393e-17, -3.01908723e-17, - -5.20888382e-18, -5.91557953e-18, -3.93837600e-17, - -1.20663132e-16, -2.20590848e-16, -2.16569288e-16, - -1.36594393e-16, -3.28467218e-17, 3.17560937e-19, - -3.73884722e-17, -1.23499062e-16, -1.55149919e-16, - -1.22670650e-16, -6.67087431e-17, -5.82448523e-17, - -5.13316908e-17, -1.81656885e-17, -7.86690988e-18, - -3.89522337e-17, -1.15855115e-16, -1.74954292e-16, - -1.33325448e-16, -8.10335324e-17, -3.84778877e-17, - -1.21467514e-17, -9.02003740e-18, -8.52923688e-17, - -1.35398261e-16, -1.43508015e-16, -1.02194616e-16, - -6.15266379e-17, -3.68234794e-17, -6.29445132e-18, - -1.94815529e-17, -3.96109287e-17, -7.49436998e-17, - -1.60857899e-16, -2.10454719e-16, -1.45321968e-16, - -5.07319263e-17, -5.47927830e-18, 1.49858513e-17, - 1.56498476e-17, -7.54459958e-19, -9.27659888e-17, - -1.23528386e-16, -1.38498554e-16, -9.40333637e-17, - -3.88191046e-17, -6.10559670e-17, -4.14069630e-17, - -4.37580381e-19, -1.07254809e-16, -1.29641473e-16, - -1.28271011e-16, -1.23214256e-16, -1.00679319e-16, - -3.73837353e-17, -1.08004091e-17, -2.74320227e-17, - -1.14146845e-16, -1.73095674e-16, -1.62518453e-16, - -8.43742901e-17, -9.06634370e-18, -7.73848113e-18, - -2.02551628e-17, -7.06752027e-17, -1.18960235e-16, - -1.57303724e-16, -1.48787619e-16, -1.01322883e-16, - -6.26503964e-17, -3.15834682e-17, 8.51226330e-19}; +float inputY[177 * 3] = { + 6.72627056e-01, 1.15215940e+00, 1.26133188e+00, 1.03926143e+00, 6.69471981e-01, + 2.86739218e-01, 7.97118828e-02, 6.25216534e-02, 7.27962929e-02, 6.06863800e-01, + 9.07325017e-01, 8.17160253e-01, 6.42560918e-01, 6.13720682e-01, 5.55894742e-01, + 3.06250586e-01, 9.42240879e-02, 1.14860784e-01, 1.46597026e-01, 5.37887505e-02, + 7.95424459e-01, 1.09991851e+00, 1.05607977e+00, 7.34281050e-01, 5.51383869e-01, + 4.93172896e-01, 2.16817664e-01, -3.44049948e-02, -1.12275706e-01, 1.06670605e+00, + 1.61324796e+00, 1.39111547e+00, 6.28650320e-01, 1.28246316e-01, 4.77769435e-02, + 2.93244898e-02, -1.95407143e-02, -2.84829409e-02, 5.80357284e-01, 1.13767723e+00, + 1.29169850e+00, 8.21477202e-01, 4.12533011e-01, 3.96345158e-01, 4.16216096e-01, + 2.20823661e-01, 1.80966938e-03, 1.46324725e-01, 5.77625692e-01, 1.27408737e+00, + 1.60142562e+00, 1.27556382e+00, 6.40444807e-01, 5.06182121e-02, -1.51261027e-01, + -8.59675180e-02, 1.00560926e+00, 1.45819710e+00, 1.34885700e+00, 8.59588359e-01, + 2.96212323e-01, -8.88367997e-02, -1.85995627e-01, -6.75487786e-02, 1.16589455e+00, + 1.56360293e+00, 1.36520189e+00, 7.95497934e-01, 1.04566338e-01, -1.93481979e-01, + -1.09909015e-01, -2.10671441e-03, 1.27338566e+00, 1.74028739e+00, 1.23715331e+00, + 6.25294537e-01, 3.39160685e-01, 1.87771210e-01, 6.46105379e-02, 8.61382871e-01, + 1.15895000e+00, 1.20580628e+00, 1.04195045e+00, 5.36684279e-01, 7.27011981e-02, + -2.55125254e-02, 2.01436646e-02, 7.80878674e-01, 1.06780232e+00, 1.04868227e+00, + 8.35316907e-01, 6.39974154e-01, 4.64459638e-01, 1.65867218e-01, 3.40941159e-02, + 7.04609207e-01, 1.06865641e+00, 1.05507003e+00, 9.28564181e-01, 8.05337648e-01, + 5.03009198e-01, 1.75321450e-01, 5.67295094e-03, 1.49232863e-02, 5.43436937e-01, + 1.15235436e+00, 1.67352530e+00, 1.52125445e+00, 8.81241613e-01, 1.50786852e-01, + -5.03902739e-02, 1.64457512e-01, 9.72215636e-01, 1.28083555e+00, 1.03216298e+00, + 6.03713399e-01, 4.79213588e-01, 3.51295656e-01, 1.07750479e-01, 3.85669759e-02, + 5.25723185e-01, 1.01161423e+00, 1.30942611e+00, 9.99592908e-01, 6.13815801e-01, + 2.52563454e-01, 4.29922074e-02, 4.39238415e-02, 6.74477255e-01, 1.06886010e+00, + 1.12801321e+00, 8.63440139e-01, 5.52385103e-01, 2.99290500e-01, 3.88777957e-02, + 9.51386231e-02, 2.00186927e-01, 6.72780758e-01, 1.26631429e+00, 1.51707019e+00, + 1.06149439e+00, 4.41678872e-01, 9.69401895e-02, -1.12514563e-01, -1.36401109e-01, + -2.36885591e-02, 8.60562569e-01, 1.15911633e+00, 1.16576111e+00, 7.62400183e-01, + 2.76009568e-01, 2.81602963e-01, 1.45604564e-01, -6.58073308e-02, 7.97702828e-01, + 1.08526832e+00, 1.10315886e+00, 9.90231311e-01, 7.55266483e-01, 3.09795369e-01, + 9.18225171e-02, 1.47032928e-01, 1.02967528e+00, 1.47570579e+00, 1.24550916e+00, + 5.90302383e-01, 4.77998886e-02, 3.23521397e-02, 9.88247362e-02, 6.51701265e-01, + 1.03579992e+00, 1.25333100e+00, 1.12108717e+00, 6.97954362e-01, 3.79107058e-01, + 1.76541250e-01, -2.19222391e-02, 3.69826234e-02, 1.19119133e-01, 1.41772359e-01, + -1.38062725e-01, -3.40943350e-01, -2.04505737e-01, -1.08727196e-01, -1.96070999e-02, + 1.08099000e-01, 9.24637637e-02, 1.44802465e-01, 1.56276642e-01, 7.22695627e-03, + -1.85895311e-02, -6.87998425e-03, -1.76437465e-01, -2.02196315e-01, -4.03664102e-02, + 7.17329777e-02, 8.51139218e-02, -5.00716464e-02, 1.91582157e-02, 1.57635014e-01, + -7.06803390e-02, -1.76039969e-01, 2.97078018e-02, 8.92895660e-02, 1.75576126e-02, + 4.46752427e-03, 4.05612685e-02, 1.60113585e-01, 1.43755896e-01, -3.50178553e-01, + -5.45858366e-01, -1.72507255e-01, 9.84828117e-02, 8.83423794e-02, 7.06939587e-02, + -4.62535874e-01, -3.55028644e-01, -2.24629412e-02, -1.87262404e-01, -2.19745085e-01, + 1.09935539e-01, 3.39313358e-01, 2.70167726e-01, 1.69525018e-01, -3.64138454e-01, + -3.95789820e-01, 4.42597532e-02, 3.52360115e-01, 1.51691007e-01, -5.37033181e-02, + -7.50426111e-02, 6.33963934e-02, 1.18603696e-01, 1.83002834e-01, 4.52440515e-02, + -7.66694087e-02, -2.71236768e-01, -3.23490988e-01, -2.36814414e-01, -1.04198585e-01, + 4.42778897e-02, 3.46311834e-01, 6.13127395e-02, -1.61421143e-01, -2.51493707e-01, + -3.11870789e-01, -1.41476337e-01, 7.77108219e-02, 9.45970584e-02, 1.46627910e-02, + 3.18033866e-02, -2.90909806e-01, -5.22313572e-01, -1.63375447e-01, 2.95181046e-01, + 2.93939388e-01, -1.32420884e-01, -3.16485442e-01, -1.94282835e-01, 9.99080854e-02, + 1.86332787e-01, 6.30315868e-02, 7.33264056e-02, 9.50710745e-02, -1.41926397e-01, + -2.49872816e-01, -2.14032294e-01, -1.75150351e-01, 5.81841766e-02, 2.97691394e-01, + 1.94150002e-01, 9.62950893e-02, -1.40590121e-01, -9.25513357e-02, -6.89795939e-02, + -2.16795100e-01, -9.29064623e-02, 1.22844210e-01, 1.69975948e-01, 1.07148867e-01, + 9.48304027e-02, -7.74917305e-01, -7.50890482e-01, -1.08152516e-03, 3.84514866e-01, + 4.90289337e-01, 3.11460219e-01, 1.51941642e-01, 3.77258994e-01, -1.12334433e-01, + -3.29402626e-01, -3.22065484e-01, -3.09468587e-01, -1.18515053e-01, 1.20509801e-01, + 9.51154181e-02, 6.68281091e-02, -7.29188671e-01, -4.20698102e-01, 5.57457503e-02, + 3.69927823e-02, 2.61042412e-03, 1.24423731e-01, 1.55613237e-01, 7.75618996e-02, + -8.71903455e-02, -1.32566013e-01, -1.25094390e-01, -2.79594396e-01, -2.71398995e-01, + -6.32828080e-02, 2.80746528e-02, 1.66658971e-01, 3.17497470e-01, -3.30384836e-01, + -1.46317528e-01, 2.50897986e-01, 1.29118198e-01, -1.80109579e-01, -1.75369396e-01, + -3.65201242e-03, 5.60400564e-02, 9.31352935e-02, -4.96950146e-01, -7.03482276e-01, + -3.64952676e-01, -1.55661264e-01, 5.83734613e-02, 5.74772645e-01, 5.33480925e-01, + 2.18900211e-01, 5.01155500e-02, -3.22798807e-01, -4.12369566e-01, -1.76224875e-01, + 2.65592962e-02, -8.30913302e-02, -3.13541397e-02, 1.93290913e-01, -5.18922713e-01, + -5.15449056e-01, -4.05494447e-02, 1.57311902e-01, 6.63999906e-02, 8.34236682e-02, + 1.73567769e-01, -3.66158984e-01, -4.22703631e-01, -1.90572209e-01, 2.36499076e-02, + 2.23505587e-01, 3.04306594e-01, 1.99562284e-01, 4.89746500e-02, -9.02181788e-17, + -1.56858856e-16, -1.72195174e-16, -1.31267156e-16, -7.40678875e-17, -2.92891456e-17, + -5.98245477e-18, -7.42648175e-18, -1.40979143e-17, -8.38578843e-17, -1.25649422e-16, + -1.14239900e-16, -8.50154612e-17, -8.01383666e-17, -7.30021612e-17, -3.30300810e-17, + -4.00429538e-18, -1.34625397e-17, -2.23136881e-17, -1.06350331e-17, -1.02783302e-16, + -1.45809760e-16, -1.45795360e-16, -9.38642075e-17, -6.53647532e-17, -6.62562494e-17, + -3.23024455e-17, 3.80493710e-18, 1.46163170e-17, -1.42322144e-16, -2.19355040e-16, + -1.89388292e-16, -6.83015086e-17, 5.81805570e-18, 8.83193541e-19, -7.96628164e-18, + -1.10176246e-18, 8.11934726e-19, -5.72567906e-17, -1.35209174e-16, -1.69361011e-16, + -1.00506356e-16, -4.52392061e-17, -5.68307292e-17, -6.90002636e-17, -4.03611583e-17, + -7.29648164e-18, -4.13099457e-18, -5.96755231e-17, -1.69817067e-16, -2.25800263e-16, + -1.74484445e-16, -8.21997430e-17, -3.54917737e-18, 1.73026950e-17, 6.39599948e-18, + -1.40197527e-16, -1.94130887e-16, -1.74639931e-16, -1.02034757e-16, -2.55843139e-17, + 2.15715340e-17, 2.88596120e-17, 7.06212489e-18, -1.68128480e-16, -2.08696477e-16, + -1.73266325e-16, -9.44071106e-17, -8.01689846e-19, 3.13986033e-17, 1.12549300e-17, + -3.66064662e-18, -1.68492334e-16, -2.30761803e-16, -1.50993482e-16, -6.06925258e-17, + -3.79127308e-17, -3.70449453e-17, -2.07558731e-17, -1.08050716e-16, -1.39618437e-16, + -1.50883627e-16, -1.41529199e-16, -7.85135708e-17, -1.22090691e-17, 3.10720543e-19, + -6.61384887e-18, -9.70413778e-17, -1.30374927e-16, -1.29346320e-16, -1.02835234e-16, + -8.67959453e-17, -7.36277809e-17, -2.99508831e-17, -8.50402205e-18, -8.70417224e-17, + -1.37037353e-16, -1.36227509e-16, -1.13395049e-16, -1.02306889e-16, -7.14306393e-17, + -3.01908723e-17, -5.20888382e-18, -5.91557953e-18, -3.93837600e-17, -1.20663132e-16, + -2.20590848e-16, -2.16569288e-16, -1.36594393e-16, -3.28467218e-17, 3.17560937e-19, + -3.73884722e-17, -1.23499062e-16, -1.55149919e-16, -1.22670650e-16, -6.67087431e-17, + -5.82448523e-17, -5.13316908e-17, -1.81656885e-17, -7.86690988e-18, -3.89522337e-17, + -1.15855115e-16, -1.74954292e-16, -1.33325448e-16, -8.10335324e-17, -3.84778877e-17, + -1.21467514e-17, -9.02003740e-18, -8.52923688e-17, -1.35398261e-16, -1.43508015e-16, + -1.02194616e-16, -6.15266379e-17, -3.68234794e-17, -6.29445132e-18, -1.94815529e-17, + -3.96109287e-17, -7.49436998e-17, -1.60857899e-16, -2.10454719e-16, -1.45321968e-16, + -5.07319263e-17, -5.47927830e-18, 1.49858513e-17, 1.56498476e-17, -7.54459958e-19, + -9.27659888e-17, -1.23528386e-16, -1.38498554e-16, -9.40333637e-17, -3.88191046e-17, + -6.10559670e-17, -4.14069630e-17, -4.37580381e-19, -1.07254809e-16, -1.29641473e-16, + -1.28271011e-16, -1.23214256e-16, -1.00679319e-16, -3.73837353e-17, -1.08004091e-17, + -2.74320227e-17, -1.14146845e-16, -1.73095674e-16, -1.62518453e-16, -8.43742901e-17, + -9.06634370e-18, -7.73848113e-18, -2.02551628e-17, -7.06752027e-17, -1.18960235e-16, + -1.57303724e-16, -1.48787619e-16, -1.01322883e-16, -6.26503964e-17, -3.15834682e-17, + 8.51226330e-19}; - //pre-saved output result - float outputP[229*177] = - {2.46442479e-05, 3.62009617e-05, 3.92805445e-05, 3.31105267e-05, - 2.44610352e-05, 1.75168153e-05, 1.44777033e-05, 1.42619684e-05, - 1.44256744e-05, 2.33214435e-05, 2.99236955e-05, 2.78217067e-05, - 2.40172106e-05, 2.34277891e-05, 2.22964534e-05, 1.78370132e-05, - 1.46574172e-05, 1.49789081e-05, 1.54532469e-05, 1.41642524e-05, - 2.72690126e-05, 3.47562524e-05, 3.36469828e-05, 2.59178471e-05, - 2.21619259e-05, 2.11235337e-05, 1.64959420e-05, 1.30077730e-05, - 1.20597531e-05, 3.38864719e-05, 5.02849103e-05, 4.31467475e-05, - 2.36252856e-05, 1.50520325e-05, 1.40335571e-05, 1.38412257e-05, - 1.32075826e-05, 1.30914952e-05, 2.26312708e-05, 3.56262526e-05, - 4.01062343e-05, 2.78118735e-05, 1.96103207e-05, 1.94129410e-05, - 1.98097588e-05, 1.65930717e-05, 1.34947934e-05, 1.53536951e-05, - 2.26003245e-05, 3.96166436e-05, 4.99489629e-05, 3.96964926e-05, - 2.39565814e-05, 1.40911249e-05, 1.16174600e-05, 1.23917415e-05, - 3.23581886e-05, 4.51986705e-05, 4.17825601e-05, 2.86584918e-05, - 1.76376738e-05, 1.22950013e-05, 1.12000393e-05, 1.26026018e-05, - 3.66475641e-05, 4.86016461e-05, 4.22416834e-05, 2.72035730e-05, - 1.47764258e-05, 1.11113020e-05, 1.20997196e-05, 1.34313365e-05, - 3.95855971e-05, 5.45908413e-05, 3.84210014e-05, 2.34986280e-05, - 1.83787526e-05, 1.60994793e-05, 1.43472775e-05, 2.87492245e-05, - 3.62227971e-05, 3.75741363e-05, 3.32621927e-05, 2.19785358e-05, - 1.44159244e-05, 1.31294032e-05, 1.37200507e-05, 2.69149552e-05, - 3.38086601e-05, 3.33251612e-05, 2.81320872e-05, 2.39788080e-05, - 2.06619087e-05, 1.57570698e-05, 1.39038052e-05, 2.52617372e-05, - 3.38908683e-05, 3.35448560e-05, 3.03151908e-05, 2.74780421e-05, - 2.13293104e-05, 1.58912820e-05, 1.35339022e-05, 1.36518387e-05, - 2.18114936e-05, 3.58375602e-05, 5.22680335e-05, 4.73230483e-05, - 2.93944210e-05, 1.55590860e-05, 1.28316631e-05, 1.57698241e-05, - 3.14234114e-05, 3.96628636e-05, 3.28567929e-05, 2.31406106e-05, - 2.08278162e-05, 1.86489096e-05, 1.49060567e-05, 1.39576809e-05, - 2.14946981e-05, 3.22923390e-05, 4.06564801e-05, 3.21599676e-05, - 2.34356595e-05, 1.70535119e-05, 1.40325872e-05, 1.40308912e-05, - 2.46462488e-05, 3.38814557e-05, 3.54577281e-05, 2.87450834e-05, - 2.21524701e-05, 1.77522488e-05, 1.39546040e-05, 1.47437400e-05, - 1.62893751e-05, 2.45330707e-05, 3.93189778e-05, 4.71486445e-05, - 3.37792038e-05, 2.01343432e-05, 1.47007211e-05, 1.20555822e-05, - 1.17869007e-05, 1.31558888e-05, 2.85944295e-05, 3.60464756e-05, - 3.63889603e-05, 2.65026290e-05, 1.74080173e-05, 1.75971986e-05, - 1.55212658e-05, 1.26525981e-05, 2.73510167e-05, 3.42379060e-05, - 3.46739713e-05, 3.18499013e-05, 2.64033817e-05, 1.79173319e-05, - 1.46597919e-05, 1.54831293e-05, 3.27095867e-05, 4.55029367e-05, - 3.87607603e-05, 2.30101128e-05, 1.40805548e-05, 1.38784434e-05, - 1.47962230e-05, 2.40873419e-05, 3.29083090e-05, 3.89264907e-05, - 3.53248621e-05, 2.52257061e-05, 1.91594181e-05, 1.59149924e-05, - 1.31705002e-05, - 2.54597212e-05, 3.45772037e-05, 3.68741094e-05, 3.12028853e-05, - 2.40349077e-05, 1.88272324e-05, 1.63827971e-05, 1.63853146e-05, - 1.68275859e-05, 2.45728577e-05, 3.00206570e-05, 2.84291124e-05, - 2.48520731e-05, 2.42886621e-05, 2.34032420e-05, 1.91738078e-05, - 1.63351233e-05, 1.69943546e-05, 1.76931871e-05, 1.65302673e-05, - 2.72134658e-05, 3.30757563e-05, 3.28886277e-05, 2.60895485e-05, - 2.27590610e-05, 2.25435029e-05, 1.86851618e-05, 1.52931875e-05, - 1.43608534e-05, 3.25418114e-05, 4.43134701e-05, 3.95450068e-05, - 2.33622213e-05, 1.59174770e-05, 1.58389562e-05, 1.62563189e-05, - 1.56328955e-05, 1.54846478e-05, 2.22438891e-05, 3.20169023e-05, - 3.66204361e-05, 2.71167734e-05, 2.05463692e-05, 2.13239509e-05, - 2.23570202e-05, 1.92426016e-05, 1.60836201e-05, 1.65812802e-05, - 2.24247624e-05, 3.66188744e-05, 4.52675416e-05, 3.72152611e-05, - 2.45971764e-05, 1.61047736e-05, 1.40457964e-05, 1.49105792e-05, - 3.20369974e-05, 4.03731253e-05, 3.74727893e-05, 2.74333528e-05, - 1.86238908e-05, 1.41126618e-05, 1.33260519e-05, 1.49622924e-05, - 3.59950748e-05, 4.26592695e-05, 3.73420663e-05, 2.64237990e-05, - 1.61958731e-05, 1.31728851e-05, 1.45443428e-05, 1.58594170e-05, - 3.64499062e-05, 4.61791629e-05, 3.41864876e-05, 2.27205685e-05, - 1.96696628e-05, 1.88488476e-05, 1.71849993e-05, 2.80282955e-05, - 3.25922112e-05, 3.40679773e-05, 3.23467724e-05, 2.37605397e-05, - 1.67151122e-05, 1.55263654e-05, 1.61342371e-05, 2.66031633e-05, - 3.12196165e-05, 3.10320135e-05, 2.74027553e-05, 2.49946529e-05, - 2.29810739e-05, 1.82740588e-05, 1.63105032e-05, 2.53314846e-05, - 3.19581792e-05, 3.18126563e-05, 2.88582413e-05, 2.72145093e-05, - 2.30071466e-05, 1.83376441e-05, 1.59842474e-05, 1.60691474e-05, - 2.07001119e-05, 3.04569861e-05, 4.45713120e-05, 4.37223253e-05, - 3.10397952e-05, 1.83824157e-05, 1.54065489e-05, 1.87487580e-05, - 3.00894355e-05, 3.48246677e-05, 3.02485839e-05, 2.31155961e-05, - 2.18469593e-05, 2.06869431e-05, 1.72448533e-05, 1.62954796e-05, - 2.05929740e-05, 2.94507214e-05, 3.73906570e-05, 3.12579873e-05, - 2.43656121e-05, 1.92790153e-05, 1.65656162e-05, 1.63881778e-05, - 2.50323716e-05, 3.17769911e-05, 3.29233516e-05, 2.74656534e-05, - 2.24558865e-05, 1.93998510e-05, 1.62064391e-05, 1.72621932e-05, - 1.90841146e-05, 2.41249711e-05, 3.54774366e-05, 4.28204669e-05, - 3.28585427e-05, 2.10928982e-05, 1.64341423e-05, 1.43408917e-05, - 1.41971772e-05, 1.55937912e-05, 2.65505266e-05, 3.07911857e-05, - 3.24881407e-05, 2.62376753e-05, 1.94209754e-05, 2.10188315e-05, - 1.89105974e-05, 1.53728286e-05, 2.76530072e-05, 3.12062321e-05, - 3.11220201e-05, 3.01359857e-05, 2.68221797e-05, 1.94900387e-05, - 1.67241597e-05, 1.80174916e-05, 2.93415714e-05, 3.75759014e-05, - 3.56116762e-05, 2.45324185e-05, 1.64096975e-05, 1.62579367e-05, - 1.73277891e-05, 2.36661067e-05, 2.98693250e-05, 3.49999999e-05, - 3.35045549e-05, 2.65950025e-05, 2.16712347e-05, 1.84338709e-05, - 1.55137547e-05, - 2.43839683e-05, 3.83619688e-05, 4.22958465e-05, 3.37828119e-05, - 2.33718957e-05, 1.61402691e-05, 1.31069160e-05, 1.29886860e-05, - 1.33093679e-05, 2.29988885e-05, 3.08083279e-05, 2.83467341e-05, - 2.36084331e-05, 2.28905282e-05, 2.16483766e-05, 1.65185155e-05, - 1.31811302e-05, 1.37068672e-05, 1.43443741e-05, 1.30092202e-05, - 2.71893384e-05, 3.62540883e-05, 3.53458913e-05, 2.55933611e-05, - 2.11755948e-05, 2.04144351e-05, 1.54746544e-05, 1.17408692e-05, - 1.07648424e-05, 3.52664660e-05, 5.67227788e-05, 4.72419745e-05, - 2.24373231e-05, 1.31745928e-05, 1.25797203e-05, 1.26884616e-05, - 1.20213059e-05, 1.18829027e-05, 2.11432996e-05, 3.60858250e-05, - 4.27066875e-05, 2.74762600e-05, 1.83356349e-05, 1.86675699e-05, - 1.95018694e-05, 1.58332135e-05, 1.24078636e-05, 1.36951074e-05, - 2.12361443e-05, 4.23481677e-05, 5.72558679e-05, 4.28601190e-05, - 2.34117996e-05, 1.27489156e-05, 1.03743643e-05, 1.12146543e-05, - 3.38525166e-05, 4.94662095e-05, 4.45954868e-05, 2.82330334e-05, - 1.60953362e-05, 1.07676587e-05, 9.80614279e-06, 1.13549135e-05, - 3.97191822e-05, 5.39888061e-05, 4.48310310e-05, 2.66297647e-05, - 1.31730167e-05, 9.68613028e-06, 1.08763111e-05, 1.22591499e-05, - 4.21969429e-05, 6.18554260e-05, 3.96445375e-05, 2.19594230e-05, - 1.71121323e-05, 1.53326686e-05, 1.34496675e-05, 2.86904591e-05, - 3.69194156e-05, 3.89585811e-05, 3.46953633e-05, 2.16666395e-05, - 1.32455617e-05, 1.19246895e-05, 1.25587607e-05, 2.65627781e-05, - 3.42689281e-05, 3.38071803e-05, 2.78724835e-05, 2.36728700e-05, - 2.03885060e-05, 1.48272549e-05, 1.27510280e-05, 2.46931219e-05, - 3.48533582e-05, 3.45120999e-05, 3.02789718e-05, 2.73252373e-05, - 2.08155205e-05, 1.49385408e-05, 1.23792017e-05, 1.24877391e-05, - 1.97111468e-05, 3.50760149e-05, 5.85457500e-05, 5.38525296e-05, - 3.11302513e-05, 1.47703074e-05, 1.17011294e-05, 1.50868802e-05, - 3.18635500e-05, 4.10098732e-05, 3.29352795e-05, 2.19889388e-05, - 1.98226194e-05, 1.78474766e-05, 1.37975815e-05, 1.27732998e-05, - 1.94622081e-05, 3.19952282e-05, 4.37016450e-05, 3.31738719e-05, - 2.29428893e-05, 1.61223948e-05, 1.29537410e-05, 1.28616708e-05, - 2.41165484e-05, 3.47174313e-05, 3.66324431e-05, 2.83106147e-05, - 2.09856331e-05, 1.65961304e-05, 1.27258534e-05, 1.37147755e-05, - 1.55697907e-05, 2.34732395e-05, 4.12636321e-05, 5.29748228e-05, - 3.54168834e-05, 1.89641783e-05, 1.32571005e-05, 1.07528123e-05, - 1.05385355e-05, 1.19731708e-05, 2.75983947e-05, 3.54641701e-05, - 3.69569644e-05, 2.60616190e-05, 1.64074702e-05, 1.73994186e-05, - 1.50264040e-05, 1.15858593e-05, 2.75298558e-05, 3.45503659e-05, - 3.47844391e-05, 3.21818299e-05, 2.63759020e-05, 1.67425688e-05, - 1.33865513e-05, 1.45334202e-05, 3.21931001e-05, 4.74181169e-05, - 4.09640569e-05, 2.27785889e-05, 1.29004092e-05, 1.27099896e-05, - 1.37787552e-05, 2.29099542e-05, 3.27001632e-05, 4.06196518e-05, - 3.69618775e-05, 2.54703133e-05, 1.87127283e-05, 1.50036554e-05, - 1.19408929e-05, - 2.44535165e-05, 3.77886350e-05, 4.14898468e-05, 3.36309437e-05, - 2.36782021e-05, 1.64981453e-05, 1.34543802e-05, 1.33088922e-05, - 1.35865812e-05, 2.30801151e-05, 3.05714845e-05, 2.82034460e-05, - 2.37179089e-05, 2.30342625e-05, 2.18188323e-05, 1.68613695e-05, - 1.35578482e-05, 1.40284614e-05, 1.46219260e-05, 1.32965985e-05, - 2.72204204e-05, 3.58688621e-05, 3.48916336e-05, 2.56881224e-05, - 2.14419032e-05, 2.05974303e-05, 1.57304515e-05, 1.20566507e-05, - 1.10864900e-05, 3.49098261e-05, 5.49768428e-05, 4.61425623e-05, - 2.27674184e-05, 1.36605276e-05, 1.29487175e-05, 1.29745357e-05, - 1.23153694e-05, 1.21828763e-05, 2.15527674e-05, 3.60154973e-05, - 4.20347113e-05, 2.75848328e-05, 1.86726493e-05, 1.88544348e-05, - 1.95643312e-05, 1.60154576e-05, 1.26750454e-05, 1.41232845e-05, - 2.16108835e-05, 4.16318263e-05, 5.52314103e-05, 4.20126543e-05, - 2.35602108e-05, 1.30876243e-05, 1.06812233e-05, 1.15047485e-05, - 3.34501642e-05, 4.83356149e-05, 4.38749511e-05, 2.83726186e-05, - 1.64993303e-05, 1.11523365e-05, 1.01529299e-05, 1.16646816e-05, - 3.88719453e-05, 5.25503895e-05, 4.41827193e-05, 2.68035983e-05, - 1.35845472e-05, 1.00411022e-05, 1.11785852e-05, 1.25497652e-05, - 4.15168389e-05, 5.99068289e-05, 3.93711557e-05, 2.23873760e-05, - 1.74424039e-05, 1.55156193e-05, 1.36656564e-05, 2.87241780e-05, - 3.67839865e-05, 3.86301247e-05, 3.43180727e-05, 2.17387992e-05, - 1.35377335e-05, 1.22236704e-05, 1.28469432e-05, 2.66710175e-05, - 3.41846577e-05, 3.37129795e-05, 2.79609066e-05, 2.37523918e-05, - 2.04441478e-05, 1.50554224e-05, 1.30372343e-05, 2.48549182e-05, - 3.46212576e-05, 3.42760094e-05, 3.03159499e-05, 2.73788152e-05, - 2.09433071e-05, 1.51734906e-05, 1.26651957e-05, 1.27765599e-05, - 2.02853388e-05, 3.53618159e-05, 5.68754415e-05, 5.20404964e-05, - 3.06340730e-05, 1.49581890e-05, 1.19791727e-05, 1.52451945e-05, - 3.17683112e-05, 4.07105345e-05, 3.29560181e-05, 2.23064752e-05, - 2.00886383e-05, 1.80476843e-05, 1.40737029e-05, 1.30683472e-05, - 2.00163793e-05, 3.21212451e-05, 4.28995432e-05, 3.29138409e-05, - 2.30738440e-05, 1.63543919e-05, 1.32197260e-05, 1.31526872e-05, - 2.42640080e-05, 3.45227911e-05, 3.63492697e-05, 2.84533267e-05, - 2.13029096e-05, 1.68934537e-05, 1.30331220e-05, 1.39683730e-05, - 1.57397989e-05, 2.37716070e-05, 4.07825229e-05, 5.13819359e-05, - 3.49820772e-05, 1.92739400e-05, 1.36250339e-05, 1.10765832e-05, - 1.08470927e-05, 1.22661581e-05, 2.79012418e-05, 3.57000893e-05, - 3.68607460e-05, 2.61932537e-05, 1.66600757e-05, 1.74226925e-05, - 1.51303627e-05, 1.18460071e-05, 2.74858036e-05, 3.45126695e-05, - 3.48090878e-05, 3.21213298e-05, 2.63869065e-05, 1.70456421e-05, - 1.37076882e-05, 1.47665170e-05, 3.23854102e-05, 4.70047111e-05, - 4.04000527e-05, 2.28319679e-05, 1.31945495e-05, 1.30004743e-05, - 1.40292577e-05, 2.32393374e-05, 3.28046945e-05, 4.02105225e-05, - 3.65393924e-05, 2.53952476e-05, 1.88130490e-05, 1.52270124e-05, - 1.22467828e-05, - 2.53267956e-05, 3.33285493e-05, 3.52734913e-05, 3.10679348e-05, - 2.48828214e-05, 1.95681751e-05, 1.70243712e-05, 1.68819679e-05, - 1.70979032e-05, 2.43787770e-05, 2.91979550e-05, 2.77358703e-05, - 2.48354647e-05, 2.43719872e-05, 2.35194961e-05, 1.98511279e-05, - 1.71306729e-05, 1.75039300e-05, 1.79828066e-05, 1.68517600e-05, - 2.71606424e-05, 3.22988192e-05, 3.17180065e-05, 2.61717420e-05, - 2.32877637e-05, 2.26361762e-05, 1.88925034e-05, 1.57680935e-05, - 1.48824636e-05, 3.17562926e-05, 4.16029742e-05, 3.75868236e-05, - 2.42571643e-05, 1.72790658e-05, 1.65953258e-05, 1.65685446e-05, - 1.59874251e-05, 1.58720192e-05, 2.34245553e-05, 3.24613944e-05, - 3.55896217e-05, 2.74233899e-05, 2.12610921e-05, 2.13301000e-05, - 2.18096180e-05, 1.90857892e-05, 1.62918823e-05, 1.76436076e-05, - 2.34528666e-05, 3.53689396e-05, 4.16714124e-05, 3.55385430e-05, - 2.47412907e-05, 1.66994570e-05, 1.44929766e-05, 1.52485716e-05, - 3.08887286e-05, 3.86496132e-05, 3.65263692e-05, 2.79387957e-05, - 1.95917597e-05, 1.49844211e-05, 1.40181164e-05, 1.54079969e-05, - 3.38536622e-05, 4.05644420e-05, 3.66962380e-05, 2.69371502e-05, - 1.71732374e-05, 1.39164146e-05, 1.49552457e-05, 1.61949241e-05, - 3.53167005e-05, 4.36778230e-05, 3.42649063e-05, 2.40258351e-05, - 2.03045935e-05, 1.86755799e-05, 1.71297279e-05, 2.81285025e-05, - 3.28775607e-05, 3.38514603e-05, 3.14066330e-05, 2.34196341e-05, - 1.70644053e-05, 1.59081169e-05, 1.64572361e-05, 2.68279500e-05, - 3.14095009e-05, 3.11316927e-05, 2.76590292e-05, 2.48474897e-05, - 2.24649323e-05, 1.83186805e-05, 1.66238078e-05, 2.56351576e-05, - 3.16235581e-05, 3.14219864e-05, 2.91259881e-05, 2.72714295e-05, - 2.28657550e-05, 1.84209044e-05, 1.62948020e-05, 1.63953461e-05, - 2.25668015e-05, 3.21702771e-05, 4.24382644e-05, 4.02669500e-05, - 2.91480171e-05, 1.82144226e-05, 1.56739685e-05, 1.84372352e-05, - 2.99741687e-05, 3.49731196e-05, 3.07167940e-05, 2.39270145e-05, - 2.22963429e-05, 2.07144306e-05, 1.75165498e-05, 1.66564971e-05, - 2.23611840e-05, 3.02481605e-05, 3.60099343e-05, 3.06128910e-05, - 2.43946282e-05, 1.93879056e-05, 1.67716688e-05, 1.67280649e-05, - 2.52268437e-05, 3.15765935e-05, 3.25977856e-05, 2.79911431e-05, - 2.32080818e-05, 1.98541025e-05, 1.66329042e-05, 1.74131877e-05, - 1.88531641e-05, 2.49443948e-05, 3.49733177e-05, 4.00025628e-05, - 3.17759733e-05, 2.17055809e-05, 1.71837183e-05, 1.48746455e-05, - 1.46501148e-05, 1.59425541e-05, 2.76881014e-05, 3.23510384e-05, - 3.29293755e-05, 2.65210279e-05, 1.96448235e-05, 2.01316111e-05, - 1.83097671e-05, 1.55413337e-05, 2.73070226e-05, 3.16114210e-05, - 3.17973748e-05, 3.01969820e-05, 2.66061797e-05, 1.99779800e-05, - 1.72282595e-05, 1.80793768e-05, 3.04227877e-05, 3.81253282e-05, - 3.47517532e-05, 2.41923281e-05, 1.67666047e-05, 1.65940628e-05, - 1.74635839e-05, 2.45869453e-05, 3.06491430e-05, 3.46851599e-05, - 3.26690406e-05, 2.59107597e-05, 2.12562600e-05, 1.84589514e-05, - 1.59332324e-05, - 2.54296260e-05, 2.86160966e-05, 2.92161952e-05, 2.82393063e-05, - 2.58216582e-05, 2.26179335e-05, 2.08204592e-05, 2.06012340e-05, - 2.05743128e-05, 2.48678399e-05, 2.69998310e-05, 2.63535976e-05, - 2.52347044e-05, 2.50421834e-05, 2.45816092e-05, 2.27516612e-05, - 2.10215788e-05, 2.10513803e-05, 2.12120217e-05, 2.04384173e-05, - 2.64405190e-05, 2.84270454e-05, 2.79702303e-05, 2.60136537e-05, - 2.47252978e-05, 2.40510829e-05, 2.17699873e-05, 1.97701483e-05, - 1.91396210e-05, 2.81894069e-05, 3.08292859e-05, 2.98923933e-05, - 2.55148378e-05, 2.15993589e-05, 2.06098814e-05, 2.02259092e-05, - 1.98332166e-05, 1.97745627e-05, 2.52520365e-05, 2.91446189e-05, - 2.96091071e-05, 2.67896813e-05, 2.36598351e-05, 2.32000054e-05, - 2.31215597e-05, 2.16314089e-05, 1.99392575e-05, 2.15961910e-05, - 2.51614976e-05, 2.94208723e-05, 3.04936197e-05, 2.92807766e-05, - 2.52857282e-05, 2.05505374e-05, 1.87728007e-05, 1.92631583e-05, - 2.76116780e-05, 3.03534184e-05, 2.99888998e-05, 2.71631734e-05, - 2.28070176e-05, 1.95252540e-05, 1.86178010e-05, 1.94752553e-05, - 2.83912730e-05, 3.07851631e-05, 3.01910685e-05, 2.66734093e-05, - 2.12019322e-05, 1.85844968e-05, 1.91002102e-05, 1.99711179e-05, - 2.94575777e-05, 3.14494366e-05, 2.96626808e-05, 2.56693982e-05, - 2.30083102e-05, 2.13405405e-05, 2.03426570e-05, 2.70129316e-05, - 2.92275477e-05, 2.93515116e-05, 2.79542555e-05, 2.42247415e-05, - 2.06131225e-05, 1.97967719e-05, 2.01534525e-05, 2.64402287e-05, - 2.85659611e-05, 2.83963222e-05, 2.68759342e-05, 2.51585112e-05, - 2.35434929e-05, 2.12572599e-05, 2.02669631e-05, 2.58698617e-05, - 2.83725049e-05, 2.82549047e-05, 2.75873374e-05, 2.65625898e-05, - 2.40303465e-05, 2.13566222e-05, 2.00243000e-05, 2.01107847e-05, - 2.52686805e-05, 2.97313923e-05, 3.12867667e-05, 3.01297155e-05, - 2.63903795e-05, 2.10260194e-05, 1.95268850e-05, 2.10749399e-05, - 2.77602267e-05, 2.99636439e-05, 2.84213848e-05, 2.52767710e-05, - 2.40938599e-05, 2.28286702e-05, 2.08725008e-05, 2.03291701e-05, - 2.50798439e-05, 2.84039247e-05, 2.95969778e-05, 2.77575521e-05, - 2.50197511e-05, 2.20275579e-05, 2.02884108e-05, 2.03639238e-05, - 2.55822227e-05, 2.84247136e-05, 2.87894110e-05, 2.72006404e-05, - 2.48327049e-05, 2.25870641e-05, 2.03651236e-05, 2.07052945e-05, - 2.14197010e-05, 2.58357507e-05, 2.96367913e-05, 3.03119795e-05, - 2.80417001e-05, 2.38557282e-05, 2.10210155e-05, 1.91441485e-05, - 1.89003772e-05, 1.97951157e-05, 2.74305312e-05, 2.97159435e-05, - 2.93316239e-05, 2.63193872e-05, 2.22811210e-05, 2.18182719e-05, - 2.07760014e-05, 1.93449683e-05, 2.63397430e-05, 2.87705410e-05, - 2.89978675e-05, 2.79607552e-05, 2.60575328e-05, 2.26916875e-05, - 2.08533191e-05, 2.11046891e-05, 2.86447021e-05, 3.12264873e-05, - 2.93764557e-05, 2.46696019e-05, 2.04054600e-05, 2.02637651e-05, - 2.07292324e-05, 2.57112451e-05, 2.85690556e-05, 2.96226438e-05, - 2.85528401e-05, 2.54068408e-05, 2.28648880e-05, 2.13390687e-05, - 1.98467196e-05, - 2.50645333e-05, 2.39746575e-05, 2.35888597e-05, 2.45501112e-05, - 2.54261917e-05, 2.53837298e-05, 2.50825409e-05, 2.49758838e-05, - 2.48734890e-05, 2.50722669e-05, 2.45865006e-05, 2.47462446e-05, - 2.51237919e-05, 2.51741496e-05, 2.52031340e-05, 2.53689239e-05, - 2.51875056e-05, 2.50688884e-05, 2.50043903e-05, 2.48662218e-05, - 2.49840184e-05, 2.42297363e-05, 2.42163260e-05, 2.50939453e-05, - 2.53661165e-05, 2.51954145e-05, 2.50593783e-05, 2.47759081e-05, - 2.46271747e-05, 2.43027143e-05, 2.20878352e-05, 2.30937699e-05, - 2.54737491e-05, 2.55347742e-05, 2.50911104e-05, 2.48148989e-05, - 2.47391879e-05, 2.47387309e-05, 2.56129526e-05, 2.44750454e-05, - 2.36396518e-05, 2.50722057e-05, 2.54397850e-05, 2.51277486e-05, - 2.49051427e-05, 2.48903359e-05, 2.47025105e-05, 2.53996241e-05, - 2.55540480e-05, 2.36388965e-05, 2.19581226e-05, 2.35282053e-05, - 2.51843967e-05, 2.50079036e-05, 2.44851270e-05, 2.45807047e-05, - 2.43227791e-05, 2.29092133e-05, 2.34754169e-05, 2.50832394e-05, - 2.54972499e-05, 2.48915408e-05, 2.45490146e-05, 2.46863596e-05, - 2.37046582e-05, 2.24194894e-05, 2.34919941e-05, 2.51759968e-05, - 2.52994576e-05, 2.45625665e-05, 2.45664406e-05, 2.47648899e-05, - 2.36702418e-05, 2.15651372e-05, 2.40904691e-05, 2.56334164e-05, - 2.53715730e-05, 2.48363695e-05, 2.46867451e-05, 2.49480269e-05, - 2.43729773e-05, 2.41056404e-05, 2.43113867e-05, 2.50260643e-05, - 2.49151373e-05, 2.47418808e-05, 2.48028065e-05, 2.50950679e-05, - 2.45795200e-05, 2.45975958e-05, 2.50365525e-05, 2.50768747e-05, - 2.49416445e-05, 2.49106589e-05, 2.48247040e-05, 2.51986030e-05, - 2.44267608e-05, 2.44412015e-05, 2.48920809e-05, 2.50091573e-05, - 2.51023339e-05, 2.49435583e-05, 2.47669611e-05, 2.47942089e-05, - 2.59095894e-05, 2.47904288e-05, 2.19419735e-05, 2.22991695e-05, - 2.42908456e-05, 2.47819948e-05, 2.46222402e-05, 2.47333314e-05, - 2.46932188e-05, 2.39713388e-05, 2.47434293e-05, 2.54564342e-05, - 2.53399114e-05, 2.51084255e-05, 2.49342733e-05, 2.48591165e-05, - 2.58776298e-05, 2.48882218e-05, 2.34979852e-05, 2.44819697e-05, - 2.51536714e-05, 2.50544904e-05, 2.47838984e-05, 2.48577689e-05, - 2.51821653e-05, 2.44647175e-05, 2.42864744e-05, 2.50838474e-05, - 2.54545034e-05, 2.52604923e-05, 2.48952304e-05, 2.48503811e-05, - 2.48265402e-05, 2.54129316e-05, 2.38507569e-05, 2.24497491e-05, - 2.42298338e-05, 2.54030650e-05, 2.51672472e-05, 2.46339176e-05, - 2.45263776e-05, 2.47271316e-05, 2.52908339e-05, 2.47270195e-05, - 2.43968198e-05, 2.51358613e-05, 2.51327960e-05, 2.46327063e-05, - 2.45599633e-05, 2.45298705e-05, 2.48830168e-05, 2.45993446e-05, - 2.46314938e-05, 2.47112466e-05, 2.49707913e-05, 2.52843583e-05, - 2.50294275e-05, 2.48905496e-05, 2.49323669e-05, 2.33573806e-05, - 2.38226134e-05, 2.50215522e-05, 2.48741819e-05, 2.48337545e-05, - 2.48488956e-05, 2.54673461e-05, 2.48277464e-05, 2.39390501e-05, - 2.41631031e-05, 2.48525388e-05, 2.49364928e-05, 2.49167164e-05, - 2.47707969e-05, - 2.44432231e-05, 2.10575919e-05, 2.02301081e-05, 2.21602416e-05, - 2.49189243e-05, 2.69825222e-05, 2.78531322e-05, 2.78100039e-05, - 2.75947059e-05, 2.47854748e-05, 2.27626631e-05, 2.33586688e-05, - 2.46691317e-05, 2.48804859e-05, 2.52192676e-05, 2.68447245e-05, - 2.79114791e-05, 2.76058486e-05, 2.73118999e-05, 2.77074671e-05, - 2.37494868e-05, 2.15477409e-05, 2.17070079e-05, 2.41771324e-05, - 2.54556913e-05, 2.55453102e-05, 2.69540742e-05, 2.81599164e-05, - 2.84704623e-05, 2.17631811e-05, 1.75509616e-05, 1.92569053e-05, - 2.51895422e-05, 2.81980448e-05, 2.80759559e-05, 2.77927670e-05, - 2.80055479e-05, 2.80648333e-05, 2.56255851e-05, 2.16802630e-05, - 2.01783347e-05, 2.37361384e-05, 2.63208630e-05, 2.59922838e-05, - 2.55852108e-05, 2.66945045e-05, 2.78097063e-05, 2.78820931e-05, - 2.55624922e-05, 2.02394383e-05, 1.74546396e-05, 2.01138266e-05, - 2.47569817e-05, 2.79349095e-05, 2.85269323e-05, 2.82191364e-05, - 2.20354011e-05, 1.88488204e-05, 1.98040822e-05, 2.35739988e-05, - 2.70840756e-05, 2.87086722e-05, 2.88715994e-05, 2.82514570e-05, - 2.07055184e-05, 1.80268872e-05, 1.97670380e-05, 2.39860749e-05, - 2.80075545e-05, 2.89465247e-05, 2.83622577e-05, 2.79271676e-05, - 2.02761250e-05, 1.66954029e-05, 2.08703005e-05, 2.54151680e-05, - 2.66531899e-05, 2.68201394e-05, 2.73785632e-05, 2.34011253e-05, - 2.14814024e-05, 2.10025807e-05, 2.18731604e-05, 2.50915554e-05, - 2.76555451e-05, 2.80495477e-05, 2.78355069e-05, 2.39550366e-05, - 2.20781095e-05, 2.21769226e-05, 2.36283166e-05, 2.46226748e-05, - 2.53686786e-05, 2.70589389e-05, 2.77757693e-05, 2.44535522e-05, - 2.18979205e-05, 2.19694953e-05, 2.30337904e-05, 2.37339434e-05, - 2.53701656e-05, 2.70467125e-05, 2.78786009e-05, 2.78573671e-05, - 2.62224858e-05, 2.19880771e-05, 1.72405924e-05, 1.80292132e-05, - 2.25281280e-05, 2.69713765e-05, 2.80396078e-05, 2.68190182e-05, - 2.26084009e-05, 2.05807696e-05, 2.24155661e-05, 2.52969165e-05, - 2.58126476e-05, 2.62234458e-05, 2.74578401e-05, 2.77966244e-05, - 2.62770977e-05, 2.26723883e-05, 1.99630271e-05, 2.22451337e-05, - 2.48537867e-05, 2.67306824e-05, 2.76582743e-05, 2.77595710e-05, - 2.45825482e-05, 2.19408900e-05, 2.15023511e-05, 2.35571626e-05, - 2.55663658e-05, 2.67360778e-05, 2.78473141e-05, 2.74180479e-05, - 2.67308994e-05, 2.48851466e-05, 2.04992425e-05, 1.81948149e-05, - 2.17006820e-05, 2.61060389e-05, 2.78642128e-05, 2.84823392e-05, - 2.84856723e-05, 2.80155055e-05, 2.38247221e-05, 2.18880690e-05, - 2.14825160e-05, 2.40937919e-05, 2.66985038e-05, 2.59837145e-05, - 2.66927211e-05, 2.80065364e-05, 2.36151010e-05, 2.20307384e-05, - 2.19965733e-05, 2.25531861e-05, 2.39232611e-05, 2.67065795e-05, - 2.76972479e-05, 2.71477130e-05, 2.26491590e-05, 1.92664831e-05, - 2.05428471e-05, 2.48059288e-05, 2.77581216e-05, 2.78004047e-05, - 2.73924250e-05, 2.50625001e-05, 2.24998127e-05, 2.06432927e-05, - 2.13892465e-05, 2.40533916e-05, 2.58340449e-05, 2.70014613e-05, - 2.80682475e-05, - 2.34482381e-05, 1.79520763e-05, 1.67882816e-05, 1.95081624e-05, - 2.40872258e-05, 2.85530355e-05, 3.09410923e-05, 3.09724463e-05, - 3.05852127e-05, 2.41352511e-05, 2.05855107e-05, 2.15879041e-05, - 2.38513087e-05, 2.42361410e-05, 2.49084495e-05, 2.82584989e-05, - 3.09491259e-05, 3.03679935e-05, 2.97533826e-05, 3.08651945e-05, - 2.21479394e-05, 1.86383057e-05, 1.89295887e-05, 2.28927399e-05, - 2.52467653e-05, 2.56009412e-05, 2.88576628e-05, 3.20878824e-05, - 3.30692242e-05, 1.89698213e-05, 1.33669071e-05, 1.54840415e-05, - 2.45956251e-05, 3.12031078e-05, 3.14678878e-05, 3.11372501e-05, - 3.17561983e-05, 3.19028364e-05, 2.53682801e-05, 1.87080445e-05, - 1.66717434e-05, 2.20505423e-05, 2.70219157e-05, 2.66302505e-05, - 2.59787786e-05, 2.84585700e-05, 3.13248768e-05, 3.06173203e-05, - 2.52920263e-05, 1.67736511e-05, 1.32854459e-05, 1.66311769e-05, - 2.39750003e-05, 3.12330093e-05, 3.34144793e-05, 3.25011991e-05, - 1.94441164e-05, 1.49375217e-05, 1.61527146e-05, 2.17310935e-05, - 2.86563008e-05, 3.33017697e-05, 3.42084937e-05, 3.24367738e-05, - 1.75208688e-05, 1.39208714e-05, 1.60832708e-05, 2.24499278e-05, - 3.10393159e-05, 3.43829173e-05, 3.28809542e-05, 3.15298938e-05, - 1.68159329e-05, 1.23575160e-05, 1.75586688e-05, 2.49137278e-05, - 2.78268438e-05, 2.88099918e-05, 3.03038835e-05, 2.15081849e-05, - 1.84280174e-05, 1.77739176e-05, 1.91600990e-05, 2.48112720e-05, - 3.06783854e-05, 3.18609374e-05, 3.12567046e-05, 2.24560483e-05, - 1.93406770e-05, 1.95050320e-05, 2.18718927e-05, 2.37993827e-05, - 2.54779442e-05, 2.92751329e-05, 3.10833980e-05, 2.33515546e-05, - 1.91242769e-05, 1.92420097e-05, 2.08596608e-05, 2.20973359e-05, - 2.53219713e-05, 2.92075518e-05, 3.14084826e-05, 3.13210897e-05, - 2.63417198e-05, 1.90421640e-05, 1.29774629e-05, 1.39845551e-05, - 2.03750326e-05, 2.92253490e-05, 3.19971496e-05, 2.89293965e-05, - 2.02201291e-05, 1.71442302e-05, 1.98329811e-05, 2.48322607e-05, - 2.60265269e-05, 2.71575732e-05, 3.01832440e-05, 3.10895383e-05, - 2.64884830e-05, 2.01966667e-05, 1.63997147e-05, 1.97099558e-05, - 2.42002793e-05, 2.83529700e-05, 3.08519025e-05, 3.10016837e-05, - 2.36243669e-05, 1.91747477e-05, 1.85208464e-05, 2.16985448e-05, - 2.53941866e-05, 2.81340438e-05, 3.11657492e-05, 3.01928485e-05, - 2.86160733e-05, 2.40306491e-05, 1.70799377e-05, 1.41615924e-05, - 1.89089568e-05, 2.65931496e-05, 3.08613336e-05, 3.30898055e-05, - 3.32503304e-05, 3.17967599e-05, 2.20469678e-05, 1.89081947e-05, - 1.84146589e-05, 2.26933974e-05, 2.81916824e-05, 2.71445730e-05, - 2.88436236e-05, 3.20404672e-05, 2.19705234e-05, 1.92428547e-05, - 1.91607395e-05, 2.01059021e-05, 2.24974920e-05, 2.80414255e-05, - 3.06345631e-05, 2.95063501e-05, 2.01234009e-05, 1.53588900e-05, - 1.71700849e-05, 2.42240919e-05, 3.09771466e-05, 3.11313942e-05, - 3.01338581e-05, 2.43419507e-05, 1.99262265e-05, 1.72681389e-05, - 1.84048019e-05, 2.28553743e-05, 2.64858069e-05, 2.91344281e-05, - 3.18684321e-05, - 2.37343549e-05, 1.87868717e-05, 1.77014271e-05, 2.03475592e-05, - 2.45512862e-05, 2.82306650e-05, 3.00796532e-05, 3.00216012e-05, - 2.95964897e-05, 2.42875245e-05, 2.11521227e-05, 2.20322751e-05, - 2.41032245e-05, 2.44527852e-05, 2.50200343e-05, 2.79642161e-05, - 3.01728063e-05, 2.95596611e-05, 2.89665630e-05, 2.98391833e-05, - 2.26568196e-05, 1.94679805e-05, 1.96574599e-05, 2.33239298e-05, - 2.54331946e-05, 2.55807586e-05, 2.82289960e-05, 3.08624379e-05, - 3.16344980e-05, 1.97583960e-05, 1.44544045e-05, 1.64805026e-05, - 2.49995290e-05, 3.06956729e-05, 3.05578176e-05, 3.00410332e-05, - 3.05353534e-05, 3.06666906e-05, 2.57493779e-05, 1.97344444e-05, - 1.76725128e-05, 2.26589920e-05, 2.69702624e-05, 2.63822111e-05, - 2.56619040e-05, 2.77511316e-05, 3.01209163e-05, 3.00550526e-05, - 2.56343330e-05, 1.77352638e-05, 1.43016061e-05, 1.75506332e-05, - 2.42525663e-05, 3.02798508e-05, 3.18385610e-05, 3.10831684e-05, - 2.01080712e-05, 1.60065357e-05, 1.72114002e-05, 2.24285007e-05, - 2.84164958e-05, 3.20580188e-05, 3.26166102e-05, 3.11070676e-05, - 1.82748496e-05, 1.50273645e-05, 1.71854587e-05, 2.30539694e-05, - 3.03467108e-05, 3.27882931e-05, 3.14160424e-05, 3.03526169e-05, - 1.77890673e-05, 1.35198998e-05, 1.86338107e-05, 2.53996480e-05, - 2.75962113e-05, 2.80130234e-05, 2.92034508e-05, 2.21428307e-05, - 1.94549016e-05, 1.87847388e-05, 1.98982150e-05, 2.47963775e-05, - 2.97118877e-05, 3.06315012e-05, 3.01381021e-05, 2.29878146e-05, - 2.02578060e-05, 2.03876624e-05, 2.24928739e-05, 2.40229438e-05, - 2.52756522e-05, 2.84746063e-05, 3.00007322e-05, 2.37716548e-05, - 1.99725718e-05, 2.00666809e-05, 2.16150245e-05, 2.26397882e-05, - 2.52753335e-05, 2.84414857e-05, 3.02456389e-05, 3.01888539e-05, - 2.68245345e-05, 2.02602375e-05, 1.41382039e-05, 1.49574963e-05, - 2.07593806e-05, 2.83317667e-05, 3.06609792e-05, 2.80376783e-05, - 2.09772812e-05, 1.82652650e-05, 2.07481176e-05, 2.51748140e-05, - 2.60529140e-05, 2.68112018e-05, 2.92891092e-05, 3.00332421e-05, - 2.69158431e-05, 2.11366144e-05, 1.73807308e-05, 2.04306951e-05, - 2.44069343e-05, 2.77889517e-05, 2.97630032e-05, 2.99539336e-05, - 2.39723687e-05, 2.00408158e-05, 1.94380998e-05, 2.24047429e-05, - 2.56299844e-05, 2.77671741e-05, 3.01297316e-05, 2.92317791e-05, - 2.78378010e-05, 2.44945995e-05, 1.81144033e-05, 1.51807491e-05, - 1.96544223e-05, 2.65786218e-05, 3.00778198e-05, 3.16585222e-05, - 3.17208577e-05, 3.05623466e-05, 2.28539708e-05, 2.01094671e-05, - 1.94683621e-05, 2.32056338e-05, 2.77128150e-05, 2.64335991e-05, - 2.78334580e-05, 3.06290623e-05, 2.24362837e-05, 2.02089663e-05, - 2.01832712e-05, 2.09115141e-05, 2.29138640e-05, 2.77073528e-05, - 2.97641003e-05, 2.86606724e-05, 2.11270384e-05, 1.66556106e-05, - 1.81459499e-05, 2.43175791e-05, 2.99450195e-05, 3.00506006e-05, - 2.91786587e-05, 2.47907435e-05, 2.08911084e-05, 1.83121115e-05, - 1.92520665e-05, 2.30948921e-05, 2.61095811e-05, 2.83568452e-05, - 3.06608999e-05, - 2.57182364e-05, 2.90512694e-05, 2.97021465e-05, 2.77333241e-05, - 2.48103538e-05, 2.22682805e-05, 2.08326673e-05, 2.08696145e-05, - 2.12033603e-05, 2.53656620e-05, 2.76093863e-05, 2.70278281e-05, - 2.54299554e-05, 2.51587896e-05, 2.47572453e-05, 2.24787115e-05, - 2.07641794e-05, 2.12486050e-05, 2.17283943e-05, 2.10038211e-05, - 2.63769388e-05, 2.84932767e-05, 2.85863911e-05, 2.59028516e-05, - 2.43385080e-05, 2.43668765e-05, 2.23291262e-05, 2.01588467e-05, - 1.95045166e-05, 2.83516780e-05, 3.12514049e-05, 3.03374550e-05, - 2.45001466e-05, 2.03521449e-05, 2.04542424e-05, 2.08309757e-05, - 2.04137066e-05, 2.03074276e-05, 2.38985417e-05, 2.77501350e-05, - 2.94244478e-05, 2.62218517e-05, 2.32012417e-05, 2.37971623e-05, - 2.44591125e-05, 2.27369352e-05, 2.07434194e-05, 2.08514436e-05, - 2.40305308e-05, 2.95112743e-05, 3.17339282e-05, 2.98014049e-05, - 2.52723680e-05, 2.06659968e-05, 1.92958123e-05, 1.99288020e-05, - 2.83391368e-05, 3.03650730e-05, 2.95575841e-05, 2.62708372e-05, - 2.20915816e-05, 1.92496406e-05, 1.87161238e-05, 1.99404057e-05, - 2.97192653e-05, 3.08144633e-05, 2.94092086e-05, 2.58917553e-05, - 2.06296755e-05, 1.85905013e-05, 1.96580721e-05, 2.05676104e-05, - 2.94299683e-05, 3.12688932e-05, 2.84468925e-05, 2.40806915e-05, - 2.27611450e-05, 2.25188598e-05, 2.15027538e-05, 2.66216163e-05, - 2.79659307e-05, 2.85336967e-05, 2.83532568e-05, 2.50533605e-05, - 2.11138626e-05, 2.03365747e-05, 2.07496589e-05, 2.60557016e-05, - 2.76196029e-05, 2.75975200e-05, 2.63439701e-05, 2.55301114e-05, - 2.47468989e-05, 2.21329607e-05, 2.08655386e-05, 2.55280335e-05, - 2.80241503e-05, 2.80032310e-05, 2.68505570e-05, 2.63411323e-05, - 2.46518177e-05, 2.21603818e-05, 2.06550783e-05, 2.07067069e-05, - 2.29346710e-05, 2.68221752e-05, 3.10003050e-05, 3.15310052e-05, - 2.82928203e-05, 2.22486308e-05, 2.02821970e-05, 2.24957052e-05, - 2.73862681e-05, 2.85667028e-05, 2.72267607e-05, 2.44153235e-05, - 2.39292322e-05, 2.34660683e-05, 2.14613144e-05, 2.08446297e-05, - 2.29111858e-05, 2.68567023e-05, 2.97181545e-05, 2.79324967e-05, - 2.52086357e-05, 2.26888756e-05, 2.10535710e-05, 2.09089871e-05, - 2.54395228e-05, 2.79235880e-05, 2.82849283e-05, 2.62757046e-05, - 2.41295786e-05, 2.26638247e-05, 2.07718679e-05, 2.15012418e-05, - 2.26666376e-05, 2.48582296e-05, 2.89723317e-05, 3.11537323e-05, - 2.85463759e-05, 2.35090143e-05, 2.08384853e-05, 1.94877173e-05, - 1.94031459e-05, 2.03890411e-05, 2.57287425e-05, 2.69784731e-05, - 2.78786208e-05, 2.58956421e-05, 2.27371014e-05, 2.38789712e-05, - 2.26583144e-05, 2.02814395e-05, 2.66351664e-05, 2.75361095e-05, - 2.74108674e-05, 2.73384299e-05, 2.62827574e-05, 2.27040304e-05, - 2.10818786e-05, 2.19778772e-05, 2.67183513e-05, 2.89420045e-05, - 2.91422761e-05, 2.53923112e-05, 2.09186822e-05, 2.08263928e-05, - 2.15450758e-05, 2.46265712e-05, 2.69954932e-05, 2.87908306e-05, - 2.86275385e-05, 2.63436780e-05, 2.40866358e-05, 2.22308322e-05, - 2.03195043e-05, - 2.57083097e-05, 2.69165060e-05, 2.70546124e-05, 2.57704806e-05, - 2.42310976e-05, 2.34027209e-05, 2.28111670e-05, 2.30469912e-05, - 2.35634247e-05, 2.57290986e-05, 2.67051769e-05, 2.65635469e-05, - 2.55019567e-05, 2.53122515e-05, 2.51715900e-05, 2.35876508e-05, - 2.25474856e-05, 2.32283702e-05, 2.37928862e-05, 2.33830024e-05, - 2.56837800e-05, 2.64668638e-05, 2.69849911e-05, 2.54513162e-05, - 2.45026242e-05, 2.50965896e-05, 2.41887256e-05, 2.26829834e-05, - 2.22193752e-05, 2.65193604e-05, 2.68519100e-05, 2.70367179e-05, - 2.40799154e-05, 2.15033727e-05, 2.24279407e-05, 2.33063210e-05, - 2.30143232e-05, 2.29037169e-05, 2.35144906e-05, 2.50166946e-05, - 2.63903310e-05, 2.52020919e-05, 2.38470584e-05, 2.50405467e-05, - 2.60235043e-05, 2.48954544e-05, 2.34210392e-05, 2.22161473e-05, - 2.37548071e-05, 2.66588087e-05, 2.76534627e-05, 2.70966629e-05, - 2.52560144e-05, 2.27885212e-05, 2.22092065e-05, 2.27647750e-05, - 2.70240043e-05, 2.65907629e-05, 2.61653334e-05, 2.49547861e-05, - 2.30070160e-05, 2.15132711e-05, 2.14416868e-05, 2.26012720e-05, - 2.78669271e-05, 2.65343089e-05, 2.58240835e-05, 2.48936351e-05, - 2.22085427e-05, 2.12748101e-05, 2.24887104e-05, 2.31286603e-05, - 2.65390639e-05, 2.60844550e-05, 2.53188816e-05, 2.34260698e-05, - 2.37709695e-05, 2.48339381e-05, 2.42106102e-05, 2.55020232e-05, - 2.51816672e-05, 2.56867892e-05, 2.67317120e-05, 2.58680345e-05, - 2.33979209e-05, 2.29288667e-05, 2.32464276e-05, 2.52869531e-05, - 2.53622209e-05, 2.54814055e-05, 2.52795173e-05, 2.56958292e-05, - 2.60474545e-05, 2.43437619e-05, 2.33229569e-05, 2.50986133e-05, - 2.59858654e-05, 2.60648203e-05, 2.52961275e-05, 2.55370491e-05, - 2.54967922e-05, 2.42980048e-05, 2.32147996e-05, 2.32184470e-05, - 2.22656361e-05, 2.35270157e-05, 2.61000111e-05, 2.79081216e-05, - 2.80910921e-05, 2.47151790e-05, 2.30778135e-05, 2.50353345e-05, - 2.57798813e-05, 2.51773339e-05, 2.50386831e-05, 2.41597541e-05, - 2.44748412e-05, 2.48975603e-05, 2.36901553e-05, 2.32388532e-05, - 2.23738362e-05, 2.46310627e-05, 2.67050063e-05, 2.64195938e-05, - 2.53958361e-05, 2.44843408e-05, 2.35855830e-05, 2.33052225e-05, - 2.52239628e-05, 2.58266390e-05, 2.59125979e-05, 2.49300460e-05, - 2.41429248e-05, 2.39799792e-05, 2.31001387e-05, 2.38921857e-05, - 2.49795130e-05, 2.42803935e-05, 2.58941163e-05, 2.73627756e-05, - 2.68743030e-05, 2.41046001e-05, 2.26559789e-05, 2.21897986e-05, - 2.22663833e-05, 2.30095824e-05, 2.40913445e-05, 2.37076553e-05, - 2.49978236e-05, 2.51885109e-05, 2.43379536e-05, 2.63791265e-05, - 2.55466375e-05, 2.32348559e-05, 2.60891222e-05, 2.50955877e-05, - 2.47660439e-05, 2.55536547e-05, 2.58909813e-05, 2.39500178e-05, - 2.31492016e-05, 2.42490018e-05, 2.42789702e-05, 2.43939624e-05, - 2.63122870e-05, 2.59339430e-05, 2.32843953e-05, 2.32672151e-05, - 2.39363730e-05, 2.40857705e-05, 2.46541743e-05, 2.57167784e-05, - 2.65040303e-05, 2.65303962e-05, 2.57318293e-05, 2.44156180e-05, - 2.28606699e-05, - 2.47730740e-05, 2.17303612e-05, 2.09775349e-05, 2.18025589e-05, - 2.35690492e-05, 2.61020643e-05, 2.73842485e-05, 2.77878560e-05, - 2.82257417e-05, 2.53654293e-05, 2.35639326e-05, 2.42178747e-05, - 2.48616936e-05, 2.49521046e-05, 2.53367857e-05, 2.61055542e-05, - 2.69792488e-05, 2.74884927e-05, 2.77643430e-05, 2.82188724e-05, - 2.37084101e-05, 2.18263733e-05, 2.25450805e-05, 2.40352788e-05, - 2.47949670e-05, 2.58263100e-05, 2.75008667e-05, 2.83119221e-05, - 2.85416835e-05, 2.21263612e-05, 1.83011947e-05, 1.99920153e-05, - 2.37786862e-05, 2.56023197e-05, 2.72778883e-05, 2.83706097e-05, - 2.85260620e-05, 2.84927731e-05, 2.36913479e-05, 2.05137416e-05, - 2.03089681e-05, 2.31121060e-05, 2.54113741e-05, 2.66500645e-05, - 2.73593351e-05, 2.81522458e-05, 2.87539230e-05, 2.61734139e-05, - 2.39226901e-05, 2.06181228e-05, 1.88502708e-05, 2.08966841e-05, - 2.46735732e-05, 2.76291847e-05, 2.89008687e-05, 2.88909103e-05, - 2.29851801e-05, 1.92273100e-05, 1.97429146e-05, 2.26100450e-05, - 2.56381816e-05, 2.75428849e-05, 2.83613891e-05, 2.85370388e-05, - 2.22749512e-05, 1.84552560e-05, 1.94050775e-05, 2.30790848e-05, - 2.65365563e-05, 2.82405660e-05, 2.88168471e-05, 2.84819037e-05, - 2.05439653e-05, 1.70191917e-05, 1.99927246e-05, 2.32480841e-05, - 2.59866561e-05, 2.84084163e-05, 2.89707602e-05, 2.30212621e-05, - 2.04720324e-05, 2.04738810e-05, 2.24771978e-05, 2.61114645e-05, - 2.80558916e-05, 2.84914948e-05, 2.83948763e-05, 2.35133015e-05, - 2.12861775e-05, 2.15193732e-05, 2.30601274e-05, 2.50466697e-05, - 2.69304049e-05, 2.81330425e-05, 2.83427779e-05, 2.39969128e-05, - 2.17284772e-05, 2.18917424e-05, 2.23225907e-05, 2.35095909e-05, - 2.60912398e-05, 2.79980274e-05, 2.84990792e-05, 2.84149879e-05, - 2.28924054e-05, 1.93545971e-05, 1.74622605e-05, 1.95756325e-05, - 2.48372289e-05, 2.86470430e-05, 2.88890673e-05, 2.88323638e-05, - 2.23388621e-05, 1.95825506e-05, 2.13234241e-05, 2.40546075e-05, - 2.53968223e-05, 2.69314211e-05, 2.80253666e-05, 2.82124986e-05, - 2.31300350e-05, 2.11796394e-05, 2.03838335e-05, 2.25920210e-05, - 2.50221151e-05, 2.74548538e-05, 2.85321528e-05, 2.82311785e-05, - 2.43554683e-05, 2.16124910e-05, 2.12173953e-05, 2.25599583e-05, - 2.44726349e-05, 2.65420728e-05, 2.80645050e-05, 2.83508445e-05, - 2.84318519e-05, 2.35830625e-05, 2.01668930e-05, 1.92782936e-05, - 2.24221057e-05, 2.53919076e-05, 2.70664174e-05, 2.85112023e-05, - 2.88229981e-05, 2.85604658e-05, 2.19271114e-05, 1.94350737e-05, - 2.02934002e-05, 2.35874453e-05, 2.70967550e-05, 2.89827131e-05, - 2.95242888e-05, 2.92074650e-05, 2.40102779e-05, 2.09615745e-05, - 2.05915397e-05, 2.20280936e-05, 2.42125941e-05, 2.64187242e-05, - 2.76209480e-05, 2.82175483e-05, 2.07838422e-05, 1.77409436e-05, - 2.06015843e-05, 2.56863666e-05, 2.81728599e-05, 2.83009432e-05, - 2.83608013e-05, 2.35931937e-05, 2.10139361e-05, 2.01433424e-05, - 2.16865266e-05, 2.52274646e-05, 2.74427855e-05, 2.81029655e-05, - 2.83845146e-05, - 2.41452643e-05, 1.96476810e-05, 1.86439486e-05, 2.01684316e-05, - 2.31722491e-05, 2.71282139e-05, 2.93148020e-05, 2.97674573e-05, - 3.01054737e-05, 2.49423040e-05, 2.21056261e-05, 2.30286403e-05, - 2.43589926e-05, 2.45693581e-05, 2.51632299e-05, 2.70345590e-05, - 2.88758134e-05, 2.92253000e-05, 2.93043008e-05, 3.02007925e-05, - 2.27208139e-05, 1.99359390e-05, 2.06685949e-05, 2.32607603e-05, - 2.47328050e-05, 2.58759211e-05, 2.87053776e-05, 3.07567070e-05, - 3.13864977e-05, 2.03033638e-05, 1.54073696e-05, 1.74183027e-05, - 2.35294064e-05, 2.74641789e-05, 2.93845072e-05, 3.04680934e-05, - 3.08715130e-05, 3.08895007e-05, 2.36743738e-05, 1.87811767e-05, - 1.80303658e-05, 2.21271507e-05, 2.59159785e-05, 2.70522110e-05, - 2.75503700e-05, 2.92521603e-05, 3.09620828e-05, 2.78890407e-05, - 2.38808909e-05, 1.83275983e-05, 1.58320875e-05, 1.85277424e-05, - 2.42145183e-05, 2.96871037e-05, 3.19305446e-05, 3.15646901e-05, - 2.12235587e-05, 1.66166644e-05, 1.73958178e-05, 2.15600370e-05, - 2.66763854e-05, 3.03383899e-05, 3.16161871e-05, 3.11406416e-05, - 1.99989149e-05, 1.56890495e-05, 1.70869016e-05, 2.22144202e-05, - 2.84247622e-05, 3.15430706e-05, 3.16272761e-05, 3.07375171e-05, - 1.82753814e-05, 1.40917493e-05, 1.80028626e-05, 2.31023755e-05, - 2.67687990e-05, 2.96517364e-05, 3.08141743e-05, 2.18800727e-05, - 1.86665121e-05, 1.84858442e-05, 2.06768209e-05, 2.58999520e-05, - 2.99540512e-05, 3.08723286e-05, 3.05392399e-05, 2.26290876e-05, - 1.96527032e-05, 1.99106500e-05, 2.20249386e-05, 2.45227792e-05, - 2.69435483e-05, 2.95275083e-05, 3.04174661e-05, 2.33646472e-05, - 1.99900253e-05, 2.01717679e-05, 2.10378001e-05, 2.25171008e-05, - 2.60493409e-05, 2.93587756e-05, 3.07111280e-05, 3.05854260e-05, - 2.31620746e-05, 1.78328815e-05, 1.46173453e-05, 1.66324084e-05, - 2.32183334e-05, 3.00596907e-05, 3.13687809e-05, 3.01478839e-05, - 2.08657387e-05, 1.75308160e-05, 1.98256916e-05, 2.38722200e-05, - 2.55821800e-05, 2.75203894e-05, 2.97408576e-05, 3.02763266e-05, - 2.34426608e-05, 1.97963156e-05, 1.80172314e-05, 2.09460406e-05, - 2.46265952e-05, 2.84794569e-05, 3.05397152e-05, 3.02645199e-05, - 2.37956148e-05, 1.98999863e-05, 1.93572100e-05, 2.15035174e-05, - 2.44581462e-05, 2.74483322e-05, 3.01414339e-05, 3.00975123e-05, - 2.96055796e-05, 2.31689894e-05, 1.80222483e-05, 1.64378864e-05, - 2.05515740e-05, 2.57588307e-05, 2.89402189e-05, 3.13596525e-05, - 3.17773381e-05, 3.09251290e-05, 2.10084382e-05, 1.78701230e-05, - 1.85038473e-05, 2.27714429e-05, 2.80476455e-05, 2.96398600e-05, - 3.08556046e-05, 3.17431386e-05, 2.29520997e-05, 1.93320053e-05, - 1.89757534e-05, 2.05473731e-05, 2.33080430e-05, 2.72886752e-05, - 2.94639512e-05, 2.97021415e-05, 1.94141844e-05, 1.54784774e-05, - 1.84269772e-05, 2.52862705e-05, 3.01914305e-05, 3.03891514e-05, - 3.00866086e-05, 2.32718214e-05, 1.95698097e-05, 1.80543060e-05, - 1.97422889e-05, 2.43941146e-05, 2.78127351e-05, 2.94443940e-05, - 3.07557964e-05, - 2.33634612e-05, 1.75794995e-05, 1.63833861e-05, 1.86029703e-05, - 2.28644338e-05, 2.82055940e-05, 3.13191845e-05, 3.17445045e-05, - 3.18482692e-05, 2.43133314e-05, 2.05154893e-05, 2.16597150e-05, - 2.37156866e-05, 2.40587329e-05, 2.48469601e-05, 2.79838921e-05, - 3.09264088e-05, 3.09474288e-05, 3.07051063e-05, 3.20803268e-05, - 2.16663924e-05, 1.80729825e-05, 1.87334064e-05, 2.24153257e-05, - 2.46483133e-05, 2.57522257e-05, 2.97263213e-05, 3.32325542e-05, - 3.43466323e-05, 1.84809146e-05, 1.28101281e-05, 1.50006556e-05, - 2.33747812e-05, 2.97715452e-05, 3.16507195e-05, 3.24650689e-05, - 3.31614427e-05, 3.32562668e-05, 2.38297371e-05, 1.72493529e-05, - 1.59010796e-05, 2.11612892e-05, 2.64463304e-05, 2.72188163e-05, - 2.73172285e-05, 2.99989618e-05, 3.30136786e-05, 2.98727358e-05, - 2.39669784e-05, 1.61528683e-05, 1.30601403e-05, 1.62373479e-05, - 2.36553018e-05, 3.18059266e-05, 3.50490355e-05, 3.42039688e-05, - 1.93623826e-05, 1.42330908e-05, 1.52480510e-05, 2.05847127e-05, - 2.78618539e-05, 3.34843992e-05, 3.51869916e-05, 3.37747960e-05, - 1.76524251e-05, 1.32105153e-05, 1.50034317e-05, 2.13994754e-05, - 3.05632005e-05, 3.52124083e-05, 3.44699278e-05, 3.29182121e-05, - 1.61326509e-05, 1.15628736e-05, 1.62295147e-05, 2.31626223e-05, - 2.75499645e-05, 3.05260733e-05, 3.23349047e-05, 2.07388178e-05, - 1.70545509e-05, 1.66645339e-05, 1.88366066e-05, 2.54018677e-05, - 3.17606314e-05, 3.32181028e-05, 3.25927256e-05, 2.17279177e-05, - 1.81494511e-05, 1.84088313e-05, 2.10056670e-05, 2.38234175e-05, - 2.65726394e-05, 3.06571058e-05, 3.23907943e-05, 2.26988715e-05, - 1.83127027e-05, 1.84960747e-05, 1.98184767e-05, 2.14855865e-05, - 2.57641390e-05, 3.04744967e-05, 3.28296163e-05, 3.26687809e-05, - 2.38198043e-05, 1.66706857e-05, 1.21387516e-05, 1.38690292e-05, - 2.12616704e-05, 3.10980540e-05, 3.37483712e-05, 3.10203366e-05, - 1.94215656e-05, 1.57280428e-05, 1.84775455e-05, 2.37581755e-05, - 2.57063071e-05, 2.78686294e-05, 3.13133964e-05, 3.22661020e-05, - 2.41188302e-05, 1.86011713e-05, 1.57836284e-05, 1.92683142e-05, - 2.40886647e-05, 2.92778485e-05, 3.23792661e-05, 3.22093712e-05, - 2.31631047e-05, 1.82664588e-05, 1.75997811e-05, 2.05271698e-05, - 2.44882699e-05, 2.82809942e-05, 3.21836207e-05, 3.16364642e-05, - 3.03858744e-05, 2.28373603e-05, 1.60563972e-05, 1.38084094e-05, - 1.86385268e-05, 2.61154961e-05, 3.09404925e-05, 3.43325749e-05, - 3.48136976e-05, 3.32323227e-05, 2.02845734e-05, 1.66481970e-05, - 1.69294508e-05, 2.19423737e-05, 2.88253884e-05, 2.96532329e-05, - 3.15914445e-05, 3.41172892e-05, 2.17689955e-05, 1.78707040e-05, - 1.75720843e-05, 1.91335505e-05, 2.22786124e-05, 2.80988956e-05, - 3.12972942e-05, 3.09297263e-05, 1.82815324e-05, 1.36014277e-05, - 1.63822996e-05, 2.46311810e-05, 3.21304040e-05, 3.23903756e-05, - 3.15959700e-05, 2.30551776e-05, 1.83215333e-05, 1.61532927e-05, - 1.78348856e-05, 2.32918962e-05, 2.77851105e-05, 3.05120551e-05, - 3.31149766e-05, - 2.43719884e-05, 2.07870757e-05, 1.99247741e-05, 2.19261204e-05, - 2.48460329e-05, 2.71205374e-05, 2.81176125e-05, 2.80846776e-05, - 2.78619899e-05, 2.47475316e-05, 2.25857017e-05, 2.32208699e-05, - 2.46125598e-05, 2.48382744e-05, 2.52070043e-05, 2.69711818e-05, - 2.81674285e-05, 2.78478919e-05, 2.75337149e-05, 2.79868345e-05, - 2.36191248e-05, 2.12937453e-05, 2.14714139e-05, 2.40750854e-05, - 2.54448378e-05, 2.55665902e-05, 2.71332074e-05, 2.84959613e-05, - 2.88570895e-05, 2.15216819e-05, 1.71593836e-05, 1.89148628e-05, - 2.51372614e-05, 2.84343958e-05, 2.83611181e-05, 2.80874364e-05, - 2.83313508e-05, 2.83965336e-05, 2.55976528e-05, 2.14061659e-05, - 1.98605026e-05, 2.35923342e-05, 2.63859103e-05, 2.60670889e-05, - 2.56493809e-05, 2.68706501e-05, 2.81211372e-05, 2.81062074e-05, - 2.55364339e-05, 1.99282519e-05, 1.70700975e-05, 1.98043927e-05, - 2.47009952e-05, 2.82175219e-05, 2.89382553e-05, 2.85872829e-05, - 2.18193720e-05, 1.84877028e-05, 1.94686456e-05, 2.34121106e-05, - 2.72165593e-05, 2.90828480e-05, 2.93081744e-05, 2.86085713e-05, - 2.04345994e-05, 1.76426432e-05, 1.94252532e-05, 2.38534005e-05, - 2.82576424e-05, 2.93886104e-05, 2.87464210e-05, 2.82417964e-05, - 1.99645472e-05, 1.62791821e-05, 2.05638902e-05, 2.53633109e-05, - 2.67603931e-05, 2.70159178e-05, 2.76495311e-05, 2.32402082e-05, - 2.12005525e-05, 2.07082052e-05, 2.16419026e-05, 2.50904172e-05, - 2.79232179e-05, 2.83793196e-05, 2.81360111e-05, 2.38303489e-05, - 2.18313256e-05, 2.19379638e-05, 2.34784276e-05, 2.45677929e-05, - 2.54064459e-05, 2.72683879e-05, 2.80674464e-05, 2.43651060e-05, - 2.16534567e-05, 2.17305098e-05, 2.28428926e-05, 2.35985685e-05, - 2.53865582e-05, 2.72505448e-05, 2.81881683e-05, 2.81611801e-05, - 2.62124688e-05, 2.17016788e-05, 1.68341535e-05, 1.76617135e-05, - 2.23667572e-05, 2.71893693e-05, 2.83844794e-05, 2.70284135e-05, - 2.24010473e-05, 2.02599360e-05, 2.21812098e-05, 2.52577897e-05, - 2.58409137e-05, 2.63237598e-05, 2.77034678e-05, 2.80857250e-05, - 2.62770360e-05, 2.24445395e-05, 1.96416160e-05, 2.20291657e-05, - 2.48116781e-05, 2.68884164e-05, 2.79438546e-05, 2.80452057e-05, - 2.45093402e-05, 2.16956775e-05, 2.12357872e-05, 2.33934659e-05, - 2.55544345e-05, 2.68665516e-05, 2.81365373e-05, 2.76710190e-05, - 2.69191585e-05, 2.48106905e-05, 2.01865603e-05, 1.78250149e-05, - 2.14626018e-05, 2.61548202e-05, 2.81182850e-05, 2.88692242e-05, - 2.88873790e-05, 2.83439103e-05, 2.36595439e-05, 2.16001271e-05, - 2.11984230e-05, 2.39775786e-05, 2.68425231e-05, 2.61235659e-05, - 2.69125931e-05, 2.83605291e-05, 2.34848363e-05, 2.17762058e-05, - 2.17339066e-05, 2.23376315e-05, 2.38123047e-05, 2.68309065e-05, - 2.79536078e-05, 2.73686216e-05, 2.24126291e-05, 1.88882918e-05, - 2.02387383e-05, 2.47768605e-05, 2.80414047e-05, 2.80932903e-05, - 2.76430676e-05, 2.49983487e-05, 2.22624267e-05, 2.03337502e-05, - 2.11277837e-05, 2.39715032e-05, 2.59187603e-05, 2.72044223e-05, - 2.83959666e-05, - 2.52895236e-05, 2.83639635e-05, 2.89298219e-05, 2.84253375e-05, - 2.62831773e-05, 2.27982815e-05, 2.08476126e-05, 2.05140359e-05, - 2.03276441e-05, 2.46407196e-05, 2.66961199e-05, 2.60303082e-05, - 2.51389364e-05, 2.49842051e-05, 2.45019292e-05, 2.28951171e-05, - 2.11714945e-05, 2.09930261e-05, 2.10102374e-05, 2.02205692e-05, - 2.64477594e-05, 2.83450608e-05, 2.76485952e-05, 2.60480505e-05, - 2.49025783e-05, 2.39138133e-05, 2.15450679e-05, 1.96346464e-05, - 1.90184176e-05, 2.80677598e-05, 3.05313683e-05, 2.96096252e-05, - 2.59818111e-05, 2.22209579e-05, 2.07155138e-05, 1.99921116e-05, - 1.96127387e-05, 1.95753500e-05, 2.58880637e-05, 2.97413883e-05, - 2.96198753e-05, 2.70266924e-05, 2.38816850e-05, 2.29460057e-05, - 2.25495757e-05, 2.11713129e-05, 1.96208728e-05, 2.19721169e-05, - 2.56892810e-05, 2.93091416e-05, 2.98425924e-05, 2.89775688e-05, - 2.52841792e-05, 2.05325855e-05, 1.85838012e-05, 1.90090341e-05, - 2.72466444e-05, 3.02563827e-05, 3.01062230e-05, 2.75492170e-05, - 2.31585702e-05, 1.96934297e-05, 1.86190517e-05, 1.93076978e-05, - 2.77518799e-05, 3.06680720e-05, 3.04694300e-05, 2.70134126e-05, - 2.14985052e-05, 1.86279176e-05, 1.88940852e-05, 1.97427491e-05, - 2.93991182e-05, 3.14067417e-05, 3.01616931e-05, 2.64171770e-05, - 2.31375290e-05, 2.08520293e-05, 1.98696864e-05, 2.71640292e-05, - 2.97576527e-05, 2.96650377e-05, 2.77297070e-05, 2.38592345e-05, - 2.04225293e-05, 1.95943715e-05, 1.99240151e-05, 2.65959596e-05, - 2.89556038e-05, 2.87182727e-05, 2.70948626e-05, 2.49843477e-05, - 2.30239464e-05, 2.08985144e-05, 2.00357320e-05, 2.60129432e-05, - 2.84825750e-05, 2.83220266e-05, 2.78927822e-05, 2.66409290e-05, - 2.37575181e-05, 2.10281667e-05, 1.97805968e-05, 1.98817534e-05, - 2.64042977e-05, 3.10898273e-05, 3.13000389e-05, 2.94196814e-05, - 2.55423394e-05, 2.05214063e-05, 1.92322649e-05, 2.04870623e-05, - 2.78921657e-05, 3.05447672e-05, 2.89335815e-05, 2.56726928e-05, - 2.41745932e-05, 2.25603890e-05, 2.06413367e-05, 2.01340215e-05, - 2.61316790e-05, 2.90896548e-05, 2.94675024e-05, 2.76371521e-05, - 2.49292967e-05, 2.17557080e-05, 1.99845116e-05, 2.01555162e-05, - 2.56365563e-05, 2.86053428e-05, 2.89652166e-05, 2.76017883e-05, - 2.51580122e-05, 2.25712292e-05, 2.02177996e-05, 2.03851258e-05, - 2.09015968e-05, 2.62807577e-05, 2.98716150e-05, 2.98415146e-05, - 2.77684602e-05, 2.40232912e-05, 2.11362203e-05, 1.90324053e-05, - 1.87195656e-05, 1.95689974e-05, 2.82095038e-05, 3.09839258e-05, - 2.99535349e-05, 2.64950230e-05, 2.20976165e-05, 2.09623305e-05, - 2.00019173e-05, 1.89737099e-05, 2.61852699e-05, 2.92959574e-05, - 2.96925171e-05, 2.82061260e-05, 2.59383180e-05, 2.27042905e-05, - 2.07822612e-05, 2.07482069e-05, 2.95159867e-05, 3.22211753e-05, - 2.94149615e-05, 2.43455077e-05, 2.02107838e-05, 2.00483147e-05, - 2.04002916e-05, 2.62097441e-05, 2.92649334e-05, 2.99373587e-05, - 2.84647975e-05, 2.49808481e-05, 2.23443442e-05, 2.09727647e-05, - 1.96735159e-05, - 2.52943891e-05, 2.83451318e-05, 2.89052156e-05, 2.83981153e-05, - 2.62677164e-05, 2.28100516e-05, 2.08717975e-05, 2.05424051e-05, - 2.03607251e-05, 2.46517839e-05, 2.66938261e-05, 2.60337240e-05, - 2.51438339e-05, 2.49892726e-05, 2.45105342e-05, 2.29073192e-05, - 2.11912680e-05, 2.10187906e-05, 2.10395065e-05, 2.02533308e-05, - 2.64410899e-05, 2.83235126e-05, 2.76381466e-05, 2.60437760e-05, - 2.49027849e-05, 2.39272519e-05, 2.15726248e-05, 1.96674072e-05, - 1.90528099e-05, 2.80496697e-05, 3.04835667e-05, 2.95763355e-05, - 2.59682995e-05, 2.22241683e-05, 2.07382084e-05, 2.00261110e-05, - 1.96477351e-05, 1.96099344e-05, 2.58712208e-05, 2.96932113e-05, - 2.95826300e-05, 2.70106453e-05, 2.38868151e-05, 2.29675046e-05, - 2.25805328e-05, 2.12062015e-05, 1.96583098e-05, 2.19827629e-05, - 2.56762888e-05, 2.92774623e-05, 2.98085635e-05, 2.89526373e-05, - 2.52860089e-05, 2.05591298e-05, 1.86212497e-05, 1.90468655e-05, - 2.72407337e-05, 3.02118187e-05, 3.00612872e-05, 2.75257937e-05, - 2.31643116e-05, 1.97181349e-05, 1.86514450e-05, 1.93423638e-05, - 2.77457711e-05, 3.06170100e-05, 3.04175138e-05, 2.69952630e-05, - 2.15131897e-05, 1.86591762e-05, 1.89310460e-05, 1.97774963e-05, - 2.93655746e-05, 3.13406523e-05, 3.01104392e-05, 2.63941594e-05, - 2.31488577e-05, 2.08889601e-05, 1.99100802e-05, 2.71486813e-05, - 2.97104812e-05, 2.96225815e-05, 2.77167327e-05, 2.38782086e-05, - 2.04538478e-05, 1.96289722e-05, 1.99581494e-05, 2.65849925e-05, - 2.89193655e-05, 2.86856491e-05, 2.70786553e-05, 2.49920073e-05, - 2.30511717e-05, 2.09321028e-05, 2.00695088e-05, 2.60065394e-05, - 2.84562041e-05, 2.82980182e-05, 2.78681089e-05, 2.66312678e-05, - 2.37749816e-05, 2.10604758e-05, 1.98155986e-05, 1.99160281e-05, - 2.63720340e-05, 3.10128958e-05, 3.12365027e-05, 2.93931536e-05, - 2.55599677e-05, 2.05600784e-05, 1.92704101e-05, 2.05278828e-05, - 2.78709525e-05, 3.04875623e-05, 2.88952306e-05, 2.56628903e-05, - 2.41814317e-05, 2.25842045e-05, 2.06728201e-05, 2.01665324e-05, - 2.61032266e-05, 2.90464057e-05, 2.94341272e-05, 2.76231069e-05, - 2.49354496e-05, 2.17834604e-05, 2.00202949e-05, 2.01882815e-05, - 2.56347528e-05, 2.85764628e-05, 2.89327557e-05, 2.75776125e-05, - 2.51531682e-05, 2.25889213e-05, 2.02487969e-05, 2.04198144e-05, - 2.09390319e-05, 2.62656899e-05, 2.98279766e-05, 2.98065734e-05, - 2.77559947e-05, 2.40289355e-05, 2.11570204e-05, 1.90665101e-05, - 1.87564028e-05, 1.96042858e-05, 2.81722062e-05, 3.09098620e-05, - 2.99025960e-05, 2.64843883e-05, 2.21216483e-05, 2.10074702e-05, - 2.00491069e-05, 1.90146234e-05, 2.61840049e-05, 2.92537519e-05, - 2.96430700e-05, 2.81798338e-05, 2.59381507e-05, 2.27206376e-05, - 2.08091851e-05, 2.07823553e-05, 2.94649313e-05, 3.21349414e-05, - 2.93797747e-05, 2.43605957e-05, 2.02430000e-05, 2.00816491e-05, - 2.04351387e-05, 2.61939476e-05, 2.92197870e-05, 2.98916993e-05, - 2.84421341e-05, 2.49940111e-05, 2.23751667e-05, 2.10062289e-05, - 1.97071046e-05, - 2.48982001e-05, 2.37630106e-05, 2.33602918e-05, 2.48893812e-05, - 2.61580626e-05, 2.56746455e-05, 2.50868087e-05, 2.47695834e-05, - 2.43802432e-05, 2.47595916e-05, 2.42443364e-05, 2.43510889e-05, - 2.50175825e-05, 2.51196762e-05, 2.51048912e-05, 2.55985579e-05, - 2.54154174e-05, 2.49244840e-05, 2.46118958e-05, 2.44199234e-05, - 2.50542370e-05, 2.42253633e-05, 2.38909798e-05, 2.51952486e-05, - 2.56657080e-05, 2.49944284e-05, 2.46453954e-05, 2.44598830e-05, - 2.43212094e-05, 2.42410240e-05, 2.19235376e-05, 2.28993159e-05, - 2.62173739e-05, 2.66110115e-05, 2.52352552e-05, 2.43325856e-05, - 2.42677940e-05, 2.43046691e-05, 2.66224175e-05, 2.53460881e-05, - 2.37782769e-05, 2.54723085e-05, 2.58043770e-05, 2.47153731e-05, - 2.39858729e-05, 2.40727683e-05, 2.40557421e-05, 2.60328372e-05, - 2.63963647e-05, 2.36260469e-05, 2.14065505e-05, 2.32825286e-05, - 2.52195294e-05, 2.49259063e-05, 2.40384697e-05, 2.40266878e-05, - 2.39259432e-05, 2.29423033e-05, 2.37474792e-05, 2.56939351e-05, - 2.60785967e-05, 2.51455744e-05, 2.44693670e-05, 2.43020244e-05, - 2.30087823e-05, 2.24451095e-05, 2.39563105e-05, 2.57231267e-05, - 2.57925433e-05, 2.45656410e-05, 2.40975296e-05, 2.42836887e-05, - 2.37222540e-05, 2.16922092e-05, 2.48276860e-05, 2.68054961e-05, - 2.55797188e-05, 2.39559413e-05, 2.37812772e-05, 2.52288446e-05, - 2.51563092e-05, 2.46128359e-05, 2.41097501e-05, 2.44802129e-05, - 2.45233884e-05, 2.43026412e-05, 2.43259083e-05, 2.53768631e-05, - 2.51872178e-05, 2.51166235e-05, 2.54114821e-05, 2.48523335e-05, - 2.41271253e-05, 2.42479354e-05, 2.43484536e-05, 2.54564733e-05, - 2.46681400e-05, 2.46250127e-05, 2.53893881e-05, 2.51821557e-05, - 2.46905287e-05, 2.43370866e-05, 2.42595784e-05, 2.43165861e-05, - 2.77113156e-05, 2.66377593e-05, 2.21220451e-05, 2.16546512e-05, - 2.31901905e-05, 2.38574472e-05, 2.40025820e-05, 2.36693041e-05, - 2.49558699e-05, 2.48055466e-05, 2.55153489e-05, 2.60934146e-05, - 2.54819184e-05, 2.46596005e-05, 2.44789443e-05, 2.44502059e-05, - 2.75544204e-05, 2.58946411e-05, 2.34695537e-05, 2.44094118e-05, - 2.50499385e-05, 2.45702925e-05, 2.41774155e-05, 2.44260162e-05, - 2.53055024e-05, 2.47984435e-05, 2.46171392e-05, 2.57156122e-05, - 2.59843597e-05, 2.52209078e-05, 2.45740291e-05, 2.42316953e-05, - 2.39002691e-05, 2.61197919e-05, 2.42609989e-05, 2.20718425e-05, - 2.39691145e-05, 2.56809771e-05, 2.53326092e-05, 2.43461407e-05, - 2.40994538e-05, 2.42440459e-05, 2.64552433e-05, 2.64550083e-05, - 2.52963759e-05, 2.54452245e-05, 2.48051871e-05, 2.31754953e-05, - 2.31601840e-05, 2.37602749e-05, 2.47226653e-05, 2.53837087e-05, - 2.56342100e-05, 2.51277116e-05, 2.48522598e-05, 2.52941843e-05, - 2.48579806e-05, 2.42251414e-05, 2.61834452e-05, 2.46453055e-05, - 2.39900517e-05, 2.45566645e-05, 2.44685456e-05, 2.43859624e-05, - 2.42157244e-05, 2.62565148e-05, 2.58435834e-05, 2.44474378e-05, - 2.41544457e-05, 2.42709014e-05, 2.40841206e-05, 2.42445744e-05, - 2.43870789e-05, - 2.48280435e-05, 3.52757991e-05, 3.79856894e-05, 3.26081656e-05, - 2.47568772e-05, 1.81638957e-05, 1.52068877e-05, 1.49822010e-05, - 1.51212783e-05, 2.35847328e-05, 2.96360120e-05, 2.77187496e-05, - 2.42538433e-05, 2.37118056e-05, 2.26519338e-05, 1.84655735e-05, - 1.53972449e-05, 1.56836270e-05, 1.61247032e-05, 1.48702707e-05, - 2.72731136e-05, 3.40270301e-05, 3.29856869e-05, 2.60351613e-05, - 2.25663016e-05, 2.15422262e-05, 1.71278298e-05, 1.37484386e-05, - 1.28155543e-05, 3.32417092e-05, 4.74757600e-05, 4.13595830e-05, - 2.39795596e-05, 1.58384472e-05, 1.47830990e-05, 1.45529031e-05, - 1.39341945e-05, 1.38228857e-05, 2.30756570e-05, 3.49411500e-05, - 3.87784659e-05, 2.78113554e-05, 2.01663703e-05, 1.99090275e-05, - 2.02349085e-05, 1.71879647e-05, 1.42033382e-05, 1.61022312e-05, - 2.30305354e-05, 3.83210090e-05, 4.70912208e-05, 3.83466606e-05, - 2.42131594e-05, 1.48241460e-05, 1.23696229e-05, 1.31276150e-05, - 3.18211187e-05, 4.31800377e-05, 4.02690148e-05, 2.86121566e-05, - 1.83027421e-05, 1.30814093e-05, 1.19764004e-05, 1.33458969e-05, - 3.55841068e-05, 4.60932832e-05, 4.07065683e-05, 2.72710966e-05, - 1.55311511e-05, 1.18926527e-05, 1.28450669e-05, 1.41525676e-05, - 3.83059246e-05, 5.11770974e-05, 3.74021947e-05, 2.39040310e-05, - 1.89813132e-05, 1.67090795e-05, 1.50150485e-05, 2.86531460e-05, - 3.54594106e-05, 3.66142476e-05, 3.26614100e-05, 2.23079258e-05, - 1.51190475e-05, 1.38597097e-05, 1.44350102e-05, 2.69741364e-05, - 3.32747034e-05, 3.28275623e-05, 2.81013527e-05, 2.42049962e-05, - 2.10468800e-05, 1.63970832e-05, 1.46143652e-05, 2.54475584e-05, - 3.32929514e-05, 3.29742704e-05, 3.01065987e-05, 2.74774252e-05, - 2.17142008e-05, 1.65308267e-05, 1.42510818e-05, 1.43683456e-05, - 2.23761119e-05, 3.52750068e-05, 4.92396025e-05, 4.48409197e-05, - 2.90466237e-05, 1.61855333e-05, 1.35558198e-05, 1.63771363e-05, - 3.10777462e-05, 3.85146245e-05, 3.24428785e-05, 2.35160894e-05, - 2.12972122e-05, 1.91813653e-05, 1.55903492e-05, 1.46715737e-05, - 2.20658027e-05, 3.19662994e-05, 3.92279243e-05, 3.16926012e-05, - 2.37137938e-05, 1.76568985e-05, 1.47307454e-05, 1.47413634e-05, - 2.48627019e-05, 3.32986812e-05, 3.47059777e-05, 2.86939264e-05, - 2.25800822e-05, 1.83623689e-05, 1.46746190e-05, 1.54209259e-05, - 1.68876367e-05, 2.48212027e-05, 3.81371524e-05, 4.47575173e-05, - 3.31141476e-05, 2.06550713e-05, 1.54351055e-05, 1.28125338e-05, - 1.25385210e-05, 1.38827724e-05, 2.86210699e-05, 3.54449784e-05, - 3.56256986e-05, 2.65982845e-05, 1.80092220e-05, 1.80895118e-05, - 1.61103448e-05, 1.33701896e-05, 2.73191941e-05, 3.36859172e-05, - 3.41091599e-05, 3.14845614e-05, 2.64555296e-05, 1.85242401e-05, - 1.53717794e-05, 1.61326722e-05, 3.23767102e-05, 4.37023491e-05, - 3.76024389e-05, 2.32784179e-05, 1.47915847e-05, 1.45915985e-05, - 1.54707311e-05, 2.44150552e-05, 3.25236699e-05, 3.78089452e-05, - 3.45325337e-05, 2.53156624e-05, 1.96276507e-05, 1.65484548e-05, - 1.39036461e-05, - 2.57013476e-05, 3.05692201e-05, 3.16232209e-05, 2.88368879e-05, - 2.47948847e-05, 2.13524296e-05, 1.95333422e-05, 1.95300552e-05, - 1.98618536e-05, 2.51686385e-05, 2.82948854e-05, 2.74307792e-05, - 2.53318042e-05, 2.49845630e-05, 2.44328058e-05, 2.15989694e-05, - 1.95013931e-05, 1.99975866e-05, 2.05169038e-05, 1.96351304e-05, - 2.67130052e-05, 2.98167216e-05, 2.97691205e-05, 2.60611492e-05, - 2.40118946e-05, 2.38847182e-05, 2.12439059e-05, 1.86682281e-05, - 1.79115947e-05, 2.95619381e-05, 3.45579435e-05, 3.27544111e-05, - 2.43776326e-05, 1.91911278e-05, 1.91138438e-05, 1.94220269e-05, - 1.89332210e-05, 1.88168389e-05, 2.36582464e-05, 2.91682237e-05, - 3.14353302e-05, 2.66342019e-05, 2.25509535e-05, 2.30823469e-05, - 2.37698797e-05, 2.16373693e-05, 1.92817862e-05, 1.96967463e-05, - 2.37803404e-05, 3.14662464e-05, 3.50401945e-05, 3.17772811e-05, - 2.51705999e-05, 1.93157757e-05, 1.76446292e-05, 1.83511128e-05, - 2.93508472e-05, 3.30252653e-05, 3.17743460e-05, 2.67959816e-05, - 2.12071225e-05, 1.77264588e-05, 1.70534339e-05, 1.83996254e-05, - 3.13114098e-05, 3.38962908e-05, 3.16732209e-05, 2.62270634e-05, - 1.93987729e-05, 1.69259360e-05, 1.80559077e-05, 1.91117130e-05, - 3.13780989e-05, 3.50582874e-05, 3.02208871e-05, 2.39556843e-05, - 2.19477573e-05, 2.13531285e-05, 2.01208544e-05, 2.71553010e-05, - 2.94613804e-05, 3.02080084e-05, 2.94831035e-05, 2.46692076e-05, - 1.97786957e-05, 1.88498297e-05, 1.93271469e-05, 2.63487398e-05, - 2.88102757e-05, 2.87269784e-05, 2.67978525e-05, 2.54232070e-05, - 2.41758907e-05, 2.09398205e-05, 1.94642947e-05, 2.56038237e-05, - 2.92304123e-05, 2.91651857e-05, 2.75901104e-05, 2.67063819e-05, - 2.41874206e-05, 2.09876329e-05, 1.92088468e-05, 1.92762982e-05, - 2.26209028e-05, 2.82485040e-05, 3.45091387e-05, 3.45155728e-05, - 2.89040496e-05, 2.10126458e-05, 1.87476464e-05, 2.12759305e-05, - 2.82703296e-05, 3.04925058e-05, 2.82936628e-05, 2.42270728e-05, - 2.34239083e-05, 2.26507451e-05, 2.01796045e-05, 1.94547297e-05, - 2.25536304e-05, 2.78500897e-05, 3.18073559e-05, 2.89151106e-05, - 2.50337964e-05, 2.16687209e-05, 1.96573871e-05, 1.95258561e-05, - 2.54310037e-05, 2.91273115e-05, 2.96926618e-05, 2.68122930e-05, - 2.38105792e-05, 2.17580813e-05, 1.93882108e-05, 2.01882663e-05, - 2.15215547e-05, 2.48513302e-05, 3.08715482e-05, 3.40917150e-05, - 2.97456361e-05, 2.29210753e-05, 1.95763899e-05, 1.78958503e-05, - 1.77713388e-05, 1.89018052e-05, 2.62516557e-05, 2.84324917e-05, - 2.93923702e-05, 2.61351471e-05, 2.17711258e-05, 2.28666052e-05, - 2.13829358e-05, 1.87145925e-05, 2.69784767e-05, 2.87793619e-05, - 2.87062829e-05, 2.82775663e-05, 2.65006927e-05, 2.18217926e-05, - 1.97913093e-05, 2.07509604e-05, 2.77632856e-05, 3.15544313e-05, - 3.09798631e-05, 2.51485501e-05, 1.95432856e-05, 1.94243785e-05, - 2.02373217e-05, 2.45647482e-05, 2.80671175e-05, 3.06366009e-05, - 3.00254943e-05, 2.63934600e-05, 2.33152956e-05, 2.10565073e-05, - 1.88417477e-05, - 2.48644288e-05, 2.23438245e-05, 2.16827426e-05, 2.26628217e-05, - 2.42814024e-05, 2.60093543e-05, 2.67584324e-05, 2.69561070e-05, - 2.71560763e-05, 2.52572066e-05, 2.38198174e-05, 2.43243155e-05, - 2.49582937e-05, 2.50490411e-05, 2.53231186e-05, 2.59936618e-05, - 2.65586716e-05, 2.67914544e-05, 2.69032323e-05, 2.71607357e-05, - 2.41242313e-05, 2.25257341e-05, 2.29815465e-05, 2.43988108e-05, - 2.50679076e-05, 2.56463558e-05, 2.67320827e-05, 2.72286610e-05, - 2.73416830e-05, 2.27542307e-05, 1.93110569e-05, 2.08289639e-05, - 2.44508617e-05, 2.58678013e-05, 2.67198254e-05, 2.72398523e-05, - 2.73251305e-05, 2.73115553e-05, 2.44784683e-05, 2.17805736e-05, - 2.12731258e-05, 2.37815655e-05, 2.55473944e-05, 2.61588084e-05, - 2.64626005e-05, 2.70298026e-05, 2.74247289e-05, 2.61420283e-05, - 2.45988014e-05, 2.14733687e-05, 1.96117298e-05, 2.16034198e-05, - 2.48713807e-05, 2.68858059e-05, 2.75056156e-05, 2.75023743e-05, - 2.33154312e-05, 2.02544701e-05, 2.08323803e-05, 2.34568988e-05, - 2.57746745e-05, 2.68707134e-05, 2.72497091e-05, 2.73376908e-05, - 2.25639244e-05, 1.95473849e-05, 2.06179682e-05, 2.38153679e-05, - 2.63399240e-05, 2.71913970e-05, 2.74690230e-05, 2.73005962e-05, - 2.14392987e-05, 1.82632999e-05, 2.12642690e-05, 2.41881970e-05, - 2.59048255e-05, 2.71723304e-05, 2.75007914e-05, 2.36566220e-05, - 2.17068295e-05, 2.15879360e-05, 2.29843113e-05, 2.57181384e-05, - 2.70772656e-05, 2.73103821e-05, 2.72540316e-05, 2.40572726e-05, - 2.23385272e-05, 2.25001969e-05, 2.37285446e-05, 2.50509723e-05, - 2.62018905e-05, 2.70617865e-05, 2.72253601e-05, 2.44334237e-05, - 2.25556849e-05, 2.26687355e-05, 2.31704789e-05, 2.40081399e-05, - 2.57578825e-05, 2.69931371e-05, 2.73064466e-05, 2.72649236e-05, - 2.41171048e-05, 2.11429719e-05, 1.87037256e-05, 2.02196481e-05, - 2.44708887e-05, 2.73065737e-05, 2.74977880e-05, 2.73810124e-05, - 2.30821529e-05, 2.09407651e-05, 2.24404099e-05, 2.46263436e-05, - 2.54591179e-05, 2.63415105e-05, 2.70464901e-05, 2.71633971e-05, - 2.42632610e-05, 2.24138520e-05, 2.12591536e-05, 2.31419171e-05, - 2.50824518e-05, 2.66815537e-05, 2.73095337e-05, 2.71701579e-05, - 2.46602134e-05, 2.24981107e-05, 2.21568449e-05, 2.34241684e-05, - 2.49082663e-05, 2.62097138e-05, 2.70943793e-05, 2.72033770e-05, - 2.71735674e-05, 2.42830041e-05, 2.12734421e-05, 2.00932511e-05, - 2.29093063e-05, 2.55037944e-05, 2.65993006e-05, 2.73275090e-05, - 2.74709651e-05, 2.73418993e-05, 2.31098190e-05, 2.11698931e-05, - 2.15992610e-05, 2.41284115e-05, 2.64934919e-05, 2.73470223e-05, - 2.77024782e-05, 2.76450860e-05, 2.42651439e-05, 2.21338339e-05, - 2.19034154e-05, 2.28881107e-05, 2.44450326e-05, 2.61409866e-05, - 2.68650936e-05, 2.71128666e-05, 2.21707367e-05, 1.94532998e-05, - 2.15447217e-05, 2.54353911e-05, 2.71416469e-05, 2.72065762e-05, - 2.72061009e-05, 2.43220126e-05, 2.22751315e-05, 2.12968876e-05, - 2.24039388e-05, 2.50335187e-05, 2.65465983e-05, 2.70406526e-05, - 2.72600659e-05, - 2.54111587e-05, 2.63910102e-05, 2.64610249e-05, 2.62877631e-05, - 2.54282134e-05, 2.39394318e-05, 2.29340667e-05, 2.28422355e-05, - 2.28886865e-05, 2.51921066e-05, 2.60119959e-05, 2.58031454e-05, - 2.53184972e-05, 2.52256914e-05, 2.50241497e-05, 2.40263470e-05, - 2.30106140e-05, 2.31102687e-05, 2.32627530e-05, 2.27918525e-05, - 2.57719846e-05, 2.63502887e-05, 2.62712540e-05, 2.56061709e-05, - 2.50196611e-05, 2.47893998e-05, 2.36010865e-05, 2.23272347e-05, - 2.18987897e-05, 2.63041969e-05, 2.62813533e-05, 2.64704647e-05, - 2.52959606e-05, 2.31812312e-05, 2.27703339e-05, 2.26633465e-05, - 2.24041466e-05, 2.23568551e-05, 2.51332116e-05, 2.64380725e-05, - 2.65000671e-05, 2.58512814e-05, 2.44845374e-05, 2.43973517e-05, - 2.44550917e-05, 2.36053433e-05, 2.25136141e-05, 2.32741993e-05, - 2.51222655e-05, 2.64833556e-05, 2.62506736e-05, 2.64644026e-05, - 2.53170176e-05, 2.27825360e-05, 2.16766641e-05, 2.20401730e-05, - 2.61901237e-05, 2.64616145e-05, 2.65163265e-05, 2.59506200e-05, - 2.39848855e-05, 2.20344575e-05, 2.14830542e-05, 2.21452796e-05, - 2.63605247e-05, 2.63668128e-05, 2.65287529e-05, 2.57891986e-05, - 2.30644553e-05, 2.14404822e-05, 2.19090402e-05, 2.24971768e-05, - 2.64881346e-05, 2.60885601e-05, 2.65140347e-05, 2.52886510e-05, - 2.41711816e-05, 2.34459183e-05, 2.28330340e-05, 2.59432458e-05, - 2.64561695e-05, 2.64820884e-05, 2.62599928e-05, 2.49362457e-05, - 2.28907745e-05, 2.23727534e-05, 2.26151966e-05, 2.57419405e-05, - 2.63414426e-05, 2.63101988e-05, 2.58846634e-05, 2.53051577e-05, - 2.46517658e-05, 2.33487604e-05, 2.26884975e-05, 2.55248057e-05, - 2.63249553e-05, 2.63028366e-05, 2.60981225e-05, 2.58018825e-05, - 2.48182867e-05, 2.33965800e-05, 2.25379005e-05, 2.25876264e-05, - 2.49964599e-05, 2.64772115e-05, 2.62225066e-05, 2.63360959e-05, - 2.58974406e-05, 2.32648515e-05, 2.22336564e-05, 2.33250795e-05, - 2.61723448e-05, 2.65390031e-05, 2.62949629e-05, 2.52101941e-05, - 2.47461970e-05, 2.42062296e-05, 2.30674541e-05, 2.27135204e-05, - 2.49320609e-05, 2.62687686e-05, 2.64906228e-05, 2.62019984e-05, - 2.52241435e-05, 2.37656211e-05, 2.27314226e-05, 2.27409333e-05, - 2.54282877e-05, 2.63301149e-05, 2.64025249e-05, 2.59602727e-05, - 2.50279354e-05, 2.39902298e-05, 2.27170765e-05, 2.29989673e-05, - 2.35031107e-05, 2.54382179e-05, 2.65101834e-05, 2.63728302e-05, - 2.62834385e-05, 2.46013866e-05, 2.30239066e-05, 2.18977397e-05, - 2.17611356e-05, 2.23815741e-05, 2.59651649e-05, 2.64826780e-05, - 2.64673334e-05, 2.56927148e-05, 2.38778062e-05, 2.38485071e-05, - 2.32150406e-05, 2.21452152e-05, 2.57670355e-05, 2.63721613e-05, - 2.64026989e-05, 2.62114782e-05, 2.56557798e-05, 2.40381675e-05, - 2.29931983e-05, 2.32565416e-05, 2.63042794e-05, 2.65355715e-05, - 2.64849608e-05, 2.51288304e-05, 2.27617345e-05, 2.26800743e-05, - 2.30171648e-05, 2.53722629e-05, 2.63083059e-05, 2.65103562e-05, - 2.63742506e-05, 2.54666947e-05, 2.43062292e-05, 2.34001708e-05, - 2.23932695e-05, - 2.45054802e-05, 2.10887075e-05, 2.02598719e-05, 2.18848420e-05, - 2.44246878e-05, 2.67918018e-05, 2.78871645e-05, 2.79988823e-05, - 2.79916672e-05, 2.49517053e-05, 2.29012072e-05, 2.35434512e-05, - 2.46972261e-05, 2.48793182e-05, 2.52539735e-05, 2.66932894e-05, - 2.77846753e-05, 2.77407145e-05, 2.76191246e-05, 2.80740737e-05, - 2.36499999e-05, 2.14648629e-05, 2.18153812e-05, 2.40645296e-05, - 2.52354005e-05, 2.56566037e-05, 2.72620329e-05, 2.84486762e-05, - 2.87678185e-05, 2.17162561e-05, 1.75190018e-05, 1.92563226e-05, - 2.46888673e-05, 2.74868849e-05, 2.80143329e-05, 2.81916437e-05, - 2.84075578e-05, 2.84408171e-05, 2.49629684e-05, 2.11086959e-05, - 2.00028045e-05, 2.34358280e-05, 2.60700504e-05, 2.62628669e-05, - 2.62023622e-05, 2.72919718e-05, 2.83387341e-05, 2.74698799e-05, - 2.50020216e-05, 2.01480738e-05, 1.76270556e-05, 2.01518009e-05, - 2.46956196e-05, 2.80356525e-05, 2.89407807e-05, 2.86998701e-05, - 2.21930277e-05, 1.87217871e-05, 1.95542785e-05, 2.31480574e-05, - 2.66986745e-05, 2.85843106e-05, 2.90107195e-05, 2.85986529e-05, - 2.10163637e-05, 1.78990664e-05, 1.94150028e-05, 2.35993935e-05, - 2.76943542e-05, 2.90239033e-05, 2.87835227e-05, 2.83324945e-05, - 2.01490525e-05, 1.65113395e-05, 2.03729069e-05, 2.46557576e-05, - 2.65126721e-05, 2.74728203e-05, 2.80858713e-05, 2.31694684e-05, - 2.09578123e-05, 2.06289960e-05, 2.19104168e-05, 2.54243832e-05, - 2.79778575e-05, 2.84287514e-05, 2.82324664e-05, 2.37282279e-05, - 2.16506172e-05, 2.17994106e-05, 2.33422555e-05, 2.47267998e-05, - 2.59003819e-05, 2.75578866e-05, 2.81690375e-05, 2.42470210e-05, - 2.16768091e-05, 2.17820520e-05, 2.26718988e-05, 2.35711000e-05, - 2.56199668e-05, 2.75023709e-05, 2.83017285e-05, 2.82560716e-05, - 2.50828969e-05, 2.09033711e-05, 1.70311766e-05, 1.82606288e-05, - 2.31462568e-05, 2.76674289e-05, 2.85615533e-05, 2.76149699e-05, - 2.23805472e-05, 2.00331306e-05, 2.18965128e-05, 2.48623182e-05, - 2.57006396e-05, 2.65281128e-05, 2.78190659e-05, 2.81389510e-05, - 2.52095835e-05, 2.20226937e-05, 1.98778092e-05, 2.22110190e-05, - 2.48841404e-05, 2.70809134e-05, 2.81465020e-05, 2.81176187e-05, - 2.44621389e-05, 2.16673427e-05, 2.12280961e-05, 2.31188481e-05, - 2.52005806e-05, 2.67682133e-05, 2.81248549e-05, 2.79023266e-05, - 2.74137539e-05, 2.44059893e-05, 2.01772510e-05, 1.82825441e-05, - 2.17703669e-05, 2.59092545e-05, 2.77812481e-05, 2.87659245e-05, - 2.88808482e-05, 2.84272813e-05, 2.30800996e-05, 2.08656543e-05, - 2.08964214e-05, 2.38515594e-05, 2.69337323e-05, 2.70334520e-05, - 2.77496063e-05, 2.86479164e-05, 2.36569196e-05, 2.15053992e-05, - 2.13524960e-05, 2.22356929e-05, 2.39445388e-05, 2.67035023e-05, - 2.78555802e-05, 2.76533732e-05, 2.18662637e-05, 1.85011433e-05, - 2.03538422e-05, 2.50745753e-05, 2.80960176e-05, 2.81729254e-05, - 2.78864963e-05, 2.45338138e-05, 2.18458480e-05, 2.02685808e-05, - 2.13070782e-05, 2.43776300e-05, 2.64140569e-05, 2.75045944e-05, - 2.84050056e-05, - 2.36836706e-05, 1.85400989e-05, 1.74286035e-05, 1.98758614e-05, - 2.40064542e-05, 2.81548852e-05, 3.03571713e-05, 3.04616736e-05, - 3.02280643e-05, 2.43601618e-05, 2.10695402e-05, 2.20240316e-05, - 2.40365186e-05, 2.43738837e-05, 2.50018219e-05, 2.79138182e-05, - 3.02836630e-05, 2.99086572e-05, 2.94562212e-05, 3.04568678e-05, - 2.24131643e-05, 1.91411806e-05, 1.95001790e-05, 2.30930923e-05, - 2.51872854e-05, 2.56647314e-05, 2.86681854e-05, 3.14763222e-05, - 3.23222999e-05, 1.94701013e-05, 1.40843969e-05, 1.61602138e-05, - 2.44648639e-05, 3.02087651e-05, 3.07655061e-05, 3.07093427e-05, - 3.12469508e-05, 3.13605337e-05, 2.50854435e-05, 1.89918613e-05, - 1.72295752e-05, 2.22311323e-05, 2.67665487e-05, 2.66671591e-05, - 2.62454441e-05, 2.84557906e-05, 3.09368769e-05, 2.98524815e-05, - 2.50657450e-05, 1.73630518e-05, 1.40863057e-05, 1.72814289e-05, - 2.41076614e-05, 3.06436869e-05, 3.26756733e-05, 3.19281126e-05, - 2.00071792e-05, 1.55783366e-05, 1.67000575e-05, 2.18784432e-05, - 2.81500963e-05, 3.23065523e-05, 3.32099438e-05, 3.18057216e-05, - 1.82492860e-05, 1.45882041e-05, 1.65899767e-05, 2.25593027e-05, - 3.02682390e-05, 3.33256944e-05, 3.22238207e-05, 3.10529209e-05, - 1.73883117e-05, 1.30291810e-05, 1.79369943e-05, 2.46291470e-05, - 2.75365665e-05, 2.87939376e-05, 3.01354177e-05, 2.17610199e-05, - 1.87489298e-05, 1.81953160e-05, 1.96865787e-05, 2.50537500e-05, - 3.02722644e-05, 3.13259892e-05, 3.08120499e-05, 2.26387487e-05, - 1.96509253e-05, 1.98274660e-05, 2.20726991e-05, 2.40244759e-05, - 2.57521399e-05, 2.91298034e-05, 3.06597895e-05, 2.34702376e-05, - 1.95389709e-05, 1.96646829e-05, 2.10998342e-05, 2.23374092e-05, - 2.54780358e-05, 2.90490779e-05, 3.09566578e-05, 3.08687504e-05, - 2.57265173e-05, 1.90764747e-05, 1.36302910e-05, 1.47962634e-05, - 2.10854846e-05, 2.91820840e-05, 3.15148820e-05, 2.89691326e-05, - 2.05640435e-05, 1.75209383e-05, 2.00713854e-05, 2.47105479e-05, - 2.59417979e-05, 2.71558247e-05, 2.98593631e-05, 3.06397826e-05, - 2.58927440e-05, 2.03521369e-05, 1.70070535e-05, 2.01724801e-05, - 2.43559696e-05, 2.82421912e-05, 3.05056285e-05, 3.05712878e-05, - 2.37599070e-05, 1.95632906e-05, 1.89462864e-05, 2.18426847e-05, - 2.52510011e-05, 2.78932757e-05, 3.06736607e-05, 2.99284722e-05, - 2.86368207e-05, 2.39621177e-05, 1.75570992e-05, 1.49111769e-05, - 1.94637569e-05, 2.64094547e-05, 3.02294296e-05, 3.23329184e-05, - 3.25263006e-05, 3.12868673e-05, 2.20227370e-05, 1.89788898e-05, - 1.87087424e-05, 2.28499796e-05, 2.80432587e-05, 2.75001329e-05, - 2.90194325e-05, 3.16118712e-05, 2.23137448e-05, 1.95154752e-05, - 1.93853988e-05, 2.04170682e-05, 2.27910300e-05, 2.77939789e-05, - 3.01526419e-05, 2.93366675e-05, 2.02234870e-05, 1.57177457e-05, - 1.77003179e-05, 2.44889794e-05, 3.05399450e-05, 3.06911477e-05, - 2.98816670e-05, 2.42215429e-05, 2.00978269e-05, 1.77138064e-05, - 1.89205155e-05, 2.32597687e-05, 2.66849044e-05, 2.90077887e-05, - 3.13112143e-05, - 2.49658440e-05, 2.36571847e-05, 2.32236480e-05, 2.44785232e-05, - 2.56593548e-05, 2.56299874e-05, 2.53138979e-05, 2.51348272e-05, - 2.49183049e-05, 2.49482318e-05, 2.43206906e-05, 2.44991946e-05, - 2.50608516e-05, 2.51433529e-05, 2.51820333e-05, 2.55834380e-05, - 2.54968266e-05, 2.52284360e-05, 2.50555873e-05, 2.49372512e-05, - 2.49186011e-05, 2.40085652e-05, 2.38952958e-05, 2.50669676e-05, - 2.54947056e-05, 2.51641432e-05, 2.50714211e-05, 2.49346561e-05, - 2.48225603e-05, 2.40740373e-05, 2.16278500e-05, 2.26943813e-05, - 2.57298853e-05, 2.61443024e-05, 2.53893718e-05, 2.48826310e-05, - 2.48319652e-05, 2.48496575e-05, 2.59880498e-05, 2.45538723e-05, - 2.33961068e-05, 2.51161794e-05, 2.56559433e-05, 2.50603754e-05, - 2.46360111e-05, 2.47461233e-05, 2.47186302e-05, 2.58371114e-05, - 2.58696474e-05, 2.33472180e-05, 2.13622440e-05, 2.31515090e-05, - 2.51748631e-05, 2.52193020e-05, 2.46424184e-05, 2.46695427e-05, - 2.39958998e-05, 2.25689144e-05, 2.32588523e-05, 2.51869683e-05, - 2.58470960e-05, 2.52905110e-05, 2.48616957e-05, 2.48329009e-05, - 2.32038927e-05, 2.20424571e-05, 2.33381761e-05, 2.52850430e-05, - 2.57035472e-05, 2.49099615e-05, 2.46980935e-05, 2.48464830e-05, - 2.34022699e-05, 2.11728708e-05, 2.40819266e-05, 2.60464741e-05, - 2.55630894e-05, 2.46823297e-05, 2.45760132e-05, 2.49309712e-05, - 2.44119049e-05, 2.40272353e-05, 2.40415325e-05, 2.48456093e-05, - 2.49988756e-05, 2.48495572e-05, 2.48765523e-05, 2.51137464e-05, - 2.45929143e-05, 2.45870296e-05, 2.50652508e-05, 2.49710249e-05, - 2.46912660e-05, 2.48499827e-05, 2.48927180e-05, 2.52424933e-05, - 2.43075775e-05, 2.43067014e-05, 2.49246397e-05, 2.49771566e-05, - 2.49874386e-05, 2.49003330e-05, 2.48351690e-05, 2.48699098e-05, - 2.65871201e-05, 2.52069933e-05, 2.15869788e-05, 2.16937531e-05, - 2.37521709e-05, 2.46269166e-05, 2.46708422e-05, 2.45182792e-05, - 2.46219316e-05, 2.39803432e-05, 2.48307035e-05, 2.56850826e-05, - 2.54429855e-05, 2.50473918e-05, 2.49784487e-05, 2.49510382e-05, - 2.65189091e-05, 2.50681270e-05, 2.31876553e-05, 2.42768459e-05, - 2.51045102e-05, 2.50239567e-05, 2.47980094e-05, 2.49386280e-05, - 2.51899952e-05, 2.43788926e-05, 2.41754900e-05, 2.51935117e-05, - 2.56674432e-05, 2.53773110e-05, 2.50205891e-05, 2.48373559e-05, - 2.46494017e-05, 2.56354793e-05, 2.37142799e-05, 2.19423485e-05, - 2.39303729e-05, 2.55737365e-05, 2.54518209e-05, 2.48363898e-05, - 2.46851820e-05, 2.48171692e-05, 2.55934875e-05, 2.50991351e-05, - 2.44743760e-05, 2.51728413e-05, 2.51513380e-05, 2.42140069e-05, - 2.42218725e-05, 2.45267798e-05, 2.47315124e-05, 2.46688250e-05, - 2.47714101e-05, 2.46881666e-05, 2.48533275e-05, 2.54149929e-05, - 2.51888274e-05, 2.48370499e-05, 2.51915648e-05, 2.34539787e-05, - 2.36067874e-05, 2.48477847e-05, 2.49633778e-05, 2.49134400e-05, - 2.48287050e-05, 2.57294887e-05, 2.50006790e-05, 2.38426440e-05, - 2.39319082e-05, 2.45874833e-05, 2.47093412e-05, 2.48477627e-05, - 2.48982748e-05, - 2.46511890e-05, 2.20874188e-05, 2.14070553e-05, 2.32247520e-05, - 2.54622956e-05, 2.65296842e-05, 2.68004619e-05, 2.66343829e-05, - 2.63327860e-05, 2.48034140e-05, 2.33459306e-05, 2.37582960e-05, - 2.48394544e-05, 2.50116370e-05, 2.52131218e-05, 2.64132849e-05, - 2.69800211e-05, 2.65803869e-05, 2.62664483e-05, 2.64177026e-05, - 2.42863922e-05, 2.25776554e-05, 2.25462160e-05, 2.46090309e-05, - 2.55921641e-05, 2.53656951e-05, 2.60667329e-05, 2.67053823e-05, - 2.68280003e-05, 2.27196513e-05, 1.91435229e-05, 2.06097546e-05, - 2.56549399e-05, 2.76732948e-05, 2.69999650e-05, 2.64295581e-05, - 2.65271920e-05, 2.65790433e-05, 2.60919612e-05, 2.30959615e-05, - 2.15341993e-05, 2.44468549e-05, 2.61812021e-05, 2.55180627e-05, - 2.49588997e-05, 2.56600009e-05, 2.63154821e-05, 2.72310591e-05, - 2.59600644e-05, 2.15151026e-05, 1.88896980e-05, 2.13031910e-05, - 2.49770791e-05, 2.67785007e-05, 2.67333674e-05, 2.65453264e-05, - 2.27654688e-05, 2.03632694e-05, 2.12821249e-05, 2.44339102e-05, - 2.67642124e-05, 2.73408023e-05, 2.71343059e-05, 2.66889426e-05, - 2.15702279e-05, 1.96455349e-05, 2.13367894e-05, 2.47039833e-05, - 2.72029258e-05, 2.72227083e-05, 2.66623924e-05, 2.64876836e-05, - 2.15753612e-05, 1.84987959e-05, 2.23776688e-05, 2.60352369e-05, - 2.62887011e-05, 2.56831708e-05, 2.59365541e-05, 2.41396609e-05, - 2.28957214e-05, 2.23808166e-05, 2.27369823e-05, 2.48724072e-05, - 2.64327528e-05, 2.65690332e-05, 2.64520272e-05, 2.45449357e-05, - 2.32888229e-05, 2.33241360e-05, 2.43550060e-05, 2.47423698e-05, - 2.48895545e-05, 2.59546159e-05, 2.64265247e-05, 2.48870128e-05, - 2.29722137e-05, 2.30005741e-05, 2.39730519e-05, 2.43285282e-05, - 2.51306076e-05, 2.59866983e-05, 2.64479687e-05, 2.64608725e-05, - 2.69090394e-05, 2.37850771e-05, 1.90131357e-05, 1.93523571e-05, - 2.27722539e-05, 2.57292767e-05, 2.64279192e-05, 2.55551335e-05, - 2.35336678e-05, 2.21823847e-05, 2.36310803e-05, 2.56708276e-05, - 2.57343560e-05, 2.56335915e-05, 2.62949492e-05, 2.64843824e-05, - 2.68795557e-05, 2.39421021e-05, 2.12786876e-05, 2.30890069e-05, - 2.49662651e-05, 2.58998794e-05, 2.62801078e-05, 2.64514932e-05, - 2.49049539e-05, 2.30503270e-05, 2.27014584e-05, 2.44319604e-05, - 2.57926048e-05, 2.61851989e-05, 2.65698248e-05, 2.61613973e-05, - 2.56054523e-05, 2.54256795e-05, 2.19237752e-05, 1.96154744e-05, - 2.25731563e-05, 2.59976817e-05, 2.69151990e-05, 2.68463423e-05, - 2.67365790e-05, 2.65224436e-05, 2.48939833e-05, 2.36512630e-05, - 2.29499676e-05, 2.46589974e-05, 2.59827812e-05, 2.48413762e-05, - 2.52526223e-05, 2.62985734e-05, 2.40683083e-05, 2.33347397e-05, - 2.34093453e-05, 2.35666599e-05, 2.43117968e-05, 2.61988517e-05, - 2.66059123e-05, 2.59974516e-05, 2.40390309e-05, 2.12644185e-05, - 2.18482926e-05, 2.47309153e-05, 2.64695873e-05, 2.64579617e-05, - 2.61390323e-05, 2.55918320e-05, 2.38121549e-05, 2.20872055e-05, - 2.24497875e-05, 2.41521670e-05, 2.51506548e-05, 2.59188480e-05, - 2.66180769e-05, - 2.45268309e-05, 3.67493916e-05, 4.00572082e-05, 3.33896662e-05, - 2.42651041e-05, 1.71326336e-05, 1.40548952e-05, 1.38462196e-05, - 1.40257712e-05, 2.31601938e-05, 3.00882047e-05, 2.78768788e-05, - 2.38682271e-05, 2.32507029e-05, 2.20790818e-05, 1.74634657e-05, - 1.42265466e-05, 1.45701407e-05, 1.50646034e-05, 1.37585298e-05, - 2.72526378e-05, 3.51801093e-05, 3.40369486e-05, 2.58347575e-05, - 2.19110957e-05, 2.08716698e-05, 1.61285376e-05, 1.25837357e-05, - 1.16291703e-05, 3.42604010e-05, 5.20120406e-05, 4.42289738e-05, - 2.33961201e-05, 1.45876853e-05, 1.35991658e-05, 1.34331336e-05, - 1.27921324e-05, 1.26733157e-05, 2.23477380e-05, 3.60029558e-05, - 4.08929514e-05, 2.77923730e-05, 1.92742735e-05, 1.91202681e-05, - 1.95638299e-05, 1.62505037e-05, 1.30902734e-05, 1.49132794e-05, - 2.23271278e-05, 4.03877755e-05, 5.17227562e-05, 4.05077083e-05, - 2.37939142e-05, 1.36675644e-05, 1.11907387e-05, 1.19732029e-05, - 3.26742671e-05, 4.64185013e-05, 4.26801804e-05, 2.86619629e-05, - 1.72403072e-05, 1.18433404e-05, 1.07587179e-05, 1.21783676e-05, - 3.72934895e-05, 5.01303282e-05, 4.31469132e-05, 2.71418502e-05, - 1.43349050e-05, 1.06669854e-05, 1.16759156e-05, 1.30185752e-05, - 4.03450713e-05, 5.66922728e-05, 3.90024136e-05, 2.32343181e-05, - 1.80194540e-05, 1.57495995e-05, 1.39665448e-05, 2.87879533e-05, - 3.66486211e-05, 3.81256665e-05, 3.36126112e-05, 2.17825359e-05, - 1.40109902e-05, 1.27117970e-05, 1.33102782e-05, 2.68626776e-05, - 3.41008263e-05, 3.35975259e-05, 2.81307182e-05, 2.38376956e-05, - 2.04376391e-05, 1.53882437e-05, 1.34961903e-05, 2.51363565e-05, - 3.42296286e-05, 3.38684336e-05, 3.04161585e-05, 2.74626267e-05, - 2.10995875e-05, 1.55220501e-05, 1.31234293e-05, 1.32413191e-05, - 2.14507787e-05, 3.61187006e-05, 5.41208901e-05, 4.88601726e-05, - 2.96101688e-05, 1.52005664e-05, 1.24193144e-05, 1.54232834e-05, - 3.16104458e-05, 4.03203912e-05, 3.30738034e-05, 2.29011072e-05, - 2.05427037e-05, 1.83363874e-05, 1.45114934e-05, 1.35475866e-05, - 2.11323185e-05, 3.24523776e-05, 4.15102851e-05, 3.24269494e-05, - 2.32626997e-05, 1.67023577e-05, 1.36327509e-05, 1.36227715e-05, - 2.45053341e-05, 3.42090232e-05, 3.58873419e-05, 2.87509859e-05, - 2.18852728e-05, 1.73919971e-05, 1.35404069e-05, 1.43547851e-05, - 1.59462197e-05, 2.43419107e-05, 4.00084789e-05, 4.86179677e-05, - 3.41699855e-05, 1.98188646e-05, 1.42733052e-05, 1.16242532e-05, - 1.13599937e-05, 1.27404640e-05, 2.85454139e-05, 3.63533744e-05, - 3.68119134e-05, 2.64286447e-05, 1.70561533e-05, 1.73195193e-05, - 1.51884790e-05, 1.22452861e-05, 2.73598454e-05, 3.45369159e-05, - 3.49757184e-05, 3.20454906e-05, 2.63620701e-05, 1.75581972e-05, - 1.42477008e-05, 1.51092511e-05, 3.28685464e-05, 4.65462558e-05, - 3.94424032e-05, 2.28482328e-05, 1.36718363e-05, 1.34691953e-05, - 1.44088292e-05, 2.38724686e-05, 3.31027715e-05, 3.95740442e-05, - 3.57871957e-05, 2.51698787e-05, 1.88880780e-05, 1.55497886e-05, - 1.27508328e-05, - 2.56916178e-05, 3.19600853e-05, 3.34052191e-05, 2.96347161e-05, - 2.45185568e-05, 2.04868169e-05, 1.84493498e-05, 1.84639810e-05, - 1.88619192e-05, 2.50513854e-05, 2.89668448e-05, 2.78672059e-05, - 2.52337351e-05, 2.48063040e-05, 2.41421321e-05, 2.07755665e-05, - 1.83948726e-05, 1.89830590e-05, 1.95921960e-05, 1.86032269e-05, - 2.69301361e-05, 3.09426273e-05, 3.08923747e-05, 2.61156990e-05, - 2.36050138e-05, 2.34934684e-05, 2.04233238e-05, 1.75161095e-05, - 1.66842687e-05, 3.06061608e-05, 3.76833505e-05, 3.50031360e-05, - 2.40125438e-05, 1.79836530e-05, 1.79699928e-05, 1.83682454e-05, - 1.78233896e-05, 1.76910533e-05, 2.31315586e-05, 3.00557541e-05, - 3.31441198e-05, 2.68100235e-05, 2.18704845e-05, 2.25603310e-05, - 2.34228215e-05, 2.09143097e-05, 1.82272214e-05, 1.85811168e-05, - 2.32886409e-05, 3.31866218e-05, 3.83744850e-05, 3.36197144e-05, - 2.50258482e-05, 1.82139031e-05, 1.64057605e-05, 1.71883178e-05, - 3.03436009e-05, 3.54059495e-05, 3.36211248e-05, 2.70009451e-05, - 2.02970047e-05, 1.64351647e-05, 1.57334754e-05, 1.72261923e-05, - 3.29844929e-05, 3.66979403e-05, 3.34834988e-05, 2.62921885e-05, - 1.82589082e-05, 1.55892403e-05, 1.68566529e-05, 1.80224381e-05, - 3.30642678e-05, 3.85244155e-05, 3.14730051e-05, 2.34768193e-05, - 2.11805607e-05, 2.05934533e-05, 1.91932951e-05, 2.74736140e-05, - 3.04479665e-05, 3.14568713e-05, 3.05080092e-05, 2.44657600e-05, - 1.87591777e-05, 1.77280479e-05, 1.82618794e-05, 2.64606974e-05, - 2.95900098e-05, 2.94838880e-05, 2.70170559e-05, 2.53550039e-05, - 2.38973980e-05, 2.00988527e-05, 1.84148933e-05, 2.55400213e-05, - 3.01559187e-05, 3.00721279e-05, 2.80144819e-05, 2.69149708e-05, - 2.38739818e-05, 2.01480644e-05, 1.81329047e-05, 1.82052701e-05, - 2.18535470e-05, 2.88257496e-05, 3.76622525e-05, 3.75655051e-05, - 2.98080761e-05, 2.02078213e-05, 1.76316848e-05, 2.05235315e-05, - 2.89007831e-05, 3.18450590e-05, 2.89092884e-05, 2.38385264e-05, - 2.29166617e-05, 2.20566175e-05, 1.92162803e-05, 1.83980179e-05, - 2.17820959e-05, 2.83261017e-05, 3.36626021e-05, 2.97556502e-05, - 2.48701076e-05, 2.09184592e-05, 1.86431159e-05, 1.84796019e-05, - 2.53375857e-05, 3.00165542e-05, 3.07667256e-05, 2.70203196e-05, - 2.33469684e-05, 2.09818440e-05, 1.83157961e-05, 1.92413955e-05, - 2.07917292e-05, 2.45888395e-05, 3.23643324e-05, 3.69523433e-05, - 3.08582779e-05, 2.23117119e-05, 1.84839031e-05, 1.66654723e-05, - 1.65419938e-05, 1.77896426e-05, 2.62886055e-05, 2.90693624e-05, - 3.03539329e-05, 2.61931242e-05, 2.10223290e-05, 2.24118100e-05, - 2.06822360e-05, 1.76093995e-05, 2.72794442e-05, 2.95439405e-05, - 2.94420738e-05, 2.89028757e-05, 2.66780013e-05, 2.10512784e-05, - 1.87535698e-05, 1.98838183e-05, 2.82057027e-05, 3.33556163e-05, - 3.25137830e-05, 2.50398878e-05, 1.84967011e-05, 1.83676870e-05, - 1.92981854e-05, 2.42356221e-05, 2.86066100e-05, 3.20414163e-05, - 3.12218220e-05, 2.65808921e-05, 2.28769311e-05, 2.02330744e-05, - 1.77140530e-05, - 2.52313931e-05, 2.36615977e-05, 2.31937680e-05, 2.32603244e-05, - 2.38165880e-05, 2.51063835e-05, 2.56570957e-05, 2.60201766e-05, - 2.65339072e-05, 2.56328027e-05, 2.48307365e-05, 2.52146371e-05, - 2.52035660e-05, 2.51834103e-05, 2.53772803e-05, 2.51903757e-05, - 2.52809051e-05, 2.59130452e-05, 2.63444411e-05, 2.64469969e-05, - 2.45113989e-05, 2.35514691e-05, 2.42485744e-05, 2.46336238e-05, - 2.47366923e-05, 2.56664723e-05, 2.63538629e-05, 2.61830520e-05, - 2.61108363e-05, 2.37776469e-05, 2.12339584e-05, 2.24984708e-05, - 2.38910955e-05, 2.39390414e-05, 2.54147332e-05, 2.65079112e-05, - 2.64713890e-05, 2.63991825e-05, 2.35952276e-05, 2.20853908e-05, - 2.24745314e-05, 2.39148744e-05, 2.48561531e-05, 2.61801751e-05, - 2.70718559e-05, 2.70892505e-05, 2.68032854e-05, 2.46213531e-05, - 2.38481629e-05, 2.27920673e-05, 2.19188631e-05, 2.31536506e-05, - 2.49756283e-05, 2.58015370e-05, 2.63302618e-05, 2.65848036e-05, - 2.45651720e-05, 2.17937324e-05, 2.19950215e-05, 2.34779816e-05, - 2.46340897e-05, 2.51575012e-05, 2.56321641e-05, 2.62864462e-05, - 2.44090630e-05, 2.12272678e-05, 2.16305463e-05, 2.37663819e-05, - 2.48472542e-05, 2.54782635e-05, 2.64091755e-05, 2.64963973e-05, - 2.26946710e-05, 2.00397278e-05, 2.18451315e-05, 2.32681911e-05, - 2.51945774e-05, 2.72266239e-05, 2.73038866e-05, 2.39763793e-05, - 2.21211309e-05, 2.23182357e-05, 2.41017095e-05, 2.61845896e-05, - 2.63504615e-05, 2.64100318e-05, 2.64957089e-05, 2.42177388e-05, - 2.27474765e-05, 2.29532046e-05, 2.39117388e-05, 2.54076839e-05, - 2.68007636e-05, 2.68290153e-05, 2.64979401e-05, 2.44615379e-05, - 2.32950145e-05, 2.34376357e-05, 2.34230111e-05, 2.43180682e-05, - 2.60122042e-05, 2.67218525e-05, 2.65470025e-05, 2.64955390e-05, - 2.25460226e-05, 2.07166571e-05, 2.03624449e-05, 2.25298495e-05, - 2.62581817e-05, 2.73264003e-05, 2.67295636e-05, 2.75901260e-05, - 2.36282355e-05, 2.15080596e-05, 2.26448711e-05, 2.41058764e-05, - 2.51182426e-05, 2.63005217e-05, 2.64642539e-05, 2.63768482e-05, - 2.27457731e-05, 2.23858347e-05, 2.26467194e-05, 2.40558634e-05, - 2.52649594e-05, 2.64562626e-05, 2.67385440e-05, 2.64191345e-05, - 2.47516013e-05, 2.31530257e-05, 2.29166679e-05, 2.34343785e-05, - 2.43725532e-05, 2.56445447e-05, 2.62195419e-05, 2.67634826e-05, - 2.73071347e-05, 2.38464364e-05, 2.21861551e-05, 2.21166519e-05, - 2.41204945e-05, 2.49552225e-05, 2.53853830e-05, 2.60779271e-05, - 2.63086014e-05, 2.64908784e-05, 2.26706859e-05, 2.08414102e-05, - 2.19274494e-05, 2.42265866e-05, 2.61604431e-05, 2.82892161e-05, - 2.82668935e-05, 2.70032218e-05, 2.48803017e-05, 2.24215653e-05, - 2.20404168e-05, 2.33272473e-05, 2.49340305e-05, 2.55518603e-05, - 2.59611009e-05, 2.68403361e-05, 2.19788748e-05, 1.99351845e-05, - 2.26475586e-05, 2.59318966e-05, 2.63726481e-05, 2.64458480e-05, - 2.67899522e-05, 2.37716319e-05, 2.22829614e-05, 2.21018650e-05, - 2.34700884e-05, 2.58778487e-05, 2.69991337e-05, 2.68421163e-05, - 2.63110707e-05, - 2.32480022e-05, 1.72720262e-05, 1.60525800e-05, 1.81825485e-05, - 2.24591569e-05, 2.81833348e-05, 3.16091308e-05, 3.21548879e-05, - 3.23915967e-05, 2.42911668e-05, 2.03350583e-05, 2.15404983e-05, - 2.35972415e-05, 2.39396129e-05, 2.47802665e-05, 2.79712122e-05, - 3.10976650e-05, 3.12720457e-05, 3.11153682e-05, 3.26218291e-05, - 2.14094212e-05, 1.77257268e-05, 1.84876254e-05, 2.21775903e-05, - 2.44427461e-05, 2.57677932e-05, 3.00733078e-05, 3.38112666e-05, - 3.50171364e-05, 1.81587165e-05, 1.24171445e-05, 1.46371490e-05, - 2.29834997e-05, 2.95511692e-05, 3.19065245e-05, 3.30544556e-05, - 3.38051003e-05, 3.38909486e-05, 2.33767508e-05, 1.66806266e-05, - 1.54768038e-05, 2.07940748e-05, 2.63042419e-05, 2.73964620e-05, - 2.76960399e-05, 3.05350592e-05, 3.37254969e-05, 2.98205439e-05, - 2.35676442e-05, 1.57670756e-05, 1.27485678e-05, 1.59076024e-05, - 2.34893657e-05, 3.21679696e-05, 3.58511549e-05, 3.49794038e-05, - 1.91563450e-05, 1.38110616e-05, 1.47860992e-05, 2.01441471e-05, - 2.77173712e-05, 3.38295340e-05, 3.58251198e-05, 3.44315509e-05, - 1.74723166e-05, 1.27822215e-05, 1.44987597e-05, 2.09992567e-05, - 3.06061875e-05, 3.58136201e-05, 3.52290115e-05, 3.35454497e-05, - 1.57316349e-05, 1.11128748e-05, 1.56785826e-05, 2.26425648e-05, - 2.75205524e-05, 3.11316950e-05, 3.31067334e-05, 2.03911513e-05, - 1.65028135e-05, 1.61689652e-05, 1.85609915e-05, 2.55189025e-05, - 3.22524014e-05, 3.38518740e-05, 3.31903888e-05, 2.14123983e-05, - 1.76546956e-05, 1.79402510e-05, 2.06405266e-05, 2.37481126e-05, - 2.68605034e-05, 3.11786917e-05, 3.29712534e-05, 2.24255838e-05, - 1.79099025e-05, 1.81119148e-05, 1.93874161e-05, 2.11926210e-05, - 2.58544088e-05, 3.09576744e-05, 3.34612212e-05, 3.32731851e-05, - 2.31442935e-05, 1.58949165e-05, 1.16783314e-05, 1.35883991e-05, - 2.13452692e-05, 3.17708474e-05, 3.45134049e-05, 3.17493835e-05, - 1.90407742e-05, 1.51525368e-05, 1.79498539e-05, 2.34121852e-05, - 2.56022786e-05, 2.81016984e-05, 3.17973432e-05, 3.28062192e-05, - 2.34852857e-05, 1.80205774e-05, 1.53951362e-05, 1.89712310e-05, - 2.39868518e-05, 2.96212110e-05, 3.30174942e-05, 3.27549818e-05, - 2.29487800e-05, 1.78399246e-05, 1.71603515e-05, 2.00795435e-05, - 2.42035307e-05, 2.83850914e-05, 3.26783289e-05, 3.22179084e-05, - 3.10001090e-05, 2.24383288e-05, 1.55741661e-05, 1.34686376e-05, - 1.83726909e-05, 2.59861816e-05, 3.11378832e-05, 3.49932761e-05, - 3.55842771e-05, 3.38875057e-05, 1.96959067e-05, 1.58959655e-05, - 1.63507986e-05, 2.16264337e-05, 2.90750199e-05, 3.04419068e-05, - 3.25284153e-05, 3.49887981e-05, 2.15836595e-05, 1.73300856e-05, - 1.69781118e-05, 1.87062110e-05, 2.21013430e-05, 2.81734827e-05, - 3.16590133e-05, 3.14742027e-05, 1.76407107e-05, 1.29380627e-05, - 1.59590870e-05, 2.46770445e-05, 3.26580048e-05, 3.29580549e-05, - 3.21804963e-05, 2.26398570e-05, 1.77345497e-05, 1.56508358e-05, - 1.74829295e-05, 2.33072261e-05, 2.81702451e-05, 3.10262425e-05, - 3.37145352e-05, - 2.37961695e-05, 1.87654088e-05, 1.76738772e-05, 1.98133168e-05, - 2.36080647e-05, 2.78433835e-05, 3.01501181e-05, 3.04044471e-05, - 3.03925600e-05, 2.45440749e-05, 2.13275313e-05, 2.22970093e-05, - 2.41058836e-05, 2.44044916e-05, 2.50417787e-05, 2.76520192e-05, - 2.99203566e-05, 2.98260228e-05, 2.95676158e-05, 3.05794296e-05, - 2.24239751e-05, 1.92585427e-05, 1.97697526e-05, 2.30693380e-05, - 2.49857958e-05, 2.57501785e-05, 2.88165925e-05, 3.14665129e-05, - 3.22741876e-05, 1.96096609e-05, 1.43256082e-05, 1.64013638e-05, - 2.40407761e-05, 2.92752499e-05, 3.04398004e-05, 3.08521162e-05, - 3.13655978e-05, 3.14465173e-05, 2.44872554e-05, 1.87106104e-05, - 1.73128320e-05, 2.20725065e-05, 2.64660984e-05, 2.68635589e-05, - 2.67882518e-05, 2.88989768e-05, 3.12015222e-05, 2.92329298e-05, - 2.45605444e-05, 1.75114454e-05, 1.44838235e-05, 1.75358958e-05, - 2.40934594e-05, 3.04879835e-05, 3.27292464e-05, 3.20925487e-05, - 2.03072715e-05, 1.57285154e-05, 1.67345337e-05, 2.16236228e-05, - 2.76526936e-05, 3.18237637e-05, 3.29430043e-05, 3.18381867e-05, - 1.87122822e-05, 1.47509591e-05, 1.65459401e-05, 2.23135710e-05, - 2.97212106e-05, 3.29865586e-05, 3.23103527e-05, 3.11849371e-05, - 1.75074105e-05, 1.31654713e-05, 1.77456622e-05, 2.39664001e-05, - 2.73035581e-05, 2.92785417e-05, 3.06193758e-05, 2.16779514e-05, - 1.85139379e-05, 1.80970810e-05, 1.98918568e-05, 2.53678387e-05, - 3.03592092e-05, 3.14170939e-05, 3.09477193e-05, 2.25300332e-05, - 1.94682396e-05, 1.96810470e-05, 2.19319731e-05, 2.41632598e-05, - 2.62297733e-05, 2.94470525e-05, 3.07993275e-05, 2.33493558e-05, - 1.95310820e-05, 1.96815726e-05, 2.09266947e-05, 2.22951370e-05, - 2.56997949e-05, 2.93267223e-05, 3.11117772e-05, 3.10033422e-05, - 2.46665164e-05, 1.83778157e-05, 1.37420565e-05, 1.52347932e-05, - 2.17632665e-05, 2.96945246e-05, 3.17435058e-05, 2.95904132e-05, - 2.05216137e-05, 1.73004244e-05, 1.97995193e-05, 2.43349981e-05, - 2.58080509e-05, 2.73653664e-05, 3.00055869e-05, 3.07285496e-05, - 2.48879666e-05, 1.99620725e-05, 1.71669799e-05, 2.03053482e-05, - 2.44159364e-05, 2.84507517e-05, 3.07493647e-05, 3.06794630e-05, - 2.37053130e-05, 1.95110404e-05, 1.89099455e-05, 2.15785041e-05, - 2.49138996e-05, 2.78086657e-05, 3.06949727e-05, 3.01953110e-05, - 2.91577170e-05, 2.35790289e-05, 1.75158427e-05, 1.52367334e-05, - 1.97015020e-05, 2.61760973e-05, 2.99127497e-05, 3.22698686e-05, - 3.25687274e-05, 3.14134851e-05, 2.14892163e-05, 1.83337732e-05, - 1.84241915e-05, 2.27201807e-05, 2.81483002e-05, 2.84252458e-05, - 2.99027063e-05, 3.19597175e-05, 2.24521326e-05, 1.92560463e-05, - 1.90325809e-05, 2.03032142e-05, 2.28963044e-05, 2.76801497e-05, - 3.00808524e-05, 2.96516049e-05, 1.97275728e-05, 1.53735827e-05, - 1.77630147e-05, 2.47625806e-05, 3.06292573e-05, 3.08080078e-05, - 3.01605364e-05, 2.37831498e-05, 1.97130542e-05, 1.76265596e-05, - 1.90436303e-05, 2.36223827e-05, 2.71770928e-05, 2.93344688e-05, - 3.13595213e-05, - 2.52927485e-05, 2.66858157e-05, 2.68447342e-05, 2.69722211e-05, - 2.60531187e-05, 2.38470541e-05, 2.24623695e-05, 2.22018609e-05, - 2.20397988e-05, 2.48922804e-05, 2.59560429e-05, 2.56182204e-05, - 2.52233331e-05, 2.51474215e-05, 2.48576854e-05, 2.39034610e-05, - 2.27152866e-05, 2.25526473e-05, 2.25393311e-05, 2.19661718e-05, - 2.59709637e-05, 2.67858961e-05, 2.63690369e-05, 2.57721072e-05, - 2.51737625e-05, 2.44843494e-05, 2.29102892e-05, 2.15428386e-05, - 2.10749705e-05, 2.66541867e-05, 2.70602272e-05, 2.70113095e-05, - 2.58872946e-05, 2.35340924e-05, 2.23788127e-05, 2.17952625e-05, - 2.15143060e-05, 2.14892224e-05, 2.58864976e-05, 2.77087468e-05, - 2.72645467e-05, 2.63591005e-05, 2.45606801e-05, 2.38421096e-05, - 2.35017446e-05, 2.26017286e-05, 2.15058840e-05, 2.33196493e-05, - 2.57393669e-05, 2.70857585e-05, 2.66170546e-05, 2.68452722e-05, - 2.53379724e-05, 2.22263412e-05, 2.07294944e-05, 2.10509882e-05, - 2.61753549e-05, 2.72920926e-05, 2.74676282e-05, 2.66788260e-05, - 2.41227212e-05, 2.16264566e-05, 2.07778358e-05, 2.12908178e-05, - 2.62094293e-05, 2.72929739e-05, 2.76812302e-05, 2.63945225e-05, - 2.29724369e-05, 2.07890819e-05, 2.09685690e-05, 2.16106000e-05, - 2.71515642e-05, 2.72876869e-05, 2.77786059e-05, 2.62209906e-05, - 2.40598540e-05, 2.23717865e-05, 2.16657229e-05, 2.63899202e-05, - 2.76726815e-05, 2.74997516e-05, 2.64578933e-05, 2.43830516e-05, - 2.21183187e-05, 2.15030900e-05, 2.17454661e-05, 2.61072639e-05, - 2.72968277e-05, 2.71653770e-05, 2.63853656e-05, 2.51083474e-05, - 2.38196915e-05, 2.24303798e-05, 2.18279234e-05, 2.57935502e-05, - 2.69524048e-05, 2.68641071e-05, 2.68033315e-05, 2.60988974e-05, - 2.43487884e-05, 2.25280010e-05, 2.16365662e-05, 2.17141331e-05, - 2.63274523e-05, 2.86278197e-05, 2.74128299e-05, 2.65393974e-05, - 2.51332479e-05, 2.21334491e-05, 2.12161187e-05, 2.20925424e-05, - 2.67179683e-05, 2.79434870e-05, 2.73555496e-05, 2.56892497e-05, - 2.47062728e-05, 2.35870608e-05, 2.22699995e-05, 2.19061401e-05, - 2.61459872e-05, 2.75105275e-05, 2.71133720e-05, 2.64758964e-05, - 2.51049824e-05, 2.30456318e-05, 2.17785113e-05, 2.19198741e-05, - 2.55550817e-05, 2.70411122e-05, 2.71738735e-05, 2.67106684e-05, - 2.53688034e-05, 2.36529299e-05, 2.19753471e-05, 2.20690914e-05, - 2.24006786e-05, 2.60461644e-05, 2.75040616e-05, 2.68460227e-05, - 2.64458455e-05, 2.46357810e-05, 2.26843571e-05, 2.10869048e-05, - 2.08363299e-05, 2.14805941e-05, 2.71628916e-05, 2.85383102e-05, - 2.77965727e-05, 2.60626990e-05, 2.32976176e-05, 2.23678945e-05, - 2.17065870e-05, 2.10081430e-05, 2.57691821e-05, 2.75046524e-05, - 2.77499092e-05, 2.69121897e-05, 2.56542606e-05, 2.37478583e-05, - 2.23990416e-05, 2.23238779e-05, 2.77799311e-05, 2.85986466e-05, - 2.72289407e-05, 2.46872572e-05, 2.19627085e-05, 2.18396979e-05, - 2.20785599e-05, 2.60249797e-05, 2.75869239e-05, 2.75815944e-05, - 2.68271476e-05, 2.50158332e-05, 2.33816940e-05, 2.24814615e-05, - 2.15667637e-05, - 2.52413340e-05, 2.54047689e-05, 2.52863587e-05, 2.57658690e-05, - 2.56938455e-05, 2.45797900e-05, 2.37289309e-05, 2.35632222e-05, - 2.34626329e-05, 2.50567034e-05, 2.53674515e-05, 2.52822142e-05, - 2.52265904e-05, 2.52051434e-05, 2.50742948e-05, 2.46103003e-05, - 2.38879051e-05, 2.37898305e-05, 2.37833012e-05, 2.34131158e-05, - 2.55180078e-05, 2.55563290e-05, 2.53864572e-05, 2.54670300e-05, - 2.52669135e-05, 2.48884565e-05, 2.40126361e-05, 2.31228088e-05, - 2.27947103e-05, 2.55361510e-05, 2.45889999e-05, 2.51041907e-05, - 2.56311572e-05, 2.43900633e-05, 2.36705071e-05, 2.33000897e-05, - 2.31092130e-05, 2.30905826e-05, 2.56661539e-05, 2.60177089e-05, - 2.54657891e-05, 2.57154453e-05, 2.49744627e-05, 2.45439614e-05, - 2.43228217e-05, 2.38178017e-05, 2.31093753e-05, 2.42641584e-05, - 2.55824841e-05, 2.53996704e-05, 2.43665068e-05, 2.52575854e-05, - 2.52970951e-05, 2.35762314e-05, 2.25548071e-05, 2.27903105e-05, - 2.53531599e-05, 2.51091930e-05, 2.54590994e-05, 2.58544787e-05, - 2.47444137e-05, 2.31535903e-05, 2.25669047e-05, 2.29508638e-05, - 2.50987678e-05, 2.48494598e-05, 2.55437018e-05, 2.57661910e-05, - 2.40472520e-05, 2.25695540e-05, 2.27276328e-05, 2.31753207e-05, - 2.54389607e-05, 2.43696801e-05, 2.58685895e-05, 2.58269383e-05, - 2.46971814e-05, 2.36756388e-05, 2.32226863e-05, 2.56843736e-05, - 2.59587187e-05, 2.57725520e-05, 2.54620012e-05, 2.47985757e-05, - 2.35122822e-05, 2.31003155e-05, 2.32664754e-05, 2.56147818e-05, - 2.59052626e-05, 2.58616147e-05, 2.57141281e-05, 2.51596189e-05, - 2.44957799e-05, 2.37143792e-05, 2.33218041e-05, 2.55093584e-05, - 2.57061233e-05, 2.56775884e-05, 2.58349946e-05, 2.55819828e-05, - 2.47997057e-05, 2.37756827e-05, 2.31938050e-05, 2.32453713e-05, - 2.59411884e-05, 2.64995283e-05, 2.46256831e-05, 2.45239693e-05, - 2.49057011e-05, 2.35259019e-05, 2.29089627e-05, 2.34988764e-05, - 2.57226633e-05, 2.58722224e-05, 2.59967192e-05, 2.55345135e-05, - 2.50306358e-05, 2.44036011e-05, 2.36118970e-05, 2.33722981e-05, - 2.58478907e-05, 2.61167147e-05, 2.53417895e-05, 2.55398367e-05, - 2.51795546e-05, 2.40922388e-05, 2.32919961e-05, 2.33820289e-05, - 2.53964052e-05, 2.57569483e-05, 2.57310589e-05, 2.58680153e-05, - 2.53819099e-05, 2.44589985e-05, 2.34161186e-05, 2.34836343e-05, - 2.36926962e-05, 2.56868992e-05, 2.56547238e-05, 2.47114590e-05, - 2.54227154e-05, 2.50070283e-05, 2.38692764e-05, 2.28022172e-05, - 2.26307198e-05, 2.30865100e-05, 2.61301669e-05, 2.64384869e-05, - 2.60158309e-05, 2.56088457e-05, 2.42447680e-05, 2.36541045e-05, - 2.32503640e-05, 2.27698257e-05, 2.53956141e-05, 2.59940223e-05, - 2.61016704e-05, 2.58080212e-05, 2.53747722e-05, 2.45147284e-05, - 2.36912847e-05, 2.36473422e-05, 2.62398526e-05, 2.57931570e-05, - 2.55399482e-05, 2.49451848e-05, 2.34098686e-05, 2.33289282e-05, - 2.34899458e-05, 2.56926263e-05, 2.61218452e-05, 2.57250471e-05, - 2.55431682e-05, 2.50495096e-05, 2.42646388e-05, 2.37461896e-05, - 2.31419129e-05, - 2.37191101e-05, 1.85294680e-05, 1.74153268e-05, 1.95392482e-05, - 2.34030606e-05, 2.78922518e-05, 3.03844582e-05, 3.06925534e-05, - 3.07311338e-05, 2.45201963e-05, 2.11818069e-05, 2.21926415e-05, - 2.40333182e-05, 2.43373405e-05, 2.50091596e-05, 2.77000011e-05, - 3.01018948e-05, 3.00646212e-05, 2.98322676e-05, 3.09226621e-05, - 2.22622169e-05, 1.90104889e-05, 1.95738107e-05, 2.29270070e-05, - 2.48938477e-05, 2.57662025e-05, 2.90368457e-05, 3.18502822e-05, - 3.27178800e-05, 1.93774084e-05, 1.40102728e-05, 1.61155342e-05, - 2.38503261e-05, 2.92826006e-05, 3.06693572e-05, 3.12214361e-05, - 3.17706875e-05, 3.18507050e-05, 2.42791740e-05, 1.83530928e-05, - 1.70070474e-05, 2.18565878e-05, 2.64329112e-05, 2.69696969e-05, - 2.69729356e-05, 2.91946936e-05, 3.16272283e-05, 2.93066448e-05, - 2.43771862e-05, 1.72257242e-05, 1.42087554e-05, 1.72764363e-05, - 2.40005800e-05, 3.07599501e-05, 3.32365796e-05, 3.25693268e-05, - 2.01359748e-05, 1.54091801e-05, 1.64051172e-05, 2.13676821e-05, - 2.76470864e-05, 3.21305229e-05, 3.33971169e-05, 3.22627941e-05, - 1.85330996e-05, 1.44211923e-05, 1.61942081e-05, 2.20871687e-05, - 2.98466042e-05, 3.34285159e-05, 3.27880608e-05, 3.15784047e-05, - 1.72145417e-05, 1.28153538e-05, 1.73846504e-05, 2.37182962e-05, - 2.73362584e-05, 2.96106622e-05, 3.10506804e-05, 2.14642115e-05, - 1.81619017e-05, 1.77664096e-05, 1.96841779e-05, 2.54175607e-05, - 3.06771740e-05, 3.18200408e-05, 3.13229803e-05, 2.23445634e-05, - 1.91553522e-05, 1.93831326e-05, 2.17146373e-05, 2.41099296e-05, - 2.63663024e-05, 2.97513709e-05, 3.11637240e-05, 2.31967260e-05, - 1.92612526e-05, 1.94222220e-05, 2.06639607e-05, 2.21155408e-05, - 2.57453642e-05, 2.96130861e-05, 3.15047011e-05, 3.13827931e-05, - 2.43649219e-05, 1.79163834e-05, 1.33899235e-05, 1.49790790e-05, - 2.17370120e-05, 3.00631439e-05, 3.22054947e-05, 2.99776173e-05, - 2.02754619e-05, 1.69225247e-05, 1.94760320e-05, 2.41699877e-05, - 2.57759458e-05, 2.75051673e-05, 3.03106056e-05, 3.10755852e-05, - 2.46098207e-05, 1.96164400e-05, 1.68765195e-05, 2.00936348e-05, - 2.43562813e-05, 2.86603111e-05, 3.11341414e-05, 3.10271539e-05, - 2.35845505e-05, 1.92301020e-05, 1.86153151e-05, 2.13186637e-05, - 2.47869438e-05, 2.79075299e-05, 3.10237614e-05, 3.05428356e-05, - 2.94900228e-05, 2.33761879e-05, 1.71848706e-05, 1.49530158e-05, - 1.94957357e-05, 2.61416178e-05, 3.01042855e-05, 3.27097756e-05, - 3.30591247e-05, 3.18243539e-05, 2.11641667e-05, 1.78832129e-05, - 1.80582842e-05, 2.25378199e-05, 2.83134528e-05, 2.88060245e-05, - 3.03762241e-05, 3.24678188e-05, 2.23218521e-05, 1.89189810e-05, - 1.86674617e-05, 2.00328863e-05, 2.27769626e-05, 2.77640236e-05, - 3.03409705e-05, 2.99701519e-05, 1.93503300e-05, 1.49322058e-05, - 1.74624921e-05, 2.47711300e-05, 3.09686467e-05, 3.11678194e-05, - 3.05082655e-05, 2.35771727e-05, 1.93607949e-05, 1.72872321e-05, - 1.87907768e-05, 2.35972120e-05, 2.73728750e-05, 2.96329758e-05, - 3.17478544e-05, - 2.38862490e-05, 1.91133536e-05, 1.80579734e-05, 2.03485911e-05, - 2.41399626e-05, 2.78622684e-05, 2.97877952e-05, 2.98874481e-05, - 2.97001909e-05, 2.45069836e-05, 2.14899919e-05, 2.23755883e-05, - 2.42043376e-05, 2.45078686e-05, 2.50769127e-05, 2.76534925e-05, - 2.97140323e-05, 2.94086445e-05, 2.90290323e-05, 2.98945743e-05, - 2.27138034e-05, 1.96725078e-05, 2.00232081e-05, 2.33357193e-05, - 2.52258830e-05, 2.56771692e-05, 2.83444901e-05, 3.07587387e-05, - 3.14731856e-05, 1.99842376e-05, 1.48251486e-05, 1.68409197e-05, - 2.45546167e-05, 2.96090904e-05, 3.01312426e-05, 3.01126376e-05, - 3.05709865e-05, 3.06658628e-05, 2.51023391e-05, 1.94971118e-05, - 1.78538967e-05, 2.25322721e-05, 2.66338721e-05, 2.65814481e-05, - 2.62292381e-05, 2.81776566e-05, 3.03147930e-05, 2.93232936e-05, - 2.50921237e-05, 1.79871160e-05, 1.48407228e-05, 1.79181481e-05, - 2.42626171e-05, 3.00376479e-05, 3.17762012e-05, 3.11523596e-05, - 2.05016577e-05, 1.62710099e-05, 1.73421794e-05, 2.21984413e-05, - 2.78444358e-05, 3.14337854e-05, 3.22054752e-05, 3.10410773e-05, - 1.88571047e-05, 1.53102641e-05, 1.72294477e-05, 2.28275088e-05, - 2.96881570e-05, 3.22979504e-05, 3.13978165e-05, 3.04061355e-05, - 1.80087288e-05, 1.37788621e-05, 1.85046840e-05, 2.46839667e-05, - 2.73223747e-05, 2.84759669e-05, 2.96396204e-05, 2.21040344e-05, - 1.92714925e-05, 1.87586122e-05, 2.01931797e-05, 2.51439088e-05, - 2.97334541e-05, 3.06367331e-05, 3.02002480e-05, 2.29118122e-05, - 2.01269847e-05, 2.02959953e-05, 2.23874930e-05, 2.41986637e-05, - 2.57834570e-05, 2.87583116e-05, 3.00699302e-05, 2.36731616e-05, - 2.00366762e-05, 2.01569724e-05, 2.14829533e-05, 2.26397455e-05, - 2.55193299e-05, 2.86854774e-05, 3.03252141e-05, 3.02487470e-05, - 2.56415533e-05, 1.95387355e-05, 1.43682990e-05, 1.55369826e-05, - 2.15369942e-05, 2.88159270e-05, 3.08055352e-05, 2.86371496e-05, - 2.09945270e-05, 1.81053759e-05, 2.05139877e-05, 2.47812775e-05, - 2.59094847e-05, 2.70165243e-05, 2.93806969e-05, 3.00496509e-05, - 2.57957501e-05, 2.07665876e-05, 1.76475423e-05, 2.06429260e-05, - 2.44938490e-05, 2.79750777e-05, 2.99438750e-05, 2.99920279e-05, - 2.39428282e-05, 2.00557847e-05, 1.94754846e-05, 2.21645675e-05, - 2.52727632e-05, 2.76480171e-05, 3.00745605e-05, 2.94479683e-05, - 2.83409588e-05, 2.41008304e-05, 1.81559167e-05, 1.56390757e-05, - 1.99863509e-05, 2.63204342e-05, 2.96703626e-05, 3.14812759e-05, - 3.16500998e-05, 3.06054942e-05, 2.23080642e-05, 1.94515370e-05, - 1.92290266e-05, 2.31042236e-05, 2.77932421e-05, 2.73673943e-05, - 2.86964001e-05, 3.08946609e-05, 2.26323194e-05, 1.99928557e-05, - 1.98620687e-05, 2.08511953e-05, 2.30687770e-05, 2.75583732e-05, - 2.96201984e-05, 2.89381104e-05, 2.06367044e-05, 1.63605430e-05, - 1.83015918e-05, 2.46304063e-05, 2.99639370e-05, 3.00954522e-05, - 2.94082551e-05, 2.43324162e-05, 2.05288524e-05, 1.83013305e-05, - 1.94646815e-05, 2.35179866e-05, 2.66174855e-05, 2.86526078e-05, - 3.06215852e-05, - 2.31683053e-05, 1.72197830e-05, 1.59959351e-05, 1.87895025e-05, - 2.36963318e-05, 2.88321010e-05, 3.16958975e-05, 3.17969880e-05, - 3.14271590e-05, 2.39634980e-05, 2.00631894e-05, 2.11645840e-05, - 2.36033983e-05, 2.40209769e-05, 2.47821551e-05, 2.85087879e-05, - 3.16391105e-05, 3.10646335e-05, 3.04153413e-05, 3.17445806e-05, - 2.16898175e-05, 1.79161814e-05, 1.82776616e-05, 2.25013441e-05, - 2.50748433e-05, 2.55846477e-05, 2.93739023e-05, 3.31615195e-05, - 3.43406718e-05, 1.82782852e-05, 1.24557299e-05, 1.46318179e-05, - 2.42569480e-05, 3.16980168e-05, 3.22765495e-05, 3.20796292e-05, - 3.28155668e-05, 3.29789178e-05, 2.50623038e-05, 1.78592180e-05, - 1.58227835e-05, 2.15229338e-05, 2.70627092e-05, 2.68042836e-05, - 2.61876529e-05, 2.90234320e-05, 3.23573772e-05, 3.11351308e-05, - 2.50114320e-05, 1.59502330e-05, 1.24178982e-05, 1.58337402e-05, - 2.37116002e-05, 3.20674513e-05, 3.48104082e-05, 3.37405059e-05, - 1.88408410e-05, 1.40383632e-05, 1.52643525e-05, 2.11381684e-05, - 2.88774521e-05, 3.44302071e-05, 3.56447016e-05, 3.36039339e-05, - 1.68374483e-05, 1.29976481e-05, 1.51673770e-05, 2.19321743e-05, - 3.16684906e-05, 3.58274892e-05, 3.41701386e-05, 3.25479073e-05, - 1.59854553e-05, 1.14044529e-05, 1.66687073e-05, 2.45250282e-05, - 2.80187738e-05, 2.94527917e-05, 3.12241935e-05, 2.09539553e-05, - 1.75761708e-05, 1.69265520e-05, 1.85040628e-05, 2.47733702e-05, - 3.15059785e-05, 3.29304022e-05, 3.22202624e-05, 2.19876492e-05, - 1.85692339e-05, 1.87580127e-05, 2.13328097e-05, 2.35703678e-05, - 2.55909461e-05, 2.99337540e-05, 3.20135498e-05, 2.29764930e-05, - 1.83952935e-05, 1.85298666e-05, 2.02145771e-05, 2.16154074e-05, - 2.53183537e-05, 2.98379348e-05, 3.24113709e-05, 3.22973050e-05, - 2.59874604e-05, 1.80747452e-05, 1.20229987e-05, 1.31435460e-05, - 1.99741186e-05, 2.99539459e-05, 3.31551585e-05, 2.96482300e-05, - 1.95648759e-05, 1.62224081e-05, 1.90687026e-05, 2.45413931e-05, - 2.59867189e-05, 2.74173055e-05, 3.09401262e-05, 3.19993670e-05, - 2.61762464e-05, 1.94207851e-05, 1.55616492e-05, 1.90721962e-05, - 2.39914143e-05, 2.88065589e-05, 3.17797756e-05, 3.19021513e-05, - 2.33046866e-05, 1.84347120e-05, 1.77405014e-05, 2.10991918e-05, - 2.51906936e-05, 2.84345839e-05, 3.20621998e-05, 3.10016186e-05, - 2.92392178e-05, 2.36386846e-05, 1.62122858e-05, 1.32920813e-05, - 1.82451587e-05, 2.65964613e-05, 3.15540844e-05, 3.43592077e-05, - 3.46034761e-05, 3.28680847e-05, 2.13858608e-05, 1.79500813e-05, - 1.75455441e-05, 2.22426057e-05, 2.85770854e-05, 2.76774769e-05, - 2.96516905e-05, 3.32595671e-05, 2.15389208e-05, 1.84385102e-05, - 1.83190839e-05, 1.94170288e-05, 2.21091199e-05, 2.83152107e-05, - 3.13868687e-05, 3.02061735e-05, 1.93051693e-05, 1.43211764e-05, - 1.63403306e-05, 2.40959766e-05, 3.18647263e-05, 3.20615778e-05, - 3.09363393e-05, 2.39668359e-05, 1.91306980e-05, 1.63957803e-05, - 1.76687779e-05, 2.25967372e-05, 2.67508263e-05, 2.97715234e-05, - 3.29209376e-05, - 2.40369749e-05, 1.96709920e-05, 1.86772066e-05, 2.10286160e-05, - 2.46538446e-05, 2.77273324e-05, 2.92054412e-05, 2.91731647e-05, - 2.88602633e-05, 2.45209575e-05, 2.18063300e-05, 2.25851972e-05, - 2.43464586e-05, 2.46388134e-05, 2.51212079e-05, 2.75178201e-05, - 2.92637527e-05, 2.88101242e-05, 2.83606932e-05, 2.90459407e-05, - 2.30874761e-05, 2.02697763e-05, 2.04702910e-05, 2.36612505e-05, - 2.54338766e-05, 2.55990923e-05, 2.77770959e-05, 2.98241239e-05, - 3.04054269e-05, 2.05369427e-05, 1.56143129e-05, 1.75386928e-05, - 2.50316283e-05, 2.96133239e-05, 2.95660928e-05, 2.92040139e-05, - 2.95828015e-05, 2.96810891e-05, 2.56374488e-05, 2.04298116e-05, - 1.86167287e-05, 2.30597265e-05, 2.67003686e-05, 2.62798788e-05, - 2.57249379e-05, 2.74227085e-05, 2.92743750e-05, 2.91457615e-05, - 2.55557285e-05, 1.86885664e-05, 1.55025205e-05, 1.85394637e-05, - 2.44611710e-05, 2.93653606e-05, 3.05627567e-05, 3.00022704e-05, - 2.08818178e-05, 1.70726067e-05, 1.81775786e-05, 2.28402692e-05, - 2.78544032e-05, 3.06970200e-05, 3.11235574e-05, 3.00127111e-05, - 1.92478818e-05, 1.61453291e-05, 1.81359252e-05, 2.33886748e-05, - 2.93816271e-05, 3.12464195e-05, 3.02487370e-05, 2.94435176e-05, - 1.87322266e-05, 1.46858521e-05, 1.94442608e-05, 2.53307830e-05, - 2.72222886e-05, 2.76366031e-05, 2.85779994e-05, 2.26208206e-05, - 2.01856622e-05, 1.96029376e-05, 2.06755600e-05, 2.49708902e-05, - 2.89439692e-05, 2.96545318e-05, 2.92785140e-05, 2.33552538e-05, - 2.09237606e-05, 2.10479906e-05, 2.29175906e-05, 2.42883889e-05, - 2.53949924e-05, 2.79894478e-05, 2.91725785e-05, 2.40315736e-05, - 2.07016564e-05, 2.07913903e-05, 2.21382992e-05, 2.30634653e-05, - 2.53615882e-05, 2.79594305e-05, 2.93628352e-05, 2.93176033e-05, - 2.64611835e-05, 2.08127770e-05, 1.52792139e-05, 1.61396702e-05, - 2.15273865e-05, 2.78931715e-05, 2.96857499e-05, 2.76683706e-05, - 2.15962920e-05, 1.90983404e-05, 2.13462104e-05, 2.51883549e-05, - 2.59630887e-05, 2.66344325e-05, 2.86180573e-05, 2.91938922e-05, - 2.65469914e-05, 2.16696038e-05, 1.83621893e-05, 2.11406202e-05, - 2.46042117e-05, 2.74295489e-05, 2.89960625e-05, 2.91339144e-05, - 2.42148996e-05, 2.07544365e-05, 2.02119813e-05, 2.28176661e-05, - 2.55787736e-05, 2.73793327e-05, 2.92633854e-05, 2.85832190e-05, - 2.74996180e-05, 2.46079716e-05, 1.89987123e-05, 1.63281154e-05, - 2.04616030e-05, 2.63860370e-05, 2.91940179e-05, 3.04226187e-05, - 3.04746010e-05, 2.96039962e-05, 2.31600359e-05, 2.06885901e-05, - 2.01871889e-05, 2.35408442e-05, 2.73568962e-05, 2.64012081e-05, - 2.75270406e-05, 2.96683809e-05, 2.29165018e-05, 2.08638716e-05, - 2.08208906e-05, 2.15238888e-05, 2.33270609e-05, 2.73273328e-05, - 2.89712201e-05, 2.81369636e-05, 2.16388164e-05, 1.75678631e-05, - 1.90499605e-05, 2.45595200e-05, 2.91255292e-05, 2.92094734e-05, - 2.85425169e-05, 2.48514898e-05, 2.14510330e-05, 1.91710638e-05, - 2.00748543e-05, 2.35244189e-05, 2.60899096e-05, 2.78965663e-05, - 2.96741350e-05, - 2.56286797e-05, 2.85117894e-05, 2.90449177e-05, 2.75771146e-05, - 2.51021474e-05, 2.26228514e-05, 2.11928060e-05, 2.11640028e-05, - 2.13875186e-05, 2.52628055e-05, 2.72348816e-05, 2.67090565e-05, - 2.53906073e-05, 2.51639039e-05, 2.47864582e-05, 2.27999229e-05, - 2.11944951e-05, 2.15380550e-05, 2.19085745e-05, 2.12157815e-05, - 2.62959303e-05, 2.81127309e-05, 2.80796833e-05, 2.58840627e-05, - 2.45352610e-05, 2.43981695e-05, 2.24590833e-05, 2.04623361e-05, - 1.98470680e-05, 2.79722977e-05, 3.02703348e-05, 2.95678404e-05, - 2.48227310e-05, 2.10432863e-05, 2.08775802e-05, 2.10428049e-05, - 2.06548375e-05, 2.05663905e-05, 2.43515089e-05, 2.77657899e-05, - 2.89408659e-05, 2.62679289e-05, 2.35110591e-05, 2.38089530e-05, - 2.42359268e-05, 2.27022948e-05, 2.09093175e-05, 2.13938933e-05, - 2.44224444e-05, 2.89617111e-05, 3.05114895e-05, 2.91200813e-05, - 2.52961122e-05, 2.10102333e-05, 1.96075953e-05, 2.01732701e-05, - 2.78436763e-05, 2.96617612e-05, 2.90933009e-05, 2.63803415e-05, - 2.25449693e-05, 1.97659138e-05, 1.91629495e-05, 2.02357466e-05, - 2.88938691e-05, 3.00023506e-05, 2.90336048e-05, 2.60207848e-05, - 2.11442298e-05, 1.90662666e-05, 1.99436817e-05, 2.07963032e-05, - 2.89166044e-05, 3.03465450e-05, 2.83196747e-05, 2.45682098e-05, - 2.30553911e-05, 2.24806353e-05, 2.15334404e-05, 2.65835148e-05, - 2.79238069e-05, 2.83187783e-05, 2.79248508e-05, 2.49019519e-05, - 2.13356826e-05, 2.05922154e-05, 2.09683254e-05, 2.60806698e-05, - 2.75673619e-05, 2.75190344e-05, 2.63683782e-05, 2.54403993e-05, - 2.45323340e-05, 2.21969119e-05, 2.10770516e-05, 2.55998393e-05, - 2.77952612e-05, 2.77577789e-05, 2.68575873e-05, 2.62987105e-05, - 2.45857431e-05, 2.22406401e-05, 2.08702166e-05, 2.09278498e-05, - 2.36847357e-05, 2.72552193e-05, 3.01757036e-05, 3.03381280e-05, - 2.75443256e-05, 2.22169293e-05, 2.04854606e-05, 2.23970186e-05, - 2.72496125e-05, 2.84516759e-05, 2.72780359e-05, 2.47119658e-05, - 2.41107009e-05, 2.34941904e-05, 2.16400513e-05, 2.10783842e-05, - 2.36277356e-05, 2.70274050e-05, 2.91256435e-05, 2.76088849e-05, - 2.51923495e-05, 2.27685776e-05, 2.12119261e-05, 2.11315697e-05, - 2.54758619e-05, 2.77396991e-05, 2.80488112e-05, 2.63915041e-05, - 2.44168987e-05, 2.28879513e-05, 2.10371961e-05, 2.16252277e-05, - 2.26009844e-05, 2.51379001e-05, 2.86557209e-05, 3.01387513e-05, - 2.80685531e-05, 2.37679359e-05, 2.12461103e-05, 1.98365269e-05, - 1.97151431e-05, 2.06280662e-05, 2.60694340e-05, 2.73575363e-05, - 2.78858500e-05, 2.59466564e-05, 2.28638848e-05, 2.35184185e-05, - 2.24290830e-05, 2.04378252e-05, 2.64457673e-05, 2.75522157e-05, - 2.75129499e-05, 2.72592843e-05, 2.61481331e-05, 2.29406925e-05, - 2.13736553e-05, 2.20525058e-05, 2.69817480e-05, 2.88995975e-05, - 2.87171571e-05, 2.52343320e-05, 2.11487528e-05, 2.10492478e-05, - 2.16613391e-05, 2.49523918e-05, 2.71528522e-05, 2.85358552e-05, - 2.82252069e-05, 2.60405299e-05, 2.39224155e-05, 2.22843046e-05, - 2.05931152e-05, - 2.54992168e-05, 2.54481035e-05, 2.52981477e-05, 2.48128247e-05, - 2.43079806e-05, 2.42490772e-05, 2.40380511e-05, 2.42630154e-05, - 2.46902700e-05, 2.56381276e-05, 2.58227823e-05, 2.58980084e-05, - 2.53889077e-05, 2.52882036e-05, 2.52774931e-05, 2.43754710e-05, - 2.37923131e-05, 2.43474874e-05, 2.47829098e-05, 2.45619592e-05, - 2.52436546e-05, 2.52209310e-05, 2.57177373e-05, 2.51759756e-05, - 2.47381398e-05, 2.53256520e-05, 2.50149568e-05, 2.40744578e-05, - 2.37665103e-05, 2.53349407e-05, 2.42704395e-05, 2.49703246e-05, - 2.42566750e-05, 2.28454645e-05, 2.37501777e-05, 2.45287710e-05, - 2.43413114e-05, 2.42574020e-05, 2.38741640e-05, 2.40146583e-05, - 2.47242200e-05, 2.48081961e-05, 2.44269599e-05, 2.54428282e-05, - 2.62155664e-05, 2.56004715e-05, 2.46627796e-05, 2.34375548e-05, - 2.40774431e-05, 2.49688570e-05, 2.48829398e-05, 2.52959236e-05, - 2.51938902e-05, 2.40569474e-05, 2.38027449e-05, 2.42083233e-05, - 2.58594811e-05, 2.44728131e-05, 2.44193613e-05, 2.45361076e-05, - 2.39005184e-05, 2.31224087e-05, 2.31691745e-05, 2.40445790e-05, - 2.61383666e-05, 2.41663117e-05, 2.41231281e-05, 2.46111978e-05, - 2.34867467e-05, 2.30302545e-05, 2.39978180e-05, 2.44173193e-05, - 2.48798507e-05, 2.33815025e-05, 2.40312145e-05, 2.37244922e-05, - 2.44789301e-05, 2.55987840e-05, 2.52507419e-05, 2.49684836e-05, - 2.40971100e-05, 2.43841948e-05, 2.55535908e-05, 2.58778931e-05, - 2.45493560e-05, 2.42753238e-05, 2.44895131e-05, 2.49548185e-05, - 2.44332831e-05, 2.45669883e-05, 2.48429440e-05, 2.55501615e-05, - 2.61515284e-05, 2.52200451e-05, 2.45367324e-05, 2.49480098e-05, - 2.49173333e-05, 2.50080878e-05, 2.46701087e-05, 2.51072053e-05, - 2.56356778e-05, 2.51678114e-05, 2.44811863e-05, 2.44723360e-05, - 2.28934607e-05, 2.28153888e-05, 2.35668474e-05, 2.52802370e-05, - 2.69569538e-05, 2.55538439e-05, 2.44346498e-05, 2.58016660e-05, - 2.49616446e-05, 2.38247132e-05, 2.42544362e-05, 2.43658151e-05, - 2.48382524e-05, 2.53981476e-05, 2.47501896e-05, 2.44589055e-05, - 2.30126910e-05, 2.39751302e-05, 2.49199779e-05, 2.54036345e-05, - 2.53557794e-05, 2.52089971e-05, 2.47491675e-05, 2.45086032e-05, - 2.51052723e-05, 2.47931259e-05, 2.47309180e-05, 2.45087994e-05, - 2.44406219e-05, 2.47154924e-05, 2.43397166e-05, 2.49390193e-05, - 2.57017515e-05, 2.43422757e-05, 2.44059782e-05, 2.48930201e-05, - 2.56204061e-05, 2.45940475e-05, 2.38819172e-05, 2.37410405e-05, - 2.38354946e-05, 2.43424773e-05, 2.38415718e-05, 2.29440254e-05, - 2.39395729e-05, 2.49113115e-05, 2.50508173e-05, 2.67312512e-05, - 2.62557575e-05, 2.45888452e-05, 2.55616189e-05, 2.41878020e-05, - 2.38920667e-05, 2.47464295e-05, 2.54874335e-05, 2.46742688e-05, - 2.43112451e-05, 2.51674734e-05, 2.36596785e-05, 2.27836553e-05, - 2.47725363e-05, 2.58339568e-05, 2.44856687e-05, 2.44913416e-05, - 2.49713612e-05, 2.42208244e-05, 2.39439802e-05, 2.43001120e-05, - 2.52023266e-05, 2.61088270e-05, 2.60398422e-05, 2.52648707e-05, - 2.42120820e-05, - 2.51362106e-05, 3.49266142e-05, 3.74289855e-05, 3.19569980e-05, - 2.44600138e-05, 1.85097156e-05, 1.57803404e-05, 1.56530565e-05, - 1.59207063e-05, 2.40547501e-05, 2.98092186e-05, 2.80468755e-05, - 2.45498932e-05, 2.40008153e-05, 2.30220616e-05, 1.88303430e-05, - 1.58677627e-05, 1.63145135e-05, 1.68652129e-05, 1.56501677e-05, - 2.72621815e-05, 3.35727640e-05, 3.29228200e-05, 2.60815749e-05, - 2.26899665e-05, 2.20258313e-05, 1.78624676e-05, 1.44794414e-05, - 1.35461031e-05, 3.29065194e-05, 4.58958247e-05, 4.04550797e-05, - 2.37335399e-05, 1.59303935e-05, 1.53051963e-05, 1.53510995e-05, - 1.47301740e-05, 1.46032640e-05, 2.27357810e-05, 3.35726590e-05, - 3.77380700e-05, 2.75119216e-05, 2.03817126e-05, 2.05769313e-05, - 2.12038126e-05, 1.81331256e-05, 1.50756292e-05, 1.63712089e-05, - 2.27936345e-05, 3.74931013e-05, 4.61283004e-05, 3.77780632e-05, - 2.44147524e-05, 1.54427675e-05, 1.31544723e-05, 1.39581747e-05, - 3.19055531e-05, 4.18040979e-05, 3.89223255e-05, 2.80881913e-05, - 1.84973227e-05, 1.35934439e-05, 1.26234544e-05, 1.41068556e-05, - 3.57280768e-05, 4.44007334e-05, 3.90921276e-05, 2.69052483e-05, - 1.58825251e-05, 1.25102202e-05, 1.36402731e-05, 1.49520840e-05, - 3.74077769e-05, 4.87050477e-05, 3.58812814e-05, 2.33999032e-05, - 1.93360272e-05, 1.76902622e-05, 1.60086560e-05, 2.83806135e-05, - 3.41143075e-05, 3.54107175e-05, 3.25034383e-05, 2.29845769e-05, - 1.58718518e-05, 1.46421682e-05, 1.52314159e-05, 2.68251841e-05, - 3.23207456e-05, 3.19960667e-05, 2.77985321e-05, 2.45854513e-05, - 2.19339921e-05, 1.72680190e-05, 1.54095044e-05, 2.54206867e-05, - 3.26694650e-05, 3.24317728e-05, 2.95424797e-05, 2.73743566e-05, - 2.23239135e-05, 1.73720510e-05, 1.50617083e-05, 1.51653962e-05, - 2.16491184e-05, 3.30039848e-05, 4.69412148e-05, 4.42197386e-05, - 2.99252773e-05, 1.71907152e-05, 1.44151829e-05, 1.74550661e-05, - 3.06262169e-05, 3.67634518e-05, 3.14296102e-05, 2.33700846e-05, - 2.15837469e-05, 1.98900514e-05, 1.63677268e-05, 1.54362265e-05, - 2.14343457e-05, 3.08063322e-05, 3.83309901e-05, 3.14872584e-05, - 2.40358160e-05, 1.84183885e-05, 1.55842675e-05, 1.55156963e-05, - 2.49661618e-05, 3.25897744e-05, 3.38680082e-05, 2.81469090e-05, - 2.25621401e-05, 1.88709863e-05, 1.54002871e-05, 1.62771902e-05, - 1.78924727e-05, 2.45357377e-05, 3.68700620e-05, 4.37661166e-05, - 3.29795008e-05, 2.08944050e-05, 1.59320667e-05, 1.35359463e-05, - 1.33163037e-05, 1.46838986e-05, 2.76859139e-05, 3.32524739e-05, - 3.41530074e-05, 2.64559368e-05, 1.86801259e-05, 1.93980762e-05, - 1.73649256e-05, 1.42925287e-05, 2.74831676e-05, 3.25325864e-05, - 3.27162472e-05, 3.08664014e-05, 2.66386193e-05, 1.90013267e-05, - 1.60207466e-05, 1.70070579e-05, 3.09709037e-05, 4.07534569e-05, - 3.66479621e-05, 2.38654431e-05, 1.55537834e-05, 1.53741667e-05, - 1.63336315e-05, 2.41074287e-05, 3.12957528e-05, 3.64749688e-05, - 3.40399364e-05, 2.59048868e-05, 2.05646180e-05, 1.74228496e-05, - 1.46623055e-05, - 2.56127111e-05, 2.93125283e-05, 3.00523645e-05, 2.82431323e-05, - 2.51948860e-05, 2.21455659e-05, 2.04615559e-05, 2.03906288e-05, - 2.05875619e-05, 2.51292024e-05, 2.75755763e-05, 2.68909232e-05, - 2.53371982e-05, 2.50744746e-05, 2.46078268e-05, 2.23380518e-05, - 2.05041655e-05, 2.08226294e-05, 2.11936217e-05, 2.04041326e-05, - 2.65049431e-05, 2.88444955e-05, 2.86861432e-05, 2.59989001e-05, - 2.44008664e-05, 2.41191682e-05, 2.18150170e-05, 1.95895155e-05, - 1.89132540e-05, 2.86349203e-05, 3.19940360e-05, 3.08362598e-05, - 2.48551084e-05, 2.04839626e-05, 2.01332106e-05, 2.02043263e-05, - 1.97750846e-05, 1.96837889e-05, 2.43440033e-05, 2.86819359e-05, - 3.00590877e-05, 2.65622897e-05, 2.31968219e-05, 2.33754945e-05, - 2.37585699e-05, 2.20091600e-05, 2.00254744e-05, 2.08031680e-05, - 2.43914337e-05, 3.00245050e-05, 3.21518929e-05, 3.01527827e-05, - 2.52579713e-05, 2.02411286e-05, 1.86275080e-05, 1.92288626e-05, - 2.83488855e-05, 3.10977452e-05, 3.03427219e-05, 2.67649223e-05, - 2.21134375e-05, 1.89172277e-05, 1.82028110e-05, 1.93272445e-05, - 2.96498946e-05, 3.16519938e-05, 3.03413460e-05, 2.62907589e-05, - 2.04952367e-05, 1.81107335e-05, 1.89914869e-05, 1.99302597e-05, - 2.99870324e-05, 3.23739847e-05, 2.94099633e-05, 2.46457158e-05, - 2.26302885e-05, 2.17438165e-05, 2.06718301e-05, 2.69294301e-05, - 2.88694200e-05, 2.93189792e-05, 2.85229640e-05, 2.46366959e-05, - 2.05485784e-05, 1.97114644e-05, 2.01223424e-05, 2.62933841e-05, - 2.83201306e-05, 2.82254184e-05, 2.66825698e-05, 2.53674642e-05, - 2.41320994e-05, 2.14665078e-05, 2.02436346e-05, 2.56882328e-05, - 2.85022577e-05, 2.84322155e-05, 2.73464597e-05, 2.65373486e-05, - 2.42922315e-05, 2.15274261e-05, 2.00076116e-05, 2.00771525e-05, - 2.37121905e-05, 2.83130283e-05, 3.20732482e-05, 3.18008061e-05, - 2.77300771e-05, 2.14360905e-05, 1.95611573e-05, 2.16109559e-05, - 2.77851104e-05, 2.96396054e-05, 2.79860152e-05, 2.46945429e-05, - 2.38567686e-05, 2.30001602e-05, 2.08784148e-05, 2.02575603e-05, - 2.36166627e-05, 2.77266573e-05, 3.02555778e-05, 2.81484378e-05, - 2.50966239e-05, 2.21547127e-05, 2.03698511e-05, 2.03127245e-05, - 2.55005734e-05, 2.84592039e-05, 2.88779554e-05, 2.67852176e-05, - 2.43122503e-05, 2.23845580e-05, 2.02276995e-05, 2.08302747e-05, - 2.18709933e-05, 2.52326971e-05, 2.97606926e-05, 3.16340718e-05, - 2.86940102e-05, 2.34809697e-05, 2.05509398e-05, 1.89047621e-05, - 1.87483367e-05, 1.97433214e-05, 2.65223003e-05, 2.84150027e-05, - 2.88588415e-05, 2.61330378e-05, 2.22968871e-05, 2.28022743e-05, - 2.15767735e-05, 1.94817451e-05, 2.66278717e-05, 2.83594278e-05, - 2.83802614e-05, 2.78467784e-05, 2.62673837e-05, 2.24558446e-05, - 2.06324080e-05, 2.13025433e-05, 2.77428361e-05, 3.05344559e-05, - 2.97490891e-05, 2.50561222e-05, 2.03367617e-05, 2.02178795e-05, - 2.08680403e-05, 2.50249174e-05, 2.78972103e-05, 2.96283255e-05, - 2.89958282e-05, 2.60067372e-05, 2.34078845e-05, 2.15636938e-05, - 1.97223730e-05, - 2.48744233e-05, 2.27838161e-05, 2.21988863e-05, 2.34569701e-05, - 2.50488738e-05, 2.59928912e-05, 2.62389654e-05, 2.62167132e-05, - 2.61514410e-05, 2.50641723e-05, 2.39206234e-05, 2.42862089e-05, - 2.49886447e-05, 2.50934884e-05, 2.52650268e-05, 2.59449216e-05, - 2.62632890e-05, 2.61744559e-05, 2.60884925e-05, 2.61783105e-05, - 2.44674305e-05, 2.30926943e-05, 2.32399496e-05, 2.47061854e-05, - 2.53524058e-05, 2.54251445e-05, 2.59833823e-05, 2.62640982e-05, - 2.62909168e-05, 2.32445836e-05, 2.01186354e-05, 2.14707935e-05, - 2.51873301e-05, 2.63569487e-05, 2.62928020e-05, 2.61913841e-05, - 2.62260915e-05, 2.62382652e-05, 2.53823116e-05, 2.30689895e-05, - 2.21099273e-05, 2.44260715e-05, 2.57367148e-05, 2.56297720e-05, - 2.54731439e-05, 2.58928306e-05, 2.61776925e-05, 2.62692545e-05, - 2.53646001e-05, 2.21756484e-05, 2.01005824e-05, 2.21166898e-05, - 2.50230837e-05, 2.62502495e-05, 2.62663043e-05, 2.62370284e-05, - 2.34649265e-05, 2.11235008e-05, 2.18149888e-05, 2.43083322e-05, - 2.60233245e-05, 2.63858674e-05, 2.63315198e-05, 2.62648472e-05, - 2.26016921e-05, 2.04751620e-05, 2.17596610e-05, 2.45551692e-05, - 2.62961218e-05, 2.63447248e-05, 2.62590742e-05, 2.62137411e-05, - 2.21932445e-05, 1.93595620e-05, 2.25247167e-05, 2.52651904e-05, - 2.58744590e-05, 2.59300352e-05, 2.60727262e-05, 2.42410975e-05, - 2.29448343e-05, 2.26494500e-05, 2.33349046e-05, 2.52310524e-05, - 2.61716291e-05, 2.62356885e-05, 2.61993753e-05, 2.45641323e-05, - 2.33694291e-05, 2.34455728e-05, 2.43656452e-05, 2.49737243e-05, - 2.53739273e-05, 2.60079742e-05, 2.61888530e-05, 2.48432861e-05, - 2.32962366e-05, 2.33508567e-05, 2.39938361e-05, 2.44481193e-05, - 2.53555005e-05, 2.60065314e-05, 2.62034469e-05, 2.62029974e-05, - 2.56033235e-05, 2.31482757e-05, 1.98084699e-05, 2.05802652e-05, - 2.38567768e-05, 2.59717419e-05, 2.62114244e-05, 2.59219433e-05, - 2.37549322e-05, 2.23043090e-05, 2.35696731e-05, 2.52499229e-05, - 2.55279330e-05, 2.57240333e-05, 2.61226626e-05, 2.61985560e-05, - 2.56379457e-05, 2.37060760e-05, 2.19755895e-05, 2.35622494e-05, - 2.50835903e-05, 2.59097125e-05, 2.61553036e-05, 2.61896494e-05, - 2.49242365e-05, 2.33131411e-05, 2.30186713e-05, 2.42960362e-05, - 2.53894072e-05, 2.59100528e-05, 2.62153230e-05, 2.61032899e-05, - 2.59012687e-05, 2.50333775e-05, 2.23046973e-05, 2.06715107e-05, - 2.32277203e-05, 2.56499096e-05, 2.62496980e-05, 2.62943920e-05, - 2.62699947e-05, 2.62260528e-05, 2.43958015e-05, 2.30965278e-05, - 2.29301492e-05, 2.46399204e-05, 2.58990048e-05, 2.56363507e-05, - 2.58673063e-05, 2.61862835e-05, 2.44126590e-05, 2.33156138e-05, - 2.32648030e-05, 2.37015210e-05, 2.45848130e-05, 2.58986198e-05, - 2.61945722e-05, 2.60324903e-05, 2.36609275e-05, 2.12592609e-05, - 2.23696454e-05, 2.50852066e-05, 2.61915074e-05, 2.61958720e-05, - 2.60963450e-05, 2.51184889e-05, 2.35939145e-05, 2.23945288e-05, - 2.29855792e-05, 2.46983683e-05, 2.55760766e-05, 2.59910996e-05, - 2.62445923e-05, - 2.52791123e-05, 2.84198231e-05, 2.90019999e-05, 2.84949870e-05, - 2.63153328e-05, 2.27627559e-05, 2.07818281e-05, 2.04393305e-05, - 2.02434990e-05, 2.46153553e-05, 2.67083236e-05, 2.60274965e-05, - 2.51275421e-05, 2.49715871e-05, 2.44802160e-05, 2.28591821e-05, - 2.11150648e-05, 2.09247281e-05, 2.09354150e-05, 2.01367054e-05, - 2.64654880e-05, 2.84048242e-05, 2.76831882e-05, 2.60587599e-05, - 2.48982781e-05, 2.38802446e-05, 2.14753027e-05, 1.95491413e-05, - 1.89282610e-05, 2.81189729e-05, 3.06666535e-05, 2.97052490e-05, - 2.60085847e-05, 2.21993697e-05, 2.06521392e-05, 1.99052506e-05, - 1.95229432e-05, 1.94862344e-05, 2.59203260e-05, 2.98593361e-05, - 2.97202593e-05, 2.70650634e-05, 2.38631958e-05, 2.28930971e-05, - 2.24775792e-05, 2.10865572e-05, 1.95264890e-05, 2.19356007e-05, - 2.57133890e-05, 2.93969375e-05, 2.99476179e-05, 2.90509670e-05, - 2.52791475e-05, 2.04613810e-05, 1.84868237e-05, 1.89123238e-05, - 2.72698480e-05, 3.03788076e-05, 3.02252799e-05, 2.76044683e-05, - 2.31357675e-05, 1.96233884e-05, 1.85317920e-05, 1.92177330e-05, - 2.77811040e-05, 3.08085379e-05, 3.06041174e-05, 2.70553492e-05, - 2.14527553e-05, 1.85428459e-05, 1.87987509e-05, 1.96537775e-05, - 2.94908817e-05, 3.15865151e-05, 3.02900209e-05, 2.64638031e-05, - 2.31042358e-05, 2.07623613e-05, 1.97704404e-05, 2.72022711e-05, - 2.98742593e-05, 2.97733382e-05, 2.77691696e-05, 2.38153479e-05, - 2.03419884e-05, 1.95052756e-05, 1.98367058e-05, 2.66222672e-05, - 2.90454802e-05, 2.87997536e-05, 2.71340378e-05, 2.49670911e-05, - 2.29609371e-05, 2.08152370e-05, 1.99494155e-05, 2.60271838e-05, - 2.85514757e-05, 2.83854107e-05, 2.79530785e-05, 2.66652901e-05, - 2.37158415e-05, 2.09477175e-05, 1.96912488e-05, 1.97940601e-05, - 2.64677569e-05, 3.12698164e-05, 3.14717276e-05, 2.95055568e-05, - 2.55116421e-05, 2.04273909e-05, 1.91355171e-05, 2.03889296e-05, - 2.79466618e-05, 3.06875420e-05, 2.90266443e-05, 2.56909151e-05, - 2.41543834e-05, 2.25015395e-05, 2.05611637e-05, 2.00503769e-05, - 2.61865971e-05, 2.91923825e-05, 2.95602530e-05, 2.76774022e-05, - 2.49144105e-05, 2.16863559e-05, 1.98942664e-05, 2.00714542e-05, - 2.56401903e-05, 2.86795913e-05, 2.90492614e-05, 2.76587642e-05, - 2.51643020e-05, 2.25237602e-05, 2.01372546e-05, 2.02981350e-05, - 2.08111604e-05, 2.63121926e-05, 2.99847415e-05, 2.99453963e-05, - 2.78075299e-05, 2.40045275e-05, 2.10777390e-05, 1.89428291e-05, - 1.86240590e-05, 1.94785326e-05, 2.82941469e-05, 3.11580459e-05, - 3.00784523e-05, 2.65200250e-05, 2.20364870e-05, 2.08578606e-05, - 1.98903743e-05, 1.88710751e-05, 2.61916874e-05, 2.93991942e-05, - 2.98118690e-05, 2.82720400e-05, 2.59410603e-05, 2.26598634e-05, - 2.07111077e-05, 2.06633835e-05, 2.96360004e-05, 3.24342033e-05, - 2.95092007e-05, 2.43112530e-05, 2.01279192e-05, 1.99628690e-05, - 2.03130499e-05, 2.62420400e-05, 2.93725939e-05, 3.00543212e-05, - 2.85277014e-05, 2.49538160e-05, 2.22716923e-05, 2.08899704e-05, - 1.95865470e-05, - 2.51420443e-05, 2.52288743e-05, 2.50893054e-05, 2.59017873e-05, - 2.60646189e-05, 2.47514418e-05, 2.37743180e-05, 2.35059577e-05, - 2.32620010e-05, 2.48879753e-05, 2.51481490e-05, 2.50451992e-05, - 2.51620165e-05, 2.51705677e-05, 2.50228110e-05, 2.47495240e-05, - 2.40427187e-05, 2.37583538e-05, 2.36249395e-05, 2.32378329e-05, - 2.55311646e-05, 2.54996769e-05, 2.51589118e-05, 2.55024261e-05, - 2.54219063e-05, 2.47903192e-05, 2.38358751e-05, 2.30207053e-05, - 2.27048653e-05, 2.54514849e-05, 2.43930285e-05, 2.49126765e-05, - 2.60105024e-05, 2.49611944e-05, 2.37875092e-05, 2.31095696e-05, - 2.29292395e-05, 2.29299020e-05, 2.61853684e-05, 2.64360458e-05, - 2.54703613e-05, 2.59013144e-05, 2.51737847e-05, 2.43477765e-05, - 2.38632099e-05, 2.34367752e-05, 2.28405453e-05, 2.46159846e-05, - 2.60157589e-05, 2.53214994e-05, 2.39480669e-05, 2.50494571e-05, - 2.53066859e-05, 2.35815007e-05, 2.24002224e-05, 2.25767355e-05, - 2.50925603e-05, 2.50400042e-05, 2.55334417e-05, 2.61493194e-05, - 2.50614716e-05, 2.33340865e-05, 2.25930294e-05, 2.28184923e-05, - 2.46533424e-05, 2.47669941e-05, 2.57243437e-05, 2.60317982e-05, - 2.43323054e-05, 2.26361084e-05, 2.25581229e-05, 2.29886854e-05, - 2.53969550e-05, 2.43321441e-05, 2.62084070e-05, 2.64280725e-05, - 2.48228585e-05, 2.32671766e-05, 2.28177505e-05, 2.58035766e-05, - 2.63281206e-05, 2.59877480e-05, 2.53035961e-05, 2.45165687e-05, - 2.33620785e-05, 2.29367845e-05, 2.30796109e-05, 2.57413207e-05, - 2.61846030e-05, 2.60942149e-05, 2.58855439e-05, 2.50333253e-05, - 2.40836580e-05, 2.34183516e-05, 2.31337757e-05, 2.56297843e-05, - 2.57864437e-05, 2.57277728e-05, 2.60645343e-05, 2.56487553e-05, - 2.45914051e-05, 2.35067993e-05, 2.29934210e-05, 2.30587024e-05, - 2.68667876e-05, 2.74468075e-05, 2.46235731e-05, 2.40614936e-05, - 2.42800542e-05, 2.31001101e-05, 2.26593430e-05, 2.30009085e-05, - 2.58227171e-05, 2.62632329e-05, 2.63670463e-05, 2.58601696e-05, - 2.51105734e-05, 2.41939684e-05, 2.34263395e-05, 2.32171301e-05, - 2.67100781e-05, 2.66142896e-05, 2.52515651e-05, 2.54561115e-05, - 2.51192547e-05, 2.38760143e-05, 2.30384437e-05, 2.32149941e-05, - 2.54489507e-05, 2.58874808e-05, 2.58551970e-05, 2.61737891e-05, - 2.56556906e-05, 2.44628011e-05, 2.33043049e-05, 2.32180297e-05, - 2.32594081e-05, 2.60444452e-05, 2.58121489e-05, 2.44024038e-05, - 2.52298867e-05, 2.51598212e-05, 2.39929556e-05, 2.27212510e-05, - 2.24842840e-05, 2.29012137e-05, 2.67182372e-05, 2.73212516e-05, - 2.64483214e-05, 2.57514955e-05, 2.41051763e-05, 2.29381763e-05, - 2.25855349e-05, 2.24482211e-05, 2.52860247e-05, 2.63680648e-05, - 2.65931493e-05, 2.59895172e-05, 2.52919077e-05, 2.45425554e-05, - 2.36485327e-05, 2.33522360e-05, 2.68680602e-05, 2.64299570e-05, - 2.55645072e-05, 2.46988094e-05, 2.32553649e-05, 2.31551688e-05, - 2.32166845e-05, 2.60942478e-05, 2.66233959e-05, 2.59376741e-05, - 2.54820962e-05, 2.47282011e-05, 2.38446779e-05, 2.34441322e-05, - 2.30053276e-05, - 2.33281669e-05, 1.76405534e-05, 1.64504081e-05, 1.92358725e-05, - 2.39862478e-05, 2.87023985e-05, 3.12602588e-05, 3.12993150e-05, - 3.08910236e-05, 2.40488137e-05, 2.03533609e-05, 2.13928594e-05, - 2.37489053e-05, 2.41511851e-05, 2.48569820e-05, 2.83904417e-05, - 3.12634381e-05, 3.06491277e-05, 2.99970306e-05, 3.11904839e-05, - 2.19701874e-05, 1.83433418e-05, 1.86449554e-05, 2.27453811e-05, - 2.52071057e-05, 2.55866848e-05, 2.90409538e-05, 3.25037676e-05, - 3.35651743e-05, 1.86844728e-05, 1.29807397e-05, 1.51223906e-05, - 2.45184481e-05, 3.15171871e-05, 3.18228790e-05, 3.14840252e-05, - 3.21505008e-05, 3.23075867e-05, 2.53261527e-05, 1.84098540e-05, - 1.63296634e-05, 2.18658620e-05, 2.70775046e-05, 2.66761636e-05, - 2.59969732e-05, 2.86247267e-05, 3.16908163e-05, 3.08986278e-05, - 2.52479759e-05, 1.64343605e-05, 1.28999121e-05, 1.62902079e-05, - 2.38766317e-05, 3.15761260e-05, 3.39447113e-05, 3.29580945e-05, - 1.91752285e-05, 1.45670244e-05, 1.58002521e-05, 2.15323076e-05, - 2.88070023e-05, 3.37994746e-05, 3.47951685e-05, 3.28828848e-05, - 1.72020004e-05, 1.35387839e-05, 1.57287976e-05, 2.22798333e-05, - 3.13540620e-05, 3.49821796e-05, 3.33665592e-05, 3.19067967e-05, - 1.64771811e-05, 1.19652930e-05, 1.72326804e-05, 2.48473188e-05, - 2.79325766e-05, 2.90009140e-05, 3.06004158e-05, 2.13037930e-05, - 1.81229136e-05, 1.74540290e-05, 1.88812361e-05, 2.47612993e-05, - 3.09883536e-05, 3.22625291e-05, 3.16124280e-05, 2.22886780e-05, - 1.90617059e-05, 1.92314779e-05, 2.16804896e-05, 2.36960356e-05, - 2.54669409e-05, 2.94922677e-05, 3.14259191e-05, 2.32224063e-05, - 1.88413292e-05, 1.89628580e-05, 2.06301144e-05, 2.19165867e-05, - 2.52962287e-05, 2.94187213e-05, 3.17767511e-05, 3.16817658e-05, - 2.63412200e-05, 1.87483976e-05, 1.25878338e-05, 1.36054396e-05, - 2.01429068e-05, 2.94456053e-05, 3.24151984e-05, 2.91329728e-05, - 1.99707419e-05, 1.68087281e-05, 1.95678074e-05, 2.47677583e-05, - 2.60299662e-05, 2.72349079e-05, 3.04588608e-05, 3.14306441e-05, - 2.64971728e-05, 1.99414760e-05, 1.60531485e-05, 1.94467689e-05, - 2.41142374e-05, 2.85048882e-05, 3.11806470e-05, 3.13368003e-05, - 2.35088740e-05, 1.88926610e-05, 1.82206613e-05, 2.14983577e-05, - 2.53591058e-05, 2.82631889e-05, 3.15101973e-05, 3.04734005e-05, - 2.87951733e-05, 2.39273263e-05, 1.67449560e-05, 1.37832972e-05, - 1.86232693e-05, 2.66257452e-05, 3.11707157e-05, 3.35868834e-05, - 3.37657650e-05, 3.21946113e-05, 2.18558790e-05, 1.86113054e-05, - 1.81086220e-05, 2.25355360e-05, 2.83300755e-05, 2.72421905e-05, - 2.90502749e-05, 3.24668963e-05, 2.17880080e-05, 1.89599979e-05, - 1.88743223e-05, 1.98516958e-05, 2.23358591e-05, 2.81638849e-05, - 3.09356428e-05, 2.97394883e-05, 1.98644202e-05, 1.49902298e-05, - 1.68382190e-05, 2.41439644e-05, 3.13097023e-05, 3.14767516e-05, - 3.04105390e-05, 2.42522339e-05, 1.96624532e-05, 1.69367438e-05, - 1.81036083e-05, 2.27141477e-05, 2.65314585e-05, 2.93422006e-05, - 3.22689470e-05, - 2.54933965e-05, 2.69469339e-05, 2.71294364e-05, 2.65860119e-05, - 2.52892387e-05, 2.35844619e-05, 2.24899568e-05, 2.24327538e-05, - 2.25514564e-05, 2.52510130e-05, 2.63627059e-05, 2.60805533e-05, - 2.53581818e-05, 2.52264805e-05, 2.49841284e-05, 2.37004032e-05, - 2.25277655e-05, 2.27242698e-05, 2.29565929e-05, 2.24302937e-05, - 2.59084209e-05, 2.67981636e-05, 2.67636374e-05, 2.56780491e-05, - 2.48799035e-05, 2.47194300e-05, 2.33535690e-05, 2.18758266e-05, - 2.13948777e-05, 2.67351633e-05, 2.72697541e-05, 2.72562357e-05, - 2.51187288e-05, 2.25430213e-05, 2.22736144e-05, 2.22927056e-05, - 2.19973352e-05, 2.19356395e-05, 2.48538946e-05, 2.66923306e-05, - 2.70950222e-05, 2.59292282e-05, 2.42129097e-05, 2.42956237e-05, - 2.44966638e-05, 2.34572935e-05, 2.21612552e-05, 2.27407966e-05, - 2.48786351e-05, 2.71034412e-05, 2.73468321e-05, 2.71517139e-05, - 2.53197755e-05, 2.23371607e-05, 2.11791809e-05, 2.16077140e-05, - 2.66522057e-05, 2.72459976e-05, 2.71290585e-05, 2.60116576e-05, - 2.35726220e-05, 2.14259250e-05, 2.08862107e-05, 2.16871466e-05, - 2.70676510e-05, 2.72524742e-05, 2.71039708e-05, 2.58071215e-05, - 2.25317909e-05, 2.08220118e-05, 2.14422964e-05, 2.21044721e-05, - 2.70894399e-05, 2.71035296e-05, 2.68958453e-05, 2.50104545e-05, - 2.38761523e-05, 2.32868615e-05, 2.25859783e-05, 2.60881520e-05, - 2.67527393e-05, 2.68949314e-05, 2.67046229e-05, 2.49904010e-05, - 2.25303045e-05, 2.19546955e-05, 2.22369107e-05, 2.58118037e-05, - 2.65974554e-05, 2.65709178e-05, 2.59816773e-05, 2.53720994e-05, - 2.47093811e-05, 2.31204265e-05, 2.23198282e-05, 2.55308463e-05, - 2.66769721e-05, 2.66569782e-05, 2.62513475e-05, 2.59216187e-05, - 2.48088008e-05, 2.31622143e-05, 2.21564753e-05, 2.22058735e-05, - 2.45136814e-05, 2.65046747e-05, 2.71626851e-05, 2.73837470e-05, - 2.64313101e-05, 2.30875403e-05, 2.18394542e-05, 2.31924328e-05, - 2.64265633e-05, 2.69361851e-05, 2.64759045e-05, 2.50362792e-05, - 2.45819133e-05, 2.40754688e-05, 2.27469604e-05, 2.23327324e-05, - 2.44617748e-05, 2.63723790e-05, 2.71494541e-05, 2.65705134e-05, - 2.52371944e-05, 2.35628418e-05, 2.23988314e-05, 2.23690867e-05, - 2.54400785e-05, 2.66580720e-05, 2.67879088e-05, 2.60196704e-05, - 2.48349510e-05, 2.37204240e-05, 2.23167497e-05, 2.27070072e-05, - 2.33650568e-05, 2.53080225e-05, 2.70064924e-05, 2.73348600e-05, - 2.67634220e-05, 2.43737481e-05, 2.25565678e-05, 2.13897280e-05, - 2.12685258e-05, 2.19745788e-05, 2.58936082e-05, 2.65446804e-05, - 2.67404786e-05, 2.57387660e-05, 2.36566852e-05, 2.39115922e-05, - 2.31509651e-05, 2.17747560e-05, 2.59645648e-05, 2.65995286e-05, - 2.65916712e-05, 2.64432280e-05, 2.58026137e-05, 2.37652970e-05, - 2.25966976e-05, 2.30144229e-05, 2.63646448e-05, 2.69909555e-05, - 2.70274052e-05, 2.52111064e-05, 2.23867052e-05, 2.23037262e-05, - 2.27313008e-05, 2.52043958e-05, 2.64318464e-05, 2.69679621e-05, - 2.68439276e-05, 2.56792295e-05, 2.42985199e-05, 2.31823137e-05, - 2.19652323e-05, - 2.55993561e-05, 2.82725395e-05, 2.87521702e-05, 2.74681728e-05, - 2.51844377e-05, 2.27759781e-05, 2.13709345e-05, 2.13247163e-05, - 2.15151680e-05, 2.52395986e-05, 2.70857242e-05, 2.65908836e-05, - 2.53803680e-05, 2.51708584e-05, 2.48088793e-05, 2.29408790e-05, - 2.13916828e-05, 2.16918323e-05, 2.20271443e-05, 2.13534446e-05, - 2.62497429e-05, 2.79283695e-05, 2.78669694e-05, 2.58656360e-05, - 2.46070684e-05, 2.44301169e-05, 2.25551232e-05, 2.06352392e-05, - 2.00383959e-05, 2.77941555e-05, 2.98200072e-05, 2.92190433e-05, - 2.49201952e-05, 2.13141762e-05, 2.10774974e-05, 2.11829078e-05, - 2.08082182e-05, 2.07257955e-05, 2.44945609e-05, 2.76896693e-05, - 2.86921960e-05, 2.62544465e-05, 2.36350908e-05, 2.38484590e-05, - 2.42053990e-05, 2.27504704e-05, 2.10388652e-05, 2.16185888e-05, - 2.45478198e-05, 2.86973588e-05, 2.99954208e-05, 2.88178507e-05, - 2.53044639e-05, 2.11867014e-05, 1.97932959e-05, 2.03337791e-05, - 2.76430474e-05, 2.93193334e-05, 2.88396598e-05, 2.63791757e-05, - 2.27260194e-05, 2.00061005e-05, 1.93909051e-05, 2.04093508e-05, - 2.85709581e-05, 2.96092418e-05, 2.88025258e-05, 2.60357074e-05, - 2.13651512e-05, 1.93033093e-05, 2.01182426e-05, 2.09443961e-05, - 2.86627505e-05, 2.98893605e-05, 2.81840376e-05, 2.47149793e-05, - 2.31843430e-05, 2.25316463e-05, 2.16177335e-05, 2.65390182e-05, - 2.78270117e-05, 2.81632832e-05, 2.77370137e-05, 2.48750860e-05, - 2.14742528e-05, 2.07503743e-05, 2.11113250e-05, 2.60675711e-05, - 2.74836732e-05, 2.74310324e-05, 2.63463342e-05, 2.54160076e-05, - 2.44976362e-05, 2.22797620e-05, 2.12165840e-05, 2.56123625e-05, - 2.76601356e-05, 2.76202509e-05, 2.68150465e-05, 2.62621052e-05, - 2.45882084e-05, 2.23271161e-05, 2.10136228e-05, 2.10720843e-05, - 2.39218570e-05, 2.73000816e-05, 2.97586296e-05, 2.98454613e-05, - 2.72935040e-05, 2.22740180e-05, 2.06307920e-05, 2.24334195e-05, - 2.71579077e-05, 2.83116981e-05, 2.72307775e-05, 2.48054683e-05, - 2.41881996e-05, 2.35442915e-05, 2.17624360e-05, 2.12239129e-05, - 2.38572321e-05, 2.70187410e-05, 2.88424976e-05, 2.74585088e-05, - 2.51930952e-05, 2.28458566e-05, 2.13351841e-05, 2.12733167e-05, - 2.54827044e-05, 2.76175625e-05, 2.79011002e-05, 2.63915497e-05, - 2.45150899e-05, 2.30014111e-05, 2.11918608e-05, 2.17331386e-05, - 2.26427040e-05, 2.52161230e-05, 2.84598088e-05, 2.96968705e-05, - 2.78631312e-05, 2.38731719e-05, 2.14363495e-05, 2.00296994e-05, - 1.98996533e-05, 2.07812329e-05, 2.61361656e-05, 2.73850839e-05, - 2.78022861e-05, 2.59440781e-05, 2.29519341e-05, 2.34665087e-05, - 2.24305170e-05, 2.05710531e-05, 2.63679162e-05, 2.74854391e-05, - 2.74682606e-05, 2.71811871e-05, 2.60928846e-05, 2.30565044e-05, - 2.15305601e-05, 2.21405416e-05, 2.69973558e-05, 2.87453856e-05, - 2.84937423e-05, 2.51977365e-05, 2.12922773e-05, 2.11922417e-05, - 2.17666295e-05, 2.50473773e-05, 2.71361125e-05, 2.83601495e-05, - 2.80308147e-05, 2.59459416e-05, 2.39136820e-05, 2.23629276e-05, - 2.07561493e-05, - 2.56859285e-05, 2.75109570e-05, 2.77904959e-05, 2.64837492e-05, - 2.46249613e-05, 2.31424718e-05, 2.22045769e-05, 2.23223132e-05, - 2.27033473e-05, 2.55491548e-05, 2.68974722e-05, 2.66082347e-05, - 2.54719485e-05, 2.52719065e-05, 2.50381251e-05, 2.33207034e-05, - 2.20589488e-05, 2.25843139e-05, 2.30559898e-05, 2.25294179e-05, - 2.59381785e-05, 2.70963254e-05, 2.73872287e-05, 2.56408766e-05, - 2.45546165e-05, 2.48360022e-05, 2.35117620e-05, 2.18157578e-05, - 2.12909514e-05, 2.70740473e-05, 2.80994235e-05, 2.79690939e-05, - 2.44265353e-05, 2.14086096e-05, 2.18563602e-05, 2.24116426e-05, - 2.20814617e-05, 2.19821206e-05, 2.39112636e-05, 2.61050642e-05, - 2.73569352e-05, 2.56476658e-05, 2.37624868e-05, 2.45588887e-05, - 2.52860575e-05, 2.40059867e-05, 2.24153469e-05, 2.19582840e-05, - 2.40788735e-05, 2.75248597e-05, 2.86678846e-05, 2.78429971e-05, - 2.52932666e-05, 2.21131040e-05, 2.11787271e-05, 2.17322591e-05, - 2.73190847e-05, 2.77335560e-05, 2.72764224e-05, 2.55466949e-05, - 2.28864328e-05, 2.08685110e-05, 2.05636575e-05, 2.16711506e-05, - 2.82112727e-05, 2.78157132e-05, 2.70489029e-05, 2.53714081e-05, - 2.18483326e-05, 2.04297600e-05, 2.14802540e-05, 2.22062010e-05, - 2.74370302e-05, 2.76489310e-05, 2.64884764e-05, 2.39454007e-05, - 2.35306761e-05, 2.38759094e-05, 2.31203611e-05, 2.59453610e-05, - 2.62620369e-05, 2.67094567e-05, 2.71802271e-05, 2.54790050e-05, - 2.25899688e-05, 2.20072319e-05, 2.23461958e-05, 2.56236436e-05, - 2.62381856e-05, 2.62908615e-05, 2.57319416e-05, 2.56025948e-05, - 2.54247881e-05, 2.34839241e-05, 2.24357701e-05, 2.53245032e-05, - 2.66931781e-05, 2.67255933e-05, 2.59306209e-05, 2.58543602e-05, - 2.51391500e-05, 2.34777774e-05, 2.22857588e-05, 2.23131177e-05, - 2.29182194e-05, 2.50163179e-05, 2.76049512e-05, 2.87621980e-05, - 2.78127284e-05, 2.36957826e-05, 2.20409636e-05, 2.39491420e-05, - 2.63647933e-05, 2.64501369e-05, 2.59375346e-05, 2.44286206e-05, - 2.43655867e-05, 2.43463603e-05, 2.28829901e-05, 2.23903338e-05, - 2.29593578e-05, 2.56008360e-05, 2.76119375e-05, 2.68769004e-05, - 2.53310830e-05, 2.38080381e-05, 2.26384556e-05, 2.24499647e-05, - 2.53471568e-05, 2.65781863e-05, 2.67447062e-05, 2.55364839e-05, - 2.43005333e-05, 2.35779782e-05, 2.22962843e-05, 2.29872569e-05, - 2.40079670e-05, 2.46677267e-05, 2.69562382e-05, 2.83653135e-05, - 2.73184046e-05, 2.40144762e-05, 2.21414114e-05, 2.12701749e-05, - 2.12577627e-05, 2.20670580e-05, 2.49183026e-05, 2.51635419e-05, - 2.61375875e-05, 2.55138066e-05, 2.37675258e-05, 2.51713204e-05, - 2.42402200e-05, 2.21047482e-05, 2.62311860e-05, 2.60736019e-05, - 2.58616363e-05, 2.62354500e-05, 2.59989188e-05, 2.35833788e-05, - 2.24695595e-05, 2.33691369e-05, 2.53729978e-05, 2.61239401e-05, - 2.72290012e-05, 2.56533695e-05, 2.24460761e-05, 2.23930886e-05, - 2.30272244e-05, 2.44813217e-05, 2.56613988e-05, 2.68063017e-05, - 2.71605305e-05, 2.63203776e-05, 2.49912416e-05, 2.35613181e-05, - 2.19704133e-05, - 2.47196264e-05, 2.15550310e-05, 2.07793270e-05, 2.17086955e-05, - 2.36083993e-05, 2.62166997e-05, 2.75388460e-05, 2.79248612e-05, - 2.83254554e-05, 2.53143659e-05, 2.34289085e-05, 2.40995042e-05, - 2.48234295e-05, 2.49278296e-05, 2.53247818e-05, 2.62073603e-05, - 2.71528277e-05, 2.76143539e-05, 2.78506613e-05, 2.83308429e-05, - 2.36469410e-05, 2.16840912e-05, 2.23774601e-05, 2.39935716e-05, - 2.48265409e-05, 2.58218691e-05, 2.75608455e-05, 2.84703266e-05, - 2.87290067e-05, 2.19851903e-05, 1.80570047e-05, 1.97753206e-05, - 2.38309729e-05, 2.58467134e-05, 2.74588119e-05, 2.84867947e-05, - 2.86607397e-05, 2.86350986e-05, 2.37824933e-05, 2.04484836e-05, - 2.01437477e-05, 2.30775402e-05, 2.54926410e-05, 2.66515496e-05, - 2.72921349e-05, 2.81612521e-05, 2.88595638e-05, 2.63700079e-05, - 2.39993376e-05, 2.04405331e-05, 1.85652330e-05, 2.06940362e-05, - 2.46512302e-05, 2.77843939e-05, 2.90854398e-05, 2.90390680e-05, - 2.28207641e-05, 1.90241021e-05, 1.95810134e-05, 2.25860854e-05, - 2.57789541e-05, 2.77839437e-05, 2.86011802e-05, 2.86991531e-05, - 2.20416549e-05, 1.82367396e-05, 1.92589709e-05, 2.30658272e-05, - 2.67337608e-05, 2.84922723e-05, 2.89839225e-05, 2.86092534e-05, - 2.03732199e-05, 1.67909769e-05, 1.98951704e-05, 2.33403406e-05, - 2.60754194e-05, 2.84203904e-05, 2.90214462e-05, 2.29643988e-05, - 2.03943821e-05, 2.03610325e-05, 2.23263819e-05, 2.60538547e-05, - 2.81677761e-05, 2.86321497e-05, 2.85149305e-05, 2.34776199e-05, - 2.12118819e-05, 2.14409225e-05, 2.30194399e-05, 2.49960198e-05, - 2.68616555e-05, 2.81800490e-05, 2.84580257e-05, 2.39796828e-05, - 2.16182677e-05, 2.17787079e-05, 2.22703540e-05, 2.34562424e-05, - 2.60596363e-05, 2.80487861e-05, 2.86205226e-05, 2.85367856e-05, - 2.30617467e-05, 1.93668242e-05, 1.72460746e-05, 1.92898976e-05, - 2.46162494e-05, 2.86657441e-05, 2.90164810e-05, 2.88279274e-05, - 2.22528589e-05, 1.94854460e-05, 2.12724934e-05, 2.41040624e-05, - 2.54340589e-05, 2.69430108e-05, 2.81175499e-05, 2.83342460e-05, - 2.32948413e-05, 2.11546236e-05, 2.01983140e-05, 2.24647649e-05, - 2.49924265e-05, 2.74945395e-05, 2.86283961e-05, 2.83483308e-05, - 2.43327581e-05, 2.15114634e-05, 2.11033063e-05, 2.25370166e-05, - 2.45270073e-05, 2.66173042e-05, 2.81964888e-05, 2.84274999e-05, - 2.84336966e-05, 2.36190981e-05, 2.00331424e-05, 1.90232496e-05, - 2.22604862e-05, 2.54550601e-05, 2.72324319e-05, 2.87007381e-05, - 2.90046150e-05, 2.86951951e-05, 2.19533407e-05, 1.94366951e-05, - 2.02247973e-05, 2.35595438e-05, 2.71471315e-05, 2.88847187e-05, - 2.94794116e-05, 2.93213912e-05, 2.39233681e-05, 2.08998159e-05, - 2.05454202e-05, 2.19531465e-05, 2.41415872e-05, 2.64959053e-05, - 2.77517263e-05, 2.82706206e-05, 2.07757719e-05, 1.76492392e-05, - 2.04477694e-05, 2.56225001e-05, 2.82917705e-05, 2.84202215e-05, - 2.84343928e-05, 2.36430505e-05, 2.09841226e-05, 2.00214141e-05, - 2.15393189e-05, 2.51191506e-05, 2.73958491e-05, 2.81451864e-05, - 2.85305231e-05, - 2.30346336e-05, 1.67713691e-05, 1.55163968e-05, 1.76966334e-05, - 2.21704320e-05, 2.83314233e-05, 3.20964273e-05, 3.27049579e-05, - 3.29738197e-05, 2.41514194e-05, 1.99640328e-05, 2.12337638e-05, - 2.34044126e-05, 2.37677777e-05, 2.46678238e-05, 2.81021818e-05, - 3.15268951e-05, 3.17273560e-05, 3.15605709e-05, 3.32280920e-05, - 2.10802430e-05, 1.72338120e-05, 1.80346315e-05, 2.18906373e-05, - 2.42946713e-05, 2.57311401e-05, 3.04152441e-05, 3.45492871e-05, - 3.58991031e-05, 1.76843853e-05, 1.18207628e-05, 1.40682185e-05, - 2.27265511e-05, 2.98096454e-05, 3.24227069e-05, 3.37095048e-05, - 3.45454194e-05, 3.46404943e-05, 2.31378737e-05, 1.61291661e-05, - 1.49149202e-05, 2.04223611e-05, 2.62928729e-05, 2.74964307e-05, - 2.78379764e-05, 3.09338705e-05, 3.44603530e-05, 3.01133283e-05, - 2.33455087e-05, 1.52167536e-05, 1.21664101e-05, 1.53682219e-05, - 2.32850968e-05, 3.27168351e-05, 3.68391780e-05, 3.58608118e-05, - 1.87332283e-05, 1.32219412e-05, 1.42057516e-05, 1.97340884e-05, - 2.78176364e-05, 3.45607438e-05, 3.68055454e-05, 3.52439043e-05, - 1.69949957e-05, 1.21825408e-05, 1.39076727e-05, 2.06338588e-05, - 3.09798666e-05, 3.67918148e-05, 3.61395698e-05, 3.42560658e-05, - 1.51784318e-05, 1.05065841e-05, 1.51041276e-05, 2.23534195e-05, - 2.76132100e-05, 3.15921176e-05, 3.37779163e-05, 2.00028103e-05, - 1.59486217e-05, 1.56133635e-05, 1.81067538e-05, 2.54747049e-05, - 3.28171619e-05, 3.45969773e-05, 3.38605856e-05, 2.10768622e-05, - 1.71418186e-05, 1.74400707e-05, 2.02617605e-05, 2.35689773e-05, - 2.69296479e-05, 3.16375835e-05, 3.36168696e-05, 2.21484409e-05, - 1.74169017e-05, 1.76280927e-05, 1.89459118e-05, 2.08485891e-05, - 2.58310375e-05, 3.13925438e-05, 3.41627713e-05, 3.39527438e-05, - 2.28718850e-05, 1.52976126e-05, 1.10698540e-05, 1.30178429e-05, - 2.10539037e-05, 3.22984311e-05, 3.53399215e-05, 3.22789318e-05, - 1.85913820e-05, 1.45636922e-05, 1.74428114e-05, 2.31854099e-05, - 2.55428509e-05, 2.82630752e-05, 3.23150146e-05, 3.34319868e-05, - 2.32377452e-05, 1.75096931e-05, 1.48365233e-05, 1.85294674e-05, - 2.38197312e-05, 2.99218009e-05, 3.36712577e-05, 3.33755861e-05, - 2.27075177e-05, 1.73416117e-05, 1.66390661e-05, 1.96657993e-05, - 2.40324488e-05, 2.85596684e-05, 3.32880349e-05, 3.27844727e-05, - 3.14486204e-05, 2.21490439e-05, 1.50064871e-05, 1.28878918e-05, - 1.79130431e-05, 2.59522613e-05, 3.15725509e-05, 3.58720450e-05, - 3.65383777e-05, 3.46376244e-05, 1.92497540e-05, 1.53014870e-05, - 1.57891799e-05, 2.13018178e-05, 2.93201082e-05, 3.08531611e-05, - 3.31511276e-05, 3.58754413e-05, 2.12714171e-05, 1.68012438e-05, - 1.64320718e-05, 1.82383920e-05, 2.18169461e-05, 2.83279728e-05, - 3.21553884e-05, 3.19635580e-05, 1.71098621e-05, 1.23060523e-05, - 1.54080396e-05, 2.45691610e-05, 3.32673249e-05, 3.36015660e-05, - 3.27434175e-05, 2.23604806e-05, 1.72131518e-05, 1.50821391e-05, - 1.69827563e-05, 2.31116272e-05, 2.83506051e-05, 3.14698927e-05, - 3.44426290e-05, - 2.21723270e-05, 1.49844214e-05, 1.36283761e-05, 1.62057596e-05, - 2.15932651e-05, 2.91082232e-05, 3.39210735e-05, 3.45613570e-05, - 3.46591094e-05, 2.34392348e-05, 1.84911014e-05, 1.99285703e-05, - 2.26504128e-05, 2.31198071e-05, 2.41962357e-05, 2.87640211e-05, - 3.33396500e-05, 3.32862836e-05, 3.28435012e-05, 3.50503529e-05, - 1.99720702e-05, 1.55653905e-05, 1.63285703e-05, 2.09441832e-05, - 2.39673113e-05, 2.54503472e-05, 3.13029782e-05, 3.70048398e-05, - 3.89183551e-05, 1.60419788e-05, 9.84229411e-06, 1.21170691e-05, - 2.22772431e-05, 3.16869064e-05, 3.44964508e-05, 3.56748491e-05, - 3.68400852e-05, 3.70106718e-05, 2.29224982e-05, 1.46482721e-05, - 1.31046554e-05, 1.93524129e-05, 2.65200676e-05, 2.75288149e-05, - 2.75977158e-05, 3.16459436e-05, 3.65428407e-05, 3.17498738e-05, - 2.30915575e-05, 1.33785588e-05, 1.00899253e-05, 1.34654024e-05, - 2.25832187e-05, 3.46932672e-05, 4.01013919e-05, 3.85915229e-05, - 1.70772324e-05, 1.13072170e-05, 1.23949002e-05, 1.86401723e-05, - 2.86414292e-05, 3.76060835e-05, 4.04767850e-05, 3.79069821e-05, - 1.50503144e-05, 1.02497072e-05, 1.21357720e-05, 1.96670445e-05, - 3.28177568e-05, 4.05524061e-05, 3.90794256e-05, 3.64291264e-05, - 1.33580912e-05, 8.61566652e-06, 1.34879548e-05, 2.20356803e-05, - 2.81131346e-05, 3.24559625e-05, 3.53509878e-05, 1.88106542e-05, - 1.44214495e-05, 1.39681062e-05, 1.64570966e-05, 2.49155428e-05, - 3.45414590e-05, 3.69447747e-05, 3.58878664e-05, 2.00676063e-05, - 1.56828626e-05, 1.59844935e-05, 1.91534026e-05, 2.27837972e-05, - 2.65374139e-05, 3.27084933e-05, 3.55536517e-05, 2.13300742e-05, - 1.58577073e-05, 1.60714573e-05, 1.76823631e-05, 1.97484755e-05, - 2.54404657e-05, 3.24325257e-05, 3.62738530e-05, 3.60140390e-05, - 2.29988827e-05, 1.40275442e-05, 9.17810178e-06, 1.09163754e-05, - 1.93759138e-05, 3.33502552e-05, 3.77905160e-05, 3.31963436e-05, - 1.71842793e-05, 1.29351480e-05, 1.60785975e-05, 2.27845902e-05, - 2.54296278e-05, 2.84795398e-05, 3.38018285e-05, 3.53655126e-05, - 2.33970320e-05, 1.62379839e-05, 1.29707256e-05, 1.69807435e-05, - 2.31553284e-05, 3.05980108e-05, 3.55005634e-05, 3.52661220e-05, - 2.19326743e-05, 1.58075788e-05, 1.50296125e-05, 1.85695618e-05, - 2.37727517e-05, 2.91640142e-05, 3.52524217e-05, 3.42845027e-05, - 3.22268113e-05, 2.15549045e-05, 1.32846071e-05, 1.08574968e-05, - 1.62191202e-05, 2.60312556e-05, 3.33475439e-05, 3.88998613e-05, - 3.96939791e-05, 3.69561459e-05, 1.83031533e-05, 1.39969903e-05, - 1.42833586e-05, 2.03465356e-05, 2.99363530e-05, 3.09928320e-05, - 3.40306869e-05, 3.83752224e-05, 2.00860269e-05, 1.53644587e-05, - 1.50267136e-05, 1.68445868e-05, 2.07475435e-05, 2.88989064e-05, - 3.38432059e-05, 3.31400024e-05, 1.58707411e-05, 1.06737920e-05, - 1.36395810e-05, 2.38577560e-05, 3.51429909e-05, 3.55604543e-05, - 3.42155394e-05, 2.18530674e-05, 1.59060297e-05, 1.33953663e-05, - 1.52878762e-05, 2.20386657e-05, 2.82926743e-05, 3.24777305e-05, - 3.67868959e-05, - 2.25984868e-05, 1.58866678e-05, 1.45736452e-05, 1.74222418e-05, - 2.28274477e-05, 2.92369234e-05, 3.30699766e-05, 3.33458612e-05, - 3.30598744e-05, 2.36067453e-05, 1.90874675e-05, 2.03658102e-05, - 2.30840841e-05, 2.35545606e-05, 2.44826331e-05, 2.88678940e-05, - 3.28479005e-05, 3.23477805e-05, 3.16697323e-05, 3.34451402e-05, - 2.07804203e-05, 1.65783759e-05, 1.70836854e-05, 2.17040330e-05, - 2.46433843e-05, 2.55011348e-05, 3.03426920e-05, 3.52347410e-05, - 3.68193114e-05, 1.69944221e-05, 1.08783739e-05, 1.31224195e-05, - 2.34767346e-05, 3.23924304e-05, 3.37340058e-05, 3.39145002e-05, - 3.48878214e-05, 3.50786972e-05, 2.43064747e-05, 1.62419754e-05, - 1.42827017e-05, 2.04595587e-05, 2.70110135e-05, 2.71078511e-05, - 2.66268331e-05, 3.01507267e-05, 3.44060243e-05, 3.19437547e-05, - 2.43203015e-05, 1.44614376e-05, 1.09321431e-05, 1.44057148e-05, - 2.31479247e-05, 3.36149759e-05, 3.75759306e-05, 3.62000676e-05, - 1.77340515e-05, 1.24459087e-05, 1.36577606e-05, 1.99436735e-05, - 2.91311165e-05, 3.65094691e-05, 3.84204239e-05, 3.58819482e-05, - 1.56280981e-05, 1.13823157e-05, 1.35050340e-05, 2.08691347e-05, - 3.27148508e-05, 3.86037912e-05, 3.67171470e-05, 3.45371217e-05, - 1.44800456e-05, 9.76448359e-06, 1.50091800e-05, 2.36074489e-05, - 2.82706350e-05, 3.07464301e-05, 3.30874000e-05, 1.98589776e-05, - 1.59640443e-05, 1.53500234e-05, 1.72911742e-05, 2.46928959e-05, - 3.30924681e-05, 3.50175407e-05, 3.40973756e-05, 2.10374074e-05, - 1.70931390e-05, 1.73282970e-05, 2.02529702e-05, 2.30990048e-05, - 2.58309655e-05, 3.12247267e-05, 3.38224513e-05, 2.21899044e-05, - 1.70219948e-05, 1.71887074e-05, 1.89475624e-05, 2.06540371e-05, - 2.52853412e-05, 3.10633968e-05, 3.43742886e-05, 3.42003885e-05, - 2.50501841e-05, 1.61894045e-05, 1.03666293e-05, 1.16973997e-05, - 1.92883209e-05, 3.14282949e-05, 3.54582185e-05, 3.11252227e-05, - 1.83060904e-05, 1.45107353e-05, 1.75861590e-05, 2.38573289e-05, - 2.58156933e-05, 2.78905510e-05, 3.23948321e-05, 3.37552272e-05, - 2.53260288e-05, 1.78957328e-05, 1.40539465e-05, 1.78760980e-05, - 2.35422484e-05, 2.96626150e-05, 3.36067171e-05, 3.36429703e-05, - 2.26307183e-05, 1.70348741e-05, 1.62797028e-05, 1.98919042e-05, - 2.46741558e-05, 2.89281896e-05, 3.37757294e-05, 3.25882762e-05, - 3.05004194e-05, 2.27708959e-05, 1.46180184e-05, 1.17820252e-05, - 1.70255492e-05, 2.64871324e-05, 3.27786390e-05, 3.68300973e-05, - 3.72756282e-05, 3.49670250e-05, 2.00208623e-05, 1.60903880e-05, - 1.58968017e-05, 2.13193959e-05, 2.92765556e-05, 2.88370828e-05, - 3.13665202e-05, 3.57179605e-05, 2.07004548e-05, 1.68947928e-05, - 1.66979032e-05, 1.80885889e-05, 2.13415967e-05, 2.87505181e-05, - 3.27852964e-05, 3.15804123e-05, 1.76909338e-05, 1.24305188e-05, - 1.48240630e-05, 2.38376890e-05, 3.35748925e-05, 3.38655764e-05, - 3.25126741e-05, 2.31182994e-05, 1.75753212e-05, 1.47846446e-05, - 1.63097915e-05, 2.21126951e-05, 2.72903193e-05, 3.10208125e-05, - 3.49632188e-05, - 2.27930074e-05, 1.63320887e-05, 1.50458604e-05, 1.79460363e-05, - 2.32583139e-05, 2.91779750e-05, 3.26160362e-05, 3.27835378e-05, - 3.24045859e-05, 2.37046944e-05, 1.93967252e-05, 2.06065866e-05, - 2.32704993e-05, 2.37309992e-05, 2.45948866e-05, 2.88127016e-05, - 3.25003434e-05, 3.18943361e-05, 3.11747711e-05, 3.27749954e-05, - 2.11238972e-05, 1.70499098e-05, 1.74695406e-05, 2.20152267e-05, - 2.48654348e-05, 2.55213608e-05, 2.99475439e-05, 3.44568492e-05, - 3.58948014e-05, 1.74418637e-05, 1.14022095e-05, 1.36252478e-05, - 2.38824899e-05, 3.23993088e-05, 3.32813861e-05, 3.31867775e-05, - 3.40745383e-05, 3.42637770e-05, 2.47489941e-05, 1.69029746e-05, - 1.48314393e-05, 2.08995862e-05, 2.71189100e-05, 2.69540345e-05, - 2.63345019e-05, 2.96174634e-05, 3.35617637e-05, 3.18187297e-05, - 2.47152045e-05, 1.49781147e-05, 1.13928835e-05, 1.48778890e-05, - 2.33713201e-05, 3.30804234e-05, 3.65105012e-05, 3.52229943e-05, - 1.80814966e-05, 1.29961386e-05, 1.42395191e-05, 2.04537567e-05, - 2.91788030e-05, 3.58641822e-05, 3.74435803e-05, 3.50126885e-05, - 1.59771495e-05, 1.19361224e-05, 1.41230033e-05, 2.13305643e-05, - 3.24802267e-05, 3.76478820e-05, 3.57277969e-05, 3.37524245e-05, - 1.50089845e-05, 1.03285762e-05, 1.56619101e-05, 2.41244477e-05, - 2.82478590e-05, 3.01378069e-05, 3.22564832e-05, 2.02918404e-05, - 1.66120416e-05, 1.59533377e-05, 1.76983531e-05, 2.46551718e-05, - 3.24761391e-05, 3.42061105e-05, 3.33552090e-05, 2.14247151e-05, - 1.76830254e-05, 1.78936386e-05, 2.06944724e-05, 2.32506502e-05, - 2.56311774e-05, 3.06609047e-05, 3.31056881e-05, 2.25211396e-05, - 1.75349812e-05, 1.76846994e-05, 1.94630200e-05, 2.10291376e-05, - 2.52524777e-05, 3.05353569e-05, 3.35934497e-05, 3.34484372e-05, - 2.56814740e-05, 1.70415699e-05, 1.09427923e-05, 1.21364257e-05, - 1.93952040e-05, 3.07419781e-05, 3.45244782e-05, 3.04096139e-05, - 1.87872151e-05, 1.51870891e-05, 1.81999295e-05, 2.42159789e-05, - 2.59243391e-05, 2.76688730e-05, 3.18133127e-05, 3.30729259e-05, - 2.59116231e-05, 1.85530548e-05, 1.45743953e-05, 1.82938838e-05, - 2.37050369e-05, 2.92948930e-05, 3.28545429e-05, 3.29611726e-05, - 2.29045390e-05, 1.75674967e-05, 1.68294926e-05, 2.04087899e-05, - 2.49621831e-05, 2.87753474e-05, 3.31283348e-05, 3.19232360e-05, - 2.98950355e-05, 2.31974509e-05, 1.52136335e-05, 1.22664057e-05, - 1.74277795e-05, 2.65987462e-05, 3.24120964e-05, 3.59128573e-05, - 3.62498863e-05, 3.41411541e-05, 2.06601235e-05, 1.69206229e-05, - 1.65688825e-05, 2.17021687e-05, 2.89957537e-05, 2.81695712e-05, - 3.04900036e-05, 3.46903899e-05, 2.09875325e-05, 1.75260991e-05, - 1.73778715e-05, 1.86111468e-05, 2.16106219e-05, 2.86273731e-05, - 3.22847307e-05, 3.09849441e-05, 1.84045139e-05, 1.31895829e-05, - 1.53695823e-05, 2.38768774e-05, 3.29101208e-05, 3.31569268e-05, - 3.18484160e-05, 2.35521897e-05, 1.82414645e-05, 1.53966747e-05, - 1.67874257e-05, 2.22152833e-05, 2.69718673e-05, 3.04706454e-05, - 3.41811057e-05, - 2.34963968e-05, 1.80414374e-05, 1.68847828e-05, 1.94708989e-05, - 2.39002841e-05, 2.84146427e-05, 3.08576566e-05, 3.09598082e-05, - 3.06750463e-05, 2.42171990e-05, 2.06936206e-05, 2.17045959e-05, - 2.38806284e-05, 2.42485005e-05, 2.49264181e-05, 2.81429763e-05, - 3.07913824e-05, 3.03417708e-05, 2.98160960e-05, 3.09363830e-05, - 2.21475891e-05, 1.86808272e-05, 1.90399400e-05, 2.28778376e-05, - 2.51537856e-05, 2.56412204e-05, 2.89349936e-05, 3.21008022e-05, - 3.30671033e-05, 1.90226733e-05, 1.34578196e-05, 1.55771193e-05, - 2.43972606e-05, 3.07692815e-05, 3.13293519e-05, 3.12186938e-05, - 3.18283419e-05, 3.19601645e-05, 2.50882329e-05, 1.85701026e-05, - 1.66968620e-05, 2.19725129e-05, 2.68857478e-05, 2.67237251e-05, - 2.62269392e-05, 2.86696903e-05, 3.14635462e-05, 3.03356826e-05, - 2.50562075e-05, 1.68276470e-05, 1.34426535e-05, 1.67314796e-05, - 2.39663468e-05, 3.11746444e-05, 3.34615201e-05, 3.25972039e-05, - 1.95687889e-05, 1.49904539e-05, 1.61557338e-05, 2.16082427e-05, - 2.84296513e-05, 3.30923923e-05, 3.41056096e-05, 3.24706723e-05, - 1.77129221e-05, 1.39784286e-05, 1.60512509e-05, 2.23321739e-05, - 3.07935888e-05, 3.42458455e-05, 3.29417188e-05, 3.16075603e-05, - 1.68570532e-05, 1.24026248e-05, 1.74611261e-05, 2.46021763e-05, - 2.77239861e-05, 2.90410710e-05, 3.05398736e-05, 2.14640783e-05, - 1.83111326e-05, 1.77187957e-05, 1.92424162e-05, 2.49535903e-05, - 3.07324126e-05, 3.19205309e-05, 3.13352124e-05, 2.24015365e-05, - 1.92485188e-05, 1.94296093e-05, 2.18018562e-05, 2.38601681e-05, - 2.56954721e-05, 2.94313918e-05, 3.11631665e-05, 2.32928059e-05, - 1.91112824e-05, 1.92403150e-05, 2.07734696e-05, 2.20727149e-05, - 2.54237795e-05, 2.93454266e-05, 3.14965357e-05, 3.13992974e-05, - 2.58384040e-05, 1.87084236e-05, 1.30122846e-05, 1.41600481e-05, - 2.06662010e-05, 2.94704835e-05, 3.21213759e-05, 2.92227044e-05, - 2.01928369e-05, 1.70331183e-05, 1.97002824e-05, 2.46571105e-05, - 2.59665035e-05, 2.72584154e-05, 3.02633782e-05, 3.11456481e-05, - 2.60125650e-05, 2.00094269e-05, 1.64583675e-05, 1.97608890e-05, - 2.42259901e-05, 2.84566062e-05, 3.09793213e-05, 3.10665833e-05, - 2.35965615e-05, 1.91417760e-05, 1.84943649e-05, 2.15713189e-05, - 2.52379784e-05, 2.81013674e-05, 3.11905312e-05, 3.03288218e-05, - 2.88629387e-05, 2.38508287e-05, 1.70499096e-05, 1.42894216e-05, - 1.90052409e-05, 2.64877046e-05, 3.07256219e-05, 3.30806777e-05, - 3.32915646e-05, 3.18727583e-05, 2.17939360e-05, 1.85999454e-05, - 1.82749888e-05, 2.26295405e-05, 2.82471926e-05, 2.75663505e-05, - 2.92538978e-05, 3.22201712e-05, 2.20276304e-05, 1.91153813e-05, - 1.89900311e-05, 2.00459818e-05, 2.25405944e-05, 2.79948934e-05, - 3.06141511e-05, 2.96622762e-05, 1.98865094e-05, 1.51904127e-05, - 1.71865762e-05, 2.43467552e-05, 3.10331711e-05, 3.12007420e-05, - 3.02751905e-05, 2.41364897e-05, 1.97412355e-05, 1.72175718e-05, - 1.84495793e-05, 2.30147295e-05, 2.67128523e-05, 2.92945686e-05, - 3.19079918e-05, - 2.57275539e-05, 2.83500585e-05, 2.88238037e-05, 2.71237350e-05, - 2.46808231e-05, 2.26645442e-05, 2.14745534e-05, 2.15620457e-05, - 2.19373582e-05, 2.54872350e-05, 2.73144122e-05, 2.68750596e-05, - 2.54691813e-05, 2.52271618e-05, 2.49070784e-05, 2.28642767e-05, - 2.13566001e-05, 2.18843472e-05, 2.23781997e-05, 2.17457308e-05, - 2.61762657e-05, 2.78420429e-05, 2.80588678e-05, 2.57831954e-05, - 2.44286557e-05, 2.46117534e-05, 2.29154821e-05, 2.09495265e-05, - 2.03513884e-05, 2.77627749e-05, 2.97613299e-05, 2.92343845e-05, - 2.44228981e-05, 2.07848525e-05, 2.11005266e-05, 2.15998667e-05, - 2.12201729e-05, 2.11142638e-05, 2.38448430e-05, 2.69062231e-05, - 2.84358855e-05, 2.59312033e-05, 2.34478406e-05, 2.41926791e-05, - 2.49259157e-05, 2.33934152e-05, 2.15646208e-05, 2.13329498e-05, - 2.40045349e-05, 2.85761778e-05, 3.03291212e-05, 2.89021523e-05, - 2.52907303e-05, 2.13474135e-05, 2.01944601e-05, 2.08006037e-05, - 2.79033442e-05, 2.91107637e-05, 2.84524460e-05, 2.58927099e-05, - 2.24323588e-05, 1.99861523e-05, 1.95746335e-05, 2.07683285e-05, - 2.90809652e-05, 2.93801293e-05, 2.82479306e-05, 2.56158012e-05, - 2.11708735e-05, 1.94400936e-05, 2.05319137e-05, 2.13619577e-05, - 2.84856637e-05, 2.95153369e-05, 2.74600096e-05, 2.39461472e-05, - 2.31148106e-05, 2.32195426e-05, 2.23202300e-05, 2.62915270e-05, - 2.71000779e-05, 2.76314646e-05, 2.78268762e-05, 2.53058169e-05, - 2.18298545e-05, 2.11420068e-05, 2.15251605e-05, 2.58416580e-05, - 2.69246797e-05, 2.69458452e-05, 2.60372026e-05, 2.55929819e-05, - 2.51372163e-05, 2.28136012e-05, 2.16293782e-05, 2.54239563e-05, - 2.73834534e-05, 2.73930678e-05, 2.63870299e-05, 2.61095834e-05, - 2.49216583e-05, 2.28217159e-05, 2.14478481e-05, 2.14866165e-05, - 2.28200181e-05, 2.58292281e-05, 2.93533888e-05, 3.02815642e-05, - 2.81784264e-05, 2.29927531e-05, 2.11393389e-05, 2.32541747e-05, - 2.68925927e-05, 2.74941496e-05, 2.65638703e-05, 2.43864813e-05, - 2.41333877e-05, 2.39183932e-05, 2.21577300e-05, 2.15927411e-05, - 2.28345281e-05, 2.61926269e-05, 2.87263503e-05, 2.74507055e-05, - 2.52851927e-05, 2.32519742e-05, 2.18335056e-05, 2.16566542e-05, - 2.53980019e-05, 2.72682297e-05, 2.75356173e-05, 2.58887866e-05, - 2.41824139e-05, 2.31011444e-05, 2.15042816e-05, 2.22384364e-05, - 2.33641175e-05, 2.47279894e-05, 2.79846430e-05, 2.98650752e-05, - 2.79991618e-05, 2.37356523e-05, 2.14386401e-05, 2.03316037e-05, - 2.02881291e-05, 2.12008598e-05, 2.52698719e-05, 2.59889968e-05, - 2.69855081e-05, 2.57033175e-05, 2.32482901e-05, 2.46015516e-05, - 2.35022367e-05, 2.11778917e-05, 2.64697018e-05, 2.67879980e-05, - 2.66038615e-05, 2.67932178e-05, 2.61703516e-05, 2.31219324e-05, - 2.17428128e-05, 2.26766403e-05, 2.59931470e-05, 2.74838958e-05, - 2.82261532e-05, 2.55622635e-05, 2.16584444e-05, 2.15866013e-05, - 2.22816612e-05, 2.45122248e-05, 2.62926141e-05, 2.78101591e-05, - 2.79430033e-05, 2.63920163e-05, 2.45827232e-05, 2.29030917e-05, - 2.11122926e-05, - 2.55850187e-05, 2.66305091e-05, 2.67245675e-05, 2.59259225e-05, - 2.47089305e-05, 2.36665947e-05, 2.29323702e-05, 2.30373743e-05, - 2.33604377e-05, 2.55164623e-05, 2.63856774e-05, 2.62292548e-05, - 2.54292574e-05, 2.52829718e-05, 2.51253037e-05, 2.38099750e-05, - 2.28036981e-05, 2.32482412e-05, 2.36410781e-05, 2.32164393e-05, - 2.57004049e-05, 2.63563934e-05, 2.66352764e-05, 2.55035123e-05, - 2.47255211e-05, 2.49934210e-05, 2.40051779e-05, 2.26220152e-05, - 2.21804497e-05, 2.63733779e-05, 2.64816285e-05, 2.66992401e-05, - 2.45705984e-05, 2.22333344e-05, 2.26407667e-05, 2.31210879e-05, - 2.28476875e-05, 2.27639812e-05, 2.41692724e-05, 2.55185375e-05, - 2.63445118e-05, 2.54413224e-05, 2.41358989e-05, 2.48120737e-05, - 2.54074438e-05, 2.44203812e-05, 2.31296444e-05, 2.27026310e-05, - 2.43116656e-05, 2.64990205e-05, 2.69370490e-05, 2.67485524e-05, - 2.52830668e-05, 2.28607888e-05, 2.20873998e-05, 2.25577921e-05, - 2.66319003e-05, 2.64237535e-05, 2.62093861e-05, 2.53270522e-05, - 2.34450713e-05, 2.18111640e-05, 2.15563379e-05, 2.25026933e-05, - 2.71700328e-05, 2.63369928e-05, 2.60085715e-05, 2.52348746e-05, - 2.26197747e-05, 2.14401593e-05, 2.23436380e-05, 2.29514629e-05, - 2.64303308e-05, 2.59341109e-05, 2.57172611e-05, 2.41699060e-05, - 2.39738859e-05, 2.43218250e-05, 2.37168210e-05, 2.56521119e-05, - 2.56224907e-05, 2.59301451e-05, 2.64839818e-05, 2.55018685e-05, - 2.32637642e-05, 2.27850328e-05, 2.30669958e-05, 2.54538545e-05, - 2.56986358e-05, 2.57604956e-05, 2.54991588e-05, 2.55387361e-05, - 2.54975593e-05, 2.39979845e-05, 2.31407157e-05, 2.52644561e-05, - 2.60651809e-05, 2.61051649e-05, 2.55814976e-05, 2.56238361e-05, - 2.52398739e-05, 2.39899081e-05, 2.30181144e-05, 2.30397353e-05, - 2.33516217e-05, 2.46180336e-05, 2.60066999e-05, 2.71315527e-05, - 2.71453420e-05, 2.41812534e-05, 2.28179611e-05, 2.43905402e-05, - 2.58945801e-05, 2.56355710e-05, 2.54901124e-05, 2.45882869e-05, - 2.46083600e-05, 2.46549617e-05, 2.35047113e-05, 2.31009267e-05, - 2.33966251e-05, 2.52355136e-05, 2.65241718e-05, 2.62823560e-05, - 2.53318582e-05, 2.42425886e-05, 2.33118372e-05, 2.31507462e-05, - 2.53044252e-05, 2.59722857e-05, 2.60443118e-05, 2.53154417e-05, - 2.45125494e-05, 2.40305050e-05, 2.30203909e-05, 2.35965880e-05, - 2.44289026e-05, 2.47422735e-05, 2.60569110e-05, 2.68313423e-05, - 2.65745917e-05, 2.43335167e-05, 2.28738074e-05, 2.21625138e-05, - 2.21543503e-05, 2.28360493e-05, 2.48086056e-05, 2.47312446e-05, - 2.55147083e-05, 2.53777667e-05, 2.41996435e-05, 2.53713518e-05, - 2.46401732e-05, 2.28748452e-05, 2.59380907e-05, 2.55475889e-05, - 2.53573645e-05, 2.57725749e-05, 2.57815038e-05, 2.40307989e-05, - 2.31562185e-05, 2.39064436e-05, 2.50320295e-05, 2.51312432e-05, - 2.62986933e-05, 2.56129772e-05, 2.31465748e-05, 2.31045969e-05, - 2.36296093e-05, 2.46011772e-05, 2.52617064e-05, 2.59527079e-05, - 2.63850898e-05, 2.60871856e-05, 2.51805020e-05, 2.40601204e-05, - 2.27528078e-05, - 2.43161535e-05, 2.02644557e-05, 1.93307741e-05, 2.08896797e-05, - 2.36998979e-05, 2.69959950e-05, 2.87166023e-05, 2.90242862e-05, - 2.92161759e-05, 2.49677180e-05, 2.24605882e-05, 2.32677643e-05, - 2.45196870e-05, 2.47173296e-05, 2.52194855e-05, 2.69013783e-05, - 2.84196459e-05, 2.86051294e-05, 2.86012298e-05, 2.93048976e-05, - 2.31250580e-05, 2.05857927e-05, 2.11675488e-05, 2.36126096e-05, - 2.49558594e-05, 2.58023768e-05, 2.81082887e-05, 2.97782377e-05, - 3.02701860e-05, 2.09071258e-05, 1.62853513e-05, 1.81921993e-05, - 2.40185944e-05, 2.74706062e-05, 2.88086327e-05, 2.95068565e-05, - 2.98271413e-05, 2.98511522e-05, 2.42126682e-05, 1.97383937e-05, - 1.88546132e-05, 2.26826382e-05, 2.59911125e-05, 2.67383367e-05, - 2.70038992e-05, 2.84365346e-05, 2.98505025e-05, 2.77150094e-05, - 2.43527201e-05, 1.90934572e-05, 1.65904944e-05, 1.92179420e-05, - 2.44328666e-05, 2.89928069e-05, 3.06518691e-05, 3.03439117e-05, - 2.16509014e-05, 1.74924192e-05, 1.82912443e-05, 2.22263314e-05, - 2.66917922e-05, 2.95924152e-05, 3.05010823e-05, 3.00599510e-05, - 2.04496235e-05, 1.66041154e-05, 1.80463181e-05, 2.27990276e-05, - 2.81195250e-05, 3.04645662e-05, 3.04141643e-05, 2.97194265e-05, - 1.90616351e-05, 1.50825879e-05, 1.89772631e-05, 2.37467709e-05, - 2.66723767e-05, 2.87410975e-05, 2.96610062e-05, 2.24293202e-05, - 1.96103111e-05, 1.93740594e-05, 2.12095888e-05, 2.57229973e-05, - 2.91233425e-05, 2.98363440e-05, 2.95645035e-05, 2.31003218e-05, - 2.04831277e-05, 2.06987064e-05, 2.25843030e-05, 2.46289258e-05, - 2.65272892e-05, 2.87048556e-05, 2.94684818e-05, 2.37467128e-05, - 2.07004857e-05, 2.08522092e-05, 2.17241436e-05, 2.29713270e-05, - 2.58898363e-05, 2.85847508e-05, 2.96916156e-05, 2.96007260e-05, - 2.39466806e-05, 1.90672689e-05, 1.56071127e-05, 1.73268373e-05, - 2.32217703e-05, 2.90557543e-05, 3.01749556e-05, 2.90843391e-05, - 2.15068072e-05, 1.85551445e-05, 2.06833198e-05, 2.42930530e-05, - 2.56460913e-05, 2.71196505e-05, 2.89352748e-05, 2.93750079e-05, - 2.41665988e-05, 2.07129501e-05, 1.87989217e-05, 2.14899670e-05, - 2.47533160e-05, 2.79031788e-05, 2.95292971e-05, 2.93594485e-05, - 2.40900408e-05, 2.06416431e-05, 2.01400306e-05, 2.21805901e-05, - 2.47777288e-05, 2.71747420e-05, 2.92915929e-05, 2.91747673e-05, - 2.86901041e-05, 2.36906657e-05, 1.89156710e-05, 1.72150632e-05, - 2.10790462e-05, 2.58339259e-05, 2.84558181e-05, 3.02540505e-05, - 3.05398709e-05, 2.98659748e-05, 2.18621727e-05, 1.90769640e-05, - 1.94859990e-05, 2.32344440e-05, 2.75920780e-05, 2.85509060e-05, - 2.95435677e-05, 3.04238878e-05, 2.32668042e-05, 2.02298601e-05, - 1.99510919e-05, 2.12564939e-05, 2.35936982e-05, 2.70549846e-05, - 2.87902366e-05, 2.88447547e-05, 2.04168232e-05, 1.66934068e-05, - 1.92332254e-05, 2.52204363e-05, 2.93085350e-05, 2.94538225e-05, - 2.91619688e-05, 2.38025371e-05, 2.05058255e-05, 1.89700543e-05, - 2.04065791e-05, 2.44129579e-05, 2.72430649e-05, 2.86350131e-05, - 2.97597682e-05, - 2.48903475e-05, 2.25043033e-05, 2.18679641e-05, 2.28512562e-05, - 2.44047943e-05, 2.59576864e-05, 2.65972241e-05, 2.67612690e-05, - 2.69267507e-05, 2.52441756e-05, 2.38986917e-05, 2.43697467e-05, - 2.49813572e-05, 2.50686095e-05, 2.53183227e-05, 2.59415663e-05, - 2.64308716e-05, 2.66240914e-05, 2.67152641e-05, 2.69305698e-05, - 2.42154144e-05, 2.26946612e-05, 2.31045720e-05, 2.44746178e-05, - 2.51072413e-05, 2.56079328e-05, 2.65675067e-05, 2.69828233e-05, - 2.70678618e-05, 2.29084748e-05, 1.95724564e-05, 2.10462776e-05, - 2.45629197e-05, 2.58516864e-05, 2.65647257e-05, 2.69954825e-05, - 2.70636438e-05, 2.70518127e-05, 2.46030981e-05, 2.20447334e-05, - 2.15023871e-05, 2.39158686e-05, 2.55477016e-05, 2.60601826e-05, - 2.63053673e-05, 2.68126450e-05, 2.71469934e-05, 2.60815079e-05, - 2.47052799e-05, 2.16836106e-05, 1.98326349e-05, 2.17901612e-05, - 2.49099473e-05, 2.67027874e-05, 2.71973821e-05, 2.72039178e-05, - 2.34165782e-05, 2.05076018e-05, 2.10867836e-05, 2.36238660e-05, - 2.57600427e-05, 2.66800007e-05, 2.69793725e-05, 2.70699683e-05, - 2.26749520e-05, 1.98187232e-05, 2.08938089e-05, 2.39573598e-05, - 2.62481416e-05, 2.69295140e-05, 2.71734075e-05, 2.70444033e-05, - 2.16558920e-05, 1.85705380e-05, 2.15385528e-05, 2.43429796e-05, - 2.58616898e-05, 2.69337643e-05, 2.72107421e-05, 2.37900165e-05, - 2.19677911e-05, 2.18336420e-05, 2.31169639e-05, 2.56525849e-05, - 2.68616121e-05, 2.70510562e-05, 2.70069082e-05, 2.41669883e-05, - 2.25608213e-05, 2.27089848e-05, 2.38642542e-05, 2.50594086e-05, - 2.60762500e-05, 2.68448298e-05, 2.69836351e-05, 2.45171902e-05, - 2.27418320e-05, 2.28454787e-05, 2.33452133e-05, 2.41135012e-05, - 2.56971785e-05, 2.67874045e-05, 2.70496115e-05, 2.70157127e-05, - 2.43085358e-05, 2.14954967e-05, 1.90065825e-05, 2.04164088e-05, - 2.44513590e-05, 2.70474743e-05, 2.72037345e-05, 2.71073897e-05, - 2.32448605e-05, 2.12332124e-05, 2.26695616e-05, 2.47193541e-05, - 2.54564292e-05, 2.62219560e-05, 2.68355320e-05, 2.69325320e-05, - 2.44374825e-05, 2.26600166e-05, 2.14757164e-05, 2.32768702e-05, - 2.50963465e-05, 2.65210848e-05, 2.70532767e-05, 2.69382255e-05, - 2.47196453e-05, 2.26936347e-05, 2.23669086e-05, 2.35943543e-05, - 2.49733668e-05, 2.61226514e-05, 2.68754452e-05, 2.69654266e-05, - 2.69333939e-05, 2.44048057e-05, 2.15234517e-05, 2.03167788e-05, - 2.30408459e-05, 2.55040572e-05, 2.64647020e-05, 2.70561030e-05, - 2.71711668e-05, 2.70772138e-05, 2.33313338e-05, 2.15139962e-05, - 2.18725250e-05, 2.42355017e-05, 2.63619277e-05, 2.70624066e-05, - 2.73719721e-05, 2.73235781e-05, 2.43313834e-05, 2.23773720e-05, - 2.21715949e-05, 2.30713938e-05, 2.45028037e-05, 2.60637117e-05, - 2.66857018e-05, 2.68883559e-05, 2.24438881e-05, 1.98208667e-05, - 2.17664743e-05, 2.53983660e-05, 2.69147180e-05, 2.69680731e-05, - 2.69675697e-05, 2.44459128e-05, 2.25282115e-05, 2.15533669e-05, - 2.25778355e-05, 2.50185363e-05, 2.63845276e-05, 2.68264804e-05, - 2.70097206e-05, - 2.21179591e-05, 1.48802163e-05, 1.35196272e-05, 1.61133593e-05, - 2.15476426e-05, 2.91469403e-05, 3.40289177e-05, 3.46742349e-05, - 3.47653365e-05, 2.33949859e-05, 1.84039447e-05, 1.98510760e-05, - 2.26017390e-05, 2.30767978e-05, 2.41639720e-05, 2.87963943e-05, - 3.34437057e-05, 3.33793291e-05, 3.29225635e-05, 3.51646539e-05, - 1.99018013e-05, 1.54659214e-05, 1.62289869e-05, 2.08827090e-05, - 2.39396853e-05, 2.54304639e-05, 3.13574115e-05, 3.71580156e-05, - 3.91081603e-05, 1.59441035e-05, 9.73173367e-06, 1.20058726e-05, - 2.22387784e-05, 3.17847357e-05, 3.46182102e-05, 3.57989304e-05, - 3.69853174e-05, 3.71602033e-05, 2.28953052e-05, 1.45540346e-05, - 1.29981727e-05, 1.92818310e-05, 2.65246519e-05, 2.75302526e-05, - 2.75888584e-05, 3.16950797e-05, 3.66771754e-05, 3.18377909e-05, - 2.30634837e-05, 1.32712942e-05, 9.97610233e-06, 1.33560786e-05, - 2.25362613e-05, 3.48120126e-05, 4.03096145e-05, 3.87666173e-05, - 1.69806909e-05, 1.11973779e-05, 1.22882042e-05, 1.85668938e-05, - 2.86798063e-05, 3.77887545e-05, 4.07056994e-05, 3.80747805e-05, - 1.49409527e-05, 1.01400701e-05, 1.20303176e-05, 1.96010810e-05, - 3.29199883e-05, 4.07858352e-05, 3.92667882e-05, 3.65666263e-05, - 1.32513996e-05, 8.50973222e-06, 1.33880945e-05, 2.20014321e-05, - 2.81358675e-05, 3.25156729e-05, 3.54566151e-05, 1.87342549e-05, - 1.43253852e-05, 1.38676285e-05, 1.63596534e-05, 2.48828092e-05, - 3.46486400e-05, 3.70929358e-05, 3.60158619e-05, 2.00012147e-05, - 1.55907418e-05, 1.58929561e-05, 1.90809024e-05, 2.27344308e-05, - 2.65179141e-05, 3.27780611e-05, 3.56757944e-05, 2.12745547e-05, - 1.57623955e-05, 1.59765682e-05, 1.76007771e-05, 1.96778736e-05, - 2.54163206e-05, 3.24992972e-05, 3.64077590e-05, 3.61442450e-05, - 2.29853837e-05, 1.39399354e-05, 9.07112282e-06, 1.08009875e-05, - 1.92837831e-05, 3.34226480e-05, 3.79483881e-05, 3.32623770e-05, - 1.70965863e-05, 1.28345762e-05, 1.59903956e-05, 2.27497592e-05, - 2.54161540e-05, 2.84927044e-05, 3.38947792e-05, 3.54863937e-05, - 2.33862694e-05, 1.61533013e-05, 1.28623850e-05, 1.68877185e-05, - 2.31118298e-05, 3.06401538e-05, 3.56178414e-05, 3.53845897e-05, - 2.18807516e-05, 1.57130555e-05, 1.49314399e-05, 1.84960260e-05, - 2.37469907e-05, 2.91960098e-05, 3.53739411e-05, 3.43807875e-05, - 3.22817831e-05, 2.15085150e-05, 1.31811127e-05, 1.07443291e-05, - 1.61197712e-05, 2.60278570e-05, 3.34500422e-05, 3.90899241e-05, - 3.98948184e-05, 3.71031195e-05, 1.82344181e-05, 1.39081563e-05, - 1.41878815e-05, 2.02829326e-05, 2.99726819e-05, 3.10156596e-05, - 3.40999741e-05, 3.85389365e-05, 2.00132848e-05, 1.52726451e-05, - 1.49355352e-05, 1.67567022e-05, 2.06809595e-05, 2.89282584e-05, - 3.39448227e-05, 3.32163242e-05, 1.57865990e-05, 1.05732593e-05, - 1.35347608e-05, 2.38151121e-05, 3.52600986e-05, 3.56835756e-05, - 3.43102605e-05, 2.18109495e-05, 1.58195487e-05, 1.32930963e-05, - 1.51871368e-05, 2.19760819e-05, 2.82941627e-05, 3.25434346e-05, - 3.69339312e-05, - 1.80163284e-05, 8.91538921e-06, 7.55233123e-06, 1.04453218e-05, - 1.77681260e-05, 3.05436161e-05, 4.05712837e-05, 4.16941741e-05, - 4.13879663e-05, 1.98404451e-05, 1.28751053e-05, 1.47023885e-05, - 1.87808911e-05, 1.95442079e-05, 2.12247052e-05, 2.97815342e-05, - 3.96075398e-05, 3.88451683e-05, 3.74342649e-05, 4.23987981e-05, - 1.50289257e-05, 9.60528081e-06, 1.03252715e-05, 1.64040018e-05, - 2.11850255e-05, 2.32229590e-05, 3.40814215e-05, 4.74733433e-05, - 5.25197744e-05, 1.01077394e-05, 4.34418922e-06, 6.17514080e-06, - 1.88249766e-05, 3.71820023e-05, 4.21934430e-05, 4.38243697e-05, - 4.67184603e-05, 4.72296177e-05, 2.00460541e-05, 8.91447762e-06, - 7.15395834e-06, 1.43748888e-05, 2.56695674e-05, 2.66789042e-05, - 2.62363653e-05, 3.41927156e-05, 4.56040447e-05, 3.66374577e-05, - 2.01918400e-05, 7.37318575e-06, 4.46355439e-06, 7.39176830e-06, - 1.87826952e-05, 4.22413131e-05, 5.54033670e-05, 5.10392890e-05, - 1.11481867e-05, 5.53355995e-06, 6.53140088e-06, 1.35412792e-05, - 2.99701221e-05, 5.03252569e-05, 5.74576454e-05, 4.96446910e-05, - 8.81945256e-06, 4.68416487e-06, 6.34277273e-06, 1.48821829e-05, - 3.88470758e-05, 5.79039510e-05, 5.25490638e-05, 4.56726295e-05, - 7.37133028e-06, 3.51611438e-06, 7.68432997e-06, 1.87511421e-05, - 2.84857291e-05, 3.57987172e-05, 4.22179860e-05, 1.35964966e-05, - 8.64749947e-06, 8.09857003e-06, 1.05187858e-05, 2.20091378e-05, - 4.13019620e-05, 4.70518044e-05, 4.43521726e-05, 1.52823507e-05, - 9.95490854e-06, 1.02620291e-05, 1.40958313e-05, 1.88961287e-05, - 2.44836877e-05, 3.66940989e-05, 4.35439579e-05, 1.70624110e-05, - 1.00162395e-05, 1.02338807e-05, 1.22677132e-05, 1.47836094e-05, - 2.30071673e-05, 3.61876804e-05, 4.52344108e-05, 4.46585571e-05, - 2.07781791e-05, 8.55028647e-06, 3.91409803e-06, 5.08094111e-06, - 1.35883780e-05, 3.76562591e-05, 4.88003428e-05, 3.70851283e-05, - 1.15573156e-05, 7.17231021e-06, 1.04645717e-05, 1.95437270e-05, - 2.35111036e-05, 2.84058260e-05, 3.94785045e-05, 4.32242881e-05, - 2.13535445e-05, 1.07388878e-05, 6.98504741e-06, 1.11737838e-05, - 1.95614482e-05, 3.25224740e-05, 4.31584933e-05, 4.29412295e-05, - 1.78621790e-05, 9.99442858e-06, 9.14483517e-06, 1.34596444e-05, - 2.10554881e-05, 3.02358590e-05, 4.31240801e-05, 4.02887867e-05, - 3.52404052e-05, 1.76935209e-05, 7.39748667e-06, 5.08614302e-06, - 1.02284404e-05, 2.46997176e-05, 3.95179364e-05, 5.25148155e-05, - 5.43284153e-05, 4.69849316e-05, 1.33721320e-05, 8.48328393e-06, - 8.53869502e-06, 1.56866095e-05, 3.13993887e-05, 3.19265793e-05, - 3.83148911e-05, 4.99572344e-05, 1.50503029e-05, 9.66317996e-06, - 9.36570847e-06, 1.12179440e-05, 1.59879840e-05, 2.97751103e-05, - 4.00764163e-05, 3.76335990e-05, 1.04029239e-05, 5.24642185e-06, - 7.67507872e-06, 2.03747008e-05, 4.26977382e-05, 4.36169404e-05, - 4.01045016e-05, 1.82020664e-05, 1.03570677e-05, 7.53120770e-06, - 9.30489656e-06, 1.75259434e-05, 2.75757040e-05, 3.61797025e-05, - 4.67741436e-05, - 1.95995466e-05, 1.08496231e-05, 9.42634365e-06, 1.25497671e-05, - 1.97364280e-05, 3.06667980e-05, 3.85199987e-05, 3.92204016e-05, - 3.87460845e-05, 2.11736814e-05, 1.47395660e-05, 1.64549952e-05, - 2.03167204e-05, 2.10254392e-05, 2.24988417e-05, 2.99959475e-05, - 3.79403087e-05, 3.70532514e-05, 3.57547448e-05, 3.95609642e-05, - 1.69301281e-05, 1.16075003e-05, 1.22477063e-05, 1.82274047e-05, - 2.26500511e-05, 2.41931282e-05, 3.30807587e-05, 4.35220503e-05, - 4.72790523e-05, 1.21014552e-05, 5.90129902e-06, 7.95409322e-06, - 2.07143721e-05, 3.66256824e-05, 3.98948654e-05, 4.06170980e-05, - 4.28118126e-05, 4.32296313e-05, 2.19404688e-05, 1.11072745e-05, - 9.08025541e-06, 1.64247404e-05, 2.65982768e-05, 2.70213391e-05, - 2.63542804e-05, 3.28795123e-05, 4.18140408e-05, 3.58740351e-05, - 2.20012376e-05, 9.28297977e-06, 5.97994155e-06, 9.25273423e-06, - 2.03790470e-05, 3.97457550e-05, 4.92373602e-05, 4.59410323e-05, - 1.30433205e-05, 7.28602750e-06, 8.43239160e-06, 1.56917081e-05, - 3.03663234e-05, 4.61956273e-05, 5.11200982e-05, 4.50777826e-05, - 1.06299121e-05, 6.32224314e-06, 8.26145540e-06, 1.69592436e-05, - 3.75403126e-05, 5.15329891e-05, 4.71349681e-05, 4.20165445e-05, - 9.29476739e-06, 4.96280623e-06, 9.77350584e-06, 2.08200999e-05, - 2.89001729e-05, 3.40989869e-05, 3.90276341e-05, 1.56380167e-05, - 1.08067730e-05, 1.01657111e-05, 1.24754713e-05, 2.29664099e-05, - 3.87643971e-05, 4.30915687e-05, 4.10224399e-05, 1.72450161e-05, - 1.21212125e-05, 1.24116502e-05, 1.61490981e-05, 2.03690933e-05, - 2.49437378e-05, 3.49671848e-05, 4.04091797e-05, 1.88978126e-05, - 1.20892336e-05, 1.22945293e-05, 1.44118676e-05, 1.67349662e-05, - 2.38982676e-05, 3.46119032e-05, 4.16624457e-05, 4.12538939e-05, - 2.29441741e-05, 1.09363219e-05, 5.44564122e-06, 6.66315916e-06, - 1.51553573e-05, 3.55135622e-05, 4.42237406e-05, 3.49598770e-05, - 1.36407702e-05, 9.24017931e-06, 1.26838669e-05, 2.13253384e-05, - 2.46178350e-05, 2.84392206e-05, 3.73022289e-05, 4.02239428e-05, - 2.34167032e-05, 1.30245822e-05, 8.86452026e-06, 1.31635185e-05, - 2.10189897e-05, 3.17797919e-05, 4.00025237e-05, 3.99881738e-05, - 1.95790754e-05, 1.20911287e-05, 1.12190881e-05, 1.56192107e-05, - 2.26401066e-05, 3.02059645e-05, 4.02227230e-05, 3.77961964e-05, - 3.36259462e-05, 1.96575399e-05, 9.39776572e-06, 6.71426670e-06, - 1.21686784e-05, 2.57173763e-05, 3.78214958e-05, 4.72937804e-05, - 4.84775191e-05, 4.30007361e-05, 1.57006265e-05, 1.08391004e-05, - 1.07181704e-05, 1.76355285e-05, 3.09748157e-05, 3.06205846e-05, - 3.56340610e-05, 4.49301464e-05, 1.68667620e-05, 1.18655237e-05, - 1.16097699e-05, 1.33471060e-05, 1.77572306e-05, 2.98556726e-05, - 3.79941816e-05, 3.57000557e-05, 1.27440919e-05, 7.16340441e-06, - 9.64265699e-06, 2.15761703e-05, 3.98243877e-05, 4.04895110e-05, - 3.76422454e-05, 2.01601348e-05, 1.26371717e-05, 9.56158628e-06, - 1.12997358e-05, 1.89806369e-05, 2.75053388e-05, 3.45560725e-05, - 4.29344770e-05, - 2.24849511e-05, 1.56895840e-05, 1.43647042e-05, 1.75102991e-05, - 2.32894543e-05, 2.96072239e-05, 3.33055513e-05, 3.33879151e-05, - 3.28210313e-05, 2.34083096e-05, 1.88378249e-05, 2.00917153e-05, - 2.30163583e-05, 2.35285238e-05, 2.44424829e-05, 2.91767866e-05, - 3.32855569e-05, 3.24261123e-05, 3.15071430e-05, 3.32567959e-05, - 2.07850711e-05, 1.64851891e-05, 1.68354611e-05, 2.17441219e-05, - 2.48809667e-05, 2.54042655e-05, 3.01429636e-05, 3.52065708e-05, - 3.68337828e-05, 1.68772676e-05, 1.06936720e-05, 1.29255852e-05, - 2.39706353e-05, 3.35758510e-05, 3.41228471e-05, 3.36970681e-05, - 3.46945358e-05, 3.49265051e-05, 2.50084636e-05, 1.65538257e-05, - 1.42302840e-05, 2.06489100e-05, 2.73664155e-05, 2.68724450e-05, - 2.59950051e-05, 2.95946611e-05, 3.40286817e-05, 3.27117270e-05, - 2.49124684e-05, 1.43458097e-05, 1.06109242e-05, 1.41890033e-05, - 2.31736556e-05, 3.37829973e-05, 3.74501848e-05, 3.59373008e-05, - 1.74506770e-05, 1.23361143e-05, 1.36533815e-05, 2.02374281e-05, - 2.97325782e-05, 3.71092563e-05, 3.87253855e-05, 3.57947381e-05, - 1.52025726e-05, 1.12649360e-05, 1.35758652e-05, 2.11544688e-05, - 3.33912647e-05, 3.90077278e-05, 3.65532515e-05, 3.43290409e-05, - 1.43925300e-05, 9.67558369e-06, 1.52261393e-05, 2.43811508e-05, - 2.85444806e-05, 3.01335161e-05, 3.24471526e-05, 1.99666924e-05, - 1.62275869e-05, 1.54744760e-05, 1.71062955e-05, 2.43405173e-05, - 3.29517302e-05, 3.48590965e-05, 3.38877340e-05, 2.11719578e-05, - 1.73053188e-05, 1.75031472e-05, 2.04228203e-05, 2.29537914e-05, - 2.52826325e-05, 3.08107991e-05, 3.36098162e-05, 2.23369513e-05, - 1.70543858e-05, 1.71954929e-05, 1.91518504e-05, 2.07165655e-05, - 2.50331765e-05, 3.06995712e-05, 3.41376550e-05, 3.39913961e-05, - 2.63171532e-05, 1.69380729e-05, 1.02975385e-05, 1.13333014e-05, - 1.86069270e-05, 3.07733026e-05, 3.51178942e-05, 3.03421322e-05, - 1.83723891e-05, 1.47554229e-05, 1.78925549e-05, 2.42960941e-05, - 2.59731600e-05, 2.76341596e-05, 3.21838022e-05, 3.36079942e-05, - 2.65283511e-05, 1.83285677e-05, 1.39289091e-05, 1.77620379e-05, - 2.34831804e-05, 2.93944083e-05, 3.32631033e-05, 3.34716461e-05, - 2.27030160e-05, 1.71126215e-05, 1.63418709e-05, 2.01957614e-05, - 2.50699561e-05, 2.90200093e-05, 3.37148916e-05, 3.22244498e-05, - 2.98466614e-05, 2.32151777e-05, 1.46860328e-05, 1.15170854e-05, - 1.68095470e-05, 2.67619497e-05, 3.31559624e-05, 3.68644527e-05, - 3.71667106e-05, 3.47628521e-05, 2.06220271e-05, 1.67811652e-05, - 1.62107913e-05, 2.14769551e-05, 2.91363362e-05, 2.77322238e-05, - 3.02646169e-05, 3.52206879e-05, 2.05677943e-05, 1.71861723e-05, - 1.70858001e-05, 1.82298053e-05, 2.12417350e-05, 2.88784177e-05, - 3.28482093e-05, 3.11659929e-05, 1.82358409e-05, 1.27866378e-05, - 1.47902317e-05, 2.35375126e-05, 3.34281078e-05, 3.36816502e-05, - 3.21344725e-05, 2.36274144e-05, 1.80009846e-05, 1.48978933e-05, - 1.62118533e-05, 2.17288546e-05, 2.67087991e-05, 3.05972424e-05, - 3.48607463e-05, - 2.37229316e-05, 1.87377102e-05, 1.76470471e-05, 2.02674709e-05, - 2.44687760e-05, 2.82276272e-05, 3.01345669e-05, 3.00999952e-05, - 2.97011361e-05, 2.42954105e-05, 2.11307959e-05, 2.20234677e-05, - 2.40903007e-05, 2.44388983e-05, 2.50164289e-05, 2.79640849e-05, - 3.02036616e-05, 2.96231663e-05, 2.90484772e-05, 2.99426881e-05, - 2.26147298e-05, 1.94079876e-05, 1.96227088e-05, 2.32851374e-05, - 2.53971678e-05, 2.55935326e-05, 2.83011616e-05, 3.09691962e-05, - 3.17550148e-05, 1.97045267e-05, 1.43827649e-05, 1.64178118e-05, - 2.49196198e-05, 3.06400291e-05, 3.06042533e-05, 3.01525946e-05, - 3.06550142e-05, 3.07842825e-05, 2.56520821e-05, 1.96128822e-05, - 1.75929217e-05, 2.25896755e-05, 2.69446187e-05, 2.64264335e-05, - 2.57472973e-05, 2.78601163e-05, 3.02540859e-05, 3.00393420e-05, - 2.55509725e-05, 1.76662388e-05, 1.42527289e-05, 1.74966114e-05, - 2.42285156e-05, 3.03480800e-05, 3.19815270e-05, 3.12242088e-05, - 2.00822890e-05, 1.59274129e-05, 1.71210992e-05, 2.23405515e-05, - 2.83859257e-05, 3.21162096e-05, 3.27274815e-05, 3.12270575e-05, - 1.82574184e-05, 1.49458257e-05, 1.70825546e-05, 2.29755543e-05, - 3.03503481e-05, 3.28917503e-05, 3.15530441e-05, 3.04699573e-05, - 1.77158764e-05, 1.34297801e-05, 1.85175094e-05, 2.52854928e-05, - 2.75936052e-05, 2.81338115e-05, 2.93499637e-05, 2.20793054e-05, - 1.93384108e-05, 1.86847400e-05, 1.98558523e-05, 2.48323855e-05, - 2.98066374e-05, 3.07490524e-05, 3.02508353e-05, 2.29308516e-05, - 2.01574238e-05, 2.02944640e-05, 2.24243595e-05, 2.40198225e-05, - 2.53445897e-05, 2.85788141e-05, 3.01108083e-05, 2.37234415e-05, - 1.98975372e-05, 1.99964822e-05, 2.15306917e-05, 2.25890020e-05, - 2.53046164e-05, 2.85387132e-05, 3.03641290e-05, 3.03026346e-05, - 2.66648114e-05, 2.00725962e-05, 1.40458307e-05, 1.49169659e-05, - 2.07966958e-05, 2.84635675e-05, 3.08016625e-05, 2.81801273e-05, - 2.09069391e-05, 1.81413197e-05, 2.06381075e-05, 2.51058095e-05, - 2.60383604e-05, 2.68653145e-05, 2.93838042e-05, 3.01358364e-05, - 2.67677154e-05, 2.10111141e-05, 1.73110795e-05, 2.03823338e-05, - 2.43970329e-05, 2.78617595e-05, 2.98842864e-05, 3.00578053e-05, - 2.39377301e-05, 1.99593652e-05, 1.93535963e-05, 2.23149576e-05, - 2.55747893e-05, 2.77923079e-05, 3.02236022e-05, 2.93445483e-05, - 2.79606217e-05, 2.44137934e-05, 1.80183148e-05, 1.51244475e-05, - 1.96147656e-05, 2.65569655e-05, 3.01143110e-05, 3.17771922e-05, - 3.18587600e-05, 3.06839780e-05, 2.27247881e-05, 1.99297009e-05, - 1.93438259e-05, 2.31481594e-05, 2.77675681e-05, 2.65902421e-05, - 2.80115120e-05, 3.07881718e-05, 2.24115509e-05, 2.00955367e-05, - 2.00541084e-05, 2.08289986e-05, 2.28900732e-05, 2.77265305e-05, - 2.98340795e-05, 2.87685007e-05, 2.09835649e-05, 1.65003795e-05, - 1.80665363e-05, 2.43399241e-05, 3.00456112e-05, 3.01581811e-05, - 2.92921539e-05, 2.47051788e-05, 2.07638450e-05, 1.82101484e-05, - 1.91910546e-05, 2.31134946e-05, 2.61950345e-05, 2.84600506e-05, - 3.07721686e-05, - 2.57144624e-05, 3.04528090e-05, 3.14723020e-05, 2.87281235e-05, - 2.47696252e-05, 2.14223010e-05, 1.96445319e-05, 1.96517392e-05, - 1.99941452e-05, 2.52033670e-05, 2.82573414e-05, 2.74197178e-05, - 2.53490301e-05, 2.50059026e-05, 2.44686158e-05, 2.16680456e-05, - 1.96020677e-05, 2.01102181e-05, 2.06356388e-05, 1.97676912e-05, - 2.66851390e-05, 2.97060136e-05, 2.96882055e-05, 2.60472357e-05, - 2.40313559e-05, 2.39379385e-05, 2.13538057e-05, 1.88051465e-05, - 1.80556604e-05, 2.94642959e-05, 3.42780804e-05, 3.25572326e-05, - 2.43615415e-05, 1.92564800e-05, 1.92235559e-05, 1.95588820e-05, - 1.90748984e-05, 1.89579133e-05, 2.36427707e-05, 2.90044153e-05, - 3.12548709e-05, 2.65846161e-05, 2.25956576e-05, 2.31632489e-05, - 2.38711738e-05, 2.17647023e-05, 1.94285478e-05, 1.97751738e-05, - 2.37719653e-05, 3.12995895e-05, 3.47880202e-05, 3.16225437e-05, - 2.51819000e-05, 1.94339274e-05, 1.77976230e-05, 1.85026958e-05, - 2.92885101e-05, 3.27917052e-05, 3.15673157e-05, 2.67269145e-05, - 2.12641109e-05, 1.78471766e-05, 1.71952139e-05, 1.85425955e-05, - 3.12172690e-05, 3.36243098e-05, 3.14508416e-05, 2.61779099e-05, - 1.94881311e-05, 1.70652726e-05, 1.82062189e-05, 1.92519581e-05, - 3.12083086e-05, 3.47130347e-05, 3.00300497e-05, 2.39236474e-05, - 2.20120884e-05, 2.14879142e-05, 2.02720299e-05, 2.71003601e-05, - 2.92945247e-05, 3.00383861e-05, 2.94000006e-05, 2.47296975e-05, - 1.99067481e-05, 1.89908091e-05, 1.94647975e-05, 2.63149981e-05, - 2.86804037e-05, 2.86070332e-05, 2.67456985e-05, 2.54464874e-05, - 2.42633547e-05, 2.10676992e-05, 1.96003612e-05, 2.55901553e-05, - 2.91173081e-05, 2.90590012e-05, 2.75067198e-05, 2.66712336e-05, - 2.42483171e-05, 2.11117549e-05, 1.93493429e-05, 1.94145533e-05, - 2.25850830e-05, 2.80399919e-05, 3.41868502e-05, 3.42984602e-05, - 2.89142299e-05, 2.11543124e-05, 1.88985649e-05, 2.14223421e-05, - 2.81850692e-05, 3.02822688e-05, 2.81674902e-05, 2.42210247e-05, - 2.34649278e-05, 2.27410899e-05, 2.03060184e-05, 1.95874942e-05, - 2.25260494e-05, 2.77201489e-05, 3.16295178e-05, 2.88380007e-05, - 2.50573476e-05, 2.17764044e-05, 1.97979375e-05, 1.96589527e-05, - 2.54304839e-05, 2.90097565e-05, 2.95567252e-05, 2.67412593e-05, - 2.38202666e-05, 2.18393432e-05, 1.95173398e-05, 2.03232280e-05, - 2.16567831e-05, 2.48262961e-05, 3.06862122e-05, 3.38599659e-05, - 2.96597308e-05, 2.29637597e-05, 1.96791110e-05, 1.80392266e-05, - 1.79222960e-05, 1.90443927e-05, 2.61593580e-05, 2.82262887e-05, - 2.92181227e-05, 2.61048909e-05, 2.18683654e-05, 2.30165006e-05, - 2.15479241e-05, 1.88732904e-05, 2.69608844e-05, 2.86361401e-05, - 2.85478968e-05, 2.81799107e-05, 2.64917702e-05, 2.18992636e-05, - 1.99079804e-05, 2.08814370e-05, 2.76176947e-05, 3.12535152e-05, - 3.08135603e-05, 2.51940517e-05, 1.96748525e-05, 1.95594581e-05, - 2.03724620e-05, 2.45414108e-05, 2.79293613e-05, 3.04509581e-05, - 2.99084065e-05, 2.64207585e-05, 2.34197215e-05, 2.11833724e-05, - 1.89800956e-05, - 2.50048181e-05, 3.63259836e-05, 3.93327805e-05, 3.25132355e-05, - 2.38834754e-05, 1.76142969e-05, 1.48251921e-05, 1.47479202e-05, - 1.51064845e-05, 2.38605225e-05, 3.04063391e-05, 2.84072788e-05, - 2.43244129e-05, 2.36927608e-05, 2.26286025e-05, 1.79734668e-05, - 1.48580560e-05, 1.54237396e-05, 1.60744367e-05, 1.48094073e-05, - 2.72871152e-05, 3.45957469e-05, 3.40284721e-05, 2.59448739e-05, - 2.21113686e-05, 2.15731915e-05, 1.71408981e-05, 1.35552764e-05, - 1.25902994e-05, 3.38492784e-05, 4.97309321e-05, 4.29859289e-05, - 2.30839400e-05, 1.47121785e-05, 1.42957135e-05, 1.45058048e-05, - 1.38548688e-05, 1.37133677e-05, 2.19036059e-05, 3.40815400e-05, - 3.94438076e-05, 2.74146217e-05, 1.95885972e-05, 2.00677695e-05, - 2.09458318e-05, 1.75600213e-05, 1.42615028e-05, 1.52765709e-05, - 2.20255184e-05, 3.92564074e-05, 5.04010599e-05, 3.97665477e-05, - 2.41147573e-05, 1.44960967e-05, 1.22209825e-05, 1.30744174e-05, - 3.28771018e-05, 4.44588430e-05, 4.07712174e-05, 2.79649475e-05, - 1.75151496e-05, 1.25119539e-05, 1.15985186e-05, 1.31866130e-05, - 3.76152853e-05, 4.76801971e-05, 4.08373544e-05, 2.66680002e-05, - 1.48058535e-05, 1.14664383e-05, 1.27255252e-05, 1.40886115e-05, - 3.91085196e-05, 5.30135057e-05, 3.68472667e-05, 2.25636532e-05, - 1.85192968e-05, 1.71041098e-05, 1.53169822e-05, 2.84514456e-05, - 3.47587045e-05, 3.64383102e-05, 3.34610077e-05, 2.27676368e-05, - 1.50270973e-05, 1.37551119e-05, 1.43791638e-05, 2.66974183e-05, - 3.27843297e-05, 3.24589998e-05, 2.77489557e-05, 2.44146345e-05, - 2.17117629e-05, 1.65834415e-05, 1.45653191e-05, 2.51386450e-05, - 3.33944953e-05, 3.31513846e-05, 2.96631489e-05, 2.73654043e-05, - 2.19824959e-05, 1.66771071e-05, 1.42098970e-05, 1.43103542e-05, - 2.04788240e-05, 3.29073837e-05, 5.07250549e-05, 4.80643275e-05, - 3.09725866e-05, 1.65823281e-05, 1.35650956e-05, 1.69107198e-05, - 3.10219043e-05, 3.78221201e-05, 3.16733173e-05, 2.27274337e-05, - 2.09638805e-05, 1.93340744e-05, 1.55667888e-05, 1.45752322e-05, - 2.02903116e-05, 3.08432978e-05, 4.02762274e-05, 3.22005366e-05, - 2.37519333e-05, 1.77581120e-05, 1.47841010e-05, 1.46645441e-05, - 2.46902709e-05, 3.32489646e-05, 3.47388691e-05, 2.80211636e-05, - 2.18871147e-05, 1.81008161e-05, 1.45143500e-05, 1.55179847e-05, - 1.73365573e-05, 2.39764021e-05, 3.82234626e-05, 4.72470017e-05, - 3.40554885e-05, 2.01696472e-05, 1.49411381e-05, 1.25756478e-05, - 1.23824580e-05, 1.38097137e-05, 2.72663180e-05, 3.32505344e-05, - 3.47363575e-05, 2.62713103e-05, 1.79884324e-05, 1.91630215e-05, - 1.69244571e-05, 1.34758864e-05, 2.76477342e-05, 3.29311871e-05, - 3.30233268e-05, 3.12158826e-05, 2.66716493e-05, 1.82244976e-05, - 1.51231576e-05, 1.63061618e-05, 3.09077266e-05, 4.22402357e-05, - 3.81216684e-05, 2.37141556e-05, 1.46973940e-05, 1.45207021e-05, - 1.55818713e-05, 2.34751137e-05, 3.13943782e-05, 3.76913306e-05, - 3.51476445e-05, 2.60595932e-05, 2.02164034e-05, 1.67516394e-05, - 1.37619330e-05, - 2.54444504e-05, 2.51745263e-05, 2.49756149e-05, 2.46723317e-05, - 2.43764495e-05, 2.44218000e-05, 2.42585154e-05, 2.44638482e-05, - 2.48493033e-05, 2.55912448e-05, 2.56358119e-05, 2.57433751e-05, - 2.53562447e-05, 2.52756840e-05, 2.52842668e-05, 2.45325600e-05, - 2.40341939e-05, 2.45353092e-05, 2.49251986e-05, 2.47349946e-05, - 2.51689877e-05, 2.50029058e-05, 2.54672300e-05, 2.51325480e-05, - 2.48010139e-05, 2.53455447e-05, 2.51248933e-05, 2.42992592e-05, - 2.40221114e-05, 2.51221470e-05, 2.38222209e-05, 2.46007436e-05, - 2.43436454e-05, 2.31685684e-05, 2.40000116e-05, 2.47068461e-05, - 2.45402327e-05, 2.44647117e-05, 2.40131343e-05, 2.39088529e-05, - 2.44494179e-05, 2.47687527e-05, 2.45568760e-05, 2.54752878e-05, - 2.61626277e-05, 2.56509653e-05, 2.48297084e-05, 2.37061644e-05, - 2.41976391e-05, 2.46768069e-05, 2.43670081e-05, 2.49645746e-05, - 2.51822593e-05, 2.42781350e-05, 2.40551528e-05, 2.44222253e-05, - 2.56196097e-05, 2.41158704e-05, 2.41431154e-05, 2.45090630e-05, - 2.41044042e-05, 2.34358061e-05, 2.34788387e-05, 2.42734047e-05, - 2.57755089e-05, 2.37691729e-05, 2.38703479e-05, 2.46027089e-05, - 2.37554819e-05, 2.33521415e-05, 2.42319149e-05, 2.46080682e-05, - 2.45985773e-05, 2.29418304e-05, 2.38677889e-05, 2.38641604e-05, - 2.46196739e-05, 2.56543546e-05, 2.53553495e-05, 2.48952883e-05, - 2.39708505e-05, 2.41999720e-05, 2.53293433e-05, 2.58277472e-05, - 2.47219983e-05, 2.44807978e-05, 2.46719826e-05, 2.49164701e-05, - 2.43192876e-05, 2.44483774e-05, 2.47941078e-05, 2.55014375e-05, - 2.60929100e-05, 2.53167870e-05, 2.47137023e-05, 2.49393305e-05, - 2.47500754e-05, 2.48379513e-05, 2.45986094e-05, 2.50429551e-05, - 2.56207807e-05, 2.52685117e-05, 2.46653710e-05, 2.46567921e-05, - 2.31339368e-05, 2.28267567e-05, 2.31580381e-05, 2.47771458e-05, - 2.66528506e-05, 2.56188920e-05, 2.46259983e-05, 2.58396362e-05, - 2.48383560e-05, 2.36581710e-05, 2.41775779e-05, 2.44498887e-05, - 2.49112095e-05, 2.54451936e-05, 2.49000323e-05, 2.46430078e-05, - 2.32471175e-05, 2.39376049e-05, 2.46110512e-05, 2.52182093e-05, - 2.53362048e-05, 2.52939083e-05, 2.49049467e-05, 2.46875407e-05, - 2.50910878e-05, 2.46394358e-05, 2.45522258e-05, 2.44829520e-05, - 2.45327443e-05, 2.48409463e-05, 2.45351583e-05, 2.50716861e-05, - 2.57450140e-05, 2.44062126e-05, 2.41833184e-05, 2.44416684e-05, - 2.53780785e-05, 2.47007174e-05, 2.41152603e-05, 2.39989913e-05, - 2.40848874e-05, 2.45414904e-05, 2.38849057e-05, 2.29388590e-05, - 2.38265788e-05, 2.48847492e-05, 2.51474519e-05, 2.66524721e-05, - 2.62488831e-05, 2.47658831e-05, 2.54519223e-05, 2.40911243e-05, - 2.38175496e-05, 2.46376369e-05, 2.54028863e-05, 2.48017756e-05, - 2.45048522e-05, 2.52718292e-05, 2.36460683e-05, 2.26093238e-05, - 2.45208796e-05, 2.57717421e-05, 2.46665044e-05, 2.46727923e-05, - 2.51004809e-05, 2.43038468e-05, 2.38979759e-05, 2.40972262e-05, - 2.49746333e-05, 2.59792391e-05, 2.60143640e-05, 2.53557156e-05, - 2.44233633e-05, - 2.42715744e-05, 2.00649058e-05, 1.91073596e-05, 2.05908442e-05, - 2.34182895e-05, 2.69939616e-05, 2.89166489e-05, 2.93075557e-05, - 2.95965200e-05, 2.49944342e-05, 2.23718686e-05, 2.32278566e-05, - 2.44708737e-05, 2.46662023e-05, 2.52064758e-05, 2.69084573e-05, - 2.85367456e-05, 2.88357949e-05, 2.88994483e-05, 2.96800969e-05, - 2.29680543e-05, 2.03510038e-05, 2.10241122e-05, 2.34700009e-05, - 2.48319226e-05, 2.58492266e-05, 2.83720889e-05, 3.01615757e-05, - 3.07002230e-05, 2.06953208e-05, 1.59841104e-05, 1.79329668e-05, - 2.37480553e-05, 2.73095638e-05, 2.89793182e-05, 2.99110867e-05, - 3.02591622e-05, 3.02749198e-05, 2.38922655e-05, 1.93018401e-05, - 1.85423193e-05, 2.24329633e-05, 2.59085549e-05, 2.69006241e-05, - 2.73246414e-05, 2.88412136e-05, 3.03353147e-05, 2.76770886e-05, - 2.40751422e-05, 1.88181052e-05, 1.63723487e-05, 1.89951170e-05, - 2.43453187e-05, 2.92395170e-05, 3.11627635e-05, 3.08524169e-05, - 2.15421811e-05, 1.71727351e-05, 1.79400349e-05, 2.19140817e-05, - 2.65989266e-05, 2.98033075e-05, 3.08926902e-05, 3.04904962e-05, - 2.03666238e-05, 1.62709371e-05, 1.76532430e-05, 2.25216037e-05, - 2.81458098e-05, 3.08296641e-05, 3.09056328e-05, 3.01437079e-05, - 1.87720438e-05, 1.47123864e-05, 1.85500606e-05, 2.33722952e-05, - 2.66699764e-05, 2.91904351e-05, 3.02033174e-05, 2.21962590e-05, - 1.91877739e-05, 1.90000669e-05, 2.10394856e-05, 2.58546020e-05, - 2.94667239e-05, 3.02601223e-05, 2.99726633e-05, 2.28938891e-05, - 2.01170495e-05, 2.03567603e-05, 2.23363786e-05, 2.46150412e-05, - 2.67845734e-05, 2.90879971e-05, 2.98673724e-05, 2.35738446e-05, - 2.04165377e-05, 2.05852419e-05, 2.14187219e-05, 2.27842018e-05, - 2.59965551e-05, 2.89415590e-05, 3.01206685e-05, 3.00125481e-05, - 2.34502271e-05, 1.84418777e-05, 1.52323236e-05, 1.71432585e-05, - 2.33594820e-05, 2.95463670e-05, 3.06848094e-05, 2.96192538e-05, - 2.12443461e-05, 1.81016864e-05, 2.02896645e-05, 2.40586435e-05, - 2.55978760e-05, 2.73183863e-05, 2.92797688e-05, 2.97461460e-05, - 2.37037668e-05, 2.02737120e-05, 1.85195256e-05, 2.13008206e-05, - 2.47161825e-05, 2.81701532e-05, 2.99711839e-05, 2.97355790e-05, - 2.39645848e-05, 2.03364688e-05, 1.98211300e-05, 2.18622530e-05, - 2.45908640e-05, 2.72689851e-05, 2.96305143e-05, 2.95870886e-05, - 2.91484207e-05, 2.34141696e-05, 1.85504582e-05, 1.69729608e-05, - 2.09176970e-05, 2.57632980e-05, 2.85920701e-05, 3.06773012e-05, - 3.10328605e-05, 3.03051658e-05, 2.14238591e-05, 1.84721697e-05, - 1.90384716e-05, 2.30274057e-05, 2.77925643e-05, 2.91579280e-05, - 3.02260861e-05, 3.10040719e-05, 2.31701919e-05, 1.98218753e-05, - 1.94941182e-05, 2.09528719e-05, 2.35021760e-05, 2.71282149e-05, - 2.90437789e-05, 2.92408848e-05, 1.99233179e-05, 1.61364711e-05, - 1.89241622e-05, 2.53005659e-05, 2.96726200e-05, 2.98432740e-05, - 2.95772805e-05, 2.35126812e-05, 2.00594968e-05, 1.85867846e-05, - 2.01671272e-05, 2.44777275e-05, 2.75625575e-05, 2.90148187e-05, - 3.01603352e-05, - 2.53145483e-05, 2.49418766e-05, 2.47141478e-05, 2.49006958e-05, - 2.49361974e-05, 2.46956630e-05, 2.43383228e-05, 2.43821139e-05, - 2.45354266e-05, 2.53502228e-05, 2.53265382e-05, 2.54023242e-05, - 2.52791523e-05, 2.52439346e-05, 2.52250094e-05, 2.47583329e-05, - 2.42812125e-05, 2.44957858e-05, 2.46835188e-05, 2.44621138e-05, - 2.52137096e-05, 2.49497660e-05, 2.51509110e-05, 2.52093941e-05, - 2.50526307e-05, 2.52118874e-05, 2.48559794e-05, 2.41426857e-05, - 2.38830397e-05, 2.50260045e-05, 2.35735645e-05, 2.43520537e-05, - 2.49155890e-05, 2.40098886e-05, 2.41893074e-05, 2.44078845e-05, - 2.42567442e-05, 2.42126973e-05, 2.47768336e-05, 2.45283076e-05, - 2.44907942e-05, 2.50673050e-05, 2.48724244e-05, 2.51820790e-05, - 2.54302735e-05, 2.50410060e-05, 2.43986175e-05, 2.42421268e-05, - 2.48445080e-05, 2.45956967e-05, 2.37725629e-05, 2.46865637e-05, - 2.52183996e-05, 2.42948778e-05, 2.38086735e-05, 2.40800761e-05, - 2.52491665e-05, 2.40522458e-05, 2.42861654e-05, 2.49621022e-05, - 2.45901597e-05, 2.37200585e-05, 2.35236666e-05, 2.40664516e-05, - 2.51149132e-05, 2.36882280e-05, 2.41636795e-05, 2.50147739e-05, - 2.41952580e-05, 2.34603607e-05, 2.39622443e-05, 2.43142586e-05, - 2.45711580e-05, 2.29293518e-05, 2.43803445e-05, 2.47361302e-05, - 2.48255662e-05, 2.49949759e-05, 2.46939684e-05, 2.50977398e-05, - 2.45242512e-05, 2.45413480e-05, 2.51199201e-05, 2.54012320e-05, - 2.44908748e-05, 2.42242033e-05, 2.43786890e-05, 2.51287392e-05, - 2.47501072e-05, 2.48140298e-05, 2.50719545e-05, 2.53284110e-05, - 2.54451934e-05, 2.48481671e-05, 2.44190492e-05, 2.51417875e-05, - 2.48984467e-05, 2.49421784e-05, 2.49598124e-05, 2.51677019e-05, - 2.53124321e-05, 2.48459023e-05, 2.43491025e-05, 2.43636114e-05, - 2.44216566e-05, 2.41123656e-05, 2.31954842e-05, 2.41079265e-05, - 2.56671386e-05, 2.49268960e-05, 2.42248348e-05, 2.50214791e-05, - 2.50142139e-05, 2.42389901e-05, 2.47336005e-05, 2.49469687e-05, - 2.50504583e-05, 2.51283046e-05, 2.46124137e-05, 2.44025263e-05, - 2.44569240e-05, 2.46646516e-05, 2.45128169e-05, 2.51216803e-05, - 2.52649107e-05, 2.49620235e-05, 2.45015990e-05, 2.44278204e-05, - 2.51925109e-05, 2.48603200e-05, 2.47644526e-05, 2.49512392e-05, - 2.49563932e-05, 2.48608238e-05, 2.43652016e-05, 2.46506282e-05, - 2.50433337e-05, 2.49475611e-05, 2.44437854e-05, 2.40162979e-05, - 2.51160940e-05, 2.49480455e-05, 2.43152832e-05, 2.38743035e-05, - 2.38524140e-05, 2.42490310e-05, 2.47342722e-05, 2.41469672e-05, - 2.44644724e-05, 2.51203247e-05, 2.49408043e-05, 2.54475725e-05, - 2.51251385e-05, 2.42411276e-05, 2.53099309e-05, 2.46516305e-05, - 2.45347204e-05, 2.49308646e-05, 2.53008151e-05, 2.48588853e-05, - 2.44469326e-05, 2.48037762e-05, 2.45428940e-05, 2.35019569e-05, - 2.45906559e-05, 2.54057323e-05, 2.44274496e-05, 2.44015810e-05, - 2.46667423e-05, 2.49064033e-05, 2.46297956e-05, 2.44350355e-05, - 2.49153819e-05, 2.54965109e-05, 2.53477428e-05, 2.48775001e-05, - 2.42110947e-05, - 2.48142184e-05, 2.25314843e-05, 2.19089100e-05, 2.32841872e-05, - 2.50568650e-05, 2.61450418e-05, 2.64673047e-05, 2.64357995e-05, - 2.63414452e-05, 2.50215200e-05, 2.37497485e-05, 2.41476357e-05, - 2.49461527e-05, 2.50676725e-05, 2.52616834e-05, 2.60829519e-05, - 2.65029417e-05, 2.63736765e-05, 2.62519749e-05, 2.63813215e-05, - 2.43725435e-05, 2.28734364e-05, 2.30137229e-05, 2.46395073e-05, - 2.53815175e-05, 2.54422012e-05, 2.61118382e-05, 2.65201191e-05, - 2.65847426e-05, 2.30333427e-05, 1.97351541e-05, 2.11434593e-05, - 2.52144639e-05, 2.66471931e-05, 2.65480156e-05, 2.64029339e-05, - 2.64617403e-05, 2.64813617e-05, 2.54508028e-05, 2.28962077e-05, - 2.18353816e-05, 2.43443509e-05, 2.58350209e-05, 2.56744401e-05, - 2.54673500e-05, 2.59856103e-05, 2.63881027e-05, 2.65160913e-05, - 2.54221461e-05, 2.18964291e-05, 1.96944419e-05, 2.18209816e-05, - 2.49922609e-05, 2.64854016e-05, 2.65662737e-05, 2.64968976e-05, - 2.32522022e-05, 2.07923872e-05, 2.15315421e-05, 2.42258274e-05, - 2.61936143e-05, 2.67159766e-05, 2.66797134e-05, 2.65307367e-05, - 2.23100831e-05, 2.01159305e-05, 2.14839334e-05, 2.44949883e-05, - 2.65521322e-05, 2.67035622e-05, 2.65376467e-05, 2.64402864e-05, - 2.19186793e-05, 1.89670017e-05, 2.23081644e-05, 2.53248423e-05, - 2.59951904e-05, 2.60329002e-05, 2.62310981e-05, 2.41342389e-05, - 2.27585298e-05, 2.24281982e-05, 2.31227836e-05, 2.52012646e-05, - 2.63702763e-05, 2.64769319e-05, 2.64157416e-05, 2.44909044e-05, - 2.32045214e-05, 2.32817375e-05, 2.42763380e-05, 2.49233137e-05, - 2.53549244e-05, 2.61396280e-05, 2.63986587e-05, 2.48010361e-05, - 2.31056345e-05, 2.31612580e-05, 2.38752050e-05, 2.43566365e-05, - 2.53514759e-05, 2.61384842e-05, 2.64240580e-05, 2.64217770e-05, - 2.57456390e-05, 2.30339654e-05, 1.94333295e-05, 2.01872377e-05, - 2.36386590e-05, 2.60881039e-05, 2.64488057e-05, 2.60198650e-05, - 2.36024496e-05, 2.20795697e-05, 2.34295270e-05, 2.52804888e-05, - 2.55780632e-05, 2.57866126e-05, 2.62993000e-05, 2.64119735e-05, - 2.57798078e-05, 2.35898770e-05, 2.16841219e-05, 2.33752938e-05, - 2.50539651e-05, 2.60155271e-05, 2.63497413e-05, 2.63985808e-05, - 2.48851059e-05, 2.31289045e-05, 2.28126603e-05, 2.42134318e-05, - 2.54353804e-05, 2.60300075e-05, 2.64360256e-05, 2.62720396e-05, - 2.59944194e-05, 2.50380782e-05, 2.20566411e-05, 2.02974650e-05, - 2.30041681e-05, 2.57279096e-05, 2.64829520e-05, 2.65899003e-05, - 2.65647041e-05, 2.64626596e-05, 2.43516720e-05, 2.29720893e-05, - 2.27491810e-05, 2.45765647e-05, 2.60066598e-05, 2.56460774e-05, - 2.59444695e-05, 2.64177560e-05, 2.42997185e-05, 2.31562433e-05, - 2.31134977e-05, 2.35528938e-05, 2.44927912e-05, 2.60175548e-05, - 2.64025632e-05, 2.61727834e-05, 2.35541964e-05, 2.10034264e-05, - 2.21120249e-05, 2.50379961e-05, 2.64008154e-05, 2.64089319e-05, - 2.62621177e-05, 2.51385823e-05, 2.34689759e-05, 2.21573234e-05, - 2.27584422e-05, 2.45953527e-05, 2.55927235e-05, 2.61169359e-05, - 2.64888944e-05, - 2.50397329e-05, 2.40968569e-05, 2.37389857e-05, 2.48226991e-05, - 2.56995252e-05, 2.53728252e-05, 2.49043721e-05, 2.47222722e-05, - 2.45279746e-05, 2.49747695e-05, 2.45836098e-05, 2.46944355e-05, - 2.51085599e-05, 2.51660125e-05, 2.51596422e-05, 2.53448196e-05, - 2.50878547e-05, 2.48537259e-05, 2.47177167e-05, 2.45299340e-05, - 2.50822223e-05, 2.44060274e-05, 2.42686770e-05, 2.51810046e-05, - 2.54536864e-05, 2.50950389e-05, 2.47898599e-05, 2.44533617e-05, - 2.42824145e-05, 2.44486569e-05, 2.23568185e-05, 2.32936271e-05, - 2.57360771e-05, 2.57224472e-05, 2.49479519e-05, 2.44583765e-05, - 2.43700058e-05, 2.43789973e-05, 2.59446381e-05, 2.49582879e-05, - 2.39248429e-05, 2.52900992e-05, 2.54985261e-05, 2.49219059e-05, - 2.45345188e-05, 2.44864438e-05, 2.42819123e-05, 2.54505580e-05, - 2.58300896e-05, 2.38669835e-05, 2.20885000e-05, 2.36767115e-05, - 2.52158499e-05, 2.47913207e-05, 2.40813109e-05, 2.41622504e-05, - 2.43340592e-05, 2.32062755e-05, 2.38231456e-05, 2.53847081e-05, - 2.55850275e-05, 2.47381453e-05, 2.42550072e-05, 2.43302553e-05, - 2.36637772e-05, 2.27419454e-05, 2.39098409e-05, 2.54336229e-05, - 2.52900632e-05, 2.42932431e-05, 2.41685126e-05, 2.43982348e-05, - 2.39203109e-05, 2.19650614e-05, 2.45611463e-05, 2.60346608e-05, - 2.53521867e-05, 2.43998658e-05, 2.42001363e-05, 2.51400476e-05, - 2.48339660e-05, 2.44891460e-05, 2.44014684e-05, 2.48248076e-05, - 2.46034210e-05, 2.43814104e-05, 2.44450117e-05, 2.52590856e-05, - 2.49517062e-05, 2.49336954e-05, 2.52509216e-05, 2.50208690e-05, - 2.46236231e-05, 2.45401028e-05, 2.44718030e-05, 2.53274747e-05, - 2.46761316e-05, 2.46666190e-05, 2.51799078e-05, 2.51453727e-05, - 2.49345114e-05, 2.45951538e-05, 2.43941770e-05, 2.44344263e-05, - 2.64834300e-05, 2.55994300e-05, 2.23448778e-05, 2.23768863e-05, - 2.40174596e-05, 2.43179558e-05, 2.41935051e-05, 2.42266051e-05, - 2.49173823e-05, 2.44881615e-05, 2.51583550e-05, 2.56745630e-05, - 2.53490678e-05, 2.48743987e-05, 2.46133031e-05, 2.45301407e-05, - 2.64048027e-05, 2.53738454e-05, 2.37313293e-05, 2.46020021e-05, - 2.51290303e-05, 2.47739135e-05, 2.43905051e-05, 2.45229967e-05, - 2.52553117e-05, 2.47453047e-05, 2.45854617e-05, 2.53936738e-05, - 2.56186113e-05, 2.51447951e-05, 2.45955040e-05, 2.44704846e-05, - 2.43787513e-05, 2.56792278e-05, 2.42204794e-05, 2.26199850e-05, - 2.43061001e-05, 2.54437279e-05, 2.50480195e-05, 2.42950854e-05, - 2.41338437e-05, 2.43526863e-05, 2.57753319e-05, 2.54994784e-05, - 2.48987626e-05, 2.53025306e-05, 2.49128863e-05, 2.40310445e-05, - 2.39322148e-05, 2.40459951e-05, 2.49042227e-05, 2.50363275e-05, - 2.51469858e-05, 2.49932080e-05, 2.49912826e-05, 2.51888019e-05, - 2.47973800e-05, 2.45126414e-05, 2.55048106e-05, 2.40835294e-05, - 2.41035271e-05, 2.48666875e-05, 2.45494098e-05, 2.44897473e-05, - 2.44653932e-05, 2.57530589e-05, 2.53247816e-05, 2.43378984e-05, - 2.43447815e-05, 2.46957612e-05, 2.45757201e-05, 2.45466563e-05, - 2.44299542e-05, - 2.52566720e-05, 2.60352127e-05, 2.60525512e-05, 2.64232545e-05, - 2.59640253e-05, 2.42386174e-05, 2.30788293e-05, 2.28421796e-05, - 2.26804248e-05, 2.49456634e-05, 2.56355710e-05, 2.54166946e-05, - 2.52205693e-05, 2.51768617e-05, 2.49597484e-05, 2.42763938e-05, - 2.33095154e-05, 2.31403430e-05, 2.31051579e-05, 2.26229591e-05, - 2.57640625e-05, 2.61855540e-05, 2.58544047e-05, 2.56412304e-05, - 2.52583976e-05, 2.46664269e-05, 2.34063263e-05, 2.22754030e-05, - 2.18741040e-05, 2.61028290e-05, 2.58111319e-05, 2.60467349e-05, - 2.58495606e-05, 2.40619461e-05, 2.30209628e-05, 2.24758358e-05, - 2.22385188e-05, 2.22201841e-05, 2.58940049e-05, 2.69795622e-05, - 2.63955324e-05, 2.60950117e-05, 2.48069333e-05, 2.41457842e-05, - 2.38088078e-05, 2.31103247e-05, 2.22166244e-05, 2.38460667e-05, - 2.57601100e-05, 2.62552827e-05, 2.54311225e-05, 2.60362085e-05, - 2.53290498e-05, 2.28736070e-05, 2.15643062e-05, 2.18349953e-05, - 2.57323835e-05, 2.62155733e-05, 2.65088605e-05, 2.63491688e-05, - 2.44907066e-05, 2.23896739e-05, 2.16310935e-05, 2.20542976e-05, - 2.55861854e-05, 2.60824576e-05, 2.66805210e-05, 2.61541058e-05, - 2.35466095e-05, 2.16462183e-05, 2.17702070e-05, 2.23195922e-05, - 2.63155443e-05, 2.58461133e-05, 2.69246422e-05, 2.61614349e-05, - 2.43972927e-05, 2.29159103e-05, 2.23281466e-05, 2.60821492e-05, - 2.69220191e-05, 2.67104352e-05, 2.59511254e-05, 2.45334499e-05, - 2.27554876e-05, 2.22315898e-05, 2.24342354e-05, 2.59043538e-05, - 2.66865099e-05, 2.65885625e-05, 2.61049379e-05, 2.51161035e-05, - 2.40676742e-05, 2.29875970e-05, 2.25039253e-05, 2.56900228e-05, - 2.63723136e-05, 2.63071244e-05, 2.63901468e-05, 2.58719649e-05, - 2.45309440e-05, 2.30736677e-05, 2.23394098e-05, 2.24076655e-05, - 2.63362952e-05, 2.77914346e-05, 2.60456603e-05, 2.54623614e-05, - 2.49039828e-05, 2.27154035e-05, 2.19717527e-05, 2.26665922e-05, - 2.62649878e-05, 2.70200586e-05, 2.67800906e-05, 2.56894301e-05, - 2.48861600e-05, 2.39422263e-05, 2.28760286e-05, 2.25757751e-05, - 2.61845235e-05, 2.69440475e-05, 2.62378599e-05, 2.60139268e-05, - 2.51372922e-05, 2.35077076e-05, 2.24506912e-05, 2.25853249e-05, - 2.54982411e-05, 2.64528108e-05, 2.65061354e-05, 2.63743348e-05, - 2.54390020e-05, 2.40457314e-05, 2.26417472e-05, 2.26930543e-05, - 2.29343331e-05, 2.59544082e-05, 2.66420566e-05, 2.57422613e-05, - 2.59185559e-05, 2.48525494e-05, 2.32782086e-05, 2.18857364e-05, - 2.16586074e-05, 2.22088355e-05, 2.67914677e-05, 2.77027592e-05, - 2.70259714e-05, 2.58817598e-05, 2.37282615e-05, 2.28421890e-05, - 2.23112484e-05, 2.17812815e-05, 2.55756090e-05, 2.68552976e-05, - 2.70569762e-05, 2.64227232e-05, 2.55116344e-05, 2.41269687e-05, - 2.30101256e-05, 2.28996642e-05, 2.71683883e-05, 2.73592253e-05, - 2.64186424e-05, 2.47696332e-05, 2.26236814e-05, 2.25163528e-05, - 2.26995449e-05, 2.59550630e-05, 2.69862536e-05, 2.67275823e-05, - 2.61991014e-05, 2.49754120e-05, 2.37259793e-05, 2.30284950e-05, - 2.22903664e-05, - 2.34967580e-05, 1.80528649e-05, 1.68973845e-05, 1.95130089e-05, - 2.39640697e-05, 2.84360082e-05, 3.08441429e-05, 3.09255354e-05, - 3.06143668e-05, 2.42041557e-05, 2.06903559e-05, 2.16945437e-05, - 2.38842031e-05, 2.42547898e-05, 2.49272364e-05, 2.81599485e-05, - 3.07992495e-05, 3.03165626e-05, 2.97702034e-05, 3.08787144e-05, - 2.21682782e-05, 1.87033687e-05, 1.90422785e-05, 2.28990371e-05, - 2.51842703e-05, 2.56314571e-05, 2.88919477e-05, 3.20491418e-05, - 3.30105181e-05, 1.90411843e-05, 1.34779457e-05, 1.55935719e-05, - 2.44614719e-05, 3.08542319e-05, 3.13271867e-05, 3.11556694e-05, - 3.17624825e-05, 3.18972799e-05, 2.51711157e-05, 1.86432553e-05, - 1.67298999e-05, 2.20156972e-05, 2.69172873e-05, 2.66920382e-05, - 2.61549146e-05, 2.85909335e-05, 3.13821911e-05, 3.03819557e-05, - 2.51270162e-05, 1.68522941e-05, 1.34441717e-05, 1.67433930e-05, - 2.39800809e-05, 3.11513517e-05, 3.33871746e-05, 3.25174462e-05, - 1.95652394e-05, 1.50191981e-05, 1.61961807e-05, 2.16655590e-05, - 2.84755173e-05, 3.30938006e-05, 3.40670145e-05, 3.24096474e-05, - 1.76964516e-05, 1.40073299e-05, 1.61016859e-05, 2.23847250e-05, - 3.08260171e-05, 3.42154219e-05, 3.28686078e-05, 3.15421411e-05, - 1.68852280e-05, 1.24363240e-05, 1.75263533e-05, 2.46965985e-05, - 2.77404334e-05, 2.89538141e-05, 3.04390321e-05, 2.15001093e-05, - 1.83792576e-05, 1.77715154e-05, 1.92519157e-05, 2.49193319e-05, - 3.06813348e-05, 3.18573703e-05, 3.12719873e-05, 2.24361380e-05, - 1.93066954e-05, 1.94824932e-05, 2.18435981e-05, 2.38550356e-05, - 2.56354917e-05, 2.93622144e-05, 3.11011024e-05, 2.33241297e-05, - 1.91478888e-05, 1.92733204e-05, 2.08241792e-05, 2.21005365e-05, - 2.53980816e-05, 2.92821189e-05, 3.14291815e-05, 3.13355882e-05, - 2.59783863e-05, 1.88351706e-05, 1.30484862e-05, 1.41556159e-05, - 2.06114580e-05, 2.93758644e-05, 3.20381124e-05, 2.91163974e-05, - 2.02294656e-05, 1.71032378e-05, 1.97681024e-05, 2.47133925e-05, - 2.59827828e-05, 2.72210127e-05, 3.02089032e-05, 3.10904076e-05, - 2.61439270e-05, 2.00912138e-05, 1.64825944e-05, 1.97773054e-05, - 2.42286668e-05, 2.84097838e-05, 3.09054141e-05, 3.10095563e-05, - 2.36176481e-05, 1.91838482e-05, 1.85367735e-05, 2.16300162e-05, - 2.52855793e-05, 2.80954605e-05, 3.11437218e-05, 3.02580496e-05, - 2.87725918e-05, 2.39129039e-05, 1.70974506e-05, 1.42982291e-05, - 1.90116441e-05, 2.65133128e-05, 3.07278827e-05, 3.30259354e-05, - 3.32205459e-05, 3.18054060e-05, 2.18865114e-05, 1.87200309e-05, - 1.83495441e-05, 2.26656393e-05, 2.82154661e-05, 2.74359560e-05, - 2.91141043e-05, 3.21202879e-05, 2.20328036e-05, 1.91838262e-05, - 1.90708863e-05, 2.00922717e-05, 2.25472379e-05, 2.79936412e-05, - 3.05850213e-05, 2.95913454e-05, 1.99824913e-05, 1.52803374e-05, - 1.72207905e-05, 2.43215432e-05, 3.09789364e-05, 3.11412866e-05, - 3.02033535e-05, 2.42041252e-05, 1.98234009e-05, 1.72703955e-05, - 1.84722331e-05, 2.29863650e-05, 2.66435874e-05, 2.92253781e-05, - 3.18505952e-05, - 2.51305126e-05, 2.36127295e-05, 2.31480730e-05, 2.36897533e-05, - 2.45176715e-05, 2.53532507e-05, 2.55920358e-05, 2.57441086e-05, - 2.59656635e-05, 2.53748584e-05, 2.46088591e-05, 2.49214368e-05, - 2.51538593e-05, 2.51767746e-05, 2.53167234e-05, 2.53850783e-05, - 2.54309659e-05, 2.57103413e-05, 2.58987997e-05, 2.59233520e-05, - 2.46576928e-05, 2.36857947e-05, 2.40729888e-05, 2.47965100e-05, - 2.50436041e-05, 2.54929051e-05, 2.59028808e-05, 2.57735311e-05, - 2.56937965e-05, 2.38534227e-05, 2.13003387e-05, 2.25057776e-05, - 2.45951416e-05, 2.48325577e-05, 2.54767069e-05, 2.59405921e-05, - 2.59037481e-05, 2.58686213e-05, 2.45080699e-05, 2.29673400e-05, - 2.27681682e-05, 2.43603027e-05, 2.51943168e-05, 2.57736334e-05, - 2.61316201e-05, 2.62094790e-05, 2.60534061e-05, 2.51459800e-05, - 2.46252218e-05, 2.29477087e-05, 2.16156452e-05, 2.30942380e-05, - 2.50586479e-05, 2.56461393e-05, 2.57573039e-05, 2.59131325e-05, - 2.43098406e-05, 2.20176921e-05, 2.24127339e-05, 2.41091780e-05, - 2.51412673e-05, 2.52953282e-05, 2.54281019e-05, 2.57985831e-05, - 2.38853042e-05, 2.14582767e-05, 2.22123555e-05, 2.43334916e-05, - 2.52407967e-05, 2.53544153e-05, 2.58224708e-05, 2.59226309e-05, - 2.29086098e-05, 2.03786244e-05, 2.26331678e-05, 2.43159535e-05, - 2.53761941e-05, 2.62682508e-05, 2.62839659e-05, 2.43244731e-05, - 2.29363177e-05, 2.29149249e-05, 2.40419202e-05, 2.56746788e-05, - 2.58880150e-05, 2.58747534e-05, 2.59318627e-05, 2.45521341e-05, - 2.34079854e-05, 2.35371414e-05, 2.43377117e-05, 2.52434875e-05, - 2.59882129e-05, 2.61036593e-05, 2.59381549e-05, 2.47604265e-05, - 2.36439911e-05, 2.37335817e-05, 2.39698408e-05, 2.45597301e-05, - 2.56313414e-05, 2.60591518e-05, 2.59474650e-05, 2.59296659e-05, - 2.40504853e-05, 2.23097158e-05, 2.07401112e-05, 2.21219526e-05, - 2.52358727e-05, 2.63084492e-05, 2.59959205e-05, 2.64166893e-05, - 2.39797048e-05, 2.23777389e-05, 2.34342046e-05, 2.47162502e-05, - 2.52674385e-05, 2.58459860e-05, 2.59442045e-05, 2.58885028e-05, - 2.41584990e-05, 2.33578567e-05, 2.27937847e-05, 2.41092455e-05, - 2.52115237e-05, 2.59413316e-05, 2.60425490e-05, 2.59082986e-05, - 2.49229101e-05, 2.35824146e-05, 2.33526936e-05, 2.40837781e-05, - 2.48822285e-05, 2.55846869e-05, 2.58216976e-05, 2.60675114e-05, - 2.63007326e-05, 2.45272677e-05, 2.27100234e-05, 2.19699453e-05, - 2.40081528e-05, 2.52211242e-05, 2.54774918e-05, 2.56795393e-05, - 2.57599761e-05, 2.59099015e-05, 2.37451069e-05, 2.23540022e-05, - 2.28351106e-05, 2.45820001e-05, 2.58115082e-05, 2.66812505e-05, - 2.66875471e-05, 2.61009462e-05, 2.48113572e-05, 2.32280726e-05, - 2.30207618e-05, 2.38151630e-05, 2.48961374e-05, 2.55415610e-05, - 2.57264269e-05, 2.61072763e-05, 2.31391899e-05, 2.11601200e-05, - 2.29596098e-05, 2.55176050e-05, 2.58899000e-05, 2.59154843e-05, - 2.60793488e-05, 2.45171656e-05, 2.32653063e-05, 2.27059318e-05, - 2.36041813e-05, 2.53692477e-05, 2.61229389e-05, 2.61093416e-05, - 2.58345648e-05, - 2.54594545e-05, 2.50939865e-05, 2.48763430e-05, 2.44891678e-05, - 2.41933006e-05, 2.44181831e-05, 2.43636901e-05, 2.46221979e-05, - 2.50762796e-05, 2.56566455e-05, 2.56407878e-05, 2.57817405e-05, - 2.53637409e-05, 2.52775184e-05, 2.53094930e-05, 2.45382502e-05, - 2.40856239e-05, 2.46680458e-05, 2.51115749e-05, 2.49540381e-05, - 2.51006700e-05, 2.48842226e-05, 2.54352595e-05, 2.50709643e-05, - 2.47364579e-05, 2.54094040e-05, 2.53017270e-05, 2.45037627e-05, - 2.42393411e-05, 2.50241164e-05, 2.36401262e-05, 2.44671065e-05, - 2.41673757e-05, 2.30372314e-05, 2.40797915e-05, 2.49399281e-05, - 2.47803733e-05, 2.46972571e-05, 2.37947806e-05, 2.35933561e-05, - 2.42573959e-05, 2.46209389e-05, 2.45093216e-05, 2.56125810e-05, - 2.64282467e-05, 2.59314735e-05, 2.51104845e-05, 2.36595697e-05, - 2.40129830e-05, 2.45233450e-05, 2.42847609e-05, 2.48665670e-05, - 2.51571731e-05, 2.44093985e-05, 2.43146206e-05, 2.46963899e-05, - 2.56164908e-05, 2.39152174e-05, 2.39095766e-05, 2.43078622e-05, - 2.40362929e-05, 2.35183370e-05, 2.36558257e-05, 2.45012593e-05, - 2.58153956e-05, 2.35507450e-05, 2.35917085e-05, 2.44293297e-05, - 2.37471012e-05, 2.35112694e-05, 2.44891044e-05, 2.48472005e-05, - 2.44301691e-05, 2.26699481e-05, 2.35582634e-05, 2.36043085e-05, - 2.46229243e-05, 2.59588865e-05, 2.56923658e-05, 2.47645883e-05, - 2.36684002e-05, 2.39447886e-05, 2.52701503e-05, 2.59674928e-05, - 2.49235516e-05, 2.47140495e-05, 2.49055547e-05, 2.48037465e-05, - 2.40725039e-05, 2.42244149e-05, 2.46486331e-05, 2.55378525e-05, - 2.63193715e-05, 2.55679400e-05, 2.49442876e-05, 2.48492211e-05, - 2.45821166e-05, 2.46858618e-05, 2.44058377e-05, 2.49489969e-05, - 2.57341476e-05, 2.55030563e-05, 2.49095666e-05, 2.48916000e-05, - 2.27791000e-05, 2.23298371e-05, 2.28850724e-05, 2.47336987e-05, - 2.68659557e-05, 2.59432658e-05, 2.49101050e-05, 2.61998824e-05, - 2.46868869e-05, 2.33201121e-05, 2.39048130e-05, 2.43012521e-05, - 2.48981357e-05, 2.56015625e-05, 2.51102267e-05, 2.48558071e-05, - 2.29178929e-05, 2.36227861e-05, 2.44540323e-05, 2.51374515e-05, - 2.53496276e-05, 2.54807005e-05, 2.51669624e-05, 2.49049523e-05, - 2.50380599e-05, 2.44510153e-05, 2.43516722e-05, 2.42764940e-05, - 2.44182258e-05, 2.49095593e-05, 2.47262188e-05, 2.53261627e-05, - 2.60594318e-05, 2.42274372e-05, 2.39363023e-05, 2.43296352e-05, - 2.53290107e-05, 2.46656612e-05, 2.41801169e-05, 2.42118300e-05, - 2.43366054e-05, 2.47854044e-05, 2.35732846e-05, 2.24607386e-05, - 2.34994597e-05, 2.47701319e-05, 2.52901379e-05, 2.71027581e-05, - 2.67106947e-05, 2.50923753e-05, 2.54371840e-05, 2.38042718e-05, - 2.34835610e-05, 2.44484866e-05, 2.53877634e-05, 2.48566029e-05, - 2.46488174e-05, 2.55276455e-05, 2.32807153e-05, 2.21466438e-05, - 2.43318371e-05, 2.58788184e-05, 2.48766088e-05, 2.48965730e-05, - 2.53579504e-05, 2.41130775e-05, 2.35760332e-05, 2.38318812e-05, - 2.48523868e-05, 2.60918836e-05, 2.62699226e-05, 2.56070759e-05, - 2.46420673e-05, - 2.38320782e-05, 1.87524488e-05, 1.76585797e-05, 1.94257273e-05, - 2.29206660e-05, 2.75342821e-05, 3.01679490e-05, 3.06563249e-05, - 3.09623063e-05, 2.47240220e-05, 2.14558631e-05, 2.24902395e-05, - 2.40967211e-05, 2.43565403e-05, 2.50437307e-05, 2.73983173e-05, - 2.97004854e-05, 2.99924016e-05, 2.99904518e-05, 3.11048262e-05, - 2.22463115e-05, 1.91061434e-05, 1.98544656e-05, 2.28738817e-05, - 2.46442122e-05, 2.58601732e-05, 2.92325831e-05, 3.18821180e-05, - 3.27128060e-05, 1.95008958e-05, 1.42408754e-05, 1.63501409e-05, - 2.33408362e-05, 2.82314270e-05, 3.03163664e-05, 3.14311265e-05, - 3.19567461e-05, 3.19980161e-05, 2.35766658e-05, 1.79866878e-05, - 1.70558347e-05, 2.16411356e-05, 2.60780919e-05, 2.72062895e-05, - 2.76369940e-05, 2.97537864e-05, 3.19900088e-05, 2.86059027e-05, - 2.37787541e-05, 1.73522428e-05, 1.46311012e-05, 1.75303686e-05, - 2.39647293e-05, 3.06073735e-05, 3.33596917e-05, 3.28196825e-05, - 2.04562134e-05, 1.55332494e-05, 1.63951843e-05, 2.10399566e-05, - 2.70743296e-05, 3.16079400e-05, 3.31389226e-05, 3.23497787e-05, - 1.90475467e-05, 1.45584099e-05, 1.60927767e-05, 2.17726644e-05, - 2.92319422e-05, 3.30856747e-05, 3.29460956e-05, 3.17786916e-05, - 1.73062480e-05, 1.29193584e-05, 1.71175190e-05, 2.29426131e-05, - 2.70655123e-05, 3.02253876e-05, 3.16791810e-05, 2.13345625e-05, - 1.78470974e-05, 1.76062424e-05, 1.98876196e-05, 2.57858828e-05, - 3.08138352e-05, 3.19732313e-05, 3.15250769e-05, 2.21891577e-05, - 1.89024073e-05, 1.91723511e-05, 2.15192369e-05, 2.42568000e-05, - 2.69439420e-05, 3.01598683e-05, 3.13688996e-05, 2.30314177e-05, - 1.92103467e-05, 1.94008977e-05, 2.04269677e-05, 2.20365418e-05, - 2.60034708e-05, 2.99716054e-05, 3.17323063e-05, 3.15841927e-05, - 2.31622005e-05, 1.70955490e-05, 1.34654922e-05, 1.54536400e-05, - 2.25369356e-05, 3.07171614e-05, 3.25303238e-05, 3.07678797e-05, - 2.01881132e-05, 1.66216618e-05, 1.91228630e-05, 2.37168667e-05, - 2.56105928e-05, 2.77620009e-05, 3.05154796e-05, 3.12183647e-05, - 2.34660673e-05, 1.91312713e-05, 1.70157627e-05, 2.02121267e-05, - 2.44104902e-05, 2.89257417e-05, 3.14661088e-05, 3.11929305e-05, - 2.34987871e-05, 1.91274404e-05, 1.85290770e-05, 2.09801027e-05, - 2.43806653e-05, 2.78150464e-05, 3.10847298e-05, 3.08971303e-05, - 3.01490175e-05, 2.29109687e-05, 1.70888646e-05, 1.52877043e-05, - 1.97375241e-05, 2.58625592e-05, 2.97570814e-05, 3.26867154e-05, - 3.31667690e-05, 3.20206505e-05, 2.05238176e-05, 1.71191156e-05, - 1.76875993e-05, 2.23588578e-05, 2.84505629e-05, 2.99752336e-05, - 3.15062072e-05, 3.29424438e-05, 2.24577863e-05, 1.85783938e-05, - 1.82217766e-05, 1.98617839e-05, 2.28758290e-05, 2.76359574e-05, - 3.02841418e-05, 3.03779145e-05, 1.87479171e-05, 1.44930130e-05, - 1.74883842e-05, 2.50854308e-05, 3.11110244e-05, 3.13455255e-05, - 3.08769804e-05, 2.30504177e-05, 1.88809618e-05, 1.71384945e-05, - 1.88924447e-05, 2.40127870e-05, 2.79768528e-05, 3.00519555e-05, - 3.18485783e-05, - 2.33853626e-05, 1.76739992e-05, 1.64854450e-05, 1.88622726e-05, - 2.32336219e-05, 2.83299495e-05, 3.12326921e-05, 3.15353591e-05, - 3.14822826e-05, 2.42564527e-05, 2.05235928e-05, 2.16269318e-05, - 2.37547256e-05, 2.41120715e-05, 2.48672349e-05, 2.80845128e-05, - 3.09638623e-05, 3.07950118e-05, 3.04325853e-05, 3.17311686e-05, - 2.18054494e-05, 1.82276807e-05, 1.87760489e-05, 2.25556188e-05, - 2.48342687e-05, 2.57095616e-05, 2.94750555e-05, 3.29131659e-05, - 3.39917695e-05, 1.86131930e-05, 1.29535784e-05, 1.51244407e-05, - 2.37453984e-05, 3.02371215e-05, 3.16277671e-05, 3.20819131e-05, - 3.27576199e-05, 3.28697829e-05, 2.42978334e-05, 1.76703318e-05, - 1.61135617e-05, 2.14233849e-05, 2.66329734e-05, 2.70444236e-05, - 2.69026703e-05, 2.95326532e-05, 3.25169896e-05, 3.01287077e-05, - 2.43714791e-05, 1.63204211e-05, 1.31026356e-05, 1.63357487e-05, - 2.37513072e-05, 3.16605224e-05, 3.45834786e-05, 3.37105020e-05, - 1.93710247e-05, 1.44228092e-05, 1.54996220e-05, 2.09226737e-05, - 2.81226157e-05, 3.34727495e-05, 3.49338414e-05, 3.33966211e-05, - 1.75904964e-05, 1.34006932e-05, 1.53068300e-05, 2.17112342e-05, - 3.07399947e-05, 3.50070769e-05, 3.40151917e-05, 3.25183262e-05, - 1.63191372e-05, 1.17766179e-05, 1.66095307e-05, 2.36913259e-05, - 2.76492002e-05, 3.00055340e-05, 3.17221994e-05, 2.09630804e-05, - 1.74498047e-05, 1.69803184e-05, 1.89188708e-05, 2.52188923e-05, - 3.14523063e-05, 3.28301705e-05, 3.22077069e-05, 2.19428058e-05, - 1.84934866e-05, 1.87251260e-05, 2.12602568e-05, 2.38130069e-05, - 2.62333760e-05, 3.02458189e-05, 3.20137748e-05, 2.28940341e-05, - 1.85429199e-05, 1.87068414e-05, 2.01223080e-05, 2.16640540e-05, - 2.56297717e-05, 3.00993508e-05, 3.24185686e-05, 3.22804643e-05, - 2.45787871e-05, 1.73544695e-05, 1.23661443e-05, 1.38783471e-05, - 2.09690706e-05, 3.05296774e-05, 3.32361226e-05, 3.03799361e-05, - 1.96508009e-05, 1.61324739e-05, 1.88714799e-05, 2.40859020e-05, - 2.58106810e-05, 2.76583046e-05, 3.09870677e-05, 3.19304781e-05, - 2.48347396e-05, 1.90666112e-05, 1.59490817e-05, 1.93880617e-05, - 2.41216230e-05, 2.90062365e-05, 3.19310344e-05, 3.18633871e-05, - 2.33010669e-05, 1.85258123e-05, 1.78613154e-05, 2.08724621e-05, - 2.47677994e-05, 2.82512219e-05, 3.18984703e-05, 3.12108869e-05, - 2.98470100e-05, 2.31975375e-05, 1.63451675e-05, 1.38908721e-05, - 1.87039237e-05, 2.62704131e-05, 3.09460591e-05, 3.39887745e-05, - 3.43695996e-05, 3.28191482e-05, 2.08051036e-05, 1.73000739e-05, - 1.73573533e-05, 2.21649835e-05, 2.86443970e-05, 2.88666383e-05, - 3.07370138e-05, 3.35011757e-05, 2.18218031e-05, 1.82678334e-05, - 1.80323003e-05, 1.94145974e-05, 2.23384771e-05, 2.80963326e-05, - 3.11203848e-05, 3.05065889e-05, 1.88182813e-05, 1.40996090e-05, - 1.66009009e-05, 2.45033101e-05, 3.18014589e-05, 3.20289660e-05, - 3.11641637e-05, 2.34444079e-05, 1.87887916e-05, 1.64695286e-05, - 1.79904354e-05, 2.31496978e-05, 2.73854818e-05, 3.01013590e-05, - 3.27620664e-05, - 2.53769293e-05, 2.88398271e-05, 2.95081449e-05, 2.85484202e-05, - 2.59890516e-05, 2.24823303e-05, 2.05461537e-05, 2.02800332e-05, - 2.01997462e-05, 2.47450944e-05, 2.70325585e-05, 2.63205058e-05, - 2.51809621e-05, 2.49859189e-05, 2.44851634e-05, 2.26115871e-05, - 2.07962461e-05, 2.07595390e-05, 2.08807886e-05, 2.00675034e-05, - 2.65176938e-05, 2.86779577e-05, 2.80980382e-05, 2.60628152e-05, - 2.47206933e-05, 2.39000394e-05, 2.14583088e-05, 1.93993608e-05, - 1.87504992e-05, 2.84012612e-05, 3.13935267e-05, 3.02857659e-05, - 2.56600028e-05, 2.15537893e-05, 2.03520254e-05, 1.98409206e-05, - 1.94369441e-05, 1.93830167e-05, 2.54307512e-05, 2.96810923e-05, - 3.00394440e-05, 2.69692033e-05, 2.35986852e-05, 2.29577301e-05, - 2.27718737e-05, 2.12360799e-05, 1.95149373e-05, 2.14710549e-05, - 2.52993627e-05, 2.97902768e-05, 3.09070186e-05, 2.95769859e-05, - 2.52656320e-05, 2.02498034e-05, 1.83489399e-05, 1.88346196e-05, - 2.76875990e-05, 3.08726178e-05, 3.05050045e-05, 2.74231463e-05, - 2.27371118e-05, 1.92448048e-05, 1.82515613e-05, 1.90828811e-05, - 2.84750389e-05, 3.13811202e-05, 3.07823395e-05, 2.68743999e-05, - 2.10324825e-05, 1.82310576e-05, 1.86817619e-05, 1.95776506e-05, - 2.98470574e-05, 3.22188196e-05, 3.02380939e-05, 2.59147912e-05, - 2.28782666e-05, 2.09216589e-05, 1.98839104e-05, 2.71865161e-05, - 2.97548966e-05, 2.98321758e-05, 2.81092407e-05, 2.40123829e-05, - 2.02586000e-05, 1.94050324e-05, 1.97669391e-05, 2.65635175e-05, - 2.89725629e-05, 2.87635325e-05, 2.70577284e-05, 2.50742047e-05, - 2.32368478e-05, 2.08768618e-05, 1.98845051e-05, 2.59412390e-05, - 2.86739585e-05, 2.85302855e-05, 2.78638243e-05, 2.66726106e-05, - 2.38345348e-05, 2.09908607e-05, 1.96279065e-05, 1.97226781e-05, - 2.56061892e-05, 3.05640562e-05, 3.20238418e-05, 3.04560016e-05, - 2.61984074e-05, 2.05870247e-05, 1.90945945e-05, 2.06108960e-05, - 2.80016670e-05, 3.06044000e-05, 2.88482268e-05, 2.53815136e-05, - 2.40153617e-05, 2.25599460e-05, 2.05161111e-05, 1.99611225e-05, - 2.53773541e-05, 2.88808610e-05, 2.99866691e-05, 2.79225411e-05, - 2.49515364e-05, 2.17137979e-05, 1.98829841e-05, 1.99929766e-05, - 2.56027200e-05, 2.87530753e-05, 2.91592045e-05, 2.74687920e-05, - 2.48827085e-05, 2.23863732e-05, 2.00142466e-05, 2.03123324e-05, - 2.09949655e-05, 2.59990837e-05, 3.01338009e-05, 3.07305431e-05, - 2.81918841e-05, 2.37895486e-05, 2.07843593e-05, 1.87582961e-05, - 1.84834533e-05, 1.93955167e-05, 2.78365540e-05, 3.05202354e-05, - 2.98988367e-05, 2.64384337e-05, 2.20094614e-05, 2.13030025e-05, - 2.02369864e-05, 1.88807347e-05, 2.63578428e-05, 2.92410892e-05, - 2.95452918e-05, 2.82574928e-05, 2.60623636e-05, 2.25060072e-05, - 2.05484126e-05, 2.07178764e-05, 2.92038607e-05, 3.21828742e-05, - 2.97820183e-05, 2.45016493e-05, 2.00407540e-05, 1.98863529e-05, - 2.03344483e-05, 2.58815416e-05, 2.90672903e-05, 3.01402331e-05, - 2.88168375e-05, 2.52622896e-05, 2.25166018e-05, 2.09600956e-05, - 1.94665020e-05, - 2.51830001e-05, 2.60458841e-05, 2.60788283e-05, 2.66688827e-05, - 2.62862122e-05, 2.42749484e-05, 2.29579238e-05, 2.26352916e-05, - 2.23623113e-05, 2.47944612e-05, 2.55325187e-05, 2.52711224e-05, - 2.51668047e-05, 2.51393925e-05, 2.48908070e-05, 2.42917520e-05, - 2.32799839e-05, 2.29667089e-05, 2.28380274e-05, 2.23205248e-05, - 2.58235674e-05, 2.62834324e-05, 2.57902935e-05, 2.57000802e-05, - 2.53601074e-05, 2.45405198e-05, 2.31418220e-05, 2.20108360e-05, - 2.16023980e-05, 2.61656450e-05, 2.59444056e-05, 2.61179176e-05, - 2.61652828e-05, 2.43796005e-05, 2.29493837e-05, 2.21558472e-05, - 2.19160398e-05, 2.19109001e-05, 2.63121024e-05, 2.75081095e-05, - 2.66096047e-05, 2.63104419e-05, 2.49028876e-05, 2.39124913e-05, - 2.33673060e-05, 2.26837464e-05, 2.18291015e-05, 2.39898239e-05, - 2.61044308e-05, 2.63903776e-05, 2.53601250e-05, 2.60571542e-05, - 2.53367230e-05, 2.27135997e-05, 2.12342174e-05, 2.14722198e-05, - 2.56242748e-05, 2.64168323e-05, 2.68038085e-05, 2.66712580e-05, - 2.46490714e-05, 2.23358406e-05, 2.14346337e-05, 2.17587875e-05, - 2.53671939e-05, 2.63040597e-05, 2.70762272e-05, 2.64291419e-05, - 2.36248005e-05, 2.14797793e-05, 2.14368492e-05, 2.19956912e-05, - 2.64823990e-05, 2.61609365e-05, 2.74187876e-05, 2.66648784e-05, - 2.44109710e-05, 2.24598526e-05, 2.18475077e-05, 2.62536984e-05, - 2.74147406e-05, 2.70826829e-05, 2.59422457e-05, 2.42686190e-05, - 2.24772579e-05, 2.19207150e-05, 2.21150752e-05, 2.60556382e-05, - 2.70674829e-05, 2.69218964e-05, 2.63126029e-05, 2.50100220e-05, - 2.36770508e-05, 2.26155618e-05, 2.21869700e-05, 2.58113199e-05, - 2.65793206e-05, 2.64833397e-05, 2.66794649e-05, 2.59802943e-05, - 2.43172129e-05, 2.27254447e-05, 2.20064148e-05, 2.20874980e-05, - 2.70881841e-05, 2.87994532e-05, 2.63735795e-05, 2.53300486e-05, - 2.44505617e-05, 2.22372527e-05, 2.15882252e-05, 2.21346479e-05, - 2.64569205e-05, 2.75755750e-05, 2.72284174e-05, 2.59513988e-05, - 2.49033004e-05, 2.36859389e-05, 2.25779795e-05, 2.22857554e-05, - 2.68756661e-05, 2.74968673e-05, 2.63735391e-05, 2.60560132e-05, - 2.50783853e-05, 2.32205451e-05, 2.20841303e-05, 2.22871548e-05, - 2.55526289e-05, 2.67037421e-05, 2.67714522e-05, 2.67071923e-05, - 2.56405737e-05, 2.39486770e-05, 2.23860648e-05, 2.23287130e-05, - 2.24614835e-05, 2.62664542e-05, 2.69836071e-05, 2.57458779e-05, - 2.58860918e-05, 2.49187641e-05, 2.32243603e-05, 2.16209191e-05, - 2.13378270e-05, 2.18812814e-05, 2.73682377e-05, 2.86552143e-05, - 2.75772464e-05, 2.60407098e-05, 2.35088018e-05, 2.21645079e-05, - 2.16446392e-05, 2.13385867e-05, 2.55317388e-05, 2.73258279e-05, - 2.76379003e-05, 2.66914033e-05, 2.54771589e-05, 2.40523677e-05, - 2.28218404e-05, 2.25239468e-05, 2.78432447e-05, 2.82089737e-05, - 2.66353263e-05, 2.45493152e-05, 2.23362954e-05, 2.22102545e-05, - 2.23299966e-05, 2.62974856e-05, 2.75514222e-05, 2.71138779e-05, - 2.62999759e-05, 2.47239432e-05, 2.33070254e-05, 2.26541910e-05, - 2.20014411e-05, - 2.44971229e-05, 2.14227153e-05, 2.06481983e-05, 2.26643800e-05, - 2.53238460e-05, 2.68924184e-05, 2.74469751e-05, 2.72962704e-05, - 2.69672214e-05, 2.47277549e-05, 2.29231816e-05, 2.34337541e-05, - 2.47228882e-05, 2.49315582e-05, 2.52051624e-05, 2.67468303e-05, - 2.76151800e-05, 2.71702241e-05, 2.68012172e-05, 2.70811716e-05, - 2.39894874e-05, 2.19596958e-05, 2.19722720e-05, 2.43840048e-05, - 2.55974379e-05, 2.54362715e-05, 2.65027557e-05, 2.75011444e-05, - 2.77365796e-05, 2.21339629e-05, 1.81400372e-05, 1.97496173e-05, - 2.55683504e-05, 2.82932293e-05, 2.76988638e-05, 2.71260857e-05, - 2.72938420e-05, 2.73603482e-05, 2.60723043e-05, 2.24357696e-05, - 2.07450367e-05, 2.41220977e-05, 2.63723157e-05, 2.57105246e-05, - 2.51119619e-05, 2.60757413e-05, 2.70430989e-05, 2.78069528e-05, - 2.59410584e-05, 2.07426152e-05, 1.79041783e-05, 2.05329425e-05, - 2.48651548e-05, 2.74630742e-05, 2.76902034e-05, 2.74025556e-05, - 2.22414095e-05, 1.94509619e-05, 2.04452130e-05, 2.40666275e-05, - 2.71228375e-05, 2.82452793e-05, 2.81629080e-05, 2.75288359e-05, - 2.08983535e-05, 1.86655357e-05, 2.04838902e-05, 2.44104464e-05, - 2.78341548e-05, 2.82671491e-05, 2.75585623e-05, 2.72289833e-05, - 2.08025177e-05, 1.74212366e-05, 2.16269910e-05, 2.59595312e-05, - 2.65759952e-05, 2.61416167e-05, 2.65637917e-05, 2.37689048e-05, - 2.22159527e-05, 2.16605523e-05, 2.21761807e-05, 2.48802412e-05, - 2.70718516e-05, 2.73458284e-05, 2.71618607e-05, 2.42665151e-05, - 2.26986905e-05, 2.27535832e-05, 2.40142228e-05, 2.46272805e-05, - 2.49832491e-05, 2.64517127e-05, 2.71165630e-05, 2.46993198e-05, - 2.23830064e-05, 2.24250540e-05, 2.35286044e-05, 2.40209092e-05, - 2.51839664e-05, 2.64729205e-05, 2.71769154e-05, 2.71780974e-05, - 2.69534595e-05, 2.31040456e-05, 1.79669340e-05, 1.84158580e-05, - 2.23758064e-05, 2.62366131e-05, 2.72309511e-05, 2.60381211e-05, - 2.30424654e-05, 2.13925941e-05, 2.30765431e-05, 2.56145101e-05, - 2.58307704e-05, 2.58850945e-05, 2.68817314e-05, 2.71712068e-05, - 2.69458038e-05, 2.34084896e-05, 2.04778103e-05, 2.25700736e-05, - 2.48852934e-05, 2.62841520e-05, 2.69514595e-05, 2.71296391e-05, - 2.47523499e-05, 2.24604514e-05, 2.20544405e-05, 2.40603908e-05, - 2.58009050e-05, 2.65199298e-05, 2.72602785e-05, 2.67588525e-05, - 2.60452114e-05, 2.52827517e-05, 2.11519092e-05, 1.86745215e-05, - 2.19936226e-05, 2.61472497e-05, 2.75437777e-05, 2.77562692e-05, - 2.76731727e-05, 2.72944281e-05, 2.45282245e-05, 2.29643462e-05, - 2.22628326e-05, 2.44025590e-05, 2.63402054e-05, 2.51533712e-05, - 2.57473198e-05, 2.71155542e-05, 2.37671943e-05, 2.27263391e-05, - 2.27820266e-05, 2.30564140e-05, 2.40599737e-05, 2.65206420e-05, - 2.72274529e-05, 2.65205454e-05, 2.34859134e-05, 2.03136711e-05, - 2.10972888e-05, 2.46732575e-05, 2.71434273e-05, 2.71518109e-05, - 2.67306936e-05, 2.54765806e-05, 2.32531869e-05, 2.13251640e-05, - 2.18118971e-05, 2.39628458e-05, 2.53537626e-05, 2.64008185e-05, - 2.73925161e-05, - 2.44539204e-05, 2.11837718e-05, 2.03752233e-05, 2.23810039e-05, - 2.51371339e-05, 2.69784125e-05, 2.77021562e-05, 2.75977171e-05, - 2.73113940e-05, 2.47410785e-05, 2.28004132e-05, 2.33591997e-05, - 2.46847450e-05, 2.48993982e-05, 2.52095801e-05, 2.68320565e-05, - 2.78236190e-05, 2.74296443e-05, 2.70837727e-05, 2.74289042e-05, - 2.38503414e-05, 2.17072863e-05, 2.17864555e-05, 2.42680891e-05, - 2.55391942e-05, 2.54904068e-05, 2.67473561e-05, 2.78806437e-05, - 2.81626234e-05, 2.19028337e-05, 1.77652427e-05, 1.94327941e-05, - 2.53994035e-05, 2.83377662e-05, 2.79493739e-05, 2.74949333e-05, - 2.76908876e-05, 2.77564997e-05, 2.58839862e-05, 2.20343998e-05, - 2.04062679e-05, 2.39186660e-05, 2.63764813e-05, 2.58522186e-05, - 2.53267250e-05, 2.63860042e-05, 2.74570708e-05, 2.79159809e-05, - 2.57812224e-05, 2.04324704e-05, 1.75898567e-05, 2.02580965e-05, - 2.48051358e-05, 2.77504988e-05, 2.81650288e-05, 2.78551094e-05, - 2.20866034e-05, 1.90819268e-05, 2.00692972e-05, 2.38131869e-05, - 2.71549997e-05, 2.85599316e-05, 2.85955885e-05, 2.79406168e-05, - 2.07299111e-05, 1.82728522e-05, 2.00742361e-05, 2.41951334e-05, - 2.79913959e-05, 2.86900714e-05, 2.80113515e-05, 2.76169574e-05, - 2.04826436e-05, 1.69801140e-05, 2.12135598e-05, 2.57229956e-05, - 2.66463763e-05, 2.64821623e-05, 2.69833243e-05, 2.35669959e-05, - 2.18208633e-05, 2.12923715e-05, 2.19764070e-05, 2.49679856e-05, - 2.73987698e-05, 2.77410349e-05, 2.75354125e-05, 2.41001442e-05, - 2.23628468e-05, 2.24386232e-05, 2.38087077e-05, 2.46096278e-05, - 2.51540134e-05, 2.67685273e-05, 2.74814509e-05, 2.45722247e-05, - 2.21038493e-05, 2.21599661e-05, 2.32641681e-05, 2.38608682e-05, - 2.52675337e-05, 2.67745696e-05, 2.75645898e-05, 2.75549792e-05, - 2.66548119e-05, 2.25481393e-05, 1.75293747e-05, 1.81337223e-05, - 2.23853690e-05, 2.66068593e-05, 2.76726473e-05, 2.64237545e-05, - 2.27972539e-05, 2.09510389e-05, 2.27283962e-05, 2.54750611e-05, - 2.58359251e-05, 2.60580653e-05, 2.71982729e-05, 2.75218380e-05, - 2.66761768e-05, 2.30315792e-05, 2.01592336e-05, 2.23666295e-05, - 2.48610959e-05, 2.65196652e-05, 2.73331739e-05, 2.74809049e-05, - 2.46614038e-05, 2.21668328e-05, 2.17398947e-05, 2.38019682e-05, - 2.57045921e-05, 2.66540555e-05, 2.75957180e-05, 2.71108270e-05, - 2.63860868e-05, 2.50984917e-05, 2.07793848e-05, 1.83530794e-05, - 2.17956078e-05, 2.61500344e-05, 2.77612383e-05, 2.81793111e-05, - 2.81352573e-05, 2.76960471e-05, 2.41868370e-05, 2.24244664e-05, - 2.18475973e-05, 2.42402152e-05, 2.65358587e-05, 2.55353488e-05, - 2.62013534e-05, 2.75927302e-05, 2.36639024e-05, 2.23567418e-05, - 2.23723129e-05, 2.27799107e-05, 2.39695592e-05, 2.66405614e-05, - 2.75052840e-05, 2.68491083e-05, 2.30642263e-05, 1.97525808e-05, - 2.07684784e-05, 2.47198577e-05, 2.74878633e-05, 2.75128950e-05, - 2.70828967e-05, 2.52891350e-05, 2.28657512e-05, 2.09416574e-05, - 2.15524742e-05, 2.39744971e-05, 2.55782368e-05, 2.67128487e-05, - 2.77759598e-05, - 2.51830931e-05, 3.37618581e-05, 3.58803222e-05, 3.15163378e-05, - 2.49670590e-05, 1.92500339e-05, 1.65605641e-05, 1.63743299e-05, - 1.65395682e-05, 2.41393982e-05, 2.92496787e-05, 2.76698148e-05, - 2.46805440e-05, 2.42051735e-05, 2.32938966e-05, 1.95314104e-05, - 1.67123711e-05, 1.70244264e-05, 1.74662991e-05, 1.62972740e-05, - 2.72070614e-05, 3.27249486e-05, 3.19679770e-05, 2.61608022e-05, - 2.31551264e-05, 2.23387835e-05, 1.83974573e-05, 1.52165948e-05, - 1.43185228e-05, 3.21126272e-05, 4.29443857e-05, 3.84454374e-05, - 2.43020883e-05, 1.70237122e-05, 1.61461314e-05, 1.60013285e-05, - 1.54115193e-05, 1.53009680e-05, 2.34834626e-05, 3.32447063e-05, - 3.63944664e-05, 2.75930835e-05, 2.10366102e-05, 2.09215319e-05, - 2.12908541e-05, 1.85071607e-05, 1.56883728e-05, 1.73195467e-05, - 2.34708959e-05, 3.60827406e-05, 4.27923302e-05, 3.61633128e-05, - 2.46212350e-05, 1.62108977e-05, 1.39004861e-05, 1.46465788e-05, - 3.10455225e-05, 3.97418823e-05, 3.74937352e-05, 2.82154118e-05, - 1.93370442e-05, 1.45162079e-05, 1.34798994e-05, 1.48382684e-05, - 3.41246825e-05, 4.18838020e-05, 3.77724661e-05, 2.71159814e-05, - 1.68061805e-05, 1.33899501e-05, 1.43643612e-05, 1.56208647e-05, - 3.60543432e-05, 4.54748596e-05, 3.51870797e-05, 2.41679786e-05, - 1.99994833e-05, 1.80726684e-05, 1.64897138e-05, 2.83132924e-05, - 3.36700862e-05, 3.46340973e-05, 3.16794472e-05, 2.30670376e-05, - 1.65252270e-05, 1.53367413e-05, 1.58888813e-05, 2.69171625e-05, - 3.19889399e-05, 3.16523208e-05, 2.78385242e-05, 2.46591234e-05, - 2.19983874e-05, 1.77542487e-05, 1.60588467e-05, 2.56354032e-05, - 3.20849441e-05, 3.18435344e-05, 2.94625844e-05, 2.73582077e-05, - 2.25237323e-05, 1.78710979e-05, 1.57176519e-05, 1.58256707e-05, - 2.27602057e-05, 3.32867675e-05, 4.40930174e-05, 4.11756057e-05, - 2.89225236e-05, 1.75914287e-05, 1.50659788e-05, 1.77885523e-05, - 3.03003054e-05, 3.60155891e-05, 3.12905505e-05, 2.39219189e-05, - 2.20697547e-05, 2.02731358e-05, 1.69753841e-05, 1.61050734e-05, - 2.25105770e-05, 3.08600153e-05, 3.67822137e-05, 3.08699225e-05, - 2.42152512e-05, 1.88927287e-05, 1.61844784e-05, 1.61737668e-05, - 2.51616905e-05, 3.20688157e-05, 3.31841531e-05, 2.82787132e-05, - 2.31305544e-05, 1.94747453e-05, 1.60976645e-05, 1.68367058e-05, - 1.82443371e-05, 2.50259631e-05, 3.58331694e-05, 4.10312196e-05, - 3.20561122e-05, 2.14825734e-05, 1.67551262e-05, 1.43136846e-05, - 1.40626959e-05, 1.53637317e-05, 2.81175672e-05, 3.34448885e-05, - 3.37728694e-05, 2.65969938e-05, 1.91932369e-05, 1.94276547e-05, - 1.75842234e-05, 1.49042668e-05, 2.72896935e-05, 3.22760405e-05, - 3.25618384e-05, 3.05967641e-05, 2.65560810e-05, 1.96145661e-05, - 1.67360516e-05, 1.75085077e-05, 3.11366811e-05, 3.97717639e-05, - 3.54828057e-05, 2.38999560e-05, 1.62181388e-05, 1.60339387e-05, - 1.68852670e-05, 2.46664931e-05, 3.13031555e-05, 3.55564105e-05, - 3.31265558e-05, 2.56748892e-05, 2.07352650e-05, 1.78960467e-05, - 1.53724404e-05, - 2.54147976e-05, 3.27620580e-05, 3.45122319e-05, 3.06552624e-05, - 2.49298562e-05, 1.99486707e-05, 1.75209852e-05, 1.73945499e-05, - 1.76193490e-05, 2.45401802e-05, 2.90142366e-05, 2.76717616e-05, - 2.49511963e-05, 2.45136046e-05, 2.37173624e-05, 2.02224337e-05, - 1.76117087e-05, 1.79924358e-05, 1.84684327e-05, 1.73783339e-05, - 2.70982167e-05, 3.18080398e-05, 3.13157455e-05, 2.61790983e-05, - 2.34702590e-05, 2.28931605e-05, 1.93447069e-05, 1.63186732e-05, - 1.54537765e-05, 3.13222925e-05, 4.00863762e-05, 3.65676894e-05, - 2.43454490e-05, 1.77101463e-05, 1.70983513e-05, 1.71056109e-05, - 1.65402262e-05, 1.64259391e-05, 2.35475161e-05, 3.18611146e-05, - 3.47493389e-05, 2.73121429e-05, 2.15540220e-05, 2.16717641e-05, - 2.21628029e-05, 1.95552683e-05, 1.68456860e-05, 1.80844164e-05, - 2.35859508e-05, 3.45709785e-05, 4.02082272e-05, 3.47514808e-05, - 2.48520000e-05, 1.72111245e-05, 1.50790745e-05, 1.58239288e-05, - 3.05679432e-05, 3.74746514e-05, 3.55661056e-05, 2.77684849e-05, - 1.99536385e-05, 1.55266541e-05, 1.45960718e-05, 1.59710887e-05, - 3.32926198e-05, 3.91531202e-05, 3.56922038e-05, 2.68505517e-05, - 1.76386820e-05, 1.44924686e-05, 1.55329158e-05, 1.67425977e-05, - 3.45163331e-05, 4.18278541e-05, 3.34949503e-05, 2.40979526e-05, - 2.06558392e-05, 1.91648456e-05, 1.76733953e-05, 2.79724884e-05, - 3.22452080e-05, 3.31507807e-05, 3.10193579e-05, 2.36572953e-05, - 1.75813000e-05, 1.64613535e-05, 1.69972585e-05, 2.67721497e-05, - 3.09378749e-05, 3.06949079e-05, 2.75316636e-05, 2.49718881e-05, - 2.27762728e-05, 1.88079833e-05, 1.71589128e-05, 2.56675217e-05, - 3.11698404e-05, 3.09929019e-05, 2.88683350e-05, 2.71916519e-05, - 2.31251836e-05, 1.89030365e-05, 1.68410800e-05, 1.69371881e-05, - 2.26896946e-05, 3.14983649e-05, 4.07536152e-05, 3.89953333e-05, - 2.90432780e-05, 1.87232697e-05, 1.62425340e-05, 1.89466390e-05, - 2.96664001e-05, 3.41159876e-05, 3.02928498e-05, 2.40447683e-05, - 2.25480486e-05, 2.10887796e-05, 1.80221089e-05, 1.71869866e-05, - 2.25050711e-05, 2.98441357e-05, 3.51449560e-05, 3.02828381e-05, - 2.45386401e-05, 1.98241028e-05, 1.73094611e-05, 1.72576300e-05, - 2.52981626e-05, 3.11176105e-05, 3.20419968e-05, 2.78147672e-05, - 2.33787898e-05, 2.02420362e-05, 1.71593853e-05, 1.79314861e-05, - 1.93385351e-05, 2.49891271e-05, 3.41662960e-05, 3.87228587e-05, - 3.13614776e-05, 2.19805468e-05, 1.76662986e-05, 1.54452495e-05, - 1.52321489e-05, 1.64971573e-05, 2.74899208e-05, 3.16728050e-05, - 3.22792875e-05, 2.64856226e-05, 2.00601766e-05, 2.06005344e-05, - 1.88445592e-05, 1.61208643e-05, 2.72539555e-05, 3.11026588e-05, - 3.12484070e-05, 2.98546985e-05, 2.66009858e-05, 2.03571393e-05, - 1.77276616e-05, 1.85775209e-05, 2.99793240e-05, 3.68439494e-05, - 3.39971132e-05, 2.43773392e-05, 1.72935784e-05, 1.71285137e-05, - 1.79810464e-05, 2.46497593e-05, 3.02074975e-05, 3.38972246e-05, - 3.21435017e-05, 2.59940223e-05, 2.16321477e-05, 1.89436163e-05, - 1.64829272e-05, - 2.47351001e-05, 3.67504912e-05, 3.99897313e-05, 3.30521101e-05, - 2.40042980e-05, 1.72401871e-05, 1.42903466e-05, 1.41489490e-05, - 1.44225202e-05, 2.34638912e-05, 3.03236017e-05, 2.81783195e-05, - 2.40533090e-05, 2.34178345e-05, 2.22850397e-05, 1.75893208e-05, - 1.43903309e-05, 1.48523965e-05, 1.54319035e-05, 1.41381598e-05, - 2.72735011e-05, 3.50498015e-05, 3.41915553e-05, 2.58689017e-05, - 2.19274227e-05, 2.11407511e-05, 1.65060765e-05, 1.29162800e-05, - 1.19529836e-05, 3.42008204e-05, 5.14936896e-05, 4.40082627e-05, - 2.31586016e-05, 1.44853414e-05, 1.37935117e-05, 1.38221380e-05, - 1.31726866e-05, 1.30416223e-05, 2.20219974e-05, 3.51541236e-05, - 4.04499402e-05, 2.76000682e-05, 1.93160439e-05, 1.94961235e-05, - 2.01734443e-05, 1.67838224e-05, 1.35282195e-05, 1.49399256e-05, - 2.20785748e-05, 4.01055138e-05, 5.17297931e-05, 4.04448459e-05, - 2.39050830e-05, 1.39311797e-05, 1.15489447e-05, 1.23701312e-05, - 3.29090499e-05, 4.58734276e-05, 4.20374947e-05, 2.83131198e-05, - 1.72388936e-05, 1.20162757e-05, 1.10183272e-05, 1.25282399e-05, - 3.77172056e-05, 4.94449731e-05, 4.22950240e-05, 2.68839605e-05, - 1.44148355e-05, 1.09057057e-05, 1.20453577e-05, 1.34040022e-05, - 4.00031979e-05, 5.55735880e-05, 3.81080853e-05, 2.27987041e-05, - 1.81457196e-05, 1.63015047e-05, 1.45020146e-05, 2.86390102e-05, - 3.58351528e-05, 3.74670689e-05, 3.36781954e-05, 2.22154848e-05, - 1.43741593e-05, 1.30819612e-05, 1.36966448e-05, 2.67673919e-05, - 3.35382159e-05, 3.31205705e-05, 2.79432100e-05, 2.40869233e-05, - 2.10029252e-05, 1.58544732e-05, 1.38837215e-05, 2.50992767e-05, - 3.39363244e-05, 3.36307960e-05, 3.00751247e-05, 2.74162967e-05, - 2.14681754e-05, 1.59685800e-05, 1.35178747e-05, 1.36273898e-05, - 2.08230396e-05, 3.45463486e-05, 5.30569299e-05, 4.90507824e-05, - 3.03951359e-05, 1.57616940e-05, 1.28409085e-05, 1.60408111e-05, - 3.13874906e-05, 3.92730838e-05, 3.24385909e-05, 2.27308258e-05, - 2.06578647e-05, 1.87291660e-05, 1.48983460e-05, 1.39139490e-05, - 2.05715682e-05, 3.16859519e-05, 4.12060496e-05, 3.24219049e-05, - 2.34552982e-05, 1.71079830e-05, 1.40635541e-05, 1.39968814e-05, - 2.45556410e-05, 3.38463167e-05, 3.54651256e-05, 2.83860318e-05, - 2.17943604e-05, 1.76223242e-05, 1.38789024e-05, 1.47964440e-05, - 1.65184772e-05, 2.40911975e-05, 3.93512453e-05, 4.84802933e-05, - 3.42702406e-05, 1.98868805e-05, 1.44564330e-05, 1.19430400e-05, - 1.17146178e-05, 1.31241339e-05, 2.78733573e-05, 3.48490804e-05, - 3.58991904e-05, 2.63292013e-05, 1.74006552e-05, 1.81399533e-05, - 1.59313402e-05, 1.27096016e-05, 2.75199180e-05, 3.38249871e-05, - 3.40819855e-05, 3.17005291e-05, 2.65139695e-05, 1.77677789e-05, - 1.45392314e-05, 1.55740670e-05, 3.19161548e-05, 4.46776248e-05, - 3.90264516e-05, 2.32349375e-05, 1.40378368e-05, 1.38474606e-05, - 1.48559618e-05, 2.35964624e-05, 3.22970875e-05, 3.88491554e-05, - 3.56429597e-05, 2.56100334e-05, 1.94607781e-05, 1.60208470e-05, - 1.31045479e-05, - 2.07418151e-05, 4.36473537e-05, 5.13924472e-05, 3.69671880e-05, - 2.07930657e-05, 1.11031523e-05, 7.82417204e-06, 7.58611597e-06, - 7.70085468e-06, 1.86437692e-05, 2.99635370e-05, 2.60152848e-05, - 1.97794491e-05, 1.88942512e-05, 1.72069435e-05, 1.14634448e-05, - 8.03300651e-06, 8.29428922e-06, 8.73254796e-06, 7.45912537e-06, - 2.52525539e-05, 4.04158785e-05, 3.76815217e-05, 2.29336746e-05, - 1.71391579e-05, 1.55291044e-05, 9.82380438e-06, 6.42286483e-06, - 5.61708204e-06, 3.84016739e-05, 8.57660380e-05, 6.22595513e-05, - 1.94788559e-05, 8.55926146e-06, 7.41883021e-06, 7.15247383e-06, - 6.57994964e-06, 6.48194700e-06, 1.80570473e-05, 4.31486314e-05, - 5.39779719e-05, 2.63846642e-05, 1.36756237e-05, 1.32306183e-05, - 1.36031494e-05, 9.85335117e-06, 6.81426405e-06, 8.79856729e-06, - 1.79561086e-05, 5.25003868e-05, 8.39086572e-05, 5.24808843e-05, - 1.97371556e-05, 7.44159692e-06, 5.24401616e-06, 5.86567363e-06, - 3.48542011e-05, 6.88299887e-05, 5.88183105e-05, 2.80583318e-05, - 1.13037564e-05, 5.87491922e-06, 4.95167365e-06, 6.06370489e-06, - 4.43172707e-05, 8.01022750e-05, 6.03696113e-05, 2.53592175e-05, - 8.19093951e-06, 4.89068415e-06, 5.63232269e-06, 6.77871965e-06, - 5.24820339e-05, 1.02914629e-04, 5.00590727e-05, 1.94340733e-05, - 1.21036823e-05, 9.31697898e-06, 7.56585885e-06, 2.80581535e-05, - 4.45256426e-05, 4.76601383e-05, 3.69246227e-05, 1.66124095e-05, - 7.70640390e-06, 6.51475593e-06, 7.04165506e-06, 2.47262768e-05, - 3.87097732e-05, 3.75653255e-05, 2.69581954e-05, 1.96765913e-05, - 1.47347140e-05, 8.99879859e-06, 7.21125106e-06, 2.19076515e-05, - 3.86304301e-05, 3.78166835e-05, 3.12118875e-05, 2.56731349e-05, - 1.57494289e-05, 9.14767404e-06, 6.86792149e-06, 6.97913331e-06, - 1.70975769e-05, 4.44579971e-05, 9.37914592e-05, 7.47489148e-05, - 2.85364604e-05, 8.75160163e-06, 6.23253627e-06, 8.94299101e-06, - 3.33235379e-05, 5.34772379e-05, 3.67071709e-05, 1.86985015e-05, - 1.52244858e-05, 1.22805572e-05, 8.17359187e-06, 7.27066385e-06, - 1.66006099e-05, 3.56353939e-05, 5.53148680e-05, 3.46480884e-05, - 1.88889056e-05, 1.04217966e-05, 7.31296756e-06, 7.33586008e-06, - 2.08567065e-05, 3.86760290e-05, 4.23140917e-05, 2.82327759e-05, - 1.71981501e-05, 1.13073991e-05, 7.27995296e-06, 7.98931157e-06, - 9.50875917e-06, 2.08992821e-05, 5.21235790e-05, 7.45623602e-05, - 3.80199021e-05, 1.43350058e-05, 8.06622844e-06, 5.61561189e-06, - 5.38183084e-06, 6.53267839e-06, 2.82229925e-05, 4.48767259e-05, - 4.50316036e-05, 2.40208348e-05, 1.08518072e-05, 1.08323883e-05, - 8.63355461e-06, 6.06119095e-06, 2.52894303e-05, 3.98162072e-05, - 4.09912384e-05, 3.43098102e-05, 2.36614241e-05, 1.15108702e-05, - 7.97523731e-06, 8.71772215e-06, 3.67088049e-05, 7.15100156e-05, - 5.04085823e-05, 1.81279201e-05, 7.38609136e-06, 7.19164953e-06, - 8.03829086e-06, 2.02190717e-05, 3.69869066e-05, 5.11735308e-05, - 4.17328974e-05, 2.15100706e-05, 1.28075931e-05, 9.16093109e-06, - 6.55809142e-06, - 2.33396405e-05, 3.87179790e-05, 4.31752335e-05, 3.51806770e-05, - 2.39720951e-05, 1.52896567e-05, 1.18455451e-05, 1.15194958e-05, - 1.15464631e-05, 2.15875209e-05, 2.98895296e-05, 2.70939928e-05, - 2.26245962e-05, 2.19509878e-05, 2.05456197e-05, 1.56105327e-05, - 1.21443968e-05, 1.22940738e-05, 1.26600262e-05, 1.13033643e-05, - 2.69107588e-05, 3.69945405e-05, 3.49415910e-05, 2.52074886e-05, - 2.07193594e-05, 1.90737332e-05, 1.37500141e-05, 1.02003769e-05, - 9.27182656e-06, 3.56764772e-05, 6.06656347e-05, 4.91037465e-05, - 2.29193670e-05, 1.29938309e-05, 1.14512927e-05, 1.09594050e-05, - 1.03305926e-05, 1.02318797e-05, 2.18981763e-05, 3.96611370e-05, - 4.51271593e-05, 2.79937793e-05, 1.77322315e-05, 1.69510596e-05, - 1.70243914e-05, 1.36155874e-05, 1.05365171e-05, 1.30963903e-05, - 2.17172905e-05, 4.40915389e-05, 5.90071647e-05, 4.37598149e-05, - 2.26824289e-05, 1.14035307e-05, 8.79026397e-06, 9.49382279e-06, - 3.30713691e-05, 5.28580249e-05, 4.79837301e-05, 2.93715744e-05, - 1.56057619e-05, 9.72784884e-06, 8.52698239e-06, 9.77053339e-06, - 3.85207279e-05, 5.83882219e-05, 4.91096312e-05, 2.73529271e-05, - 1.24026844e-05, 8.47161189e-06, 9.24547304e-06, 1.05489590e-05, - 4.41697294e-05, 6.89701123e-05, 4.36740412e-05, 2.31424023e-05, - 1.62082886e-05, 1.30630820e-05, 1.12626136e-05, 2.91017382e-05, - 4.04123635e-05, 4.19742676e-05, 3.45954416e-05, 1.97902751e-05, - 1.15866905e-05, 1.02672178e-05, 1.08400448e-05, 2.66837879e-05, - 3.65771410e-05, 3.57497310e-05, 2.83899833e-05, 2.24662559e-05, - 1.80586575e-05, 1.28296554e-05, 1.10253511e-05, 2.45322278e-05, - 3.61433144e-05, 3.55657295e-05, 3.14930010e-05, 2.72978082e-05, - 1.91445809e-05, 1.30010555e-05, 1.06394297e-05, 1.07712283e-05, - 2.15102419e-05, 4.15523340e-05, 6.50561412e-05, 5.45472703e-05, - 2.82358471e-05, 1.24805506e-05, 9.89493072e-06, 1.26190387e-05, - 3.27121015e-05, 4.57827119e-05, 3.54440737e-05, 2.22147883e-05, - 1.89954307e-05, 1.60716577e-05, 1.20583930e-05, 1.11117472e-05, - 2.10075922e-05, 3.49611479e-05, 4.56331671e-05, 3.32629170e-05, - 2.19157934e-05, 1.43056721e-05, 1.10929927e-05, 1.11750368e-05, - 2.36236667e-05, 3.62696079e-05, 3.85401828e-05, 2.95137834e-05, - 2.09001289e-05, 1.53453511e-05, 1.11502310e-05, 1.18080102e-05, - 1.32340410e-05, 2.40405858e-05, 4.44473632e-05, 5.49618746e-05, - 3.52231539e-05, 1.82823007e-05, 1.21589061e-05, 9.27500492e-06, - 8.96036667e-06, 1.02740957e-05, 2.99337043e-05, 4.16871027e-05, - 4.08555615e-05, 2.61778118e-05, 1.47859112e-05, 1.42691401e-05, - 1.21794564e-05, 9.65624498e-06, 2.67584769e-05, 3.74688523e-05, - 3.84475145e-05, 3.35154463e-05, 2.55935012e-05, 1.55605186e-05, - 1.19476965e-05, 1.25437849e-05, 3.59113091e-05, 5.63192692e-05, - 4.31460546e-05, 2.10773455e-05, 1.12379391e-05, 1.10132138e-05, - 1.18542221e-05, 2.35480989e-05, 3.58676650e-05, 4.40303350e-05, - 3.77991243e-05, 2.36414158e-05, 1.63546642e-05, 1.29890449e-05, - 1.03326346e-05, - 2.53445709e-05, 2.74058533e-05, 2.77246684e-05, 2.74855485e-05, - 2.60201887e-05, 2.33936720e-05, 2.18266316e-05, 2.15710662e-05, - 2.14474221e-05, 2.48732032e-05, 2.63388411e-05, 2.58819939e-05, - 2.52309125e-05, 2.51134462e-05, 2.47551030e-05, 2.34773124e-05, - 2.20711305e-05, 2.19652947e-05, 2.20076457e-05, 2.13514435e-05, - 2.61648672e-05, 2.74142447e-05, 2.69598668e-05, 2.58810960e-05, - 2.50288788e-05, 2.43146521e-05, 2.24515443e-05, 2.08363941e-05, - 2.03027180e-05, 2.72392075e-05, 2.84459203e-05, 2.80781416e-05, - 2.58000536e-05, 2.28399035e-05, 2.16993131e-05, 2.11618713e-05, - 2.08365205e-05, 2.07998925e-05, 2.57131324e-05, 2.83235476e-05, - 2.81622457e-05, 2.65599646e-05, 2.42421286e-05, 2.35786975e-05, - 2.33096990e-05, 2.21870541e-05, 2.08646648e-05, 2.26865636e-05, - 2.55777530e-05, 2.79686040e-05, 2.80084837e-05, 2.77471876e-05, - 2.53300292e-05, 2.15720639e-05, 1.99409551e-05, 2.03255676e-05, - 2.67002864e-05, 2.84415976e-05, 2.84400579e-05, 2.69143491e-05, - 2.36517691e-05, 2.08163767e-05, 1.99250058e-05, 2.05632457e-05, - 2.69861639e-05, 2.85961157e-05, 2.86642883e-05, 2.65470179e-05, - 2.23120595e-05, 1.99221561e-05, 2.02149517e-05, 2.09490625e-05, - 2.80286496e-05, 2.88362690e-05, 2.85513147e-05, 2.60907437e-05, - 2.36722774e-05, 2.19297726e-05, 2.11075184e-05, 2.66561400e-05, - 2.83257897e-05, 2.82433625e-05, 2.70186566e-05, 2.42983507e-05, - 2.15156348e-05, 2.08168532e-05, 2.11032656e-05, 2.62629874e-05, - 2.78299325e-05, 2.76778215e-05, 2.66074585e-05, 2.51233386e-05, - 2.36736772e-05, 2.19447130e-05, 2.11982331e-05, 2.58492770e-05, - 2.75160597e-05, 2.74127491e-05, 2.71453720e-05, 2.62973425e-05, - 2.42106969e-05, 2.20461562e-05, 2.09845636e-05, 2.10673353e-05, - 2.60351031e-05, 2.91878216e-05, 2.88643914e-05, 2.78229042e-05, - 2.55443430e-05, 2.16591443e-05, 2.05270624e-05, 2.16457289e-05, - 2.71414872e-05, 2.87741125e-05, 2.78235513e-05, 2.55795759e-05, - 2.44876655e-05, 2.32762225e-05, 2.17068578e-05, 2.12737022e-05, - 2.58427054e-05, 2.79295455e-05, 2.80491446e-05, 2.69658781e-05, - 2.50756199e-05, 2.26310704e-05, 2.11701039e-05, 2.12946295e-05, - 2.55832738e-05, 2.75976836e-05, 2.78167686e-05, 2.69497644e-05, - 2.52039871e-05, 2.32451365e-05, 2.13343397e-05, 2.15103582e-05, - 2.19757742e-05, 2.60198249e-05, 2.83444223e-05, 2.81071282e-05, - 2.70392551e-05, 2.43596494e-05, 2.20489974e-05, 2.03125966e-05, - 2.00573405e-05, 2.08004039e-05, 2.73524397e-05, 2.91178851e-05, - 2.84507504e-05, 2.61910269e-05, 2.28926410e-05, 2.20801690e-05, - 2.12753346e-05, 2.03215883e-05, 2.59862473e-05, 2.80491510e-05, - 2.83033320e-05, 2.73487498e-05, 2.58106417e-05, 2.33467863e-05, - 2.17923018e-05, 2.18198752e-05, 2.82053098e-05, 2.96899222e-05, - 2.80565802e-05, 2.46613349e-05, 2.13383749e-05, 2.12055489e-05, - 2.15247808e-05, 2.59636170e-05, 2.80404056e-05, 2.83954526e-05, - 2.74864681e-05, 2.51378450e-05, 2.31410291e-05, 2.20073831e-05, - 2.08779860e-05, - 2.44602374e-05, 2.12228338e-05, 2.04198793e-05, 2.24322496e-05, - 2.51760101e-05, 2.69672636e-05, 2.76592955e-05, 2.75447333e-05, - 2.72480835e-05, 2.47364174e-05, 2.28186848e-05, 2.33687947e-05, - 2.46907584e-05, 2.49048789e-05, 2.52084399e-05, 2.68204167e-05, - 2.77910690e-05, 2.73845151e-05, 2.70321321e-05, 2.73654595e-05, - 2.38750519e-05, 2.17503661e-05, 2.18155793e-05, 2.42891729e-05, - 2.55524476e-05, 2.54798269e-05, 2.67020423e-05, 2.78130670e-05, - 2.80871138e-05, 2.19418503e-05, 1.78274569e-05, 1.94850917e-05, - 2.54354515e-05, 2.83418306e-05, 2.79087817e-05, 2.74274634e-05, - 2.76186467e-05, 2.76848039e-05, 2.59258636e-05, 2.21097997e-05, - 2.04649617e-05, 2.39571727e-05, 2.63798749e-05, 2.58246275e-05, - 2.52817057e-05, 2.63253369e-05, 2.73800723e-05, 2.79045098e-05, - 2.58167338e-05, 2.04851352e-05, 1.76389818e-05, 2.03029280e-05, - 2.48161723e-05, 2.77012177e-05, 2.80795613e-05, 2.77723686e-05, - 2.21098560e-05, 1.91447593e-05, 2.01352520e-05, 2.38619503e-05, - 2.71558855e-05, 2.85095958e-05, 2.85213904e-05, 2.78667393e-05, - 2.07530295e-05, 1.83395300e-05, 2.01473582e-05, 2.42369867e-05, - 2.79703199e-05, 2.86184620e-05, 2.79294708e-05, 2.75461861e-05, - 2.05374714e-05, 1.70555282e-05, 2.12896999e-05, 2.57744158e-05, - 2.66370325e-05, 2.64156034e-05, 2.69027219e-05, 2.36041519e-05, - 2.18944438e-05, 2.13590906e-05, 2.20089423e-05, 2.49484111e-05, - 2.73394826e-05, 2.76694485e-05, 2.74671839e-05, 2.41313675e-05, - 2.24251599e-05, 2.24967007e-05, 2.38473289e-05, 2.46110629e-05, - 2.51176103e-05, 2.67082482e-05, 2.74147291e-05, 2.45966441e-05, - 2.21535285e-05, 2.22067972e-05, 2.33137020e-05, 2.38900293e-05, - 2.52499265e-05, 2.67174803e-05, 2.74935986e-05, 2.74861664e-05, - 2.67227853e-05, 2.26574059e-05, 1.76046441e-05, 1.81766836e-05, - 2.23744410e-05, 2.65346818e-05, 2.75911064e-05, 2.63475148e-05, - 2.28414704e-05, 2.10325951e-05, 2.27942236e-05, 2.55051705e-05, - 2.58369621e-05, 2.60247447e-05, 2.71401279e-05, 2.74582778e-05, - 2.67381568e-05, 2.31042710e-05, 2.02131759e-05, 2.24008951e-05, - 2.48647650e-05, 2.64752224e-05, 2.72621960e-05, 2.74169991e-05, - 2.46784857e-05, 2.22197278e-05, 2.17962286e-05, 2.38517515e-05, - 2.57264647e-05, 2.66314085e-05, 2.75356891e-05, 2.70448879e-05, - 2.63190219e-05, 2.51367193e-05, 2.08459679e-05, 1.84047137e-05, - 2.18273437e-05, 2.61528017e-05, 2.77264969e-05, 2.81045152e-05, - 2.80522120e-05, 2.76228916e-05, 2.42552729e-05, 2.25300542e-05, - 2.19255023e-05, 2.42710205e-05, 2.64998233e-05, 2.54559915e-05, - 2.61098108e-05, 2.75034418e-05, 2.36804715e-05, 2.24261841e-05, - 2.24502789e-05, 2.28307085e-05, 2.39843234e-05, 2.66208270e-05, - 2.74567174e-05, 2.67867632e-05, 2.31464631e-05, 1.98572147e-05, - 2.08257649e-05, 2.47080981e-05, 2.74254075e-05, 2.74471254e-05, - 2.70167714e-05, 2.53286903e-05, 2.29402372e-05, 2.10108955e-05, - 2.15966926e-05, 2.39676792e-05, 2.55321558e-05, 2.66533062e-05, - 2.77069901e-05, - 2.38383199e-05, 1.90447624e-05, 1.79840504e-05, 2.04617580e-05, - 2.44292699e-05, 2.80224771e-05, 2.98349171e-05, 2.98350057e-05, - 2.95097450e-05, 2.44030154e-05, 2.13768725e-05, 2.22423665e-05, - 2.41800954e-05, 2.45045093e-05, 2.50582995e-05, 2.77853681e-05, - 2.98650595e-05, 2.93841381e-05, 2.88879883e-05, 2.97263615e-05, - 2.27494819e-05, 1.96711841e-05, 1.99172925e-05, 2.33858394e-05, - 2.53644908e-05, 2.56186981e-05, 2.81944729e-05, 3.06537996e-05, - 3.13736042e-05, 1.99651402e-05, 1.47700946e-05, 1.67772957e-05, - 2.48543048e-05, 3.01420685e-05, 3.02470419e-05, 2.99262445e-05, - 3.03886519e-05, 3.05019802e-05, 2.55104651e-05, 1.97688229e-05, - 1.78904163e-05, 2.26838606e-05, 2.68122048e-05, 2.64349062e-05, - 2.58665540e-05, 2.78425945e-05, 3.00458697e-05, 2.96534430e-05, - 2.54372104e-05, 1.79786797e-05, 1.46806780e-05, 1.78390372e-05, - 2.42926639e-05, 3.00452040e-05, 3.16032243e-05, 3.09258582e-05, - 2.03710596e-05, 1.62717899e-05, 1.74154026e-05, 2.24196370e-05, - 2.81284440e-05, 3.16164964e-05, 3.22252923e-05, 3.09016410e-05, - 1.86334989e-05, 1.53067798e-05, 1.73571873e-05, 2.30337627e-05, - 2.99608645e-05, 3.23615366e-05, 3.12143054e-05, 3.02193995e-05, - 1.80198939e-05, 1.37980449e-05, 1.87238671e-05, 2.51440244e-05, - 2.74421702e-05, 2.81086326e-05, 2.92477861e-05, 2.22104646e-05, - 1.95135641e-05, 1.89115330e-05, 2.01282990e-05, 2.49454904e-05, - 2.95919070e-05, 3.04703213e-05, 3.00162592e-05, 2.30246285e-05, - 2.03242519e-05, 2.04666833e-05, 2.25289839e-05, 2.41288725e-05, - 2.54696721e-05, 2.84913791e-05, 2.98866399e-05, 2.37831026e-05, - 2.01161119e-05, 2.02184828e-05, 2.16580096e-05, 2.27118172e-05, - 2.53747032e-05, 2.84453654e-05, 3.01257376e-05, 3.00642578e-05, - 2.63573248e-05, 2.01031266e-05, 1.44028645e-05, 1.53475239e-05, - 2.11508566e-05, 2.84239836e-05, 3.05472622e-05, 2.81803634e-05, - 2.10870238e-05, 1.83482514e-05, 2.07680240e-05, 2.50442403e-05, - 2.59910252e-05, 2.68534769e-05, 2.92093432e-05, 2.98993458e-05, - 2.64697569e-05, 2.10990276e-05, 1.76336711e-05, 2.06217521e-05, - 2.44713671e-05, 2.77939849e-05, 2.96971414e-05, 2.98306859e-05, - 2.40045447e-05, 2.01650310e-05, 1.95796581e-05, 2.23925826e-05, - 2.55011893e-05, 2.76636541e-05, 2.99669378e-05, 2.91980073e-05, - 2.79534050e-05, 2.43804201e-05, 1.82749123e-05, 1.55244553e-05, - 1.99018639e-05, 2.64603007e-05, 2.97919350e-05, 3.13910407e-05, - 3.14877526e-05, 3.04171999e-05, 2.27186627e-05, 1.99788704e-05, - 1.95057819e-05, 2.32284557e-05, 2.76825918e-05, 2.67449078e-05, - 2.80749252e-05, 3.05587007e-05, 2.25844626e-05, 2.02442166e-05, - 2.01793857e-05, 2.09935800e-05, 2.30370569e-05, 2.75949725e-05, - 2.95836367e-05, 2.86687939e-05, 2.10442633e-05, 1.67038923e-05, - 1.83487108e-05, 2.44661379e-05, 2.98153586e-05, 2.99260456e-05, - 2.91515290e-05, 2.46456127e-05, 2.08605451e-05, 1.84506352e-05, - 1.94613876e-05, 2.33117450e-05, 2.62803969e-05, 2.83819039e-05, - 3.04829358e-05, - 2.40463549e-05, 1.97437267e-05, 1.87591693e-05, 2.11705545e-05, - 2.48126109e-05, 2.77424818e-05, 2.91184531e-05, 2.90399341e-05, - 2.86725354e-05, 2.44931998e-05, 2.18264316e-05, 2.25822436e-05, - 2.43605281e-05, 2.46564102e-05, 2.51204386e-05, 2.75256382e-05, - 2.92244319e-05, 2.87025605e-05, 2.82126903e-05, 2.88623585e-05, - 2.31561098e-05, 2.03671097e-05, 2.05143092e-05, 2.37254600e-05, - 2.55010631e-05, 2.55678496e-05, 2.76430466e-05, 2.96425564e-05, - 3.02040072e-05, 2.06218828e-05, 1.57314416e-05, 1.76371266e-05, - 2.51866557e-05, 2.97466780e-05, 2.94991177e-05, 2.90063793e-05, - 2.93735565e-05, 2.94769510e-05, 2.58307263e-05, 2.06589498e-05, - 1.87532110e-05, 2.31850228e-05, 2.67538723e-05, 2.61896341e-05, - 2.55473765e-05, 2.72123897e-05, 2.90354701e-05, 2.91969157e-05, - 2.57201732e-05, 1.88022579e-05, 1.55689698e-05, 1.86204125e-05, - 2.44987295e-05, 2.92538916e-05, 3.03202390e-05, 2.97565686e-05, - 2.09080475e-05, 1.72066740e-05, 1.83368520e-05, 2.30037532e-05, - 2.79253875e-05, 3.06187732e-05, 3.09493165e-05, 2.98077041e-05, - 1.92513536e-05, 1.62844429e-05, 1.83225941e-05, 2.35341004e-05, - 2.93967171e-05, 3.10878261e-05, 3.00137733e-05, 2.92372339e-05, - 1.88550017e-05, 1.48446346e-05, 1.96609657e-05, 2.55572777e-05, - 2.72329494e-05, 2.74049239e-05, 2.83054043e-05, 2.27324760e-05, - 2.04036308e-05, 1.97847535e-05, 2.07363845e-05, 2.48882875e-05, - 2.87764563e-05, 2.94501757e-05, 2.90793951e-05, 2.34559218e-05, - 2.11085885e-05, 2.12178107e-05, 2.30407107e-05, 2.42819727e-05, - 2.52482703e-05, 2.77939432e-05, 2.89775038e-05, 2.41169213e-05, - 2.08320813e-05, 2.09117388e-05, 2.22921059e-05, 2.31501295e-05, - 2.52952335e-05, 2.77774275e-05, 2.91534334e-05, 2.91168672e-05, - 2.67850119e-05, 2.11832087e-05, 1.54426262e-05, 1.61879946e-05, - 2.14228232e-05, 2.76422772e-05, 2.94369897e-05, 2.73941926e-05, - 2.17190689e-05, 1.93312414e-05, 2.15523130e-05, 2.53217347e-05, - 2.59896074e-05, 2.65269609e-05, 2.84473975e-05, 2.90136283e-05, - 2.68475955e-05, 2.19091200e-05, 1.84767798e-05, 2.12155568e-05, - 2.46134387e-05, 2.72911962e-05, 2.87772540e-05, 2.89505316e-05, - 2.42730578e-05, 2.08986385e-05, 2.03615710e-05, 2.29849204e-05, - 2.56858318e-05, 2.73356375e-05, 2.91008555e-05, 2.83767476e-05, - 2.72625910e-05, 2.47630391e-05, 1.91713503e-05, 1.64114651e-05, - 2.05160498e-05, 2.64295310e-05, 2.91430154e-05, 3.02249501e-05, - 3.02406757e-05, 2.93911685e-05, 2.34105956e-05, 2.10421821e-05, - 2.04223762e-05, 2.36433118e-05, 2.72539025e-05, 2.60863484e-05, - 2.71811485e-05, 2.93838366e-05, 2.29482394e-05, 2.10763397e-05, - 2.10667773e-05, 2.16721987e-05, 2.33586444e-05, 2.72951481e-05, - 2.88524832e-05, 2.79357467e-05, 2.19162856e-05, 1.78687206e-05, - 1.91866489e-05, 2.45023178e-05, 2.89484596e-05, 2.90196535e-05, - 2.83342065e-05, 2.50173616e-05, 2.16938824e-05, 1.93565791e-05, - 2.01739109e-05, 2.34690478e-05, 2.59151138e-05, 2.77021539e-05, - 2.94821714e-05, - 2.56112572e-05, 2.74870703e-05, 2.77745534e-05, 2.67202918e-05, - 2.49552941e-05, 2.32119389e-05, 2.21262047e-05, 2.21538982e-05, - 2.24111728e-05, 2.53946554e-05, 2.67680511e-05, 2.64393735e-05, - 2.54215670e-05, 2.52415028e-05, 2.49785848e-05, 2.33677565e-05, - 2.20734643e-05, 2.24476326e-05, 2.28145262e-05, 2.22565811e-05, - 2.59970207e-05, 2.71730575e-05, 2.72875832e-05, 2.57035676e-05, - 2.46740126e-05, 2.47198914e-05, 2.32669456e-05, 2.15921792e-05, - 2.10655375e-05, 2.71152252e-05, 2.81762686e-05, 2.79929007e-05, - 2.47522928e-05, 2.17506762e-05, 2.18309994e-05, 2.21211928e-05, - 2.17924161e-05, 2.17086092e-05, 2.43339837e-05, 2.66159028e-05, - 2.75450128e-05, 2.58659929e-05, 2.38843925e-05, 2.43323462e-05, - 2.48123158e-05, 2.35728160e-05, 2.20502109e-05, 2.21399060e-05, - 2.44334535e-05, 2.76289197e-05, 2.85053807e-05, 2.78197486e-05, - 2.53089316e-05, 2.19956700e-05, 2.08919186e-05, 2.14033065e-05, - 2.71740081e-05, 2.78969208e-05, 2.75464392e-05, 2.58689607e-05, - 2.30755865e-05, 2.08688972e-05, 2.04238421e-05, 2.14161292e-05, - 2.79168360e-05, 2.79945212e-05, 2.74217533e-05, 2.56504960e-05, - 2.19688451e-05, 2.03216813e-05, 2.11864968e-05, 2.19140657e-05, - 2.75756544e-05, 2.79193845e-05, 2.69635467e-05, 2.44443081e-05, - 2.35739203e-05, 2.34108426e-05, 2.26387587e-05, 2.61166279e-05, - 2.67381623e-05, 2.70657277e-05, 2.71442720e-05, 2.52021862e-05, - 2.23425444e-05, 2.17316957e-05, 2.20574784e-05, 2.57791878e-05, - 2.66091297e-05, 2.66155125e-05, 2.59416320e-05, 2.54951827e-05, - 2.50072340e-05, 2.31209913e-05, 2.21483229e-05, 2.54541672e-05, - 2.68880595e-05, 2.68891499e-05, 2.62172796e-05, 2.59638465e-05, - 2.49243277e-05, 2.31415587e-05, 2.19826833e-05, 2.20237181e-05, - 2.36290752e-05, 2.59487746e-05, 2.78927986e-05, 2.85329609e-05, - 2.72619086e-05, 2.32079544e-05, 2.16851739e-05, 2.33934548e-05, - 2.65501010e-05, 2.69828944e-05, 2.63751854e-05, 2.47038817e-05, - 2.44029913e-05, 2.40981630e-05, 2.26103296e-05, 2.21326841e-05, - 2.36200560e-05, 2.61373548e-05, 2.77140150e-05, 2.69009004e-05, - 2.52775506e-05, 2.35343064e-05, 2.22937096e-05, 2.21827570e-05, - 2.54095129e-05, 2.68184607e-05, 2.69963792e-05, 2.58690878e-05, - 2.45194523e-05, 2.35088130e-05, 2.20766055e-05, 2.26401672e-05, - 2.35211155e-05, 2.49882323e-05, 2.72786398e-05, 2.83002280e-05, - 2.72541699e-05, 2.41046871e-05, 2.21311016e-05, 2.10522816e-05, - 2.09801546e-05, 2.17726559e-05, 2.54793662e-05, 2.60503068e-05, - 2.66691659e-05, 2.56783481e-05, 2.35676036e-05, 2.44123015e-05, - 2.35138774e-05, 2.16814255e-05, 2.61782122e-05, 2.65307740e-05, - 2.64222819e-05, 2.64981864e-05, 2.59599244e-05, 2.35371395e-05, - 2.23189240e-05, 2.30037876e-05, 2.60200061e-05, 2.69254628e-05, - 2.74228177e-05, 2.54222400e-05, 2.21905778e-05, 2.21179955e-05, - 2.26737578e-05, 2.48315454e-05, 2.62088237e-05, 2.71745469e-05, - 2.72388851e-05, 2.60415979e-05, 2.45494148e-05, 2.31946642e-05, - 2.17190066e-05, - 2.56730808e-05, 2.76761932e-05, 2.79972008e-05, 2.66903049e-05, - 2.47411324e-05, 2.30666425e-05, 2.20296566e-05, 2.21129779e-05, - 2.24541927e-05, 2.54899852e-05, 2.69441738e-05, 2.66119687e-05, - 2.54575644e-05, 2.52551138e-05, 2.49944016e-05, 2.32424320e-05, - 2.19187103e-05, 2.23976302e-05, 2.28413131e-05, 2.22825564e-05, - 2.60073902e-05, 2.72743172e-05, 2.74948934e-05, 2.56916559e-05, - 2.45677192e-05, 2.47552955e-05, 2.33131908e-05, 2.15667122e-05, - 2.10256586e-05, 2.72293852e-05, 2.84601431e-05, 2.82346032e-05, - 2.45289836e-05, 2.13860162e-05, 2.16924029e-05, 2.21533237e-05, - 2.18130586e-05, 2.17171659e-05, 2.40306332e-05, 2.64295475e-05, - 2.76368025e-05, 2.57759091e-05, 2.37371174e-05, 2.44141312e-05, - 2.50648616e-05, 2.37449401e-05, 2.21254102e-05, 2.18860291e-05, - 2.41755716e-05, 2.77728643e-05, 2.89529101e-05, 2.80525753e-05, - 2.52995658e-05, 2.19184768e-05, 2.08847346e-05, 2.14363935e-05, - 2.73947937e-05, 2.80651642e-05, 2.76013461e-05, 2.57200353e-05, - 2.28526740e-05, 2.06854803e-05, 2.03143006e-05, 2.14045019e-05, - 2.82973494e-05, 2.81892573e-05, 2.74105324e-05, 2.55105134e-05, - 2.17461569e-05, 2.01900893e-05, 2.11917994e-05, 2.19404595e-05, - 2.76953342e-05, 2.81106668e-05, 2.68362659e-05, 2.41021892e-05, - 2.34597224e-05, 2.35956475e-05, 2.28046234e-05, 2.60717602e-05, - 2.65832174e-05, 2.70103231e-05, 2.73028586e-05, 2.53584913e-05, - 2.23560352e-05, 2.17422061e-05, 2.20864525e-05, 2.57189103e-05, - 2.64960162e-05, 2.65279041e-05, 2.58619448e-05, 2.55689532e-05, - 2.52363416e-05, 2.32328027e-05, 2.21795313e-05, 2.53873534e-05, - 2.68969210e-05, 2.69149353e-05, 2.61154533e-05, 2.59428915e-05, - 2.50289335e-05, 2.32380294e-05, 2.20179467e-05, 2.20520006e-05, - 2.31193456e-05, 2.54730673e-05, 2.80489782e-05, 2.89981517e-05, - 2.77159389e-05, 2.33985574e-05, 2.17431222e-05, 2.36322441e-05, - 2.65325900e-05, 2.68304198e-05, 2.62038612e-05, 2.45074626e-05, - 2.43311289e-05, 2.41819536e-05, 2.26485465e-05, 2.21452648e-05, - 2.31395934e-05, 2.58907471e-05, 2.78719455e-05, 2.70035934e-05, - 2.53068254e-05, 2.36088561e-05, 2.23646099e-05, 2.22028207e-05, - 2.53790232e-05, 2.67960492e-05, 2.69865232e-05, 2.57143202e-05, - 2.43461608e-05, 2.34592865e-05, 2.20642448e-05, 2.27245527e-05, - 2.37234776e-05, 2.47817646e-05, 2.72679461e-05, 2.86493065e-05, - 2.74390442e-05, 2.39867382e-05, 2.19933907e-05, 2.10074337e-05, - 2.09697765e-05, 2.17959379e-05, 2.51666607e-05, 2.56088432e-05, - 2.64779591e-05, 2.56060273e-05, 2.35991505e-05, 2.48163216e-05, - 2.38603884e-05, 2.17803996e-05, 2.62655034e-05, 2.63638650e-05, - 2.61895962e-05, 2.64334759e-05, 2.60238837e-05, 2.34750503e-05, - 2.22728638e-05, 2.31125909e-05, 2.57027996e-05, 2.66507197e-05, - 2.74942644e-05, 2.55641435e-05, 2.22037914e-05, 2.21406875e-05, - 2.27632112e-05, 2.45984869e-05, 2.59627104e-05, 2.71273682e-05, - 2.73464466e-05, 2.62496226e-05, 2.47700588e-05, 2.33115737e-05, - 2.17144253e-05, - 2.54735215e-05, 2.63075937e-05, 2.63480846e-05, 2.59766419e-05, - 2.50877946e-05, 2.39286839e-05, 2.31073712e-05, 2.31093153e-05, - 2.32772226e-05, 2.53448601e-05, 2.60787452e-05, 2.59262030e-05, - 2.53631561e-05, 2.52564079e-05, 2.50945336e-05, 2.40352020e-05, - 2.30866445e-05, 2.33367877e-05, 2.35882399e-05, 2.31645629e-05, - 2.56803978e-05, 2.61820717e-05, 2.62787514e-05, 2.55225071e-05, - 2.49132443e-05, 2.49272588e-05, 2.39172253e-05, 2.26654513e-05, - 2.22510359e-05, 2.61764294e-05, 2.60153318e-05, 2.62949130e-05, - 2.49668794e-05, 2.29073397e-05, 2.28944364e-05, 2.30576796e-05, - 2.28053118e-05, 2.27440441e-05, 2.47112275e-05, 2.58382055e-05, - 2.61891694e-05, 2.55976885e-05, 2.43995080e-05, 2.46616747e-05, - 2.49516947e-05, 2.41034670e-05, 2.29862772e-05, 2.31687654e-05, - 2.47715962e-05, 2.62554044e-05, 2.62030415e-05, 2.63553953e-05, - 2.52973966e-05, 2.30001148e-05, 2.20966439e-05, 2.24918711e-05, - 2.62508368e-05, 2.61435243e-05, 2.61168917e-05, 2.55864296e-05, - 2.38494536e-05, 2.21516596e-05, 2.17588822e-05, 2.25203149e-05, - 2.65240850e-05, 2.60155337e-05, 2.60275437e-05, 2.54794635e-05, - 2.30290243e-05, 2.16846203e-05, 2.23295375e-05, 2.28984980e-05, - 2.62276300e-05, 2.56228935e-05, 2.59338724e-05, 2.47801336e-05, - 2.41783645e-05, 2.39810495e-05, 2.34075453e-05, 2.57289481e-05, - 2.58876446e-05, 2.60241938e-05, 2.62104343e-05, 2.52208118e-05, - 2.32350446e-05, 2.27614708e-05, 2.30093759e-05, 2.55580218e-05, - 2.58928328e-05, 2.59107569e-05, 2.56371520e-05, 2.54057480e-05, - 2.50851553e-05, 2.37896922e-05, 2.30790447e-05, 2.53805464e-05, - 2.60490077e-05, 2.60598012e-05, 2.57574903e-05, 2.56588165e-05, - 2.50501635e-05, 2.38097789e-05, 2.29487479e-05, 2.29833658e-05, - 2.42710898e-05, 2.54396156e-05, 2.57512183e-05, 2.63641388e-05, - 2.63592150e-05, 2.38289478e-05, 2.27060227e-05, 2.39510251e-05, - 2.59236886e-05, 2.58946006e-05, 2.57857398e-05, 2.49369078e-05, - 2.47348074e-05, 2.45003483e-05, 2.34306093e-05, 2.30737561e-05, - 2.42635871e-05, 2.56627808e-05, 2.62577750e-05, 2.61039861e-05, - 2.52774737e-05, 2.41034478e-05, 2.31768988e-05, 2.31097496e-05, - 2.53562425e-05, 2.60099433e-05, 2.60604742e-05, 2.55850295e-05, - 2.48206732e-05, 2.41174178e-05, 2.30394276e-05, 2.34374638e-05, - 2.40565909e-05, 2.51073036e-05, 2.60747916e-05, 2.62541743e-05, - 2.62565440e-05, 2.45435289e-05, 2.31250226e-05, 2.22424280e-05, - 2.21696023e-05, 2.27887473e-05, 2.53569985e-05, 2.54926850e-05, - 2.58421808e-05, 2.55032628e-05, 2.41389172e-05, 2.46392006e-05, - 2.40046854e-05, 2.26864895e-05, 2.57834114e-05, 2.58346157e-05, - 2.57579653e-05, 2.58835259e-05, 2.56671564e-05, 2.41405580e-05, - 2.32375724e-05, 2.37033335e-05, 2.55821447e-05, 2.55935259e-05, - 2.61771343e-05, 2.53586162e-05, 2.31182687e-05, 2.30586785e-05, - 2.34612254e-05, 2.50143295e-05, 2.56874436e-05, 2.60325952e-05, - 2.62003432e-05, 2.57190931e-05, 2.47805365e-05, 2.38427077e-05, - 2.27573348e-05, - 2.53214538e-05, 2.52924063e-05, 2.51369487e-05, 2.53338853e-05, - 2.51998144e-05, 2.45495063e-05, 2.39654997e-05, 2.39364293e-05, - 2.40110545e-05, 2.52633856e-05, 2.54564974e-05, 2.54483020e-05, - 2.52813913e-05, 2.52398267e-05, 2.51644259e-05, 2.46088447e-05, - 2.39820952e-05, 2.41035752e-05, 2.42394097e-05, 2.39392571e-05, - 2.53841311e-05, 2.53257554e-05, 2.53962950e-05, 2.53425774e-05, - 2.51047291e-05, 2.50738442e-05, 2.44540224e-05, 2.36011440e-05, - 2.32953435e-05, 2.53602597e-05, 2.42466626e-05, 2.48743425e-05, - 2.51512206e-05, 2.39653924e-05, 2.38350974e-05, 2.38580446e-05, - 2.36784195e-05, 2.36398227e-05, 2.50479968e-05, 2.51859345e-05, - 2.50473045e-05, 2.53536540e-05, 2.48391385e-05, 2.49089801e-05, - 2.50134976e-05, 2.45176053e-05, 2.37808894e-05, 2.40915651e-05, - 2.50682753e-05, 2.50939884e-05, 2.43134164e-05, 2.51139467e-05, - 2.52609698e-05, 2.38775737e-05, 2.31553538e-05, 2.34347167e-05, - 2.54351186e-05, 2.46894301e-05, 2.49222036e-05, 2.53374314e-05, - 2.45321183e-05, 2.33078780e-05, 2.29568889e-05, 2.34835389e-05, - 2.53214857e-05, 2.43903401e-05, 2.48676214e-05, 2.53231923e-05, - 2.39773100e-05, 2.29127901e-05, 2.33276060e-05, 2.37442478e-05, - 2.50886921e-05, 2.37671664e-05, 2.50728216e-05, 2.50852380e-05, - 2.46938344e-05, 2.44289401e-05, 2.40370095e-05, 2.53799742e-05, - 2.51729925e-05, 2.51455078e-05, 2.53932034e-05, 2.51904337e-05, - 2.39969737e-05, 2.36516858e-05, 2.38244647e-05, 2.53500419e-05, - 2.52818494e-05, 2.53062014e-05, 2.53616070e-05, 2.52931614e-05, - 2.50969084e-05, 2.43350159e-05, 2.38741707e-05, 2.52980897e-05, - 2.53247702e-05, 2.53414400e-05, 2.53554086e-05, 2.53759049e-05, - 2.51179285e-05, 2.43565592e-05, 2.37762487e-05, 2.38057575e-05, - 2.48704894e-05, 2.50408784e-05, 2.40113623e-05, 2.45691796e-05, - 2.55338015e-05, 2.43216401e-05, 2.35819430e-05, 2.43810516e-05, - 2.53748685e-05, 2.49899819e-05, 2.52850223e-05, 2.51340085e-05, - 2.50030185e-05, 2.48114287e-05, 2.41229595e-05, 2.38808229e-05, - 2.48606028e-05, 2.52654706e-05, 2.50309372e-05, 2.54029939e-05, - 2.52462198e-05, 2.45638928e-05, 2.39230733e-05, 2.39028050e-05, - 2.52867628e-05, 2.53138822e-05, 2.52607046e-05, 2.53354437e-05, - 2.50745098e-05, 2.46285765e-05, 2.38698581e-05, 2.41030287e-05, - 2.44713435e-05, 2.52067813e-05, 2.50630059e-05, 2.45620955e-05, - 2.53855153e-05, 2.49117455e-05, 2.40002771e-05, 2.32918153e-05, - 2.32140255e-05, 2.36645224e-05, 2.52626404e-05, 2.50499082e-05, - 2.51506714e-05, 2.53355263e-05, 2.46066007e-05, 2.47586731e-05, - 2.43622917e-05, 2.35425158e-05, 2.54131205e-05, 2.52462362e-05, - 2.52031836e-05, 2.53497687e-05, 2.53845428e-05, 2.46486184e-05, - 2.40311674e-05, 2.42769168e-05, 2.52235869e-05, 2.45120536e-05, - 2.51233090e-05, 2.52598846e-05, 2.39128279e-05, 2.38641208e-05, - 2.41171761e-05, 2.51722228e-05, 2.52514340e-05, 2.50735942e-05, - 2.53055345e-05, 2.53949045e-05, 2.49254792e-05, 2.43687734e-05, - 2.36574764e-05, - 2.38988644e-05, 1.90908958e-05, 1.80320304e-05, 2.01794799e-05, - 2.38645772e-05, 2.77598138e-05, 2.98244287e-05, 3.00138596e-05, - 2.99445295e-05, 2.45778186e-05, 2.15297118e-05, 2.24433491e-05, - 2.42007456e-05, 2.44904625e-05, 2.50815015e-05, 2.75715879e-05, - 2.96583156e-05, 2.94996152e-05, 2.92145676e-05, 3.01236237e-05, - 2.26378659e-05, 1.95961868e-05, 2.00415484e-05, 2.32552513e-05, - 2.50960281e-05, 2.57263216e-05, 2.85235541e-05, 3.09524025e-05, - 3.16803610e-05, 1.99262327e-05, 1.47656290e-05, 1.67981436e-05, - 2.42762883e-05, 2.92230859e-05, 3.01157723e-05, 3.03629613e-05, - 3.08287348e-05, 3.09095323e-05, 2.47399571e-05, 1.91849934e-05, - 1.77304383e-05, 2.23538422e-05, 2.64930378e-05, 2.67237218e-05, - 2.65581131e-05, 2.85183686e-05, 3.06435896e-05, 2.91041671e-05, - 2.47830960e-05, 1.79035539e-05, 1.48734537e-05, 1.78957623e-05, - 2.42124734e-05, 3.01147413e-05, 3.20566770e-05, 3.14641001e-05, - 2.05463489e-05, 1.61690987e-05, 1.71837219e-05, 2.19563303e-05, - 2.76348164e-05, 3.13919957e-05, 3.23269865e-05, 3.12724301e-05, - 1.89693065e-05, 1.52077126e-05, 1.70235205e-05, 2.26057734e-05, - 2.95264700e-05, 3.23835472e-05, 3.16775902e-05, 3.06637849e-05, - 1.79083001e-05, 1.36519801e-05, 1.82293171e-05, 2.42715542e-05, - 2.72447043e-05, 2.88518279e-05, 3.00629771e-05, 2.19594174e-05, - 1.89826288e-05, 1.85416256e-05, 2.01771375e-05, 2.53080325e-05, - 2.99351178e-05, 3.08819327e-05, 3.04505105e-05, 2.27715261e-05, - 1.98836927e-05, 2.00770047e-05, 2.22160053e-05, 2.42349141e-05, - 2.60608531e-05, 2.90500736e-05, 3.03164854e-05, 2.35453802e-05, - 1.98936970e-05, 2.00306071e-05, 2.12722836e-05, 2.25312995e-05, - 2.56418219e-05, 2.89517469e-05, 3.05922558e-05, 3.05006115e-05, - 2.50296668e-05, 1.89826999e-05, 1.42296474e-05, 1.55984519e-05, - 2.18205210e-05, 2.92211386e-05, 3.11368631e-05, 2.90971515e-05, - 2.08496894e-05, 1.78071046e-05, 2.02259904e-05, 2.45376587e-05, - 2.58401403e-05, 2.71812947e-05, 2.96008485e-05, 3.02664172e-05, - 2.52208856e-05, 2.04146386e-05, 1.75663901e-05, 2.05931130e-05, - 2.44929546e-05, 2.81742390e-05, 3.02440297e-05, 3.02172440e-05, - 2.38605769e-05, 1.98872858e-05, 1.93061679e-05, 2.19162343e-05, - 2.50662388e-05, 2.76673308e-05, 3.02540782e-05, 2.97396432e-05, - 2.87322306e-05, 2.38331902e-05, 1.79635318e-05, 1.56349007e-05, - 1.99855325e-05, 2.62074304e-05, 2.96393027e-05, 3.16803838e-05, - 3.19177154e-05, 3.08693954e-05, 2.19066041e-05, 1.89253702e-05, - 1.89104407e-05, 2.29565419e-05, 2.79264238e-05, 2.79528733e-05, - 2.93076817e-05, 3.12979195e-05, 2.26282400e-05, 1.97022903e-05, - 1.95145328e-05, 2.06619243e-05, 2.30561399e-05, 2.75576343e-05, - 2.97265146e-05, 2.92358551e-05, 2.02203374e-05, 1.59679605e-05, - 1.81721338e-05, 2.47563314e-05, 3.01771647e-05, 3.03302633e-05, - 2.97050827e-05, 2.40393821e-05, 2.01752498e-05, 1.80840293e-05, - 1.93882430e-05, 2.36651310e-05, 2.69302109e-05, 2.89455017e-05, - 3.08417496e-05, - 2.26844913e-05, 1.60773669e-05, 1.47754644e-05, 1.76302618e-05, - 2.29805238e-05, 2.91965703e-05, 3.28749597e-05, 3.31158064e-05, - 3.28053291e-05, 2.36578713e-05, 1.92264109e-05, 2.04784174e-05, - 2.31645602e-05, 2.36289576e-05, 2.45317553e-05, 2.88320411e-05, - 3.26866438e-05, 3.21605856e-05, 3.14772623e-05, 3.31820274e-05, - 2.09205974e-05, 1.67744011e-05, 1.72532146e-05, 2.18295139e-05, - 2.47233331e-05, 2.55157256e-05, 3.01929291e-05, 3.49195526e-05, - 3.64417130e-05, 1.71820578e-05, 1.10986739e-05, 1.33355633e-05, - 2.36182183e-05, 3.23398991e-05, 3.35321334e-05, 3.36291375e-05, - 3.45660843e-05, 3.47542897e-05, 2.44527459e-05, 1.64933627e-05, - 1.45070782e-05, 2.06294158e-05, 2.70390909e-05, 2.70584470e-05, - 2.65405269e-05, 2.99618839e-05, 3.40804994e-05, 3.18573942e-05, - 2.44527220e-05, 1.46762636e-05, 1.11344406e-05, 1.46078837e-05, - 2.32387462e-05, 3.33902042e-05, 3.71470080e-05, 3.58142275e-05, - 1.78899706e-05, 1.26733135e-05, 1.38926962e-05, 2.01364356e-05, - 2.91229198e-05, 3.62185254e-05, 3.80072964e-05, 3.55320202e-05, - 1.57917087e-05, 1.16112071e-05, 1.37505219e-05, 2.10429143e-05, - 3.25882241e-05, 3.81945462e-05, 3.63214505e-05, 3.42278680e-05, - 1.46983461e-05, 9.99538826e-06, 1.52616295e-05, 2.37801127e-05, - 2.82496564e-05, 3.05294392e-05, 3.27802593e-05, 2.00299185e-05, - 1.62125742e-05, 1.55875252e-05, 1.74660976e-05, 2.46965644e-05, - 3.28491395e-05, 3.46948731e-05, 3.38056936e-05, 2.11888313e-05, - 1.73213368e-05, 1.75485949e-05, 2.04243573e-05, 2.31692414e-05, - 2.57783272e-05, 3.10163272e-05, 3.35413611e-05, 2.23182271e-05, - 1.72283959e-05, 1.73896142e-05, 1.91467359e-05, 2.08040707e-05, - 2.52860185e-05, 3.08672210e-05, 3.40680124e-05, 3.39046505e-05, - 2.52452421e-05, 1.64951570e-05, 1.06015336e-05, 1.18934181e-05, - 1.93672887e-05, 3.11814307e-05, 3.50940159e-05, 3.08726430e-05, - 1.84982484e-05, 1.47710240e-05, 1.78193361e-05, 2.39825557e-05, - 2.58536883e-05, 2.78144943e-05, 3.21692228e-05, 3.34851169e-05, - 2.55058815e-05, 1.81401245e-05, 1.42706672e-05, 1.80517918e-05, - 2.36127497e-05, 2.95274396e-05, 3.33174543e-05, 3.33742399e-05, - 2.27395892e-05, 1.72468682e-05, 1.64991864e-05, 2.00868884e-05, - 2.47730445e-05, 2.88631422e-05, 3.35157571e-05, 3.23358358e-05, - 3.02867818e-05, 2.29230958e-05, 1.48550873e-05, 1.19910132e-05, - 1.72000235e-05, 2.65206219e-05, 3.26125304e-05, 3.64545336e-05, - 3.68622645e-05, 3.46406358e-05, 2.02502880e-05, 1.63902476e-05, - 1.61523909e-05, 2.14678871e-05, 2.91706412e-05, 2.86203914e-05, - 3.10634455e-05, 3.53227000e-05, 2.08247101e-05, 1.71355412e-05, - 1.69532095e-05, 1.82935876e-05, 2.14569732e-05, 2.86958094e-05, - 3.25795474e-05, 3.13590411e-05, 1.79521796e-05, 1.27170949e-05, - 1.50463443e-05, 2.38700224e-05, 3.33119629e-05, 3.35864234e-05, - 3.22612596e-05, 2.32703287e-05, 1.78235003e-05, 1.50260241e-05, - 1.65084561e-05, 2.21749107e-05, 2.71908112e-05, 3.08184933e-05, - 3.46498965e-05, - 2.39434875e-05, 1.94158399e-05, 1.83952540e-05, 2.08886662e-05, - 2.47245169e-05, 2.79105724e-05, 2.94462456e-05, 2.93753154e-05, - 2.89896581e-05, 2.44273277e-05, 2.15984247e-05, 2.23977180e-05, - 2.42762994e-05, 2.45904597e-05, 2.50899852e-05, 2.76772039e-05, - 2.95471467e-05, 2.89960694e-05, 2.84724794e-05, 2.91969858e-05, - 2.29878707e-05, 2.00592115e-05, 2.02221396e-05, 2.35909429e-05, - 2.54805043e-05, 2.55764248e-05, 2.78464725e-05, 3.00577301e-05, - 3.06890617e-05, 2.03267211e-05, 1.52869532e-05, 1.72373552e-05, - 2.51239641e-05, 3.00666338e-05, 2.98589495e-05, 2.93604480e-05, - 2.97699710e-05, 2.98825304e-05, 2.58033971e-05, 2.03399861e-05, - 1.83802575e-05, 2.30065970e-05, 2.68298385e-05, 2.62600435e-05, - 2.55928988e-05, 2.74013088e-05, 2.94070848e-05, 2.94880484e-05, - 2.56918175e-05, 1.84345545e-05, 1.51286695e-05, 1.82522037e-05, - 2.44179062e-05, 2.96036133e-05, 3.08349058e-05, 3.02080872e-05, - 2.06361095e-05, 1.67905473e-05, 1.79474809e-05, 2.28076761e-05, - 2.80934929e-05, 3.11046539e-05, 3.15118305e-05, 3.02495471e-05, - 1.89175794e-05, 1.58472130e-05, 1.79286079e-05, 2.33711574e-05, - 2.97190387e-05, 3.16609732e-05, 3.04900816e-05, 2.96182227e-05, - 1.84875402e-05, 1.43813736e-05, 1.93058810e-05, 2.55034028e-05, - 2.73591494e-05, 2.76174328e-05, 2.86153468e-05, 2.25322976e-05, - 2.00763049e-05, 1.94398560e-05, 2.04505009e-05, 2.48621311e-05, - 2.90970524e-05, 2.98529736e-05, 2.94414702e-05, 2.32978833e-05, - 2.08162592e-05, 2.09329594e-05, 2.28547930e-05, 2.41975051e-05, - 2.52637397e-05, 2.80300986e-05, 2.93277367e-05, 2.40013526e-05, - 2.05375787e-05, 2.06224714e-05, 2.20609035e-05, 2.29777731e-05, - 2.52932766e-05, 2.80078031e-05, 2.95267919e-05, 2.94833747e-05, - 2.67964396e-05, 2.08624730e-05, 1.49872301e-05, 1.57617463e-05, - 2.12006535e-05, 2.78823250e-05, 2.98546502e-05, 2.76192615e-05, - 2.14658686e-05, 1.89620774e-05, 2.12759446e-05, 2.52731248e-05, - 2.60142724e-05, 2.66285920e-05, 2.87368568e-05, 2.93624106e-05, - 2.68691634e-05, 2.16432634e-05, 1.80986468e-05, 2.09481101e-05, - 2.45466490e-05, 2.74651419e-05, 2.91154426e-05, 2.92939837e-05, - 2.41732285e-05, 2.06045036e-05, 2.00442559e-05, 2.27870763e-05, - 2.56686690e-05, 2.74857277e-05, 2.94524121e-05, 2.86712521e-05, - 2.74641820e-05, 2.46725763e-05, 1.88063392e-05, 1.59847193e-05, - 2.02220334e-05, 2.64829359e-05, 2.94614175e-05, 3.07109578e-05, - 3.07426431e-05, 2.97907496e-05, 2.32194726e-05, 2.07182947e-05, - 2.00929070e-05, 2.34957153e-05, 2.74142068e-05, 2.62127484e-05, - 2.74103842e-05, 2.98091180e-05, 2.27762564e-05, 2.07777369e-05, - 2.07619623e-05, 2.14119845e-05, 2.32098116e-05, 2.74385446e-05, - 2.91643288e-05, 2.81867825e-05, 2.16439517e-05, 1.74455398e-05, - 1.88279866e-05, 2.44440959e-05, 2.92895323e-05, 2.93723597e-05, - 2.86252191e-05, 2.49410036e-05, 2.14174008e-05, 1.89958196e-05, - 1.98579786e-05, 2.33459682e-05, 2.59876143e-05, 2.79296102e-05, - 2.98839010e-05, - 2.39430654e-05, 1.94730304e-05, 1.84601972e-05, 2.10500793e-05, - 2.49384417e-05, 2.79558936e-05, 2.93679105e-05, 2.92322947e-05, - 2.87671580e-05, 2.43796516e-05, 2.15958381e-05, 2.23687708e-05, - 2.42850643e-05, 2.46067357e-05, 2.50852014e-05, 2.77097709e-05, - 2.95360879e-05, 2.88838924e-05, 2.82985952e-05, 2.89826032e-05, - 2.30619686e-05, 2.01538229e-05, 2.02441542e-05, 2.36635558e-05, - 2.55734748e-05, 2.55339305e-05, 2.76848962e-05, 2.98566764e-05, - 3.04689683e-05, 2.04057309e-05, 1.53890596e-05, 1.73201064e-05, - 2.53362657e-05, 3.03035320e-05, 2.98134788e-05, 2.91287372e-05, - 2.95273230e-05, 2.96482828e-05, 2.60758389e-05, 2.06198532e-05, - 1.85204095e-05, 2.31595578e-05, 2.69169633e-05, 2.61426643e-05, - 2.53499507e-05, 2.71306745e-05, 2.91194342e-05, 2.96022264e-05, - 2.59226660e-05, 1.85434295e-05, 1.51609302e-05, 1.83151088e-05, - 2.44603459e-05, 2.94934015e-05, 3.05604015e-05, 2.99210125e-05, - 2.06360440e-05, 1.69207582e-05, 1.81172750e-05, 2.30124134e-05, - 2.82186769e-05, 3.10602344e-05, 3.13405402e-05, 3.00187610e-05, - 1.88773493e-05, 1.59812260e-05, 1.81364169e-05, 2.35550332e-05, - 2.97858197e-05, 3.15134135e-05, 3.02213475e-05, 2.93777704e-05, - 1.86092195e-05, 1.45387205e-05, 1.95624092e-05, 2.58197358e-05, - 2.73922416e-05, 2.73198678e-05, 2.82726540e-05, 2.26627337e-05, - 2.03389352e-05, 1.96483544e-05, 2.04969531e-05, 2.47427227e-05, - 2.89035493e-05, 2.96180585e-05, 2.92086970e-05, 2.34188143e-05, - 2.10370170e-05, 2.11334983e-05, 2.30035710e-05, 2.41773469e-05, - 2.50600114e-05, 2.77862423e-05, 2.90991449e-05, 2.41066239e-05, - 2.06808324e-05, 2.07522506e-05, 2.22466605e-05, 2.30767977e-05, - 2.51998938e-05, 2.77821848e-05, 2.92809551e-05, 2.92488898e-05, - 2.72638359e-05, 2.13455153e-05, 1.51524152e-05, 1.57709450e-05, - 2.10253318e-05, 2.75613189e-05, 2.95589576e-05, 2.72638929e-05, - 2.16043552e-05, 1.92394854e-05, 2.15294460e-05, 2.54564994e-05, - 2.60557845e-05, 2.64910865e-05, 2.85348561e-05, 2.91545539e-05, - 2.73042979e-05, 2.19461689e-05, 1.82072400e-05, 2.10170086e-05, - 2.45509838e-05, 2.72936414e-05, 2.88518368e-05, 2.90810273e-05, - 2.42421703e-05, 2.07673102e-05, 2.02112435e-05, 2.29969290e-05, - 2.58189721e-05, 2.74448439e-05, 2.92700047e-05, 2.84194338e-05, - 2.71577757e-05, 2.48808594e-05, 1.89987556e-05, 1.60424416e-05, - 2.02583953e-05, 2.65526148e-05, 2.94330900e-05, 3.04963103e-05, - 3.04786722e-05, 2.95434481e-05, 2.35496886e-05, 2.11764166e-05, - 2.03797879e-05, 2.36207038e-05, 2.72907703e-05, 2.57890555e-05, - 2.69558332e-05, 2.94640162e-05, 2.27977720e-05, 2.10369331e-05, - 2.10679795e-05, 2.15856395e-05, 2.32343290e-05, 2.74130840e-05, - 2.90387428e-05, 2.79368001e-05, 2.20003581e-05, 1.78114366e-05, - 1.89705713e-05, 2.43560693e-05, 2.90851885e-05, 2.91515088e-05, - 2.83703670e-05, 2.51668329e-05, 2.17234484e-05, 1.92071370e-05, - 1.99538509e-05, 2.32518814e-05, 2.57519358e-05, 2.76861767e-05, - 2.96663757e-05, - 2.56960736e-05, 2.88107249e-05, 2.94052239e-05, 2.76115111e-05, - 2.48752166e-05, 2.24185670e-05, 2.10158135e-05, 2.10411275e-05, - 2.13497923e-05, 2.53543592e-05, 2.74683038e-05, 2.69208470e-05, - 2.54255914e-05, 2.51705162e-05, 2.47861923e-05, 2.26184824e-05, - 2.09602400e-05, 2.14115880e-05, 2.18630927e-05, 2.11589105e-05, - 2.63297710e-05, 2.83036654e-05, 2.83779004e-05, 2.58834929e-05, - 2.44059321e-05, 2.44086739e-05, 2.24419176e-05, 2.03452294e-05, - 1.97086418e-05, 2.81706237e-05, 3.07819591e-05, 2.99791717e-05, - 2.45802873e-05, 2.05986687e-05, 2.06552296e-05, 2.09894244e-05, - 2.05849383e-05, 2.04836088e-05, 2.40173867e-05, 2.76446094e-05, - 2.91613527e-05, 2.61980143e-05, 2.33199880e-05, 2.38529192e-05, - 2.44586524e-05, 2.28130367e-05, 2.08957743e-05, 2.10639219e-05, - 2.41363338e-05, 2.92369033e-05, 3.12079209e-05, 2.94949633e-05, - 2.52827519e-05, 2.08497899e-05, 1.94979603e-05, 2.01091241e-05, - 2.81458369e-05, 3.00051295e-05, 2.92842879e-05, 2.62529626e-05, - 2.22617488e-05, 1.94873369e-05, 1.89501827e-05, 2.01292196e-05, - 2.94068486e-05, 3.03999026e-05, 2.91530326e-05, 2.58927045e-05, - 2.08421831e-05, 1.88313283e-05, 1.98499514e-05, 2.07338995e-05, - 2.91644700e-05, 3.07803194e-05, 2.82828572e-05, 2.41983572e-05, - 2.28894193e-05, 2.25995497e-05, 2.16172522e-05, 2.65693505e-05, - 2.78415584e-05, 2.83567307e-05, 2.81667781e-05, 2.50454504e-05, - 2.12683996e-05, 2.05116666e-05, 2.09108213e-05, 2.60360898e-05, - 2.75152132e-05, 2.74916260e-05, 2.63120357e-05, 2.55148546e-05, - 2.47390814e-05, 2.22394505e-05, 2.10232650e-05, 2.55357356e-05, - 2.78780770e-05, 2.78566027e-05, 2.67931761e-05, 2.63006025e-05, - 2.46698512e-05, 2.22689431e-05, 2.08174382e-05, 2.08691049e-05, - 2.31260803e-05, 2.68108164e-05, 3.05535513e-05, 3.10340966e-05, - 2.80703886e-05, 2.23366063e-05, 2.04493489e-05, 2.25668634e-05, - 2.72851903e-05, 2.83945441e-05, 2.71551608e-05, 2.44946827e-05, - 2.40072233e-05, 2.35336168e-05, 2.16015101e-05, 2.10064996e-05, - 2.30985381e-05, 2.68177636e-05, 2.94242448e-05, 2.77810838e-05, - 2.52155013e-05, 2.27848218e-05, 2.11986667e-05, 2.10677263e-05, - 2.54455939e-05, 2.77880465e-05, 2.81224477e-05, 2.62584031e-05, - 2.42170284e-05, 2.27835638e-05, 2.09404434e-05, 2.16314703e-05, - 2.27393024e-05, 2.49196769e-05, 2.87557710e-05, 3.07017613e-05, - 2.83433634e-05, 2.36112128e-05, 2.10293291e-05, 1.96931832e-05, - 1.96036521e-05, 2.05603645e-05, 2.57635937e-05, 2.69529018e-05, - 2.77641993e-05, 2.58860650e-05, 2.28394479e-05, 2.38724690e-05, - 2.27037782e-05, 2.04405733e-05, 2.65625332e-05, 2.74434869e-05, - 2.73340358e-05, 2.72464558e-05, 2.62322533e-05, 2.28247305e-05, - 2.12486916e-05, 2.20896114e-05, 2.66966557e-05, 2.87377501e-05, - 2.89051116e-05, 2.53719441e-05, 2.10784869e-05, 2.09867853e-05, - 2.16730938e-05, 2.47027423e-05, 2.69477264e-05, 2.85922944e-05, - 2.84274568e-05, 2.62671635e-05, 2.41063429e-05, 2.23333616e-05, - 2.04979486e-05, - 2.55585743e-05, 2.67827254e-05, 2.69158768e-05, 2.61891931e-05, - 2.49179750e-05, 2.36184530e-05, 2.27439984e-05, 2.27897301e-05, - 2.30394692e-05, 2.54237936e-05, 2.64004259e-05, 2.61929485e-05, - 2.54079894e-05, 2.52648760e-05, 2.50732912e-05, 2.37532584e-05, - 2.26757173e-05, 2.30324726e-05, 2.33692509e-05, 2.29027142e-05, - 2.57882453e-05, 2.65483799e-05, 2.67143970e-05, 2.55752441e-05, - 2.47776139e-05, 2.48900404e-05, 2.37492673e-05, 2.23181600e-05, - 2.18584740e-05, 2.65349928e-05, 2.68316458e-05, 2.69531574e-05, - 2.47656717e-05, 2.23146414e-05, 2.24777034e-05, 2.27907375e-05, - 2.25067987e-05, 2.24306271e-05, 2.44085364e-05, 2.59657574e-05, - 2.66579150e-05, 2.56288744e-05, 2.41517497e-05, 2.46157853e-05, - 2.50704134e-05, 2.40520195e-05, 2.27469306e-05, 2.26891538e-05, - 2.45098782e-05, 2.67605950e-05, 2.71553843e-05, 2.69403424e-05, - 2.52997278e-05, 2.26416867e-05, 2.17189512e-05, 2.21772448e-05, - 2.66692354e-05, 2.67742523e-05, 2.65852858e-05, 2.55856624e-05, - 2.34716700e-05, 2.16348498e-05, 2.12728264e-05, 2.21720152e-05, - 2.71763005e-05, 2.67272058e-05, 2.64458871e-05, 2.54499158e-05, - 2.25593140e-05, 2.11751365e-05, 2.19796739e-05, 2.26127001e-05, - 2.67107835e-05, 2.64234745e-05, 2.61734940e-05, 2.44661192e-05, - 2.39233606e-05, 2.39253464e-05, 2.32782503e-05, 2.58244652e-05, - 2.60564126e-05, 2.63108766e-05, 2.65943957e-05, 2.53166291e-05, - 2.29701371e-05, 2.24511063e-05, 2.27355402e-05, 2.55931634e-05, - 2.60464333e-05, 2.60764237e-05, 2.56858281e-05, 2.54834442e-05, - 2.52080295e-05, 2.36574061e-05, 2.28133387e-05, 2.53663369e-05, - 2.63139018e-05, 2.63320612e-05, 2.58399967e-05, 2.57438471e-05, - 2.50811203e-05, 2.36679518e-05, 2.26744387e-05, 2.27066331e-05, - 2.37529278e-05, 2.53072402e-05, 2.64869064e-05, 2.72891394e-05, - 2.69123592e-05, 2.37611811e-05, 2.24288423e-05, 2.39331590e-05, - 2.61084408e-05, 2.61366046e-05, 2.58651707e-05, 2.47467773e-05, - 2.45919111e-05, 2.44331918e-05, 2.32042240e-05, 2.27928890e-05, - 2.37635880e-05, 2.56608242e-05, 2.67956238e-05, 2.64132311e-05, - 2.53002615e-05, 2.39786650e-05, 2.29514847e-05, 2.28381165e-05, - 2.53582973e-05, 2.62466517e-05, 2.63430746e-05, 2.55811247e-05, - 2.46237024e-05, 2.39019971e-05, 2.27357330e-05, 2.32476141e-05, - 2.40226520e-05, 2.49464819e-05, 2.64369345e-05, 2.70760615e-05, - 2.66753299e-05, 2.43382237e-05, 2.27312061e-05, 2.18451687e-05, - 2.17947648e-05, 2.24909068e-05, 2.52052251e-05, 2.53964399e-05, - 2.59817397e-05, 2.55168296e-05, 2.39863528e-05, 2.48253864e-05, - 2.40748508e-05, 2.24405251e-05, 2.59622501e-05, 2.59492539e-05, - 2.58226761e-05, 2.60358766e-05, 2.58007242e-05, 2.39188266e-05, - 2.29264011e-05, 2.35595279e-05, 2.55254081e-05, 2.58349856e-05, - 2.66011117e-05, 2.54705746e-05, 2.28420455e-05, 2.27843864e-05, - 2.32776721e-05, 2.48169718e-05, 2.57001625e-05, 2.63542901e-05, - 2.65846072e-05, 2.59501677e-05, 2.48514610e-05, 2.37200747e-05, - 2.24345840e-05, - 2.26370495e-05, 1.59345287e-05, 1.46254827e-05, 1.72129183e-05, - 2.23358893e-05, 2.89387962e-05, 3.29824034e-05, 3.34469217e-05, - 3.34217024e-05, 2.37411275e-05, 1.92128482e-05, 2.05288968e-05, - 2.30862383e-05, 2.35243563e-05, 2.44802746e-05, 2.86190112e-05, - 3.25673191e-05, 3.23905116e-05, 3.19253368e-05, 3.37679882e-05, - 2.06833527e-05, 1.65321388e-05, 1.71893342e-05, 2.15854540e-05, - 2.43840640e-05, 2.55694722e-05, 3.06039426e-05, 3.54505366e-05, - 3.70375442e-05, 1.69740644e-05, 1.08990561e-05, 1.31571668e-05, - 2.29654433e-05, 3.14282742e-05, 3.35200025e-05, 3.42770062e-05, - 3.52521677e-05, 3.54086742e-05, 2.36206268e-05, 1.58194491e-05, - 1.41844595e-05, 2.01868449e-05, 2.66836217e-05, 2.73374112e-05, - 2.72337487e-05, 3.07532948e-05, 3.49353545e-05, 3.13406362e-05, - 2.37328671e-05, 1.44236884e-05, 1.10856798e-05, 1.44642408e-05, - 2.30629326e-05, 3.36040064e-05, 3.79491349e-05, 3.66663246e-05, - 1.78790468e-05, 1.23960630e-05, 1.35120493e-05, 1.95694408e-05, - 2.86193806e-05, 3.61722696e-05, 3.84103488e-05, 3.61712467e-05, - 1.58964550e-05, 1.13385774e-05, 1.32890054e-05, 2.05131162e-05, - 3.22123255e-05, 3.85066029e-05, 3.71026683e-05, 3.49065523e-05, - 1.44157745e-05, 9.69553223e-06, 1.46655454e-05, 2.28480669e-05, - 2.80423516e-05, 3.14179533e-05, 3.38404873e-05, 1.96549761e-05, - 1.55834265e-05, 1.50927224e-05, 1.73377129e-05, 2.49927387e-05, - 3.33610617e-05, 3.53518956e-05, 3.44570357e-05, 2.08222911e-05, - 1.67669731e-05, 1.70381496e-05, 1.99958698e-05, 2.31749468e-05, - 2.63413721e-05, 3.17123976e-05, 3.41780304e-05, 2.19781215e-05, - 1.68612060e-05, 1.70531547e-05, 1.86448591e-05, 2.05012674e-05, - 2.54983586e-05, 3.14988003e-05, 3.47669568e-05, 3.45620493e-05, - 2.38820759e-05, 1.53830710e-05, 1.02778419e-05, 1.18929845e-05, - 1.98407089e-05, 3.21566669e-05, 3.59792902e-05, 3.19736632e-05, - 1.81247412e-05, 1.41397174e-05, 1.71781798e-05, 2.34015269e-05, - 2.56502475e-05, 2.81552984e-05, 3.27138813e-05, 3.40464518e-05, - 2.42172108e-05, 1.73765267e-05, 1.40233437e-05, 1.78602290e-05, - 2.35430558e-05, 2.99749393e-05, 3.40831089e-05, 3.39544384e-05, - 2.24946523e-05, 1.68320052e-05, 1.60857522e-05, 1.95079063e-05, - 2.42699866e-05, 2.88828711e-05, 3.39850566e-05, 3.30592599e-05, - 3.12067727e-05, 2.22946023e-05, 1.44089998e-05, 1.18803086e-05, - 1.70997556e-05, 2.62245917e-05, 3.25522028e-05, 3.70297647e-05, - 3.76241990e-05, 3.53438926e-05, 1.93712462e-05, 1.53332985e-05, - 1.54702569e-05, 2.10864737e-05, 2.94580826e-05, 2.99613440e-05, - 3.25409184e-05, 3.63985081e-05, 2.07321377e-05, 1.64951497e-05, - 1.62100721e-05, 1.78358392e-05, 2.13501631e-05, 2.86677551e-05, - 3.28530103e-05, 3.20767172e-05, 1.70706313e-05, 1.19548808e-05, - 1.47109392e-05, 2.40734081e-05, 3.38611796e-05, 3.41947040e-05, - 3.29957719e-05, 2.25882238e-05, 1.70600098e-05, 1.45346944e-05, - 1.62661148e-05, 2.24043172e-05, 2.78598681e-05, 3.15132344e-05, - 3.52426463e-05, - 2.08585238e-05, 1.26935526e-05, 1.12697399e-05, 1.42834386e-05, - 2.08163901e-05, 3.01245165e-05, 3.64286370e-05, 3.70407525e-05, - 3.67695527e-05, 2.22758980e-05, 1.64552108e-05, 1.80568389e-05, - 2.14820440e-05, 2.20949257e-05, 2.33859827e-05, 2.95954965e-05, - 3.59070138e-05, 3.53343789e-05, 3.43916435e-05, 3.73858519e-05, - 1.84158096e-05, 1.34137721e-05, 1.40770298e-05, 1.95845434e-05, - 2.34346259e-05, 2.48635375e-05, 3.22679173e-05, 4.03720304e-05, - 4.31880086e-05, 1.39015003e-05, 7.55613660e-06, 9.75210788e-06, - 2.16713347e-05, 3.46274584e-05, 3.74432571e-05, 3.82137652e-05, - 3.98901990e-05, 4.01940797e-05, 2.26838282e-05, 1.28232144e-05, - 1.08803665e-05, 1.79019835e-05, 2.67633848e-05, 2.73025859e-05, - 2.68674289e-05, 3.22253549e-05, 3.91923885e-05, 3.41730651e-05, - 2.27682573e-05, 1.11017929e-05, 7.67191481e-06, 1.10951554e-05, - 2.15100669e-05, 3.74045040e-05, 4.46967917e-05, 4.22869370e-05, - 1.48539714e-05, 9.03013664e-06, 1.02043021e-05, 1.71977343e-05, - 2.98054910e-05, 4.21644278e-05, 4.59239369e-05, 4.15721583e-05, - 1.25325384e-05, 8.00012174e-06, 1.00103416e-05, 1.83656269e-05, - 3.55133306e-05, 4.61896209e-05, 4.31460714e-05, 3.92870779e-05, - 1.11070958e-05, 6.49430299e-06, 1.15192714e-05, 2.16849601e-05, - 2.87050105e-05, 3.32256790e-05, 3.71305783e-05, 1.71976425e-05, - 1.25385050e-05, 1.19345147e-05, 1.42813518e-05, 2.38853161e-05, - 3.67495527e-05, 4.00911091e-05, 3.85236357e-05, 1.86675342e-05, - 1.38378522e-05, 1.41282515e-05, 1.76535352e-05, 2.15509410e-05, - 2.56445235e-05, 3.38515499e-05, 3.80514470e-05, 2.01572616e-05, - 1.38518097e-05, 1.40573490e-05, 1.60268280e-05, 1.82212151e-05, - 2.46581603e-05, 3.35510552e-05, 3.90255794e-05, 3.87016289e-05, - 2.33901035e-05, 1.25512684e-05, 7.02945310e-06, 8.42271048e-06, - 1.69634383e-05, 3.43693949e-05, 4.10180098e-05, 3.39727352e-05, - 1.53335676e-05, 1.09738637e-05, 1.43575951e-05, 2.22230455e-05, - 2.51489966e-05, 2.84922341e-05, 3.56296010e-05, 3.78851160e-05, - 2.38141536e-05, 1.46526578e-05, 1.06768792e-05, 1.49250505e-05, - 2.20989292e-05, 3.12386035e-05, 3.77831072e-05, 3.77111218e-05, - 2.07869589e-05, 1.38422544e-05, 1.29940848e-05, 1.71278849e-05, - 2.33794494e-05, 2.98372412e-05, 3.78537431e-05, 3.60704425e-05, - 3.28598853e-05, 2.07513304e-05, 1.11748901e-05, 8.45537772e-06, - 1.39920350e-05, 2.60463793e-05, 3.58346915e-05, 4.31916953e-05, - 4.41266862e-05, 4.00383010e-05, 1.71249306e-05, 1.24690810e-05, - 1.24387623e-05, 1.90162641e-05, 3.05412195e-05, 3.05723553e-05, - 3.46212398e-05, 4.16106068e-05, 1.83957566e-05, 1.35699235e-05, - 1.32971195e-05, 1.50346198e-05, 1.91983809e-05, 2.95383347e-05, - 3.60775316e-05, 3.44345233e-05, 1.43560869e-05, 8.79837812e-06, - 1.14467580e-05, 2.26591567e-05, 3.75755802e-05, 3.81033641e-05, - 3.59546816e-05, 2.11783819e-05, 1.42829473e-05, 1.13300202e-05, - 1.31130748e-05, 2.03832372e-05, 2.78184801e-05, 3.35268140e-05, - 3.99511919e-05, - 2.38804924e-05, 1.91779433e-05, 1.81310934e-05, 2.05917408e-05, - 2.44945003e-05, 2.79669308e-05, 2.96993512e-05, 2.96871425e-05, - 2.93576209e-05, 2.44247240e-05, 2.14656835e-05, 2.23114561e-05, - 2.42164482e-05, 2.45349409e-05, 2.50723475e-05, 2.77344649e-05, - 2.97410933e-05, 2.92572631e-05, 2.87655693e-05, 2.95684671e-05, - 2.28262028e-05, 1.98019813e-05, 2.00329611e-05, 2.34497379e-05, - 2.53880388e-05, 2.56126297e-05, 2.80959997e-05, 3.04657775e-05, - 3.11548231e-05, 2.00893073e-05, 1.49493566e-05, 1.69391468e-05, - 2.49097767e-05, 3.00539959e-05, 3.01035167e-05, 2.97580985e-05, - 3.02020285e-05, 3.03129290e-05, 2.55605914e-05, 1.99271711e-05, - 1.80501973e-05, 2.27747696e-05, 2.67980303e-05, 2.63945828e-05, - 2.58182321e-05, 2.77341941e-05, 2.98625415e-05, 2.95595356e-05, - 2.54822015e-05, 1.81326568e-05, 1.48498134e-05, 1.79873382e-05, - 2.43322719e-05, 2.98963871e-05, 3.13644853e-05, 3.07106363e-05, - 2.04764278e-05, 1.64451953e-05, 1.75846207e-05, 2.25238343e-05, - 2.80839476e-05, 3.14230606e-05, 3.19825901e-05, 3.06986004e-05, - 1.87561673e-05, 1.54876737e-05, 1.75327428e-05, 2.31229767e-05, - 2.98480731e-05, 3.21180594e-05, 3.09918476e-05, 3.00392526e-05, - 1.81754105e-05, 1.39899569e-05, 1.88920204e-05, 2.52099195e-05, - 2.74011719e-05, 2.79870375e-05, 2.90809597e-05, 2.23064820e-05, - 1.96727086e-05, 1.90700742e-05, 2.02448595e-05, 2.49421511e-05, - 2.94426091e-05, 3.02822829e-05, 2.98447712e-05, 2.31037382e-05, - 2.04655993e-05, 2.06027546e-05, 2.26221228e-05, 2.41613987e-05, - 2.54385358e-05, 2.83682132e-05, 2.97204748e-05, 2.38442352e-05, - 2.02483273e-05, 2.03470690e-05, 2.17726563e-05, 2.27933716e-05, - 2.53656619e-05, 2.83271098e-05, 2.99478451e-05, 2.98907547e-05, - 2.64185302e-05, 2.02873561e-05, 1.45933922e-05, 1.55090884e-05, - 2.12143527e-05, 2.82880917e-05, 3.03443383e-05, 2.80453934e-05, - 2.12036008e-05, 1.85239109e-05, 2.09077923e-05, 2.50905569e-05, - 2.59903063e-05, 2.67982048e-05, 2.90711505e-05, 2.97367758e-05, - 2.65229278e-05, 2.12412857e-05, 1.77912724e-05, 2.07344972e-05, - 2.45004992e-05, 2.77056631e-05, 2.95306591e-05, 2.96694928e-05, - 2.40548985e-05, 2.02996233e-05, 1.97231231e-05, 2.24980958e-05, - 2.55311725e-05, 2.76030825e-05, 2.98069613e-05, 2.90505977e-05, - 2.78348398e-05, 2.44457933e-05, 1.84385000e-05, 1.56923271e-05, - 2.00200763e-05, 2.64524076e-05, 2.96672122e-05, 3.11726800e-05, - 3.12556884e-05, 3.02286298e-05, 2.28372446e-05, 2.01611339e-05, - 1.96687299e-05, 2.33042037e-05, 2.76064255e-05, 2.66389610e-05, - 2.79237341e-05, 3.03454017e-05, 2.26555949e-05, 2.03926979e-05, - 2.03359945e-05, 2.11172633e-05, 2.30999107e-05, 2.75391604e-05, - 2.94475970e-05, 2.85388635e-05, 2.11956130e-05, 1.69086637e-05, - 1.85037782e-05, 2.44794063e-05, 2.96563624e-05, 2.97600244e-05, - 2.90050634e-05, 2.47080129e-05, 2.10070245e-05, 1.86151095e-05, - 1.95952464e-05, 2.33488799e-05, 2.62226040e-05, 2.82622327e-05, - 3.02978699e-05, - 2.37993041e-05, 1.89889134e-05, 1.79239897e-05, 2.05468850e-05, - 2.46533941e-05, 2.81462969e-05, 2.98715463e-05, 2.97946988e-05, - 2.93634045e-05, 2.43210783e-05, 2.12872347e-05, 2.21375091e-05, - 2.41594327e-05, 2.45000637e-05, 2.50422372e-05, 2.78869945e-05, - 2.99824818e-05, 2.93651618e-05, 2.87791783e-05, 2.95971171e-05, - 2.27747880e-05, 1.96672528e-05, 1.98329372e-05, 2.34225000e-05, - 2.54705576e-05, 2.55720868e-05, 2.80785060e-05, 3.05735100e-05, - 3.12978083e-05, 1.99475286e-05, 1.47243417e-05, 1.67250422e-05, - 2.50867064e-05, 3.05608649e-05, 3.03372010e-05, 2.97831879e-05, - 3.02489151e-05, 3.03764157e-05, 2.58289233e-05, 1.99785507e-05, - 1.79155592e-05, 2.27994056e-05, 2.69497595e-05, 2.63209621e-05, - 2.55882453e-05, 2.75856573e-05, 2.98399357e-05, 2.99112255e-05, - 2.57056257e-05, 1.79690333e-05, 1.45548115e-05, 1.77749830e-05, - 2.43140039e-05, 3.00513058e-05, 3.14712672e-05, 3.07526514e-05, - 2.02678872e-05, 1.62691197e-05, 1.74690306e-05, 2.25897368e-05, - 2.83493450e-05, 3.17595012e-05, 3.22420414e-05, 3.07950049e-05, - 1.84594254e-05, 1.53007659e-05, 1.74533875e-05, 2.31922238e-05, - 3.01735649e-05, 3.24122671e-05, 3.10740821e-05, 3.00762172e-05, - 1.80254055e-05, 1.38095441e-05, 1.88920299e-05, 2.55038374e-05, - 2.75342556e-05, 2.78273806e-05, 2.89484014e-05, 2.22906485e-05, - 1.96998317e-05, 1.90275759e-05, 2.00754553e-05, 2.47914819e-05, - 2.94830203e-05, 3.03428053e-05, 2.98750820e-05, 2.31099675e-05, - 2.04752565e-05, 2.05968258e-05, 2.26366019e-05, 2.40731101e-05, - 2.52282058e-05, 2.82863325e-05, 2.97459371e-05, 2.38663816e-05, - 2.01748916e-05, 2.02633365e-05, 2.17917478e-05, 2.27653637e-05, - 2.52618930e-05, 2.82607067e-05, 2.99727761e-05, 2.99227202e-05, - 2.69229840e-05, 2.05477077e-05, 1.44262963e-05, 1.51993420e-05, - 2.08544888e-05, 2.81242521e-05, 3.03496601e-05, 2.78317575e-05, - 2.11561347e-05, 1.85351358e-05, 2.09638180e-05, 2.52477180e-05, - 2.60528396e-05, 2.67270467e-05, 2.90774674e-05, 2.97838904e-05, - 2.70015521e-05, 2.13569772e-05, 1.76197929e-05, 2.06026489e-05, - 2.44521451e-05, 2.76540970e-05, 2.95079451e-05, 2.97067474e-05, - 2.40503673e-05, 2.02470538e-05, 1.96576416e-05, 2.25680444e-05, - 2.56776162e-05, 2.76749668e-05, 2.98842498e-05, 2.90061451e-05, - 2.76568472e-05, 2.45968660e-05, 1.83643333e-05, 1.54331197e-05, - 1.98339304e-05, 2.65676904e-05, 2.98863738e-05, 3.13224382e-05, - 3.13638706e-05, 3.02729205e-05, 2.30388994e-05, 2.03934145e-05, - 1.97195038e-05, 2.33227459e-05, 2.75966014e-05, 2.62723948e-05, - 2.76032381e-05, 3.03020893e-05, 2.25451917e-05, 2.04378614e-05, - 2.04253098e-05, 2.11016225e-05, 2.30103277e-05, 2.76224874e-05, - 2.95554525e-05, 2.84620013e-05, 2.13621346e-05, 1.69709876e-05, - 1.83821296e-05, 2.43380600e-05, 2.97011868e-05, 2.97959792e-05, - 2.89544994e-05, 2.48886504e-05, 2.11178981e-05, 1.85638055e-05, - 1.94559022e-05, 2.31513999e-05, 2.60215006e-05, 2.81739510e-05, - 3.03766919e-05, - 2.57088470e-05, 2.86147453e-05, 2.91576166e-05, 2.74108134e-05, - 2.48023054e-05, 2.25258028e-05, 2.12088562e-05, 2.12580198e-05, - 2.15915479e-05, 2.54080852e-05, 2.74007255e-05, 2.68982921e-05, - 2.54441373e-05, 2.51951200e-05, 2.48372886e-05, 2.27250859e-05, - 2.11293781e-05, 2.16090920e-05, 2.20757771e-05, 2.14008220e-05, - 2.62673112e-05, 2.81099638e-05, 2.82405611e-05, 2.58437964e-05, - 2.44199756e-05, 2.44931188e-05, 2.26371020e-05, 2.05956043e-05, - 1.99749663e-05, 2.79990204e-05, 3.03474356e-05, 2.96623377e-05, - 2.45230152e-05, 2.06873161e-05, 2.08439153e-05, 2.12407699e-05, - 2.08466494e-05, 2.07437809e-05, 2.39560951e-05, 2.73434297e-05, - 2.88572640e-05, 2.60913627e-05, 2.33786364e-05, 2.39922706e-05, - 2.46453888e-05, 2.30483127e-05, 2.11696703e-05, 2.11836015e-05, - 2.40906720e-05, 2.89584281e-05, 3.08281253e-05, 2.92422625e-05, - 2.52878814e-05, 2.10581661e-05, 1.97851734e-05, 2.03932834e-05, - 2.80400103e-05, 2.96275529e-05, 2.89365508e-05, 2.61090739e-05, - 2.23401354e-05, 1.96989874e-05, 1.92108676e-05, 2.03933443e-05, - 2.92613035e-05, 2.99685335e-05, 2.87764198e-05, 2.57833083e-05, - 2.09854700e-05, 1.90862235e-05, 2.01309771e-05, 2.09925482e-05, - 2.88791421e-05, 3.02451180e-05, 2.79443933e-05, 2.41050416e-05, - 2.29873197e-05, 2.28506145e-05, 2.19025600e-05, 2.64567788e-05, - 2.75381513e-05, 2.80571777e-05, 2.80222118e-05, 2.51499825e-05, - 2.15003296e-05, 2.07716597e-05, 2.11638334e-05, 2.59586934e-05, - 2.72739432e-05, 2.72683556e-05, 2.62017364e-05, 2.55465818e-05, - 2.48981438e-05, 2.24738651e-05, 2.12728767e-05, 2.54928810e-05, - 2.76733508e-05, 2.76643787e-05, 2.66287423e-05, 2.62234679e-05, - 2.47723667e-05, 2.24950681e-05, 2.10768059e-05, 2.11234234e-05, - 2.30150156e-05, 2.64155453e-05, 3.00469706e-05, 3.07069623e-05, - 2.81030418e-05, 2.26022219e-05, 2.07322612e-05, 2.28438161e-05, - 2.71239176e-05, 2.80241511e-05, 2.69152905e-05, 2.44570615e-05, - 2.40630292e-05, 2.36913882e-05, 2.18306388e-05, 2.12485349e-05, - 2.30041677e-05, 2.65659016e-05, 2.91297221e-05, 2.76421860e-05, - 2.52450441e-05, 2.29765938e-05, 2.14588817e-05, 2.13106531e-05, - 2.54283115e-05, 2.75737088e-05, 2.78796516e-05, 2.61107771e-05, - 2.42092537e-05, 2.29175343e-05, 2.11740374e-05, 2.18799952e-05, - 2.29918419e-05, 2.48476696e-05, 2.84355855e-05, 3.03428570e-05, - 2.81962013e-05, 2.36676218e-05, 2.12033001e-05, 1.99578845e-05, - 1.98860927e-05, 2.08241391e-05, 2.55686848e-05, 2.65641227e-05, - 2.74462124e-05, 2.58138816e-05, 2.30085622e-05, 2.41617655e-05, - 2.30228605e-05, 2.07415531e-05, 2.65230000e-05, 2.71765568e-05, - 2.70376669e-05, 2.70612408e-05, 2.62062537e-05, 2.29506863e-05, - 2.14548026e-05, 2.23293549e-05, 2.64139448e-05, 2.82214368e-05, - 2.86211908e-05, 2.54480189e-05, 2.13179507e-05, 2.12340665e-05, - 2.19221321e-05, 2.46319839e-05, 2.66832738e-05, 2.82685751e-05, - 2.82240085e-05, 2.63142361e-05, 2.42977366e-05, 2.25658336e-05, - 2.07518509e-05, - 2.57623730e-05, 2.80118309e-05, 2.83967666e-05, 2.66972056e-05, - 2.44436954e-05, 2.28224492e-05, 2.18332784e-05, 2.19921722e-05, - 2.24515460e-05, 2.56187336e-05, 2.72272607e-05, 2.68779242e-05, - 2.55065568e-05, 2.52689686e-05, 2.50044476e-05, 2.30277993e-05, - 2.16434403e-05, 2.22689237e-05, 2.28227917e-05, 2.22542994e-05, - 2.60393317e-05, 2.74763135e-05, 2.78433579e-05, 2.56843742e-05, - 2.44061178e-05, 2.47856288e-05, 2.33288811e-05, 2.14590827e-05, - 2.08918057e-05, 2.74452903e-05, 2.89986756e-05, 2.86802779e-05, - 2.42141657e-05, 2.08289557e-05, 2.14353151e-05, 2.21315113e-05, - 2.17709472e-05, 2.16574206e-05, 2.36005407e-05, 2.62297036e-05, - 2.78518330e-05, 2.56697206e-05, 2.35032001e-05, 2.44990095e-05, - 2.53957178e-05, 2.39392591e-05, 2.21616361e-05, 2.14799564e-05, - 2.38074005e-05, 2.80604460e-05, 2.97309662e-05, 2.84689315e-05, - 2.52842754e-05, 2.17463138e-05, 2.07932961e-05, 2.14061909e-05, - 2.77557145e-05, 2.84136616e-05, 2.77714292e-05, 2.55363921e-05, - 2.25027583e-05, 2.03561571e-05, 2.00789507e-05, 2.13134124e-05, - 2.89135152e-05, 2.85908520e-05, 2.74884184e-05, 2.53312933e-05, - 2.13788812e-05, 1.99240074e-05, 2.11209139e-05, 2.19078787e-05, - 2.79478828e-05, 2.85312651e-05, 2.67324823e-05, 2.36242559e-05, - 2.32638756e-05, 2.38046686e-05, 2.29747202e-05, 2.60342192e-05, - 2.64301408e-05, 2.70037382e-05, 2.75791375e-05, 2.55656039e-05, - 2.23120114e-05, 2.16854373e-05, 2.20594131e-05, 2.56494166e-05, - 2.63895329e-05, 2.64547481e-05, 2.57720985e-05, 2.56711477e-05, - 2.55391327e-05, 2.33359361e-05, 2.21568483e-05, 2.52991871e-05, - 2.69628498e-05, 2.70030761e-05, 2.60065379e-05, 2.59318566e-05, - 2.51583973e-05, 2.33204008e-05, 2.19984535e-05, 2.20235372e-05, - 2.24069320e-05, 2.48764415e-05, 2.84096016e-05, 2.97908584e-05, - 2.83996099e-05, 2.36121482e-05, 2.17506579e-05, 2.39160969e-05, - 2.65481951e-05, 2.66970687e-05, 2.60111631e-05, 2.42268730e-05, - 2.42093200e-05, 2.42647014e-05, 2.26423876e-05, 2.20969140e-05, - 2.24644236e-05, 2.55906694e-05, 2.81846623e-05, 2.71938936e-05, - 2.53428064e-05, 2.36680683e-05, 2.23984359e-05, 2.21654089e-05, - 2.53381617e-05, 2.68176501e-05, 2.70339299e-05, 2.55230171e-05, - 2.40916742e-05, 2.33492307e-05, 2.19811069e-05, 2.27821527e-05, - 2.39588226e-05, 2.44953462e-05, 2.73330441e-05, 2.92699593e-05, - 2.77558849e-05, 2.37966113e-05, 2.17417820e-05, 2.08666781e-05, - 2.08750221e-05, 2.17571654e-05, 2.47565056e-05, 2.50596535e-05, - 2.62750440e-05, 2.55173071e-05, 2.36002088e-05, 2.53513222e-05, - 2.42975452e-05, 2.18443337e-05, 2.64069231e-05, 2.61842949e-05, - 2.59206683e-05, 2.63848228e-05, 2.61266432e-05, 2.33485693e-05, - 2.21475375e-05, 2.32096242e-05, 2.53075102e-05, 2.63720049e-05, - 2.76737147e-05, 2.57572041e-05, 2.21571440e-05, 2.21059285e-05, - 2.28283036e-05, 2.42729078e-05, 2.56664226e-05, 2.71388913e-05, - 2.75603970e-05, 2.65509258e-05, 2.50508456e-05, 2.34229803e-05, - 2.16369073e-05, - 2.56926275e-05, 2.87659390e-05, 2.93498661e-05, 2.75861427e-05, - 2.48840276e-05, 2.24462133e-05, 2.10511416e-05, 2.10751100e-05, - 2.13802045e-05, 2.53537542e-05, 2.74431628e-05, 2.69024782e-05, - 2.54252415e-05, 2.51729888e-05, 2.47921969e-05, 2.26443548e-05, - 2.09971281e-05, 2.14436502e-05, 2.18908079e-05, 2.11907753e-05, - 2.63202680e-05, 2.82673092e-05, 2.83398817e-05, 2.58791742e-05, - 2.44173881e-05, 2.44176604e-05, 2.24655317e-05, 2.03825535e-05, - 1.97493504e-05, 2.81362413e-05, 3.06936065e-05, 2.99119915e-05, - 2.45920397e-05, 2.06419923e-05, 2.06934417e-05, 2.10220901e-05, - 2.06200076e-05, 2.05194692e-05, 2.40354849e-05, 2.76193480e-05, - 2.91100924e-05, 2.61912441e-05, 2.33411300e-05, 2.38656193e-05, - 2.44632172e-05, 2.28315487e-05, 2.09279894e-05, 2.11023088e-05, - 2.41526570e-05, 2.91844510e-05, 3.11117653e-05, 2.94379150e-05, - 2.52845059e-05, 2.08856154e-05, 1.95388651e-05, 2.01462854e-05, - 2.81111215e-05, 2.99361168e-05, 2.92302323e-05, 2.62462271e-05, - 2.22919873e-05, 1.95323108e-05, 1.89957901e-05, 2.01672998e-05, - 2.93515645e-05, 3.03205824e-05, 2.91010425e-05, 2.58899709e-05, - 2.08811763e-05, 1.88779309e-05, 1.98889738e-05, 2.07680631e-05, - 2.91132972e-05, 3.06862582e-05, 2.82469932e-05, 2.42154393e-05, - 2.29131501e-05, 2.26192243e-05, 2.16434273e-05, 2.65577242e-05, - 2.78131311e-05, 2.83197391e-05, 2.81321949e-05, 2.50466979e-05, - 2.12999195e-05, 2.05473398e-05, 2.09439836e-05, 2.60307669e-05, - 2.74916786e-05, 2.74683050e-05, 2.63038315e-05, 2.55130349e-05, - 2.47417262e-05, 2.22630052e-05, 2.10557659e-05, 2.55358216e-05, - 2.78486063e-05, 2.78273609e-05, 2.67793767e-05, 2.62918232e-05, - 2.46753504e-05, 2.22926339e-05, 2.08509617e-05, 2.09025072e-05, - 2.31550316e-05, 2.67986960e-05, 3.04670416e-05, 3.09440286e-05, - 2.80344123e-05, 2.23578616e-05, 2.04842700e-05, 2.25856035e-05, - 2.72642530e-05, 2.83565207e-05, 2.71370767e-05, 2.45068070e-05, - 2.40215010e-05, 2.35487451e-05, 2.16305601e-05, 2.10395028e-05, - 2.31272382e-05, 2.68047720e-05, 2.93681771e-05, 2.77524186e-05, - 2.52172933e-05, 2.28055402e-05, 2.12293218e-05, 2.11002278e-05, - 2.54460615e-05, 2.77600650e-05, 2.80892982e-05, 2.62516670e-05, - 2.42312613e-05, 2.28067860e-05, 2.09743564e-05, 2.16593446e-05, - 2.27576778e-05, 2.49279431e-05, 2.87117379e-05, 3.06182009e-05, - 2.83059943e-05, 2.36295380e-05, 2.10654645e-05, 1.97340761e-05, - 1.96441601e-05, 2.05955015e-05, 2.57642936e-05, 2.69385960e-05, - 2.77370380e-05, 2.58825378e-05, 2.28606597e-05, 2.38786197e-05, - 2.27193043e-05, 2.04746068e-05, 2.65494043e-05, 2.74212356e-05, - 2.73136354e-05, 2.72264082e-05, 2.62231283e-05, 2.28479096e-05, - 2.12816134e-05, 2.21141756e-05, 2.66857249e-05, 2.86906804e-05, - 2.88586256e-05, 2.53704051e-05, 2.11110792e-05, 2.10196738e-05, - 2.17006116e-05, 2.47134895e-05, 2.69329509e-05, 2.85511333e-05, - 2.83891287e-05, 2.62555980e-05, 2.41143713e-05, 2.23562066e-05, - 2.05340299e-05, - 2.52901949e-05, 3.28030532e-05, 3.45984723e-05, 3.09426093e-05, - 2.51846143e-05, 1.98919395e-05, 1.73333201e-05, 1.71410827e-05, - 1.72774819e-05, 2.43340557e-05, 2.88808768e-05, 2.74829992e-05, - 2.48437544e-05, 2.44194180e-05, 2.35882372e-05, 2.01500080e-05, - 1.74934578e-05, 1.77633369e-05, 1.81629162e-05, 1.70504539e-05, - 2.71251996e-05, 3.19427421e-05, 3.12473129e-05, 2.61952109e-05, - 2.34991542e-05, 2.27070611e-05, 1.90376599e-05, 1.60262897e-05, - 1.51615516e-05, 3.14073940e-05, 4.04366804e-05, 3.67500909e-05, - 2.45835398e-05, 1.78471321e-05, 1.69478232e-05, 1.67657972e-05, - 1.62026119e-05, 1.60992017e-05, 2.38623644e-05, 3.25036102e-05, - 3.50871975e-05, 2.75041776e-05, 2.15592709e-05, 2.13857237e-05, - 2.16786734e-05, 1.91074039e-05, 1.64551682e-05, 1.80985239e-05, - 2.38361871e-05, 3.48018076e-05, 4.02389565e-05, 3.48342503e-05, - 2.48044409e-05, 1.69940580e-05, 1.47476994e-05, 1.54618819e-05, - 3.04398429e-05, 3.78605941e-05, 3.60305872e-05, 2.80790804e-05, - 1.99957223e-05, 1.53881590e-05, 1.43616634e-05, 1.56579100e-05, - 3.30411288e-05, 3.96131441e-05, 3.62930368e-05, 2.70951409e-05, - 1.76010078e-05, 1.42789326e-05, 1.51952422e-05, 1.64023809e-05, - 3.47875502e-05, 4.25172629e-05, 3.41496365e-05, 2.45004293e-05, - 2.05844464e-05, 1.86949731e-05, 1.71991229e-05, 2.81294577e-05, - 3.28584630e-05, 3.36473170e-05, 3.10146107e-05, 2.33381907e-05, - 1.72713015e-05, 1.61331549e-05, 1.66588587e-05, 2.68899158e-05, - 3.13857596e-05, 3.10828629e-05, 2.77193529e-05, 2.48123714e-05, - 2.23371729e-05, 1.84133322e-05, 1.68210969e-05, 2.57403036e-05, - 3.14228953e-05, 3.12066595e-05, 2.91672668e-05, 2.72708188e-05, - 2.28561859e-05, 1.85277808e-05, 1.64930958e-05, 1.65984355e-05, - 2.32657563e-05, 3.26567918e-05, 4.14253665e-05, 3.89133125e-05, - 2.84976448e-05, 1.82390054e-05, 1.58608457e-05, 1.84129608e-05, - 2.98740965e-05, 3.48665282e-05, 3.07987738e-05, 2.42284248e-05, - 2.24917940e-05, 2.07831457e-05, 1.76938165e-05, 1.68700125e-05, - 2.30261532e-05, 3.04503865e-05, 3.53879908e-05, 3.03292899e-05, - 2.44236460e-05, 1.94957372e-05, 1.69313656e-05, 1.69338574e-05, - 2.53006294e-05, 3.14207089e-05, 3.23821667e-05, 2.81374386e-05, - 2.34976526e-05, 2.00755367e-05, 1.68691996e-05, 1.75500803e-05, - 1.88521573e-05, 2.52354588e-05, 3.46527787e-05, 3.88456569e-05, - 3.13320701e-05, 2.19636283e-05, 1.75297664e-05, 1.51580455e-05, - 1.49061696e-05, 1.61559971e-05, 2.80505001e-05, 3.27796947e-05, - 3.29615640e-05, 2.66070760e-05, 1.97893326e-05, 1.99083796e-05, - 1.81927033e-05, 1.56950810e-05, 2.71730090e-05, 3.16561720e-05, - 3.19301372e-05, 3.01514914e-05, 2.65248185e-05, 2.02099116e-05, - 1.74876676e-05, 1.81815775e-05, 3.07198947e-05, 3.80823443e-05, - 3.43212695e-05, 2.41019766e-05, 1.69780207e-05, 1.67993820e-05, - 1.75949940e-05, 2.49180952e-05, 3.08383116e-05, 3.44320811e-05, - 3.22872909e-05, 2.56867923e-05, 2.11738122e-05, 1.85460009e-05, - 1.61712148e-05, - 2.52120675e-05, 3.13251894e-05, 3.27070343e-05, 3.04470029e-05, - 2.59165696e-05, 2.08311360e-05, 1.82906631e-05, 1.79772112e-05, - 1.79144931e-05, 2.42669755e-05, 2.80335112e-05, 2.68329510e-05, - 2.48848696e-05, 2.45658925e-05, 2.38101647e-05, 2.10211231e-05, - 1.85836973e-05, 1.85885821e-05, 1.87849279e-05, 1.77384072e-05, - 2.69873201e-05, 3.08802911e-05, 2.99601488e-05, 2.62275120e-05, - 2.40652960e-05, 2.29592206e-05, 1.95570070e-05, 1.68789554e-05, - 1.60797821e-05, 3.03846199e-05, 3.71682049e-05, 3.43970228e-05, - 2.53955582e-05, 1.94604502e-05, 1.80225610e-05, 1.74550058e-05, - 1.69452556e-05, 1.68732685e-05, 2.49733093e-05, 3.23259688e-05, - 3.35493853e-05, 2.76248073e-05, 2.23924847e-05, 2.16364675e-05, - 2.14852246e-05, 1.93290599e-05, 1.70658172e-05, 1.94113848e-05, - 2.48126045e-05, 3.31358973e-05, 3.64308884e-05, 3.28674160e-05, - 2.49759966e-05, 1.79216495e-05, 1.56100374e-05, 1.62108249e-05, - 2.92353309e-05, 3.55483724e-05, 3.44586283e-05, 2.83188559e-05, - 2.11334551e-05, 1.66222998e-05, 1.54557308e-05, 1.64954561e-05, - 3.09285202e-05, 3.68500560e-05, 3.49126732e-05, 2.74137347e-05, - 1.88549779e-05, 1.54232294e-05, 1.60145560e-05, 1.71227152e-05, - 3.32059034e-05, 3.91243072e-05, 3.35295038e-05, 2.56820086e-05, - 2.13978078e-05, 1.89195437e-05, 1.75699361e-05, 2.80394612e-05, - 3.25218426e-05, 3.28488119e-05, 2.99123329e-05, 2.32149639e-05, - 1.79756208e-05, 1.69013580e-05, 1.73606186e-05, 2.69884623e-05, - 3.11052474e-05, 3.07574667e-05, 2.77838205e-05, 2.47529090e-05, - 2.21341312e-05, 1.88231916e-05, 1.75094746e-05, 2.59807428e-05, - 3.07343127e-05, 3.04941195e-05, 2.91312279e-05, 2.72089124e-05, - 2.29142638e-05, 1.89648710e-05, 1.71893214e-05, 1.73048073e-05, - 2.50610015e-05, 3.35308687e-05, 3.84170971e-05, 3.53494332e-05, - 2.69291144e-05, 1.84845425e-05, 1.65385367e-05, 1.85396402e-05, - 2.94812876e-05, 3.42304733e-05, 3.07903916e-05, 2.49908625e-05, - 2.30485580e-05, 2.10797802e-05, 1.83177034e-05, 1.75976458e-05, - 2.47415626e-05, 3.07410320e-05, 3.35721972e-05, 2.94992573e-05, - 2.45265852e-05, 1.99152570e-05, 1.75255568e-05, 1.76413183e-05, - 2.54813620e-05, 3.08343875e-05, 3.16167825e-05, 2.83892444e-05, - 2.42539843e-05, 2.07576925e-05, 1.76533249e-05, 1.80780430e-05, - 1.90253362e-05, 2.59395716e-05, 3.35420260e-05, 3.56944975e-05, - 3.01006243e-05, 2.26873038e-05, 1.85768636e-05, 1.60872386e-05, - 1.57697730e-05, 1.68950377e-05, 2.88252686e-05, 3.35072179e-05, - 3.27391498e-05, 2.67724566e-05, 2.02908824e-05, 1.95445905e-05, - 1.81065769e-05, 1.62935216e-05, 2.68054263e-05, 3.15230119e-05, - 3.19909471e-05, 2.98733297e-05, 2.63014627e-05, 2.09145959e-05, - 1.83181557e-05, 1.86140254e-05, 3.12255492e-05, 3.74181416e-05, - 3.29812106e-05, 2.39358224e-05, 1.76986190e-05, 1.75079443e-05, - 1.81088383e-05, 2.57307179e-05, 3.10811323e-05, 3.34843503e-05, - 3.11519310e-05, 2.51642393e-05, 2.11051699e-05, 1.89350154e-05, - 1.69710618e-05, - 2.52123031e-05, 2.60242062e-05, 2.60469965e-05, 2.65541819e-05, - 2.61528279e-05, 2.42714993e-05, 2.30245421e-05, 2.27373126e-05, - 2.25091425e-05, 2.48576270e-05, 2.55659495e-05, 2.53250186e-05, - 2.51889530e-05, 2.51558193e-05, 2.49220042e-05, 2.42962968e-05, - 2.33089773e-05, 2.30538237e-05, 2.29622393e-05, 2.24615029e-05, - 2.57940945e-05, 2.62276201e-05, 2.58026642e-05, 2.56729619e-05, - 2.53215060e-05, 2.45970064e-05, 2.32630224e-05, 2.21387090e-05, - 2.17350299e-05, 2.61254359e-05, 2.58568140e-05, 2.60631939e-05, - 2.60359657e-05, 2.42653523e-05, 2.29967704e-05, 2.23045542e-05, - 2.20669758e-05, 2.20567211e-05, 2.61421237e-05, 2.72725433e-05, - 2.64991448e-05, 2.62158596e-05, 2.48711293e-05, 2.40157484e-05, - 2.35544409e-05, 2.28704608e-05, 2.20057816e-05, 2.39464908e-05, - 2.59650367e-05, 2.63131918e-05, 2.53573758e-05, 2.60270388e-05, - 2.53337656e-05, 2.27968925e-05, 2.13913342e-05, 2.16410268e-05, - 2.56564297e-05, 2.63060548e-05, 2.66578650e-05, 2.65312837e-05, - 2.45953167e-05, 2.23794896e-05, 2.15384949e-05, 2.18999870e-05, - 2.54393838e-05, 2.61814050e-05, 2.68878711e-05, 2.63108625e-05, - 2.36094965e-05, 2.15716410e-05, 2.15943409e-05, 2.21467703e-05, - 2.63921068e-05, 2.59940113e-05, 2.71939754e-05, 2.64580214e-05, - 2.44152031e-05, 2.26593718e-05, 2.20601548e-05, 2.61758232e-05, - 2.71933140e-05, 2.69096444e-05, 2.59324011e-05, 2.43803603e-05, - 2.26079427e-05, 2.20671064e-05, 2.22636795e-05, 2.59889028e-05, - 2.68957251e-05, 2.67705642e-05, 2.62207418e-05, 2.50536651e-05, - 2.38421276e-05, 2.27817334e-05, 2.23343288e-05, 2.57595384e-05, - 2.64795500e-05, 2.63967649e-05, 2.65506076e-05, 2.59304000e-05, - 2.44092075e-05, 2.28817257e-05, 2.21609763e-05, 2.22366413e-05, - 2.67809478e-05, 2.83629377e-05, 2.62032494e-05, 2.53550561e-05, - 2.46278579e-05, 2.24466706e-05, 2.17645618e-05, 2.23653705e-05, - 2.63667613e-05, 2.73236496e-05, 2.70299877e-05, 2.58451057e-05, - 2.49017295e-05, 2.37999012e-05, 2.27157680e-05, 2.24220993e-05, - 2.65943127e-05, 2.72557573e-05, 2.62949066e-05, 2.60266635e-05, - 2.51035866e-05, 2.33499257e-05, 2.22513157e-05, 2.24266608e-05, - 2.55293644e-05, 2.65858049e-05, 2.66454792e-05, 2.65626280e-05, - 2.55608806e-05, 2.39993532e-05, 2.25084919e-05, 2.24936574e-05, - 2.26674405e-05, 2.61371443e-05, 2.68211837e-05, 2.57149631e-05, - 2.58852724e-05, 2.48982785e-05, 2.32631973e-05, 2.17507698e-05, - 2.14908493e-05, 2.20343708e-05, 2.71226265e-05, 2.82417608e-05, - 2.73312086e-05, 2.59714537e-05, 2.36100112e-05, 2.24506470e-05, - 2.19299272e-05, 2.15391301e-05, 2.55446312e-05, 2.71162701e-05, - 2.73817779e-05, 2.65689011e-05, 2.54876350e-05, 2.40935678e-05, - 2.29155299e-05, 2.26921151e-05, 2.75506570e-05, 2.78270817e-05, - 2.65253789e-05, 2.46412174e-05, 2.24713356e-05, 2.23532651e-05, - 2.24969491e-05, 2.61563525e-05, 2.73042990e-05, 2.69333323e-05, - 2.62421937e-05, 2.48250516e-05, 2.34861357e-05, 2.28209902e-05, - 2.21388653e-05, - 2.52196950e-05, 2.84947936e-05, 2.91087159e-05, 2.87039162e-05, - 2.64972304e-05, 2.27159912e-05, 2.06278846e-05, 2.02384547e-05, - 1.99847374e-05, 2.45004847e-05, 2.66663211e-05, 2.59450364e-05, - 2.50758016e-05, 2.49254783e-05, 2.44073540e-05, 2.28029885e-05, - 2.10113061e-05, 2.07455131e-05, 2.07086060e-05, 1.98850182e-05, - 2.65073456e-05, 2.85280217e-05, 2.76910557e-05, 2.60898788e-05, - 2.49259432e-05, 2.37659802e-05, 2.12552772e-05, 1.93119744e-05, - 1.86833739e-05, 2.82123864e-05, 3.09242196e-05, 2.98696852e-05, - 2.61786880e-05, 2.22887176e-05, 2.05217352e-05, 1.96429769e-05, - 1.92567553e-05, 1.92263730e-05, 2.61435391e-05, 3.02825893e-05, - 2.99635505e-05, 2.72097743e-05, 2.38669161e-05, 2.27065333e-05, - 2.21755165e-05, 2.07791632e-05, 1.92278617e-05, 2.19315424e-05, - 2.58912800e-05, 2.95814110e-05, 3.00516118e-05, 2.91568188e-05, - 2.52641170e-05, 2.02843811e-05, 1.82108645e-05, 1.86225108e-05, - 2.72405030e-05, 3.06510424e-05, 3.05388198e-05, 2.78248844e-05, - 2.31590535e-05, 1.94913775e-05, 1.83212048e-05, 1.89629392e-05, - 2.77048600e-05, 3.11202405e-05, 3.09934592e-05, 2.72326392e-05, - 2.14081873e-05, 1.83469284e-05, 1.85228099e-05, 1.93877639e-05, - 2.96972333e-05, 3.20117668e-05, 3.07156207e-05, 2.67484935e-05, - 2.30511238e-05, 2.04372484e-05, 1.94264651e-05, 2.73268104e-05, - 3.02784483e-05, 3.01062762e-05, 2.78107544e-05, 2.36253536e-05, - 2.01041942e-05, 1.92447505e-05, 1.95743508e-05, 2.67189536e-05, - 2.93511896e-05, 2.90691323e-05, 2.72765137e-05, 2.48835579e-05, - 2.26915504e-05, 2.05336597e-05, 1.96889904e-05, 2.60917597e-05, - 2.87410099e-05, 2.85516265e-05, 2.81669771e-05, 2.67394658e-05, - 2.35517869e-05, 2.06794846e-05, 1.94209444e-05, 1.95308949e-05, - 2.68869074e-05, 3.20299588e-05, 3.18900992e-05, 2.95499943e-05, - 2.52465465e-05, 2.00886223e-05, 1.88366416e-05, 2.00224007e-05, - 2.81062304e-05, 3.11680650e-05, 2.93689454e-05, 2.58236721e-05, - 2.41216122e-05, 2.22976864e-05, 2.03151917e-05, 1.98042635e-05, - 2.65645410e-05, 2.95994325e-05, 2.97527141e-05, 2.77445655e-05, - 2.48554887e-05, 2.14568462e-05, 1.96085082e-05, 1.98214044e-05, - 2.56587975e-05, 2.88984663e-05, 2.92908875e-05, 2.78869101e-05, - 2.52517394e-05, 2.24037184e-05, 1.99091173e-05, 2.00163901e-05, - 2.04777658e-05, 2.64884752e-05, 3.03111089e-05, 3.00872990e-05, - 2.78371353e-05, 2.39951114e-05, 2.09611721e-05, 1.87014196e-05, - 1.83533526e-05, 1.92095231e-05, 2.86791199e-05, 3.18814581e-05, - 3.05247746e-05, 2.66181383e-05, 2.18461747e-05, 2.04186363e-05, - 1.94526013e-05, 1.85416098e-05, 2.61694723e-05, 2.97695140e-05, - 3.02618195e-05, 2.84856433e-05, 2.59179922e-05, 2.25535324e-05, - 2.05222659e-05, 2.03786822e-05, 3.01298102e-05, 3.31873953e-05, - 2.97439114e-05, 2.41534234e-05, 1.98837452e-05, 1.97079999e-05, - 2.00287759e-05, 2.64329465e-05, 2.97941511e-05, 3.04087375e-05, - 2.86571312e-05, 2.47904790e-05, 2.19793875e-05, 2.06078550e-05, - 1.93375194e-05, - 2.44914264e-05, 2.15656282e-05, 2.08155996e-05, 2.29726715e-05, - 2.56598353e-05, 2.69054531e-05, 2.72509769e-05, 2.70058524e-05, - 2.65646554e-05, 2.46399653e-05, 2.29397841e-05, 2.33979315e-05, - 2.47281662e-05, 2.49451271e-05, 2.51785462e-05, 2.67436955e-05, - 2.75176941e-05, 2.69298760e-05, 2.64753349e-05, 2.66884000e-05, - 2.41190010e-05, 2.21614373e-05, 2.20451144e-05, 2.45030022e-05, - 2.57227550e-05, 2.53437366e-05, 2.62017311e-05, 2.71186796e-05, - 2.73200520e-05, 2.23051012e-05, 1.84071984e-05, 1.99612563e-05, - 2.58944825e-05, 2.85608766e-05, 2.75456870e-05, 2.67065504e-05, - 2.68545710e-05, 2.69320274e-05, 2.64846975e-05, 2.29637806e-05, - 2.10491431e-05, 2.43842658e-05, 2.64674704e-05, 2.54932530e-05, - 2.47069402e-05, 2.56159112e-05, 2.65425328e-05, 2.78989980e-05, - 2.62872572e-05, 2.09891022e-05, 1.80393713e-05, 2.06981147e-05, - 2.49234837e-05, 2.72180205e-05, 2.71954154e-05, 2.68958776e-05, - 2.22719564e-05, 1.97556820e-05, 2.08093854e-05, 2.44201904e-05, - 2.72566552e-05, 2.80749939e-05, 2.78057170e-05, 2.71017475e-05, - 2.08738711e-05, 1.89879938e-05, 2.09188543e-05, 2.47191939e-05, - 2.78504813e-05, 2.79414824e-05, 2.70752096e-05, 2.67943363e-05, - 2.10716433e-05, 1.78051035e-05, 2.21304027e-05, 2.64507228e-05, - 2.65783944e-05, 2.56403832e-05, 2.59900470e-05, 2.39998748e-05, - 2.27174418e-05, 2.20743377e-05, 2.22891068e-05, 2.46736053e-05, - 2.67105663e-05, 2.69168437e-05, 2.67400030e-05, 2.44702916e-05, - 2.31128629e-05, 2.31301135e-05, 2.42716066e-05, 2.45865145e-05, - 2.46411244e-05, 2.60265134e-05, 2.67018635e-05, 2.48667120e-05, - 2.26643040e-05, 2.26814949e-05, 2.38616052e-05, 2.41924185e-05, - 2.50141787e-05, 2.60748882e-05, 2.67353863e-05, 2.67533596e-05, - 2.76656048e-05, 2.39911949e-05, 1.83592789e-05, 1.85032759e-05, - 2.21060195e-05, 2.56991701e-05, 2.67151269e-05, 2.54520848e-05, - 2.33024947e-05, 2.19402190e-05, 2.35410123e-05, 2.58903849e-05, - 2.58658150e-05, 2.56330350e-05, 2.65116577e-05, 2.67862536e-05, - 2.76026751e-05, 2.39537106e-05, 2.07276450e-05, 2.27162664e-05, - 2.48800683e-05, 2.59720588e-05, 2.64880246e-05, 2.67379691e-05, - 2.48573620e-05, 2.27752942e-05, 2.23847076e-05, 2.44230643e-05, - 2.60160715e-05, 2.64062732e-05, 2.69114008e-05, 2.63164329e-05, - 2.55319884e-05, 2.56102850e-05, 2.15457927e-05, 1.88511739e-05, - 2.20914353e-05, 2.62201567e-05, 2.74218220e-05, 2.73472298e-05, - 2.71940862e-05, 2.68482794e-05, 2.50902147e-05, 2.38091431e-05, - 2.28079404e-05, 2.46102284e-05, 2.61013433e-05, 2.44732543e-05, - 2.50183523e-05, 2.65301004e-05, 2.38113946e-05, 2.32095688e-05, - 2.33494231e-05, 2.33784024e-05, 2.41040402e-05, 2.64313230e-05, - 2.69652141e-05, 2.60849859e-05, 2.41261829e-05, 2.10561429e-05, - 2.14001384e-05, 2.45205603e-05, 2.67643314e-05, 2.67478944e-05, - 2.62842454e-05, 2.58284282e-05, 2.38082702e-05, 2.17508049e-05, - 2.20182888e-05, 2.38107789e-05, 2.49570471e-05, 2.59770961e-05, - 2.69882068e-05, - 2.33781273e-05, 1.78015311e-05, 1.66254280e-05, 1.94756098e-05, - 2.42255477e-05, 2.87078942e-05, 3.10878381e-05, 3.10595193e-05, - 3.05788711e-05, 2.40440404e-05, 2.04376902e-05, 2.14414800e-05, - 2.38015594e-05, 2.42051103e-05, 2.48804638e-05, 2.83893281e-05, - 3.11595351e-05, 3.04561610e-05, 2.97559194e-05, 3.08794507e-05, - 2.21059706e-05, 1.85317100e-05, 1.87675092e-05, 2.28705100e-05, - 2.53176068e-05, 2.55624763e-05, 2.88335289e-05, 3.21735721e-05, - 3.31865782e-05, 1.88566598e-05, 1.31973594e-05, 1.53184705e-05, - 2.47495745e-05, 3.16567423e-05, 3.16710318e-05, 3.11476686e-05, - 3.17856909e-05, 3.19475441e-05, 2.56022739e-05, 1.87566969e-05, - 1.65688288e-05, 2.20741127e-05, 2.71527979e-05, 2.65601506e-05, - 2.57702024e-05, 2.83158163e-05, 3.12905180e-05, 3.09286831e-05, - 2.54866520e-05, 1.66466918e-05, 1.30601658e-05, 1.64643602e-05, - 2.39589383e-05, 3.13635513e-05, 3.34972431e-05, 3.25246661e-05, - 1.92735531e-05, 1.48040095e-05, 1.60662680e-05, 2.17902786e-05, - 2.88887030e-05, 3.36002278e-05, 3.44345660e-05, 3.25113480e-05, - 1.72815870e-05, 1.37806283e-05, 1.60264956e-05, 2.25114829e-05, - 3.13269237e-05, 3.46417591e-05, 3.29414920e-05, 3.15505770e-05, - 1.67001109e-05, 1.22253923e-05, 1.75654831e-05, 2.51697993e-05, - 2.79404900e-05, 2.86559634e-05, 3.01701210e-05, 2.14976907e-05, - 1.84566647e-05, 1.77454219e-05, 1.90232808e-05, 2.46769372e-05, - 3.07038741e-05, 3.19029546e-05, 3.12717354e-05, 2.24633351e-05, - 1.93540766e-05, 1.95052032e-05, 2.18869358e-05, 2.37223593e-05, - 2.52886099e-05, 2.91911144e-05, 3.10942702e-05, 2.33715562e-05, - 1.90682444e-05, 1.91771489e-05, 2.08796588e-05, 2.20756014e-05, - 2.52279603e-05, 2.91379023e-05, 3.14182062e-05, 3.13375315e-05, - 2.67837890e-05, 1.92643221e-05, 1.28547585e-05, 1.37453759e-05, - 2.00723871e-05, 2.90661386e-05, 3.19873015e-05, 2.87253673e-05, - 2.01844178e-05, 1.71605542e-05, 1.98849483e-05, 2.49688835e-05, - 2.60789046e-05, 2.70884930e-05, 3.01782233e-05, 3.11204834e-05, - 2.69082017e-05, 2.02986790e-05, 1.62670440e-05, 1.96036889e-05, - 2.41574888e-05, 2.82989003e-05, 3.08185689e-05, 3.10236510e-05, - 2.36208114e-05, 1.91361524e-05, 1.84723290e-05, 2.17612083e-05, - 2.55211995e-05, 2.81922375e-05, 3.12245338e-05, 3.01409674e-05, - 2.84458626e-05, 2.41621845e-05, 1.70261420e-05, 1.39626838e-05, - 1.87586120e-05, 2.66918538e-05, 3.10513473e-05, 3.32134967e-05, - 3.33346777e-05, 3.18237534e-05, 2.22219855e-05, 1.91069783e-05, - 1.84629410e-05, 2.27110325e-05, 2.81758511e-05, 2.68077248e-05, - 2.85413853e-05, 3.19849230e-05, 2.18780212e-05, 1.92860463e-05, - 1.92408340e-05, 2.00972540e-05, 2.24219354e-05, 2.81100621e-05, - 3.07223526e-05, 2.94263368e-05, 2.02681132e-05, 1.54173044e-05, - 1.70770144e-05, 2.40995009e-05, 3.10061740e-05, 3.11519095e-05, - 3.00764782e-05, 2.44991568e-05, 2.00242251e-05, 1.72329408e-05, - 1.82947937e-05, 2.26851942e-05, 2.63015320e-05, 2.90449087e-05, - 3.19275020e-05, - 2.55236231e-05, 2.94298910e-05, 3.02193749e-05, 2.85747524e-05, - 2.54848311e-05, 2.20893071e-05, 2.02380957e-05, 2.00890079e-05, - 2.01851417e-05, 2.49499485e-05, 2.75065397e-05, 2.67573031e-05, - 2.52618841e-05, 2.50094077e-05, 2.45008176e-05, 2.22662277e-05, - 2.03622194e-05, 2.05556061e-05, 2.08437870e-05, 2.00150314e-05, - 2.65771466e-05, 2.90410929e-05, 2.86951981e-05, 2.60553502e-05, - 2.44559217e-05, 2.39457814e-05, 2.14737271e-05, 1.92295137e-05, - 1.85429595e-05, 2.87841945e-05, 3.24028095e-05, 3.10954380e-05, - 2.51273757e-05, 2.06371951e-05, 1.99495275e-05, 1.97976735e-05, - 1.93636672e-05, 1.92839119e-05, 2.46939262e-05, 2.93342214e-05, - 3.04444730e-05, 2.67956792e-05, 2.32172069e-05, 2.30835731e-05, - 2.32596213e-05, 2.15118124e-05, 1.95551258e-05, 2.08166194e-05, - 2.46750810e-05, 3.03170757e-05, 3.23066530e-05, 3.03180813e-05, - 2.52426603e-05, 1.99803092e-05, 1.82042491e-05, 1.87782547e-05, - 2.82972973e-05, 3.15292857e-05, 3.08373722e-05, 2.71133495e-05, - 2.21663576e-05, 1.87351245e-05, 1.78939822e-05, 1.89378936e-05, - 2.95105038e-05, 3.21465670e-05, 3.09511850e-05, 2.65739843e-05, - 2.04468639e-05, 1.78268340e-05, 1.85666046e-05, 1.95183902e-05, - 3.03143457e-05, 3.30488823e-05, 3.00692849e-05, 2.50845832e-05, - 2.25624589e-05, 2.12156694e-05, 2.01151544e-05, 2.71312255e-05, - 2.94948919e-05, 2.98405807e-05, 2.85883553e-05, 2.43317333e-05, - 2.01829407e-05, 1.93102927e-05, 1.97159551e-05, 2.64526711e-05, - 2.87984713e-05, 2.86490955e-05, 2.69124219e-05, 2.52395052e-05, - 2.36899428e-05, 2.10189255e-05, 1.98400320e-05, 2.57983785e-05, - 2.88038428e-05, 2.86974616e-05, 2.76854078e-05, 2.66608292e-05, - 2.40339213e-05, 2.11032720e-05, 1.95877987e-05, 1.96695659e-05, - 2.43329286e-05, 2.94250748e-05, 3.27356486e-05, 3.18558796e-05, - 2.72680779e-05, 2.08846046e-05, 1.90927137e-05, 2.10064966e-05, - 2.80405297e-05, 3.03801074e-05, 2.85175881e-05, 2.49108364e-05, - 2.38175477e-05, 2.26805026e-05, 2.04968985e-05, 1.98789009e-05, - 2.41813666e-05, 2.83510556e-05, 3.05606561e-05, 2.82566793e-05, - 2.50105030e-05, 2.17951652e-05, 1.99207634e-05, 1.99269357e-05, - 2.55384623e-05, 2.88061702e-05, 2.92600997e-05, 2.71452512e-05, - 2.44600381e-05, 2.22091554e-05, 1.98802861e-05, 2.03859031e-05, - 2.13267966e-05, 2.55142761e-05, 3.02735494e-05, 3.18543436e-05, - 2.87390525e-05, 2.34799901e-05, 2.03881949e-05, 1.85405078e-05, - 1.83337823e-05, 1.93270927e-05, 2.71098961e-05, 2.94800134e-05, - 2.95453534e-05, 2.62948030e-05, 2.20041529e-05, 2.20492198e-05, - 2.08348515e-05, 1.89581972e-05, 2.65958233e-05, 2.89333257e-05, - 2.90693273e-05, 2.81854764e-05, 2.62353595e-05, 2.23026503e-05, - 2.03500384e-05, 2.08502940e-05, 2.84899099e-05, 3.16671406e-05, - 3.01209583e-05, 2.48042507e-05, 1.99610879e-05, 1.98241406e-05, - 2.04189502e-05, 2.53281658e-05, 2.85431764e-05, 3.01830992e-05, - 2.92020952e-05, 2.57397545e-05, 2.29290935e-05, 2.11145978e-05, - 1.93412144e-05, - 2.50942402e-05, 2.35599401e-05, 2.30900238e-05, 2.37724696e-05, - 2.46984432e-05, 2.54364777e-05, 2.56064955e-05, 2.57042389e-05, - 2.58491108e-05, 2.53016479e-05, 2.45251589e-05, 2.48248196e-05, - 2.51331956e-05, 2.51695222e-05, 2.52991204e-05, 2.54529321e-05, - 2.55016242e-05, 2.56860677e-05, 2.58088248e-05, 2.58196570e-05, - 2.46791182e-05, 2.36850141e-05, 2.39922674e-05, 2.48264251e-05, - 2.51246721e-05, 2.54497678e-05, 2.58065699e-05, 2.57055503e-05, - 2.56291813e-05, 2.38389084e-05, 2.12552908e-05, 2.24550981e-05, - 2.47794525e-05, 2.51035614e-05, 2.55270763e-05, 2.58273149e-05, - 2.57937811e-05, 2.57688509e-05, 2.47536084e-05, 2.31695541e-05, - 2.27996831e-05, 2.44609474e-05, 2.52934101e-05, 2.56762127e-05, - 2.58954081e-05, 2.60025521e-05, 2.58951108e-05, 2.53141626e-05, - 2.48331599e-05, 2.29428646e-05, 2.14730210e-05, 2.30317698e-05, - 2.50734780e-05, 2.56387759e-05, 2.56549750e-05, 2.57809605e-05, - 2.42111714e-05, 2.20219935e-05, 2.24750920e-05, 2.42583123e-05, - 2.52943211e-05, 2.53752240e-05, 2.54240275e-05, 2.57125485e-05, - 2.37069535e-05, 2.14597165e-05, 2.23189961e-05, 2.44691054e-05, - 2.53762436e-05, 2.53719183e-05, 2.57137936e-05, 2.58098749e-05, - 2.29195224e-05, 2.04024019e-05, 2.28036743e-05, 2.45963451e-05, - 2.54382408e-05, 2.60436818e-05, 2.60525317e-05, 2.43960774e-05, - 2.31186540e-05, 2.30339952e-05, 2.39927341e-05, 2.55405414e-05, - 2.57988574e-05, 2.57735584e-05, 2.58201214e-05, 2.46252343e-05, - 2.35525054e-05, 2.36616528e-05, 2.44321620e-05, 2.51926955e-05, - 2.57811628e-05, 2.59401128e-05, 2.58264909e-05, 2.48289576e-05, - 2.37030482e-05, 2.37790567e-05, 2.40914412e-05, 2.46061628e-05, - 2.55331372e-05, 2.59110326e-05, 2.58275219e-05, 2.58177644e-05, - 2.44666239e-05, 2.27152783e-05, 2.07769772e-05, 2.19554386e-05, - 2.49470600e-05, 2.60714047e-05, 2.58454063e-05, 2.61394346e-05, - 2.40452654e-05, 2.25688326e-05, 2.36165832e-05, 2.48764341e-05, - 2.53110472e-05, 2.57392500e-05, 2.58376618e-05, 2.57950099e-05, - 2.45493439e-05, 2.35926218e-05, 2.27847582e-05, 2.40928060e-05, - 2.51918311e-05, 2.58259008e-05, 2.58951908e-05, 2.58086070e-05, - 2.49590886e-05, 2.36633615e-05, 2.34320089e-05, 2.42376881e-05, - 2.50183086e-05, 2.55851737e-05, 2.57516861e-05, 2.59164994e-05, - 2.60630973e-05, 2.47022284e-05, 2.28057714e-05, 2.18722907e-05, - 2.39438408e-05, 2.52986906e-05, 2.55324909e-05, 2.56197878e-05, - 2.56629202e-05, 2.57967803e-05, 2.40179129e-05, 2.27356233e-05, - 2.30429922e-05, 2.46620108e-05, 2.57376039e-05, 2.62872864e-05, - 2.63104305e-05, 2.59084748e-05, 2.47751979e-05, 2.34121460e-05, - 2.32525949e-05, 2.39168226e-05, 2.48710291e-05, 2.55544539e-05, - 2.56953657e-05, 2.59430865e-05, 2.34262468e-05, 2.14431869e-05, - 2.29985945e-05, 2.54046198e-05, 2.57972147e-05, 2.58115459e-05, - 2.59243214e-05, 2.47114114e-05, 2.35015639e-05, 2.28244742e-05, - 2.36021006e-05, 2.52243620e-05, 2.59056679e-05, 2.59431366e-05, - 2.57483349e-05, - 2.52532565e-05, 2.44840507e-05, 2.41721611e-05, 2.45100768e-05, - 2.48360141e-05, 2.49373727e-05, 2.47626791e-05, 2.48318987e-05, - 2.49936583e-05, 2.53524054e-05, 2.50745580e-05, 2.52289214e-05, - 2.52406085e-05, 2.52274828e-05, 2.52600358e-05, 2.49870769e-05, - 2.46818196e-05, 2.49005119e-05, 2.50767209e-05, 2.49326602e-05, - 2.50369141e-05, 2.45246952e-05, 2.47751916e-05, 2.50829264e-05, - 2.50721091e-05, 2.53055432e-05, 2.51930871e-05, 2.46742121e-05, - 2.44727850e-05, 2.46301033e-05, 2.27814137e-05, 2.37122630e-05, - 2.48492753e-05, 2.43396353e-05, 2.46309719e-05, 2.48998106e-05, - 2.47860624e-05, 2.47466798e-05, 2.47393401e-05, 2.40384309e-05, - 2.39109556e-05, 2.48538359e-05, 2.50058361e-05, 2.53690479e-05, - 2.56281860e-05, 2.53979070e-05, 2.49219047e-05, 2.45800062e-05, - 2.48167334e-05, 2.40351620e-05, 2.30030572e-05, 2.41344628e-05, - 2.51748379e-05, 2.47469658e-05, 2.44357928e-05, 2.46651303e-05, - 2.49180008e-05, 2.33560092e-05, 2.36588546e-05, 2.47077573e-05, - 2.48093976e-05, 2.42597176e-05, 2.41537830e-05, 2.46272983e-05, - 2.46676243e-05, 2.29210514e-05, 2.35172989e-05, 2.48166841e-05, - 2.45735133e-05, 2.40909139e-05, 2.45600867e-05, 2.48306588e-05, - 2.40085462e-05, 2.20495475e-05, 2.38188183e-05, 2.46539298e-05, - 2.50280998e-05, 2.53828954e-05, 2.51834022e-05, 2.48560879e-05, - 2.40210862e-05, 2.40124428e-05, 2.47502122e-05, 2.54755561e-05, - 2.49432693e-05, 2.47562081e-05, 2.48774878e-05, 2.49546383e-05, - 2.43256668e-05, 2.44084756e-05, 2.48479915e-05, 2.52978714e-05, - 2.55959369e-05, 2.52412626e-05, 2.49068723e-05, 2.50332520e-05, - 2.44881688e-05, 2.45452499e-05, 2.46530904e-05, 2.49778782e-05, - 2.54085824e-05, 2.52280065e-05, 2.48610097e-05, 2.48665338e-05, - 2.43811648e-05, 2.35766188e-05, 2.23533592e-05, 2.33953057e-05, - 2.54743396e-05, 2.53478087e-05, 2.47868358e-05, 2.54396147e-05, - 2.46814634e-05, 2.36410920e-05, 2.43312758e-05, 2.49064824e-05, - 2.51387106e-05, 2.53552954e-05, 2.50405235e-05, 2.48828774e-05, - 2.44362917e-05, 2.42697496e-05, 2.39263512e-05, 2.47809352e-05, - 2.52507846e-05, 2.52735365e-05, 2.49901391e-05, 2.49052954e-05, - 2.51158027e-05, 2.44460729e-05, 2.43031887e-05, 2.46928035e-05, - 2.49641646e-05, 2.51093666e-05, 2.48401968e-05, 2.50983941e-05, - 2.54237255e-05, 2.48456948e-05, 2.38724989e-05, 2.32956484e-05, - 2.47331016e-05, 2.50612555e-05, 2.47171461e-05, 2.44631352e-05, - 2.44673770e-05, 2.47822493e-05, 2.44564408e-05, 2.36100313e-05, - 2.39516746e-05, 2.49605720e-05, 2.52241819e-05, 2.57919540e-05, - 2.55796303e-05, 2.48241663e-05, 2.51418878e-05, 2.42063570e-05, - 2.40670010e-05, 2.45768974e-05, 2.51668167e-05, 2.50961002e-05, - 2.48715417e-05, 2.52123794e-05, 2.41242383e-05, 2.27501397e-05, - 2.40446117e-05, 2.54298397e-05, 2.49003437e-05, 2.48890952e-05, - 2.51124058e-05, 2.48186567e-05, 2.42151038e-05, 2.38698199e-05, - 2.44735903e-05, 2.54341129e-05, 2.55735486e-05, 2.52624132e-05, - 2.47370344e-05, - 2.53482287e-05, 2.57036578e-05, 2.56321172e-05, 2.57368521e-05, - 2.53523764e-05, 2.43365610e-05, 2.35618821e-05, 2.34914693e-05, - 2.35324031e-05, 2.52152212e-05, 2.56487486e-05, 2.55586700e-05, - 2.52925917e-05, 2.52352175e-05, 2.51068398e-05, 2.44022296e-05, - 2.36194327e-05, 2.37039344e-05, 2.38270835e-05, 2.34542501e-05, - 2.55463685e-05, 2.57268109e-05, 2.57123850e-05, 2.54590535e-05, - 2.51005383e-05, 2.49512996e-05, 2.40893666e-05, 2.30752585e-05, - 2.27205178e-05, 2.57256027e-05, 2.50134015e-05, 2.54749562e-05, - 2.52718059e-05, 2.37396164e-05, 2.34285417e-05, 2.33511981e-05, - 2.31403728e-05, 2.31011699e-05, 2.51651348e-05, 2.57466992e-05, - 2.56234505e-05, 2.55853211e-05, 2.47334718e-05, 2.46797462e-05, - 2.47234932e-05, 2.40965450e-05, 2.32318673e-05, 2.38208405e-05, - 2.51605793e-05, 2.56329363e-05, 2.50074888e-05, 2.56175412e-05, - 2.52910844e-05, 2.34417791e-05, 2.25364218e-05, 2.28416388e-05, - 2.56991084e-05, 2.53764833e-05, 2.55633217e-05, 2.56307917e-05, - 2.43660781e-05, 2.28247112e-05, 2.23674811e-05, 2.29263707e-05, - 2.56665503e-05, 2.51529345e-05, 2.55505263e-05, 2.55542711e-05, - 2.36578491e-05, 2.23300753e-05, 2.27313863e-05, 2.32164030e-05, - 2.56371279e-05, 2.46666022e-05, 2.56950491e-05, 2.52610975e-05, - 2.45093988e-05, 2.39745748e-05, 2.34925147e-05, 2.56274663e-05, - 2.57385909e-05, 2.57088526e-05, 2.57169718e-05, 2.50512895e-05, - 2.35327943e-05, 2.31142603e-05, 2.33121806e-05, 2.55310825e-05, - 2.57474393e-05, 2.57432029e-05, 2.56011262e-05, 2.52848154e-05, - 2.48602622e-05, 2.38972220e-05, 2.33714298e-05, 2.54128291e-05, - 2.57373514e-05, 2.57343271e-05, 2.56899042e-05, 2.55613610e-05, - 2.49721479e-05, 2.39337919e-05, 2.32498676e-05, 2.32898490e-05, - 2.50608155e-05, 2.57478804e-05, 2.48749803e-05, 2.51913952e-05, - 2.55847894e-05, 2.38342856e-05, 2.30024220e-05, 2.38823734e-05, - 2.57113430e-05, 2.56612105e-05, 2.57447257e-05, 2.52194553e-05, - 2.49187569e-05, 2.45422674e-05, 2.36741086e-05, 2.33907427e-05, - 2.50204869e-05, 2.57411329e-05, 2.55950753e-05, 2.57119088e-05, - 2.52344907e-05, 2.42153456e-05, 2.34076425e-05, 2.34131232e-05, - 2.53574153e-05, 2.57403187e-05, 2.57349682e-05, 2.56349942e-05, - 2.51033620e-05, 2.43789137e-05, 2.33924434e-05, 2.36217347e-05, - 2.40190370e-05, 2.53586133e-05, 2.56602958e-05, 2.52258917e-05, - 2.57160325e-05, 2.48169331e-05, 2.36309737e-05, 2.27193758e-05, - 2.26070923e-05, 2.31220642e-05, 2.56337122e-05, 2.57466117e-05, - 2.57384586e-05, 2.55052749e-05, 2.42982285e-05, 2.42836798e-05, - 2.37987428e-05, 2.29313524e-05, 2.55430503e-05, 2.57515824e-05, - 2.57542110e-05, 2.57236320e-05, 2.54859026e-05, 2.44139073e-05, - 2.36115028e-05, 2.38253005e-05, 2.57481332e-05, 2.53999729e-05, - 2.56674317e-05, 2.51756665e-05, 2.34295226e-05, 2.33642650e-05, - 2.36363415e-05, 2.53180291e-05, 2.57485266e-05, 2.56751798e-05, - 2.57230796e-05, 2.53797076e-05, 2.46172653e-05, 2.39372477e-05, - 2.31302978e-05, - 2.40910954e-05, 1.97174170e-05, 1.87256668e-05, 2.08139625e-05, - 2.42205542e-05, 2.75305133e-05, 2.91989473e-05, 2.93090720e-05, - 2.91887587e-05, 2.46627983e-05, 2.19349714e-05, 2.27503692e-05, - 2.43693441e-05, 2.46345708e-05, 2.51453116e-05, 2.73583988e-05, - 2.91090901e-05, 2.88991690e-05, 2.86096555e-05, 2.93457555e-05, - 2.30080622e-05, 2.02197130e-05, 2.05779597e-05, 2.35668879e-05, - 2.52323087e-05, 2.56875791e-05, 2.80295828e-05, 3.00478181e-05, - 3.06333447e-05, 2.05154701e-05, 1.56213489e-05, 1.75658756e-05, - 2.45885515e-05, 2.89170174e-05, 2.94681951e-05, 2.95327389e-05, - 2.99126560e-05, 2.99863820e-05, 2.50449829e-05, 1.99729370e-05, - 1.84984764e-05, 2.28088475e-05, 2.64600106e-05, 2.65056485e-05, - 2.62583271e-05, 2.79372455e-05, 2.97226759e-05, 2.87309841e-05, - 2.50541308e-05, 1.86384727e-05, 1.56698046e-05, 1.85949894e-05, - 2.44057679e-05, 2.94188015e-05, 3.08987183e-05, 3.04032962e-05, - 2.10292451e-05, 1.70000339e-05, 1.80012550e-05, 2.24839847e-05, - 2.74807094e-05, 3.05282469e-05, 3.11973097e-05, 3.02895009e-05, - 1.95243987e-05, 1.60753905e-05, 1.78770170e-05, 2.30609788e-05, - 2.90544766e-05, 3.12607804e-05, 3.05932425e-05, 2.97770885e-05, - 1.86528813e-05, 1.45766185e-05, 1.90572946e-05, 2.46574151e-05, - 2.70754217e-05, 2.82007036e-05, 2.91911710e-05, 2.24318575e-05, - 1.97708381e-05, 1.93167044e-05, 2.07234738e-05, 2.52561256e-05, - 2.92036801e-05, 2.99629403e-05, 2.96051333e-05, 2.31649876e-05, - 2.05827516e-05, 2.07477887e-05, 2.26800227e-05, 2.43774522e-05, - 2.58534528e-05, 2.84138956e-05, 2.94962890e-05, 2.38535654e-05, - 2.05344326e-05, 2.06516753e-05, 2.18425420e-05, 2.29300605e-05, - 2.55728255e-05, 2.83447509e-05, 2.97131877e-05, 2.96456495e-05, - 2.54339946e-05, 1.99227561e-05, 1.51481265e-05, 1.63532137e-05, - 2.20591891e-05, 2.84963676e-05, 3.01262080e-05, 2.83619159e-05, - 2.14176734e-05, 1.86729377e-05, 2.09248066e-05, 2.48013563e-05, - 2.58523825e-05, 2.68890000e-05, 2.89149691e-05, 2.94706605e-05, - 2.55823275e-05, 2.11350241e-05, 1.83183848e-05, 2.11270609e-05, - 2.46275800e-05, 2.77216457e-05, 2.94077154e-05, 2.94254378e-05, - 2.41100033e-05, 2.05431833e-05, 2.00036992e-05, 2.24510330e-05, - 2.52480458e-05, 2.73859578e-05, 2.94801851e-05, 2.89925966e-05, - 2.80910112e-05, 2.41882973e-05, 1.87588633e-05, 1.64281405e-05, - 2.05372120e-05, 2.61966837e-05, 2.90802990e-05, 3.06375572e-05, - 3.07935504e-05, 2.99427818e-05, 2.25277518e-05, 1.98524607e-05, - 1.97204759e-05, 2.33359065e-05, 2.75459956e-05, 2.73191534e-05, - 2.84561292e-05, 3.02196226e-05, 2.29586688e-05, 2.04415948e-05, - 2.02997656e-05, 2.12704002e-05, 2.33496165e-05, 2.73027590e-05, - 2.90805553e-05, 2.85671065e-05, 2.09921780e-05, 1.69789161e-05, - 1.89185651e-05, 2.47901649e-05, 2.93985827e-05, 2.95139294e-05, - 2.89609589e-05, 2.43859863e-05, 2.09151507e-05, 1.88869096e-05, - 2.00262861e-05, 2.38060309e-05, 2.65902799e-05, 2.83250478e-05, - 2.99431670e-05, - 2.24751016e-05, 1.56203896e-05, 1.42927664e-05, 1.71312013e-05, - 2.26098396e-05, 2.92889996e-05, 3.33411561e-05, 3.36673833e-05, - 3.34170380e-05, 2.35320660e-05, 1.88915079e-05, 2.02061084e-05, - 2.29682451e-05, 2.34470539e-05, 2.44103412e-05, 2.89137840e-05, - 3.30706504e-05, 3.26082318e-05, 3.19382870e-05, 3.38143954e-05, - 2.05819189e-05, 1.63043713e-05, 1.68461018e-05, 2.15256405e-05, - 2.45274837e-05, 2.54772196e-05, 3.05506973e-05, 3.56779820e-05, - 3.73518425e-05, 1.67317942e-05, 1.05746990e-05, 1.28268901e-05, - 2.32749919e-05, 3.24597994e-05, 3.40145558e-05, 3.43156066e-05, - 3.53408799e-05, 3.55354658e-05, 2.40975629e-05, 1.58920366e-05, - 1.39710599e-05, 2.02198040e-05, 2.69671378e-05, 2.71741127e-05, - 2.67461226e-05, 3.04151440e-05, 3.48650135e-05, 3.20597505e-05, - 2.41307936e-05, 1.41627670e-05, 1.06528534e-05, 1.41244515e-05, - 2.30174846e-05, 3.39286554e-05, 3.81825667e-05, 3.67452039e-05, - 1.75150655e-05, 1.21313955e-05, 1.33321172e-05, 1.96723460e-05, - 2.91374774e-05, 3.69164272e-05, 3.90031504e-05, 3.63750883e-05, - 1.53994165e-05, 1.10666011e-05, 1.31651286e-05, 2.06236973e-05, - 3.28879708e-05, 3.91806718e-05, 3.72761522e-05, 3.49723585e-05, - 1.41765998e-05, 9.44749660e-06, 1.46586671e-05, 2.33620319e-05, - 2.82957020e-05, 3.10510581e-05, 3.35208144e-05, 1.96180300e-05, - 1.56182110e-05, 1.50197085e-05, 1.70460051e-05, 2.46849108e-05, - 3.34333771e-05, 3.54718360e-05, 3.45074915e-05, 2.08230605e-05, - 1.67744774e-05, 1.70203724e-05, 2.00111941e-05, 2.29975934e-05, - 2.59025623e-05, 3.15165920e-05, 3.42174406e-05, 2.20072830e-05, - 1.67334172e-05, 1.69076237e-05, 1.86678982e-05, 2.04418280e-05, - 2.52812954e-05, 3.13377387e-05, 3.48053441e-05, 3.46163005e-05, - 2.47726451e-05, 1.57653601e-05, 1.00436804e-05, 1.14261633e-05, - 1.91763359e-05, 3.17756228e-05, 3.59725295e-05, 3.14810631e-05, - 1.80365002e-05, 1.41499115e-05, 1.72603353e-05, 2.36781672e-05, - 2.57584365e-05, 2.79944284e-05, 3.27106725e-05, 3.41343622e-05, - 2.50695417e-05, 1.75542795e-05, 1.37529321e-05, 1.76295650e-05, - 2.34402425e-05, 2.98501139e-05, 3.40137382e-05, 3.40201991e-05, - 2.24751617e-05, 1.67385721e-05, 1.59735304e-05, 1.96175210e-05, - 2.45315608e-05, 2.90156974e-05, 3.41401682e-05, 3.29427691e-05, - 3.08003822e-05, 2.25545437e-05, 1.42887922e-05, 1.14930485e-05, - 1.67811356e-05, 2.64358848e-05, 3.30084170e-05, 3.73596550e-05, - 3.78598532e-05, 3.54267726e-05, 1.96986944e-05, 1.56744374e-05, - 1.55413569e-05, 2.11090002e-05, 2.94223203e-05, 2.91426548e-05, - 3.17954657e-05, 3.62773027e-05, 2.05242721e-05, 1.65590029e-05, - 1.63422783e-05, 1.78013445e-05, 2.11775484e-05, 2.88233725e-05, - 3.30721663e-05, 3.18907491e-05, 1.73264706e-05, 1.20359786e-05, - 1.45149444e-05, 2.37894829e-05, 3.39437767e-05, 3.42577220e-05, - 3.28657420e-05, 2.29019950e-05, 1.72288741e-05, 1.44494115e-05, - 1.60322895e-05, 2.20230752e-05, 2.74281325e-05, 3.13040501e-05, - 3.54039900e-05, - 2.28183069e-05, 1.63966874e-05, 1.51146027e-05, 1.80431820e-05, - 2.33621221e-05, 2.91893052e-05, 3.25506586e-05, 3.26876700e-05, - 3.22755502e-05, 2.37076671e-05, 1.94335348e-05, 2.06297288e-05, - 2.32972909e-05, 2.37586851e-05, 2.46104141e-05, 2.88208682e-05, - 3.24657300e-05, 3.18193477e-05, 3.10777662e-05, 3.26465511e-05, - 2.11831111e-05, 1.71259388e-05, 1.75200836e-05, 2.20709445e-05, - 2.49178276e-05, 2.55172309e-05, 2.98652967e-05, 3.43199386e-05, - 3.57356244e-05, 1.75119691e-05, 1.14824769e-05, 1.37004889e-05, - 2.39837680e-05, 3.24722853e-05, 3.32256560e-05, 3.30467624e-05, - 3.39215011e-05, 3.41129832e-05, 2.48698986e-05, 1.70398408e-05, - 1.49243951e-05, 2.09878771e-05, 2.71585473e-05, 2.69110080e-05, - 2.62426633e-05, 2.94894372e-05, 3.33921769e-05, 3.18430889e-05, - 2.48206728e-05, 1.50610569e-05, 1.14524407e-05, 1.49461265e-05, - 2.34105656e-05, 3.29970596e-05, 3.63189702e-05, 3.50380135e-05, - 1.81229008e-05, 1.30859150e-05, 1.43417892e-05, 2.05613722e-05, - 2.92231585e-05, 3.57882314e-05, 3.72931737e-05, 3.48566655e-05, - 1.60095424e-05, 1.20262894e-05, 1.42369148e-05, 2.14287941e-05, - 3.24798583e-05, 3.75070212e-05, 3.55467809e-05, 3.36033226e-05, - 1.50959995e-05, 1.04230375e-05, 1.57913998e-05, 2.42633331e-05, - 2.82595001e-05, 2.99934627e-05, 3.20729253e-05, 2.03736606e-05, - 1.67434532e-05, 1.60676434e-05, 1.77568225e-05, 2.46247785e-05, - 3.23597876e-05, 3.40555247e-05, 3.32132229e-05, 2.15000356e-05, - 1.78002506e-05, 1.80039456e-05, 2.07817952e-05, 2.32664042e-05, - 2.55604448e-05, 3.05365571e-05, 3.29678284e-05, 2.25872165e-05, - 1.76266109e-05, 1.77715804e-05, 1.95659788e-05, 2.10976932e-05, - 2.52292942e-05, 3.04202109e-05, 3.34432466e-05, 3.33048312e-05, - 2.58717540e-05, 1.72421466e-05, 1.10406184e-05, 1.21890976e-05, - 1.93685210e-05, 3.05818810e-05, 3.43420604e-05, 3.02365939e-05, - 1.88751607e-05, 1.53228883e-05, 1.83275067e-05, 2.43053386e-05, - 2.59517028e-05, 2.76128402e-05, 3.16985453e-05, 3.29449483e-05, - 2.60895335e-05, 1.86966738e-05, 1.46574579e-05, 1.83588226e-05, - 2.37282265e-05, 2.92130669e-05, 3.27026070e-05, 3.28317967e-05, - 2.29556629e-05, 1.76656205e-05, 1.69298217e-05, 2.05182851e-05, - 2.50362302e-05, 2.87530070e-05, 3.30116165e-05, 3.17848169e-05, - 2.97486882e-05, 2.32993692e-05, 1.53229929e-05, 1.23339338e-05, - 1.74833482e-05, 2.66339959e-05, 3.23704929e-05, 3.57561235e-05, - 3.60660760e-05, 3.39853167e-05, 2.08107880e-05, 1.71134073e-05, - 1.67080136e-05, 2.17781338e-05, 2.89368361e-05, 2.79844407e-05, - 3.02701060e-05, 3.44825557e-05, 2.10279409e-05, 1.76560473e-05, - 1.75230324e-05, 1.87114254e-05, 2.16499342e-05, 2.86124345e-05, - 3.22007147e-05, 3.08551918e-05, 1.85657191e-05, 1.33489521e-05, - 1.54630853e-05, 2.38631348e-05, 3.27851518e-05, 3.30222126e-05, - 3.17092393e-05, 2.36594951e-05, 1.83863103e-05, 1.55119666e-05, - 1.68642670e-05, 2.22071964e-05, 2.68787644e-05, 3.03480174e-05, - 3.40389247e-05, - 2.41898275e-05, 2.03432237e-05, 1.94318847e-05, 2.18676139e-05, - 2.52805478e-05, 2.75395084e-05, 2.84799380e-05, 2.82896389e-05, - 2.78260973e-05, 2.45025655e-05, 2.21644320e-05, 2.28078727e-05, - 2.44896602e-05, 2.47690715e-05, 2.51438310e-05, 2.73278130e-05, - 2.86982475e-05, 2.80626908e-05, 2.75270361e-05, 2.80025908e-05, - 2.35243568e-05, 2.09960002e-05, 2.09964934e-05, 2.40375501e-05, - 2.56662753e-05, 2.54703545e-05, 2.70609353e-05, 2.86844266e-05, - 2.91139682e-05, 2.12037532e-05, 1.66084667e-05, 1.84012015e-05, - 2.56113140e-05, 2.96122388e-05, 2.88636862e-05, 2.80910819e-05, - 2.83790100e-05, 2.84818575e-05, 2.62962682e-05, 2.16163486e-05, - 1.95681511e-05, 2.36988185e-05, 2.67592136e-05, 2.58781045e-05, - 2.50742523e-05, 2.64811691e-05, 2.80080417e-05, 2.89142548e-05, - 2.61201044e-05, 1.95554262e-05, 1.63185686e-05, 1.92969424e-05, - 2.46769962e-05, 2.85331220e-05, 2.91038217e-05, 2.86130498e-05, - 2.13207947e-05, 1.80801963e-05, 1.92304256e-05, 2.36313042e-05, - 2.78487071e-05, 2.97970028e-05, 2.98203568e-05, 2.87646493e-05, - 1.96976416e-05, 1.72026821e-05, 1.92887788e-05, 2.40735357e-05, - 2.89925238e-05, 2.99794520e-05, 2.88621155e-05, 2.82687667e-05, - 1.96293515e-05, 1.58530960e-05, 2.06414093e-05, 2.61365596e-05, - 2.70748610e-05, 2.65966325e-05, 2.72834913e-05, 2.32444747e-05, - 2.13464398e-05, 2.06667218e-05, 2.12489175e-05, 2.47210529e-05, - 2.79698306e-05, 2.84581457e-05, 2.81506450e-05, 2.38844252e-05, - 2.19219477e-05, 2.19849373e-05, 2.35597604e-05, 2.43647131e-05, - 2.48828681e-05, 2.70343603e-05, 2.80726886e-05, 2.44520493e-05, - 2.15198509e-05, 2.15683857e-05, 2.29458749e-05, 2.35657586e-05, - 2.51325270e-05, 2.70548924e-05, 2.81878971e-05, 2.81789391e-05, - 2.75035535e-05, 2.24850966e-05, 1.64488316e-05, 1.68730861e-05, - 2.14680449e-05, 2.67567711e-05, 2.83297420e-05, 2.64772951e-05, - 2.23307448e-05, 2.03715634e-05, 2.23934423e-05, 2.56771170e-05, - 2.60016640e-05, 2.61361415e-05, 2.76737998e-05, 2.81430199e-05, - 2.74975797e-05, 2.28148207e-05, 1.92473039e-05, 2.17352541e-05, - 2.47081342e-05, 2.67377482e-05, 2.78360786e-05, 2.80799170e-05, - 2.45242153e-05, 2.16183824e-05, 2.11270924e-05, 2.36237791e-05, - 2.59380448e-05, 2.70239707e-05, 2.82655148e-05, 2.75183047e-05, - 2.64566647e-05, 2.52256014e-05, 2.00608336e-05, 1.71802607e-05, - 2.10250952e-05, 2.64420256e-05, 2.85964172e-05, 2.91418490e-05, - 2.90588414e-05, 2.83848036e-05, 2.42367176e-05, 2.23076779e-05, - 2.14095956e-05, 2.40617041e-05, 2.67965766e-05, 2.52079836e-05, - 2.61040628e-05, 2.81897058e-05, 2.32364816e-05, 2.19644596e-05, - 2.20437797e-05, 2.23537114e-05, 2.36150732e-05, 2.70180481e-05, - 2.81643429e-05, 2.71445311e-05, 2.29220907e-05, 1.91576707e-05, - 1.99812112e-05, 2.44348450e-05, 2.80946940e-05, 2.81231517e-05, - 2.74762196e-05, 2.54858307e-05, 2.26227563e-05, 2.02706039e-05, - 2.08182315e-05, 2.34923102e-05, 2.54129162e-05, 2.69561553e-05, - 2.85184886e-05, - 2.35880872e-05, 1.84085687e-05, 1.72876286e-05, 2.01109045e-05, - 2.46087028e-05, 2.84895513e-05, 3.04522921e-05, 3.03465211e-05, - 2.98237645e-05, 2.41487599e-05, 2.08450917e-05, 2.17572773e-05, - 2.39891341e-05, 2.43691295e-05, 2.49650030e-05, 2.81888402e-05, - 3.05989855e-05, 2.98532394e-05, 2.91573391e-05, 3.00984565e-05, - 2.24898899e-05, 1.91442685e-05, 1.92926624e-05, 2.31991730e-05, - 2.54762196e-05, 2.55448080e-05, 2.83525556e-05, 3.12483476e-05, - 3.21036211e-05, 1.94371613e-05, 1.39836578e-05, 1.60409276e-05, - 2.50894742e-05, 3.13415472e-05, 3.10059009e-05, 3.03120748e-05, - 3.08565655e-05, 3.10086226e-05, 2.59391001e-05, 1.95500986e-05, - 1.73092674e-05, 2.25459309e-05, 2.71389518e-05, 2.63635316e-05, - 2.54997333e-05, 2.77574238e-05, 3.03659870e-05, 3.05490131e-05, - 2.57865704e-05, 1.73527285e-05, 1.37807727e-05, 1.71302969e-05, - 2.41719376e-05, 3.06548447e-05, 3.23005874e-05, 3.14425757e-05, - 1.97493446e-05, 1.55870004e-05, 1.68532631e-05, 2.23365699e-05, - 2.87463570e-05, 3.26894255e-05, 3.32436272e-05, 3.15040844e-05, - 1.78099793e-05, 1.45886633e-05, 1.68526467e-05, 2.29871983e-05, - 3.08425852e-05, 3.34528690e-05, 3.18279040e-05, 3.06538836e-05, - 1.74171892e-05, 1.30743396e-05, 1.83862670e-05, 2.55913813e-05, - 2.77862527e-05, 2.80275369e-05, 2.93120444e-05, 2.19828268e-05, - 1.92460641e-05, 1.85101616e-05, 1.95612354e-05, 2.46475209e-05, - 2.99702584e-05, 3.09688559e-05, 3.04195138e-05, 2.28738346e-05, - 2.00575116e-05, 2.01798559e-05, 2.23666326e-05, 2.38836393e-05, - 2.51081128e-05, 2.85697670e-05, 3.02691771e-05, 2.36995016e-05, - 1.97053378e-05, 1.97946847e-05, 2.14621945e-05, 2.24887518e-05, - 2.51810224e-05, 2.85450013e-05, 3.05311798e-05, 3.04749924e-05, - 2.72371110e-05, 2.02414942e-05, 1.37058088e-05, 1.44321470e-05, - 2.03144924e-05, 2.83630983e-05, 3.09641003e-05, 2.80176388e-05, - 2.07571412e-05, 1.80178673e-05, 2.05949680e-05, 2.52586257e-05, - 2.61118942e-05, 2.68169318e-05, 2.94960642e-05, 3.03184311e-05, - 2.73143741e-05, 2.10379530e-05, 1.69860453e-05, 2.01348377e-05, - 2.43118676e-05, 2.78630887e-05, 2.99827243e-05, 3.02269621e-05, - 2.38896305e-05, 1.97902352e-05, 1.91626935e-05, 2.23148632e-05, - 2.57273900e-05, 2.79245973e-05, 3.04419178e-05, 2.94008811e-05, - 2.78294686e-05, 2.45440096e-05, 1.78028101e-05, 1.46928944e-05, - 1.92992782e-05, 2.67011959e-05, 3.04822674e-05, 3.21340227e-05, - 3.21741688e-05, 3.08838311e-05, 2.28746944e-05, 2.00661239e-05, - 1.92768536e-05, 2.31086288e-05, 2.78109829e-05, 2.62194218e-05, - 2.77301721e-05, 3.08979100e-05, 2.22199237e-05, 2.00327591e-05, - 2.00381155e-05, 2.07120033e-05, 2.27296161e-05, 2.78692344e-05, - 3.00714656e-05, 2.87709324e-05, 2.10647993e-05, 1.64159552e-05, - 1.78012741e-05, 2.41539471e-05, 3.02224858e-05, 3.03295629e-05, - 2.93401473e-05, 2.48740714e-05, 2.07815998e-05, 1.80209192e-05, - 1.89197485e-05, 2.28423172e-05, 2.59896443e-05, 2.84403703e-05, - 3.10125719e-05, - 2.54830965e-05, 2.59395975e-05, 2.58972888e-05, 2.55121993e-05, - 2.48082401e-05, 2.40868347e-05, 2.35010190e-05, 2.35822642e-05, - 2.38389645e-05, 2.54572439e-05, 2.59587853e-05, 2.58987804e-05, - 2.53763810e-05, 2.52752354e-05, 2.51739068e-05, 2.41983293e-05, - 2.34000886e-05, 2.37549721e-05, 2.40672554e-05, 2.37227041e-05, - 2.55096263e-05, 2.57838291e-05, 2.60305900e-05, 2.53916174e-05, - 2.48655564e-05, 2.50901683e-05, 2.43554602e-05, 2.32356518e-05, - 2.28646226e-05, 2.58257465e-05, 2.52674589e-05, 2.57279376e-05, - 2.47173718e-05, 2.29450753e-05, 2.32648830e-05, 2.36435168e-05, - 2.34179435e-05, 2.33496831e-05, 2.44211591e-05, 2.51186437e-05, - 2.55830570e-05, 2.52963816e-05, 2.44399316e-05, 2.49701306e-05, - 2.54257937e-05, 2.46793601e-05, 2.36452257e-05, 2.33228250e-05, - 2.45338046e-05, 2.57168170e-05, 2.56123397e-05, 2.58993517e-05, - 2.52648117e-05, 2.34404979e-05, 2.27788787e-05, 2.31722354e-05, - 2.60699718e-05, 2.54413745e-05, 2.54181284e-05, 2.51855846e-05, - 2.39108282e-05, 2.25744365e-05, 2.23421769e-05, 2.31331308e-05, - 2.63247265e-05, 2.52349151e-05, 2.52501937e-05, 2.51527176e-05, - 2.32540829e-05, 2.22461622e-05, 2.29954165e-05, 2.35036493e-05, - 2.56667365e-05, 2.46762868e-05, 2.51727616e-05, 2.44050841e-05, - 2.43239012e-05, 2.46018455e-05, 2.41176709e-05, 2.54332619e-05, - 2.51777370e-05, 2.53642446e-05, 2.59295750e-05, 2.54696317e-05, - 2.37626906e-05, 2.33670158e-05, 2.35991768e-05, 2.53290736e-05, - 2.53164318e-05, 2.53792672e-05, 2.53324419e-05, 2.54614390e-05, - 2.54852574e-05, 2.43482670e-05, 2.36598210e-05, 2.52223497e-05, - 2.55926316e-05, 2.56342628e-05, 2.53346681e-05, 2.54454843e-05, - 2.52778216e-05, 2.43424431e-05, 2.35578772e-05, 2.35766885e-05, - 2.37865919e-05, 2.44173772e-05, 2.48333706e-05, 2.58688933e-05, - 2.65444826e-05, 2.44902194e-05, 2.33874836e-05, 2.46538954e-05, - 2.55411186e-05, 2.50658687e-05, 2.51872811e-05, 2.47406833e-05, - 2.47948128e-05, 2.48545761e-05, 2.39567030e-05, 2.36290947e-05, - 2.38278697e-05, 2.50090098e-05, 2.56960607e-05, 2.58127871e-05, - 2.53128299e-05, 2.45406658e-05, 2.37962761e-05, 2.36693190e-05, - 2.52668474e-05, 2.55224486e-05, 2.55243498e-05, 2.51742563e-05, - 2.46993008e-05, 2.43722767e-05, 2.35654067e-05, 2.40275594e-05, - 2.46855187e-05, 2.48327301e-05, 2.53967532e-05, 2.56585200e-05, - 2.59806655e-05, 2.45889324e-05, 2.34561920e-05, 2.28502296e-05, - 2.28368519e-05, 2.34078472e-05, 2.47851869e-05, 2.44983568e-05, - 2.50897973e-05, 2.52806260e-05, 2.45062209e-05, 2.54119550e-05, - 2.48454581e-05, 2.34286302e-05, 2.56893960e-05, 2.51869757e-05, - 2.50268656e-05, 2.54349327e-05, 2.55934161e-05, 2.43716340e-05, - 2.36799126e-05, 2.42754430e-05, 2.48388631e-05, 2.44626041e-05, - 2.55988878e-05, 2.55372114e-05, 2.36666154e-05, 2.36309896e-05, - 2.40539169e-05, 2.47318824e-05, 2.50100327e-05, 2.53326192e-05, - 2.57860455e-05, 2.58544437e-05, 2.52572612e-05, 2.43973779e-05, - 2.33422015e-05, - 2.49368006e-05, 2.23946659e-05, 2.17347889e-05, 2.23532427e-05, - 2.37350863e-05, 2.57888884e-05, 2.67768192e-05, 2.71446787e-05, - 2.75809226e-05, 2.54481834e-05, 2.39918264e-05, 2.45477865e-05, - 2.49900770e-05, 2.50463080e-05, 2.53595424e-05, 2.58160428e-05, - 2.64035352e-05, 2.69225266e-05, 2.72305455e-05, 2.75493559e-05, - 2.40133435e-05, 2.24392181e-05, 2.31230552e-05, 2.42718852e-05, - 2.48182505e-05, 2.57681902e-05, 2.70649787e-05, 2.75231142e-05, - 2.76406683e-05, 2.27096377e-05, 1.92933044e-05, 2.08466550e-05, - 2.38983759e-05, 2.51115024e-05, 2.66334808e-05, 2.76635150e-05, - 2.77485695e-05, 2.77047268e-05, 2.37581024e-05, 2.11413567e-05, - 2.10790178e-05, 2.34444779e-05, 2.52633490e-05, 2.64600937e-05, - 2.71812385e-05, 2.77037067e-05, 2.79961529e-05, 2.56872826e-05, - 2.39843721e-05, 2.13790924e-05, 1.98546183e-05, 2.16658892e-05, - 2.48007489e-05, 2.69761659e-05, 2.79321832e-05, 2.80102237e-05, - 2.35148941e-05, 2.01187933e-05, 2.05510896e-05, 2.29813558e-05, - 2.53471048e-05, 2.67142881e-05, 2.73710035e-05, 2.76954908e-05, - 2.29633387e-05, 1.94111189e-05, 2.02183821e-05, 2.33833395e-05, - 2.59879777e-05, 2.72459185e-05, 2.79072213e-05, 2.77291799e-05, - 2.13024421e-05, 1.80581908e-05, 2.07036799e-05, 2.33674967e-05, - 2.57396899e-05, 2.79091694e-05, 2.82893079e-05, 2.33963408e-05, - 2.11192539e-05, 2.11660054e-05, 2.30394415e-05, 2.61023122e-05, - 2.74167475e-05, 2.77074296e-05, 2.76747886e-05, 2.38020478e-05, - 2.18583677e-05, 2.20757696e-05, 2.34072841e-05, 2.51707994e-05, - 2.68205808e-05, 2.76131325e-05, 2.76429735e-05, 2.42003343e-05, - 2.23080328e-05, 2.24597715e-05, 2.27645768e-05, 2.38252018e-05, - 2.60413812e-05, 2.74944652e-05, 2.77560082e-05, 2.76872702e-05, - 2.29262862e-05, 1.99734989e-05, 1.84683397e-05, 2.05362252e-05, - 2.52421507e-05, 2.80915963e-05, 2.80561745e-05, 2.82894973e-05, - 2.28265612e-05, 2.03238782e-05, 2.18606137e-05, 2.41444377e-05, - 2.53280711e-05, 2.66796546e-05, 2.74329353e-05, 2.75232448e-05, - 2.31423896e-05, 2.16945409e-05, 2.11726518e-05, 2.31110690e-05, - 2.51158717e-05, 2.70658968e-05, 2.78373181e-05, 2.75482861e-05, - 2.45234123e-05, 2.21905581e-05, 2.18482959e-05, 2.29351019e-05, - 2.45004623e-05, 2.62340894e-05, 2.73809383e-05, 2.77311859e-05, - 2.79483333e-05, 2.37526842e-05, 2.09093952e-05, 2.02243283e-05, - 2.30040917e-05, 2.52787535e-05, 2.64912864e-05, 2.76111730e-05, - 2.78776675e-05, 2.77761449e-05, 2.22961107e-05, 2.00617589e-05, - 2.09435888e-05, 2.38558592e-05, 2.67465320e-05, 2.85930132e-05, - 2.89344311e-05, 2.83408761e-05, 2.43180339e-05, 2.15460370e-05, - 2.11873248e-05, 2.25312599e-05, 2.44725637e-05, 2.61265113e-05, - 2.70211519e-05, 2.76703958e-05, 2.13113540e-05, 1.85957737e-05, - 2.13346690e-05, 2.57465255e-05, 2.74971125e-05, 2.76003532e-05, - 2.77456709e-05, 2.37395158e-05, 2.15505700e-05, 2.08730450e-05, - 2.23185805e-05, 2.54185564e-05, 2.72157701e-05, 2.75979053e-05, - 2.76093288e-05, - 2.53465966e-05, 2.50751396e-05, 2.48701716e-05, 2.49505047e-05, - 2.48732406e-05, 2.46030993e-05, 2.42363219e-05, 2.42987088e-05, - 2.44843827e-05, 2.53850794e-05, 2.54262385e-05, 2.54896921e-05, - 2.52984945e-05, 2.52518147e-05, 2.52259633e-05, 2.46757013e-05, - 2.41592776e-05, 2.44155774e-05, 2.46355240e-05, 2.44024855e-05, - 2.52446669e-05, 2.50492066e-05, 2.52785777e-05, 2.52247201e-05, - 2.50105539e-05, 2.52113500e-05, 2.48237851e-05, 2.40532496e-05, - 2.37789282e-05, 2.51254711e-05, 2.37832798e-05, 2.45278006e-05, - 2.48435325e-05, 2.38130005e-05, 2.40674034e-05, 2.43476077e-05, - 2.41863959e-05, 2.41367647e-05, 2.46694306e-05, 2.45405424e-05, - 2.46100996e-05, 2.50681596e-05, 2.47965207e-05, 2.51852114e-05, - 2.54951532e-05, 2.50544371e-05, 2.43510933e-05, 2.40899246e-05, - 2.47528379e-05, 2.47290306e-05, 2.40281881e-05, 2.48472647e-05, - 2.52219921e-05, 2.41964312e-05, 2.37125773e-05, 2.40067031e-05, - 2.53750929e-05, 2.42130074e-05, 2.44007076e-05, 2.49484719e-05, - 2.44704855e-05, 2.35635918e-05, 2.33840710e-05, 2.39783162e-05, - 2.53087674e-05, 2.38673929e-05, 2.42597999e-05, 2.49952028e-05, - 2.40491011e-05, 2.33112855e-05, 2.38756157e-05, 2.42481164e-05, - 2.46969455e-05, 2.31235942e-05, 2.44245495e-05, 2.46216980e-05, - 2.47514454e-05, 2.50090339e-05, 2.46869752e-05, 2.51191160e-05, - 2.45494565e-05, 2.46043480e-05, 2.52304764e-05, 2.54479155e-05, - 2.44289178e-05, 2.41493543e-05, 2.43161461e-05, 2.51340651e-05, - 2.47767399e-05, 2.48464045e-05, 2.50781879e-05, 2.53602413e-05, - 2.55078395e-05, 2.48334067e-05, 2.43589989e-05, 2.51344808e-05, - 2.49645490e-05, 2.50119819e-05, 2.49713898e-05, 2.51895217e-05, - 2.53371171e-05, 2.48267408e-05, 2.42871857e-05, 2.43001907e-05, - 2.42340508e-05, 2.40316568e-05, 2.33737470e-05, 2.43617635e-05, - 2.58526204e-05, 2.49387282e-05, 2.41648723e-05, 2.50521172e-05, - 2.50593188e-05, 2.42807855e-05, 2.47364180e-05, 2.48807327e-05, - 2.50105339e-05, 2.51264245e-05, 2.45638346e-05, 2.43360953e-05, - 2.42772165e-05, 2.46397661e-05, 2.46544197e-05, 2.52091817e-05, - 2.52781614e-05, 2.49444656e-05, 2.44572914e-05, 2.43648132e-05, - 2.51934796e-05, 2.49164029e-05, 2.48321044e-05, 2.49361846e-05, - 2.48909469e-05, 2.48046797e-05, 2.42895271e-05, 2.46174459e-05, - 2.50651054e-05, 2.48877550e-05, 2.45283065e-05, 2.42361422e-05, - 2.52373249e-05, 2.48866577e-05, 2.42001000e-05, 2.37682655e-05, - 2.37567851e-05, 2.41791832e-05, 2.46653041e-05, 2.40786334e-05, - 2.44789010e-05, 2.51190649e-05, 2.49107881e-05, 2.55492438e-05, - 2.51919422e-05, 2.41947661e-05, 2.53667481e-05, 2.46631163e-05, - 2.45271871e-05, 2.49629407e-05, 2.53443746e-05, 2.47996050e-05, - 2.43652785e-05, 2.47856716e-05, 2.44971007e-05, 2.35298053e-05, - 2.46982697e-05, 2.54542839e-05, 2.43623681e-05, 2.43381602e-05, - 2.46358512e-05, 2.48342850e-05, 2.46084785e-05, 2.45065469e-05, - 2.50193892e-05, 2.55807387e-05, 2.53971590e-05, 2.48658606e-05, - 2.41310070e-05, - 2.49373952e-05, 2.27818595e-05, 2.21888546e-05, 2.31482272e-05, - 2.45696338e-05, 2.58495763e-05, 2.63231408e-05, 2.64439481e-05, - 2.65697930e-05, 2.52340210e-05, 2.40445247e-05, 2.44621243e-05, - 2.50203206e-05, 2.50988738e-05, 2.53100899e-05, 2.58361099e-05, - 2.61994104e-05, 2.63483808e-05, 2.64200586e-05, 2.65694625e-05, - 2.43599390e-05, 2.29758245e-05, 2.33242932e-05, 2.45914013e-05, - 2.51516881e-05, 2.55491650e-05, 2.63119674e-05, 2.65884372e-05, - 2.66272709e-05, 2.31674663e-05, 2.00222958e-05, 2.14207715e-05, - 2.47077289e-05, 2.57610637e-05, 2.62927730e-05, 2.66133362e-05, - 2.66529688e-05, 2.66417537e-05, 2.47558250e-05, 2.24470032e-05, - 2.18804410e-05, 2.41165824e-05, 2.55228153e-05, 2.59133225e-05, - 2.60915208e-05, 2.64948420e-05, 2.67204263e-05, 2.59398695e-05, - 2.48354383e-05, 2.20364395e-05, 2.02320495e-05, 2.21145623e-05, - 2.49673308e-05, 2.63977071e-05, 2.67093222e-05, 2.67381642e-05, - 2.36030303e-05, 2.09327566e-05, 2.15019700e-05, 2.38698683e-05, - 2.56983171e-05, 2.63429931e-05, 2.65310870e-05, 2.66439610e-05, - 2.28943405e-05, 2.02762833e-05, 2.13370258e-05, 2.41636464e-05, - 2.60618734e-05, 2.64901770e-05, 2.67071376e-05, 2.66429299e-05, - 2.20163803e-05, 1.90868525e-05, 2.19653512e-05, 2.45394453e-05, - 2.57724041e-05, 2.65848948e-05, 2.67799283e-05, 2.39953881e-05, - 2.23687869e-05, 2.22216820e-05, 2.33464723e-05, 2.55681211e-05, - 2.65210086e-05, 2.66419835e-05, 2.66199520e-05, 2.43318601e-05, - 2.29028853e-05, 2.30320378e-05, 2.40686862e-05, 2.50803067e-05, - 2.59080777e-05, 2.65181163e-05, 2.66054407e-05, 2.46391550e-05, - 2.30398892e-05, 2.31302977e-05, 2.36104216e-05, 2.42766841e-05, - 2.56131570e-05, 2.64756864e-05, 2.66486528e-05, 2.66253981e-05, - 2.45374570e-05, 2.20085036e-05, 1.95122843e-05, 2.07790907e-05, - 2.44749674e-05, 2.66679392e-05, 2.67490765e-05, 2.67128457e-05, - 2.35014480e-05, 2.16873969e-05, 2.30153324e-05, 2.48371366e-05, - 2.54385785e-05, 2.60425959e-05, 2.65063497e-05, 2.65680742e-05, - 2.46425273e-05, 2.30239039e-05, 2.18403029e-05, 2.35034632e-05, - 2.51197696e-05, 2.62763799e-05, 2.66591797e-05, 2.65733740e-05, - 2.48075213e-05, 2.30031482e-05, 2.27017714e-05, 2.38448332e-05, - 2.50492422e-05, 2.59738612e-05, 2.65253313e-05, 2.66018587e-05, - 2.65846813e-05, 2.45682083e-05, 2.19239291e-05, 2.07116125e-05, - 2.32716007e-05, 2.54837848e-05, 2.62254862e-05, 2.66183645e-05, - 2.66955930e-05, 2.66620314e-05, 2.36441919e-05, 2.20174090e-05, - 2.22894558e-05, 2.43944481e-05, 2.61557772e-05, 2.66744863e-05, - 2.69066884e-05, 2.68336446e-05, 2.44460347e-05, 2.27477004e-05, - 2.25744386e-05, 2.33555049e-05, 2.46008960e-05, 2.59284353e-05, - 2.63917482e-05, 2.65494792e-05, 2.28433145e-05, 2.03884722e-05, - 2.21299897e-05, 2.53567124e-05, 2.65564973e-05, 2.65934464e-05, - 2.66039201e-05, 2.46086743e-05, 2.29037894e-05, 2.19602472e-05, - 2.28677594e-05, 2.50201640e-05, 2.61587976e-05, 2.65048713e-05, - 2.66119840e-05, - 2.46256921e-05, 2.15885650e-05, 2.08270346e-05, 2.23538108e-05, - 2.46249707e-05, 2.65665747e-05, 2.73999933e-05, 2.74687297e-05, - 2.74414485e-05, 2.49954466e-05, 2.32091183e-05, 2.37712423e-05, - 2.47950451e-05, 2.49547200e-05, 2.52690513e-05, 2.64829655e-05, - 2.73381984e-05, 2.72778494e-05, 2.71655395e-05, 2.75069069e-05, - 2.39023018e-05, 2.19472793e-05, 2.22386909e-05, 2.42660626e-05, - 2.52843381e-05, 2.55988658e-05, 2.68858432e-05, 2.77922071e-05, - 2.80194713e-05, 2.21704360e-05, 1.82629356e-05, 1.98985539e-05, - 2.48525794e-05, 2.71660546e-05, 2.75054146e-05, 2.75916392e-05, - 2.77509436e-05, 2.77778613e-05, 2.51051388e-05, 2.16887703e-05, - 2.06183210e-05, 2.37399387e-05, 2.59854705e-05, 2.60831636e-05, - 2.59901762e-05, 2.68759343e-05, 2.76872462e-05, 2.71246013e-05, - 2.51265625e-05, 2.07409136e-05, 1.83351120e-05, 2.07259408e-05, - 2.48049165e-05, 2.75053627e-05, 2.81288896e-05, 2.79541429e-05, - 2.25726721e-05, 1.94156151e-05, 2.02122005e-05, 2.35021231e-05, - 2.65126751e-05, 2.79275281e-05, 2.82000186e-05, 2.78948278e-05, - 2.14824338e-05, 1.86385081e-05, 2.00967419e-05, 2.38944838e-05, - 2.72875667e-05, 2.82138071e-05, 2.80189657e-05, 2.76954557e-05, - 2.07468594e-05, 1.73205675e-05, 2.10044937e-05, 2.48543615e-05, - 2.63354888e-05, 2.70120347e-05, 2.74787661e-05, 2.34961977e-05, - 2.15446860e-05, 2.12232884e-05, 2.23344871e-05, 2.53757846e-05, - 2.74389278e-05, 2.77687340e-05, 2.76222477e-05, 2.39871630e-05, - 2.21622275e-05, 2.22902091e-05, 2.36557291e-05, 2.48107790e-05, - 2.57501390e-05, 2.70964493e-05, 2.75753419e-05, 2.44363077e-05, - 2.21584174e-05, 2.22491259e-05, 2.30712755e-05, 2.38412381e-05, - 2.55510009e-05, 2.70580234e-05, 2.76709076e-05, 2.76396033e-05, - 2.52592336e-05, 2.15671441e-05, 1.78232835e-05, 1.89275600e-05, - 2.33601693e-05, 2.71589983e-05, 2.78508701e-05, 2.71063503e-05, - 2.27933498e-05, 2.06976403e-05, 2.23963945e-05, 2.49929568e-05, - 2.56626175e-05, 2.62964369e-05, 2.73137674e-05, 2.75581458e-05, - 2.53583108e-05, 2.25268413e-05, 2.04896611e-05, 2.26151957e-05, - 2.49548925e-05, 2.67371647e-05, 2.75484314e-05, 2.75405232e-05, - 2.46114434e-05, 2.21568966e-05, 2.17579291e-05, 2.34778659e-05, - 2.52721373e-05, 2.65228590e-05, 2.75542893e-05, 2.73640164e-05, - 2.69619978e-05, 2.46070536e-05, 2.08000920e-05, 1.89698780e-05, - 2.22033283e-05, 2.58462460e-05, 2.73312134e-05, 2.80194042e-05, - 2.80892658e-05, 2.77643854e-05, 2.34816754e-05, 2.15248986e-05, - 2.14968278e-05, 2.40969184e-05, 2.66327401e-05, 2.66134325e-05, - 2.71796524e-05, 2.79009699e-05, 2.38899430e-05, 2.20434922e-05, - 2.19201610e-05, 2.26752548e-05, 2.41443084e-05, 2.64746309e-05, - 2.73632315e-05, 2.71699741e-05, 2.24028581e-05, 1.92973917e-05, - 2.09446598e-05, 2.50871798e-05, 2.75264165e-05, 2.75804106e-05, - 2.73508432e-05, 2.47229404e-05, 2.23680810e-05, 2.08916576e-05, - 2.18036093e-05, 2.44810488e-05, 2.61693525e-05, 2.70543357e-05, - 2.77556228e-05, - 2.51084720e-05, 2.50650283e-05, 2.48960724e-05, 2.58222160e-05, - 2.61225305e-05, 2.48622877e-05, 2.39049542e-05, 2.36192085e-05, - 2.33440316e-05, 2.48569166e-05, 2.50351834e-05, 2.49507209e-05, - 2.51423512e-05, 2.51636330e-05, 2.50264980e-05, 2.48493886e-05, - 2.41926929e-05, 2.38659476e-05, 2.37001949e-05, 2.33288607e-05, - 2.54889730e-05, 2.53699076e-05, 2.50086405e-05, 2.54795113e-05, - 2.54668750e-05, 2.47998188e-05, 2.38924409e-05, 2.31442324e-05, - 2.28458518e-05, 2.53246431e-05, 2.41227669e-05, 2.46908395e-05, - 2.60803360e-05, 2.51896846e-05, 2.39394915e-05, 2.32024240e-05, - 2.30339035e-05, 2.30402587e-05, 2.62948969e-05, 2.63843381e-05, - 2.53058840e-05, 2.58854288e-05, 2.52608585e-05, 2.43605761e-05, - 2.38203495e-05, 2.34519115e-05, 2.29229251e-05, 2.47951020e-05, - 2.61089681e-05, 2.51463997e-05, 2.36428606e-05, 2.48509756e-05, - 2.53017814e-05, 2.37099729e-05, 2.25350099e-05, 2.26872515e-05, - 2.49483666e-05, 2.48245272e-05, 2.53680450e-05, 2.61445965e-05, - 2.51994746e-05, 2.35268269e-05, 2.27718281e-05, 2.29422116e-05, - 2.44382741e-05, 2.45263829e-05, 2.55740835e-05, 2.60376544e-05, - 2.45068234e-05, 2.28247582e-05, 2.26821962e-05, 2.30885684e-05, - 2.52284630e-05, 2.40632360e-05, 2.61175792e-05, 2.65424450e-05, - 2.49124354e-05, 2.32838509e-05, 2.28602623e-05, 2.57650940e-05, - 2.62620334e-05, 2.58818097e-05, 2.51692856e-05, 2.44803402e-05, - 2.34543439e-05, 2.30459782e-05, 2.31750406e-05, 2.57242615e-05, - 2.61245499e-05, 2.60302434e-05, 2.58634501e-05, 2.50024646e-05, - 2.40390656e-05, 2.34619670e-05, 2.32261820e-05, 2.56304628e-05, - 2.56893614e-05, 2.56284785e-05, 2.60300634e-05, 2.56142697e-05, - 2.45772327e-05, 2.35538431e-05, 2.30889669e-05, 2.31552100e-05, - 2.70671182e-05, 2.74907844e-05, 2.43738882e-05, 2.37652423e-05, - 2.40989739e-05, 2.31210213e-05, 2.27557294e-05, 2.30047048e-05, - 2.57530935e-05, 2.61710949e-05, 2.63329373e-05, 2.59257002e-05, - 2.51581955e-05, 2.42143351e-05, 2.35042362e-05, 2.33153200e-05, - 2.69021452e-05, 2.66093668e-05, 2.50661084e-05, 2.53457391e-05, - 2.51073448e-05, 2.39169614e-05, 2.31157768e-05, 2.33096909e-05, - 2.54440006e-05, 2.57996013e-05, 2.57516087e-05, 2.61701750e-05, - 2.57237154e-05, 2.45371601e-05, 2.34112610e-05, 2.32823891e-05, - 2.32685715e-05, 2.60989457e-05, 2.56811192e-05, 2.41329539e-05, - 2.50846161e-05, 2.52307427e-05, 2.41359732e-05, 2.28641217e-05, - 2.26180369e-05, 2.30055990e-05, 2.67694948e-05, 2.73512222e-05, - 2.63922124e-05, 2.57421051e-05, 2.41561908e-05, 2.28750442e-05, - 2.25602708e-05, 2.25328249e-05, 2.52201202e-05, 2.63212682e-05, - 2.65637762e-05, 2.59306018e-05, 2.52413888e-05, 2.46193273e-05, - 2.37586681e-05, 2.33999712e-05, 2.68832550e-05, 2.63357264e-05, - 2.54145094e-05, 2.46568218e-05, 2.33518256e-05, 2.32508257e-05, - 2.32787498e-05, 2.61626577e-05, 2.66130456e-05, 2.58197507e-05, - 2.53464157e-05, 2.46464915e-05, 2.38177594e-05, 2.34843025e-05, - 2.31193368e-05, - 2.51837612e-05, 2.87002221e-05, 2.93745739e-05, 2.89421500e-05, - 2.65888137e-05, 2.25787184e-05, 2.03921520e-05, 1.99769442e-05, - 1.96976902e-05, 2.44153964e-05, 2.67171409e-05, 2.59433065e-05, - 2.50346105e-05, 2.48784406e-05, 2.43291412e-05, 2.26658042e-05, - 2.08026796e-05, 2.05046669e-05, 2.04513205e-05, 1.95977694e-05, - 2.65655037e-05, 2.87409238e-05, 2.78226211e-05, 2.61218945e-05, - 2.48987989e-05, 2.36485258e-05, 2.10161615e-05, 1.90159232e-05, - 1.83711975e-05, 2.83959325e-05, 3.14216711e-05, 3.02208063e-05, - 2.62506945e-05, 2.21819921e-05, 2.02910469e-05, 1.93462825e-05, - 1.89497016e-05, 1.89207520e-05, 2.62283890e-05, 3.06815542e-05, - 3.03207836e-05, 2.73327934e-05, 2.37877605e-05, 2.25265466e-05, - 2.19426799e-05, 2.04985439e-05, 1.89093514e-05, 2.17826946e-05, - 2.59512275e-05, 2.98973590e-05, 3.04511215e-05, 2.94277575e-05, - 2.52416340e-05, 2.00319752e-05, 1.78787158e-05, 1.82937688e-05, - 2.73329839e-05, 3.10933952e-05, 3.09605282e-05, 2.80029227e-05, - 2.30593427e-05, 1.92353429e-05, 1.80138514e-05, 1.86532303e-05, - 2.78295663e-05, 3.16299844e-05, 3.14666575e-05, 2.73643799e-05, - 2.12304605e-05, 1.80452073e-05, 1.81967573e-05, 1.90837785e-05, - 3.00256067e-05, 3.26649971e-05, 3.11567401e-05, 2.68806634e-05, - 2.29237636e-05, 2.01412089e-05, 1.90978241e-05, 2.74528004e-05, - 3.06750808e-05, 3.04807982e-05, 2.79560039e-05, 2.34811365e-05, - 1.98270695e-05, 1.89393217e-05, 1.92759790e-05, 2.68018725e-05, - 2.96551653e-05, 2.93450991e-05, 2.74031539e-05, 2.48248445e-05, - 2.24874102e-05, 2.02540050e-05, 1.93940234e-05, 2.61319990e-05, - 2.89795131e-05, 2.87717951e-05, 2.83665203e-05, 2.68185095e-05, - 2.34115277e-05, 2.04081858e-05, 1.91163054e-05, 1.92312187e-05, - 2.70643513e-05, 3.26299674e-05, 3.25109800e-05, 2.98818396e-05, - 2.51674307e-05, 1.97786443e-05, 1.85093500e-05, 1.97019348e-05, - 2.82916470e-05, 3.16595064e-05, 2.96797525e-05, 2.58678978e-05, - 2.40421709e-05, 2.20977725e-05, 2.00409367e-05, 1.95168473e-05, - 2.67143221e-05, 2.99388432e-05, 3.00874394e-05, 2.78885510e-05, - 2.48017570e-05, 2.12210338e-05, 1.93032449e-05, 1.95331118e-05, - 2.56648177e-05, 2.91536404e-05, 2.95819539e-05, 2.80705945e-05, - 2.52562114e-05, 2.22328985e-05, 1.96302438e-05, 1.97226884e-05, - 2.01803121e-05, 2.65781358e-05, 3.07064391e-05, 3.04757880e-05, - 2.79828816e-05, 2.39172154e-05, 2.07469052e-05, 1.83908047e-05, - 1.80257457e-05, 1.89004552e-05, 2.89484737e-05, 3.24629970e-05, - 3.09484877e-05, 2.66955757e-05, 2.16349856e-05, 2.00874835e-05, - 1.90949380e-05, 1.81978393e-05, 2.61937709e-05, 3.01171267e-05, - 3.06621206e-05, 2.87079603e-05, 2.59278194e-05, 2.23921153e-05, - 2.02721894e-05, 2.00937206e-05, 3.05255858e-05, 3.39259886e-05, - 3.00775767e-05, 2.40411057e-05, 1.95989388e-05, 1.94153315e-05, - 1.97345792e-05, 2.65235321e-05, 3.01513059e-05, 3.08150862e-05, - 2.88816446e-05, 2.47075082e-05, 2.17422662e-05, 2.03301332e-05, - 1.90380569e-05, - 2.50103506e-05, 2.43017722e-05, 2.39897621e-05, 2.52102576e-05, - 2.60490855e-05, 2.53201269e-05, 2.46228014e-05, 2.43465626e-05, - 2.40415890e-05, 2.48476047e-05, 2.46058062e-05, 2.46460231e-05, - 2.50880521e-05, 2.51513912e-05, 2.50946001e-05, 2.52776670e-05, - 2.49046605e-05, 2.45302677e-05, 2.43100591e-05, 2.40528596e-05, - 2.52210310e-05, 2.46753369e-05, 2.43753953e-05, 2.52992688e-05, - 2.55531781e-05, 2.49524213e-05, 2.44101864e-05, 2.39844040e-05, - 2.37792428e-05, 2.46757968e-05, 2.27907482e-05, 2.36198882e-05, - 2.60670167e-05, 2.59034665e-05, 2.47062887e-05, 2.39544566e-05, - 2.38461170e-05, 2.38656528e-05, 2.63597559e-05, 2.56313117e-05, - 2.43530672e-05, 2.55846184e-05, 2.55467067e-05, 2.46386816e-05, - 2.40520517e-05, 2.39441581e-05, 2.36982146e-05, 2.54606361e-05, - 2.61730959e-05, 2.42194753e-05, 2.23416100e-05, 2.39266822e-05, - 2.52538854e-05, 2.44597050e-05, 2.35034922e-05, 2.35728813e-05, - 2.43838427e-05, 2.36645830e-05, 2.43382270e-05, 2.57910697e-05, - 2.56573957e-05, 2.44703990e-05, 2.38064013e-05, 2.38175873e-05, - 2.36627740e-05, 2.32420895e-05, 2.45185700e-05, 2.57765249e-05, - 2.52202128e-05, 2.38738998e-05, 2.36015522e-05, 2.38790592e-05, - 2.43012246e-05, 2.25806944e-05, 2.52275056e-05, 2.65450322e-05, - 2.52944114e-05, 2.38150812e-05, 2.35434445e-05, 2.54055285e-05, - 2.54797749e-05, 2.50377066e-05, 2.45548220e-05, 2.45617314e-05, - 2.41579867e-05, 2.38674599e-05, 2.39386685e-05, 2.54802725e-05, - 2.54717231e-05, 2.54046906e-05, 2.55423686e-05, 2.49489684e-05, - 2.42099814e-05, 2.40325978e-05, 2.39727199e-05, 2.54957580e-05, - 2.50365853e-05, 2.49947879e-05, 2.55758566e-05, 2.53336204e-05, - 2.47092461e-05, 2.41153848e-05, 2.38683558e-05, 2.39251799e-05, - 2.72107110e-05, 2.67101047e-05, 2.29595779e-05, 2.25563610e-05, - 2.37001964e-05, 2.36965398e-05, 2.35951302e-05, 2.35555276e-05, - 2.52356024e-05, 2.52199127e-05, 2.57306482e-05, 2.59460276e-05, - 2.53419435e-05, 2.45518936e-05, 2.41600916e-05, 2.40604390e-05, - 2.70686326e-05, 2.60369169e-05, 2.40938192e-05, 2.47894015e-05, - 2.50936967e-05, 2.43843629e-05, 2.38434436e-05, 2.40467964e-05, - 2.53496386e-05, 2.51461967e-05, 2.50160980e-05, 2.58112711e-05, - 2.58154601e-05, 2.49628666e-05, 2.41613145e-05, 2.39447464e-05, - 2.37816427e-05, 2.60200819e-05, 2.47567634e-05, 2.29182096e-05, - 2.44437508e-05, 2.54722406e-05, 2.48408705e-05, 2.37990492e-05, - 2.35709222e-05, 2.38220587e-05, 2.64206507e-05, 2.65613841e-05, - 2.55993603e-05, 2.55251574e-05, 2.45999781e-05, 2.32586387e-05, - 2.31159844e-05, 2.33803226e-05, 2.49457172e-05, 2.56430493e-05, - 2.58590983e-05, 2.53879293e-05, 2.50274962e-05, 2.50329666e-05, - 2.44509353e-05, 2.39943955e-05, 2.62846756e-05, 2.51150015e-05, - 2.45219224e-05, 2.46665058e-05, 2.40857011e-05, 2.40012478e-05, - 2.39356664e-05, 2.61166407e-05, 2.60054587e-05, 2.49111719e-05, - 2.46230607e-05, 2.45042661e-05, 2.41014422e-05, 2.40408083e-05, - 2.39400529e-05, - 2.44894550e-05, 3.65919007e-05, 3.98572978e-05, 3.34243487e-05, - 2.44091855e-05, 1.72039773e-05, 1.40938598e-05, 1.38608477e-05, - 1.40049991e-05, 2.31033182e-05, 2.99617578e-05, 2.77594759e-05, - 2.38475392e-05, 2.32439682e-05, 2.20706695e-05, 1.75256804e-05, - 1.42917548e-05, 1.45896572e-05, 1.50503909e-05, 1.37449977e-05, - 2.72497191e-05, 3.51027332e-05, 3.38732281e-05, 2.58462701e-05, - 2.19760242e-05, 2.08518449e-05, 1.61050349e-05, 1.25907544e-05, - 1.16408343e-05, 3.41733808e-05, 5.16900257e-05, 4.39927927e-05, - 2.35416306e-05, 1.47527917e-05, 1.36550435e-05, 1.34171805e-05, - 1.27809926e-05, 1.26669504e-05, 2.25391239e-05, 3.61860068e-05, - 4.08176164e-05, 2.78627822e-05, 1.93544849e-05, 1.90764118e-05, - 1.94301134e-05, 1.61690070e-05, 1.30573241e-05, 1.50275759e-05, - 2.24889247e-05, 4.02621747e-05, 5.12098759e-05, 4.02963035e-05, - 2.38019360e-05, 1.36973309e-05, 1.11900283e-05, 1.19575640e-05, - 3.25048164e-05, 4.62527656e-05, 4.26411626e-05, 2.87794644e-05, - 1.73522906e-05, 1.19109761e-05, 1.07944786e-05, 1.21797249e-05, - 3.69667837e-05, 4.99228890e-05, 4.31777321e-05, 2.72467321e-05, - 1.44313670e-05, 1.07104885e-05, 1.16707250e-05, 1.30050919e-05, - 4.02431051e-05, 5.64664794e-05, 3.91419145e-05, 2.34583456e-05, - 1.80775706e-05, 1.56641476e-05, 1.38952216e-05, 2.88269854e-05, - 3.68051417e-05, 3.81922188e-05, 3.34900945e-05, 2.16925998e-05, - 1.40026573e-05, 1.27046634e-05, 1.32956573e-05, 2.69093412e-05, - 3.42090974e-05, 3.36819827e-05, 2.81943244e-05, 2.37933091e-05, - 2.03122269e-05, 1.53360213e-05, 1.34805882e-05, 2.51839779e-05, - 3.42320867e-05, 3.38562629e-05, 3.05030863e-05, 2.74821887e-05, - 2.10404460e-05, 1.54763831e-05, 1.31063542e-05, 1.32270027e-05, - 2.17698292e-05, 3.65849732e-05, 5.39488972e-05, 4.83543963e-05, - 2.92877662e-05, 1.51145949e-05, 1.23938973e-05, 1.53157023e-05, - 3.16323619e-05, 4.04910178e-05, 3.32288346e-05, 2.30264651e-05, - 2.05838373e-05, 1.82925041e-05, 1.44924866e-05, 1.35396291e-05, - 2.14282529e-05, 3.26694610e-05, 4.13683245e-05, 3.23520790e-05, - 2.32462554e-05, 1.66650581e-05, 1.36008126e-05, 1.36117187e-05, - 2.45277488e-05, 3.42384153e-05, 3.59077863e-05, 2.88733337e-05, - 2.19913042e-05, 1.74154234e-05, 1.35427683e-05, 1.43162470e-05, - 1.58522637e-05, 2.44811657e-05, 4.00346769e-05, 4.82418740e-05, - 3.40242720e-05, 1.98844307e-05, 1.43310657e-05, 1.16377785e-05, - 1.13605111e-05, 1.27282955e-05, 2.87899750e-05, 3.67877384e-05, - 3.70038051e-05, 2.64828884e-05, 1.70392388e-05, 1.71271619e-05, - 1.50369175e-05, 1.22045849e-05, 2.73028787e-05, 3.46948748e-05, - 3.51961610e-05, 3.21066640e-05, 2.63220658e-05, 1.75882585e-05, - 1.42650455e-05, 1.50589122e-05, 3.31509985e-05, 4.68927093e-05, - 3.93881317e-05, 2.27639605e-05, 1.36636175e-05, 1.34570891e-05, - 1.43680649e-05, 2.40271655e-05, 3.33235826e-05, 3.96356996e-05, - 3.57035103e-05, 2.50379134e-05, 1.87735838e-05, 1.54949696e-05, - 1.27496762e-05, - 2.55484719e-05, 3.19300687e-05, 3.34017294e-05, 2.99738265e-05, - 2.49056060e-05, 2.04983524e-05, 1.82869014e-05, 1.82036059e-05, - 1.84661703e-05, 2.48024080e-05, 2.87611722e-05, 2.76032414e-05, - 2.51206602e-05, 2.47173231e-05, 2.40127705e-05, 2.07622269e-05, - 1.83344051e-05, 1.87562717e-05, 1.92479675e-05, 1.82298208e-05, - 2.69758988e-05, 3.10568987e-05, 3.07391984e-05, 2.61595269e-05, - 2.37014904e-05, 2.32911353e-05, 2.00718939e-05, 1.72006565e-05, - 1.63712070e-05, 3.06624242e-05, 3.78976632e-05, 3.50835631e-05, - 2.43850408e-05, 1.82873178e-05, 1.78648975e-05, 1.79774791e-05, - 1.74376959e-05, 1.73224591e-05, 2.36176101e-05, 3.08325559e-05, - 3.34686635e-05, 2.70777926e-05, 2.19549896e-05, 2.22234006e-05, - 2.27852545e-05, 2.03474271e-05, 1.77586752e-05, 1.87087854e-05, - 2.36874143e-05, 3.33743575e-05, 3.81678846e-05, 3.36066597e-05, - 2.49984273e-05, 1.80091269e-05, 1.60324214e-05, 1.67661305e-05, - 3.01205547e-05, 3.57313352e-05, 3.40919596e-05, 2.74202751e-05, - 2.04488991e-05, 1.63551096e-05, 1.55110017e-05, 1.68796624e-05, - 3.25426795e-05, 3.70772054e-05, 3.41258482e-05, 2.66377459e-05, - 1.83154519e-05, 1.53989154e-05, 1.64729379e-05, 1.76321666e-05, - 3.33064003e-05, 3.91209028e-05, 3.22318960e-05, 2.40719841e-05, - 2.11648503e-05, 1.99942358e-05, 1.85917620e-05, 2.76837025e-05, - 3.11799245e-05, 3.20208883e-05, 3.04473907e-05, 2.40620274e-05, - 1.84122828e-05, 1.73571039e-05, 1.78736392e-05, 2.66358097e-05, - 3.01345398e-05, 2.99547573e-05, 2.72755661e-05, 2.51677001e-05, - 2.33233016e-05, 1.96172004e-05, 1.80270220e-05, 2.56691914e-05, - 3.04401269e-05, 3.03072558e-05, 2.84002295e-05, 2.70310928e-05, - 2.35488754e-05, 1.96956608e-05, 1.77303581e-05, 1.78166754e-05, - 2.26930466e-05, 3.02468634e-05, 3.82669085e-05, 3.72377608e-05, - 2.90107732e-05, 1.95877991e-05, 1.71781280e-05, 1.98253901e-05, - 2.91512719e-05, 3.27114257e-05, 2.95410084e-05, 2.41411629e-05, - 2.29037967e-05, 2.16953375e-05, 1.88396138e-05, 1.80420151e-05, - 2.25528689e-05, 2.90949427e-05, 3.38542539e-05, 2.97776524e-05, - 2.47513368e-05, 2.05320165e-05, 1.81926256e-05, 1.81129325e-05, - 2.53743660e-05, 3.03680136e-05, 3.11494919e-05, 2.74549318e-05, - 2.35692417e-05, 2.08321988e-05, 1.80007862e-05, 1.87837014e-05, - 2.01661996e-05, 2.49637300e-05, 3.28941262e-05, 3.69039936e-05, - 3.07579083e-05, 2.23605255e-05, 1.83962611e-05, 1.63601766e-05, - 1.61769127e-05, 1.73985793e-05, 2.70393475e-05, 3.04250332e-05, - 3.11728075e-05, 2.63774611e-05, 2.07203613e-05, 2.14582368e-05, - 1.97962483e-05, 1.70866616e-05, 2.71730568e-05, 3.02218179e-05, - 3.02805990e-05, 2.92688060e-05, 2.65874400e-05, 2.09287513e-05, - 1.85118554e-05, 1.94011871e-05, 2.91423711e-05, 3.47552367e-05, - 3.28362947e-05, 2.46926212e-05, 1.81424677e-05, 1.79932588e-05, - 1.88331458e-05, 2.46447582e-05, 2.94001442e-05, 3.26390924e-05, - 3.13420241e-05, 2.61690530e-05, 2.22821903e-05, 1.97462576e-05, - 1.73684404e-05, - 2.37620267e-05, 1.84993762e-05, 1.73824069e-05, 1.89279023e-05, - 2.23216203e-05, 2.73873329e-05, 3.03936710e-05, 3.10759593e-05, - 3.16271930e-05, 2.47906590e-05, 2.13718634e-05, 2.24849012e-05, - 2.40049499e-05, 2.42476271e-05, 2.49975440e-05, 2.72824647e-05, - 2.97340422e-05, 3.03112308e-05, 3.04907031e-05, 3.17469718e-05, - 2.19714717e-05, 1.87630271e-05, 1.96959558e-05, 2.26076288e-05, - 2.43434253e-05, 2.59250934e-05, 2.96841726e-05, 3.24972625e-05, - 3.34021781e-05, 1.91973228e-05, 1.38726399e-05, 1.60278216e-05, - 2.27482217e-05, 2.76311980e-05, 3.04535611e-05, 3.21327117e-05, - 3.27018947e-05, 3.27176216e-05, 2.28534078e-05, 1.72335515e-05, - 1.66008697e-05, 2.11729492e-05, 2.58071315e-05, 2.74993214e-05, - 2.83198923e-05, 3.05532323e-05, 3.28795050e-05, 2.83009776e-05, - 2.31478255e-05, 1.69698515e-05, 1.44308438e-05, 1.72588263e-05, - 2.37842884e-05, 3.09310373e-05, 3.42323988e-05, 3.37222382e-05, - 2.03589200e-05, 1.51001044e-05, 1.58739279e-05, 2.04512495e-05, - 2.67217863e-05, 3.17660034e-05, 3.36896607e-05, 3.30651614e-05, - 1.90508608e-05, 1.41176224e-05, 1.54904050e-05, 2.12343545e-05, - 2.90549692e-05, 3.35654461e-05, 3.37922509e-05, 3.25137546e-05, - 1.68939512e-05, 1.24325839e-05, 1.64128751e-05, 2.21230506e-05, - 2.69439002e-05, 3.11199461e-05, 3.27466999e-05, 2.09172555e-05, - 1.71290918e-05, 1.70013696e-05, 1.96668674e-05, 2.60678045e-05, - 3.13870131e-05, 3.26944675e-05, 3.22316185e-05, 2.17998840e-05, - 1.82724387e-05, 1.85866808e-05, 2.10600522e-05, 2.42436403e-05, - 2.74942265e-05, 3.08790894e-05, 3.20596740e-05, 2.26861337e-05, - 1.87532605e-05, 1.89757104e-05, 1.98779771e-05, 2.16989676e-05, - 2.62126015e-05, 3.06304314e-05, 3.24834825e-05, 3.22971216e-05, - 2.20439170e-05, 1.59713404e-05, 1.29599539e-05, 1.53131681e-05, - 2.29588903e-05, 3.16970590e-05, 3.34555113e-05, 3.18660181e-05, - 1.97459607e-05, 1.58762555e-05, 1.84238442e-05, 2.31926763e-05, - 2.54495947e-05, 2.81212507e-05, 3.11096534e-05, 3.18423729e-05, - 2.24101565e-05, 1.83309533e-05, 1.66333916e-05, 1.99370285e-05, - 2.43335116e-05, 2.94026127e-05, 3.22691360e-05, 3.18321900e-05, - 2.32469943e-05, 1.86255171e-05, 1.80161826e-05, 2.03798267e-05, - 2.39390605e-05, 2.79005891e-05, 3.16289667e-05, 3.16531698e-05, - 3.10719846e-05, 2.23244884e-05, 1.65184309e-05, 1.50247064e-05, - 1.95415651e-05, 2.56327806e-05, 2.98380749e-05, 3.33588506e-05, - 3.40021362e-05, 3.27815906e-05, 1.96691974e-05, 1.60372928e-05, - 1.69208212e-05, 2.19610917e-05, 2.87781311e-05, 3.13101262e-05, - 3.29716245e-05, 3.40388368e-05, 2.23181186e-05, 1.78672012e-05, - 1.74160533e-05, 1.93378147e-05, 2.27318098e-05, 2.76770473e-05, - 3.06465614e-05, 3.11199480e-05, 1.78429783e-05, 1.35954046e-05, - 1.70284979e-05, 2.52690633e-05, 3.17223961e-05, 3.20118341e-05, - 3.16423630e-05, 2.24257090e-05, 1.80744525e-05, 1.65276624e-05, - 1.85454553e-05, 2.42030398e-05, 2.86403904e-05, 3.07682123e-05, - 3.25135836e-05, - 2.32398710e-05, 1.72430927e-05, 1.60217536e-05, 1.80962177e-05, - 2.23308768e-05, 2.81330502e-05, 3.16300116e-05, 3.22199744e-05, - 3.25146426e-05, 2.43102401e-05, 2.03343682e-05, 2.15534215e-05, - 2.35826660e-05, 2.39196059e-05, 2.47711601e-05, 2.79296550e-05, - 3.10743665e-05, 3.13175171e-05, 3.12053519e-05, 3.27382504e-05, - 2.13616787e-05, 1.76756128e-05, 1.84760552e-05, 2.21286766e-05, - 2.43754084e-05, 2.57802061e-05, 3.01567988e-05, 3.39148121e-05, - 3.51320675e-05, 1.81160469e-05, 1.23738288e-05, 1.45995758e-05, - 2.28540741e-05, 2.93793166e-05, 3.19038567e-05, 3.31829826e-05, - 3.39402767e-05, 3.40194827e-05, 2.32137010e-05, 1.65416038e-05, - 1.54084729e-05, 2.07043020e-05, 2.62343936e-05, 2.74549187e-05, - 2.78432784e-05, 3.06983520e-05, 3.38958445e-05, 2.97213275e-05, - 2.34259049e-05, 1.57138633e-05, 1.27397916e-05, 1.58781247e-05, - 2.34547071e-05, 3.22095843e-05, 3.60064075e-05, 3.51466151e-05, - 1.91563282e-05, 1.37514427e-05, 1.47050505e-05, 2.00291735e-05, - 2.76196014e-05, 3.38197393e-05, 3.59007841e-05, 3.45561402e-05, - 1.74984556e-05, 1.27229722e-05, 1.44006254e-05, 2.08922650e-05, - 3.05337693e-05, 3.58715674e-05, 3.53811741e-05, 3.36795346e-05, - 1.56719770e-05, 1.10465282e-05, 1.55540821e-05, 2.24601971e-05, - 2.74800751e-05, 3.13147495e-05, 3.33221930e-05, 2.03147928e-05, - 1.63724638e-05, 1.60653352e-05, 1.85354615e-05, 2.55825385e-05, - 3.23541140e-05, 3.39810108e-05, 3.33194159e-05, 2.13382722e-05, - 1.75402404e-05, 1.78348428e-05, 2.05534877e-05, 2.37510338e-05, - 2.69804766e-05, 3.13204010e-05, 3.30976005e-05, 2.23572617e-05, - 1.78337175e-05, 1.80422173e-05, 1.92848140e-05, 2.11313449e-05, - 2.58999478e-05, 3.10861182e-05, 3.35996268e-05, 3.34033281e-05, - 2.28850137e-05, 1.56724251e-05, 1.16071989e-05, 1.35909565e-05, - 2.14529848e-05, 3.19712491e-05, 3.46884628e-05, 3.19773940e-05, - 1.89639548e-05, 1.50205362e-05, 1.78184263e-05, 2.32969056e-05, - 2.55623331e-05, 2.81725248e-05, 3.19064037e-05, 3.29173173e-05, - 2.32394945e-05, 1.78653770e-05, 1.53428689e-05, 1.89323089e-05, - 2.39740473e-05, 2.97128116e-05, 3.31705563e-05, 3.28700248e-05, - 2.28999060e-05, 1.77538748e-05, 1.70741364e-05, 1.99621562e-05, - 2.41038934e-05, 2.83897663e-05, 3.27708075e-05, 3.23635708e-05, - 3.11903063e-05, 2.23131457e-05, 1.54800644e-05, 1.34457964e-05, - 1.83532020e-05, 2.59279066e-05, 3.11260314e-05, 3.51041037e-05, - 3.57318540e-05, 3.40260749e-05, 1.95203969e-05, 1.56835170e-05, - 1.62098552e-05, 2.15494169e-05, 2.91338865e-05, 3.07283277e-05, - 3.28383875e-05, 3.52027237e-05, 2.15660928e-05, 1.71982552e-05, - 1.68258610e-05, 1.86120102e-05, 2.20808136e-05, 2.81686140e-05, - 3.17129339e-05, 3.16199711e-05, 1.74626340e-05, 1.27783535e-05, - 1.58883496e-05, 2.47214259e-05, 3.27668240e-05, 3.30785735e-05, - 3.23285566e-05, 2.25045280e-05, 1.75790934e-05, 1.55474989e-05, - 1.74326963e-05, 2.33581076e-05, 2.83113315e-05, 3.11679330e-05, - 3.38307528e-05, - 2.51620777e-05, 2.49941620e-05, 2.48013332e-05, 2.55496205e-05, - 2.58100107e-05, 2.48505373e-05, 2.40634633e-05, 2.38625808e-05, - 2.36940898e-05, 2.49896351e-05, 2.50915184e-05, 2.50555839e-05, - 2.51805464e-05, 2.51895891e-05, 2.50877101e-05, 2.48557446e-05, - 2.42616892e-05, 2.40718619e-05, 2.39929362e-05, 2.36657745e-05, - 2.54073904e-05, 2.52253233e-05, 2.50144415e-05, 2.54043481e-05, - 2.53690959e-05, 2.49209699e-05, 2.41750103e-05, 2.34535882e-05, - 2.31701052e-05, 2.52146679e-05, 2.39058311e-05, 2.45451504e-05, - 2.57770364e-05, 2.49226966e-05, 2.40533610e-05, 2.35590351e-05, - 2.33981990e-05, 2.33926299e-05, 2.59004529e-05, 2.58507665e-05, - 2.50414889e-05, 2.56584832e-05, 2.51811809e-05, 2.45935639e-05, - 2.42485467e-05, 2.38897271e-05, 2.33483346e-05, 2.46931272e-05, - 2.57831708e-05, 2.49536077e-05, 2.36050432e-05, 2.47597301e-05, - 2.52830835e-05, 2.39091427e-05, 2.29205930e-05, 2.30980810e-05, - 2.49991705e-05, 2.45590483e-05, 2.50278066e-05, 2.58170837e-05, - 2.50710514e-05, 2.36357750e-05, 2.30292843e-05, 2.32852151e-05, - 2.45727428e-05, 2.42358204e-05, 2.51438382e-05, 2.57583053e-05, - 2.44712431e-05, 2.30533544e-05, 2.30667003e-05, 2.34523804e-05, - 2.50074696e-05, 2.36813845e-05, 2.56083937e-05, 2.60658611e-05, - 2.49172808e-05, 2.37540491e-05, 2.33691118e-05, 2.55748145e-05, - 2.57590762e-05, 2.54830771e-05, 2.51264585e-05, 2.47272676e-05, - 2.37657559e-05, 2.33995873e-05, 2.35318385e-05, 2.55596913e-05, - 2.57278972e-05, 2.56778649e-05, 2.56424228e-05, 2.50895993e-05, - 2.44131053e-05, 2.38537102e-05, 2.35793277e-05, 2.55004213e-05, - 2.54491683e-05, 2.54171847e-05, 2.57268734e-05, 2.54869198e-05, - 2.47799114e-05, 2.39215470e-05, 2.34607992e-05, 2.35135514e-05, - 2.63658704e-05, 2.65300380e-05, 2.39843236e-05, 2.37879688e-05, - 2.44799850e-05, 2.36170526e-05, 2.31830232e-05, 2.35510864e-05, - 2.55346501e-05, 2.56049291e-05, 2.58782527e-05, 2.56742353e-05, - 2.51463761e-05, 2.44741663e-05, 2.38310478e-05, 2.36418129e-05, - 2.62581154e-05, 2.60620260e-05, 2.48699183e-05, 2.52607446e-05, - 2.51532609e-05, 2.42172916e-05, 2.35161698e-05, 2.36435263e-05, - 2.53786670e-05, 2.55198343e-05, 2.54542208e-05, 2.58325443e-05, - 2.55327334e-05, 2.46510476e-05, 2.37043801e-05, 2.36747689e-05, - 2.37534502e-05, 2.57955218e-05, 2.53054259e-05, 2.40365689e-05, - 2.50612452e-05, 2.51763722e-05, 2.42281496e-05, 2.31816434e-05, - 2.29929333e-05, 2.33752906e-05, 2.62101534e-05, 2.64394809e-05, - 2.58366359e-05, 2.55721406e-05, 2.43891996e-05, 2.35466723e-05, - 2.32396290e-05, 2.30198079e-05, 2.52333885e-05, 2.58430086e-05, - 2.59855398e-05, 2.56411527e-05, 2.52502841e-05, 2.47108060e-05, - 2.39810634e-05, 2.37974377e-05, 2.62251804e-05, 2.55026282e-05, - 2.51513750e-05, 2.48559495e-05, 2.36747763e-05, 2.35936063e-05, - 2.36757570e-05, 2.58328513e-05, 2.60530758e-05, 2.54052355e-05, - 2.51972642e-05, 2.48625019e-05, 2.42290897e-05, 2.38770005e-05, - 2.34511563e-05, - 2.48572816e-05, 2.32796157e-05, 2.27891076e-05, 2.43425630e-05, - 2.58661644e-05, 2.59083532e-05, 2.56089059e-05, 2.53621756e-05, - 2.50343315e-05, 2.48256386e-05, 2.40232647e-05, 2.42317389e-05, - 2.49902819e-05, 2.51073356e-05, 2.51638120e-05, 2.58281203e-05, - 2.58656313e-05, 2.54487170e-05, 2.51670417e-05, 2.50811518e-05, - 2.48231791e-05, 2.37259222e-05, 2.35270389e-05, 2.50166243e-05, - 2.56193822e-05, 2.51457007e-05, 2.51351907e-05, 2.51757364e-05, - 2.51101422e-05, 2.37889319e-05, 2.10700426e-05, 2.22138154e-05, - 2.59650773e-05, 2.68041987e-05, 2.57542650e-05, 2.50268616e-05, - 2.50072200e-05, 2.50436727e-05, 2.63458873e-05, 2.45452487e-05, - 2.30684176e-05, 2.51198446e-05, 2.58859434e-05, 2.50222636e-05, - 2.44060522e-05, 2.46612764e-05, 2.48172581e-05, 2.63237395e-05, - 2.61701753e-05, 2.29778106e-05, 2.06858237e-05, 2.27048699e-05, - 2.51549137e-05, 2.54991941e-05, 2.48983657e-05, 2.48502843e-05, - 2.36290544e-05, 2.21340504e-05, 2.29488908e-05, 2.52415645e-05, - 2.62247197e-05, 2.57742264e-05, 2.52741689e-05, 2.50668346e-05, - 2.26591163e-05, 2.15634629e-05, 2.30837724e-05, 2.53541958e-05, - 2.61636717e-05, 2.53576253e-05, 2.49235089e-05, 2.50085050e-05, - 2.30545401e-05, 2.06636844e-05, 2.39781109e-05, 2.64342135e-05, - 2.57805644e-05, 2.45929822e-05, 2.45450399e-05, 2.48713083e-05, - 2.43628887e-05, 2.38624960e-05, 2.37219564e-05, 2.46806194e-05, - 2.51522654e-05, 2.50400174e-05, 2.50278690e-05, 2.50995279e-05, - 2.45324441e-05, 2.45067645e-05, 2.50524619e-05, 2.48605728e-05, - 2.44717229e-05, 2.48520227e-05, 2.50365393e-05, 2.52634485e-05, - 2.41233241e-05, 2.41100994e-05, 2.49019105e-05, 2.49116330e-05, - 2.48887728e-05, 2.49175712e-05, 2.49832170e-05, 2.50238483e-05, - 2.72481974e-05, 2.55185075e-05, 2.11170374e-05, 2.10165990e-05, - 2.32102429e-05, 2.45418730e-05, 2.48079208e-05, 2.43749417e-05, - 2.44956197e-05, 2.38872550e-05, 2.48447469e-05, 2.58976609e-05, - 2.55542757e-05, 2.50219454e-05, 2.50888244e-05, 2.51172051e-05, - 2.71468622e-05, 2.51728832e-05, 2.27970128e-05, 2.40225451e-05, - 2.50511765e-05, 2.50419714e-05, 2.48888971e-05, 2.50933876e-05, - 2.51813563e-05, 2.42256007e-05, 2.39908202e-05, 2.52531690e-05, - 2.58728188e-05, 2.55289998e-05, 2.52189260e-05, 2.48948916e-05, - 2.45365529e-05, 2.58315855e-05, 2.34880285e-05, 2.13519599e-05, - 2.35810890e-05, 2.57554918e-05, 2.57960708e-05, 2.51308994e-05, - 2.49405614e-05, 2.49903697e-05, 2.58380021e-05, 2.53668208e-05, - 2.44607295e-05, 2.51786429e-05, 2.52125617e-05, 2.38650448e-05, - 2.39664160e-05, 2.46164199e-05, 2.45553800e-05, 2.46586357e-05, - 2.48252339e-05, 2.46043797e-05, 2.47150833e-05, 2.55783570e-05, - 2.54123444e-05, 2.48486177e-05, 2.53693557e-05, 2.34188217e-05, - 2.33101970e-05, 2.46811604e-05, 2.51255982e-05, 2.50687266e-05, - 2.48788826e-05, 2.59669118e-05, 2.50953357e-05, 2.36550741e-05, - 2.36372561e-05, 2.43204640e-05, 2.45238346e-05, 2.48404109e-05, - 2.51073410e-05, - 2.42339780e-05, 2.03001114e-05, 1.93780751e-05, 2.15198487e-05, - 2.47380085e-05, 2.73762994e-05, 2.85925633e-05, 2.85691479e-05, - 2.83203022e-05, 2.46630550e-05, 2.22557435e-05, 2.29573496e-05, - 2.45027847e-05, 2.47559627e-05, 2.51764078e-05, 2.72034297e-05, - 2.86363564e-05, 2.82752753e-05, 2.79134524e-05, 2.84693242e-05, - 2.33852715e-05, 2.08418344e-05, 2.10406009e-05, 2.38923404e-05, - 2.54319090e-05, 2.55919747e-05, 2.74344223e-05, 2.90883526e-05, - 2.95433197e-05, 2.10894284e-05, 1.64714439e-05, 1.83075250e-05, - 2.50665861e-05, 2.89030007e-05, 2.88801922e-05, 2.85963478e-05, - 2.88978785e-05, 2.89755913e-05, 2.55805501e-05, 2.09475522e-05, - 1.93039534e-05, 2.33464198e-05, 2.65122007e-05, 2.61800388e-05, - 2.57227508e-05, 2.71492611e-05, 2.86533680e-05, 2.85337438e-05, - 2.55165253e-05, 1.93783236e-05, 1.63828730e-05, 1.92502358e-05, - 2.45975303e-05, 2.87220191e-05, 2.96636614e-05, 2.92279519e-05, - 2.14198598e-05, 1.78552737e-05, 1.88863138e-05, 2.31415815e-05, - 2.74740052e-05, 2.97714930e-05, 3.00976105e-05, 2.92366920e-05, - 1.99313017e-05, 1.69718480e-05, 1.88379009e-05, 2.36323313e-05, - 2.87271086e-05, 3.01921716e-05, 2.94205699e-05, 2.87873607e-05, - 1.94159536e-05, 1.55595239e-05, 2.00452039e-05, 2.53090272e-05, - 2.69568171e-05, 2.73272990e-05, 2.80962241e-05, 2.29599769e-05, - 2.07274544e-05, 2.02031100e-05, 2.12226771e-05, 2.50623628e-05, - 2.83867150e-05, 2.89545969e-05, 2.86558585e-05, 2.36140346e-05, - 2.14117973e-05, 2.15291723e-05, 2.32208951e-05, 2.44565887e-05, - 2.54369997e-05, 2.76139613e-05, 2.85711460e-05, 2.42121480e-05, - 2.12260278e-05, 2.13106827e-05, 2.25174121e-05, 2.33595290e-05, - 2.53949657e-05, 2.75883543e-05, 2.87232678e-05, 2.86870618e-05, - 2.62569391e-05, 2.12519895e-05, 1.61314958e-05, 1.69993467e-05, - 2.20370229e-05, 2.75390280e-05, 2.89793004e-05, 2.73564034e-05, - 2.20388436e-05, 1.97194032e-05, 2.17887127e-05, 2.52067826e-05, - 2.58921807e-05, 2.64810876e-05, 2.81238969e-05, 2.85877008e-05, - 2.63350552e-05, 2.20711104e-05, 1.90739115e-05, 2.16407022e-05, - 2.47276963e-05, 2.71478957e-05, 2.84305852e-05, 2.85398164e-05, - 2.43785289e-05, 2.12699675e-05, 2.07730343e-05, 2.31204690e-05, - 2.55482672e-05, 2.70951118e-05, 2.86426294e-05, 2.80976749e-05, - 2.72149673e-05, 2.46989607e-05, 1.96470885e-05, 1.71664931e-05, - 2.10296587e-05, 2.62483284e-05, 2.85810745e-05, 2.95567695e-05, - 2.95959074e-05, 2.89146901e-05, 2.34021428e-05, 2.11440486e-05, - 2.07233449e-05, 2.37772390e-05, 2.70837316e-05, 2.63095107e-05, - 2.72446383e-05, 2.89652072e-05, 2.32429262e-05, 2.13488840e-05, - 2.12993781e-05, 2.19662640e-05, 2.36058721e-05, 2.70503431e-05, - 2.84060314e-05, 2.77348857e-05, 2.20318865e-05, 1.82629419e-05, - 1.97064149e-05, 2.47023311e-05, 2.85328663e-05, 2.86004726e-05, - 2.80648418e-05, 2.49080548e-05, 2.18725616e-05, 1.98026589e-05, - 2.06628886e-05, 2.37992529e-05, 2.60315628e-05, 2.75378185e-05, - 2.89699769e-05, - 2.50976746e-05, 2.48429913e-05, 2.46288749e-05, 2.55903059e-05, - 2.60251734e-05, 2.49824808e-05, 2.41366758e-05, 2.38749595e-05, - 2.36189882e-05, 2.48898818e-05, 2.49359268e-05, 2.48973642e-05, - 2.51393784e-05, 2.51687967e-05, 2.50620285e-05, 2.49664127e-05, - 2.44000935e-05, 2.40957075e-05, 2.39376716e-05, 2.36074158e-05, - 2.53983751e-05, 2.51479937e-05, 2.48413465e-05, 2.54140810e-05, - 2.54668591e-05, 2.48730271e-05, 2.41031256e-05, 2.34461359e-05, - 2.31757607e-05, 2.51239104e-05, 2.37071799e-05, 2.43655384e-05, - 2.60013535e-05, 2.53115028e-05, 2.41726318e-05, 2.34932868e-05, - 2.33424192e-05, 2.33491965e-05, 2.62133302e-05, 2.60477037e-05, - 2.49831565e-05, 2.57490681e-05, 2.53183650e-05, 2.44954005e-05, - 2.39919954e-05, 2.36950161e-05, 2.32372293e-05, 2.49466959e-05, - 2.60448127e-05, 2.48488497e-05, 2.32806196e-05, 2.45797214e-05, - 2.52860979e-05, 2.39603530e-05, 2.28895373e-05, 2.30266421e-05, - 2.48110828e-05, 2.44445146e-05, 2.50050099e-05, 2.59684443e-05, - 2.52898953e-05, 2.38046558e-05, 2.31109925e-05, 2.32617940e-05, - 2.42644325e-05, 2.41055978e-05, 2.51811918e-05, 2.58985902e-05, - 2.46878985e-05, 2.31603510e-05, 2.30237040e-05, 2.33912948e-05, - 2.49237099e-05, 2.35641816e-05, 2.57498853e-05, 2.64232459e-05, - 2.50168684e-05, 2.35453765e-05, 2.31714553e-05, 2.56222608e-05, - 2.59252751e-05, 2.55547564e-05, 2.49948465e-05, 2.45663487e-05, - 2.37211245e-05, 2.33542092e-05, 2.34689804e-05, 2.56190237e-05, - 2.58500114e-05, 2.57743668e-05, 2.57231492e-05, 2.50120924e-05, - 2.41809291e-05, 2.37141269e-05, 2.35147330e-05, 2.55632864e-05, - 2.54546034e-05, 2.54062269e-05, 2.58330119e-05, 2.55086445e-05, - 2.46655750e-05, 2.37975514e-05, 2.33908212e-05, 2.34511963e-05, - 2.69272894e-05, 2.70369472e-05, 2.38919839e-05, 2.34438531e-05, - 2.40894164e-05, 2.34007029e-05, 2.30872377e-05, 2.32905126e-05, - 2.55605038e-05, 2.57722022e-05, 2.60572776e-05, 2.58689267e-05, - 2.52059388e-05, 2.43716950e-05, 2.37623925e-05, 2.35967625e-05, - 2.67831651e-05, 2.63180766e-05, 2.47552536e-05, 2.51764328e-05, - 2.51171909e-05, 2.41188655e-05, 2.34113209e-05, 2.35908953e-05, - 2.54040593e-05, 2.55546315e-05, 2.54798616e-05, 2.59899962e-05, - 2.57013785e-05, 2.46808541e-05, 2.36855477e-05, 2.35588036e-05, - 2.35289959e-05, 2.60024700e-05, 2.53380033e-05, 2.37802006e-05, - 2.49079020e-05, 2.52829648e-05, 2.43474330e-05, 2.31927242e-05, - 2.29658185e-05, 2.33165855e-05, 2.65352643e-05, 2.69075533e-05, - 2.60391438e-05, 2.56427480e-05, 2.43348478e-05, 2.31479201e-05, - 2.28806167e-05, 2.28814829e-05, 2.51518017e-05, 2.60190408e-05, - 2.62288316e-05, 2.57131631e-05, 2.51882310e-05, 2.47541474e-05, - 2.39999240e-05, 2.36598308e-05, 2.65565247e-05, 2.57948004e-05, - 2.51085950e-05, 2.47116282e-05, 2.36294331e-05, 2.35377723e-05, - 2.35549041e-05, 2.60681859e-05, 2.63090360e-05, 2.54710917e-05, - 2.51155109e-05, 2.46648464e-05, 2.39989901e-05, 2.37329860e-05, - 2.34218575e-05, - 2.50167027e-05, 2.44994403e-05, 2.42269493e-05, 2.54433362e-05, - 2.61765699e-05, 2.52219296e-05, 2.44046067e-05, 2.40965035e-05, - 2.37615237e-05, 2.48066430e-05, 2.46860537e-05, 2.46817060e-05, - 2.50897348e-05, 2.51477195e-05, 2.50604876e-05, 2.51799533e-05, - 2.47192263e-05, 2.43080827e-05, 2.40705239e-05, 2.37710850e-05, - 2.53120848e-05, 2.48828538e-05, 2.45183372e-05, 2.53684015e-05, - 2.55698949e-05, 2.48783333e-05, 2.41957947e-05, 2.36846468e-05, - 2.34520742e-05, 2.48614439e-05, 2.31610481e-05, 2.39101337e-05, - 2.61778246e-05, 2.58366428e-05, 2.44922642e-05, 2.36592071e-05, - 2.35338940e-05, 2.35544347e-05, 2.64850592e-05, 2.59852122e-05, - 2.46578245e-05, 2.57330961e-05, 2.55117030e-05, 2.44972052e-05, - 2.38547817e-05, 2.36824387e-05, 2.33736196e-05, 2.53462640e-05, - 2.62744280e-05, 2.44943029e-05, 2.26456001e-05, 2.41666318e-05, - 2.52736797e-05, 2.42198005e-05, 2.31464959e-05, 2.32269650e-05, - 2.44962518e-05, 2.40144236e-05, 2.46854411e-05, 2.59860755e-05, - 2.56001113e-05, 2.42165291e-05, 2.34784968e-05, 2.34977202e-05, - 2.37941732e-05, 2.36269830e-05, 2.49020301e-05, 2.59343152e-05, - 2.50712900e-05, 2.35526920e-05, 2.32567143e-05, 2.35721737e-05, - 2.45856827e-05, 2.30381687e-05, 2.56025459e-05, 2.67131782e-05, - 2.52078849e-05, 2.35330828e-05, 2.32121069e-05, 2.55544416e-05, - 2.58293961e-05, 2.53647925e-05, 2.47100472e-05, 2.44609563e-05, - 2.38898708e-05, 2.35567429e-05, 2.36406009e-05, 2.55945228e-05, - 2.57564739e-05, 2.56682024e-05, 2.56933161e-05, 2.49336881e-05, - 2.40452494e-05, 2.37681676e-05, 2.36799756e-05, 2.55735675e-05, - 2.52675299e-05, 2.52116411e-05, 2.57847044e-05, 2.54432520e-05, - 2.46119191e-05, 2.38613647e-05, 2.35613294e-05, 2.36250705e-05, - 2.74274433e-05, 2.72195389e-05, 2.34053755e-05, 2.28203092e-05, - 2.36644265e-05, 2.33952163e-05, 2.32545689e-05, 2.32429033e-05, - 2.54292508e-05, 2.56277487e-05, 2.60244430e-05, 2.60311668e-05, - 2.53066507e-05, 2.43873948e-05, 2.38979294e-05, 2.37772757e-05, - 2.72598372e-05, 2.63564226e-05, 2.43796736e-05, 2.49460365e-05, - 2.50834825e-05, 2.41756415e-05, 2.35388320e-05, 2.37629842e-05, - 2.53960189e-05, 2.53908438e-05, 2.52847760e-05, 2.60109773e-05, - 2.58633919e-05, 2.48283075e-05, 2.38885784e-05, 2.36584006e-05, - 2.34989313e-05, 2.61456003e-05, 2.50933216e-05, 2.32230451e-05, - 2.45982519e-05, 2.54385434e-05, 2.46489481e-05, 2.34738677e-05, - 2.32213980e-05, 2.35069507e-05, 2.66955111e-05, 2.70554558e-05, - 2.59694938e-05, 2.56352170e-05, 2.44199786e-05, 2.29434498e-05, - 2.27571165e-05, 2.30171753e-05, 2.50057460e-05, 2.59615565e-05, - 2.62180545e-05, 2.56115522e-05, 2.50753703e-05, 2.49089833e-05, - 2.42164444e-05, 2.37223767e-05, 2.66485465e-05, 2.56724126e-05, - 2.48131638e-05, 2.45985150e-05, 2.38064302e-05, 2.37111759e-05, - 2.36490147e-05, 2.62440395e-05, 2.63370069e-05, 2.52576262e-05, - 2.48384740e-05, 2.44653164e-05, 2.38977449e-05, 2.37793843e-05, - 2.36370960e-05, - 2.54303115e-05, 3.14544510e-05, 3.28189194e-05, 3.00183024e-05, - 2.53509471e-05, 2.07888131e-05, 1.84854077e-05, 1.83082222e-05, - 1.84305503e-05, 2.46255646e-05, 2.83696590e-05, 2.72373016e-05, - 2.50571351e-05, 2.47006417e-05, 2.39959426e-05, 2.10168253e-05, - 1.86329167e-05, 1.88758318e-05, 1.92357984e-05, 1.82233622e-05, - 2.69514314e-05, 3.07939732e-05, 3.02459449e-05, 2.61860596e-05, - 2.39239586e-05, 2.32413444e-05, 2.00222210e-05, 1.72808472e-05, - 1.64750153e-05, 3.03760398e-05, 3.70456981e-05, 3.44159098e-05, - 2.48462906e-05, 1.89587431e-05, 1.81336484e-05, 1.79619829e-05, - 1.74429132e-05, 1.73474997e-05, 2.42380492e-05, 3.12411506e-05, - 3.31936362e-05, 2.72651649e-05, 2.22538912e-05, 2.20956719e-05, - 2.23443249e-05, 2.00804520e-05, 1.76746671e-05, 1.91846227e-05, - 2.42147985e-05, 3.29765984e-05, 3.68936010e-05, 3.29955281e-05, - 2.50257219e-05, 1.81745201e-05, 1.60852391e-05, 1.67540041e-05, - 2.96100533e-05, 3.52286855e-05, 3.38979280e-05, 2.77351323e-05, - 2.08826455e-05, 1.66905541e-05, 1.57232041e-05, 1.69380747e-05, - 3.16256129e-05, 3.64766540e-05, 3.40954928e-05, 2.69320797e-05, - 1.87323955e-05, 1.56453404e-05, 1.65053796e-05, 1.76273891e-05, - 3.29672991e-05, 3.84760490e-05, 3.24983430e-05, 2.47789183e-05, - 2.13997536e-05, 1.97102624e-05, 1.83550583e-05, 2.77723566e-05, - 3.15135613e-05, 3.21134373e-05, 3.00660346e-05, 2.37775726e-05, - 1.84257700e-05, 1.73788978e-05, 1.78637196e-05, 2.67609051e-05, - 3.03692423e-05, 3.01308521e-05, 2.74402934e-05, 2.50293560e-05, - 2.29155277e-05, 1.94592360e-05, 1.80128216e-05, 2.58103640e-05, - 3.03931683e-05, 3.02231270e-05, 2.86113854e-05, 2.70719009e-05, - 2.33669724e-05, 1.95628514e-05, 1.77108311e-05, 1.78081107e-05, - 2.37329822e-05, 3.13674415e-05, 3.77383001e-05, 3.59594065e-05, - 2.80462515e-05, 1.92992555e-05, 1.71249199e-05, 1.94545164e-05, - 2.91727034e-05, 3.30402904e-05, 2.99105763e-05, 2.45457692e-05, - 2.30595097e-05, 2.15683585e-05, 1.88101281e-05, 1.80582775e-05, - 2.35275571e-05, 2.96380640e-05, 3.34144923e-05, 2.95285559e-05, - 2.47036523e-05, 2.04303366e-05, 1.81128597e-05, 1.81166512e-05, - 2.54423946e-05, 3.03928438e-05, 3.11399928e-05, 2.77826670e-05, - 2.39245698e-05, 2.09488627e-05, 1.80582351e-05, 1.86779305e-05, - 1.98507592e-05, 2.53933011e-05, 3.28729625e-05, 3.59211954e-05, - 3.03134844e-05, 2.26043633e-05, 1.86655952e-05, 1.64718581e-05, - 1.62344825e-05, 1.73996894e-05, 2.77165879e-05, 3.14615338e-05, - 3.15942150e-05, 2.65284942e-05, 2.06927560e-05, 2.07845401e-05, - 1.92516717e-05, 1.69695136e-05, 2.69875225e-05, 3.05825257e-05, - 3.07982079e-05, 2.93949697e-05, 2.64555916e-05, 2.10680462e-05, - 1.86248823e-05, 1.92501122e-05, 2.98529027e-05, 3.54130061e-05, - 3.26186132e-05, 2.44274909e-05, 1.81573498e-05, 1.79931198e-05, - 1.87186616e-05, 2.51279649e-05, 2.99441721e-05, 3.27083546e-05, - 3.10608706e-05, 2.57551121e-05, 2.19055802e-05, 1.95785874e-05, - 1.74145602e-05, - 2.56809138e-05, 2.90946400e-05, 2.97642064e-05, 2.78806747e-05, - 2.49514061e-05, 2.22570892e-05, 2.07441715e-05, 2.07426033e-05, - 2.10254816e-05, 2.52866711e-05, 2.75737702e-05, 2.69642868e-05, - 2.54001874e-05, 2.51348168e-05, 2.47147660e-05, 2.24595955e-05, - 2.07153941e-05, 2.11379601e-05, 2.15758735e-05, 2.08329618e-05, - 2.64124880e-05, 2.85758319e-05, 2.85824388e-05, 2.59330002e-05, - 2.43736090e-05, 2.42939349e-05, 2.21796290e-05, 2.00038804e-05, - 1.93452387e-05, 2.84134566e-05, 3.14093504e-05, 3.04367332e-05, - 2.46343065e-05, 2.04433132e-05, 2.03858411e-05, 2.06515568e-05, - 2.02324890e-05, 2.01321869e-05, 2.40696416e-05, 2.80382121e-05, - 2.95861271e-05, 2.63318753e-05, 2.32236570e-05, 2.36684290e-05, - 2.42259591e-05, 2.25083891e-05, 2.05318294e-05, 2.08764945e-05, - 2.41714091e-05, 2.96310960e-05, 3.17749796e-05, 2.98620544e-05, - 2.52714021e-05, 2.05594857e-05, 1.91099211e-05, 1.97282857e-05, - 2.83082158e-05, 3.05404921e-05, 2.97664492e-05, 2.64324653e-05, - 2.21322137e-05, 1.91840265e-05, 1.85886332e-05, 1.97709691e-05, - 2.96397765e-05, 3.10137064e-05, 2.96691070e-05, 2.60256698e-05, - 2.06259620e-05, 1.84755971e-05, 1.94709699e-05, 2.03859477e-05, - 2.95658183e-05, 3.15408836e-05, 2.87341529e-05, 2.42907806e-05, - 2.27431887e-05, 2.22750501e-05, 2.12458856e-05, 2.67155892e-05, - 2.82412831e-05, 2.87607274e-05, 2.83765581e-05, 2.49146144e-05, - 2.09545774e-05, 2.01606401e-05, 2.05704968e-05, 2.61326385e-05, - 2.78326053e-05, 2.77865145e-05, 2.64518777e-05, 2.54750327e-05, - 2.45414171e-05, 2.19307155e-05, 2.06876039e-05, 2.55844542e-05, - 2.81565581e-05, 2.81194098e-05, 2.70054038e-05, 2.64004753e-05, - 2.45370114e-05, 2.19698804e-05, 2.04692751e-05, 2.05270039e-05, - 2.32277608e-05, 2.73081340e-05, 3.12698335e-05, 3.15288713e-05, - 2.80653406e-05, 2.19933375e-05, 2.00721611e-05, 2.22127560e-05, - 2.75010736e-05, 2.88880320e-05, 2.74650545e-05, 2.45243787e-05, - 2.39214735e-05, 2.33245982e-05, 2.12934812e-05, 2.06792672e-05, - 2.31800546e-05, 2.71371342e-05, 2.98422227e-05, 2.79776334e-05, - 2.51745373e-05, 2.25295455e-05, 2.08523574e-05, 2.07399437e-05, - 2.54628016e-05, 2.80768243e-05, 2.84519102e-05, 2.64424991e-05, - 2.42082460e-05, 2.25946443e-05, 2.06222591e-05, 2.13017166e-05, - 2.24143726e-05, 2.49953359e-05, 2.91929253e-05, 3.12292569e-05, - 2.85592849e-05, 2.35205152e-05, 2.07795045e-05, 1.93315030e-05, - 1.92215748e-05, 2.02054236e-05, 2.59980696e-05, 2.74443762e-05, - 2.81807445e-05, 2.59743543e-05, 2.26106394e-05, 2.35164953e-05, - 2.23033379e-05, 2.00430988e-05, 2.66211200e-05, 2.77913369e-05, - 2.77165120e-05, 2.74908887e-05, 2.62701487e-05, 2.26454440e-05, - 2.09639948e-05, 2.17735560e-05, 2.70521445e-05, 2.94245052e-05, - 2.92997370e-05, 2.52782688e-05, 2.07546979e-05, 2.06534841e-05, - 2.13430916e-05, 2.47742681e-05, 2.72845989e-05, 2.90308088e-05, - 2.87137438e-05, 2.62189994e-05, 2.38645321e-05, 2.20276424e-05, - 2.01536800e-05, - 2.56588954e-05, 2.92276133e-05, 2.99358224e-05, 2.80466846e-05, - 2.50342528e-05, 2.21846119e-05, 2.05981489e-05, 2.05714623e-05, - 2.08251595e-05, 2.52274430e-05, 2.76024569e-05, 2.69567644e-05, - 2.53767525e-05, 2.51092904e-05, 2.46675953e-05, 2.23852212e-05, - 2.05949715e-05, 2.09829107e-05, 2.13998246e-05, 2.06345824e-05, - 2.64583505e-05, 2.87186275e-05, 2.86643435e-05, 2.59630251e-05, - 2.43715689e-05, 2.42176059e-05, 2.20147559e-05, 1.98052436e-05, - 1.91362461e-05, 2.85361058e-05, 3.17311381e-05, 3.06640682e-05, - 2.47053219e-05, 2.04116786e-05, 2.02482001e-05, 2.04452482e-05, - 2.00197070e-05, 1.99220274e-05, 2.41538803e-05, 2.83102574e-05, - 2.98232213e-05, 2.64270734e-05, 2.31904644e-05, 2.35428391e-05, - 2.40421626e-05, 2.22972361e-05, 2.03032408e-05, 2.08069623e-05, - 2.42370828e-05, 2.98393943e-05, 3.20267705e-05, 3.00365585e-05, - 2.52645400e-05, 2.03992562e-05, 1.88813283e-05, 1.94971068e-05, - 2.83623922e-05, 3.08297233e-05, 3.00458049e-05, 2.65662487e-05, - 2.20921959e-05, 1.90337934e-05, 1.83921922e-05, 1.95602489e-05, - 2.97052920e-05, 3.13454184e-05, 2.99823369e-05, 2.61295083e-05, - 2.05339578e-05, 1.82861428e-05, 1.92454962e-05, 2.01747900e-05, - 2.97832097e-05, 3.19632289e-05, 2.90303312e-05, 2.44065287e-05, - 2.26744276e-05, 2.20503039e-05, 2.09976300e-05, 2.68099100e-05, - 2.85110553e-05, 2.90138727e-05, 2.84708836e-05, 2.48072485e-05, - 2.07653376e-05, 1.99503806e-05, 2.03633035e-05, 2.61998081e-05, - 2.80438285e-05, 2.79791342e-05, 2.65487769e-05, 2.54362016e-05, - 2.43820651e-05, 2.17276281e-05, 2.04827252e-05, 2.56240070e-05, - 2.83208332e-05, 2.82709614e-05, 2.71503380e-05, 2.64624165e-05, - 2.44377034e-05, 2.17750176e-05, 2.02565005e-05, 2.03189021e-05, - 2.33789851e-05, 2.77004484e-05, 3.16722311e-05, 3.17336992e-05, - 2.79768723e-05, 2.17568513e-05, 1.98388997e-05, 2.19617588e-05, - 2.76324073e-05, 2.92151775e-05, 2.76827410e-05, 2.45758189e-05, - 2.38813577e-05, 2.31842983e-05, 2.11033999e-05, 2.04824098e-05, - 2.33136194e-05, 2.73748908e-05, 3.00621847e-05, 2.80746224e-05, - 2.51430577e-05, 2.23638680e-05, 2.06346202e-05, 2.05415034e-05, - 2.54768441e-05, 2.82533142e-05, 2.86507482e-05, 2.65801624e-05, - 2.42322934e-05, 2.24893580e-05, 2.04348570e-05, 2.10912125e-05, - 2.21863377e-05, 2.50764719e-05, 2.94576601e-05, 3.14772662e-05, - 2.86522813e-05, 2.34855591e-05, 2.06532710e-05, 1.91243300e-05, - 1.89969325e-05, 1.99907626e-05, 2.61958406e-05, 2.78264200e-05, - 2.84678793e-05, 2.60387499e-05, 2.24678591e-05, 2.32355367e-05, - 2.20074559e-05, 1.97913589e-05, 2.66383705e-05, 2.80314932e-05, - 2.79905716e-05, 2.76484380e-05, 2.62793441e-05, 2.25480285e-05, - 2.08017996e-05, 2.15667650e-05, 2.73255804e-05, 2.98963746e-05, - 2.95224773e-05, 2.51953187e-05, 2.05597276e-05, 2.04514079e-05, - 2.11315795e-05, 2.48576817e-05, 2.75330569e-05, 2.93035077e-05, - 2.88638522e-05, 2.61508364e-05, 2.36811149e-05, 2.18254172e-05, - 1.99498554e-05, - 2.55253552e-05, 2.75011640e-05, 2.78080071e-05, 2.70173965e-05, - 2.53272064e-05, 2.32577733e-05, 2.19933872e-05, 2.19204319e-05, - 2.20427017e-05, 2.52148449e-05, 2.66419592e-05, 2.62616037e-05, - 2.53601908e-05, 2.52000263e-05, 2.48999605e-05, 2.33897131e-05, - 2.20451941e-05, 2.22522982e-05, 2.25058655e-05, 2.19081023e-05, - 2.60709154e-05, 2.72949231e-05, 2.72082576e-05, 2.57764861e-05, - 2.47957582e-05, 2.45735144e-05, 2.29590673e-05, 2.12926995e-05, - 2.07600556e-05, 2.71940164e-05, 2.83476936e-05, 2.80833805e-05, - 2.51156137e-05, 2.20976809e-05, 2.17553784e-05, 2.17521266e-05, - 2.14222080e-05, 2.13548560e-05, 2.48055944e-05, 2.72383086e-05, - 2.78110129e-05, 2.61226092e-05, 2.39983632e-05, 2.40569097e-05, - 2.42697633e-05, 2.30606122e-05, 2.15985534e-05, 2.23036723e-05, - 2.48259348e-05, 2.77982241e-05, 2.84089740e-05, 2.78464217e-05, - 2.53211628e-05, 2.18178243e-05, 2.05175316e-05, 2.09862907e-05, - 2.70396351e-05, 2.81510245e-05, 2.79112021e-05, 2.62478242e-05, - 2.32576460e-05, 2.08146534e-05, 2.02089606e-05, 2.10805167e-05, - 2.76333422e-05, 2.82762738e-05, 2.79059721e-05, 2.59742289e-05, - 2.20606514e-05, 2.01415517e-05, 2.08065310e-05, 2.15414322e-05, - 2.77838968e-05, 2.83220725e-05, 2.75536994e-05, 2.50082508e-05, - 2.35939022e-05, 2.28622408e-05, 2.20651608e-05, 2.63232906e-05, - 2.73221586e-05, 2.75155976e-05, 2.71344674e-05, 2.48823216e-05, - 2.20229244e-05, 2.13758923e-05, 2.16897887e-05, 2.59609371e-05, - 2.70629014e-05, 2.70142666e-05, 2.61896347e-05, 2.53702053e-05, - 2.45288210e-05, 2.26812208e-05, 2.17827954e-05, 2.56000790e-05, - 2.71405156e-05, 2.71048035e-05, 2.65614701e-05, 2.60956494e-05, - 2.46697944e-05, 2.27313552e-05, 2.15985651e-05, 2.16549966e-05, - 2.44374721e-05, 2.70732961e-05, 2.83090870e-05, 2.83553132e-05, - 2.66743147e-05, 2.26326720e-05, 2.12408825e-05, 2.27464577e-05, - 2.67827323e-05, 2.76443514e-05, 2.69027552e-05, 2.50072026e-05, - 2.44267435e-05, 2.37957374e-05, 2.22651988e-05, 2.17999252e-05, - 2.43673476e-05, 2.67781478e-05, 2.78845007e-05, 2.69541574e-05, - 2.52102965e-05, 2.31971549e-05, 2.18663996e-05, 2.18398611e-05, - 2.54769836e-05, 2.71225812e-05, 2.73190627e-05, 2.62601736e-05, - 2.47542829e-05, 2.34003351e-05, 2.17854294e-05, 2.22133075e-05, - 2.29499024e-05, 2.53491097e-05, 2.76953942e-05, 2.83036919e-05, - 2.72147012e-05, 2.41850177e-05, 2.20751929e-05, 2.07550270e-05, - 2.06164896e-05, 2.13963939e-05, 2.61355531e-05, 2.71202260e-05, - 2.73183897e-05, 2.58686955e-05, 2.33129230e-05, 2.35573703e-05, - 2.26851619e-05, 2.11634965e-05, 2.61272054e-05, 2.70858848e-05, - 2.70996738e-05, 2.68206410e-05, 2.59207943e-05, 2.34549183e-05, - 2.21067907e-05, 2.25602422e-05, 2.67922492e-05, 2.79225284e-05, - 2.76908811e-05, 2.51567057e-05, 2.18606941e-05, 2.17658406e-05, - 2.22402009e-05, 2.52249230e-05, 2.68645683e-05, 2.76427272e-05, - 2.73645822e-05, 2.57327447e-05, 2.40385686e-05, 2.27515256e-05, - 2.13897387e-05, - 2.52545998e-05, 2.53304180e-05, 2.51938612e-05, 2.56293395e-05, - 2.55779073e-05, 2.46031568e-05, 2.38289395e-05, 2.36947569e-05, - 2.36318160e-05, 2.51042619e-05, 2.53609158e-05, 2.53012815e-05, - 2.52369737e-05, 2.52136866e-05, 2.51005387e-05, 2.46384162e-05, - 2.39551699e-05, 2.39040583e-05, 2.39262975e-05, 2.35789215e-05, - 2.54718118e-05, 2.54599778e-05, 2.53484114e-05, 2.54286686e-05, - 2.52370180e-05, 2.49416286e-05, 2.41465813e-05, 2.32849506e-05, - 2.29675154e-05, 2.54552309e-05, 2.44232238e-05, 2.49821757e-05, - 2.55222413e-05, 2.43381878e-05, 2.37571212e-05, 2.34747708e-05, - 2.32901107e-05, 2.32677952e-05, 2.55302573e-05, 2.57803714e-05, - 2.53093974e-05, 2.56152723e-05, 2.49632077e-05, 2.46456080e-05, - 2.44943129e-05, 2.40080244e-05, 2.33109598e-05, 2.42675691e-05, - 2.54705237e-05, 2.52705576e-05, 2.42675558e-05, 2.51651412e-05, - 2.52873061e-05, 2.36928683e-05, 2.27522276e-05, 2.29925718e-05, - 2.53359508e-05, 2.49381887e-05, 2.52705875e-05, 2.57154012e-05, - 2.47261440e-05, 2.32484246e-05, 2.27207300e-05, 2.31273869e-05, - 2.50985439e-05, 2.46608230e-05, 2.53217714e-05, 2.56500153e-05, - 2.40770873e-05, 2.27136355e-05, 2.29219608e-05, 2.33548267e-05, - 2.52997540e-05, 2.41345150e-05, 2.56304485e-05, 2.56585978e-05, - 2.47219985e-05, 2.38802526e-05, 2.34504428e-05, 2.55934669e-05, - 2.57300381e-05, 2.55760920e-05, 2.54075437e-05, 2.48936079e-05, - 2.36675087e-05, 2.32777687e-05, 2.34418763e-05, 2.55404063e-05, - 2.57223299e-05, 2.56960308e-05, 2.56147577e-05, 2.51878335e-05, - 2.46433907e-05, 2.38918556e-05, 2.34948916e-05, 2.54541999e-05, - 2.55784005e-05, 2.55614029e-05, 2.56979644e-05, 2.55185727e-05, - 2.48814811e-05, 2.39436861e-05, 2.33756671e-05, 2.34217001e-05, - 2.57047803e-05, 2.61148582e-05, 2.43927550e-05, 2.44535689e-05, - 2.50213425e-05, 2.37427611e-05, 2.31148110e-05, 2.37333769e-05, - 2.56115328e-05, 2.56101532e-05, 2.57968551e-05, 2.54459532e-05, - 2.50375281e-05, 2.45186494e-05, 2.37701058e-05, 2.35354388e-05, - 2.56323918e-05, 2.58866633e-05, 2.52083898e-05, 2.54739364e-05, - 2.51952421e-05, 2.42298300e-05, 2.34815848e-05, 2.35474339e-05, - 2.53669473e-05, 2.56151477e-05, 2.55775784e-05, 2.57250337e-05, - 2.53191754e-05, 2.45258225e-05, 2.35672207e-05, 2.36665583e-05, - 2.39018020e-05, 2.55738157e-05, 2.54609212e-05, 2.45973013e-05, - 2.53735843e-05, 2.50021433e-05, 2.39444998e-05, 2.29726249e-05, - 2.28233232e-05, 2.32696462e-05, 2.59106658e-05, 2.60696284e-05, - 2.57681909e-05, 2.55342620e-05, 2.43561697e-05, 2.39269707e-05, - 2.35359460e-05, 2.29984740e-05, 2.53832369e-05, 2.57809024e-05, - 2.58521324e-05, 2.56700741e-05, 2.53646125e-05, 2.45727083e-05, - 2.38131384e-05, 2.38283091e-05, 2.59699530e-05, 2.54209941e-05, - 2.53880819e-05, 2.50182573e-05, 2.35710664e-05, 2.34983936e-05, - 2.36742867e-05, 2.55723506e-05, 2.58850970e-05, 2.55186870e-05, - 2.54432803e-05, 2.51195143e-05, 2.44328491e-05, 2.39232155e-05, - 2.33112609e-05, - 2.50173106e-05, 2.43398116e-05, 2.40344574e-05, 2.52351576e-05, - 2.60447829e-05, 2.52958657e-05, 2.45892757e-05, 2.43148724e-05, - 2.40144431e-05, 2.48520487e-05, 2.46300673e-05, 2.46651253e-05, - 2.50922990e-05, 2.51530983e-05, 2.50930374e-05, 2.52554876e-05, - 2.48689684e-05, 2.45009374e-05, 2.42860439e-05, 2.40239302e-05, - 2.52332141e-05, 2.47079073e-05, 2.44088076e-05, 2.53070444e-05, - 2.55463193e-05, 2.49480325e-05, 2.43908199e-05, 2.39484446e-05, - 2.37386406e-05, 2.47069390e-05, 2.28536612e-05, 2.36715784e-05, - 2.60597910e-05, 2.58582844e-05, 2.46688788e-05, 2.39245603e-05, - 2.38131869e-05, 2.38316815e-05, 2.63458760e-05, 2.56564836e-05, - 2.43956613e-05, 2.55945862e-05, 2.55297562e-05, 2.46307012e-05, - 2.40518060e-05, 2.39303879e-05, 2.36689584e-05, 2.54226919e-05, - 2.61611493e-05, 2.42626402e-05, 2.24075898e-05, 2.39723814e-05, - 2.52562538e-05, 2.44255846e-05, 2.34626824e-05, 2.35372655e-05, - 2.44149195e-05, 2.37176301e-05, 2.43827336e-05, 2.58010632e-05, - 2.56298993e-05, 2.44232460e-05, 2.37584252e-05, 2.37806526e-05, - 2.37068288e-05, 2.33007209e-05, 2.45620042e-05, 2.57829945e-05, - 2.51815320e-05, 2.38243210e-05, 2.35633811e-05, 2.38472883e-05, - 2.43436623e-05, 2.26468246e-05, 2.52603883e-05, 2.65321883e-05, - 2.52746638e-05, 2.38001173e-05, 2.35214206e-05, 2.54195526e-05, - 2.55072788e-05, 2.50711818e-05, 2.45859814e-05, 2.45644997e-05, - 2.41294503e-05, 2.38337342e-05, 2.39081527e-05, 2.54889610e-05, - 2.54954032e-05, 2.54281511e-05, 2.55535551e-05, 2.49544970e-05, - 2.42114740e-05, 2.40133940e-05, 2.39430240e-05, 2.54996596e-05, - 2.50644585e-05, 2.50224499e-05, 2.55917566e-05, 2.53452306e-05, - 2.47081559e-05, 2.40960094e-05, 2.38374045e-05, 2.38943647e-05, - 2.71840995e-05, 2.67251142e-05, 2.30221267e-05, 2.26193086e-05, - 2.37314757e-05, 2.36799192e-05, 2.35624683e-05, 2.35415906e-05, - 2.52570698e-05, 2.52544052e-05, 2.57501463e-05, 2.59384459e-05, - 2.53322795e-05, 2.45414940e-05, 2.41345462e-05, 2.40300853e-05, - 2.70423955e-05, 2.60523552e-05, 2.41391986e-05, 2.48164475e-05, - 2.50960190e-05, 2.43681672e-05, 2.38160626e-05, 2.40170767e-05, - 2.53531807e-05, 2.51730436e-05, 2.50467017e-05, 2.58212707e-05, - 2.58057585e-05, 2.49437851e-05, 2.41297744e-05, 2.39206518e-05, - 2.37680442e-05, 2.60163144e-05, 2.47949600e-05, 2.29783891e-05, - 2.44767815e-05, 2.54583455e-05, 2.48062041e-05, 2.37581767e-05, - 2.35306643e-05, 2.37890481e-05, 2.64240768e-05, 2.65782087e-05, - 2.56259953e-05, 2.55322850e-05, 2.45831994e-05, 2.32569363e-05, - 2.31053855e-05, 2.33488659e-05, 2.49607906e-05, 2.56658448e-05, - 2.58805640e-05, 2.54087922e-05, 2.50392996e-05, 2.50139132e-05, - 2.44205559e-05, 2.39740769e-05, 2.62984632e-05, 2.51561321e-05, - 2.45614815e-05, 2.46717466e-05, 2.40558554e-05, 2.39710573e-05, - 2.39119902e-05, 2.61104154e-05, 2.60223815e-05, 2.49475296e-05, - 2.46569863e-05, 2.45178978e-05, 2.40980022e-05, 2.40223848e-05, - 2.39057669e-05, - 2.52088356e-05, 2.80050102e-05, 2.84978513e-05, 2.83602311e-05, - 2.65439553e-05, 2.30395270e-05, 2.10597052e-05, 2.06641554e-05, - 2.03835475e-05, 2.45377510e-05, 2.64253252e-05, 2.57885946e-05, - 2.50949940e-05, 2.49728084e-05, 2.45006870e-05, 2.31087071e-05, - 2.14515290e-05, 2.11462933e-05, 2.10726672e-05, 2.02976435e-05, - 2.63971944e-05, 2.81034599e-05, 2.72991587e-05, 2.60389887e-05, - 2.50484896e-05, 2.39034366e-05, 2.15748079e-05, 1.97798219e-05, - 1.91885779e-05, 2.78209290e-05, 2.99088436e-05, 2.91125953e-05, - 2.62629482e-05, 2.27722740e-05, 2.09816835e-05, 2.00659387e-05, - 1.97055139e-05, 1.96823770e-05, 2.62874677e-05, 2.98548356e-05, - 2.93307510e-05, 2.70929828e-05, 2.41046089e-05, 2.29037303e-05, - 2.23245968e-05, 2.10676111e-05, 1.96527368e-05, 2.23710231e-05, - 2.60266779e-05, 2.89635257e-05, 2.90458683e-05, 2.85294478e-05, - 2.52937875e-05, 2.07258443e-05, 1.87222426e-05, 1.90967870e-05, - 2.68977670e-05, 2.98216605e-05, 2.98442185e-05, 2.76820625e-05, - 2.34966793e-05, 2.00289707e-05, 1.88755824e-05, 1.94415669e-05, - 2.71817455e-05, 3.01661766e-05, 3.02856872e-05, 2.71495478e-05, - 2.18621900e-05, 1.89108280e-05, 1.90144452e-05, 1.98270268e-05, - 2.90823755e-05, 3.08478350e-05, 3.01678947e-05, 2.68631675e-05, - 2.33321237e-05, 2.07416022e-05, 1.97993977e-05, 2.71640672e-05, - 2.98226320e-05, 2.95854685e-05, 2.74391933e-05, 2.37060603e-05, - 2.05105523e-05, 1.96988964e-05, 2.00025114e-05, 2.66346959e-05, - 2.89892381e-05, 2.87238234e-05, 2.71447279e-05, 2.48978157e-05, - 2.28115510e-05, 2.08667415e-05, 2.01098942e-05, 2.60774449e-05, - 2.83611336e-05, 2.81837270e-05, 2.79477623e-05, 2.66255830e-05, - 2.36678507e-05, 2.10109166e-05, 1.98542835e-05, 1.99617068e-05, - 2.71158741e-05, 3.16306035e-05, 3.08066568e-05, 2.86346379e-05, - 2.49931172e-05, 2.04118413e-05, 1.92892580e-05, 2.03276353e-05, - 2.78297120e-05, 3.05729108e-05, 2.90538344e-05, 2.59231459e-05, - 2.42925989e-05, 2.25248130e-05, 2.06972411e-05, 2.02278142e-05, - 2.68002915e-05, 2.93184458e-05, 2.90941049e-05, 2.74232171e-05, - 2.48996932e-05, 2.17484954e-05, 2.00150287e-05, 2.02404026e-05, - 2.56636896e-05, 2.85226032e-05, 2.88501118e-05, 2.77413819e-05, - 2.53883642e-05, 2.26953396e-05, 2.03390402e-05, 2.03935990e-05, - 2.07713144e-05, 2.65306272e-05, 2.97171159e-05, 2.91809804e-05, - 2.74423882e-05, 2.42045654e-05, 2.13951846e-05, 1.92081291e-05, - 1.88598784e-05, 1.96594592e-05, 2.85664973e-05, 3.14684215e-05, - 3.00662598e-05, 2.65530393e-05, 2.21333695e-05, 2.06242740e-05, - 1.97449107e-05, 1.89901701e-05, 2.60442936e-05, 2.93966085e-05, - 2.98791644e-05, 2.81978955e-05, 2.58349592e-05, 2.28413649e-05, - 2.09342359e-05, 2.07227362e-05, 2.98414602e-05, 3.23699299e-05, - 2.91648416e-05, 2.41952577e-05, 2.03026107e-05, 2.01319423e-05, - 2.04028600e-05, 2.64993942e-05, 2.94871612e-05, 2.98333962e-05, - 2.82094508e-05, 2.47328235e-05, 2.21596202e-05, 2.09338466e-05, - 1.97940743e-05, - 2.51736351e-05, 2.56692140e-05, 2.56199573e-05, 2.62967377e-05, - 2.61612686e-05, 2.44935879e-05, 2.33434917e-05, 2.30523700e-05, - 2.28015451e-05, 2.48532496e-05, 2.53666939e-05, 2.51821546e-05, - 2.51724829e-05, 2.51602968e-05, 2.49605969e-05, 2.45035910e-05, - 2.36338213e-05, 2.33454322e-05, 2.32222544e-05, 2.27664074e-05, - 2.56872722e-05, 2.59153645e-05, 2.55063769e-05, 2.56076650e-05, - 2.53837498e-05, 2.46689384e-05, 2.34838396e-05, 2.24951923e-05, - 2.21287837e-05, 2.58329221e-05, 2.52111832e-05, 2.55538194e-05, - 2.60717065e-05, 2.46227316e-05, 2.33406946e-05, 2.26195328e-05, - 2.24066244e-05, 2.24030080e-05, 2.62230442e-05, 2.69702788e-05, - 2.60653547e-05, 2.61074030e-05, 2.50228433e-05, 2.41343810e-05, - 2.36336664e-05, 2.30656167e-05, 2.23242023e-05, 2.42675774e-05, - 2.60389754e-05, 2.58855418e-05, 2.47090360e-05, 2.55901576e-05, - 2.53257869e-05, 2.31255906e-05, 2.17937385e-05, 2.20069704e-05, - 2.53903404e-05, 2.57612963e-05, 2.61912663e-05, 2.64071693e-05, - 2.48284857e-05, 2.27976568e-05, 2.19797937e-05, 2.22680003e-05, - 2.50570558e-05, 2.55708036e-05, 2.64171538e-05, 2.62267195e-05, - 2.39447950e-05, 2.20215448e-05, 2.19766823e-05, 2.24773291e-05, - 2.59672422e-05, 2.52810324e-05, 2.68186614e-05, 2.65180205e-05, - 2.46020434e-05, 2.28686473e-05, 2.23316780e-05, 2.60351938e-05, - 2.68729604e-05, 2.65466725e-05, 2.56505208e-05, 2.44074533e-05, - 2.29065437e-05, 2.24116383e-05, 2.25835507e-05, 2.59017518e-05, - 2.66302684e-05, 2.65143549e-05, 2.61018750e-05, 2.50328709e-05, - 2.38985911e-05, 2.30154971e-05, 2.26473001e-05, 2.57212763e-05, - 2.61982316e-05, 2.61221685e-05, 2.63747744e-05, 2.58219164e-05, - 2.44639262e-05, 2.31137635e-05, 2.24861077e-05, 2.25590505e-05, - 2.69278759e-05, 2.80907698e-05, 2.55304327e-05, 2.47518707e-05, - 2.44118679e-05, 2.26728927e-05, 2.21097337e-05, 2.25761696e-05, - 2.61511271e-05, 2.69224446e-05, 2.67958219e-05, 2.58915235e-05, - 2.50005881e-05, 2.39428329e-05, 2.29924550e-05, 2.27369505e-05, - 2.67461275e-05, 2.70458768e-05, 2.58436464e-05, 2.57782720e-05, - 2.51054892e-05, 2.35469238e-05, 2.25518775e-05, 2.27374257e-05, - 2.55039585e-05, 2.63081830e-05, 2.63279132e-05, 2.64368990e-05, - 2.56345904e-05, 2.41953670e-05, 2.28285475e-05, 2.27670414e-05, - 2.28673912e-05, 2.61421489e-05, 2.64140271e-05, 2.51216066e-05, - 2.55880599e-05, 2.50275065e-05, 2.35828454e-05, 2.21457859e-05, - 2.18878703e-05, 2.23752987e-05, 2.70238088e-05, 2.79598535e-05, - 2.70108637e-05, 2.58978218e-05, 2.38028587e-05, 2.25759353e-05, - 2.21306174e-05, 2.18821370e-05, 2.54254150e-05, 2.68463057e-05, - 2.71086580e-05, 2.63478480e-05, 2.53980364e-05, 2.42863316e-05, - 2.32175773e-05, 2.29356911e-05, 2.73389885e-05, 2.73110958e-05, - 2.61230891e-05, 2.46394055e-05, 2.27817419e-05, 2.26688485e-05, - 2.27675647e-05, 2.61793597e-05, 2.70781626e-05, 2.65384886e-05, - 2.59156980e-05, 2.47497667e-05, 2.35905726e-05, 2.30485077e-05, - 2.24851076e-05, - 2.52461356e-05, 2.45025343e-05, 2.41953850e-05, 2.45673878e-05, - 2.49008413e-05, 2.49430973e-05, 2.47323632e-05, 2.47830634e-05, - 2.49209643e-05, 2.53286786e-05, 2.50672000e-05, 2.52113947e-05, - 2.52366153e-05, 2.52259596e-05, 2.52511652e-05, 2.49891257e-05, - 2.46705331e-05, 2.48600228e-05, 2.50171802e-05, 2.48628856e-05, - 2.50572722e-05, 2.45575812e-05, 2.47782919e-05, 2.51019561e-05, - 2.50954630e-05, 2.52840428e-05, 2.51360193e-05, 2.46103723e-05, - 2.44053112e-05, 2.46562341e-05, 2.28280005e-05, 2.37453939e-05, - 2.49123673e-05, 2.43956265e-05, 2.46101272e-05, 2.48254698e-05, - 2.47097865e-05, 2.46730992e-05, 2.48193776e-05, 2.41430422e-05, - 2.39666380e-05, 2.49024978e-05, 2.50254415e-05, 2.53233702e-05, - 2.55388210e-05, 2.53055830e-05, 2.48315821e-05, 2.46037691e-05, - 2.48840376e-05, 2.40773292e-05, 2.30151756e-05, 2.41570071e-05, - 2.51824403e-05, 2.47077829e-05, 2.43541046e-05, 2.45778420e-05, - 2.49118978e-05, 2.34117864e-05, 2.37285292e-05, 2.47753713e-05, - 2.48385763e-05, 2.42396366e-05, 2.41011039e-05, 2.45557152e-05, - 2.46444268e-05, 2.29813760e-05, 2.36032408e-05, 2.48752844e-05, - 2.45838385e-05, 2.40446228e-05, 2.44788130e-05, 2.47545578e-05, - 2.40560703e-05, 2.21261696e-05, 2.39189769e-05, 2.47489038e-05, - 2.50305066e-05, 2.52828676e-05, 2.50736628e-05, 2.48977300e-05, - 2.41202717e-05, 2.40929188e-05, 2.47630597e-05, 2.54271854e-05, - 2.48793154e-05, 2.46823554e-05, 2.48030714e-05, 2.49912742e-05, - 2.44058947e-05, 2.44806160e-05, 2.48955258e-05, 2.52837541e-05, - 2.55191106e-05, 2.51593748e-05, 2.48333389e-05, 2.50631008e-05, - 2.45393660e-05, 2.45909568e-05, 2.47161558e-05, 2.50072675e-05, - 2.53697261e-05, 2.51516529e-05, 2.47830990e-05, 2.47917461e-05, - 2.45155950e-05, 2.37524651e-05, 2.24314914e-05, 2.33953355e-05, - 2.53971410e-05, 2.52415204e-05, 2.46958535e-05, 2.53213581e-05, - 2.47285280e-05, 2.37511222e-05, 2.44220225e-05, 2.49597575e-05, - 2.51447141e-05, 2.53036263e-05, 2.49732148e-05, 2.48154107e-05, - 2.45608938e-05, 2.43769685e-05, 2.39691594e-05, 2.48021185e-05, - 2.52451615e-05, 2.52126221e-05, 2.49057923e-05, 2.48361848e-05, - 2.51328164e-05, 2.45047219e-05, 2.43651077e-05, 2.47622960e-05, - 2.50057946e-05, 2.50890254e-05, 2.47802400e-05, 2.50160962e-05, - 2.53202937e-05, 2.49088157e-05, 2.39487287e-05, 2.33192346e-05, - 2.47420754e-05, 2.50758184e-05, 2.47009918e-05, 2.43971876e-05, - 2.43882193e-05, 2.47047204e-05, 2.45659585e-05, 2.37780349e-05, - 2.40600889e-05, 2.49982454e-05, 2.51781944e-05, 2.56436230e-05, - 2.54285554e-05, 2.47190185e-05, 2.51431949e-05, 2.43012601e-05, - 2.41794724e-05, 2.46373796e-05, 2.51689614e-05, 2.50804971e-05, - 2.48273944e-05, 2.51291057e-05, 2.42506056e-05, 2.29041836e-05, - 2.41000804e-05, 2.53919403e-05, 2.48337082e-05, 2.48179150e-05, - 2.50290558e-05, 2.48867160e-05, 2.43245004e-05, 2.39530927e-05, - 2.45073665e-05, 2.53928121e-05, 2.54879322e-05, 2.51803454e-05, - 2.46681555e-05, - 2.53119151e-05, 2.48039369e-05, 2.45482620e-05, 2.47204282e-05, - 2.48160422e-05, 2.47466362e-05, 2.44864394e-05, 2.45638017e-05, - 2.47546842e-05, 2.53878823e-05, 2.52781055e-05, 2.53883237e-05, - 2.52772990e-05, 2.52436958e-05, 2.52482141e-05, 2.48116829e-05, - 2.43954035e-05, 2.46544185e-05, 2.48678689e-05, 2.46798956e-05, - 2.51416658e-05, 2.47980014e-05, 2.50564756e-05, 2.51515936e-05, - 2.50237349e-05, 2.52681345e-05, 2.50234163e-05, 2.43658825e-05, - 2.41252211e-05, 2.48916605e-05, 2.33096723e-05, 2.41468301e-05, - 2.48063201e-05, 2.40073871e-05, 2.43274323e-05, 2.46374792e-05, - 2.44979511e-05, 2.44509748e-05, 2.46493009e-05, 2.42518964e-05, - 2.42660900e-05, 2.49436664e-05, 2.48766589e-05, 2.52968908e-05, - 2.56133867e-05, 2.52659251e-05, 2.46593766e-05, 2.42893130e-05, - 2.47383654e-05, 2.43963599e-05, 2.35672980e-05, 2.45192176e-05, - 2.51978913e-05, 2.44627342e-05, 2.40806697e-05, 2.43506564e-05, - 2.51795774e-05, 2.37983446e-05, 2.40283240e-05, 2.47999051e-05, - 2.46007990e-05, 2.38801863e-05, 2.37532884e-05, 2.43080157e-05, - 2.50430724e-05, 2.34095641e-05, 2.38763129e-05, 2.48799589e-05, - 2.42720353e-05, 2.36806191e-05, 2.42268350e-05, 2.45521923e-05, - 2.43631508e-05, 2.25971777e-05, 2.40927126e-05, 2.45753283e-05, - 2.48721015e-05, 2.52387098e-05, 2.49758973e-05, 2.49777698e-05, - 2.42527106e-05, 2.42916888e-05, 2.50121525e-05, 2.54932747e-05, - 2.46957183e-05, 2.44624250e-05, 2.46100018e-05, 2.50328316e-05, - 2.45268300e-05, 2.46076545e-05, 2.49474414e-05, 2.53437296e-05, - 2.55982688e-05, 2.50659198e-05, 2.46464803e-05, 2.50720722e-05, - 2.47225751e-05, 2.47779126e-05, 2.47915589e-05, 2.50788702e-05, - 2.53953601e-05, 2.50527910e-05, 2.45886873e-05, 2.45964411e-05, - 2.42124468e-05, 2.37171499e-05, 2.28705891e-05, 2.39353744e-05, - 2.57390465e-05, 2.51877182e-05, 2.44955729e-05, 2.52996187e-05, - 2.48636979e-05, 2.39272703e-05, 2.44999477e-05, 2.48586972e-05, - 2.50641588e-05, 2.52616088e-05, 2.48165699e-05, 2.46191598e-05, - 2.42672137e-05, 2.44080371e-05, 2.43060694e-05, 2.50083614e-05, - 2.52713985e-05, 2.51291802e-05, 2.47453411e-05, 2.46462329e-05, - 2.51498241e-05, 2.46721892e-05, 2.45597304e-05, 2.47852089e-05, - 2.48972953e-05, 2.49523391e-05, 2.45693831e-05, 2.48817885e-05, - 2.52904186e-05, 2.48295492e-05, 2.41899852e-05, 2.38055793e-05, - 2.50109577e-05, 2.49549477e-05, 2.44370087e-05, 2.41140034e-05, - 2.41178285e-05, 2.44930148e-05, 2.45033446e-05, 2.37632259e-05, - 2.41765775e-05, 2.50263593e-05, 2.50789571e-05, 2.57538663e-05, - 2.54610419e-05, 2.45378768e-05, 2.52687596e-05, 2.44010141e-05, - 2.42519981e-05, 2.47548546e-05, 2.52666325e-05, 2.49406183e-05, - 2.46157073e-05, 2.50272358e-05, 2.42515444e-05, 2.30844648e-05, - 2.43746804e-05, 2.54700002e-05, 2.46410974e-05, 2.46254292e-05, - 2.48989845e-05, 2.47844557e-05, 2.43649647e-05, 2.41720661e-05, - 2.47581488e-05, 2.55451894e-05, 2.55317833e-05, 2.50936050e-05, - 2.44404906e-05, - 2.49530585e-05, 2.28864893e-05, 2.23103176e-05, 2.32654691e-05, - 2.46391314e-05, 2.58102854e-05, 2.62180252e-05, 2.63203411e-05, - 2.64282268e-05, 2.52262627e-05, 2.40966370e-05, 2.44930378e-05, - 2.50334573e-05, 2.51091674e-05, 2.53051777e-05, 2.57972332e-05, - 2.61126653e-05, 2.62411351e-05, 2.63028788e-05, 2.64268269e-05, - 2.44154725e-05, 2.30837748e-05, 2.34052780e-05, 2.46365093e-05, - 2.51708223e-05, 2.55238819e-05, 2.62095862e-05, 2.64346389e-05, - 2.64562156e-05, 2.32662304e-05, 2.01953927e-05, 2.15636636e-05, - 2.47696051e-05, 2.57358949e-05, 2.61898764e-05, 2.64623887e-05, - 2.64913961e-05, 2.64808100e-05, 2.48231535e-05, 2.26101264e-05, - 2.20276968e-05, 2.41969338e-05, 2.55159972e-05, 2.58522719e-05, - 2.59996890e-05, 2.63646257e-05, 2.65509947e-05, 2.58911364e-05, - 2.48925660e-05, 2.21724145e-05, 2.03816360e-05, 2.22372485e-05, - 2.49889164e-05, 2.62800010e-05, 2.65189608e-05, 2.65550084e-05, - 2.36703854e-05, 2.10977175e-05, 2.16650485e-05, 2.39696988e-05, - 2.56794956e-05, 2.62166723e-05, 2.63595358e-05, 2.64775499e-05, - 2.29716515e-05, 2.04540804e-05, 2.15128415e-05, 2.42474974e-05, - 2.59948562e-05, 2.63228456e-05, 2.65247056e-05, 2.64847155e-05, - 2.21559496e-05, 1.92890823e-05, 2.21369912e-05, 2.46250892e-05, - 2.57394821e-05, 2.64422490e-05, 2.66060869e-05, 2.40764509e-05, - 2.25306627e-05, 2.23760907e-05, 2.34324364e-05, 2.55295457e-05, - 2.63866823e-05, 2.64813559e-05, 2.64672500e-05, 2.43972423e-05, - 2.30401335e-05, 2.31610705e-05, 2.41502485e-05, 2.50853442e-05, - 2.58347535e-05, 2.63861789e-05, 2.64560467e-05, 2.46877361e-05, - 2.31566749e-05, 2.32413918e-05, 2.37167009e-05, 2.43404003e-05, - 2.55761063e-05, 2.63500167e-05, 2.64903534e-05, 2.64714233e-05, - 2.46410802e-05, 2.22232055e-05, 1.97106587e-05, 2.09132350e-05, - 2.44722444e-05, 2.65132280e-05, 2.65693771e-05, 2.65509428e-05, - 2.36022501e-05, 2.18706608e-05, 2.31554623e-05, 2.48876230e-05, - 2.54323145e-05, 2.59687933e-05, 2.63756689e-05, 2.64245693e-05, - 2.47358746e-05, 2.31731392e-05, 2.19807690e-05, 2.35894992e-05, - 2.51269563e-05, 2.61773801e-05, 2.65024063e-05, 2.64294800e-05, - 2.48416894e-05, 2.31252407e-05, 2.28337571e-05, 2.39465913e-05, - 2.50826144e-05, 2.59158292e-05, 2.63881556e-05, 2.64564671e-05, - 2.64415995e-05, 2.46369242e-05, 2.20823957e-05, 2.08609245e-05, - 2.33574955e-05, 2.54779019e-05, 2.61351821e-05, 2.64485727e-05, - 2.65101235e-05, 2.64986385e-05, 2.37748779e-05, 2.22273819e-05, - 2.24585830e-05, 2.44577941e-05, 2.60730276e-05, 2.65107177e-05, - 2.67143533e-05, 2.66390666e-05, 2.44878271e-05, 2.28975508e-05, - 2.27389031e-05, 2.34684216e-05, 2.46366946e-05, 2.58760388e-05, - 2.62773275e-05, 2.64129150e-05, 2.30085296e-05, 2.06204577e-05, - 2.22717757e-05, 2.53353530e-05, 2.64153787e-05, 2.64456982e-05, - 2.64583432e-05, 2.46778886e-05, 2.30576790e-05, 2.21220840e-05, - 2.29790957e-05, 2.50142532e-05, 2.60631514e-05, 2.63747645e-05, - 2.64562104e-05, - 2.44692109e-05, 2.08701575e-05, 2.00113906e-05, 2.15587153e-05, - 2.41320380e-05, 2.68124098e-05, 2.81202722e-05, 2.83153144e-05, - 2.84031987e-05, 2.49922781e-05, 2.28109290e-05, 2.35078977e-05, - 2.46573958e-05, 2.48379352e-05, 2.52545239e-05, 2.67227184e-05, - 2.79337364e-05, 2.80034195e-05, 2.79480498e-05, 2.84810743e-05, - 2.34893830e-05, 2.12086557e-05, 2.16615115e-05, 2.39215150e-05, - 2.51186307e-05, 2.57214443e-05, 2.75549208e-05, 2.88658960e-05, - 2.92323125e-05, 2.14867258e-05, 1.71707271e-05, 1.89633840e-05, - 2.44100732e-05, 2.73462566e-05, 2.82189261e-05, 2.86275486e-05, - 2.88716416e-05, 2.88971380e-05, 2.46309697e-05, 2.06197569e-05, - 1.96522666e-05, 2.31727082e-05, 2.60020530e-05, 2.64488304e-05, - 2.65465906e-05, 2.77235004e-05, 2.88531846e-05, 2.74579595e-05, - 2.47175190e-05, 1.98404299e-05, 1.73752752e-05, 1.99035610e-05, - 2.46147277e-05, 2.83161622e-05, 2.94838842e-05, 2.92391387e-05, - 2.20783758e-05, 1.83569705e-05, 1.91565790e-05, 2.28136779e-05, - 2.66238787e-05, 2.88332150e-05, 2.94399009e-05, 2.90625139e-05, - 2.09253672e-05, 1.75148618e-05, 1.89675023e-05, 2.33064520e-05, - 2.77503015e-05, 2.94275325e-05, 2.93070566e-05, 2.87886490e-05, - 1.98251830e-05, 1.60767171e-05, 1.98905172e-05, 2.42613182e-05, - 2.65311782e-05, 2.79485450e-05, 2.86538869e-05, 2.29232900e-05, - 2.04843842e-05, 2.02103012e-05, 2.17277255e-05, 2.55752318e-05, - 2.83532279e-05, 2.88850079e-05, 2.86724222e-05, 2.35141962e-05, - 2.12466736e-05, 2.14239101e-05, 2.30805678e-05, 2.47238874e-05, - 2.61802435e-05, 2.79697724e-05, 2.85996295e-05, 2.40722494e-05, - 2.13664387e-05, 2.14912862e-05, 2.23425096e-05, 2.33773472e-05, - 2.57462539e-05, 2.78882371e-05, 2.87623082e-05, 2.86997155e-05, - 2.45537131e-05, 2.01857814e-05, 1.65934849e-05, 1.80500296e-05, - 2.32947551e-05, 2.81838790e-05, 2.91012645e-05, 2.81735968e-05, - 2.20977508e-05, 1.95175753e-05, 2.14622610e-05, 2.46241758e-05, - 2.56666297e-05, 2.67521738e-05, 2.81946060e-05, 2.85423811e-05, - 2.47198099e-05, 2.15364223e-05, 1.95643999e-05, 2.20086762e-05, - 2.48575356e-05, 2.73759937e-05, 2.86185695e-05, 2.85257835e-05, - 2.43395794e-05, 2.13329436e-05, 2.08758846e-05, 2.27774681e-05, - 2.50160876e-05, 2.68876772e-05, 2.84967462e-05, 2.83444307e-05, - 2.78978673e-05, 2.41188650e-05, 1.97663752e-05, 1.80055608e-05, - 2.15967116e-05, 2.58528640e-05, 2.79496267e-05, 2.92238662e-05, - 2.94064763e-05, 2.88984008e-05, 2.26020021e-05, 2.01730880e-05, - 2.03932522e-05, 2.36375162e-05, 2.71616475e-05, 2.76580918e-05, - 2.84484107e-05, 2.92549526e-05, 2.35614076e-05, 2.10522232e-05, - 2.08411139e-05, 2.19059846e-05, 2.38557836e-05, 2.68011072e-05, - 2.81417196e-05, 2.80784112e-05, 2.13153223e-05, 1.78489970e-05, - 2.00086364e-05, 2.51710514e-05, 2.84923160e-05, 2.85943752e-05, - 2.83314136e-05, 2.42327441e-05, 2.13501565e-05, 1.98371469e-05, - 2.10449643e-05, 2.44552593e-05, 2.67579729e-05, 2.79129496e-05, - 2.88386589e-05, - 2.54280950e-05, 2.77647768e-05, 2.81538671e-05, 2.75532750e-05, - 2.57643045e-05, 2.31464225e-05, 2.16037572e-05, 2.14117266e-05, - 2.13867909e-05, 2.49797735e-05, 2.66141132e-05, 2.61291511e-05, - 2.52770234e-05, 2.51264092e-05, 2.47574436e-05, 2.32583369e-05, - 2.17794733e-05, 2.18036657e-05, 2.19409069e-05, 2.12683004e-05, - 2.62179054e-05, 2.76563081e-05, 2.73119044e-05, 2.58923154e-05, - 2.48829863e-05, 2.43260119e-05, 2.24196518e-05, 2.06804684e-05, - 2.01191733e-05, 2.74870840e-05, 2.90507560e-05, 2.85678321e-05, - 2.55232129e-05, 2.22814944e-05, 2.14204082e-05, 2.10818692e-05, - 2.07359198e-05, 2.06841337e-05, 2.53206197e-05, 2.82199068e-05, - 2.84479037e-05, 2.64971640e-05, 2.40164507e-05, 2.36227607e-05, - 2.35467748e-05, 2.22964580e-05, 2.08289330e-05, 2.22778150e-05, - 2.52447836e-05, 2.83107116e-05, 2.87907964e-05, 2.81921907e-05, - 2.53219021e-05, 2.13678806e-05, 1.97901178e-05, 2.02294512e-05, - 2.70532163e-05, 2.88664961e-05, 2.86979761e-05, 2.67871210e-05, - 2.33084323e-05, 2.04628906e-05, 1.96497275e-05, 2.04186206e-05, - 2.75616243e-05, 2.90834018e-05, 2.88459663e-05, 2.64153925e-05, - 2.19367493e-05, 1.96193893e-05, 2.00839117e-05, 2.08576562e-05, - 2.83420535e-05, 2.93718369e-05, 2.85509194e-05, 2.56556808e-05, - 2.34731884e-05, 2.20466245e-05, 2.11816756e-05, 2.66590527e-05, - 2.82685628e-05, 2.83252062e-05, 2.73111037e-05, 2.44575589e-05, - 2.14212211e-05, 2.07037737e-05, 2.10182296e-05, 2.62269272e-05, - 2.78017272e-05, 2.76766341e-05, 2.65609804e-05, 2.52129091e-05, - 2.38964114e-05, 2.19774605e-05, 2.11179313e-05, 2.57867979e-05, - 2.76391373e-05, 2.75525573e-05, 2.70949468e-05, 2.63152071e-05, - 2.43039218e-05, 2.20635103e-05, 2.09044429e-05, 2.09806999e-05, - 2.53475798e-05, 2.86899017e-05, 2.93388486e-05, 2.85991364e-05, - 2.61131781e-05, 2.17753326e-05, 2.04640907e-05, 2.18159120e-05, - 2.72065539e-05, 2.87532509e-05, 2.77115883e-05, 2.53318609e-05, - 2.43684196e-05, 2.33132398e-05, 2.16465679e-05, 2.11727894e-05, - 2.51938671e-05, 2.77138564e-05, 2.84179478e-05, 2.71817532e-05, - 2.51070797e-05, 2.26381074e-05, 2.11361024e-05, 2.12031478e-05, - 2.55577887e-05, 2.76827028e-05, 2.79333619e-05, 2.68160625e-05, - 2.49745704e-05, 2.31167141e-05, 2.12046702e-05, 2.15001041e-05, - 2.21139361e-05, 2.57746167e-05, 2.84986485e-05, 2.87557833e-05, - 2.73673313e-05, 2.41762165e-05, 2.17787646e-05, 2.01232173e-05, - 1.99047731e-05, 2.07021942e-05, 2.70109118e-05, 2.86711064e-05, - 2.83482749e-05, 2.61356718e-05, 2.28549539e-05, 2.24446002e-05, - 2.15534601e-05, 2.03019388e-05, 2.61305524e-05, 2.79568252e-05, - 2.81297418e-05, 2.73605995e-05, 2.59169858e-05, 2.32053235e-05, - 2.16315796e-05, 2.18458903e-05, 2.78993785e-05, 2.95596721e-05, - 2.83046348e-05, 2.48169622e-05, 2.12396482e-05, 2.11152496e-05, - 2.15208198e-05, 2.56792444e-05, 2.78315616e-05, 2.85008017e-05, - 2.77419059e-05, 2.53938353e-05, 2.33355746e-05, 2.20477386e-05, - 2.07480844e-05, - 2.52110452e-05, 2.72482460e-05, 2.75555573e-05, 2.77287841e-05, - 2.64840679e-05, 2.35291391e-05, 2.17830767e-05, 2.14082020e-05, - 2.11228668e-05, 2.46435766e-05, 2.60863659e-05, 2.55943052e-05, - 2.51363334e-05, 2.50518220e-05, 2.46633635e-05, 2.35773186e-05, - 2.21556719e-05, 2.18377381e-05, 2.17376815e-05, 2.10539903e-05, - 2.61954065e-05, 2.74093136e-05, 2.67179613e-05, 2.59288841e-05, - 2.51928989e-05, 2.41564518e-05, 2.21671052e-05, 2.06135942e-05, - 2.00869041e-05, 2.71903891e-05, 2.83345147e-05, 2.79375871e-05, - 2.62646753e-05, 2.34190823e-05, 2.17336427e-05, 2.08453045e-05, - 2.05280456e-05, 2.05122395e-05, 2.63436887e-05, 2.89805231e-05, - 2.82794978e-05, 2.68203099e-05, 2.44340050e-05, 2.32900574e-05, - 2.27096573e-05, 2.16671444e-05, 2.04586486e-05, 2.30101178e-05, - 2.60981686e-05, 2.79666912e-05, 2.75714601e-05, 2.75649990e-05, - 2.53282521e-05, 2.14790834e-05, 1.96512059e-05, 1.99753575e-05, - 2.64073837e-05, 2.84872325e-05, 2.86681695e-05, 2.73271065e-05, - 2.39636203e-05, 2.09041292e-05, 1.98301552e-05, 2.03040071e-05, - 2.64662368e-05, 2.86424030e-05, 2.90479674e-05, 2.69055774e-05, - 2.25495983e-05, 1.98709185e-05, 1.99116295e-05, 2.06344557e-05, - 2.80770372e-05, 2.89829424e-05, 2.91271214e-05, 2.68392490e-05, - 2.37615911e-05, 2.13766945e-05, 2.05529118e-05, 2.68378768e-05, - 2.89207490e-05, 2.86357032e-05, 2.68668168e-05, 2.39212047e-05, - 2.12481827e-05, 2.05262528e-05, 2.07900937e-05, 2.64373095e-05, - 2.82753577e-05, 2.80545429e-05, 2.68519811e-05, 2.49511145e-05, - 2.31332121e-05, 2.15186563e-05, 2.08848374e-05, 2.60000826e-05, - 2.76904964e-05, 2.75434955e-05, 2.74883994e-05, 2.63991686e-05, - 2.39195369e-05, 2.16518588e-05, 2.06551637e-05, 2.07539815e-05, - 2.71756705e-05, 3.05967380e-05, 2.90510369e-05, 2.73146698e-05, - 2.47674119e-05, 2.10846656e-05, 2.01392604e-05, 2.09901572e-05, - 2.73216373e-05, 2.94352969e-05, 2.83837387e-05, 2.59697485e-05, - 2.45453992e-05, 2.29667730e-05, 2.14022972e-05, 2.09976657e-05, - 2.68954538e-05, 2.86577388e-05, 2.80369587e-05, 2.69064037e-05, - 2.49818829e-05, 2.23041638e-05, 2.07837612e-05, 2.10056646e-05, - 2.56418325e-05, 2.78403551e-05, 2.80642274e-05, 2.73779673e-05, - 2.55169388e-05, 2.31825515e-05, 2.11072628e-05, 2.11139777e-05, - 2.13949821e-05, 2.64675218e-05, 2.86707734e-05, 2.78177355e-05, - 2.68445147e-05, 2.45000623e-05, 2.20979392e-05, 2.01065581e-05, - 1.97775083e-05, 2.04856925e-05, 2.81560047e-05, 3.04374884e-05, - 2.91359445e-05, 2.63823167e-05, 2.26577580e-05, 2.11791191e-05, - 2.04322864e-05, 1.98537698e-05, 2.58591046e-05, 2.86294515e-05, - 2.90515665e-05, 2.76421311e-05, 2.57109146e-05, 2.33142956e-05, - 2.16491879e-05, 2.13935703e-05, 2.91190269e-05, 3.07740781e-05, - 2.81921478e-05, 2.43337076e-05, 2.10638766e-05, 2.09080620e-05, - 2.11199917e-05, 2.64626189e-05, 2.87815442e-05, 2.87962779e-05, - 2.74794885e-05, 2.47292660e-05, 2.25854925e-05, 2.15751738e-05, - 2.06177374e-05, - 2.42588083e-05, 2.05508949e-05, 1.96639370e-05, 2.19860068e-05, - 2.52295765e-05, 2.73946697e-05, 2.82882531e-05, 2.81249095e-05, - 2.77129222e-05, 2.45687457e-05, 2.23265586e-05, 2.29510392e-05, - 2.45405339e-05, 2.48030062e-05, 2.51630394e-05, 2.72007579e-05, - 2.84764948e-05, 2.79109553e-05, 2.74287674e-05, 2.78735979e-05, - 2.36030455e-05, 2.11688429e-05, 2.11946630e-05, 2.40923715e-05, - 2.56289641e-05, 2.54808475e-05, 2.69951113e-05, 2.84948511e-05, - 2.88873386e-05, 2.13748782e-05, 1.68881506e-05, 1.86529955e-05, - 2.55430459e-05, 2.92677908e-05, 2.86341439e-05, 2.79575232e-05, - 2.82224160e-05, 2.83150093e-05, 2.61720770e-05, 2.17011317e-05, - 1.97681921e-05, 2.37445570e-05, 2.66570430e-05, 2.58825549e-05, - 2.51586349e-05, 2.64792100e-05, 2.78901497e-05, 2.86510610e-05, - 2.60179783e-05, 1.97676263e-05, 1.66315779e-05, 1.95334852e-05, - 2.47083492e-05, 2.83425018e-05, 2.88842986e-05, 2.84414835e-05, - 2.15148152e-05, 1.83206008e-05, 1.94280674e-05, 2.36633145e-05, - 2.76636159e-05, 2.94831494e-05, 2.95187871e-05, 2.85719266e-05, - 1.99600988e-05, 1.74590038e-05, 1.94701020e-05, 2.40920548e-05, - 2.87321252e-05, 2.96592550e-05, 2.86651216e-05, 2.81214258e-05, - 1.98346762e-05, 1.61203904e-05, 2.07662893e-05, 2.60085328e-05, - 2.69650593e-05, 2.65916815e-05, 2.72341549e-05, 2.33177923e-05, - 2.14466669e-05, 2.08089008e-05, 2.14297148e-05, 2.47948176e-05, - 2.78400143e-05, 2.82934844e-05, 2.80122252e-05, 2.39316883e-05, - 2.20173991e-05, 2.20852546e-05, 2.36131469e-05, 2.44303903e-05, - 2.49690655e-05, 2.69867701e-05, 2.79401768e-05, 2.44764696e-05, - 2.16572451e-05, 2.17087716e-05, 2.30136461e-05, 2.36347181e-05, - 2.51760261e-05, 2.70022653e-05, 2.80483199e-05, 2.80383830e-05, - 2.72515756e-05, 2.24638016e-05, 1.67045840e-05, 1.71857951e-05, - 2.17132713e-05, 2.67444340e-05, 2.81849498e-05, 2.64920546e-05, - 2.24393706e-05, 2.04964275e-05, 2.24597755e-05, 2.56136460e-05, - 2.59584696e-05, 2.61287935e-05, 2.75692542e-05, 2.80012763e-05, - 2.72552629e-05, 2.28474774e-05, 1.94679932e-05, 2.18904819e-05, - 2.47487132e-05, 2.66971324e-05, 2.77288924e-05, 2.79442741e-05, - 2.45557868e-05, 2.17453524e-05, 2.12696235e-05, 2.36544449e-05, - 2.58691656e-05, 2.69347648e-05, 2.81093584e-05, 2.74348790e-05, - 2.64635660e-05, 2.51792220e-05, 2.02271888e-05, 1.74678850e-05, - 2.12173096e-05, 2.63644279e-05, 2.83861775e-05, 2.89119151e-05, - 2.88425442e-05, 2.82283762e-05, 2.42000239e-05, 2.23020121e-05, - 2.14987258e-05, 2.40992765e-05, 2.67415045e-05, 2.53244138e-05, - 2.61643153e-05, 2.80639640e-05, 2.33447397e-05, 2.20445942e-05, - 2.21040819e-05, 2.24494147e-05, 2.37048249e-05, 2.69257454e-05, - 2.80068559e-05, 2.70897879e-05, 2.29315412e-05, 1.92783522e-05, - 2.01686489e-05, 2.45158327e-05, 2.79564107e-05, 2.79851663e-05, - 2.73966559e-05, 2.54203610e-05, 2.26617124e-05, 2.04236926e-05, - 2.09966164e-05, 2.36232777e-05, 2.54747010e-05, 2.69143125e-05, - 2.83459937e-05, - 2.45335083e-05, 2.16460350e-05, 2.09044676e-05, 2.29336751e-05, - 2.55025580e-05, 2.68102244e-05, 2.72052155e-05, 2.70102526e-05, - 2.66398405e-05, 2.47098074e-05, 2.30341415e-05, 2.34984754e-05, - 2.47548652e-05, 2.49582066e-05, 2.51969872e-05, 2.66649273e-05, - 2.74183589e-05, 2.69235026e-05, 2.65313945e-05, 2.67508255e-05, - 2.41185501e-05, 2.21971360e-05, 2.21437350e-05, 2.44911163e-05, - 2.56510854e-05, 2.53806302e-05, 2.62679422e-05, 2.71424555e-05, - 2.73352450e-05, 2.23505241e-05, 1.84968557e-05, 2.00489097e-05, - 2.57301744e-05, 2.82556183e-05, 2.74624224e-05, 2.67760610e-05, - 2.69179753e-05, 2.69855552e-05, 2.62544143e-05, 2.28229333e-05, - 2.10672939e-05, 2.43147003e-05, 2.63674775e-05, 2.55714870e-05, - 2.49016212e-05, 2.57775313e-05, 2.66505272e-05, 2.77056735e-05, - 2.60948594e-05, 2.10361551e-05, 1.81997551e-05, 2.07909537e-05, - 2.49187517e-05, 2.71908761e-05, 2.72432657e-05, 2.69752530e-05, - 2.23827054e-05, 1.98026249e-05, 2.08045873e-05, 2.43085874e-05, - 2.70931882e-05, 2.79503488e-05, 2.77570886e-05, 2.71400377e-05, - 2.10511479e-05, 1.90407150e-05, 2.08773960e-05, 2.46153605e-05, - 2.76868724e-05, 2.78708630e-05, 2.71316196e-05, 2.68613827e-05, - 2.11058715e-05, 1.78455271e-05, 2.20253799e-05, 2.61888703e-05, - 2.65078541e-05, 2.58150627e-05, 2.61644443e-05, 2.39593175e-05, - 2.25965149e-05, 2.20133670e-05, 2.23617500e-05, 2.47908407e-05, - 2.67610583e-05, 2.69718680e-05, 2.68075459e-05, 2.44228954e-05, - 2.30204206e-05, 2.30545154e-05, 2.42086690e-05, 2.46391298e-05, - 2.48145281e-05, 2.61484471e-05, 2.67702221e-05, 2.48180700e-05, - 2.26476762e-05, 2.26757826e-05, 2.37804867e-05, 2.41705636e-05, - 2.50993340e-05, 2.61840286e-05, 2.68094141e-05, 2.68207155e-05, - 2.72467675e-05, 2.36486834e-05, 1.83876177e-05, 1.86793530e-05, - 2.23567157e-05, 2.58824245e-05, 2.68131486e-05, 2.56689098e-05, - 2.32744315e-05, 2.18192061e-05, 2.34111517e-05, 2.57475057e-05, - 2.58234863e-05, 2.57166405e-05, 2.65800850e-05, 2.68384433e-05, - 2.72103693e-05, 2.37724375e-05, 2.07795300e-05, 2.27598942e-05, - 2.49040974e-05, 2.60573045e-05, 2.65887760e-05, 2.67961368e-05, - 2.48358548e-05, 2.27396486e-05, 2.23539637e-05, 2.43072789e-05, - 2.58921795e-05, 2.63904424e-05, 2.69421076e-05, 2.64234534e-05, - 2.57180647e-05, 2.54589554e-05, 2.15085377e-05, 1.89776814e-05, - 2.21771753e-05, 2.61431177e-05, 2.73381332e-05, 2.73578118e-05, - 2.72380148e-05, 2.69142838e-05, 2.48585516e-05, 2.34924891e-05, - 2.26637617e-05, 2.45552631e-05, 2.61514297e-05, 2.47851679e-05, - 2.53133311e-05, 2.66643106e-05, 2.38606676e-05, 2.30819407e-05, - 2.31780480e-05, 2.33194885e-05, 2.41414517e-05, 2.64047641e-05, - 2.69635044e-05, 2.62064206e-05, 2.38949891e-05, 2.08616162e-05, - 2.14099233e-05, 2.46230119e-05, 2.68163922e-05, 2.68091617e-05, - 2.63949888e-05, 2.56563725e-05, 2.36274644e-05, 2.16930385e-05, - 2.20561061e-05, 2.39448072e-05, 2.51348096e-05, 2.61019093e-05, - 2.70297386e-05, - 2.54282214e-05, 2.54198733e-05, 2.52746841e-05, 2.50754434e-05, - 2.47073035e-05, 2.43641728e-05, 2.39749329e-05, 2.40854022e-05, - 2.43547246e-05, 2.54746914e-05, 2.56840262e-05, 2.57156759e-05, - 2.53470905e-05, 2.52706817e-05, 2.52272652e-05, 2.44622177e-05, - 2.38465327e-05, 2.42100643e-05, 2.45131235e-05, 2.42507406e-05, - 2.53222892e-05, 2.53045990e-05, 2.56092462e-05, 2.52619473e-05, - 2.48998227e-05, 2.52093411e-05, 2.47418036e-05, 2.38252209e-05, - 2.35137578e-05, 2.53812193e-05, 2.43293757e-05, 2.49840774e-05, - 2.46544310e-05, 2.33087752e-05, 2.37551455e-05, 2.41943960e-05, - 2.40075369e-05, 2.39435452e-05, 2.43896469e-05, 2.45660929e-05, - 2.49165965e-05, 2.50667483e-05, 2.45994469e-05, 2.51936944e-05, - 2.56655566e-05, 2.50914855e-05, 2.42311859e-05, 2.36992404e-05, - 2.45135772e-05, 2.50729634e-05, 2.46983763e-05, 2.52641568e-05, - 2.52294013e-05, 2.39444472e-05, 2.34683670e-05, 2.38205874e-05, - 2.57015783e-05, 2.46287288e-05, 2.46941150e-05, 2.49089241e-05, - 2.41617416e-05, 2.31640830e-05, 2.30284846e-05, 2.37539247e-05, - 2.58152876e-05, 2.43316919e-05, 2.45042468e-05, 2.49407570e-05, - 2.36742325e-05, 2.29315321e-05, 2.36554676e-05, 2.40799896e-05, - 2.50208113e-05, 2.36274168e-05, 2.45330824e-05, 2.43234489e-05, - 2.45596467e-05, 2.50480263e-05, 2.46720304e-05, 2.51710198e-05, - 2.46087831e-05, 2.47625894e-05, 2.55158318e-05, 2.55692631e-05, - 2.42709755e-05, 2.39589099e-05, 2.41571450e-05, 2.51447072e-05, - 2.48405831e-05, 2.49254697e-05, 2.50907048e-05, 2.54416000e-05, - 2.56718962e-05, 2.47972896e-05, 2.42063324e-05, 2.51128354e-05, - 2.51321290e-05, 2.51894386e-05, 2.49970391e-05, 2.52430993e-05, - 2.54010219e-05, 2.47790654e-05, 2.41299310e-05, 2.41389619e-05, - 2.37496678e-05, 2.38156913e-05, 2.38349997e-05, 2.50275165e-05, - 2.63391555e-05, 2.49722292e-05, 2.40131606e-05, 2.51347914e-05, - 2.51724834e-05, 2.43826360e-05, 2.47382574e-05, 2.47069084e-05, - 2.49060569e-05, 2.51222282e-05, 2.44402630e-05, 2.41668687e-05, - 2.38130560e-05, 2.45695689e-05, 2.50200970e-05, 2.54338595e-05, - 2.53110772e-05, 2.49002690e-05, 2.43453770e-05, 2.42044031e-05, - 2.51937172e-05, 2.50575903e-05, 2.50032588e-05, 2.48928904e-05, - 2.47196341e-05, 2.46597692e-05, 2.40963929e-05, 2.45339846e-05, - 2.51241943e-05, 2.47299440e-05, 2.47428444e-05, 2.48100707e-05, - 2.55508436e-05, 2.47268632e-05, 2.39046648e-05, 2.34981415e-05, - 2.35136552e-05, 2.40016545e-05, 2.44821092e-05, 2.38945568e-05, - 2.45099549e-05, 2.51126718e-05, 2.48339350e-05, 2.58181947e-05, - 2.53699661e-05, 2.40784559e-05, 2.55123087e-05, 2.46871533e-05, - 2.45014028e-05, 2.50417360e-05, 2.54554567e-05, 2.46464729e-05, - 2.41562353e-05, 2.47410053e-05, 2.43724434e-05, 2.35935814e-05, - 2.49741067e-05, 2.55800374e-05, 2.41965541e-05, 2.41767799e-05, - 2.45583172e-05, 2.46448145e-05, 2.45473580e-05, 2.46868383e-05, - 2.52866984e-05, 2.57995382e-05, 2.55271844e-05, 2.48377877e-05, - 2.39269971e-05, - 2.55128220e-05, 2.64099564e-05, 2.64666659e-05, 2.59477792e-05, - 2.49495724e-05, 2.38422215e-05, 2.30570778e-05, 2.30967768e-05, - 2.33205726e-05, 2.54074757e-05, 2.61819905e-05, 2.60304739e-05, - 2.53868830e-05, 2.52666174e-05, 2.51077265e-05, 2.39617039e-05, - 2.29967635e-05, 2.33171353e-05, 2.36190517e-05, 2.31969965e-05, - 2.56835264e-05, 2.62325958e-05, 2.63957236e-05, 2.55131637e-05, - 2.48474968e-05, 2.49547838e-05, 2.39591557e-05, 2.26651905e-05, - 2.22424229e-05, 2.62359657e-05, 2.61568629e-05, 2.64200052e-05, - 2.48233336e-05, 2.26734116e-05, 2.28161734e-05, 2.30947806e-05, - 2.28358010e-05, 2.27666003e-05, 2.45156357e-05, 2.57093424e-05, - 2.62277759e-05, 2.55363900e-05, 2.43095703e-05, 2.47219118e-05, - 2.51209057e-05, 2.42276253e-05, 2.30527755e-05, 2.30108598e-05, - 2.46060798e-05, 2.63261276e-05, 2.64398681e-05, 2.64795505e-05, - 2.52921626e-05, 2.29633785e-05, 2.21109721e-05, 2.25321590e-05, - 2.63779440e-05, 2.62225538e-05, 2.61314296e-05, 2.54867767e-05, - 2.37108864e-05, 2.20443573e-05, 2.17036512e-05, 2.25300444e-05, - 2.67411764e-05, 2.61066434e-05, 2.60015429e-05, 2.53868519e-05, - 2.28928085e-05, 2.16142459e-05, 2.23515493e-05, 2.29324644e-05, - 2.62837089e-05, 2.57060999e-05, 2.58397906e-05, 2.45584122e-05, - 2.41116477e-05, 2.41145032e-05, 2.35323822e-05, 2.56953747e-05, - 2.57780142e-05, 2.59752683e-05, 2.62980970e-05, 2.53245102e-05, - 2.32587196e-05, 2.27852788e-05, 2.30445740e-05, 2.55166805e-05, - 2.58113289e-05, 2.58456666e-05, 2.55821434e-05, 2.54536261e-05, - 2.52376886e-05, 2.38760871e-05, 2.31154208e-05, 2.53368717e-05, - 2.60434881e-05, 2.60651603e-05, 2.56862645e-05, 2.56418409e-05, - 2.51219170e-05, 2.38858362e-05, 2.29884804e-05, 2.30182184e-05, - 2.39373674e-05, 2.51268342e-05, 2.58160716e-05, 2.66148160e-05, - 2.66337757e-05, 2.39673520e-05, 2.27622301e-05, 2.41203273e-05, - 2.59044117e-05, 2.57840082e-05, 2.56683852e-05, 2.48113583e-05, - 2.46930593e-05, 2.45631814e-05, 2.34699322e-05, 2.30975779e-05, - 2.39497078e-05, 2.54980704e-05, 2.63357219e-05, 2.61586579e-05, - 2.52977141e-05, 2.41630140e-05, 2.32395186e-05, 2.31384571e-05, - 2.53365916e-05, 2.59850066e-05, 2.60417168e-05, 2.54815680e-05, - 2.47111456e-05, 2.40942718e-05, 2.30465330e-05, 2.35077015e-05, - 2.42010593e-05, 2.49740392e-05, 2.60517584e-05, 2.64375365e-05, - 2.63596096e-05, 2.44723761e-05, 2.30466462e-05, 2.22304366e-05, - 2.21814839e-05, 2.28210986e-05, 2.51519864e-05, 2.52018507e-05, - 2.57097460e-05, 2.54546851e-05, 2.41696807e-05, 2.49100168e-05, - 2.42442610e-05, 2.27705273e-05, 2.58349660e-05, 2.57189853e-05, - 2.56005715e-05, 2.58342062e-05, 2.57053255e-05, 2.41088920e-05, - 2.32210128e-05, 2.37882787e-05, 2.53721189e-05, 2.54041210e-05, - 2.62048281e-05, 2.54513756e-05, 2.31423111e-05, 2.30894014e-05, - 2.35347181e-05, 2.48640511e-05, 2.55226576e-05, 2.59875344e-05, - 2.62540412e-05, 2.58497990e-05, 2.49307168e-05, 2.39321450e-05, - 2.27709134e-05, - 2.55330404e-05, 2.77962631e-05, 2.81724900e-05, 2.72614950e-05, - 2.53637912e-05, 2.30843846e-05, 2.17227439e-05, 2.16362467e-05, - 2.17529763e-05, 2.51811920e-05, 2.67798031e-05, 2.63437731e-05, - 2.53533355e-05, 2.51791896e-05, 2.48465501e-05, 2.32232982e-05, - 2.17874548e-05, 2.19907864e-05, 2.22490322e-05, 2.16126271e-05, - 2.61571929e-05, 2.75647004e-05, 2.74382832e-05, 2.58284487e-05, - 2.47535252e-05, 2.44838425e-05, 2.27311589e-05, 2.09690198e-05, - 2.04100503e-05, 2.74406898e-05, 2.89425859e-05, 2.85333072e-05, - 2.51298751e-05, 2.18799226e-05, 2.14768436e-05, 2.14461948e-05, - 2.10987242e-05, 2.10294088e-05, 2.48020476e-05, 2.75636399e-05, - 2.82093768e-05, 2.62357506e-05, 2.38871707e-05, 2.39115477e-05, - 2.41159970e-05, 2.28204789e-05, 2.12769405e-05, 2.20798654e-05, - 2.48155671e-05, 2.81793610e-05, 2.89796698e-05, 2.82194166e-05, - 2.53180782e-05, 2.15331136e-05, 2.01503712e-05, 2.06369561e-05, - 2.72355114e-05, 2.86536753e-05, 2.83518447e-05, 2.63909087e-05, - 2.30979238e-05, 2.04902226e-05, 1.98427032e-05, 2.07430291e-05, - 2.79180144e-05, 2.88470383e-05, 2.83645209e-05, 2.60770734e-05, - 2.18154073e-05, 1.97755973e-05, 2.04520099e-05, 2.12239276e-05, - 2.81670732e-05, 2.90099571e-05, 2.79386365e-05, 2.50344094e-05, - 2.34421577e-05, 2.26057798e-05, 2.17582117e-05, 2.64560558e-05, - 2.76581194e-05, 2.78719704e-05, 2.73603615e-05, 2.48029940e-05, - 2.17365555e-05, 2.10513336e-05, 2.13806137e-05, 2.60461227e-05, - 2.73345054e-05, 2.72706784e-05, 2.63101192e-05, 2.53577465e-05, - 2.44027652e-05, 2.24231642e-05, 2.14788550e-05, 2.56405599e-05, - 2.73995862e-05, 2.73532203e-05, 2.67424810e-05, 2.61913647e-05, - 2.45777896e-05, 2.24791841e-05, 2.12830336e-05, 2.13438625e-05, - 2.44384558e-05, 2.74404015e-05, 2.89568061e-05, 2.88705658e-05, - 2.67671361e-05, 2.23592691e-05, 2.09015627e-05, 2.24737505e-05, - 2.69823268e-05, 2.80611902e-05, 2.71575704e-05, 2.50043017e-05, - 2.43416448e-05, 2.36275315e-05, 2.19905059e-05, 2.14999107e-05, - 2.43551835e-05, 2.70280162e-05, 2.82879421e-05, 2.71585101e-05, - 2.51877914e-05, 2.29825084e-05, 2.15614449e-05, 2.15411146e-05, - 2.54958542e-05, 2.73851193e-05, 2.76190535e-05, 2.64062891e-05, - 2.47202304e-05, 2.32218272e-05, 2.14884339e-05, 2.19280854e-05, - 2.26970829e-05, 2.53867293e-05, 2.80874481e-05, 2.88276863e-05, - 2.74505884e-05, 2.40854644e-05, 2.18165396e-05, 2.04055299e-05, - 2.02547107e-05, 2.10710374e-05, 2.62976283e-05, 2.74879098e-05, - 2.76627829e-05, 2.59440868e-05, 2.31141165e-05, 2.33207117e-05, - 2.23925944e-05, 2.08138218e-05, 2.62065697e-05, 2.73747230e-05, - 2.74074032e-05, 2.70368579e-05, 2.59770350e-05, 2.32828972e-05, - 2.18351972e-05, 2.22943084e-05, 2.70616099e-05, 2.84833253e-05, - 2.80603928e-05, 2.51086799e-05, 2.15642884e-05, 2.14621938e-05, - 2.19559419e-05, 2.52534481e-05, 2.71299668e-05, 2.80299431e-05, - 2.76476275e-05, 2.57395497e-05, 2.38692958e-05, 2.24976041e-05, - 2.10682931e-05, - 2.55403698e-05, 2.76478561e-05, 2.79869271e-05, 2.71045422e-05, - 2.53017212e-05, 2.31661687e-05, 2.18739473e-05, 2.18060070e-05, - 2.19413088e-05, 2.52202838e-05, 2.67269256e-05, 2.63248638e-05, - 2.53649949e-05, 2.51954487e-05, 2.48834645e-05, 2.33044623e-05, - 2.19198962e-05, 2.21448488e-05, 2.24141105e-05, 2.18014566e-05, - 2.61061847e-05, 2.74160329e-05, 2.73336920e-05, 2.57947055e-05, - 2.47609466e-05, 2.45468541e-05, 2.28818378e-05, 2.11660172e-05, - 2.06207126e-05, 2.73087936e-05, 2.86243562e-05, 2.82979178e-05, - 2.50800037e-05, 2.19476574e-05, 2.16251885e-05, 2.16425898e-05, - 2.13039014e-05, 2.12336295e-05, 2.47479475e-05, 2.73262297e-05, - 2.79786914e-05, 2.61493217e-05, 2.39298838e-05, 2.40174928e-05, - 2.42574508e-05, 2.30011161e-05, 2.14907007e-05, 2.21726064e-05, - 2.47744716e-05, 2.79690467e-05, 2.87059858e-05, 2.80303937e-05, - 2.53190759e-05, 2.16965851e-05, 2.03775165e-05, 2.08603147e-05, - 2.71545936e-05, 2.83719267e-05, 2.80878774e-05, 2.62746931e-05, - 2.31566326e-05, 2.06587188e-05, 2.00507395e-05, 2.09510568e-05, - 2.78104011e-05, 2.85275805e-05, 2.80769569e-05, 2.59876872e-05, - 2.19273767e-05, 1.99794022e-05, 2.06735970e-05, 2.14264430e-05, - 2.79510238e-05, 2.86165583e-05, 2.76751836e-05, 2.49542212e-05, - 2.35162658e-05, 2.27987179e-05, 2.19789357e-05, 2.63658302e-05, - 2.74200694e-05, 2.76400451e-05, 2.72495161e-05, 2.48813742e-05, - 2.19175103e-05, 2.12553564e-05, 2.15784465e-05, 2.59827043e-05, - 2.71447127e-05, 2.70952103e-05, 2.62210545e-05, 2.53797682e-05, - 2.45229814e-05, 2.26042000e-05, 2.16738544e-05, 2.56037959e-05, - 2.72405254e-05, 2.72039538e-05, 2.66114627e-05, 2.61286867e-05, - 2.46547620e-05, 2.26538564e-05, 2.14859189e-05, 2.15427815e-05, - 2.43409133e-05, 2.71198167e-05, 2.85820604e-05, 2.86345505e-05, - 2.67913171e-05, 2.25636659e-05, 2.11231760e-05, 2.26861280e-05, - 2.68554913e-05, 2.77729151e-05, 2.69672091e-05, 2.49702558e-05, - 2.43821445e-05, 2.37479899e-05, 2.21686854e-05, 2.16891387e-05, - 2.42717273e-05, 2.68262869e-05, 2.80662702e-05, 2.70508910e-05, - 2.52079532e-05, 2.31300609e-05, 2.17641619e-05, 2.17309042e-05, - 2.54792892e-05, 2.72180626e-05, 2.74309403e-05, 2.62870720e-05, - 2.47099911e-05, 2.33244925e-05, 2.16712983e-05, 2.21210211e-05, - 2.28908549e-05, 2.53254777e-05, 2.78416079e-05, 2.85655066e-05, - 2.73382906e-05, 2.41264053e-05, 2.19527105e-05, 2.06149791e-05, - 2.04779617e-05, 2.12778442e-05, 2.61380841e-05, 2.71738469e-05, - 2.74124916e-05, 2.58845313e-05, 2.32441237e-05, 2.35393649e-05, - 2.26357360e-05, 2.10490865e-05, 2.61739597e-05, 2.71639024e-05, - 2.71720981e-05, 2.68908208e-05, 2.59545563e-05, 2.33792291e-05, - 2.19962241e-05, 2.24796744e-05, 2.68339302e-05, 2.80808377e-05, - 2.78439673e-05, 2.51650768e-05, 2.17513993e-05, 2.16554840e-05, - 2.21491845e-05, 2.51928078e-05, 2.69186006e-05, 2.77802646e-05, - 2.74918416e-05, 2.57737653e-05, 2.40147261e-05, 2.26769911e-05, - 2.12676781e-05, - 2.45333646e-05, 2.12256130e-05, 2.04154223e-05, 2.20479774e-05, - 2.45375703e-05, 2.67509996e-05, 2.77467718e-05, 2.78287696e-05, - 2.77922136e-05, 2.49463459e-05, 2.29727472e-05, 2.35874204e-05, - 2.47227170e-05, 2.49018424e-05, 2.52555087e-05, 2.66522938e-05, - 2.76739400e-05, 2.75958518e-05, 2.74573530e-05, 2.78732532e-05, - 2.37331110e-05, 2.16099398e-05, 2.19223442e-05, 2.41349541e-05, - 2.52752091e-05, 2.56289884e-05, 2.71221348e-05, 2.82312467e-05, - 2.85231687e-05, 2.18494527e-05, 1.77296556e-05, 1.94358572e-05, - 2.47922286e-05, 2.74768394e-05, 2.78785116e-05, 2.79777988e-05, - 2.81772205e-05, 2.82116316e-05, 2.50782742e-05, 2.13356715e-05, - 2.01949802e-05, 2.35560068e-05, 2.60757106e-05, 2.61827811e-05, - 2.60733955e-05, 2.71076758e-05, 2.80953717e-05, 2.74197859e-05, - 2.51010531e-05, 2.03244780e-05, 1.78044738e-05, 2.03083237e-05, - 2.47344522e-05, 2.78754633e-05, 2.86647294e-05, 2.84351267e-05, - 2.22822786e-05, 1.89297934e-05, 1.97664584e-05, 2.32962202e-05, - 2.66907371e-05, 2.84133402e-05, 2.87661036e-05, 2.83610726e-05, - 2.11118504e-05, 1.81194969e-05, 1.96452251e-05, 2.37267423e-05, - 2.76157529e-05, 2.87864126e-05, 2.85201692e-05, 2.81073616e-05, - 2.03308778e-05, 1.67568699e-05, 2.06057451e-05, 2.47975802e-05, - 2.64798176e-05, 2.72694947e-05, 2.78347066e-05, 2.32882231e-05, - 2.11813040e-05, 2.08377168e-05, 2.20257092e-05, 2.53740943e-05, - 2.77901111e-05, 2.82000380e-05, 2.80159299e-05, 2.38275515e-05, - 2.18426192e-05, 2.19800602e-05, 2.34634410e-05, 2.47397828e-05, - 2.57986982e-05, 2.73720144e-05, 2.79576282e-05, 2.43246126e-05, - 2.18373151e-05, 2.19347389e-05, 2.28254772e-05, 2.36663392e-05, - 2.55734367e-05, 2.73262985e-05, 2.80763407e-05, 2.80375557e-05, - 2.52601909e-05, 2.12100054e-05, 1.72750519e-05, 1.84201236e-05, - 2.31364230e-05, 2.74455968e-05, 2.83021158e-05, 2.73815638e-05, - 2.25227757e-05, 2.02806000e-05, 2.20955134e-05, 2.49490453e-05, - 2.57038198e-05, 2.64294745e-05, 2.76364570e-05, 2.79370090e-05, - 2.53712658e-05, 2.22374193e-05, 2.00587169e-05, 2.23289290e-05, - 2.49017902e-05, 2.69453894e-05, 2.79230180e-05, 2.79149452e-05, - 2.45188417e-05, 2.18359576e-05, 2.14079025e-05, 2.32697717e-05, - 2.52630447e-05, 2.66966354e-05, 2.79331876e-05, 2.76962967e-05, - 2.72095151e-05, 2.45174099e-05, 2.03879936e-05, 1.84641738e-05, - 2.18844172e-05, 2.59149335e-05, 2.76645809e-05, 2.85233574e-05, - 2.86127309e-05, 2.81940405e-05, 2.32769138e-05, 2.11642247e-05, - 2.11306077e-05, 2.39488304e-05, 2.68234031e-05, 2.67956635e-05, - 2.74685395e-05, 2.83644658e-05, 2.37186380e-05, 2.17156516e-05, - 2.15841270e-05, 2.23954272e-05, 2.39993130e-05, 2.66405611e-05, - 2.76996803e-05, 2.74604993e-05, 2.21047136e-05, 1.88086619e-05, - 2.05407792e-05, 2.50488034e-05, 2.78977698e-05, 2.79642141e-05, - 2.76801025e-05, 2.46474099e-05, 2.20660454e-05, 2.04853240e-05, - 2.14559673e-05, 2.43709277e-05, 2.62802015e-05, 2.73214148e-05, - 2.81841502e-05, - 2.33923105e-05, 1.77594714e-05, 1.65785454e-05, 1.91896503e-05, - 2.37410794e-05, 2.85167272e-05, 3.11452339e-05, 3.12786963e-05, - 3.10074705e-05, 2.41572553e-05, 2.04967110e-05, 2.15474051e-05, - 2.37881132e-05, 2.41679001e-05, 2.48807811e-05, 2.82353758e-05, - 3.10493973e-05, 3.06108774e-05, 3.00777288e-05, 3.12818733e-05, - 2.19711030e-05, 1.84012542e-05, 1.87912424e-05, 2.27268773e-05, - 2.50844443e-05, 2.56396268e-05, 2.91415717e-05, 3.25164218e-05, - 3.35568730e-05, 1.87557925e-05, 1.31011157e-05, 1.52459470e-05, - 2.42577607e-05, 3.09357332e-05, 3.16338237e-05, 3.15889676e-05, - 3.22426430e-05, 3.23798062e-05, 2.49572549e-05, 1.82332159e-05, - 1.63652508e-05, 2.17650822e-05, 2.68963081e-05, 2.67991060e-05, - 2.63251095e-05, 2.89036208e-05, 3.18722240e-05, 3.05202537e-05, - 2.49372969e-05, 1.65073622e-05, 1.31056324e-05, 1.64232627e-05, - 2.38658103e-05, 3.14942590e-05, 3.40020764e-05, 3.30817606e-05, - 1.93402326e-05, 1.46386596e-05, 1.58073170e-05, 2.13731304e-05, - 2.85042885e-05, 3.35134363e-05, 3.46505570e-05, 3.29233592e-05, - 1.74545322e-05, 1.36163175e-05, 1.56905920e-05, 2.21267826e-05, - 3.10228020e-05, 3.47914853e-05, 3.34427249e-05, 3.20064640e-05, - 1.65334886e-05, 1.20266667e-05, 1.71091194e-05, 2.44376738e-05, - 2.77946912e-05, 2.93063913e-05, 3.09123296e-05, 2.12477062e-05, - 1.79737765e-05, 1.73853273e-05, 1.89909520e-05, 2.49492916e-05, - 3.10569323e-05, 3.23378079e-05, 3.17133778e-05, 2.22184539e-05, - 1.89441288e-05, 1.91355801e-05, 2.15902789e-05, 2.37766887e-05, - 2.57544231e-05, 2.96978774e-05, 3.15286519e-05, 2.31460909e-05, - 1.88268521e-05, 1.89630568e-05, 2.05194051e-05, 2.18857175e-05, - 2.54305831e-05, 2.95998400e-05, 3.18903831e-05, 3.17822775e-05, - 2.56775860e-05, 1.83177875e-05, 1.26360693e-05, 1.38350744e-05, - 2.05262295e-05, 2.97698209e-05, 3.25769625e-05, 2.95215119e-05, - 1.99372188e-05, 1.66678423e-05, 1.93971802e-05, 2.45373303e-05, - 2.59501846e-05, 2.73674452e-05, 3.05625644e-05, 3.15017524e-05, - 2.58692154e-05, 1.96996081e-05, 1.61321957e-05, 1.95154733e-05, - 2.41485524e-05, 2.86407149e-05, 3.13471989e-05, 3.14197076e-05, - 2.34730491e-05, 1.88521627e-05, 1.81888496e-05, 2.13334879e-05, - 2.51530458e-05, 2.82180734e-05, 3.15393981e-05, 3.06516433e-05, - 2.91217133e-05, 2.36915582e-05, 1.67090263e-05, 1.39514627e-05, - 1.87512090e-05, 2.64855312e-05, 3.09861179e-05, 3.35691717e-05, - 3.38154615e-05, 3.22918887e-05, 2.15264184e-05, 1.82138433e-05, - 1.79299490e-05, 2.24529227e-05, 2.84019990e-05, 2.78016562e-05, - 2.95951445e-05, 3.27030245e-05, 2.18643251e-05, 1.87965788e-05, - 1.86548215e-05, 1.97756750e-05, 2.23936550e-05, 2.81004616e-05, - 3.09049240e-05, 2.99445893e-05, 1.95580775e-05, 1.47765454e-05, - 1.68625502e-05, 2.43060850e-05, 3.13807661e-05, 3.15655274e-05, - 3.05959604e-05, 2.39824982e-05, 1.94237498e-05, 1.68741479e-05, - 1.81644905e-05, 2.29247321e-05, 2.68316018e-05, 2.95530235e-05, - 3.23174105e-05, - 2.43957324e-05, 2.09205710e-05, 2.00765270e-05, 2.21048357e-05, - 2.49877801e-05, 2.70883887e-05, 2.79722972e-05, 2.79017408e-05, - 2.76398655e-05, 2.47324195e-05, 2.26485552e-05, 2.32538577e-05, - 2.46357852e-05, 2.48601310e-05, 2.52058183e-05, 2.69367744e-05, - 2.80603337e-05, 2.76932529e-05, 2.73539040e-05, 2.77646372e-05, - 2.37072548e-05, 2.14423793e-05, 2.15708836e-05, 2.41512800e-05, - 2.54963306e-05, 2.55320265e-05, 2.69755679e-05, 2.82601689e-05, - 2.85930065e-05, 2.16563743e-05, 1.73682496e-05, 1.90918074e-05, - 2.52697052e-05, 2.84621431e-05, 2.82250583e-05, 2.78505687e-05, - 2.80775183e-05, 2.81449786e-05, 2.57521811e-05, 2.16683837e-05, - 2.00613903e-05, 2.37296257e-05, 2.64044085e-05, 2.59716620e-05, - 2.54886208e-05, 2.66552149e-05, 2.78487319e-05, 2.80761880e-05, - 2.56680706e-05, 2.01081515e-05, 1.72333672e-05, 1.99565640e-05, - 2.47425701e-05, 2.80487908e-05, 2.86371186e-05, 2.82950284e-05, - 2.18985564e-05, 1.87007038e-05, 1.96941566e-05, 2.35853690e-05, - 2.72285211e-05, 2.89134908e-05, 2.90508431e-05, 2.83496411e-05, - 2.05108918e-05, 1.78676589e-05, 1.96755709e-05, 2.40032144e-05, - 2.81930258e-05, 2.91413064e-05, 2.84580079e-05, 2.79931381e-05, - 2.01520910e-05, 1.65322475e-05, 2.08268941e-05, 2.55511006e-05, - 2.67337131e-05, 2.67789511e-05, 2.73619874e-05, 2.33718826e-05, - 2.14559910e-05, 2.09387122e-05, 2.17538258e-05, 2.50218087e-05, - 2.77162899e-05, 2.81281108e-05, 2.78964806e-05, 2.39422482e-05, - 2.20487470e-05, 2.21407478e-05, 2.36158595e-05, 2.45743499e-05, - 2.52768673e-05, 2.70556186e-05, 2.78333025e-05, 2.44539594e-05, - 2.18260899e-05, 2.18932500e-05, 2.30175568e-05, 2.37025638e-05, - 2.53258875e-05, 2.70495898e-05, 2.79384964e-05, 2.79195559e-05, - 2.64614464e-05, 2.20816285e-05, 1.70875456e-05, 1.78041812e-05, - 2.23238173e-05, 2.69319333e-05, 2.80959762e-05, 2.67552627e-05, - 2.25559331e-05, 2.05410850e-05, 2.24117186e-05, 2.53693334e-05, - 2.58493134e-05, 2.62079880e-05, 2.75000492e-05, 2.78634413e-05, - 2.65050336e-05, 2.26996738e-05, 1.98255011e-05, 2.21479913e-05, - 2.48269164e-05, 2.67332521e-05, 2.76933772e-05, 2.78214916e-05, - 2.45722101e-05, 2.18797260e-05, 2.14309958e-05, 2.35702893e-05, - 2.56372520e-05, 2.67915705e-05, 2.79275896e-05, 2.74384479e-05, - 2.66800087e-05, 2.49500320e-05, 2.04155788e-05, 1.79980350e-05, - 2.15713464e-05, 2.61703767e-05, 2.80029437e-05, 2.86078621e-05, - 2.85951445e-05, 2.80867006e-05, 2.39027678e-05, 2.19671875e-05, - 2.14688999e-05, 2.40883361e-05, 2.67182630e-05, 2.58360929e-05, - 2.65815187e-05, 2.80427904e-05, 2.35434766e-05, 2.20184596e-05, - 2.20057874e-05, 2.25156416e-05, 2.38651919e-05, 2.67664862e-05, - 2.77866007e-05, 2.71484729e-05, 2.27009707e-05, 1.92457816e-05, - 2.04353840e-05, 2.47360036e-05, 2.78230831e-05, 2.78627912e-05, - 2.74097090e-05, 2.51429251e-05, 2.25233986e-05, 2.05722989e-05, - 2.12801255e-05, 2.39467529e-05, 2.57547830e-05, 2.69941955e-05, - 2.81546017e-05, - 2.37878169e-05, 1.88568468e-05, 1.77763692e-05, 2.02051292e-05, - 2.42037665e-05, 2.80450151e-05, 3.00347226e-05, 3.00960531e-05, - 2.98346199e-05, 2.44084430e-05, 2.12778031e-05, 2.21831557e-05, - 2.41293276e-05, 2.44547794e-05, 2.50412943e-05, 2.78120216e-05, - 3.00029664e-05, 2.95992317e-05, 2.91437231e-05, 3.00515882e-05, - 2.26093154e-05, 1.94597959e-05, 1.97723315e-05, 2.32603634e-05, - 2.52677830e-05, 2.56505950e-05, 2.84146167e-05, 3.10025760e-05, - 3.17709128e-05, 1.97714820e-05, 1.45046305e-05, 1.65422050e-05, - 2.46401691e-05, 3.00632684e-05, 3.04315258e-05, 3.02758388e-05, - 3.07670390e-05, 3.08767667e-05, 2.52602970e-05, 1.94028785e-05, - 1.76180112e-05, 2.24736986e-05, 2.67601547e-05, 2.65585517e-05, - 2.60914589e-05, 2.81548451e-05, 3.04544704e-05, 2.96682228e-05, - 2.52212197e-05, 1.77335932e-05, 1.44731679e-05, 1.76314694e-05, - 2.42144800e-05, 3.02830716e-05, 3.20638612e-05, 3.13696885e-05, - 2.02525401e-05, 1.59926783e-05, 1.71133823e-05, 2.21598483e-05, - 2.80820025e-05, 3.18551672e-05, 3.26126714e-05, 3.12894258e-05, - 1.85248635e-05, 1.50178961e-05, 1.70231700e-05, 2.28039593e-05, - 3.00301972e-05, 3.27320401e-05, 3.16523614e-05, 3.05889179e-05, - 1.77644494e-05, 1.34834148e-05, 1.83640699e-05, 2.48472431e-05, - 2.74576948e-05, 2.84558012e-05, 2.96796102e-05, 2.20105806e-05, - 1.91584825e-05, 1.85937522e-05, 1.99653018e-05, 2.50300649e-05, - 2.98920139e-05, 3.08444798e-05, 3.03703712e-05, 2.28491658e-05, - 2.00153993e-05, 2.01769926e-05, 2.23193860e-05, 2.41028634e-05, - 2.56465511e-05, 2.88000144e-05, 3.02316933e-05, 2.36376372e-05, - 1.98696757e-05, 1.99850820e-05, 2.14004641e-05, 2.25490680e-05, - 2.54466200e-05, 2.87349312e-05, 3.04967854e-05, 3.04218970e-05, - 2.59623892e-05, 1.95768389e-05, 1.40839579e-05, 1.51635969e-05, - 2.12029386e-05, 2.88047845e-05, 3.09838540e-05, 2.85861627e-05, - 2.08600728e-05, 1.79671221e-05, 2.04384786e-05, 2.48598727e-05, - 2.59569293e-05, 2.70082733e-05, 2.95034494e-05, 3.02248977e-05, - 2.61049346e-05, 2.07334874e-05, 1.73851018e-05, 2.04471108e-05, - 2.44315446e-05, 2.80102382e-05, 3.00688180e-05, 3.01585152e-05, - 2.38961128e-05, 1.99027074e-05, 1.93053953e-05, 2.21279122e-05, - 2.53572616e-05, 2.77538406e-05, 3.02706394e-05, 2.95395790e-05, - 2.83038521e-05, 2.41586760e-05, 1.79630535e-05, 1.53005837e-05, - 1.97441752e-05, 2.64138870e-05, 2.99432477e-05, 3.17837915e-05, - 3.19329538e-05, 3.08012548e-05, 2.23584354e-05, 1.94708805e-05, - 1.91305867e-05, 2.30537129e-05, 2.78500716e-05, 2.71703041e-05, - 2.85747819e-05, 3.10444444e-05, 2.24872814e-05, 1.99020566e-05, - 1.97975120e-05, 2.07350256e-05, 2.29466214e-05, 2.76687924e-05, - 2.98187286e-05, 2.89895349e-05, 2.06336541e-05, 1.62370303e-05, - 1.80793880e-05, 2.45098171e-05, 3.01343166e-05, 3.02651461e-05, - 2.94943241e-05, 2.44148312e-05, 2.04886738e-05, 1.81250572e-05, - 1.92459480e-05, 2.33337931e-05, 2.65103928e-05, 2.86863383e-05, - 3.08407458e-05, - 2.49401200e-05, 3.43402217e-05, 3.67114800e-05, 3.21623649e-05, - 2.51007573e-05, 1.87917292e-05, 1.58968272e-05, 1.56448671e-05, - 1.57317150e-05, 2.37551857e-05, 2.92683370e-05, 2.75190400e-05, - 2.44257785e-05, 2.39370401e-05, 2.29418661e-05, 1.90681026e-05, - 1.61177263e-05, 1.63329963e-05, 1.67145224e-05, 1.54971895e-05, - 2.72477371e-05, 3.33109172e-05, 3.22706680e-05, 2.61216038e-05, - 2.29547415e-05, 2.18827543e-05, 1.76705835e-05, 1.44292086e-05, - 1.35187726e-05, 3.25916743e-05, 4.48838048e-05, 3.96534371e-05, - 2.43790003e-05, 1.66824549e-05, 1.55078958e-05, 1.51843250e-05, - 1.45859639e-05, 1.44835371e-05, 2.35933456e-05, 3.44354639e-05, - 3.75561190e-05, 2.78328857e-05, 2.07106914e-05, 2.03049301e-05, - 2.04986629e-05, 1.76512468e-05, 1.48192554e-05, 1.68675582e-05, - 2.35133477e-05, 3.70935601e-05, 4.43468496e-05, 3.70191726e-05, - 2.44237665e-05, 1.55118106e-05, 1.30610638e-05, 1.37877008e-05, - 3.12087823e-05, 4.13267268e-05, 3.89139662e-05, 2.86252680e-05, - 1.89786583e-05, 1.38596596e-05, 1.27240548e-05, 1.40262075e-05, - 3.44224198e-05, 4.38137506e-05, 3.93776402e-05, 2.73780215e-05, - 1.62905415e-05, 1.26522292e-05, 1.35240731e-05, 1.47964934e-05, - 3.71069818e-05, 4.81561089e-05, 3.65802128e-05, 2.44081426e-05, - 1.95550038e-05, 1.71839197e-05, 1.55592804e-05, 2.85675033e-05, - 3.48682999e-05, 3.57951305e-05, 3.20255898e-05, 2.25151268e-05, - 1.57465591e-05, 1.45185559e-05, 1.50710366e-05, 2.70327931e-05, - 3.28506951e-05, 3.24192929e-05, 2.80910583e-05, 2.43505650e-05, - 2.12795428e-05, 1.69268389e-05, 1.52447972e-05, 2.56216308e-05, - 3.27427580e-05, 3.24379630e-05, 2.99539791e-05, 2.74634783e-05, - 2.19947801e-05, 1.70649400e-05, 1.48878844e-05, 1.50063248e-05, - 2.31030353e-05, 3.50657684e-05, 4.65599065e-05, 4.24029763e-05, - 2.84942243e-05, 1.66767541e-05, 1.41950124e-05, 1.68333487e-05, - 3.07601006e-05, 3.76022516e-05, 3.21553786e-05, 2.39209452e-05, - 2.17297873e-05, 1.96119241e-05, 1.61900511e-05, 1.53111329e-05, - 2.27823152e-05, 3.17983800e-05, 3.78787531e-05, 3.12036865e-05, - 2.39266943e-05, 1.81611638e-05, 1.53359019e-05, 1.53749389e-05, - 2.50468555e-05, 3.27795427e-05, 3.40350691e-05, 2.87060698e-05, - 2.30201298e-05, 1.89180259e-05, 1.53283115e-05, 1.59989244e-05, - 1.73450129e-05, 2.51544764e-05, 3.71030134e-05, 4.24713540e-05, - 3.24078274e-05, 2.11545103e-05, 1.61442388e-05, 1.35184263e-05, - 1.32296864e-05, 1.45341564e-05, 2.87884663e-05, 3.51799541e-05, - 3.50580646e-05, 2.66951714e-05, 1.85263677e-05, 1.83727723e-05, - 1.65160553e-05, 1.39913028e-05, 2.72242266e-05, 3.32794365e-05, - 3.37332765e-05, 3.11762590e-05, 2.64472533e-05, 1.90816015e-05, - 1.60273918e-05, 1.66734762e-05, 3.22471393e-05, 4.23494763e-05, - 3.65363629e-05, 2.34338729e-05, 1.54277968e-05, 1.52273917e-05, - 1.60443001e-05, 2.47962245e-05, 3.23064337e-05, 3.68522413e-05, - 3.37582760e-05, 2.52767287e-05, 1.99455898e-05, 1.70696986e-05, - 1.45699127e-05, - 2.55861745e-05, 3.10488232e-05, 3.22614144e-05, 2.94220745e-05, - 2.50452225e-05, 2.10594683e-05, 1.90020429e-05, 1.89173710e-05, - 1.91530365e-05, 2.49222805e-05, 2.83713174e-05, 2.73726816e-05, - 2.52106920e-05, 2.48552937e-05, 2.42273064e-05, 2.12995377e-05, - 1.90534147e-05, 1.94351312e-05, 1.98837208e-05, 1.89338707e-05, - 2.68427875e-05, 3.03255051e-05, 3.00506161e-05, 2.61311655e-05, - 2.39617660e-05, 2.35783543e-05, 2.06444120e-05, 1.79718164e-05, - 1.71871680e-05, 2.99930320e-05, 3.58365450e-05, 3.36237821e-05, - 2.45838906e-05, 1.90337990e-05, 1.86112680e-05, 1.86964574e-05, - 1.81899485e-05, 1.80826989e-05, 2.39067975e-05, 3.01557341e-05, - 3.23226709e-05, 2.69407129e-05, 2.23908821e-05, 2.26089312e-05, - 2.30979458e-05, 2.08835130e-05, 1.84855924e-05, 1.94147832e-05, - 2.39647363e-05, 3.22431123e-05, 3.60454525e-05, 3.24284576e-05, - 2.51070804e-05, 1.87393538e-05, 1.68603615e-05, 1.75533385e-05, - 2.95268412e-05, 3.41427620e-05, 3.28310313e-05, 2.72432663e-05, - 2.10227693e-05, 1.71893205e-05, 1.63743447e-05, 1.76664324e-05, - 3.15440458e-05, 3.52008270e-05, 3.28605642e-05, 2.65617258e-05, - 1.90436699e-05, 1.62695830e-05, 1.72783716e-05, 1.83724940e-05, - 3.21887042e-05, 3.67629295e-05, 3.13169516e-05, 2.43165982e-05, - 2.16670512e-05, 2.05561772e-05, 1.92554969e-05, 2.74624045e-05, - 3.04446034e-05, 3.11388885e-05, 2.98083222e-05, 2.42560919e-05, - 1.91061988e-05, 1.81151580e-05, 1.85993081e-05, 2.65527199e-05, - 2.95638364e-05, 2.94100439e-05, 2.71116755e-05, 2.52484252e-05, - 2.35856244e-05, 2.02161314e-05, 1.87430738e-05, 2.57054596e-05, - 2.98133347e-05, 2.96999929e-05, 2.80851267e-05, 2.68937748e-05, - 2.38022394e-05, 2.02906390e-05, 1.84638272e-05, 1.85458529e-05, - 2.30964187e-05, 2.96788450e-05, 3.61162629e-05, 3.53238497e-05, - 2.85593835e-05, 2.01793866e-05, 1.79403319e-05, 2.03935536e-05, - 2.87216655e-05, 3.17128326e-05, 2.90650284e-05, 2.43639495e-05, - 2.32413274e-05, 2.21286753e-05, 1.95022960e-05, 1.87594009e-05, - 2.29671027e-05, 2.86906565e-05, 3.26339650e-05, 2.92455177e-05, - 2.48838734e-05, 2.10649800e-05, 1.88935669e-05, 1.88250204e-05, - 2.54418151e-05, 2.97547148e-05, 3.04105326e-05, 2.72738003e-05, - 2.38502642e-05, 2.13550707e-05, 1.87237244e-05, 1.94445910e-05, - 2.07128187e-05, 2.50959637e-05, 3.18569271e-05, 3.50646308e-05, - 3.00681044e-05, 2.27554769e-05, 1.91092710e-05, 1.71772818e-05, - 1.69985387e-05, 1.81527319e-05, 2.69263193e-05, 2.98269301e-05, - 3.04406164e-05, 2.63279386e-05, 2.12430749e-05, 2.18745247e-05, - 2.03534244e-05, 1.78488039e-05, 2.70071654e-05, 2.96410372e-05, - 2.96946340e-05, 2.88256216e-05, 2.64985948e-05, 2.14450192e-05, - 1.92064522e-05, 2.00161797e-05, 2.87357942e-05, 3.33692511e-05, - 3.18054382e-05, 2.48197590e-05, 1.88535438e-05, 1.87124165e-05, - 1.94900888e-05, 2.48157024e-05, 2.89504188e-05, 3.16489799e-05, - 3.05638639e-05, 2.61174293e-05, 2.26462771e-05, 2.03350310e-05, - 1.81276942e-05, - 2.54199633e-05, 2.53078504e-05, 2.51403424e-05, 2.49608119e-05, - 2.46557506e-05, 2.44162618e-05, 2.40836650e-05, 2.42087585e-05, - 2.44919477e-05, 2.54887847e-05, 2.56325403e-05, 2.56871604e-05, - 2.53424011e-05, 2.52697215e-05, 2.52413458e-05, 2.45133113e-05, - 2.39408125e-05, 2.43197631e-05, 2.46299917e-05, 2.43890501e-05, - 2.52745877e-05, 2.51934337e-05, 2.55239578e-05, 2.52263047e-05, - 2.48947791e-05, 2.52425839e-05, 2.48455226e-05, 2.39731748e-05, - 2.36755316e-05, 2.52801298e-05, 2.41226966e-05, 2.48213895e-05, - 2.46112978e-05, 2.33553703e-05, 2.38627805e-05, 2.43394921e-05, - 2.41613818e-05, 2.40969758e-05, 2.43449844e-05, 2.44061671e-05, - 2.47578227e-05, 2.49971581e-05, 2.46212934e-05, 2.52593702e-05, - 2.57557036e-05, 2.52173627e-05, 2.43909931e-05, 2.37630870e-05, - 2.44770640e-05, 2.49251846e-05, 2.45136215e-05, 2.51277115e-05, - 2.52179400e-05, 2.40634281e-05, 2.36450508e-05, 2.39915667e-05, - 2.56311533e-05, 2.44415912e-05, 2.45173477e-05, 2.48210333e-05, - 2.41975877e-05, 2.32916590e-05, 2.31909387e-05, 2.39118722e-05, - 2.57259438e-05, 2.41248754e-05, 2.43153414e-05, 2.48699744e-05, - 2.37531685e-05, 2.30908329e-05, 2.38259694e-05, 2.42310698e-05, - 2.48700098e-05, 2.33846605e-05, 2.43581328e-05, 2.42618301e-05, - 2.46049005e-05, 2.51844520e-05, 2.48348313e-05, 2.50983112e-05, - 2.44481905e-05, 2.46044864e-05, 2.54272466e-05, 2.56115999e-05, - 2.44025291e-05, 2.41120707e-05, 2.43037095e-05, 2.50898135e-05, - 2.47073178e-05, 2.48003971e-05, 2.50192500e-05, 2.54436599e-05, - 2.57453671e-05, 2.49255011e-05, 2.43501619e-05, 2.50760379e-05, - 2.50157686e-05, 2.50788018e-05, 2.48992173e-05, 2.51880923e-05, - 2.54434222e-05, 2.49021253e-05, 2.42810053e-05, 2.42865732e-05, - 2.36792311e-05, 2.36130063e-05, 2.36011508e-05, 2.48627119e-05, - 2.63359064e-05, 2.51188626e-05, 2.41813071e-05, 2.52870437e-05, - 2.50761753e-05, 2.41944585e-05, 2.46053071e-05, 2.46741982e-05, - 2.49246161e-05, 2.51995890e-05, 2.45684266e-05, 2.43060484e-05, - 2.37515157e-05, 2.44307813e-05, 2.48657719e-05, 2.53480252e-05, - 2.53126393e-05, 2.50004682e-05, 2.44948901e-05, 2.43438202e-05, - 2.51702640e-05, 2.49367919e-05, 2.48698520e-05, 2.48031795e-05, - 2.47032147e-05, 2.47261564e-05, 2.42306399e-05, 2.46739222e-05, - 2.52607788e-05, 2.46788171e-05, 2.45765621e-05, 2.46320386e-05, - 2.54610154e-05, 2.47467365e-05, 2.40016205e-05, 2.36589492e-05, - 2.36865633e-05, 2.41569475e-05, 2.43693864e-05, 2.36950336e-05, - 2.43428579e-05, 2.50605423e-05, 2.49205921e-05, 2.59704951e-05, - 2.55470724e-05, 2.42582602e-05, 2.54758159e-05, 2.45422087e-05, - 2.43431273e-05, 2.49341676e-05, 2.54262861e-05, 2.47080755e-05, - 2.42719534e-05, 2.48732022e-05, 2.42193873e-05, 2.33482726e-05, - 2.48235501e-05, 2.56060292e-05, 2.43337555e-05, 2.43193442e-05, - 2.46983525e-05, 2.45945337e-05, 2.44029471e-05, 2.45187583e-05, - 2.51711682e-05, 2.58078884e-05, 2.56214745e-05, 2.49643593e-05, - 2.40763636e-05, - 2.36973387e-05, 1.84421799e-05, 1.73197475e-05, 1.93659271e-05, - 2.31943207e-05, 2.78474863e-05, 3.04709010e-05, 3.08447048e-05, - 3.09642006e-05, 2.45454628e-05, 2.11535558e-05, 2.21916623e-05, - 2.40043577e-05, 2.43027285e-05, 2.49965945e-05, 2.76658816e-05, - 3.01222182e-05, 3.01819382e-05, 3.00094769e-05, 3.11487415e-05, - 2.21688553e-05, 1.88919909e-05, 1.95193765e-05, 2.28369849e-05, - 2.47928397e-05, 2.57921515e-05, 2.91965155e-05, 3.20696233e-05, - 3.29637247e-05, 1.92728535e-05, 1.38820938e-05, 1.60036713e-05, - 2.36441183e-05, 2.90764548e-05, 3.07260847e-05, 3.14676109e-05, - 3.20323943e-05, 3.21042879e-05, 2.40249728e-05, 1.80854883e-05, - 1.68485086e-05, 2.16946473e-05, 2.63434484e-05, 2.70735638e-05, - 2.72036209e-05, 2.94675701e-05, 3.19352266e-05, 2.92074532e-05, - 2.41571607e-05, 1.70929902e-05, 1.41386667e-05, 1.71824270e-05, - 2.39410484e-05, 3.08800916e-05, 3.35436818e-05, 3.28841719e-05, - 2.01026261e-05, 1.52581642e-05, 1.62226177e-05, 2.11619791e-05, - 2.75295825e-05, 3.21966901e-05, 3.35987077e-05, 3.25160249e-05, - 1.85326323e-05, 1.42673195e-05, 1.59820439e-05, 2.19000373e-05, - 2.97932532e-05, 3.36064282e-05, 3.30852799e-05, 3.18363492e-05, - 1.70712303e-05, 1.26446948e-05, 1.71348886e-05, 2.34277919e-05, - 2.72997930e-05, 2.99148698e-05, 3.14136696e-05, 2.13203004e-05, - 1.79074181e-05, 1.75537436e-05, 1.96084439e-05, 2.55156018e-05, - 3.08801061e-05, 3.20740797e-05, 3.15710137e-05, 2.22109602e-05, - 1.89338539e-05, 1.91779330e-05, 2.15558703e-05, 2.41078414e-05, - 2.65532988e-05, 2.99998061e-05, 3.14062385e-05, 2.30790831e-05, - 1.91024657e-05, 1.92748507e-05, 2.04724826e-05, 2.20001126e-05, - 2.58197007e-05, 2.98416713e-05, 3.17677005e-05, 3.16330518e-05, - 2.39596378e-05, 1.75034185e-05, 1.32125524e-05, 1.49293068e-05, - 2.18755256e-05, 3.03955992e-05, 3.25265827e-05, 3.03469723e-05, - 2.01222980e-05, 1.66572478e-05, 1.92290872e-05, 2.39888080e-05, - 2.57244548e-05, 2.76317645e-05, 3.05196395e-05, 3.12960730e-05, - 2.42291027e-05, 1.93315329e-05, 1.67437271e-05, 1.99992452e-05, - 2.43326386e-05, 2.88276106e-05, 3.14129906e-05, 3.12525268e-05, - 2.34999450e-05, 1.90552229e-05, 1.84363257e-05, 2.11087188e-05, - 2.46358200e-05, 2.79429026e-05, 3.12179005e-05, 3.08050370e-05, - 2.98029152e-05, 2.31720279e-05, 1.69846632e-05, 1.48615498e-05, - 1.94284529e-05, 2.60664123e-05, 3.01409394e-05, 3.29499319e-05, - 3.33535953e-05, 3.20913332e-05, 2.08593115e-05, 1.74873537e-05, - 1.77854128e-05, 2.24012836e-05, 2.84308229e-05, 2.92445669e-05, - 3.08600824e-05, 3.28443548e-05, 2.22753018e-05, 1.86673106e-05, - 1.83800960e-05, 1.98502776e-05, 2.27292012e-05, 2.77840636e-05, - 3.04733714e-05, 3.02264582e-05, 1.90253117e-05, 1.46067629e-05, - 1.73022836e-05, 2.48358158e-05, 3.11847524e-05, 3.14023598e-05, - 3.07733991e-05, 2.33591016e-05, 1.90734343e-05, 1.70722480e-05, - 1.86708587e-05, 2.36627789e-05, 2.75982026e-05, 2.98801815e-05, - 3.19833339e-05, - 2.23732722e-05, 1.53866682e-05, 1.40485468e-05, 1.66748915e-05, - 2.20004316e-05, 2.90938854e-05, 3.35354611e-05, 3.40657573e-05, - 3.40636087e-05, 2.35543193e-05, 1.87859638e-05, 2.01659018e-05, - 2.28452253e-05, 2.33067690e-05, 2.43269545e-05, 2.87518768e-05, - 3.30601295e-05, 3.28968952e-05, 3.24071959e-05, 3.44418798e-05, - 2.03001716e-05, 1.59904914e-05, 1.66845485e-05, 2.12464679e-05, - 2.41981292e-05, 2.54981704e-05, 3.09618139e-05, 3.62950705e-05, - 3.80635124e-05, 1.64486243e-05, 1.02878054e-05, 1.25564194e-05, - 2.26648966e-05, 3.17462486e-05, 3.41161266e-05, 3.50083844e-05, - 3.60892119e-05, 3.62596445e-05, 2.33432280e-05, 1.52183257e-05, - 1.35831035e-05, 1.97613735e-05, 2.66541293e-05, 2.74146111e-05, - 2.73426422e-05, 3.11598595e-05, 3.57540214e-05, 3.16833833e-05, - 2.34721570e-05, 1.38331072e-05, 1.04891982e-05, 1.38850561e-05, - 2.28114510e-05, 3.42282515e-05, 3.90984170e-05, 3.76729358e-05, - 1.74021447e-05, 1.17793802e-05, 1.28955686e-05, 1.91052517e-05, - 2.87267896e-05, 3.70460771e-05, 3.95798640e-05, 3.71039032e-05, - 1.53722924e-05, 1.07193404e-05, 1.26621709e-05, 2.00947442e-05, - 3.26489705e-05, 3.96799694e-05, 3.81523039e-05, 3.57062779e-05, - 1.38221388e-05, 9.08265833e-06, 1.40465866e-05, 2.25162085e-05, - 2.81295647e-05, 3.18936354e-05, 3.45652209e-05, 1.92122082e-05, - 1.49807449e-05, 1.44916930e-05, 1.68313146e-05, 2.49055561e-05, - 3.39874932e-05, 3.61970105e-05, 3.52073231e-05, 2.04337075e-05, - 1.62025375e-05, 1.64859564e-05, 1.95630842e-05, 2.29470251e-05, - 2.63724359e-05, 3.21971678e-05, 3.48982292e-05, 2.16508720e-05, - 1.63171314e-05, 1.65178090e-05, 1.81490931e-05, 2.01033255e-05, - 2.54370882e-05, 3.19578518e-05, 3.55538310e-05, 3.53237871e-05, - 2.35756638e-05, 1.47324498e-05, 9.65743992e-06, 1.13018194e-05, - 1.94887598e-05, 3.27091487e-05, 3.69127833e-05, 3.25209246e-05, - 1.76216155e-05, 1.35084109e-05, 1.66182523e-05, 2.31330604e-05, - 2.55608142e-05, 2.83014784e-05, 3.32797310e-05, 3.47464097e-05, - 2.39380778e-05, 1.68117904e-05, 1.34268040e-05, 1.73651058e-05, - 2.33298559e-05, 3.02812042e-05, 3.48052828e-05, 3.46467120e-05, - 2.22044115e-05, 1.62825507e-05, 1.55156729e-05, 1.90399961e-05, - 2.40620281e-05, 2.90581324e-05, 3.46705175e-05, 3.36751063e-05, - 3.16662188e-05, 2.19583121e-05, 1.37995415e-05, 1.12778985e-05, - 1.65886262e-05, 2.61671513e-05, 3.30486589e-05, 3.80530543e-05, - 3.87320800e-05, 3.61922787e-05, 1.88705567e-05, 1.46863804e-05, - 1.48600693e-05, 2.07094525e-05, 2.97055653e-05, 3.03522830e-05, - 3.31781139e-05, 3.73953988e-05, 2.03649929e-05, 1.59149452e-05, - 1.56126572e-05, 1.73146245e-05, 2.10120652e-05, 2.88211315e-05, - 3.34080309e-05, 3.25975590e-05, 1.64855846e-05, 1.12902212e-05, - 1.41175112e-05, 2.39184725e-05, 3.45411959e-05, 3.49140582e-05, - 3.36064179e-05, 2.22635043e-05, 1.64852457e-05, 1.39231618e-05, - 1.57171610e-05, 2.21541520e-05, 2.80140891e-05, 3.19794773e-05, - 3.60703564e-05, - 2.44518688e-05, 2.09809014e-05, 2.01405678e-05, 2.19363098e-05, - 2.46354470e-05, 2.69307754e-05, 2.79625071e-05, 2.80038569e-05, - 2.78945058e-05, 2.48597746e-05, 2.27743419e-05, 2.34079757e-05, - 2.46650329e-05, 2.48660744e-05, 2.52339056e-05, 2.68096358e-05, - 2.79336039e-05, 2.77602792e-05, 2.75493040e-05, 2.79956290e-05, - 2.36533314e-05, 2.14174826e-05, 2.16826070e-05, 2.40838889e-05, - 2.53374292e-05, 2.56114645e-05, 2.71771446e-05, 2.84269928e-05, - 2.87593924e-05, 2.16559873e-05, 1.73991626e-05, 1.91387757e-05, - 2.49097221e-05, 2.79052181e-05, 2.81422706e-05, 2.81030035e-05, - 2.83281399e-05, 2.83758981e-05, 2.52686180e-05, 2.12870768e-05, - 1.99776217e-05, 2.35302587e-05, 2.62125970e-05, 2.61598748e-05, - 2.59287927e-05, 2.70668702e-05, 2.81934121e-05, 2.77431787e-05, - 2.52601053e-05, 2.00848906e-05, 1.74110112e-05, 2.00271150e-05, - 2.47063875e-05, 2.80854134e-05, 2.88851125e-05, 2.85972933e-05, - 2.20433772e-05, 1.86583075e-05, 1.95584937e-05, 2.32959585e-05, - 2.69280729e-05, 2.87724191e-05, 2.90948920e-05, 2.85562562e-05, - 2.07735363e-05, 1.78278814e-05, 1.94657889e-05, 2.37386893e-05, - 2.79296656e-05, 2.91393458e-05, 2.87149642e-05, 2.82476385e-05, - 2.01028448e-05, 1.64559266e-05, 2.05050146e-05, 2.49988419e-05, - 2.66172312e-05, 2.72279097e-05, 2.78407178e-05, 2.32253251e-05, - 2.11111440e-05, 2.07064285e-05, 2.18133267e-05, 2.52651805e-05, - 2.79166051e-05, 2.83616265e-05, 2.81467556e-05, 2.37942474e-05, - 2.17700772e-05, 2.18978153e-05, 2.34278145e-05, 2.46587852e-05, - 2.56588771e-05, 2.73917679e-05, 2.80820549e-05, 2.43158489e-05, - 2.16988161e-05, 2.17898788e-05, 2.27794174e-05, 2.36029477e-05, - 2.55067407e-05, 2.73551203e-05, 2.82065945e-05, 2.81706642e-05, - 2.56183908e-05, 2.13189652e-05, 1.69913473e-05, 1.80220716e-05, - 2.27930852e-05, 2.74093082e-05, 2.84311752e-05, 2.73055887e-05, - 2.24185836e-05, 2.01840923e-05, 2.20636789e-05, 2.50563899e-05, - 2.57645475e-05, 2.64175835e-05, 2.77315729e-05, 2.80754902e-05, - 2.57147879e-05, 2.22538972e-05, 1.98081186e-05, 2.21534685e-05, - 2.48558586e-05, 2.69683608e-05, 2.80118525e-05, 2.80454338e-05, - 2.44951582e-05, 2.17141004e-05, 2.12678186e-05, 2.32719982e-05, - 2.53713425e-05, 2.67984968e-05, 2.80924463e-05, 2.77583102e-05, - 2.71516668e-05, 2.46090751e-05, 2.02237899e-05, 1.81126836e-05, - 2.16553265e-05, 2.60205542e-05, 2.79087040e-05, 2.87641674e-05, - 2.88308139e-05, 2.83440789e-05, 2.33775404e-05, 2.12515682e-05, - 2.10782420e-05, 2.39278390e-05, 2.68715847e-05, 2.65765900e-05, - 2.73173765e-05, 2.84632818e-05, 2.35926785e-05, 2.16686106e-05, - 2.15690992e-05, 2.23136080e-05, 2.38968176e-05, 2.67484722e-05, - 2.78688555e-05, 2.74879921e-05, 2.21573140e-05, 1.87352165e-05, - 2.03398666e-05, 2.49365425e-05, 2.80326762e-05, 2.80963030e-05, - 2.77369696e-05, 2.47638601e-05, 2.20757978e-05, 2.03413131e-05, - 2.12567669e-05, 2.41944918e-05, 2.61655856e-05, 2.73342169e-05, - 2.83574982e-05, - 2.51691872e-05, 2.57131048e-05, 2.56743086e-05, 2.63591322e-05, - 2.62022348e-05, 2.44720774e-05, 2.32898088e-05, 2.29879651e-05, - 2.27254542e-05, 2.48347307e-05, 2.53776466e-05, 2.51809493e-05, - 2.51679385e-05, 2.51553431e-05, 2.49475042e-05, 2.44811363e-05, - 2.35913335e-05, 2.32882156e-05, 2.31567486e-05, 2.26908188e-05, - 2.57080446e-05, 2.59653253e-05, 2.55338168e-05, 2.56234205e-05, - 2.53898458e-05, 2.46444987e-05, 2.34234593e-05, 2.24181960e-05, - 2.20462662e-05, 2.58760868e-05, 2.53045744e-05, 2.56235097e-05, - 2.61086146e-05, 2.46217106e-05, 2.32904052e-05, 2.25404244e-05, - 2.23241555e-05, 2.23214395e-05, 2.62678845e-05, 2.70741361e-05, - 2.61443475e-05, 2.61483989e-05, 2.50175107e-05, 2.40904542e-05, - 2.35677310e-05, 2.29874165e-05, 2.22358911e-05, 2.42481589e-05, - 2.60750749e-05, 2.59537793e-05, 2.47770352e-05, 2.56449889e-05, - 2.53281323e-05, 2.30656249e-05, 2.17025253e-05, 2.19160063e-05, - 2.54085965e-05, 2.58515773e-05, 2.62843602e-05, 2.64637266e-05, - 2.48215133e-05, 2.27406464e-05, 2.19012594e-05, 2.21855499e-05, - 2.50750410e-05, 2.56712889e-05, 2.65235436e-05, 2.62725181e-05, - 2.39151027e-05, 2.19458864e-05, 2.18875257e-05, 2.23957946e-05, - 2.60391901e-05, 2.54050695e-05, 2.69265729e-05, 2.65763904e-05, - 2.45818305e-05, 2.27849055e-05, 2.22370808e-05, 2.60743495e-05, - 2.69743238e-05, 2.66375761e-05, 2.56832899e-05, 2.43705433e-05, - 2.28348741e-05, 2.23300788e-05, 2.25039483e-05, 2.59319824e-05, - 2.67109315e-05, 2.65878344e-05, 2.61431010e-05, 2.50221194e-05, - 2.38419635e-05, 2.29396112e-05, 2.25688328e-05, 2.57418538e-05, - 2.62584874e-05, 2.61777000e-05, 2.64331934e-05, 2.58491538e-05, - 2.44302497e-05, 2.30411716e-05, 2.24040585e-05, 2.24790048e-05, - 2.70083940e-05, 2.82528262e-05, 2.56515178e-05, 2.48068761e-05, - 2.43802220e-05, 2.25842100e-05, 2.20186365e-05, 2.24824428e-05, - 2.62017366e-05, 2.70411927e-05, 2.68814759e-05, 2.59202161e-05, - 2.49913805e-05, 2.38929917e-05, 2.29208967e-05, 2.26617547e-05, - 2.68181561e-05, 2.71421329e-05, 2.59147192e-05, 2.58135830e-05, - 2.50980848e-05, 2.34865151e-05, 2.24684915e-05, 2.26616719e-05, - 2.55143943e-05, 2.63736209e-05, 2.63998647e-05, 2.64950314e-05, - 2.56522335e-05, 2.41596917e-05, 2.27571804e-05, 2.26872873e-05, - 2.27826283e-05, 2.61822100e-05, 2.65061496e-05, 2.51925741e-05, - 2.56196383e-05, 2.50210114e-05, 2.35378169e-05, 2.20640127e-05, - 2.17985394e-05, 2.22920114e-05, 2.71102336e-05, 2.81158584e-05, - 2.71197280e-05, 2.59274380e-05, 2.37517145e-05, 2.24740245e-05, - 2.20207835e-05, 2.17836100e-05, 2.54344048e-05, 2.69389746e-05, - 2.72158595e-05, 2.64089265e-05, 2.54047013e-05, 2.42539590e-05, - 2.31571820e-05, 2.28581243e-05, 2.74511581e-05, 2.74805885e-05, - 2.61987383e-05, 2.46117003e-05, 2.27074342e-05, 2.25914718e-05, - 2.26874757e-05, 2.62212243e-05, 2.71778939e-05, 2.66348880e-05, - 2.59677159e-05, 2.47269136e-05, 2.35244579e-05, 2.29730942e-05, - 2.24061965e-05, - 2.49568795e-05, 2.38186132e-05, 2.34179942e-05, 2.47477871e-05, - 2.58870950e-05, 2.55832538e-05, 2.51089237e-05, 2.48687684e-05, - 2.45823774e-05, 2.48741042e-05, 2.43569291e-05, 2.44865432e-05, - 2.50557043e-05, 2.51402173e-05, 2.51438500e-05, 2.55287653e-05, - 2.53553677e-05, 2.49990921e-05, 2.47747778e-05, 2.46059743e-05, - 2.50215143e-05, 2.42074434e-05, 2.39915392e-05, 2.51537692e-05, - 2.55595243e-05, 2.50733868e-05, 2.48130785e-05, 2.46026213e-05, - 2.44634107e-05, 2.42453319e-05, 2.19462616e-05, 2.29400571e-05, - 2.59438603e-05, 2.62360682e-05, 2.52077546e-05, 2.45325610e-05, - 2.44658134e-05, 2.44896409e-05, 2.62521204e-05, 2.50032423e-05, - 2.37007422e-05, 2.53174007e-05, 2.56804314e-05, 2.48748709e-05, - 2.43259021e-05, 2.43847471e-05, 2.43157023e-05, 2.58215892e-05, - 2.60884683e-05, 2.36046477e-05, 2.15700459e-05, 2.33459350e-05, - 2.52062598e-05, 2.49805617e-05, 2.42327753e-05, 2.42569421e-05, - 2.40543546e-05, 2.28976971e-05, 2.36188068e-05, 2.54595762e-05, - 2.58799480e-05, 2.50835550e-05, 2.45326618e-05, 2.44706753e-05, - 2.32387005e-05, 2.23998822e-05, 2.37560262e-05, 2.55150627e-05, - 2.56347619e-05, 2.45992179e-05, 2.42982209e-05, 2.44845300e-05, - 2.36771455e-05, 2.16046333e-05, 2.45308064e-05, 2.63723425e-05, - 2.55163566e-05, 2.42916294e-05, 2.41308243e-05, 2.51161391e-05, - 2.48453282e-05, 2.44026094e-05, 2.41659846e-05, 2.46817523e-05, - 2.46890526e-05, 2.44893545e-05, 2.45243108e-05, 2.52672292e-05, - 2.49452276e-05, 2.49082670e-05, 2.52652569e-05, 2.49335244e-05, - 2.44278555e-05, 2.45069496e-05, 2.45460601e-05, 2.53589142e-05, - 2.45613887e-05, 2.45399513e-05, 2.51940518e-05, 2.51113970e-05, - 2.48452664e-05, 2.45755911e-05, 2.44694992e-05, 2.45154590e-05, - 2.70444366e-05, 2.59256602e-05, 2.20168034e-05, 2.18540019e-05, - 2.35753723e-05, 2.42103012e-05, 2.42549197e-05, 2.40709831e-05, - 2.48452138e-05, 2.44708042e-05, 2.52138024e-05, 2.58605394e-05, - 2.54366274e-05, 2.48341395e-05, 2.46660312e-05, 2.46234368e-05, - 2.69357318e-05, 2.55064267e-05, 2.34525773e-05, 2.44203551e-05, - 2.50883956e-05, 2.47617243e-05, 2.44213277e-05, 2.46072415e-05, - 2.52585393e-05, 2.46576972e-05, 2.44751681e-05, 2.54732801e-05, - 2.57933627e-05, 2.52496371e-05, 2.47156682e-05, 2.44778606e-05, - 2.42517253e-05, 2.58579568e-05, 2.40843435e-05, 2.21751127e-05, - 2.40460339e-05, 2.55875687e-05, 2.52953015e-05, 2.44817962e-05, - 2.42861031e-05, 2.44464262e-05, 2.60143877e-05, 2.57881061e-05, - 2.49417421e-05, 2.53262540e-05, 2.49392436e-05, 2.37106080e-05, - 2.36806340e-05, 2.40666779e-05, 2.47738727e-05, 2.50753314e-05, - 2.52435398e-05, 2.49596597e-05, 2.48900543e-05, 2.53044834e-05, - 2.49433422e-05, 2.44858889e-05, 2.57026351e-05, 2.41327512e-05, - 2.39036358e-05, 2.47268072e-05, 2.46402233e-05, 2.45734203e-05, - 2.44669197e-05, 2.59650605e-05, 2.54508187e-05, 2.42349516e-05, - 2.41372673e-05, 2.44784857e-05, 2.44019114e-05, 2.45065146e-05, - 2.45536903e-05, - 2.54588387e-05, 3.12414073e-05, 3.25384795e-05, 2.98403992e-05, - 2.53399859e-05, 2.09295296e-05, 1.86846850e-05, 1.85180949e-05, - 1.86486539e-05, 2.46869813e-05, 2.82997827e-05, 2.72138084e-05, - 2.50950717e-05, 2.47476225e-05, 2.40667603e-05, 2.11544956e-05, - 1.88215863e-05, 1.90733076e-05, 1.94356768e-05, 1.84432533e-05, - 2.69146360e-05, 3.05999429e-05, 3.00958176e-05, 2.61755924e-05, - 2.39791647e-05, 2.33387862e-05, 2.02073056e-05, 1.75109422e-05, - 1.67158757e-05, 3.02046807e-05, 3.65098372e-05, 3.40458532e-05, - 2.48520548e-05, 1.91115172e-05, 1.83342511e-05, 1.81874229e-05, - 1.76759603e-05, 1.75806620e-05, 2.42522674e-05, 3.09747473e-05, - 3.28697933e-05, 2.71998332e-05, 2.23545416e-05, 2.22329668e-05, - 2.24974103e-05, 2.02802772e-05, 1.79104050e-05, 1.93481446e-05, - 2.42370262e-05, 3.26740632e-05, 3.63971112e-05, 3.27069342e-05, - 2.50580282e-05, 1.83822965e-05, 1.63354686e-05, 1.69994888e-05, - 2.94919115e-05, 3.47950238e-05, 3.35264207e-05, 2.76406243e-05, - 2.10099248e-05, 1.69103549e-05, 1.59659767e-05, 1.71753679e-05, - 3.14343450e-05, 3.59646819e-05, 3.37001651e-05, 2.68722368e-05, - 1.89098727e-05, 1.58864413e-05, 1.67512202e-05, 1.78580082e-05, - 3.26611311e-05, 3.78158924e-05, 3.21747873e-05, 2.47679538e-05, - 2.15289117e-05, 1.99198695e-05, 1.85895830e-05, 2.76932174e-05, - 3.12385014e-05, 3.18239809e-05, 2.99167392e-05, 2.38752645e-05, - 1.86402729e-05, 1.76117775e-05, 1.80905267e-05, 2.67206268e-05, - 3.01600576e-05, 2.99377392e-05, 2.73694222e-05, 2.50738042e-05, - 2.30492633e-05, 1.96651458e-05, 1.82372303e-05, 2.58055704e-05, - 3.02035851e-05, 3.00446532e-05, 2.84866040e-05, 2.70253953e-05, - 2.34702613e-05, 1.97646027e-05, 1.79410939e-05, 1.80358163e-05, - 2.37304614e-05, 3.10397681e-05, 3.71283194e-05, 3.55294131e-05, - 2.80309298e-05, 1.95182833e-05, 1.73676490e-05, 1.96761777e-05, - 2.90365279e-05, 3.26813621e-05, 2.97136783e-05, 2.45662752e-05, - 2.31471596e-05, 2.17202150e-05, 1.90202075e-05, 1.82795508e-05, - 2.35368222e-05, 2.94410338e-05, 3.30893932e-05, 2.93955221e-05, - 2.47528308e-05, 2.06095722e-05, 1.83403302e-05, 1.83377838e-05, - 2.54566696e-05, 3.01980148e-05, 3.09098215e-05, 2.76851741e-05, - 2.39696360e-05, 2.10987736e-05, 1.82763961e-05, 1.88963915e-05, - 2.00594715e-05, 2.53820140e-05, 3.25493388e-05, 3.54740458e-05, - 3.01565472e-05, 2.26990205e-05, 1.88558650e-05, 1.67121637e-05, - 1.64822948e-05, 1.76337795e-05, 2.75951648e-05, 3.11355283e-05, - 3.13083170e-05, 2.64954566e-05, 2.08599952e-05, 2.09965837e-05, - 1.94903021e-05, 1.72195198e-05, 2.69611099e-05, 3.03533085e-05, - 3.05463044e-05, 2.92407214e-05, 2.64463909e-05, 2.12131797e-05, - 1.88279305e-05, 1.94600554e-05, 2.96328254e-05, 3.48832010e-05, - 3.23236228e-05, 2.45021659e-05, 1.83768783e-05, 1.82168325e-05, - 1.89369523e-05, 2.51221005e-05, 2.97324537e-05, 3.23875020e-05, - 3.08544867e-05, 2.57932102e-05, 2.20664868e-05, 1.97825752e-05, - 1.76449972e-05, - 2.55565513e-05, 2.63912133e-05, 2.64363849e-05, 2.57626593e-05, - 2.47158846e-05, 2.38061291e-05, 2.31357118e-05, 2.32406273e-05, - 2.35519903e-05, 2.55096878e-05, 2.62481253e-05, 2.61288671e-05, - 2.54157937e-05, 2.52834923e-05, 2.51478744e-05, 2.39405386e-05, - 2.30082431e-05, 2.34355853e-05, 2.38100734e-05, 2.34157976e-05, - 2.56296950e-05, 2.61505532e-05, 2.64326511e-05, 2.54599367e-05, - 2.47644060e-05, 2.50375622e-05, 2.41483020e-05, 2.28537631e-05, - 2.24364666e-05, 2.61792270e-05, 2.60482662e-05, 2.63567257e-05, - 2.45942715e-05, 2.24480665e-05, 2.28583043e-05, 2.33275861e-05, - 2.30704848e-05, 2.29906726e-05, 2.42208134e-05, 2.53377601e-05, - 2.60630780e-05, 2.53732038e-05, 2.42310264e-05, 2.48870684e-05, - 2.54554100e-05, 2.45486147e-05, 2.33405257e-05, 2.29005009e-05, - 2.43587830e-05, 2.62170505e-05, 2.64830932e-05, 2.64531937e-05, - 2.52760089e-05, 2.30713969e-05, 2.23515031e-05, 2.27993665e-05, - 2.64481210e-05, 2.60661134e-05, 2.59108491e-05, 2.52514882e-05, - 2.35897331e-05, 2.20736415e-05, 2.18391539e-05, 2.27430342e-05, - 2.68982620e-05, 2.59355595e-05, 2.57133957e-05, 2.51834560e-05, - 2.28278244e-05, 2.17269169e-05, 2.25948000e-05, 2.31683363e-05, - 2.61521369e-05, 2.54698814e-05, 2.54889240e-05, 2.42093046e-05, - 2.40916245e-05, 2.44602104e-05, 2.38986007e-05, 2.55622213e-05, - 2.54288902e-05, 2.57038865e-05, 2.62938093e-05, 2.55150266e-05, - 2.34583204e-05, 2.30106320e-05, 2.32766893e-05, 2.53979899e-05, - 2.55353790e-05, 2.56013603e-05, 2.54241970e-05, 2.55216366e-05, - 2.55298973e-05, 2.41516095e-05, 2.33458012e-05, 2.52394616e-05, - 2.58847523e-05, 2.59278832e-05, 2.54722971e-05, 2.55532052e-05, - 2.52721228e-05, 2.41419303e-05, 2.32317076e-05, 2.32511299e-05, - 2.34411908e-05, 2.44723759e-05, 2.55712763e-05, 2.67052716e-05, - 2.69818412e-05, 2.43317278e-05, 2.30465522e-05, 2.45312423e-05, - 2.57565885e-05, 2.53938041e-05, 2.53490398e-05, 2.46181671e-05, - 2.46702966e-05, 2.47462618e-05, 2.36853806e-05, 2.33064461e-05, - 2.34891578e-05, 2.51128575e-05, 2.62261287e-05, 2.61170476e-05, - 2.53304309e-05, 2.43702319e-05, 2.35101518e-05, 2.33538287e-05, - 2.52866951e-05, 2.57960887e-05, 2.58426329e-05, 2.52391178e-05, - 2.45590391e-05, 2.41552246e-05, 2.32282815e-05, 2.37766773e-05, - 2.45611000e-05, 2.47470060e-05, 2.58003172e-05, 2.64240923e-05, - 2.63728343e-05, 2.44146671e-05, 2.30757826e-05, 2.24190564e-05, - 2.24145469e-05, 2.30598599e-05, 2.47540754e-05, 2.45781295e-05, - 2.53235475e-05, 2.53307442e-05, 2.43237127e-05, 2.54523580e-05, - 2.47759677e-05, 2.31041632e-05, 2.58565725e-05, 2.53848314e-05, - 2.51966842e-05, 2.56337207e-05, 2.57199716e-05, 2.41531897e-05, - 2.33506204e-05, 2.40667588e-05, 2.49119174e-05, 2.48336876e-05, - 2.60385299e-05, 2.56070091e-05, 2.33491097e-05, 2.33110751e-05, - 2.38079706e-05, 2.46172601e-05, 2.51294416e-05, 2.57064899e-05, - 2.61698017e-05, 2.60303937e-05, 2.52460664e-05, 2.42095699e-05, - 2.29787676e-05, - 2.53696320e-05, 3.21391051e-05, 3.37166482e-05, 3.04859247e-05, - 2.52687023e-05, 2.03371411e-05, 1.79023541e-05, 1.77185979e-05, - 1.78503197e-05, 2.44893872e-05, 2.86388852e-05, 2.73737575e-05, - 2.49587367e-05, 2.45673152e-05, 2.37986298e-05, 2.05811695e-05, - 1.80550508e-05, 1.83146728e-05, 1.86972256e-05, 1.76322785e-05, - 2.70468874e-05, 3.13770376e-05, 3.07596737e-05, 2.61982765e-05, - 2.37144574e-05, 2.29802528e-05, 1.95301250e-05, 1.66453058e-05, - 1.58075909e-05, 3.09015121e-05, 3.87300727e-05, 3.55856401e-05, - 2.47151974e-05, 1.83899990e-05, 1.75318294e-05, 1.73587478e-05, - 1.68160127e-05, 1.67160676e-05, 2.40474859e-05, 3.18700874e-05, - 3.41425331e-05, 2.73900861e-05, 2.19059328e-05, 2.17460967e-05, - 2.20218960e-05, 1.95974182e-05, 1.70600596e-05, 1.86320929e-05, - 2.40241529e-05, 3.38939081e-05, 3.85622750e-05, 3.39226361e-05, - 2.49220029e-05, 1.75770113e-05, 1.54055016e-05, 1.60996770e-05, - 3.00391627e-05, 3.65406519e-05, 3.49623508e-05, 2.79105223e-05, - 2.04339987e-05, 1.60258078e-05, 1.50281678e-05, 1.62891694e-05, - 3.23496912e-05, 3.80344273e-05, 3.51890639e-05, 2.70174240e-05, - 1.81570411e-05, 1.49471599e-05, 1.58407447e-05, 1.70087482e-05, - 3.38813031e-05, 4.04698784e-05, 3.33204396e-05, 2.46361780e-05, - 2.09908836e-05, 1.92055397e-05, 1.77761472e-05, 2.79576984e-05, - 3.21842090e-05, 3.28805970e-05, 3.05520143e-05, 2.35680944e-05, - 1.78441073e-05, 1.67488707e-05, 1.72558205e-05, 2.68317379e-05, - 3.08795606e-05, 3.06101869e-05, 2.75855561e-05, 2.49302373e-05, - 2.26371722e-05, 1.89368012e-05, 1.74119241e-05, 2.57810970e-05, - 3.09142576e-05, 3.07219550e-05, 2.88938544e-05, 2.71789668e-05, - 2.31197488e-05, 1.90457003e-05, 1.70962528e-05, 1.71976456e-05, - 2.34896624e-05, 3.19985977e-05, 3.95603377e-05, 3.74390069e-05, - 2.82940359e-05, 1.87711850e-05, 1.64861760e-05, 1.89373454e-05, - 2.95302735e-05, 3.39470893e-05, 3.03554253e-05, 2.43879504e-05, - 2.27783984e-05, 2.11801966e-05, 1.82490974e-05, 1.74587756e-05, - 2.32678891e-05, 3.00427175e-05, 3.44049299e-05, 2.99394059e-05, - 2.45713959e-05, 1.99648573e-05, 1.75182851e-05, 1.75202131e-05, - 2.53781417e-05, 3.09119348e-05, 3.17652862e-05, 2.79632605e-05, - 2.37120266e-05, 2.05118637e-05, 1.74577429e-05, 1.81119327e-05, - 1.93551508e-05, 2.53155683e-05, 3.37623830e-05, 3.73821598e-05, - 3.08349969e-05, 2.22847393e-05, 1.80900552e-05, 1.58041353e-05, - 1.55596816e-05, 1.67710437e-05, 2.78814791e-05, 3.21081782e-05, - 3.22745596e-05, 2.65736806e-05, 2.02423203e-05, 2.03573225e-05, - 1.87278397e-05, 1.63261237e-05, 2.70912219e-05, 3.11191321e-05, - 3.13611670e-05, 2.97783017e-05, 2.65002810e-05, 2.06385432e-05, - 1.80508625e-05, 1.87157815e-05, 3.02820489e-05, 3.67253406e-05, - 3.34732179e-05, 2.42754085e-05, 1.75625804e-05, 1.73909608e-05, - 1.81549800e-05, 2.50232155e-05, 3.03893006e-05, 3.35689415e-05, - 3.16824793e-05, 2.57348760e-05, 2.15484021e-05, 1.90632237e-05, - 1.67854657e-05, - 2.54682908e-05, 3.09367826e-05, 3.21461012e-05, 2.96530631e-05, - 2.53956376e-05, 2.11265803e-05, 1.89320285e-05, 1.87620372e-05, - 1.88791344e-05, 2.47229362e-05, 2.81608685e-05, 2.71286591e-05, - 2.51232770e-05, 2.47930032e-05, 2.41380517e-05, 2.13423750e-05, - 1.90733861e-05, 1.93057952e-05, 1.96495922e-05, 1.86804377e-05, - 2.68681089e-05, 3.03480097e-05, 2.98555145e-05, 2.61654820e-05, - 2.40713469e-05, 2.34339180e-05, 2.03987876e-05, 1.77736775e-05, - 1.69947050e-05, 2.99733309e-05, 3.58083585e-05, 3.35460068e-05, - 2.49284667e-05, 1.93847187e-05, 1.85945849e-05, 1.84293717e-05, - 1.79298239e-05, 1.78378766e-05, 2.43635577e-05, 3.07495443e-05, - 3.24781044e-05, 2.71557046e-05, 2.25087421e-05, 2.23594066e-05, - 2.25920583e-05, 2.04535583e-05, 1.81528631e-05, 1.96009112e-05, - 2.43420443e-05, 3.22862902e-05, 3.56744928e-05, 3.23016490e-05, - 2.50943877e-05, 1.86337804e-05, 1.66166169e-05, 1.72646013e-05, - 2.92831280e-05, 3.42529636e-05, 3.30966276e-05, 2.75850973e-05, - 2.12153726e-05, 1.72035053e-05, 1.62649605e-05, 1.74426971e-05, - 3.10862398e-05, 3.53256716e-05, 3.32701631e-05, 2.68508918e-05, - 1.91685868e-05, 1.61892162e-05, 1.70240146e-05, 1.81075148e-05, - 3.22784180e-05, 3.70153618e-05, 3.18665660e-05, 2.48657136e-05, - 2.17042125e-05, 2.01012897e-05, 1.88062116e-05, 2.76187305e-05, - 3.09923610e-05, 3.15251184e-05, 2.96943996e-05, 2.39338566e-05, - 1.88746433e-05, 1.78681451e-05, 1.83349128e-05, 2.66937602e-05, - 2.99688452e-05, 2.97545862e-05, 2.73157616e-05, 2.50973606e-05, - 2.31279303e-05, 1.98624535e-05, 1.84782307e-05, 2.58196262e-05, - 2.99896164e-05, 2.98368120e-05, 2.83821921e-05, 2.69785942e-05, - 2.35509916e-05, 1.99613013e-05, 1.81878108e-05, 1.82814317e-05, - 2.38920248e-05, 3.08616462e-05, 3.63974683e-05, 3.48758353e-05, - 2.78633690e-05, 1.97094271e-05, 1.76229659e-05, 1.98572452e-05, - 2.88902929e-05, 3.23452336e-05, 2.95567063e-05, 2.46496851e-05, - 2.32641698e-05, 2.18627576e-05, 1.92427097e-05, 1.85219587e-05, - 2.37005939e-05, 2.93112341e-05, 3.26713700e-05, 2.92108407e-05, - 2.47957272e-05, 2.07862946e-05, 1.85741921e-05, 1.85780047e-05, - 2.54798743e-05, 2.99895431e-05, 3.06583310e-05, 2.76284597e-05, - 2.40719666e-05, 2.12779782e-05, 1.85219837e-05, 1.91160036e-05, - 2.02349333e-05, 2.54347908e-05, 3.21966824e-05, 3.48461146e-05, - 2.99164218e-05, 2.28377932e-05, 1.91046796e-05, 1.69916557e-05, - 1.67614595e-05, 1.78881528e-05, 2.75681147e-05, 3.09457587e-05, - 3.10643121e-05, 2.64804933e-05, 2.10352618e-05, 2.11197818e-05, - 1.96629336e-05, 1.74727144e-05, 2.69007097e-05, 3.01603514e-05, - 3.03536848e-05, 2.90914076e-05, 2.64129036e-05, 2.13907407e-05, - 1.90655913e-05, 1.96629414e-05, 2.95047860e-05, 3.44171563e-05, - 3.19712567e-05, 2.45387434e-05, 1.86171052e-05, 1.84593250e-05, - 1.91549788e-05, 2.51893622e-05, 2.95870363e-05, 3.20516879e-05, - 3.05866000e-05, 2.57670824e-05, 2.21797241e-05, 1.99762054e-05, - 1.79025646e-05, - 2.50269610e-05, 2.33411774e-05, 2.28389974e-05, 2.37163826e-05, - 2.48453644e-05, 2.56060860e-05, 2.57743368e-05, 2.58248238e-05, - 2.58925007e-05, 2.52185536e-05, 2.43425802e-05, 2.46557316e-05, - 2.50902748e-05, 2.51485041e-05, 2.52858379e-05, 2.56013417e-05, - 2.57196127e-05, 2.58052765e-05, 2.58544897e-05, 2.58814052e-05, - 2.46315097e-05, 2.35306745e-05, 2.37714529e-05, 2.48052429e-05, - 2.52092857e-05, 2.54311657e-05, 2.58238473e-05, 2.58292844e-05, - 2.57802026e-05, 2.36798908e-05, 2.09418868e-05, 2.21812689e-05, - 2.49422290e-05, 2.55079032e-05, 2.57398372e-05, 2.58875312e-05, - 2.58724699e-05, 2.58601313e-05, 2.49919085e-05, 2.32063152e-05, - 2.26292499e-05, 2.44835983e-05, 2.54389717e-05, 2.56354551e-05, - 2.57148574e-05, 2.59122436e-05, 2.59207419e-05, 2.56113318e-05, - 2.50349248e-05, 2.27408668e-05, 2.10667064e-05, 2.27730149e-05, - 2.50658534e-05, 2.57945684e-05, 2.57816434e-05, 2.58589526e-05, - 2.39865845e-05, 2.17876069e-05, 2.23218501e-05, 2.43178958e-05, - 2.55294815e-05, 2.56590270e-05, 2.56558803e-05, 2.58291696e-05, - 2.33627375e-05, 2.12012863e-05, 2.22059148e-05, 2.45338727e-05, - 2.56543521e-05, 2.56268957e-05, 2.58217095e-05, 2.58804386e-05, - 2.27331666e-05, 2.01347387e-05, 2.27840193e-05, 2.48557397e-05, - 2.55705876e-05, 2.59470337e-05, 2.59884580e-05, 2.43785735e-05, - 2.31301678e-05, 2.29708601e-05, 2.38064574e-05, 2.54202140e-05, - 2.58686546e-05, 2.58625435e-05, 2.58846946e-05, 2.46326321e-05, - 2.35499886e-05, 2.36443761e-05, 2.44446880e-05, 2.51212282e-05, - 2.56133076e-05, 2.59088786e-05, 2.58867614e-05, 2.48545452e-05, - 2.36157741e-05, 2.36820275e-05, 2.41041958e-05, 2.45801728e-05, - 2.54580598e-05, 2.58916083e-05, 2.58887443e-05, 2.58838196e-05, - 2.48872114e-05, 2.29534546e-05, 2.05333770e-05, 2.15414717e-05, - 2.45741755e-05, 2.59746219e-05, 2.58947887e-05, 2.59999645e-05, - 2.39905427e-05, 2.25592823e-05, 2.36612148e-05, 2.50229216e-05, - 2.53813735e-05, 2.57037568e-05, 2.58796505e-05, 2.58713648e-05, - 2.49498331e-05, 2.36950742e-05, 2.25703118e-05, 2.39500462e-05, - 2.51586528e-05, 2.58133793e-05, 2.59183755e-05, 2.58773106e-05, - 2.49620181e-05, 2.35976236e-05, 2.33491812e-05, 2.43009011e-05, - 2.51567437e-05, 2.56700773e-05, 2.58505776e-05, 2.59197239e-05, - 2.59500076e-05, 2.48423943e-05, 2.27048031e-05, 2.15260182e-05, - 2.37375626e-05, 2.54140038e-05, 2.57343604e-05, 2.57755684e-05, - 2.57901182e-05, 2.58737308e-05, 2.42004268e-05, 2.29477408e-05, - 2.30782962e-05, 2.46816614e-05, 2.57577300e-05, 2.59996184e-05, - 2.60822497e-05, 2.59225104e-05, 2.46706370e-05, 2.34443723e-05, - 2.33278634e-05, 2.38927570e-05, 2.47897992e-05, 2.56481091e-05, - 2.58152595e-05, 2.59172180e-05, 2.35762845e-05, 2.14831247e-05, - 2.28465670e-05, 2.52880907e-05, 2.58714473e-05, 2.58797957e-05, - 2.59225262e-05, 2.48770563e-05, 2.35990080e-05, 2.27492191e-05, - 2.34409640e-05, 2.50440568e-05, 2.57550309e-05, 2.59059578e-05, - 2.58506032e-05, - 2.41845161e-05, 2.01565204e-05, 1.92181524e-05, 2.14414131e-05, - 2.47769053e-05, 2.74774872e-05, 2.87251573e-05, 2.86817684e-05, - 2.83949077e-05, 2.46141935e-05, 2.21412213e-05, 2.28550990e-05, - 2.44662380e-05, 2.47314540e-05, 2.51616594e-05, 2.72919587e-05, - 2.87909546e-05, 2.83790815e-05, 2.79782269e-05, 2.85553879e-05, - 2.33312658e-05, 2.07237015e-05, 2.09020384e-05, 2.38548284e-05, - 2.54588654e-05, 2.55824090e-05, 2.74762944e-05, 2.92179657e-05, - 2.96992618e-05, 2.09718439e-05, 1.62814931e-05, 1.81350957e-05, - 2.51173410e-05, 2.91451096e-05, 2.90399532e-05, 2.86854143e-05, - 2.90033087e-05, 2.90884949e-05, 2.56707404e-05, 2.08958694e-05, - 1.91693093e-05, 2.33174277e-05, 2.65842060e-05, 2.61729271e-05, - 2.56553067e-05, 2.71431003e-05, 2.87302913e-05, 2.87185593e-05, - 2.55909006e-05, 1.92340016e-05, 1.61661338e-05, 1.90871489e-05, - 2.45755102e-05, 2.88534766e-05, 2.98139316e-05, 2.93435404e-05, - 2.12832549e-05, 1.76930581e-05, 1.87546702e-05, 2.31234082e-05, - 2.76043735e-05, 2.99909701e-05, 3.03076092e-05, 2.93681996e-05, - 1.97452830e-05, 1.67992969e-05, 1.87189160e-05, 2.36228459e-05, - 2.89096032e-05, 3.04156166e-05, 2.95546924e-05, 2.88861820e-05, - 1.92768850e-05, 1.53813920e-05, 1.99658669e-05, 2.54024895e-05, - 2.70332573e-05, 2.73226658e-05, 2.81226600e-05, 2.29113803e-05, - 2.06648337e-05, 2.01103267e-05, 2.10971252e-05, 2.50060851e-05, - 2.84736933e-05, 2.90659227e-05, 2.87483945e-05, 2.35831026e-05, - 2.13509669e-05, 2.14643681e-05, 2.31865319e-05, 2.44088690e-05, - 2.53694106e-05, 2.76411586e-05, 2.86595101e-05, 2.41965766e-05, - 2.11339917e-05, 2.12161044e-05, 2.24742814e-05, 2.33129965e-05, - 2.53608244e-05, 2.76195332e-05, 2.88164373e-05, 2.87811040e-05, - 2.64364356e-05, 2.12765517e-05, 1.59612919e-05, 1.67813272e-05, - 2.18569555e-05, 2.75391868e-05, 2.90754779e-05, 2.73361537e-05, - 2.19662850e-05, 1.96408791e-05, 2.17486107e-05, 2.52536814e-05, - 2.59221577e-05, 2.64818739e-05, 2.81926703e-05, 2.86829912e-05, - 2.65077698e-05, 2.20551578e-05, 1.89238292e-05, 2.15336559e-05, - 2.46982257e-05, 2.71716052e-05, 2.85002056e-05, 2.86306631e-05, - 2.43570526e-05, 2.11857449e-05, 2.06784023e-05, 2.31033508e-05, - 2.55982706e-05, 2.71558025e-05, 2.87485929e-05, 2.81504352e-05, - 2.72015801e-05, 2.47345880e-05, 1.95374153e-05, 1.69684624e-05, - 2.08958132e-05, 2.63028833e-05, 2.87273646e-05, 2.97151351e-05, - 2.97439692e-05, 2.90199352e-05, 2.34336973e-05, 2.11576897e-05, - 2.06689853e-05, 2.37531018e-05, 2.71187093e-05, 2.62134130e-05, - 2.71887152e-05, 2.90468725e-05, 2.31667440e-05, 2.12996510e-05, - 2.12649353e-05, 2.19037025e-05, 2.35426671e-05, 2.71134898e-05, - 2.85137368e-05, 2.77670915e-05, 2.20329427e-05, 1.81907209e-05, - 1.95803854e-05, 2.46418652e-05, 2.86257333e-05, 2.86928772e-05, - 2.81147730e-05, 2.49571432e-05, 2.18524550e-05, 1.97026692e-05, - 2.05410165e-05, 2.37033256e-05, 2.59805306e-05, 2.75609018e-05, - 2.90871512e-05, - 2.47114630e-05, 2.23987932e-05, 2.17656309e-05, 2.35141739e-05, - 2.55674697e-05, 2.63698812e-05, 2.64902641e-05, 2.63039324e-05, - 2.59972777e-05, 2.48169754e-05, 2.35283578e-05, 2.38889797e-05, - 2.48850016e-05, 2.50425221e-05, 2.52065642e-05, 2.62635095e-05, - 2.66889873e-05, 2.62873748e-05, 2.59838735e-05, 2.60715611e-05, - 2.44302149e-05, 2.28768188e-05, 2.28053426e-05, 2.47194790e-05, - 2.56027791e-05, 2.53152176e-05, 2.58293182e-05, 2.63059321e-05, - 2.63771370e-05, 2.29993777e-05, 1.96337972e-05, 2.10226014e-05, - 2.57358470e-05, 2.74418280e-05, 2.66741627e-05, 2.60657575e-05, - 2.61314708e-05, 2.61788698e-05, 2.61564659e-05, 2.34648230e-05, - 2.19282157e-05, 2.46232978e-05, 2.61069806e-05, 2.53964784e-05, - 2.48257605e-05, 2.54074336e-05, 2.59269067e-05, 2.69926144e-05, - 2.60143924e-05, 2.18923675e-05, 1.93504524e-05, 2.16667031e-05, - 2.50286554e-05, 2.64452462e-05, 2.62513956e-05, 2.61024478e-05, - 2.29954837e-05, 2.08154380e-05, 2.17078662e-05, 2.46432498e-05, - 2.66240083e-05, 2.69272273e-05, 2.66428421e-05, 2.62647875e-05, - 2.18586726e-05, 2.01330307e-05, 2.17810705e-05, 2.48736261e-05, - 2.69301573e-05, 2.67292978e-05, 2.62069239e-05, 2.61031202e-05, - 2.19563228e-05, 1.90440290e-05, 2.27846369e-05, 2.61360871e-05, - 2.61594689e-05, 2.54064997e-05, 2.55787477e-05, 2.43318456e-05, - 2.32695344e-05, 2.27598285e-05, 2.29963888e-05, 2.48317131e-05, - 2.61013821e-05, 2.61706253e-05, 2.60823689e-05, 2.46919008e-05, - 2.36080835e-05, 2.36286872e-05, 2.45378571e-05, 2.47802662e-05, - 2.47913401e-05, 2.56730891e-05, 2.60661263e-05, 2.49883750e-05, - 2.32705880e-05, 2.32888823e-05, 2.42138658e-05, 2.44835207e-05, - 2.50758713e-05, 2.57137669e-05, 2.60675083e-05, 2.60877290e-05, - 2.69899819e-05, 2.42183453e-05, 1.95440109e-05, 1.97819058e-05, - 2.28984581e-05, 2.54267571e-05, 2.60059937e-05, 2.52555249e-05, - 2.37843517e-05, 2.26144284e-05, 2.39418277e-05, 2.57309269e-05, - 2.56919340e-05, 2.54816051e-05, 2.59840946e-05, 2.61296868e-05, - 2.69427885e-05, 2.42556621e-05, 2.16697072e-05, 2.33346457e-05, - 2.49946876e-05, 2.56826356e-05, 2.59202941e-05, 2.60994153e-05, - 2.49814284e-05, 2.33541823e-05, 2.30338132e-05, 2.46446049e-05, - 2.58153985e-05, 2.60185025e-05, 2.62189152e-05, 2.58354031e-05, - 2.53348185e-05, 2.55315513e-05, 2.23236767e-05, 2.00612435e-05, - 2.28387012e-05, 2.59380149e-05, 2.66233415e-05, 2.63960111e-05, - 2.62651636e-05, 2.61235127e-05, 2.51342577e-05, 2.40808357e-05, - 2.33338838e-05, 2.47968202e-05, 2.57878109e-05, 2.45992247e-05, - 2.49267225e-05, 2.58607229e-05, 2.42009282e-05, 2.36729501e-05, - 2.37691221e-05, 2.38354659e-05, 2.44226207e-05, 2.60412778e-05, - 2.62964278e-05, 2.57035071e-05, 2.43759527e-05, 2.18028837e-05, - 2.22243561e-05, 2.47267738e-05, 2.61211457e-05, 2.60975658e-05, - 2.58148560e-05, 2.56891880e-05, 2.41387691e-05, 2.24874496e-05, - 2.27587729e-05, 2.42054753e-05, 2.49974618e-05, 2.56438775e-05, - 2.62242487e-05, - 2.48932424e-05, 2.32564789e-05, 2.27564771e-05, 2.41616966e-05, - 2.56163408e-05, 2.58622583e-05, 2.56898576e-05, 2.55139840e-05, - 2.52768872e-05, 2.49190412e-05, 2.40774337e-05, 2.43168838e-05, - 2.50120464e-05, 2.51173690e-05, 2.51973866e-05, 2.57984774e-05, - 2.58719152e-05, 2.55717248e-05, 2.53645341e-05, 2.53118291e-05, - 2.47642314e-05, 2.36448794e-05, 2.35534319e-05, 2.49574966e-05, - 2.55266460e-05, 2.52225889e-05, 2.53275266e-05, 2.53792684e-05, - 2.53233615e-05, 2.37306969e-05, 2.09761863e-05, 2.21540886e-05, - 2.57179331e-05, 2.65302830e-05, 2.57953286e-05, 2.52733121e-05, - 2.52584335e-05, 2.52843424e-05, 2.60212646e-05, 2.41827809e-05, - 2.29166429e-05, 2.49520629e-05, 2.57952606e-05, 2.51831828e-05, - 2.47253030e-05, 2.49823292e-05, 2.51214030e-05, 2.61904018e-05, - 2.58995369e-05, 2.28758356e-05, 2.07136496e-05, 2.26757372e-05, - 2.51320101e-05, 2.56128754e-05, 2.51635713e-05, 2.51393621e-05, - 2.36854637e-05, 2.19952934e-05, 2.27481542e-05, 2.50010657e-05, - 2.60835463e-05, 2.58020220e-05, 2.54259849e-05, 2.52979883e-05, - 2.27861090e-05, 2.14155348e-05, 2.28207552e-05, 2.51436609e-05, - 2.60824961e-05, 2.54837567e-05, 2.51890722e-05, 2.52599336e-05, - 2.29322956e-05, 2.04672552e-05, 2.36449809e-05, 2.60504690e-05, - 2.57523216e-05, 2.49399633e-05, 2.49215850e-05, 2.47352827e-05, - 2.40253137e-05, 2.36058632e-05, 2.37114388e-05, 2.48600970e-05, - 2.53621438e-05, 2.52818586e-05, 2.52741346e-05, 2.49756471e-05, - 2.42627033e-05, 2.42677364e-05, 2.48905516e-05, 2.49204258e-05, - 2.47491878e-05, 2.51330174e-05, 2.52802238e-05, 2.51592345e-05, - 2.39691966e-05, 2.39760798e-05, 2.46871124e-05, 2.48184958e-05, - 2.50312710e-05, 2.51788701e-05, 2.52417710e-05, 2.52712342e-05, - 2.66748395e-05, 2.48451801e-05, 2.09101293e-05, 2.10820625e-05, - 2.35078402e-05, 2.49094797e-05, 2.51121994e-05, 2.47848224e-05, - 2.43487083e-05, 2.35181360e-05, 2.45280154e-05, 2.56885825e-05, - 2.55238551e-05, 2.52022721e-05, 2.53131895e-05, 2.53384193e-05, - 2.66164093e-05, 2.47847142e-05, 2.26954078e-05, 2.39775465e-05, - 2.50768894e-05, 2.52506722e-05, 2.51730194e-05, 2.53210559e-05, - 2.51248257e-05, 2.40422860e-05, 2.38002431e-05, 2.50053964e-05, - 2.57062652e-05, 2.55870322e-05, 2.54117988e-05, 2.51739768e-05, - 2.48960348e-05, 2.55892299e-05, 2.32541293e-05, 2.13348583e-05, - 2.35863333e-05, 2.56877792e-05, 2.58221159e-05, 2.53382679e-05, - 2.51969270e-05, 2.52460576e-05, 2.54212125e-05, 2.47304678e-05, - 2.40855628e-05, 2.50488918e-05, 2.53670039e-05, 2.43795668e-05, - 2.44870278e-05, 2.49716798e-05, 2.45692307e-05, 2.43306218e-05, - 2.44257288e-05, 2.44061569e-05, 2.47224464e-05, 2.56187459e-05, - 2.55479642e-05, 2.51337426e-05, 2.49010952e-05, 2.28850179e-05, - 2.31553019e-05, 2.48257790e-05, 2.53441885e-05, 2.53035330e-05, - 2.51619899e-05, 2.57015731e-05, 2.47008278e-05, 2.33919478e-05, - 2.35545824e-05, 2.44841462e-05, 2.48282599e-05, 2.51225741e-05, - 2.53306487e-05, - 2.46595160e-05, 2.15003119e-05, 2.07212922e-05, 2.19566447e-05, - 2.40751836e-05, 2.64241620e-05, 2.75463727e-05, 2.77830008e-05, - 2.79752194e-05, 2.51550541e-05, 2.32787122e-05, 2.39079233e-05, - 2.47988003e-05, 2.49336013e-05, 2.52990566e-05, 2.63765634e-05, - 2.73126043e-05, 2.75214253e-05, 2.75845826e-05, 2.80128783e-05, - 2.37379835e-05, 2.17444279e-05, 2.22496727e-05, 2.41005222e-05, - 2.50461476e-05, 2.57248803e-05, 2.72883054e-05, 2.82376101e-05, - 2.84942595e-05, 2.20117164e-05, 1.80492547e-05, 1.97428200e-05, - 2.43055595e-05, 2.65340480e-05, 2.75600920e-05, 2.81383988e-05, - 2.83134496e-05, 2.83147816e-05, 2.44040926e-05, 2.09655916e-05, - 2.02868648e-05, 2.33584634e-05, 2.57488421e-05, 2.64024994e-05, - 2.66829393e-05, 2.75912192e-05, 2.83810960e-05, 2.67905553e-05, - 2.45302573e-05, 2.05022687e-05, 1.83482113e-05, 2.06271711e-05, - 2.47139422e-05, 2.77295536e-05, 2.87378457e-05, 2.86180268e-05, - 2.26457282e-05, 1.91148076e-05, 1.97936313e-05, 2.29818332e-05, - 2.61663335e-05, 2.79538965e-05, 2.85273073e-05, 2.84110368e-05, - 2.16991747e-05, 1.83253819e-05, 1.95676962e-05, 2.34282970e-05, - 2.70663881e-05, 2.84784595e-05, 2.86252000e-05, 2.82570892e-05, - 2.04699208e-05, 1.69308532e-05, 2.03418931e-05, 2.40445920e-05, - 2.62322140e-05, 2.77955398e-05, 2.83513098e-05, 2.31787409e-05, - 2.08674994e-05, 2.06948711e-05, 2.22706869e-05, 2.57308747e-05, - 2.78926917e-05, 2.83083401e-05, 2.81692701e-05, 2.36912583e-05, - 2.16005568e-05, 2.17841278e-05, 2.32863482e-05, 2.48964774e-05, - 2.63383141e-05, 2.77174496e-05, 2.81148787e-05, 2.41779851e-05, - 2.18134780e-05, 2.19422607e-05, 2.26039468e-05, 2.36077426e-05, - 2.58235763e-05, 2.76298220e-05, 2.82496773e-05, 2.81898185e-05, - 2.40909683e-05, 2.03233290e-05, 1.74117728e-05, 1.90137862e-05, - 2.39643741e-05, 2.79987738e-05, 2.85501333e-05, 2.80530675e-05, - 2.24585592e-05, 1.99762735e-05, 2.17461200e-05, 2.45198058e-05, - 2.55550655e-05, 2.66630439e-05, 2.78004136e-05, 2.80419721e-05, - 2.42654447e-05, 2.17460372e-05, 2.02527387e-05, 2.24818094e-05, - 2.49673428e-05, 2.71764096e-05, 2.81879527e-05, 2.80398183e-05, - 2.44504830e-05, 2.17564742e-05, 2.13466986e-05, 2.29439498e-05, - 2.48822248e-05, 2.66111098e-05, 2.79688728e-05, 2.79863702e-05, - 2.77757462e-05, 2.40720423e-05, 2.03167204e-05, 1.88968965e-05, - 2.21713864e-05, 2.56588136e-05, 2.73505714e-05, 2.84796406e-05, - 2.86744482e-05, 2.83384152e-05, 2.26342617e-05, 2.03416687e-05, - 2.07539480e-05, 2.37886880e-05, 2.69427705e-05, 2.78181665e-05, - 2.84215844e-05, 2.87333553e-05, 2.38760705e-05, 2.13771446e-05, - 2.11284289e-05, 2.22427140e-05, 2.41169883e-05, 2.65230853e-05, - 2.76375797e-05, 2.78028126e-05, 2.14830965e-05, 1.83260883e-05, - 2.06054849e-05, 2.53610183e-05, 2.80031593e-05, 2.80981406e-05, - 2.79828848e-05, 2.41418177e-05, 2.15783901e-05, 2.03547268e-05, - 2.15980597e-05, 2.47930494e-05, 2.68293601e-05, 2.76773066e-05, - 2.82489496e-05, - 2.53006859e-05, 2.42555422e-05, 2.38919358e-05, 2.39418170e-05, - 2.42326118e-05, 2.49023522e-05, 2.50787830e-05, 2.53224911e-05, - 2.57080501e-05, 2.55589677e-05, 2.51027882e-05, 2.53587941e-05, - 2.52621009e-05, 2.52289824e-05, 2.53343290e-05, 2.49839810e-05, - 2.48202859e-05, 2.53083197e-05, 2.56602450e-05, 2.56211685e-05, - 2.48223128e-05, 2.41703759e-05, 2.46946744e-05, 2.48858890e-05, - 2.48523940e-05, 2.55021184e-05, 2.57468844e-05, 2.53145461e-05, - 2.51542543e-05, 2.43395271e-05, 2.22663398e-05, 2.33328429e-05, - 2.42649593e-05, 2.38627446e-05, 2.48619124e-05, 2.56337476e-05, - 2.55427423e-05, 2.54786086e-05, 2.40085776e-05, 2.30447760e-05, - 2.33371167e-05, 2.43815885e-05, 2.48327747e-05, 2.57993711e-05, - 2.64681495e-05, 2.62848240e-05, 2.58102343e-05, 2.43927533e-05, - 2.41993717e-05, 2.35834459e-05, 2.27986432e-05, 2.38592608e-05, - 2.50904015e-05, 2.51482958e-05, 2.52555026e-05, 2.55324462e-05, - 2.49260179e-05, 2.27692739e-05, 2.29565387e-05, 2.40629426e-05, - 2.45598045e-05, 2.44952207e-05, 2.47019161e-05, 2.53437638e-05, - 2.48189664e-05, 2.22869258e-05, 2.26703878e-05, 2.42577677e-05, - 2.45124600e-05, 2.45796351e-05, 2.53722481e-05, 2.55841148e-05, - 2.35089232e-05, 2.12612419e-05, 2.28565679e-05, 2.37873034e-05, - 2.50187429e-05, 2.63464583e-05, 2.62516858e-05, 2.44433759e-05, - 2.30732279e-05, 2.32253626e-05, 2.45821376e-05, 2.59177843e-05, - 2.55751029e-05, 2.54904496e-05, 2.56129713e-05, 2.45941045e-05, - 2.35516473e-05, 2.37075674e-05, 2.43846431e-05, 2.54126652e-05, - 2.63124398e-05, 2.60341626e-05, 2.56327294e-05, 2.47408274e-05, - 2.39720778e-05, 2.40794452e-05, 2.40428541e-05, 2.46805895e-05, - 2.57652602e-05, 2.59675608e-05, 2.56309301e-05, 2.56060071e-05, - 2.31771114e-05, 2.19699136e-05, 2.15554400e-05, 2.33061765e-05, - 2.61546063e-05, 2.63748055e-05, 2.56861960e-05, 2.65802217e-05, - 2.42104820e-05, 2.25896064e-05, 2.34674397e-05, 2.44121771e-05, - 2.50836567e-05, 2.58458910e-05, 2.57008177e-05, 2.55509519e-05, - 2.33190225e-05, 2.32632266e-05, 2.34661854e-05, 2.45408580e-05, - 2.52898854e-05, 2.58601640e-05, 2.58177978e-05, 2.55884195e-05, - 2.49425055e-05, 2.38634331e-05, 2.36866119e-05, 2.40309579e-05, - 2.45790921e-05, 2.53131419e-05, 2.54374074e-05, 2.59017781e-05, - 2.64186435e-05, 2.42572179e-05, 2.31183081e-05, 2.29932199e-05, - 2.45985886e-05, 2.49314747e-05, 2.49003569e-05, 2.51301920e-05, - 2.52617286e-05, 2.55511882e-05, 2.34421979e-05, 2.20692393e-05, - 2.29227078e-05, 2.45923311e-05, 2.56686451e-05, 2.72119261e-05, - 2.70399286e-05, 2.58604860e-05, 2.51006404e-05, 2.33017618e-05, - 2.30074804e-05, 2.39844589e-05, 2.51217638e-05, 2.52551166e-05, - 2.53156105e-05, 2.60202000e-05, 2.29498065e-05, 2.13076703e-05, - 2.34762075e-05, 2.57693965e-05, 2.55597344e-05, 2.55928368e-05, - 2.59254418e-05, 2.41880237e-05, 2.31876470e-05, 2.30544958e-05, - 2.41094988e-05, 2.57952019e-05, 2.63815107e-05, 2.60560198e-05, - 2.54238727e-05, - 2.52550659e-05, 2.42568555e-05, 2.38996132e-05, 2.41583694e-05, - 2.45516209e-05, 2.49927159e-05, 2.50196561e-05, 2.51694786e-05, - 2.54270098e-05, 2.54392717e-05, 2.50134832e-05, 2.52329247e-05, - 2.52381110e-05, 2.52229815e-05, 2.53010321e-05, 2.50520758e-05, - 2.48571265e-05, 2.51900334e-05, 2.54361432e-05, 2.53589508e-05, - 2.48953362e-05, 2.42537607e-05, 2.46333079e-05, 2.49631692e-05, - 2.49848024e-05, 2.54148856e-05, 2.55234036e-05, 2.50988084e-05, - 2.49321114e-05, 2.43942518e-05, 2.23408499e-05, 2.33707550e-05, - 2.45826806e-05, 2.42333063e-05, 2.48573704e-05, 2.53514189e-05, - 2.52583964e-05, 2.52101352e-05, 2.44185013e-05, 2.34777687e-05, - 2.35040279e-05, 2.45929027e-05, 2.49712728e-05, 2.56034488e-05, - 2.60359117e-05, 2.58724120e-05, 2.54470369e-05, 2.45992363e-05, - 2.45470836e-05, 2.36852110e-05, 2.26991610e-05, 2.38611979e-05, - 2.51263652e-05, 2.50479175e-05, 2.49639547e-05, 2.52002633e-05, - 2.48258616e-05, 2.29114632e-05, 2.31843406e-05, 2.43619505e-05, - 2.47674538e-05, 2.45173338e-05, 2.45697321e-05, 2.50924419e-05, - 2.46023264e-05, 2.24370265e-05, 2.29760617e-05, 2.45233416e-05, - 2.46580557e-05, 2.44821543e-05, 2.50762145e-05, 2.52977543e-05, - 2.36377881e-05, 2.14696924e-05, 2.32517573e-05, 2.42621941e-05, - 2.50827812e-05, 2.58983815e-05, 2.57726994e-05, 2.46123596e-05, - 2.34763329e-05, 2.35291425e-05, 2.45732922e-05, 2.56818292e-05, - 2.53405267e-05, 2.52200278e-05, 2.53318088e-05, 2.47522180e-05, - 2.38770279e-05, 2.39962443e-05, 2.45878475e-05, 2.53368226e-05, - 2.59386083e-05, 2.56876666e-05, 2.53538873e-05, 2.48783791e-05, - 2.41530421e-05, 2.42351556e-05, 2.43071902e-05, 2.47976964e-05, - 2.55855852e-05, 2.56489895e-05, 2.53335890e-05, 2.53237553e-05, - 2.38559154e-05, 2.27387319e-05, 2.17795736e-05, 2.31552932e-05, - 2.57014517e-05, 2.58994022e-05, 2.53282584e-05, 2.60372026e-05, - 2.43872703e-05, 2.30258174e-05, 2.38505038e-05, 2.46855691e-05, - 2.51407981e-05, 2.56266291e-05, 2.54423446e-05, 2.53036146e-05, - 2.39541861e-05, 2.37299926e-05, 2.35656192e-05, 2.45819450e-05, - 2.52627477e-05, 2.56099100e-05, 2.54796341e-05, 2.53314292e-05, - 2.50203497e-05, 2.40816336e-05, 2.39111880e-05, 2.43385926e-05, - 2.48034888e-05, 2.52671529e-05, 2.52298148e-05, 2.55655490e-05, - 2.59499013e-05, 2.45671755e-05, 2.33914401e-05, 2.29641377e-05, - 2.45665099e-05, 2.50390945e-05, 2.49116448e-05, 2.49161822e-05, - 2.49813085e-05, 2.52608542e-05, 2.39461264e-05, 2.28004719e-05, - 2.33695366e-05, 2.47589874e-05, 2.54929593e-05, 2.64819797e-05, - 2.63194163e-05, 2.54286446e-05, 2.50757364e-05, 2.36961888e-05, - 2.34842584e-05, 2.42252406e-05, 2.51088474e-05, 2.52317699e-05, - 2.51821567e-05, 2.56696172e-05, 2.35057362e-05, 2.19246037e-05, - 2.36493762e-05, 2.55786427e-05, 2.53152260e-05, 2.53268234e-05, - 2.55829317e-05, 2.45262119e-05, 2.36608553e-05, 2.33644287e-05, - 2.41938320e-05, 2.55667083e-05, 2.59763136e-05, 2.57066599e-05, - 2.51793079e-05, - 2.56447366e-05, 2.82874889e-05, 2.87618915e-05, 2.73385016e-05, - 2.50079681e-05, 2.27458437e-05, 2.14196432e-05, 2.14202649e-05, - 2.16746365e-05, 2.53280895e-05, 2.71600892e-05, 2.66868870e-05, - 2.54127376e-05, 2.51925619e-05, 2.48465268e-05, 2.29225976e-05, - 2.13916546e-05, 2.17709570e-05, 2.21607936e-05, 2.15028667e-05, - 2.62216542e-05, 2.78875971e-05, 2.79244642e-05, 2.58359375e-05, - 2.45479984e-05, 2.44982237e-05, 2.26907764e-05, 2.07589480e-05, - 2.01627112e-05, 2.77735297e-05, 2.97737347e-05, 2.92052860e-05, - 2.47468986e-05, 2.11390736e-05, 2.10985422e-05, 2.13412361e-05, - 2.09655338e-05, 2.08751152e-05, 2.42682210e-05, 2.74019232e-05, - 2.85863285e-05, 2.61379938e-05, 2.35758702e-05, 2.39750761e-05, - 2.44613762e-05, 2.29835512e-05, 2.12351537e-05, 2.15295819e-05, - 2.43593568e-05, 2.86393712e-05, 3.00859480e-05, 2.88315665e-05, - 2.53010716e-05, 2.12557722e-05, 1.99486357e-05, 2.05109650e-05, - 2.77257117e-05, 2.92252801e-05, 2.86860989e-05, 2.62041481e-05, - 2.26315755e-05, 2.00140414e-05, 1.94712216e-05, 2.05490061e-05, - 2.87354996e-05, 2.95048307e-05, 2.85894492e-05, 2.58858142e-05, - 2.13090321e-05, 1.93673557e-05, 2.02773834e-05, 2.11033983e-05, - 2.85852052e-05, 2.97288122e-05, 2.79146332e-05, 2.44452107e-05, - 2.31679082e-05, 2.27807440e-05, 2.18738408e-05, 2.64481989e-05, - 2.75587669e-05, 2.79628538e-05, 2.77593896e-05, 2.50286400e-05, - 2.16106805e-05, 2.09007466e-05, 2.12687109e-05, 2.59863835e-05, - 2.72774832e-05, 2.72514624e-05, 2.62344994e-05, 2.54791519e-05, - 2.47247954e-05, 2.24762465e-05, 2.13734004e-05, 2.55462264e-05, - 2.75534880e-05, 2.75313684e-05, 2.66588854e-05, 2.62060678e-05, - 2.47088292e-05, 2.25099065e-05, 2.11782705e-05, 2.12297888e-05, - 2.35343044e-05, 2.67652476e-05, 2.95890823e-05, 2.99738506e-05, - 2.75948379e-05, 2.25343204e-05, 2.08218881e-05, 2.27284299e-05, - 2.70578955e-05, 2.80078197e-05, 2.69873070e-05, 2.46604463e-05, - 2.41740604e-05, 2.36821679e-05, 2.19120442e-05, 2.13654491e-05, - 2.34985414e-05, 2.67191917e-05, 2.87852322e-05, 2.74479834e-05, - 2.52272857e-05, 2.29967013e-05, 2.15214021e-05, 2.14197937e-05, - 2.54536657e-05, 2.74853520e-05, 2.77615522e-05, 2.62106595e-05, - 2.44016906e-05, 2.30449377e-05, 2.13138459e-05, 2.19209498e-05, - 2.29030868e-05, 2.50450586e-05, 2.82776533e-05, 2.97325432e-05, - 2.79010390e-05, 2.38308239e-05, 2.14493681e-05, 2.01501721e-05, - 2.00504197e-05, 2.09412601e-05, 2.58261237e-05, 2.68771212e-05, - 2.75019050e-05, 2.58581314e-05, 2.30643142e-05, 2.38665640e-05, - 2.28113640e-05, 2.07961913e-05, 2.64009890e-05, 2.72296939e-05, - 2.71526240e-05, 2.70375123e-05, 2.61185511e-05, 2.30878559e-05, - 2.16169257e-05, 2.23381229e-05, 2.66337163e-05, 2.82772594e-05, - 2.83852608e-05, 2.53271583e-05, 2.14327510e-05, 2.13427084e-05, - 2.19577384e-05, 2.48601409e-05, 2.68297286e-05, 2.81519401e-05, - 2.79889234e-05, 2.61010182e-05, 2.41527362e-05, 2.25614095e-05, - 2.08941858e-05, - 2.55432385e-05, 2.69878996e-05, 2.71709131e-05, 2.64576103e-05, - 2.50802518e-05, 2.35264404e-05, 2.25189927e-05, 2.25183259e-05, - 2.27148723e-05, 2.53478162e-05, 2.64572025e-05, 2.61953274e-05, - 2.53914689e-05, 2.52459293e-05, 2.50193888e-05, 2.36575680e-05, - 2.24978195e-05, 2.27914580e-05, 2.30906317e-05, 2.25811118e-05, - 2.58800690e-05, 2.67738791e-05, 2.68467272e-05, 2.56443054e-05, - 2.48013827e-05, 2.47875805e-05, 2.34919614e-05, 2.19933085e-05, - 2.15114380e-05, 2.67314097e-05, 2.72716524e-05, 2.72796878e-05, - 2.49105533e-05, 2.22995904e-05, 2.22677070e-05, 2.24538061e-05, - 2.21562153e-05, 2.20845795e-05, 2.45793780e-05, 2.63928312e-05, - 2.70110575e-05, 2.58007450e-05, 2.41264644e-05, 2.44289191e-05, - 2.47823194e-05, 2.37120287e-05, 2.23679566e-05, 2.26043064e-05, - 2.46488818e-05, 2.70711308e-05, 2.74937776e-05, 2.71984024e-05, - 2.53113706e-05, 2.23901008e-05, 2.13333135e-05, 2.17897281e-05, - 2.67608917e-05, 2.71864045e-05, 2.69966035e-05, 2.58183048e-05, - 2.34374942e-05, 2.13990928e-05, 2.09466685e-05, 2.18234720e-05, - 2.72745840e-05, 2.71888053e-05, 2.69071528e-05, 2.56381675e-05, - 2.24335929e-05, 2.08620110e-05, 2.16017795e-05, 2.22657521e-05, - 2.70355010e-05, 2.69920099e-05, 2.66257068e-05, 2.46878979e-05, - 2.38370981e-05, 2.35600790e-05, 2.28658525e-05, 2.59918256e-05, - 2.64771485e-05, 2.66994505e-05, 2.67476459e-05, 2.51600859e-05, - 2.26658065e-05, 2.21049809e-05, 2.23966749e-05, 2.57213655e-05, - 2.63845188e-05, 2.63866797e-05, 2.58594542e-05, 2.54409714e-05, - 2.49625666e-05, 2.33304054e-05, 2.24791924e-05, 2.54531064e-05, - 2.65766381e-05, 2.65757413e-05, 2.60847815e-05, 2.58617074e-05, - 2.49388699e-05, 2.33559979e-05, 2.23247822e-05, 2.23659175e-05, - 2.40429547e-05, 2.59247833e-05, 2.70367946e-05, 2.75672392e-05, - 2.67801213e-05, 2.33735591e-05, 2.20390198e-05, 2.35199797e-05, - 2.63271345e-05, 2.66312978e-05, 2.62176661e-05, 2.48597130e-05, - 2.45525135e-05, 2.42205779e-05, 2.28992611e-05, 2.24736282e-05, - 2.40242400e-05, 2.60482304e-05, 2.71202246e-05, 2.65741202e-05, - 2.52711912e-05, 2.37203987e-05, 2.25940310e-05, 2.25161075e-05, - 2.54036972e-05, 2.65289192e-05, 2.66547726e-05, 2.58198409e-05, - 2.46923715e-05, 2.37513830e-05, 2.24338706e-05, 2.29051268e-05, - 2.36518978e-05, 2.51056203e-05, 2.68361365e-05, 2.74189363e-05, - 2.68249096e-05, 2.43089595e-05, 2.25426695e-05, 2.15015446e-05, - 2.14172574e-05, 2.21366878e-05, 2.55438510e-05, 2.59964038e-05, - 2.64291835e-05, 2.56416475e-05, 2.37690688e-05, 2.43639145e-05, - 2.35802694e-05, 2.20156324e-05, 2.60065233e-05, 2.63317845e-05, - 2.62574050e-05, 2.62954092e-05, 2.58338678e-05, 2.37821211e-05, - 2.26719626e-05, 2.32253287e-05, 2.59685756e-05, 2.65221395e-05, - 2.69373282e-05, 2.53547237e-05, 2.25265232e-05, 2.24553380e-05, - 2.29334673e-05, 2.49814577e-05, 2.61020344e-05, 2.67675768e-05, - 2.68197186e-05, 2.58565258e-05, 2.45635610e-05, 2.33949068e-05, - 2.21005201e-05, - 2.50628097e-05, 2.42466789e-05, 2.39153623e-05, 2.49419426e-05, - 2.57156431e-05, 2.52855419e-05, 2.47644559e-05, 2.45802850e-05, - 2.43919731e-05, 2.49808485e-05, 2.46710474e-05, 2.47581481e-05, - 2.51229612e-05, 2.51720950e-05, 2.51500878e-05, 2.52634859e-05, - 2.49492459e-05, 2.47247154e-05, 2.45998055e-05, 2.43884888e-05, - 2.51374187e-05, 2.45421219e-05, 2.43946839e-05, 2.52192677e-05, - 2.54398116e-05, 2.50690161e-05, 2.46907707e-05, 2.42878975e-05, - 2.40974523e-05, 2.45764630e-05, 2.26096675e-05, 2.34999071e-05, - 2.57406123e-05, 2.55837628e-05, 2.47980799e-05, 2.43110917e-05, - 2.42102013e-05, 2.42164823e-05, 2.59335671e-05, 2.51013218e-05, - 2.41078474e-05, 2.53505515e-05, 2.54453676e-05, 2.48712043e-05, - 2.44937654e-05, 2.43926647e-05, 2.41296400e-05, 2.53214857e-05, - 2.58194845e-05, 2.40460380e-05, 2.23383921e-05, 2.38564842e-05, - 2.52286745e-05, 2.46448035e-05, 2.38887077e-05, 2.39869546e-05, - 2.44473955e-05, 2.34272991e-05, 2.40194195e-05, 2.54544764e-05, - 2.54975578e-05, 2.45519035e-05, 2.40491463e-05, 2.41573498e-05, - 2.38181879e-05, 2.29851614e-05, 2.41097141e-05, 2.54860830e-05, - 2.51512724e-05, 2.40844773e-05, 2.39862439e-05, 2.42429503e-05, - 2.40990910e-05, 2.22422611e-05, 2.47297607e-05, 2.60352157e-05, - 2.52801122e-05, 2.42980914e-05, 2.40668832e-05, 2.52120423e-05, - 2.49827346e-05, 2.46504905e-05, 2.45234186e-05, 2.48134873e-05, - 2.44662177e-05, 2.42197064e-05, 2.42953219e-05, 2.53090641e-05, - 2.50774328e-05, 2.50547330e-05, 2.53153050e-05, 2.50353921e-05, - 2.45949325e-05, 2.44302194e-05, 2.43256638e-05, 2.53565488e-05, - 2.48033833e-05, 2.47905563e-05, 2.52690265e-05, 2.52026856e-05, - 2.49129179e-05, 2.44871371e-05, 2.42411806e-05, 2.42834172e-05, - 2.64558077e-05, 2.57432445e-05, 2.26099198e-05, 2.26107978e-05, - 2.41017649e-05, 2.42070453e-05, 2.40278378e-05, 2.41207920e-05, - 2.50192550e-05, 2.46673503e-05, 2.52740596e-05, 2.56728354e-05, - 2.53163531e-05, 2.48118023e-05, 2.44859261e-05, 2.43843465e-05, - 2.63730053e-05, 2.54831109e-05, 2.39187554e-05, 2.47124864e-05, - 2.51354963e-05, 2.46850887e-05, 2.42481892e-05, 2.43788466e-05, - 2.52769380e-05, 2.48722839e-05, 2.47276668e-05, 2.54643882e-05, - 2.56032469e-05, 2.50641542e-05, 2.44487525e-05, 2.43417019e-05, - 2.42807192e-05, 2.56964452e-05, 2.43969239e-05, 2.28532968e-05, - 2.44332625e-05, 2.53994337e-05, 2.49108268e-05, 2.41098294e-05, - 2.39445726e-05, 2.41919826e-05, 2.58424369e-05, 2.56454552e-05, - 2.50489419e-05, 2.53472561e-05, 2.48287727e-05, 2.39598727e-05, - 2.38253565e-05, 2.38784293e-05, 2.49613659e-05, 2.51660037e-05, - 2.52806019e-05, 2.50992106e-05, 2.50366503e-05, 2.51105495e-05, - 2.46626282e-05, 2.43978633e-05, 2.56179469e-05, 2.43081698e-05, - 2.42753863e-05, 2.48693648e-05, 2.44059469e-05, 2.43428239e-05, - 2.43377295e-05, 2.57637788e-05, 2.54404985e-05, 2.45109874e-05, - 2.44862525e-05, 2.47285089e-05, 2.45243978e-05, 2.44396744e-05, - 2.42684704e-05, - 2.52366182e-05, 2.64796292e-05, 2.66014162e-05, 2.69421104e-05, - 2.62172983e-05, 2.39945832e-05, 2.25887911e-05, 2.22851666e-05, - 2.20574551e-05, 2.48187036e-05, 2.57892238e-05, 2.54646914e-05, - 2.51899949e-05, 2.51343150e-05, 2.48492639e-05, 2.40325870e-05, - 2.28885293e-05, 2.26386911e-05, 2.25629765e-05, 2.19983280e-05, - 2.59394565e-05, 2.66493300e-05, 2.61620419e-05, 2.57648720e-05, - 2.52618039e-05, 2.44677827e-05, 2.29129008e-05, 2.16217771e-05, - 2.11710966e-05, 2.65123392e-05, 2.67313995e-05, 2.67385600e-05, - 2.60640178e-05, 2.38908735e-05, 2.25425333e-05, 2.18247327e-05, - 2.15564067e-05, 2.15412844e-05, 2.61387180e-05, 2.77918111e-05, - 2.71108240e-05, 2.64029880e-05, 2.46971448e-05, 2.38008648e-05, - 2.33370871e-05, 2.25120621e-05, 2.15052199e-05, 2.35735752e-05, - 2.59518071e-05, 2.68964010e-05, 2.61828260e-05, 2.65931160e-05, - 2.53395120e-05, 2.23395517e-05, 2.08027732e-05, 2.10886487e-05, - 2.59651907e-05, 2.70623074e-05, 2.73339673e-05, 2.67657878e-05, - 2.43350642e-05, 2.18390852e-05, 2.09354370e-05, 2.13614760e-05, - 2.58719567e-05, 2.70314806e-05, 2.75954876e-05, 2.64818939e-05, - 2.32028232e-05, 2.09655035e-05, 2.10292397e-05, 2.16469450e-05, - 2.69798024e-05, 2.70073811e-05, 2.78005267e-05, 2.65028334e-05, - 2.41766102e-05, 2.22761981e-05, 2.15942185e-05, 2.63932433e-05, - 2.77271042e-05, 2.74684795e-05, 2.62870812e-05, 2.42729440e-05, - 2.21584484e-05, 2.15534196e-05, 2.17780752e-05, 2.61323124e-05, - 2.73288360e-05, 2.71793702e-05, 2.64193005e-05, 2.50470078e-05, - 2.36661131e-05, 2.23890014e-05, 2.18577081e-05, 2.58326880e-05, - 2.68887535e-05, 2.67892960e-05, 2.68436138e-05, 2.60903081e-05, - 2.42796815e-05, 2.24970045e-05, 2.16655545e-05, 2.17476867e-05, - 2.67785548e-05, 2.89665296e-05, 2.71652234e-05, 2.61037155e-05, - 2.47838728e-05, 2.20371048e-05, 2.12323662e-05, 2.19616154e-05, - 2.66865116e-05, 2.79802890e-05, 2.74395518e-05, 2.58459688e-05, - 2.47744628e-05, 2.35488377e-05, 2.22883348e-05, 2.19497832e-05, - 2.65703326e-05, 2.76605160e-05, 2.69095616e-05, 2.63507183e-05, - 2.50799474e-05, 2.30237602e-05, 2.17777315e-05, 2.19573501e-05, - 2.55691429e-05, 2.70014398e-05, 2.71171056e-05, 2.68019646e-05, - 2.55118557e-05, 2.37216758e-05, 2.20382291e-05, 2.20539768e-05, - 2.22916704e-05, 2.62034243e-05, 2.74304535e-05, 2.64854395e-05, - 2.62539461e-05, 2.47450896e-05, 2.28431325e-05, 2.11869837e-05, - 2.09110454e-05, 2.15210017e-05, 2.73895832e-05, 2.88437610e-05, - 2.78800799e-05, 2.60994580e-05, 2.33058180e-05, 2.21170610e-05, - 2.15055685e-05, 2.09951618e-05, 2.56796792e-05, 2.75782885e-05, - 2.78763354e-05, 2.69153312e-05, 2.55870304e-05, 2.38255405e-05, - 2.24839410e-05, 2.22863568e-05, 2.79891198e-05, 2.87129856e-05, - 2.70960420e-05, 2.45816336e-05, 2.20051113e-05, 2.18761087e-05, - 2.20593930e-05, 2.62073880e-05, 2.77334124e-05, 2.75378580e-05, - 2.66833324e-05, 2.48512323e-05, 2.32427603e-05, 2.24354203e-05, - 2.16284587e-05, - 2.45051428e-05, 2.13473033e-05, 2.05595410e-05, 2.24684360e-05, - 2.50902054e-05, 2.68643786e-05, 2.75560612e-05, 2.74729533e-05, - 2.72268202e-05, 2.47910779e-05, 2.29269686e-05, 2.34707167e-05, - 2.47214448e-05, 2.49226126e-05, 2.52217253e-05, 2.67315996e-05, - 2.76539656e-05, 2.73138841e-05, 2.70094059e-05, 2.73322922e-05, - 2.39076967e-05, 2.18408437e-05, 2.19425701e-05, 2.43065308e-05, - 2.55054540e-05, 2.54965681e-05, 2.66973209e-05, 2.77387208e-05, - 2.79938799e-05, 2.20352591e-05, 1.79918918e-05, 1.96341810e-05, - 2.53393167e-05, 2.80739536e-05, 2.77747671e-05, 2.73952675e-05, - 2.75742706e-05, 2.76320901e-05, 2.57802822e-05, 2.20921238e-05, - 2.05619065e-05, 2.39481766e-05, 2.62935274e-05, 2.58552728e-05, - 2.53951970e-05, 2.63872732e-05, 2.73703093e-05, 2.77133595e-05, - 2.56950641e-05, 2.05990096e-05, 1.78478289e-05, 2.04463412e-05, - 2.48257603e-05, 2.76058737e-05, 2.80026307e-05, 2.77283048e-05, - 2.22396317e-05, 1.92727222e-05, 2.02224008e-05, 2.38307391e-05, - 2.70093147e-05, 2.83242358e-05, 2.83714536e-05, 2.77969988e-05, - 2.09421945e-05, 1.84778980e-05, 2.02128266e-05, 2.42025899e-05, - 2.77918522e-05, 2.84520568e-05, 2.78653812e-05, 2.75071838e-05, - 2.06430942e-05, 1.71954122e-05, 2.13042723e-05, 2.56153999e-05, - 2.65588651e-05, 2.64816657e-05, 2.69496175e-05, 2.36188542e-05, - 2.18914042e-05, 2.13982814e-05, 2.21175088e-05, 2.50254972e-05, - 2.73011024e-05, 2.76182622e-05, 2.74321352e-05, 2.41315640e-05, - 2.24304528e-05, 2.25105899e-05, 2.38443493e-05, 2.46586480e-05, - 2.52231385e-05, 2.67341250e-05, 2.73825029e-05, 2.45860460e-05, - 2.22071590e-05, 2.22660032e-05, 2.33103984e-05, 2.39099419e-05, - 2.53005918e-05, 2.67359387e-05, 2.74607212e-05, 2.74501423e-05, - 2.64522604e-05, 2.25176090e-05, 1.77338526e-05, 1.83912333e-05, - 2.25848057e-05, 2.66011310e-05, 2.75659239e-05, 2.64397226e-05, - 2.28772585e-05, 2.10412985e-05, 2.27719705e-05, 2.54192853e-05, - 2.57988072e-05, 2.60523975e-05, 2.71197642e-05, 2.74155561e-05, - 2.64814140e-05, 2.30473942e-05, 2.03330797e-05, 2.24860912e-05, - 2.48897844e-05, 2.64890931e-05, 2.72539629e-05, 2.73792875e-05, - 2.46816231e-05, 2.22612170e-05, 2.18469370e-05, 2.38183496e-05, - 2.56454450e-05, 2.65836981e-05, 2.74781600e-05, 2.70493145e-05, - 2.63949572e-05, 2.50552060e-05, 2.09056704e-05, 1.85870916e-05, - 2.19464549e-05, 2.60860585e-05, 2.76004049e-05, 2.80080365e-05, - 2.79750029e-05, 2.75796514e-05, 2.41481531e-05, 2.24066448e-05, - 2.19086569e-05, 2.42639157e-05, 2.64932133e-05, 2.56329976e-05, - 2.62549145e-05, 2.75012654e-05, 2.37460698e-05, 2.24112025e-05, - 2.24098982e-05, 2.28487435e-05, 2.40368047e-05, 2.65675277e-05, - 2.73855299e-05, 2.68093677e-05, 2.30606214e-05, 1.98375386e-05, - 2.09133866e-05, 2.47824625e-05, 2.73840917e-05, 2.74096926e-05, - 2.70243742e-05, 2.52308694e-05, 2.28864499e-05, 2.10565314e-05, - 2.16906335e-05, 2.40773897e-05, 2.56286449e-05, 2.66828366e-05, - 2.76470128e-05, - 2.56180028e-05, 2.80991932e-05, 2.85326207e-05, 2.72605090e-05, - 2.50819218e-05, 2.28674490e-05, 2.15569191e-05, 2.15410870e-05, - 2.17654864e-05, 2.53035260e-05, 2.70378555e-05, 2.65874412e-05, - 2.54017733e-05, 2.51957464e-05, 2.48609238e-05, 2.30338887e-05, - 2.15467569e-05, 2.18871175e-05, 2.22458212e-05, 2.16022911e-05, - 2.61862171e-05, 2.77454533e-05, 2.77539154e-05, 2.58223141e-05, - 2.46069516e-05, 2.45183183e-05, 2.27577273e-05, 2.08880496e-05, - 2.03066277e-05, 2.76349002e-05, 2.94274329e-05, 2.89344675e-05, - 2.48325752e-05, 2.13620053e-05, 2.12547281e-05, 2.14421285e-05, - 2.10771423e-05, 2.09919967e-05, 2.43926845e-05, 2.73591888e-05, - 2.83987691e-05, 2.61334827e-05, 2.36760324e-05, 2.39976789e-05, - 2.44207628e-05, 2.30067519e-05, 2.13254915e-05, 2.17112899e-05, - 2.44678160e-05, 2.84365423e-05, 2.96796008e-05, 2.85947126e-05, - 2.53068582e-05, 2.13906352e-05, 2.00864031e-05, 2.06272459e-05, - 2.75628909e-05, 2.89648620e-05, 2.84978725e-05, 2.62127670e-05, - 2.27788379e-05, 2.02032644e-05, 1.96469835e-05, 2.06778292e-05, - 2.84723810e-05, 2.92063279e-05, 2.84224933e-05, 2.59054904e-05, - 2.14860306e-05, 1.95512804e-05, 2.04059529e-05, 2.12106669e-05, - 2.83917718e-05, 2.93854187e-05, 2.78247889e-05, 2.45749973e-05, - 2.32695752e-05, 2.28052605e-05, 2.19245330e-05, 2.64179282e-05, - 2.74988404e-05, 2.78533074e-05, 2.76104448e-05, 2.49972168e-05, - 2.17115447e-05, 2.10165697e-05, 2.13719786e-05, 2.59800439e-05, - 2.72238489e-05, 2.71928315e-05, 2.62230258e-05, 2.54552043e-05, - 2.46826663e-05, 2.25292067e-05, 2.14739180e-05, 2.55590364e-05, - 2.74537328e-05, 2.74286210e-05, 2.66341324e-05, 2.61798299e-05, - 2.47025287e-05, 2.25665442e-05, 2.12814688e-05, 2.13340301e-05, - 2.37413707e-05, 2.68307877e-05, 2.92768468e-05, 2.95826478e-05, - 2.73783786e-05, 2.25630261e-05, 2.09251969e-05, 2.27385854e-05, - 2.69914332e-05, 2.79168072e-05, 2.69642140e-05, 2.47413998e-05, - 2.42349042e-05, 2.37124981e-05, 2.19992293e-05, 2.14716094e-05, - 2.36981035e-05, 2.67294317e-05, 2.85678741e-05, 2.73302563e-05, - 2.52248404e-05, 2.30478521e-05, 2.16072511e-05, 2.15226525e-05, - 2.54598044e-05, 2.73972857e-05, 2.76541413e-05, 2.62205738e-05, - 2.44845286e-05, 2.31309549e-05, 2.14283929e-05, 2.19944211e-05, - 2.29195349e-05, 2.51155126e-05, 2.81357507e-05, 2.93868732e-05, - 2.77374346e-05, 2.39151804e-05, 2.15982257e-05, 2.02957760e-05, - 2.01874613e-05, 2.10525502e-05, 2.58956091e-05, 2.69277267e-05, - 2.74541962e-05, 2.58603052e-05, 2.31262382e-05, 2.38000340e-05, - 2.27884649e-05, 2.08879039e-05, 2.63370177e-05, 2.71922223e-05, - 2.71359141e-05, 2.69843422e-05, 2.60727164e-05, 2.31764251e-05, - 2.17351947e-05, 2.23951583e-05, 2.66665956e-05, 2.81856965e-05, - 2.82173441e-05, 2.52895587e-05, 2.15373626e-05, 2.14463491e-05, - 2.20289279e-05, 2.49446665e-05, 2.68341136e-05, 2.80272973e-05, - 2.78390834e-05, 2.60162809e-05, 2.41304049e-05, 2.26108834e-05, - 2.10145891e-05, - 2.56445488e-05, 2.79569477e-05, 2.83506876e-05, 2.70480688e-05, - 2.49426618e-05, 2.29330703e-05, 2.17260267e-05, 2.17500490e-05, - 2.20225218e-05, 2.53807872e-05, 2.70171864e-05, 2.66102663e-05, - 2.54268233e-05, 2.52205932e-05, 2.49132628e-05, 2.31042996e-05, - 2.16751245e-05, 2.20731482e-05, 2.24679784e-05, 2.18551022e-05, - 2.61226110e-05, 2.75791588e-05, 2.76740161e-05, 2.57750712e-05, - 2.45871809e-05, 2.46100794e-05, 2.29666733e-05, 2.11367401e-05, - 2.05688865e-05, 2.74940063e-05, 2.90874781e-05, 2.86922344e-05, - 2.47065735e-05, 2.13482080e-05, 2.14081976e-05, 2.17065380e-05, - 2.13496763e-05, 2.12598202e-05, 2.42393993e-05, 2.70005853e-05, - 2.81227624e-05, 2.59964429e-05, 2.36905957e-05, 2.41583698e-05, - 2.46760308e-05, 2.32905628e-05, 2.16248534e-05, 2.17605882e-05, - 2.43436926e-05, 2.82010904e-05, 2.94416713e-05, 2.84109725e-05, - 2.53055013e-05, 2.15811183e-05, 2.03794517e-05, 2.09269911e-05, - 2.75176952e-05, 2.86423125e-05, 2.81686014e-05, 2.60211603e-05, - 2.27930018e-05, 2.03699241e-05, 1.98857781e-05, 2.09447983e-05, - 2.84356178e-05, 2.88413137e-05, 2.80449839e-05, 2.57510641e-05, - 2.15688301e-05, 1.97782629e-05, 2.06953909e-05, 2.14813907e-05, - 2.81423351e-05, 2.89224547e-05, 2.74480347e-05, 2.43776121e-05, - 2.33339697e-05, 2.31087872e-05, 2.22590114e-05, 2.62882435e-05, - 2.71477246e-05, 2.75365442e-05, 2.75091192e-05, 2.51428016e-05, - 2.19505541e-05, 2.12846967e-05, 2.16373539e-05, 2.58809958e-05, - 2.69464565e-05, 2.69408590e-05, 2.60853894e-05, 2.55042142e-05, - 2.49034640e-05, 2.27963597e-05, 2.17362484e-05, 2.54928137e-05, - 2.72489946e-05, 2.72412011e-05, 2.64360468e-05, 2.60924768e-05, - 2.48318169e-05, 2.28210244e-05, 2.15552166e-05, 2.16006196e-05, - 2.34764506e-05, 2.62891420e-05, 2.88292310e-05, 2.93992307e-05, - 2.75356607e-05, 2.28832149e-05, 2.12298289e-05, 2.30830204e-05, - 2.68215458e-05, 2.75012146e-05, 2.66705438e-05, 2.46431906e-05, - 2.42675512e-05, 2.38926793e-05, 2.22416832e-05, 2.17211092e-05, - 2.34590858e-05, 2.64010000e-05, 2.83212878e-05, 2.72179783e-05, - 2.52591032e-05, 2.32607459e-05, 2.18909915e-05, 2.17750217e-05, - 2.54297939e-05, 2.71737324e-05, 2.74065407e-05, 2.60235011e-05, - 2.44234357e-05, 2.32504762e-05, 2.16625007e-05, 2.22692717e-05, - 2.32291632e-05, 2.49794064e-05, 2.78127400e-05, 2.91379761e-05, - 2.76413430e-05, 2.39355977e-05, 2.17362328e-05, 2.05550338e-05, - 2.04745369e-05, 2.13279596e-05, 2.56039862e-05, 2.64033393e-05, - 2.70776281e-05, 2.57629863e-05, 2.33041211e-05, 2.41999860e-05, - 2.32042572e-05, 2.12221431e-05, 2.63184794e-05, 2.68732229e-05, - 2.67677744e-05, 2.67767539e-05, 2.60609840e-05, 2.32842043e-05, - 2.19313728e-05, 2.26671057e-05, 2.62859485e-05, 2.75904530e-05, - 2.79545452e-05, 2.54023813e-05, 2.17842925e-05, 2.17040202e-05, - 2.23056269e-05, 2.48021041e-05, 2.64933605e-05, 2.76896204e-05, - 2.76651855e-05, 2.61184689e-05, 2.43818703e-05, 2.28773365e-05, - 2.12723655e-05, - 2.55041035e-05, 2.58760298e-05, 2.58165490e-05, 2.53512373e-05, - 2.46468148e-05, 2.40876677e-05, 2.35955396e-05, 2.37225287e-05, - 2.40381539e-05, 2.55229484e-05, 2.59728345e-05, 2.59424125e-05, - 2.53903099e-05, 2.52837787e-05, 2.52030126e-05, 2.42076317e-05, - 2.34478701e-05, 2.38738471e-05, 2.42328984e-05, 2.39148092e-05, - 2.54554188e-05, 2.56841140e-05, 2.60117823e-05, 2.53432324e-05, - 2.48132997e-05, 2.51531993e-05, 2.45139675e-05, 2.34139296e-05, - 2.30524317e-05, 2.57453346e-05, 2.51075860e-05, 2.56148493e-05, - 2.45623139e-05, 2.28301479e-05, 2.33369495e-05, 2.38471469e-05, - 2.36267036e-05, 2.35518568e-05, 2.42266506e-05, 2.48296818e-05, - 2.54137292e-05, 2.51683759e-05, 2.44022258e-05, 2.50968620e-05, - 2.56644342e-05, 2.49269031e-05, 2.38886896e-05, 2.32842617e-05, - 2.43708385e-05, 2.55845179e-05, 2.55491391e-05, 2.58198680e-05, - 2.52491465e-05, 2.35572472e-05, 2.30015705e-05, 2.34084594e-05, - 2.60774486e-05, 2.52635765e-05, 2.52084880e-05, 2.50073526e-05, - 2.38538275e-05, 2.26474094e-05, 2.24947963e-05, 2.33306673e-05, - 2.63733582e-05, 2.50395414e-05, 2.49963438e-05, 2.50006633e-05, - 2.32492376e-05, 2.23835236e-05, 2.32169434e-05, 2.37118622e-05, - 2.55201150e-05, 2.44271413e-05, 2.48891492e-05, 2.41713801e-05, - 2.43313086e-05, 2.48691263e-05, 2.44096905e-05, 2.53214027e-05, - 2.49014514e-05, 2.51338885e-05, 2.58853547e-05, 2.56005323e-05, - 2.39401755e-05, 2.35698390e-05, 2.38030633e-05, 2.52336644e-05, - 2.50945126e-05, 2.51793217e-05, 2.52066670e-05, 2.55014636e-05, - 2.56909214e-05, 2.45697328e-05, 2.38614126e-05, 2.51475196e-05, - 2.54461699e-05, 2.55028320e-05, 2.51644749e-05, 2.53676100e-05, - 2.53849398e-05, 2.45498929e-05, 2.37705170e-05, 2.37815329e-05, - 2.34623659e-05, 2.39469337e-05, 2.45835540e-05, 2.58423635e-05, - 2.67458427e-05, 2.47734903e-05, 2.36327344e-05, 2.49676674e-05, - 2.54100762e-05, 2.47538157e-05, 2.49403502e-05, 2.46112912e-05, - 2.47887394e-05, 2.49973462e-05, 2.41421550e-05, 2.38156233e-05, - 2.35283334e-05, 2.47213197e-05, 2.55604076e-05, 2.57482100e-05, - 2.53318524e-05, 2.47083464e-05, 2.40246852e-05, 2.38598676e-05, - 2.52259217e-05, 2.53565031e-05, 2.53468237e-05, 2.49910428e-05, - 2.46012618e-05, 2.44373436e-05, 2.37333796e-05, 2.42505454e-05, - 2.49614361e-05, 2.46754044e-05, 2.51741844e-05, 2.55664632e-05, - 2.59460017e-05, 2.45627271e-05, 2.35157611e-05, 2.30343218e-05, - 2.30533079e-05, 2.36197266e-05, 2.45012495e-05, 2.40469636e-05, - 2.47892692e-05, 2.51833790e-05, 2.46359619e-05, 2.58040894e-05, - 2.52434349e-05, 2.37090274e-05, 2.56844416e-05, 2.49262089e-05, - 2.47199443e-05, 2.52682304e-05, 2.55877589e-05, 2.44246305e-05, - 2.38081871e-05, 2.45005331e-05, 2.45015466e-05, 2.40226907e-05, - 2.54324279e-05, 2.56399070e-05, 2.38509984e-05, 2.38267652e-05, - 2.42795138e-05, 2.45632951e-05, 2.47152750e-05, 2.50922256e-05, - 2.56830401e-05, 2.59635364e-05, 2.54865157e-05, 2.46192183e-05, - 2.35327489e-05, - 2.50719954e-05, 2.34933346e-05, 2.30137810e-05, 2.37643073e-05, - 2.47564739e-05, 2.54918524e-05, 2.56550377e-05, 2.57345327e-05, - 2.58506952e-05, 2.52715602e-05, 2.44659894e-05, 2.47682911e-05, - 2.51192519e-05, 2.51629831e-05, 2.52938118e-05, 2.55009428e-05, - 2.55693957e-05, 2.57174069e-05, 2.58134794e-05, 2.58275782e-05, - 2.46677135e-05, 2.36414147e-05, 2.39225347e-05, 2.48232520e-05, - 2.51559860e-05, 2.54406200e-05, 2.58026590e-05, 2.57341497e-05, - 2.56657433e-05, 2.37927282e-05, 2.11624736e-05, 2.23730439e-05, - 2.48422603e-05, 2.52419824e-05, 2.55915123e-05, 2.58339292e-05, - 2.58058889e-05, 2.57854283e-05, 2.48432695e-05, 2.31986079e-05, - 2.27544827e-05, 2.44766346e-05, 2.53435040e-05, 2.56558544e-05, - 2.58229408e-05, 2.59582378e-05, 2.58878891e-05, 2.54131075e-05, - 2.49090920e-05, 2.28853898e-05, 2.13448578e-05, 2.29529293e-05, - 2.50727400e-05, 2.56819326e-05, 2.56812513e-05, 2.57908427e-05, - 2.41387346e-05, 2.19561586e-05, 2.24375894e-05, 2.42888728e-05, - 2.53745186e-05, 2.54622592e-05, 2.54887916e-05, 2.57374976e-05, - 2.35932984e-05, 2.13867833e-05, 2.22969320e-05, 2.44998741e-05, - 2.54668264e-05, 2.54451374e-05, 2.57342266e-05, 2.58194448e-05, - 2.28679234e-05, 2.03288696e-05, 2.28138937e-05, 2.46951568e-05, - 2.54812086e-05, 2.59959751e-05, 2.60133892e-05, 2.43977754e-05, - 2.31387546e-05, 2.30271928e-05, 2.39356662e-05, 2.54943787e-05, - 2.58103707e-05, 2.57893608e-05, 2.58281007e-05, 2.46340871e-05, - 2.35651532e-05, 2.36682918e-05, 2.44444266e-05, 2.51679397e-05, - 2.57149330e-05, 2.59164036e-05, 2.58332679e-05, 2.48425121e-05, - 2.36839029e-05, 2.37559073e-05, 2.41062750e-05, 2.46031526e-05, - 2.55030283e-05, 2.58920569e-05, 2.58338096e-05, 2.58261455e-05, - 2.46231559e-05, 2.28198651e-05, 2.07114906e-05, 2.18229429e-05, - 2.48152768e-05, 2.60225269e-05, 2.58455737e-05, 2.60748575e-05, - 2.40359095e-05, 2.25838080e-05, 2.36460136e-05, 2.49324359e-05, - 2.53348941e-05, 2.57195244e-05, 2.58397672e-05, 2.58079692e-05, - 2.46978987e-05, 2.36431752e-05, 2.27233696e-05, 2.40510506e-05, - 2.51807235e-05, 2.58118530e-05, 2.58882787e-05, 2.58188491e-05, - 2.49632855e-05, 2.36523119e-05, 2.34159826e-05, 2.42697113e-05, - 2.50698199e-05, 2.56091526e-05, 2.57731258e-05, 2.59036371e-05, - 2.60095634e-05, 2.47578244e-05, 2.27861304e-05, 2.17653393e-05, - 2.38797249e-05, 2.53383068e-05, 2.55943035e-05, 2.56581303e-05, - 2.56898279e-05, 2.58081113e-05, 2.40944806e-05, 2.28306639e-05, - 2.30721616e-05, 2.46749511e-05, 2.57365446e-05, 2.61702287e-05, - 2.62117423e-05, 2.58948757e-05, 2.47424371e-05, 2.34382412e-05, - 2.32952340e-05, 2.39194394e-05, 2.48458691e-05, 2.55820320e-05, - 2.57262740e-05, 2.59208302e-05, 2.34950325e-05, 2.14806585e-05, - 2.29592923e-05, 2.53614588e-05, 2.58096515e-05, 2.58212720e-05, - 2.59096797e-05, 2.47759451e-05, 2.35508486e-05, 2.28141999e-05, - 2.35564580e-05, 2.51602621e-05, 2.58433774e-05, 2.59175101e-05, - 2.57692371e-05, - 2.51727756e-05, 2.46602225e-05, 2.43961586e-05, 2.50815555e-05, - 2.54852547e-05, 2.49867497e-05, 2.44525511e-05, 2.43386082e-05, - 2.42660646e-05, 2.51063294e-05, 2.49912321e-05, 2.50441663e-05, - 2.51915226e-05, 2.52032278e-05, 2.51623151e-05, 2.49994564e-05, - 2.45611923e-05, 2.44894749e-05, 2.44777803e-05, 2.42336978e-05, - 2.52326131e-05, 2.48468503e-05, 2.47964985e-05, 2.52653246e-05, - 2.52986574e-05, 2.50819071e-05, 2.46182231e-05, 2.40337264e-05, - 2.37969978e-05, 2.48837660e-05, 2.32429789e-05, 2.40366584e-05, - 2.54807823e-05, 2.48997795e-05, 2.44151162e-05, 2.41562884e-05, - 2.40238366e-05, 2.40108167e-05, 2.55455615e-05, 2.50992350e-05, - 2.44655659e-05, 2.53371302e-05, 2.51948252e-05, 2.49058961e-05, - 2.47368189e-05, 2.44784373e-05, 2.40227819e-05, 2.48118070e-05, - 2.54916601e-05, 2.44516093e-05, 2.31146674e-05, 2.43515682e-05, - 2.52422069e-05, 2.43490545e-05, 2.36213617e-05, 2.37958988e-05, - 2.48470732e-05, 2.39115994e-05, 2.43572934e-05, 2.53852898e-05, - 2.50956434e-05, 2.40518934e-05, 2.36235138e-05, 2.39111203e-05, - 2.44258329e-05, 2.35233997e-05, 2.43839800e-05, 2.54017452e-05, - 2.46697231e-05, 2.36236147e-05, 2.37495051e-05, 2.40700696e-05, - 2.44796737e-05, 2.28203643e-05, 2.48332363e-05, 2.56148681e-05, - 2.50439868e-05, 2.43888167e-05, 2.40959543e-05, 2.52676886e-05, - 2.50253005e-05, 2.48223942e-05, 2.48696458e-05, 2.49854572e-05, - 2.43012658e-05, 2.40176747e-05, 2.41332632e-05, 2.53154281e-05, - 2.51330835e-05, 2.51323963e-05, 2.53197446e-05, 2.51475130e-05, - 2.48266616e-05, 2.44235582e-05, 2.41712226e-05, 2.53252583e-05, - 2.49970107e-05, 2.49980107e-05, 2.52837584e-05, 2.52650147e-05, - 2.50125930e-05, 2.44642702e-05, 2.40827238e-05, 2.41187020e-05, - 2.57556482e-05, 2.53921038e-05, 2.31396422e-05, 2.33853368e-05, - 2.47005770e-05, 2.42933003e-05, 2.38815427e-05, 2.42695859e-05, - 2.51481962e-05, 2.47587295e-05, 2.52477107e-05, 2.54374082e-05, - 2.51903816e-05, 2.48331685e-05, 2.43655086e-05, 2.42065696e-05, - 2.57072764e-05, 2.53577649e-05, 2.43493160e-05, 2.49846127e-05, - 2.51854349e-05, 2.46607560e-05, 2.41489624e-05, 2.42128704e-05, - 2.52779667e-05, 2.50312407e-05, 2.49218697e-05, 2.53896645e-05, - 2.53763052e-05, 2.48977916e-05, 2.42375447e-05, 2.42769644e-05, - 2.43966364e-05, 2.54773977e-05, 2.46385598e-05, 2.35231648e-05, - 2.48134754e-05, 2.51992456e-05, 2.45478990e-05, 2.38022968e-05, - 2.36775384e-05, 2.40078100e-05, 2.55685762e-05, 2.53413759e-05, - 2.50522442e-05, 2.53319527e-05, 2.47583153e-05, 2.43332442e-05, - 2.40954912e-05, 2.37817218e-05, 2.51456369e-05, 2.51659708e-05, - 2.52099869e-05, 2.51809613e-05, 2.51790654e-05, 2.49317429e-05, - 2.44244208e-05, 2.43812395e-05, 2.54131039e-05, 2.43339720e-05, - 2.45970480e-05, 2.50431124e-05, 2.42321446e-05, 2.41764613e-05, - 2.42807104e-05, 2.55011755e-05, 2.53258844e-05, 2.47087406e-05, - 2.48047641e-05, 2.50134838e-05, 2.47187814e-05, 2.44429142e-05, - 2.40471303e-05, - 2.54362410e-05, 2.93550368e-05, 3.01440138e-05, 2.87564686e-05, - 2.57665494e-05, 2.21460638e-05, 2.01808469e-05, 1.99611599e-05, - 1.99607101e-05, 2.47981562e-05, 2.73534045e-05, 2.65765568e-05, - 2.51976990e-05, 2.49644584e-05, 2.44339786e-05, 2.23031457e-05, - 2.03797930e-05, 2.04499843e-05, 2.06534955e-05, 1.98067340e-05, - 2.66018540e-05, 2.90654076e-05, 2.85570654e-05, 2.60867448e-05, - 2.45465285e-05, 2.38345281e-05, 2.12759371e-05, 1.90644951e-05, - 1.83810234e-05, 2.87767096e-05, 3.23948492e-05, 3.10493295e-05, - 2.54054122e-05, 2.09341694e-05, 1.99363226e-05, 1.95776078e-05, - 1.91479997e-05, 1.90805727e-05, 2.50644957e-05, 2.97912625e-05, - 3.05676326e-05, 2.69675365e-05, 2.33150212e-05, 2.28873552e-05, - 2.28643490e-05, 2.11674928e-05, 1.92808503e-05, 2.09731523e-05, - 2.49809617e-05, 3.03576792e-05, 3.20589998e-05, 3.02346172e-05, - 2.52368005e-05, 1.98932900e-05, 1.79987712e-05, 1.85373013e-05, - 2.81218692e-05, 3.16191267e-05, 3.10412397e-05, 2.73837499e-05, - 2.23264170e-05, 1.87473145e-05, 1.78005496e-05, 1.87509913e-05, - 2.91842241e-05, 3.22468708e-05, 3.12612125e-05, 2.68043371e-05, - 2.05522877e-05, 1.77579302e-05, 1.83533589e-05, 1.92992068e-05, - 3.03891360e-05, 3.32386611e-05, 3.04884407e-05, 2.55288967e-05, - 2.25948220e-05, 2.08503517e-05, 1.97493080e-05, 2.72571651e-05, - 2.99156648e-05, 3.01370469e-05, 2.85102210e-05, 2.40828788e-05, - 1.99929380e-05, 1.91052284e-05, 1.94978392e-05, 2.65671714e-05, - 2.91127405e-05, 2.89174356e-05, 2.70756317e-05, 2.51258303e-05, - 2.33338885e-05, 2.07331337e-05, 1.96219218e-05, 2.58921498e-05, - 2.89437570e-05, 2.88075979e-05, 2.79195234e-05, 2.67315776e-05, - 2.38391906e-05, 2.08372349e-05, 1.93598070e-05, 1.94512903e-05, - 2.49870922e-05, 3.03430064e-05, 3.29465912e-05, 3.15516130e-05, - 2.67545819e-05, 2.05058528e-05, 1.88293359e-05, 2.05760705e-05, - 2.81752506e-05, 3.08602717e-05, 2.88998331e-05, 2.51420439e-05, - 2.38388301e-05, 2.24701268e-05, 2.02850127e-05, 1.96832646e-05, - 2.47843950e-05, 2.88346499e-05, 3.05972200e-05, 2.82372824e-05, - 2.49453437e-05, 2.15718942e-05, 1.96586007e-05, 1.97236173e-05, - 2.55725456e-05, 2.89904643e-05, 2.94535004e-05, 2.74256181e-05, - 2.46405411e-05, 2.21486493e-05, 1.97138759e-05, 2.01179243e-05, - 2.09438708e-05, 2.57866239e-05, 3.05337946e-05, 3.17105711e-05, - 2.86332100e-05, 2.35489642e-05, 2.03853359e-05, 1.83842625e-05, - 1.81342021e-05, 1.91076656e-05, 2.76178000e-05, 3.03463277e-05, - 3.00241447e-05, 2.64183959e-05, 2.18381052e-05, 2.14560213e-05, - 2.02832008e-05, 1.86464589e-05, 2.65192785e-05, 2.93350323e-05, - 2.95784689e-05, 2.83944515e-05, 2.61741032e-05, 2.22607028e-05, - 2.02345866e-05, 2.05642209e-05, 2.90893042e-05, 3.24502904e-05, - 3.02520045e-05, 2.45888782e-05, 1.97664974e-05, 1.96155695e-05, - 2.01458379e-05, 2.56290315e-05, 2.90381654e-05, 3.04907988e-05, - 2.92267161e-05, 2.54747606e-05, 2.25626006e-05, 2.08250605e-05, - 1.91542237e-05, - 2.43054945e-05, 2.04997615e-05, 1.96005063e-05, 2.16066711e-05, - 2.46470622e-05, 2.72229307e-05, 2.84135328e-05, 2.84289352e-05, - 2.82474498e-05, 2.47414425e-05, 2.24227148e-05, 2.31107083e-05, - 2.45540130e-05, 2.47884856e-05, 2.51981993e-05, 2.70702359e-05, - 2.84153279e-05, 2.81429187e-05, 2.78471486e-05, 2.83786193e-05, - 2.34511317e-05, 2.09977625e-05, 2.12387964e-05, 2.39345079e-05, - 2.53776113e-05, 2.56123634e-05, 2.73993273e-05, 2.89327306e-05, - 2.93527688e-05, 2.12471869e-05, 1.67321060e-05, 1.85454279e-05, - 2.49589169e-05, 2.85193892e-05, 2.86571189e-05, 2.85040246e-05, - 2.87836222e-05, 2.88492326e-05, 2.54069487e-05, 2.09758573e-05, - 1.94763272e-05, 2.33630557e-05, 2.63940740e-05, 2.62089695e-05, - 2.58602412e-05, 2.72014706e-05, 2.85874161e-05, 2.82502063e-05, - 2.53721098e-05, 1.95702504e-05, 1.66958266e-05, 1.94776951e-05, - 2.46221775e-05, 2.85495916e-05, 2.94896883e-05, 2.91059581e-05, - 2.16188941e-05, 1.80698985e-05, 1.90492172e-05, 2.31341032e-05, - 2.72663400e-05, 2.94629865e-05, 2.98220394e-05, 2.90829671e-05, - 2.02104018e-05, 1.72011017e-05, 1.89758064e-05, 2.36157621e-05, - 2.84541996e-05, 2.98937590e-05, 2.92689725e-05, 2.86823086e-05, - 1.95979744e-05, 1.57930139e-05, 2.01173106e-05, 2.51237896e-05, - 2.68409035e-05, 2.73815969e-05, 2.81123731e-05, 2.30086849e-05, - 2.07744077e-05, 2.03028216e-05, 2.13976113e-05, 2.51633133e-05, - 2.82914051e-05, 2.88306195e-05, 2.85586864e-05, 2.36387383e-05, - 2.14631890e-05, 2.15896910e-05, 2.32459803e-05, 2.45288053e-05, - 2.55683018e-05, 2.76132747e-05, 2.84793487e-05, 2.42172074e-05, - 2.13356658e-05, 2.14262874e-05, 2.25490593e-05, 2.34104316e-05, - 2.54593570e-05, 2.75789740e-05, 2.86272291e-05, 2.85879810e-05, - 2.59261928e-05, 2.11377186e-05, 1.63518626e-05, 1.73181369e-05, - 2.23300316e-05, 2.75900778e-05, 2.88867220e-05, 2.74428287e-05, - 2.21209666e-05, 1.97867937e-05, 2.18047499e-05, 2.51092848e-05, - 2.58418092e-05, 2.65017777e-05, 2.80562509e-05, 2.84826390e-05, - 2.60188841e-05, 2.20442674e-05, 1.92743629e-05, 2.17847355e-05, - 2.47693694e-05, 2.71407309e-05, 2.83714328e-05, 2.84419746e-05, - 2.43980625e-05, 2.13649592e-05, 2.08824507e-05, 2.31106308e-05, - 2.54516249e-05, 2.70136155e-05, 2.85181754e-05, 2.80611142e-05, - 2.72834817e-05, 2.46136103e-05, 1.97740736e-05, 1.74468690e-05, - 2.12184867e-05, 2.61580508e-05, 2.83746201e-05, 2.93618925e-05, - 2.94234849e-05, 2.88014289e-05, 2.33028802e-05, 2.10493667e-05, - 2.07543250e-05, 2.37914523e-05, 2.70525470e-05, 2.65187487e-05, - 2.73994870e-05, 2.89014021e-05, 2.33497673e-05, 2.13771207e-05, - 2.12985387e-05, 2.20280251e-05, 2.36932966e-05, 2.69628552e-05, - 2.82701645e-05, 2.77278913e-05, 2.19718832e-05, 1.83061415e-05, - 1.98657599e-05, 2.48042669e-05, 2.84307534e-05, 2.85016192e-05, - 2.80328679e-05, 2.48005972e-05, 2.18511538e-05, 1.99123500e-05, - 2.08240794e-05, 2.39541381e-05, 2.61437817e-05, 2.75430492e-05, - 2.88348468e-05, - 2.28834926e-05, 1.65331572e-05, 1.52600903e-05, 1.81117334e-05, - 2.33087544e-05, 2.90758701e-05, 3.24056221e-05, 3.25762180e-05, - 3.22240916e-05, 2.37791313e-05, 1.95588494e-05, 2.07490985e-05, - 2.33481124e-05, 2.37960105e-05, 2.46401269e-05, 2.87248195e-05, - 3.22844661e-05, 3.17169235e-05, 3.10336108e-05, 3.25787847e-05, - 2.12421429e-05, 1.72370250e-05, 1.76597979e-05, 2.21140839e-05, - 2.48898890e-05, 2.55462276e-05, 2.98488446e-05, 3.41902142e-05, - 3.55692563e-05, 1.76253814e-05, 1.16327435e-05, 1.38489374e-05, - 2.39171842e-05, 3.21511157e-05, 3.30395743e-05, 3.29768512e-05, - 3.38301841e-05, 3.40102883e-05, 2.47524133e-05, 1.70696086e-05, - 1.50387386e-05, 2.10122883e-05, 2.70781339e-05, 2.69472927e-05, - 2.63644172e-05, 2.95464467e-05, 3.33452893e-05, 3.16108762e-05, - 2.47251205e-05, 1.51877359e-05, 1.16312791e-05, 1.50939541e-05, - 2.34418615e-05, 3.28563799e-05, 3.61659892e-05, 3.49370570e-05, - 1.82653740e-05, 1.32180878e-05, 1.44485252e-05, 2.05689912e-05, - 2.90652699e-05, 3.55130753e-05, 3.70404058e-05, 3.47270805e-05, - 1.61944730e-05, 1.21619565e-05, 1.43285520e-05, 2.14300678e-05, - 3.22536520e-05, 3.72315134e-05, 3.54171127e-05, 3.35209676e-05, - 1.52167839e-05, 1.05532167e-05, 1.58469219e-05, 2.41389797e-05, - 2.81786612e-05, 3.00526539e-05, 3.21000032e-05, 2.04198398e-05, - 1.67846687e-05, 1.61406577e-05, 1.78821774e-05, 2.47147342e-05, - 3.22884810e-05, 3.39551213e-05, 3.31386861e-05, 2.15303590e-05, - 1.78454736e-05, 1.80553234e-05, 2.08119729e-05, 2.33326887e-05, - 2.56757523e-05, 3.05490061e-05, 3.28985261e-05, 2.26039275e-05, - 1.77091680e-05, 1.78583208e-05, 1.95998352e-05, 2.11461249e-05, - 2.52920425e-05, 3.04252588e-05, 3.33692891e-05, 3.32284161e-05, - 2.56324434e-05, 1.71823180e-05, 1.11668143e-05, 1.23758719e-05, - 1.95801050e-05, 3.06387585e-05, 3.42695467e-05, 3.03235369e-05, - 1.89420090e-05, 1.53748165e-05, 1.83502389e-05, 2.42457566e-05, - 2.59258989e-05, 2.76427917e-05, 3.16524272e-05, 3.28639209e-05, - 2.58600672e-05, 1.86914449e-05, 1.47877510e-05, 1.84656467e-05, - 2.37723393e-05, 2.92202699e-05, 3.26626739e-05, 3.27573849e-05, - 2.29829963e-05, 1.77387907e-05, 1.70107353e-05, 2.05242812e-05, - 2.49761531e-05, 2.86992715e-05, 3.29132625e-05, 3.17656840e-05, - 2.98197331e-05, 2.32501585e-05, 1.54110199e-05, 1.24998463e-05, - 1.76168346e-05, 2.65763594e-05, 3.22022306e-05, 3.55856753e-05, - 3.59154006e-05, 3.38947570e-05, 2.07552278e-05, 1.70660040e-05, - 1.67391950e-05, 2.18011650e-05, 2.89242433e-05, 2.81697237e-05, - 3.04161790e-05, 3.44361310e-05, 2.11155650e-05, 1.76862407e-05, - 1.75345769e-05, 1.87645243e-05, 2.17249085e-05, 2.85540172e-05, - 3.20943057e-05, 3.08621690e-05, 1.85389068e-05, 1.33840345e-05, - 1.55712569e-05, 2.39524904e-05, 3.27070516e-05, 3.29465425e-05, - 3.16941669e-05, 2.35936176e-05, 1.83846797e-05, 1.55899189e-05, - 1.69779282e-05, 2.23319879e-05, 2.69816556e-05, 3.03655352e-05, - 3.39284934e-05, - 2.45419904e-05, 2.15972575e-05, 2.08464945e-05, 2.27982087e-05, - 2.53391089e-05, 2.67909919e-05, 2.72806170e-05, 2.71325631e-05, - 2.68197107e-05, 2.47568950e-05, 2.30408095e-05, 2.35281753e-05, - 2.47564970e-05, 2.49543790e-05, 2.52108339e-05, 2.66548386e-05, - 2.74447460e-05, 2.70232802e-05, 2.66762990e-05, 2.69246596e-05, - 2.40639592e-05, 2.21171340e-05, 2.21272388e-05, 2.44393303e-05, - 2.55881397e-05, 2.54248712e-05, 2.64039752e-05, 2.73061188e-05, - 2.75118142e-05, 2.22848464e-05, 1.83964843e-05, 1.99719570e-05, - 2.55698967e-05, 2.81002709e-05, 2.75144164e-05, 2.69621563e-05, - 2.71113798e-05, 2.71728802e-05, 2.60488615e-05, 2.25807771e-05, - 2.09414460e-05, 2.41944715e-05, 2.63131586e-05, 2.56742202e-05, - 2.51008533e-05, 2.59946325e-05, 2.68763776e-05, 2.76393661e-05, - 2.59222808e-05, 2.09387578e-05, 1.81655652e-05, 2.07344862e-05, - 2.48935277e-05, 2.72895284e-05, 2.74574447e-05, 2.71992393e-05, - 2.23858566e-05, 1.96804352e-05, 2.06500966e-05, 2.41440267e-05, - 2.70136559e-05, 2.80034034e-05, 2.78992897e-05, 2.73245253e-05, - 2.10873113e-05, 1.89117323e-05, 2.06879007e-05, 2.44707527e-05, - 2.76564311e-05, 2.79966405e-05, 2.73423454e-05, 2.70534131e-05, - 2.09970884e-05, 1.76886179e-05, 2.17983923e-05, 2.59459667e-05, - 2.64966349e-05, 2.60515279e-05, 2.64312022e-05, 2.38562893e-05, - 2.23682273e-05, 2.18302484e-05, 2.23245700e-05, 2.48949438e-05, - 2.69199234e-05, 2.71596984e-05, 2.69943110e-05, 2.43303731e-05, - 2.28328887e-05, 2.28851843e-05, 2.40913796e-05, 2.46639070e-05, - 2.49840745e-05, 2.63449338e-05, 2.69541216e-05, 2.47406949e-05, - 2.25267145e-05, 2.25668504e-05, 2.36287859e-05, 2.40952368e-05, - 2.51831612e-05, 2.63671857e-05, 2.70053863e-05, 2.70086550e-05, - 2.68903209e-05, 2.32287461e-05, 1.82255072e-05, 1.86677850e-05, - 2.25076785e-05, 2.61353840e-05, 2.70438291e-05, 2.59474794e-05, - 2.31608773e-05, 2.15713684e-05, 2.31973170e-05, 2.56113090e-05, - 2.58026422e-05, 2.58347719e-05, 2.67453438e-05, 2.70074552e-05, - 2.68805620e-05, 2.35176339e-05, 2.06813781e-05, 2.27045171e-05, - 2.49097611e-05, 2.62008455e-05, 2.67979982e-05, 2.69688631e-05, - 2.47885863e-05, 2.26018722e-05, 2.22103312e-05, 2.41383044e-05, - 2.57841292e-05, 2.64358059e-05, 2.70927961e-05, 2.66248544e-05, - 2.59613258e-05, 2.52998813e-05, 2.13370533e-05, 1.89210447e-05, - 2.21482623e-05, 2.61014061e-05, 2.73770268e-05, 2.75305590e-05, - 2.74450477e-05, 2.71109570e-05, 2.45899607e-05, 2.30936952e-05, - 2.24139331e-05, 2.44600380e-05, 2.62590079e-05, 2.51183256e-05, - 2.56642087e-05, 2.69296742e-05, 2.38491665e-05, 2.28604795e-05, - 2.29151975e-05, 2.31754915e-05, 2.41282969e-05, 2.64383604e-05, - 2.70731268e-05, 2.64071660e-05, 2.35934909e-05, 2.05216530e-05, - 2.12834643e-05, 2.47022261e-05, 2.69829375e-05, 2.69874758e-05, - 2.65986461e-05, 2.54842234e-05, 2.33685617e-05, 2.15053238e-05, - 2.19744310e-05, 2.40284581e-05, 2.53279442e-05, 2.62982198e-05, - 2.72052139e-05, - 2.46270557e-05, 2.20912341e-05, 2.14145749e-05, 2.33398712e-05, - 2.56415340e-05, 2.65778048e-05, 2.67611498e-05, 2.65423532e-05, - 2.61724605e-05, 2.47401792e-05, 2.33027969e-05, 2.36957353e-05, - 2.48262932e-05, 2.50077195e-05, 2.51941216e-05, 2.64485649e-05, - 2.69962542e-05, 2.65085768e-05, 2.61383026e-05, 2.62666466e-05, - 2.43254610e-05, 2.26223347e-05, 2.25186424e-05, 2.46502948e-05, - 2.56640671e-05, 2.53173400e-05, 2.59408974e-05, 2.65765949e-05, - 2.66934863e-05, 2.27497231e-05, 1.91834972e-05, 2.06322795e-05, - 2.58342292e-05, 2.78981779e-05, 2.69916424e-05, 2.62671084e-05, - 2.63620366e-05, 2.64220251e-05, 2.63292991e-05, 2.33313168e-05, - 2.16208709e-05, 2.45613738e-05, 2.62570913e-05, 2.54112761e-05, - 2.47368322e-05, 2.54389956e-05, 2.61100317e-05, 2.73497606e-05, - 2.61587240e-05, 2.15688661e-05, 1.88507948e-05, 2.13080227e-05, - 2.49957978e-05, 2.67154393e-05, 2.65598642e-05, 2.63525715e-05, - 2.27184801e-05, 2.04364210e-05, 2.13997351e-05, 2.45977727e-05, - 2.68820253e-05, 2.73471139e-05, 2.70484978e-05, 2.65398823e-05, - 2.14720574e-05, 1.97219325e-05, 2.14954105e-05, 2.48496358e-05, - 2.72843664e-05, 2.71568512e-05, 2.64879203e-05, 2.63220525e-05, - 2.16427613e-05, 1.86021804e-05, 2.25885480e-05, 2.63125134e-05, - 2.63217521e-05, 2.54433901e-05, 2.56759944e-05, 2.42303901e-05, - 2.31131088e-05, 2.25412227e-05, 2.27350498e-05, 2.47491844e-05, - 2.62969202e-05, 2.64110734e-05, 2.62898846e-05, 2.46301858e-05, - 2.34638514e-05, 2.34788696e-05, 2.44648546e-05, 2.47021701e-05, - 2.46970725e-05, 2.57640346e-05, 2.62660679e-05, 2.49612524e-05, - 2.30679056e-05, 2.30829511e-05, 2.41160171e-05, 2.43912654e-05, - 2.50347026e-05, 2.58105794e-05, 2.62768258e-05, 2.62979815e-05, - 2.73281695e-05, 2.42321243e-05, 1.91250240e-05, 1.92900041e-05, - 2.25607293e-05, 2.54745830e-05, 2.62231073e-05, 2.52689726e-05, - 2.36278585e-05, 2.24156143e-05, 2.38400254e-05, 2.58240378e-05, - 2.57639782e-05, 2.55136620e-05, 2.61475646e-05, 2.63407373e-05, - 2.72688564e-05, 2.42013622e-05, 2.13312142e-05, 2.31119548e-05, - 2.49511509e-05, 2.57612117e-05, 2.60891089e-05, 2.63028898e-05, - 2.49464440e-05, 2.31660193e-05, 2.28199299e-05, 2.46007406e-05, - 2.59175773e-05, 2.61562428e-05, 2.64474886e-05, 2.59733513e-05, - 2.53562969e-05, 2.55994398e-05, 2.20665162e-05, 1.96072505e-05, - 2.25599232e-05, 2.60557188e-05, 2.69165197e-05, 2.67162969e-05, - 2.65695810e-05, 2.63539797e-05, 2.51813041e-05, 2.40725684e-05, - 2.31926442e-05, 2.47490910e-05, 2.58835502e-05, 2.44778522e-05, - 2.48844445e-05, 2.60553184e-05, 2.40562012e-05, 2.35489761e-05, - 2.36717314e-05, 2.36956333e-05, 2.43054821e-05, 2.61825339e-05, - 2.65252754e-05, 2.58040928e-05, 2.43526550e-05, 2.15983125e-05, - 2.19385265e-05, 2.46315089e-05, 2.63277282e-05, 2.63042154e-05, - 2.59479230e-05, 2.57829999e-05, 2.40745448e-05, 2.22501373e-05, - 2.24949450e-05, 2.40369590e-05, 2.49398046e-05, 2.57272340e-05, - 2.64740647e-05, - 2.57218316e-05, 2.92028778e-05, 2.98917014e-05, 2.78392765e-05, - 2.48051452e-05, 2.21775355e-05, 2.07047285e-05, 2.07392837e-05, - 2.10754576e-05, 2.53530099e-05, 2.76833567e-05, 2.70750531e-05, - 2.54249097e-05, 2.51456959e-05, 2.47296991e-05, 2.23921877e-05, - 2.06381645e-05, 2.11270582e-05, 2.16132794e-05, 2.08725856e-05, - 2.64124731e-05, 2.86239880e-05, 2.87077479e-05, 2.59207803e-05, - 2.43068374e-05, 2.43246095e-05, 2.22274124e-05, 2.00133569e-05, - 1.93478322e-05, 2.84723961e-05, 3.15668665e-05, 3.05724293e-05, - 2.44843971e-05, 2.02299728e-05, 2.03207778e-05, 2.06957761e-05, - 2.02707195e-05, 2.01630078e-05, 2.38689157e-05, 2.78796588e-05, - 2.96175227e-05, 2.62612848e-05, 2.31367049e-05, 2.37335250e-05, - 2.44034490e-05, 2.26377414e-05, 2.06041079e-05, 2.07333374e-05, - 2.40014012e-05, 2.97011302e-05, 3.20554787e-05, 2.99962905e-05, - 2.52655057e-05, 2.05334363e-05, 1.91339763e-05, 1.97760212e-05, - 2.84450870e-05, 3.06191275e-05, 2.97679036e-05, 2.63189406e-05, - 2.20015334e-05, 1.90958041e-05, 1.85498274e-05, 1.97901004e-05, - 2.98843274e-05, 3.11068411e-05, 2.96214120e-05, 2.59222777e-05, - 2.05048008e-05, 1.84233080e-05, 1.95018325e-05, 2.04273626e-05, - 2.96183496e-05, 3.16229643e-05, 2.86108440e-05, 2.40608974e-05, - 2.26815586e-05, 2.24133675e-05, 2.13745526e-05, 2.66739650e-05, - 2.81035981e-05, 2.86911010e-05, 2.84680545e-05, 2.50245298e-05, - 2.09856860e-05, 2.01926171e-05, 2.06129563e-05, 2.60848402e-05, - 2.77307672e-05, 2.77039083e-05, 2.63876596e-05, 2.55254484e-05, - 2.47021326e-05, 2.20223835e-05, 2.07311069e-05, 2.55363093e-05, - 2.81409049e-05, 2.81164736e-05, 2.69202900e-05, 2.63783955e-05, - 2.46135007e-05, 2.20513928e-05, 2.05161130e-05, 2.05691642e-05, - 2.28914335e-05, 2.69425451e-05, 3.13286700e-05, 3.18247629e-05, - 2.83691294e-05, 2.21361747e-05, 2.01347320e-05, 2.23864235e-05, - 2.74722895e-05, 2.87434970e-05, 2.73245407e-05, 2.43941223e-05, - 2.38812821e-05, 2.33925412e-05, 2.13393939e-05, 2.07107862e-05, - 2.28646489e-05, 2.69451547e-05, 2.99206444e-05, 2.80317373e-05, - 2.51959888e-05, 2.25946022e-05, 2.09209078e-05, 2.07760770e-05, - 2.54409207e-05, 2.80390424e-05, 2.84195653e-05, 2.63246889e-05, - 2.40965046e-05, 2.25770930e-05, 2.06378879e-05, 2.13775676e-05, - 2.25637938e-05, 2.48540879e-05, 2.91517004e-05, 3.14390820e-05, - 2.86684948e-05, 2.34515212e-05, 2.07130714e-05, 1.93309881e-05, - 1.92432702e-05, 2.02454331e-05, 2.57712373e-05, 2.71025311e-05, - 2.80167081e-05, 2.59193123e-05, 2.26469056e-05, 2.37959325e-05, - 2.25467670e-05, 2.01318762e-05, 2.66739222e-05, 2.76502787e-05, - 2.75275813e-05, 2.74279801e-05, 2.63088453e-05, 2.26192449e-05, - 2.09564128e-05, 2.18637680e-05, 2.68091851e-05, 2.91757583e-05, - 2.93189410e-05, 2.53766464e-05, 2.07863554e-05, 2.06916145e-05, - 2.14220963e-05, 2.46163223e-05, 2.70911833e-05, 2.89640823e-05, - 2.87653179e-05, 2.63584364e-05, 2.40218247e-05, 2.21223267e-05, - 2.01760104e-05, - 2.56911777e-05, 3.14231493e-05, 3.27157520e-05, 2.93574511e-05, - 2.46596863e-05, 2.08219690e-05, 1.88516472e-05, 1.88520676e-05, - 1.92151510e-05, 2.50841149e-05, 2.86983387e-05, 2.76857477e-05, - 2.52693948e-05, 2.48744268e-05, 2.42500502e-05, 2.10931021e-05, - 1.88133417e-05, 1.93548867e-05, 1.99217791e-05, 1.89699308e-05, - 2.68565945e-05, 3.05204578e-05, 3.04515041e-05, 2.61046074e-05, - 2.37741156e-05, 2.36340491e-05, 2.07137671e-05, 1.79311353e-05, - 1.71265303e-05, 3.02117459e-05, 3.64728745e-05, 3.41343478e-05, - 2.41863952e-05, 1.84669866e-05, 1.83985878e-05, 1.87415745e-05, - 1.82175203e-05, 1.80923272e-05, 2.33751475e-05, 2.97752649e-05, - 3.25075576e-05, 2.67688975e-05, 2.21419770e-05, 2.27400696e-05, - 2.35132611e-05, 2.11516455e-05, 1.85946709e-05, 1.90174536e-05, - 2.35125005e-05, 3.25355230e-05, 3.70494842e-05, 3.29056019e-05, - 2.50858042e-05, 1.86194149e-05, 1.68472868e-05, 1.75986796e-05, - 2.99486515e-05, 3.45022357e-05, 3.29404603e-05, 2.69597589e-05, - 2.06593944e-05, 1.69188394e-05, 1.62158926e-05, 1.76464365e-05, - 3.23057889e-05, 3.56295068e-05, 3.28296680e-05, 2.62994485e-05, - 1.86986152e-05, 1.60801373e-05, 1.72831969e-05, 1.84087383e-05, - 3.24306692e-05, 3.72035249e-05, 3.10481325e-05, 2.37103644e-05, - 2.14769356e-05, 2.08418942e-05, 1.95036773e-05, 2.73731949e-05, - 3.01254456e-05, 3.10192069e-05, 3.01125281e-05, 2.45196128e-05, - 1.91234328e-05, 1.81276842e-05, 1.86395985e-05, 2.64373066e-05, - 2.93348129e-05, 2.92322296e-05, 2.69585094e-05, 2.53736362e-05, - 2.39667326e-05, 2.03867044e-05, 1.87868520e-05, 2.55807201e-05, - 2.98247343e-05, 2.97446039e-05, 2.78859451e-05, 2.68499609e-05, - 2.39756810e-05, 2.04376865e-05, 1.85133801e-05, 1.85850608e-05, - 2.22139445e-05, 2.87125466e-05, 3.64684304e-05, 3.63462559e-05, - 2.94046378e-05, 2.04713989e-05, 1.80226298e-05, 2.07614799e-05, - 2.86822477e-05, 3.13883438e-05, 2.87244208e-05, 2.40160963e-05, - 2.31155241e-05, 2.22616307e-05, 1.95575602e-05, 1.87751620e-05, - 2.21390079e-05, 2.82054863e-05, 3.29583472e-05, 2.94383657e-05, - 2.49304206e-05, 2.11799989e-05, 1.89972808e-05, 1.88520845e-05, - 2.53827218e-05, 2.97044774e-05, 3.03845551e-05, 2.69790751e-05, - 2.35470161e-05, 2.12713505e-05, 1.87019031e-05, 1.95702522e-05, - 2.10269911e-05, 2.47237899e-05, 3.18280481e-05, 3.58294358e-05, - 3.04254792e-05, 2.25537645e-05, 1.88951326e-05, 1.71094474e-05, - 1.69807940e-05, 1.81841922e-05, 2.63364422e-05, 2.89282717e-05, - 3.00474899e-05, 2.61911852e-05, 2.12898624e-05, 2.25182486e-05, - 2.08860741e-05, 1.79909074e-05, 2.71621814e-05, 2.93043507e-05, - 2.92253450e-05, 2.86948251e-05, 2.66096242e-05, 2.13407280e-05, - 1.91327482e-05, 2.01812880e-05, 2.81102734e-05, 3.27592270e-05, - 3.19462213e-05, 2.50618751e-05, 1.88702849e-05, 1.87433693e-05, - 1.96236163e-05, 2.43985078e-05, 2.84631116e-05, 3.15447533e-05, - 3.07724432e-05, 2.64844092e-05, 2.30052204e-05, 2.05140180e-05, - 1.81178439e-05, - 2.54681748e-05, 2.52143202e-05, 2.50202027e-05, 2.46233225e-05, - 2.42672084e-05, 2.43703805e-05, 2.42463246e-05, 2.44833330e-05, - 2.49144588e-05, 2.56373920e-05, 2.56927836e-05, 2.58074185e-05, - 2.53698908e-05, 2.52807220e-05, 2.52951819e-05, 2.44902465e-05, - 2.39895086e-05, 2.45461069e-05, 2.49754614e-05, 2.47921890e-05, - 2.51575550e-05, 2.50079570e-05, 2.55243185e-05, 2.51154021e-05, - 2.47516470e-05, 2.53715771e-05, 2.51799450e-05, 2.43342111e-05, - 2.40542208e-05, 2.51358722e-05, 2.38617186e-05, 2.46418162e-05, - 2.42324350e-05, 2.30107824e-05, 2.39668399e-05, 2.47694022e-05, - 2.46001182e-05, 2.45184417e-05, 2.38661768e-05, 2.37845368e-05, - 2.44345470e-05, 2.47080624e-05, 2.44963915e-05, 2.55335921e-05, - 2.63084399e-05, 2.57739134e-05, 2.49187433e-05, 2.36057633e-05, - 2.40726870e-05, 2.46859204e-05, 2.44752030e-05, 2.50123101e-05, - 2.51738354e-05, 2.42784582e-05, 2.41087405e-05, 2.44942685e-05, - 2.56878333e-05, 2.41201909e-05, 2.41081280e-05, 2.44185124e-05, - 2.40123375e-05, 2.33853563e-05, 2.34754843e-05, 2.43185423e-05, - 2.59002199e-05, 2.37761372e-05, 2.38063331e-05, 2.45205059e-05, - 2.36737295e-05, 2.33365037e-05, 2.42897747e-05, 2.46698578e-05, - 2.45972248e-05, 2.29343344e-05, 2.37629357e-05, 2.36965824e-05, - 2.45809230e-05, 2.57875250e-05, 2.54899956e-05, 2.48527529e-05, - 2.38588509e-05, 2.41279528e-05, 2.53654853e-05, 2.59112387e-05, - 2.47707867e-05, 2.45354097e-05, 2.47334905e-05, 2.48727246e-05, - 2.42312749e-05, 2.43729549e-05, 2.47372778e-05, 2.55339123e-05, - 2.62212528e-05, 2.54119292e-05, 2.47753663e-05, 2.48981291e-05, - 2.47162540e-05, 2.48127811e-05, 2.45250183e-05, 2.50159123e-05, - 2.56811396e-05, 2.53544036e-05, 2.47315483e-05, 2.47183199e-05, - 2.28903904e-05, 2.25789814e-05, 2.31412556e-05, 2.49008702e-05, - 2.68457109e-05, 2.57589557e-05, 2.47094941e-05, 2.60050722e-05, - 2.48000216e-05, 2.35400819e-05, 2.40660688e-05, 2.43530986e-05, - 2.48841607e-05, 2.55085766e-05, 2.49596988e-05, 2.46939216e-05, - 2.30179415e-05, 2.37940213e-05, 2.46232362e-05, 2.52325726e-05, - 2.53489680e-05, 2.53611172e-05, 2.49881172e-05, 2.47422129e-05, - 2.50696894e-05, 2.45916256e-05, 2.45056060e-05, 2.43894664e-05, - 2.44503803e-05, 2.48386193e-05, 2.45721628e-05, 2.51579484e-05, - 2.58865928e-05, 2.43004331e-05, 2.41263422e-05, 2.45167459e-05, - 2.54244011e-05, 2.46531096e-05, 2.40796262e-05, 2.40282745e-05, - 2.41355937e-05, 2.46031854e-05, 2.37196304e-05, 2.27051485e-05, - 2.36985747e-05, 2.48366696e-05, 2.51897128e-05, 2.68958023e-05, - 2.64768213e-05, 2.48741837e-05, 2.54769233e-05, 2.39783489e-05, - 2.36751134e-05, 2.45765624e-05, 2.54204360e-05, 2.47921103e-05, - 2.45194361e-05, 2.53670196e-05, 2.34706340e-05, 2.24315990e-05, - 2.45008568e-05, 2.58427429e-05, 2.47170617e-05, 2.47298307e-05, - 2.51892382e-05, 2.41866486e-05, 2.37533086e-05, 2.40255263e-05, - 2.49807033e-05, 2.60724717e-05, 2.61472795e-05, 2.54526810e-05, - 2.44691916e-05, - 2.53675599e-05, 2.50078080e-05, 2.47857561e-05, 2.47709187e-05, - 2.46834660e-05, 2.45957498e-05, 2.43377928e-05, 2.44542242e-05, - 2.47092970e-05, 2.54566068e-05, 2.54422803e-05, 2.55381338e-05, - 2.53109537e-05, 2.52577016e-05, 2.52548474e-05, 2.46785561e-05, - 2.42054207e-05, 2.45459584e-05, 2.48209381e-05, 2.46191256e-05, - 2.51813687e-05, 2.49402834e-05, 2.52597528e-05, 2.51670012e-05, - 2.49451335e-05, 2.52787881e-05, 2.50008603e-05, 2.42537855e-05, - 2.39910031e-05, 2.50375971e-05, 2.36191377e-05, 2.44101547e-05, - 2.46601167e-05, 2.36653172e-05, 2.41420656e-05, 2.45778951e-05, - 2.44229315e-05, 2.43655572e-05, 2.44385521e-05, 2.42183206e-05, - 2.44276098e-05, 2.49208091e-05, 2.47457306e-05, 2.53257326e-05, - 2.57646050e-05, 2.53351374e-05, 2.46284025e-05, 2.40339497e-05, - 2.45588594e-05, 2.45874588e-05, 2.39691835e-05, 2.47645200e-05, - 2.52003679e-05, 2.43241153e-05, 2.39663241e-05, 2.42760697e-05, - 2.53850395e-05, 2.40253627e-05, 2.41747164e-05, 2.47443534e-05, - 2.43950490e-05, 2.36385635e-05, 2.35543197e-05, 2.42017747e-05, - 2.53665345e-05, 2.36630738e-05, 2.39848412e-05, 2.48195382e-05, - 2.40327432e-05, 2.34632432e-05, 2.41277263e-05, 2.44839305e-05, - 2.45393694e-05, 2.28651305e-05, 2.41118599e-05, 2.43461653e-05, - 2.47524808e-05, 2.53128548e-05, 2.50206525e-05, 2.49911970e-05, - 2.42424077e-05, 2.43508739e-05, 2.51828768e-05, 2.55937843e-05, - 2.46283108e-05, 2.43789026e-05, 2.45467701e-05, 2.50232492e-05, - 2.45286344e-05, 2.46227553e-05, 2.49337249e-05, 2.54026343e-05, - 2.57393435e-05, 2.50840528e-05, 2.45868684e-05, 2.50457892e-05, - 2.48021457e-05, 2.48662612e-05, 2.47783660e-05, 2.50993218e-05, - 2.54554931e-05, 2.50610030e-05, 2.45281849e-05, 2.45319637e-05, - 2.38486077e-05, 2.35015226e-05, 2.31126219e-05, 2.43413978e-05, - 2.60788386e-05, 2.52614167e-05, 2.44446519e-05, 2.54100591e-05, - 2.49120740e-05, 2.39374356e-05, 2.44586433e-05, 2.47266221e-05, - 2.49976733e-05, 2.52853891e-05, 2.47725290e-05, 2.45462074e-05, - 2.39204742e-05, 2.43145493e-05, 2.45099273e-05, 2.51378704e-05, - 2.52961159e-05, 2.51322530e-05, 2.47166565e-05, 2.45796476e-05, - 2.51433021e-05, 2.47319333e-05, 2.46360944e-05, 2.47264406e-05, - 2.47722428e-05, 2.48728584e-05, 2.44777548e-05, 2.48701856e-05, - 2.53788486e-05, 2.47028351e-05, 2.42854297e-05, 2.41441691e-05, - 2.52007941e-05, 2.48497791e-05, 2.42602536e-05, 2.39759199e-05, - 2.40030301e-05, 2.44194205e-05, 2.43390565e-05, 2.35708621e-05, - 2.41444930e-05, 2.50057434e-05, 2.50543970e-05, 2.59958408e-05, - 2.56474532e-05, 2.45160994e-05, 2.53597186e-05, 2.43712707e-05, - 2.41832092e-05, 2.47755432e-05, 2.53359294e-05, 2.48537433e-05, - 2.45066875e-05, 2.50406294e-05, 2.41154144e-05, 2.30496428e-05, - 2.45178035e-05, 2.55680945e-05, 2.45699305e-05, 2.45591855e-05, - 2.48916301e-05, 2.46357001e-05, 2.42760039e-05, 2.42432100e-05, - 2.49072163e-05, 2.57025029e-05, 2.56559800e-05, 2.51168985e-05, - 2.43460311e-05, - 2.52831953e-05, 3.01987222e-05, 3.12481757e-05, 2.96743097e-05, - 2.60638147e-05, 2.15895041e-05, 1.92647373e-05, 1.89494111e-05, - 1.88510573e-05, 2.44562202e-05, 2.75623514e-05, 2.65734322e-05, - 2.50210837e-05, 2.47625660e-05, 2.41116327e-05, 2.17477850e-05, - 1.95629010e-05, 1.95136580e-05, 1.96539839e-05, 1.86974992e-05, - 2.68113700e-05, 2.99166802e-05, 2.91009368e-05, 2.61897012e-05, - 2.44072132e-05, 2.33625770e-05, 2.03431752e-05, 1.79275505e-05, - 1.71884340e-05, 2.95115108e-05, 3.45072039e-05, 3.25183777e-05, - 2.56261307e-05, 2.04776410e-05, 1.90398953e-05, 1.84336119e-05, - 1.79675673e-05, 1.79063801e-05, 2.53184114e-05, 3.13017666e-05, - 3.20101830e-05, 2.74125799e-05, 2.29746180e-05, 2.21778878e-05, - 2.19528416e-05, 2.00746128e-05, 1.80540510e-05, 2.03706869e-05, - 2.51495398e-05, 3.16463499e-05, 3.38104911e-05, 3.13630593e-05, - 2.51275183e-05, 1.89162758e-05, 1.67323593e-05, 1.72780590e-05, - 2.85083755e-05, 3.34471660e-05, 3.27378804e-05, 2.80307464e-05, - 2.19038847e-05, 1.77640014e-05, 1.66327875e-05, 1.75641477e-05, - 2.97367547e-05, 3.43730946e-05, 3.31445913e-05, 2.72724980e-05, - 1.98467660e-05, 1.66121352e-05, 1.71068295e-05, 1.81293118e-05, - 3.17214529e-05, 3.59827322e-05, 3.21922208e-05, 2.59528599e-05, - 2.20765266e-05, 1.96986443e-05, 1.84771910e-05, 2.77237448e-05, - 3.14288596e-05, 3.15979800e-05, 2.90993137e-05, 2.35143521e-05, - 1.89213751e-05, 1.79315468e-05, 1.83480135e-05, 2.68610617e-05, - 3.02689899e-05, 2.99696217e-05, 2.75371665e-05, 2.48849208e-05, - 2.25340216e-05, 1.96467693e-05, 1.84842630e-05, 2.60182452e-05, - 2.98737007e-05, 2.96681018e-05, 2.86633521e-05, 2.70177389e-05, - 2.32833637e-05, 1.97827615e-05, 1.81867923e-05, 1.82968002e-05, - 2.55381438e-05, 3.25180613e-05, 3.55320797e-05, 3.30134675e-05, - 2.64697583e-05, 1.93013674e-05, 1.75725569e-05, 1.93287300e-05, - 2.88846098e-05, 3.27576979e-05, 3.00641813e-05, 2.52617393e-05, - 2.35039271e-05, 2.16847568e-05, 1.92225138e-05, 1.85743616e-05, - 2.52409379e-05, 3.00863812e-05, 3.19687893e-05, 2.88086129e-05, - 2.47191583e-05, 2.06509015e-05, 1.84803776e-05, 1.86110027e-05, - 2.55711885e-05, 2.99787060e-05, 3.05907579e-05, 2.80932557e-05, - 2.46126803e-05, 2.14706973e-05, 1.86376154e-05, 1.89811050e-05, - 1.97858353e-05, 2.60780617e-05, 3.20963475e-05, 3.33776181e-05, - 2.92302694e-05, 2.32158517e-05, 1.95478039e-05, 1.71976954e-05, - 1.68840795e-05, 1.79197557e-05, 2.85739606e-05, 3.24667557e-05, - 3.16319125e-05, 2.66885382e-05, 2.10099628e-05, 2.01565214e-05, - 1.88858601e-05, 1.73259151e-05, 2.66074513e-05, 3.06474443e-05, - 3.10763915e-05, 2.92388110e-05, 2.62014173e-05, 2.16175114e-05, - 1.92645328e-05, 1.94582547e-05, 3.05364328e-05, 3.52919546e-05, - 3.15900529e-05, 2.41441524e-05, 1.86670158e-05, 1.84868902e-05, - 1.90068567e-05, 2.59186979e-05, 3.03600694e-05, 3.20846399e-05, - 3.01271656e-05, 2.51512678e-05, 2.16346845e-05, 1.97456574e-05, - 1.80032662e-05, - 2.50793549e-05, 2.46667511e-05, 2.44188081e-05, 2.54345004e-05, - 2.59869808e-05, 2.50838304e-05, 2.43081319e-05, 2.40546436e-05, - 2.37996865e-05, 2.48969529e-05, 2.48434007e-05, 2.48361810e-05, - 2.51298150e-05, 2.51678052e-05, 2.50814785e-05, 2.50624627e-05, - 2.45637949e-05, 2.42586378e-05, 2.40946592e-05, 2.37930799e-05, - 2.53326818e-05, 2.49822734e-05, 2.46995212e-05, 2.53684742e-05, - 2.54792809e-05, 2.49155803e-05, 2.42387869e-05, 2.36557498e-05, - 2.34072428e-05, 2.49707948e-05, 2.33929912e-05, 2.41149699e-05, - 2.59772006e-05, 2.54513689e-05, 2.43517673e-05, 2.36866328e-05, - 2.35497651e-05, 2.35586242e-05, 2.62001970e-05, 2.58426883e-05, - 2.47513735e-05, 2.56660345e-05, 2.53765749e-05, 2.45739037e-05, - 2.40737611e-05, 2.38359892e-05, 2.34407305e-05, 2.50877703e-05, - 2.60363302e-05, 2.46276417e-05, 2.29849354e-05, 2.43658300e-05, - 2.52740254e-05, 2.41418428e-05, 2.31333105e-05, 2.32537556e-05, - 2.46877616e-05, 2.41660220e-05, 2.47508889e-05, 2.58667209e-05, - 2.53829554e-05, 2.40227228e-05, 2.33601261e-05, 2.34816997e-05, - 2.40990909e-05, 2.37974235e-05, 2.49153412e-05, 2.58208193e-05, - 2.48443796e-05, 2.34106091e-05, 2.32564369e-05, 2.35937531e-05, - 2.47005607e-05, 2.32053608e-05, 2.55158600e-05, 2.63905168e-05, - 2.51024884e-05, 2.36973957e-05, 2.33603202e-05, 2.55285945e-05, - 2.57157900e-05, 2.53384271e-05, 2.48539810e-05, 2.46017030e-05, - 2.39004076e-05, 2.35628528e-05, 2.36649309e-05, 2.55529896e-05, - 2.56766588e-05, 2.56101159e-05, 2.56359880e-05, 2.50060971e-05, - 2.42452461e-05, 2.38693998e-05, 2.37066016e-05, 2.55240799e-05, - 2.52918343e-05, 2.52496895e-05, 2.57104480e-05, 2.54369629e-05, - 2.47092079e-05, 2.39490759e-05, 2.35913774e-05, 2.36486752e-05, - 2.69100036e-05, 2.67968149e-05, 2.35480654e-05, 2.31730323e-05, - 2.40257550e-05, 2.35644987e-05, 2.33052125e-05, 2.34523429e-05, - 2.54295412e-05, 2.55206883e-05, 2.58912895e-05, 2.58558906e-05, - 2.52461430e-05, 2.44654072e-05, 2.39321001e-05, 2.37863954e-05, - 2.67749897e-05, 2.61524433e-05, 2.45236049e-05, 2.50457935e-05, - 2.51172699e-05, 2.42445209e-05, 2.36023684e-05, 2.37792666e-05, - 2.53783558e-05, 2.53890509e-05, 2.52946824e-05, 2.58863770e-05, - 2.57084922e-05, 2.47839633e-05, 2.38738793e-05, 2.37346620e-05, - 2.36779808e-05, 2.59637025e-05, 2.51052145e-05, 2.35003451e-05, - 2.47624022e-05, 2.53330693e-05, 2.45112304e-05, 2.34240589e-05, - 2.32053338e-05, 2.35252697e-05, 2.64186337e-05, 2.66687182e-05, - 2.58237438e-05, 2.55823915e-05, 2.44504448e-05, 2.32809487e-05, - 2.30529875e-05, 2.31055856e-05, 2.50911624e-05, 2.58344846e-05, - 2.60315928e-05, 2.55717363e-05, 2.51408686e-05, 2.48529731e-05, - 2.41702724e-05, 2.38208417e-05, 2.63775137e-05, 2.54652730e-05, - 2.48904383e-05, 2.47275647e-05, 2.38162996e-05, 2.37297626e-05, - 2.37298760e-05, 2.60349004e-05, 2.61347040e-05, 2.52392525e-05, - 2.49430132e-05, 2.46478115e-05, 2.40912616e-05, 2.38851622e-05, - 2.36287550e-05, - 2.45830112e-05, 2.18957611e-05, 2.11907065e-05, 2.31794552e-05, - 2.56098702e-05, 2.66885346e-05, 2.69503566e-05, 2.67335036e-05, - 2.63524725e-05, 2.47177631e-05, 2.31783463e-05, 2.35998071e-05, - 2.47937441e-05, 2.49862978e-05, 2.51933621e-05, 2.65502041e-05, - 2.71847933e-05, 2.66798749e-05, 2.62910802e-05, 2.64554504e-05, - 2.42413866e-05, 2.24422545e-05, 2.23494978e-05, 2.45876747e-05, - 2.56708220e-05, 2.53384773e-05, 2.60652216e-05, 2.68044830e-05, - 2.69534163e-05, 2.25789032e-05, 1.88853956e-05, 2.03779621e-05, - 2.58180003e-05, 2.80920783e-05, 2.71974640e-05, 2.64648718e-05, - 2.65797955e-05, 2.66443836e-05, 2.63352620e-05, 2.31445110e-05, - 2.13901073e-05, 2.44717107e-05, 2.63187407e-05, 2.54656503e-05, - 2.47749399e-05, 2.55532032e-05, 2.63146462e-05, 2.75258652e-05, - 2.61633402e-05, 2.13422180e-05, 1.85562602e-05, 2.10806149e-05, - 2.49658426e-05, 2.69145108e-05, 2.68316044e-05, 2.65948994e-05, - 2.25636522e-05, 2.01674710e-05, 2.11552492e-05, 2.44971383e-05, - 2.69946178e-05, 2.76129418e-05, 2.73452358e-05, 2.67794230e-05, - 2.12713015e-05, 1.94320966e-05, 2.12471938e-05, 2.47704349e-05, - 2.74748313e-05, 2.74591500e-05, 2.67422909e-05, 2.65325170e-05, - 2.14164084e-05, 1.82824002e-05, 2.23733035e-05, 2.63033608e-05, - 2.64097722e-05, 2.55690687e-05, 2.58492117e-05, 2.41261215e-05, - 2.29197557e-05, 2.23337256e-05, 2.25706785e-05, 2.47489325e-05, - 2.64794304e-05, 2.66320927e-05, 2.64914848e-05, 2.45532951e-05, - 2.32963986e-05, 2.33166807e-05, 2.43702317e-05, 2.46690222e-05, - 2.47191215e-05, 2.59030825e-05, 2.64620623e-05, 2.49109521e-05, - 2.28981464e-05, 2.29168908e-05, 2.39914700e-05, 2.43048534e-05, - 2.50488741e-05, 2.59471479e-05, 2.64834790e-05, 2.65016681e-05, - 2.73605642e-05, 2.40457689e-05, 1.88153820e-05, 1.90099796e-05, - 2.24383399e-05, 2.56136543e-05, 2.64493429e-05, 2.53996125e-05, - 2.34875852e-05, 2.21890399e-05, 2.36844833e-05, 2.58157804e-05, - 2.57958774e-05, 2.55846802e-05, 2.63144595e-05, 2.65366113e-05, - 2.73065482e-05, 2.40538544e-05, 2.10958717e-05, 2.29609678e-05, - 2.49290320e-05, 2.58699733e-05, 2.62782780e-05, 2.64960316e-05, - 2.49053174e-05, 2.29967079e-05, 2.26334036e-05, 2.44989945e-05, - 2.59273469e-05, 2.62554242e-05, 2.66454250e-05, 2.61414218e-05, - 2.54761709e-05, 2.55662321e-05, 2.18427117e-05, 1.93272729e-05, - 2.23895610e-05, 2.61044143e-05, 2.71024510e-05, 2.69768376e-05, - 2.68358751e-05, 2.65731067e-05, 2.50855431e-05, 2.38835632e-05, - 2.29978429e-05, 2.46789289e-05, 2.59862591e-05, 2.45559137e-05, - 2.50147103e-05, 2.62836428e-05, 2.39690306e-05, 2.33772597e-05, - 2.34958262e-05, 2.35507995e-05, 2.42331553e-05, 2.62784927e-05, - 2.67053209e-05, 2.59505077e-05, 2.42010541e-05, 2.13247150e-05, - 2.17195135e-05, 2.46129831e-05, 2.65199528e-05, 2.65016260e-05, - 2.61141836e-05, 2.57587040e-05, 2.39194436e-05, 2.20299491e-05, - 2.23088618e-05, 2.39790984e-05, 2.49929118e-05, 2.58618724e-05, - 2.66950892e-05, - 2.49628727e-05, 2.43081689e-05, 2.40050127e-05, 2.53869454e-05, - 2.62992516e-05, 2.53629733e-05, 2.45433302e-05, 2.41982830e-05, - 2.38049588e-05, 2.47428248e-05, 2.45346283e-05, 2.45446422e-05, - 2.50557651e-05, 2.51316989e-05, 2.50519459e-05, 2.53036436e-05, - 2.48984264e-05, 2.44086722e-05, 2.41147004e-05, 2.38283633e-05, - 2.52699974e-05, 2.47443816e-05, 2.43305521e-05, 2.53492053e-05, - 2.56401375e-05, 2.48671561e-05, 2.42176243e-05, 2.37889947e-05, - 2.35770432e-05, 2.47207680e-05, 2.28706086e-05, 2.36633053e-05, - 2.63143030e-05, 2.61776007e-05, 2.46666853e-05, 2.37155974e-05, - 2.36044047e-05, 2.36343659e-05, 2.66883339e-05, 2.60066126e-05, - 2.44977439e-05, 2.57479394e-05, 2.56331113e-05, 2.44716383e-05, - 2.37275714e-05, 2.36259314e-05, 2.34050370e-05, 2.55928355e-05, - 2.64449319e-05, 2.43098310e-05, 2.22866933e-05, 2.39379854e-05, - 2.52676243e-05, 2.43489223e-05, 2.32531174e-05, 2.32974386e-05, - 2.43082962e-05, 2.37946937e-05, 2.45368182e-05, 2.60316912e-05, - 2.57963169e-05, 2.44465028e-05, 2.36651115e-05, 2.35967544e-05, - 2.35092345e-05, 2.33824041e-05, 2.47863362e-05, 2.59852109e-05, - 2.53006461e-05, 2.37573898e-05, 2.33493557e-05, 2.36365235e-05, - 2.44136746e-05, 2.27764788e-05, 2.55717591e-05, 2.69365636e-05, - 2.53184494e-05, 2.34731677e-05, 2.31785478e-05, 2.55350178e-05, - 2.58279223e-05, 2.52972231e-05, 2.45493260e-05, 2.43718366e-05, - 2.39529821e-05, 2.36349464e-05, 2.37003102e-05, 2.55975099e-05, - 2.57447148e-05, 2.56442380e-05, 2.56994133e-05, 2.48776672e-05, - 2.39248229e-05, 2.37553666e-05, 2.37363572e-05, 2.55930496e-05, - 2.51843923e-05, 2.51210215e-05, 2.57890643e-05, 2.54183276e-05, - 2.45575385e-05, 2.38569141e-05, 2.36187013e-05, 2.36859275e-05, - 2.78027821e-05, 2.74332162e-05, 2.31667743e-05, 2.24614261e-05, - 2.33788189e-05, 2.33363836e-05, 2.33038625e-05, 2.31542367e-05, - 2.53760604e-05, 2.56048611e-05, 2.60545255e-05, 2.61534334e-05, - 2.53659594e-05, 2.43669311e-05, 2.39398696e-05, 2.38455976e-05, - 2.76144377e-05, 2.64385379e-05, 2.41835675e-05, 2.48210797e-05, - 2.50579188e-05, 2.41745766e-05, 2.35678608e-05, 2.38255421e-05, - 2.53976606e-05, 2.53254883e-05, 2.52032244e-05, 2.60596763e-05, - 2.59787630e-05, 2.49010274e-05, 2.39738710e-05, 2.36720400e-05, - 2.34271395e-05, 2.62623833e-05, 2.49916139e-05, 2.29137068e-05, - 2.44212270e-05, 2.55348485e-05, 2.48150626e-05, 2.36024514e-05, - 2.33284133e-05, 2.35762044e-05, 2.68510057e-05, 2.72429721e-05, - 2.59891225e-05, 2.56487037e-05, 2.44429234e-05, 2.27514320e-05, - 2.26103865e-05, 2.30412992e-05, 2.49186943e-05, 2.59798072e-05, - 2.62746941e-05, 2.55833453e-05, 2.50079781e-05, 2.49885457e-05, - 2.43176233e-05, 2.37138835e-05, 2.67746316e-05, 2.56915752e-05, - 2.46700922e-05, 2.45101715e-05, 2.38730868e-05, 2.37735018e-05, - 2.36589417e-05, 2.63831180e-05, 2.64144122e-05, 2.51781640e-05, - 2.46936674e-05, 2.43254493e-05, 2.37930291e-05, 2.37620377e-05, - 2.37252160e-05, - 2.55518519e-05, 2.72713868e-05, 2.75189287e-05, 2.67114565e-05, - 2.51460227e-05, 2.33691304e-05, 2.22527963e-05, 2.22313325e-05, - 2.24126611e-05, 2.53107091e-05, 2.65862474e-05, 2.62686920e-05, - 2.53878188e-05, 2.52302304e-05, 2.49700004e-05, 2.35054352e-05, - 2.22519608e-05, 2.25299989e-05, 2.28258664e-05, 2.22744858e-05, - 2.59733865e-05, 2.70406395e-05, 2.70645615e-05, 2.57052309e-05, - 2.47760177e-05, 2.46986748e-05, 2.32562077e-05, 2.16614223e-05, - 2.11520279e-05, 2.69742970e-05, 2.78339626e-05, 2.77083077e-05, - 2.49547365e-05, 2.21197812e-05, 2.19976477e-05, 2.21350663e-05, - 2.18194449e-05, 2.17469780e-05, 2.46138478e-05, 2.67402932e-05, - 2.74034276e-05, 2.59308535e-05, 2.40343006e-05, 2.42770184e-05, - 2.46039218e-05, 2.34497410e-05, 2.20272588e-05, 2.24056715e-05, - 2.46717061e-05, 2.74422640e-05, 2.80197793e-05, 2.75537561e-05, - 2.53161425e-05, 2.21065378e-05, 2.09510861e-05, 2.14229386e-05, - 2.69436284e-05, 2.76715838e-05, 2.74327190e-05, 2.59839939e-05, - 2.33029127e-05, 2.10841213e-05, 2.05769936e-05, 2.14748013e-05, - 2.75305212e-05, 2.77359519e-05, 2.73661543e-05, 2.57629256e-05, - 2.22086721e-05, 2.04951852e-05, 2.12322944e-05, 2.19349336e-05, - 2.74107676e-05, 2.76482626e-05, 2.70249644e-05, 2.47563512e-05, - 2.36991581e-05, 2.32787940e-05, 2.25314702e-05, 2.61370809e-05, - 2.68319295e-05, 2.70647225e-05, 2.69659221e-05, 2.50695759e-05, - 2.23704737e-05, 2.17681434e-05, 2.20747246e-05, 2.58205482e-05, - 2.66730634e-05, 2.66580052e-05, 2.59958691e-05, 2.54277922e-05, - 2.48157993e-05, 2.30551692e-05, 2.21627356e-05, 2.55079063e-05, - 2.68415022e-05, 2.68285835e-05, 2.62834208e-05, 2.59675801e-05, - 2.48404364e-05, 2.30887673e-05, 2.19951594e-05, 2.20418931e-05, - 2.41037965e-05, 2.63394285e-05, 2.76588654e-05, 2.80391812e-05, - 2.68374365e-05, 2.30732490e-05, 2.16806206e-05, 2.32153136e-05, - 2.65360303e-05, 2.70632918e-05, 2.64953679e-05, 2.48837474e-05, - 2.44794547e-05, 2.40443804e-05, 2.26139269e-05, 2.21635090e-05, - 2.40687348e-05, 2.63283110e-05, 2.75115960e-05, 2.67763331e-05, - 2.52521983e-05, 2.34958181e-05, 2.22721266e-05, 2.22065543e-05, - 2.54329495e-05, 2.68001011e-05, 2.69612976e-05, 2.59891089e-05, - 2.46823070e-05, 2.35784003e-05, 2.21297884e-05, 2.26033353e-05, - 2.33726993e-05, 2.51716491e-05, 2.72316391e-05, 2.79089500e-05, - 2.70506106e-05, 2.42257638e-05, 2.22939404e-05, 2.11432562e-05, - 2.10414146e-05, 2.17975609e-05, 2.57444677e-05, 2.64083597e-05, - 2.67954437e-05, 2.57321868e-05, 2.35659436e-05, 2.40811921e-05, - 2.32424977e-05, 2.16411987e-05, 2.60853466e-05, 2.66421420e-05, - 2.65922352e-05, 2.65251770e-05, 2.58916135e-05, 2.36173205e-05, - 2.23991825e-05, 2.29418803e-05, 2.62743588e-05, 2.71003266e-05, - 2.73037499e-05, 2.52981085e-05, 2.22202778e-05, 2.21401359e-05, - 2.26321774e-05, 2.50410397e-05, 2.63971627e-05, 2.71617364e-05, - 2.70988841e-05, 2.58497410e-05, 2.43720065e-05, 2.31235983e-05, - 2.17687802e-05, - 2.56832797e-05, 2.76271616e-05, 2.79346533e-05, 2.66073909e-05, - 2.46787997e-05, 2.30846440e-05, 2.20900443e-05, 2.21911972e-05, - 2.25546455e-05, 2.55209424e-05, 2.69404195e-05, 2.66246927e-05, - 2.54662714e-05, 2.52629488e-05, 2.50129030e-05, 2.32629882e-05, - 2.19609610e-05, 2.24663401e-05, 2.29270983e-05, 2.23807338e-05, - 2.59814233e-05, 2.72131731e-05, 2.74698588e-05, 2.56710849e-05, - 2.45542404e-05, 2.47897741e-05, 2.33943178e-05, 2.16615489e-05, - 2.11256011e-05, 2.71781500e-05, 2.83421258e-05, 2.81505507e-05, - 2.44712796e-05, 2.13658078e-05, 2.17451501e-05, 2.22564337e-05, - 2.19191304e-05, 2.18209203e-05, 2.39599454e-05, 2.62878783e-05, - 2.75349746e-05, 2.57187974e-05, 2.37353316e-05, 2.44772679e-05, - 2.51716055e-05, 2.38605409e-05, 2.22442559e-05, 2.18939429e-05, - 2.41173551e-05, 2.76877489e-05, 2.88779764e-05, 2.79897291e-05, - 2.52965463e-05, 2.19880632e-05, 2.09984180e-05, 2.15540874e-05, - 2.73833431e-05, 2.79492088e-05, 2.74788601e-05, 2.56405735e-05, - 2.28480936e-05, 2.07420065e-05, 2.04024336e-05, 2.15072670e-05, - 2.82948791e-05, 2.80589666e-05, 2.72683071e-05, 2.54451537e-05, - 2.17681859e-05, 2.02726963e-05, 2.13043645e-05, 2.20459714e-05, - 2.76042172e-05, 2.79453833e-05, 2.66901692e-05, 2.40138031e-05, - 2.34783289e-05, 2.37197248e-05, 2.29408642e-05, 2.60190042e-05, - 2.64453533e-05, 2.68884040e-05, 2.72680158e-05, 2.54182715e-05, - 2.24481946e-05, 2.18461471e-05, 2.21898560e-05, 2.56770772e-05, - 2.63863430e-05, 2.64284211e-05, 2.58049805e-05, 2.55882212e-05, - 2.53284572e-05, 2.33396288e-05, 2.22817618e-05, 2.53576492e-05, - 2.68182361e-05, 2.68432524e-05, 2.60352705e-05, 2.59068550e-05, - 2.50805034e-05, 2.33391999e-05, 2.21249821e-05, 2.21558788e-05, - 2.30003965e-05, 2.52564958e-05, 2.78878332e-05, 2.89439216e-05, - 2.77908585e-05, 2.35296726e-05, 2.18636105e-05, 2.37749250e-05, - 2.64658492e-05, 2.66695454e-05, 2.60862001e-05, 2.44611218e-05, - 2.43389453e-05, 2.42528822e-05, 2.27429154e-05, 2.22416584e-05, - 2.30311155e-05, 2.57578351e-05, 2.77832561e-05, 2.69626330e-05, - 2.53188350e-05, 2.36925228e-05, 2.24768858e-05, 2.23006260e-05, - 2.53643315e-05, 2.67093170e-05, 2.68914176e-05, 2.56326322e-05, - 2.43146278e-05, 2.35016580e-05, 2.21535697e-05, 2.28336213e-05, - 2.38506306e-05, 2.47208797e-05, 2.71453656e-05, 2.85667386e-05, - 2.74071139e-05, 2.39882300e-05, 2.20400312e-05, 2.11059867e-05, - 2.10808819e-05, 2.19032748e-05, 2.50447774e-05, 2.53994716e-05, - 2.63296667e-05, 2.55644151e-05, 2.36673737e-05, 2.49873666e-05, - 2.40362737e-05, 2.19144777e-05, 2.62593746e-05, 2.62371728e-05, - 2.60428682e-05, 2.63511095e-05, 2.60195138e-05, 2.35123818e-05, - 2.23457718e-05, 2.32212709e-05, 2.55486293e-05, 2.64224547e-05, - 2.73965215e-05, 2.56105827e-05, 2.22991595e-05, 2.22407401e-05, - 2.28731999e-05, 2.45342576e-05, 2.58253671e-05, 2.69981829e-05, - 2.72827105e-05, 2.62942578e-05, 2.48741843e-05, 2.34182832e-05, - 2.18136444e-05, - 2.57338594e-05, 3.00786754e-05, 3.09935521e-05, 2.84302268e-05, - 2.47452636e-05, 2.16475691e-05, 1.99765003e-05, 2.00021276e-05, - 2.03573110e-05, 2.52759411e-05, 2.81068953e-05, 2.73446327e-05, - 2.53860016e-05, 2.50596061e-05, 2.45625454e-05, 2.18868320e-05, - 1.99161675e-05, 2.04365633e-05, 2.09631218e-05, 2.01352895e-05, - 2.66018212e-05, 2.93700841e-05, 2.94084402e-05, 2.60080956e-05, - 2.41069522e-05, 2.40765982e-05, 2.16516411e-05, 1.91962388e-05, - 1.84704854e-05, 2.91613936e-05, 3.34265116e-05, 3.19452421e-05, - 2.43645057e-05, 1.95138481e-05, 1.95599782e-05, 1.99376249e-05, - 1.94701078e-05, 1.93539243e-05, 2.36649908e-05, 2.85941538e-05, - 3.07286952e-05, 2.64646060e-05, 2.27507926e-05, 2.33701379e-05, - 2.40976094e-05, 2.20850803e-05, 1.98269364e-05, 2.00468709e-05, - 2.38038177e-05, 3.07978684e-05, 3.39666387e-05, 3.11305144e-05, - 2.52127041e-05, 1.97817664e-05, 1.82317249e-05, 1.89242031e-05, - 2.90573660e-05, 3.20992534e-05, 3.09778126e-05, 2.65669168e-05, - 2.14696275e-05, 1.82238884e-05, 1.76175928e-05, 1.89483615e-05, - 3.08556814e-05, 3.28192065e-05, 3.08366650e-05, 2.60707242e-05, - 1.97841435e-05, 1.74849974e-05, 1.86298561e-05, 1.96417782e-05, - 3.07042646e-05, 3.37087807e-05, 2.95315608e-05, 2.39089175e-05, - 2.22151412e-05, 2.18271748e-05, 2.06635601e-05, 2.69548468e-05, - 2.88682309e-05, 2.95796776e-05, 2.91264197e-05, 2.48612816e-05, - 2.02639655e-05, 1.93861312e-05, 1.98465251e-05, 2.62319401e-05, - 2.83448589e-05, 2.82924853e-05, 2.66161381e-05, 2.54917375e-05, - 2.44553138e-05, 2.14030826e-05, 1.99770108e-05, 2.55644345e-05, - 2.87978522e-05, 2.87544667e-05, 2.72961439e-05, 2.65750295e-05, - 2.43929957e-05, 2.14396208e-05, 1.97380052e-05, 1.97981847e-05, - 2.25956930e-05, 2.75791138e-05, 3.32550459e-05, 3.35695974e-05, - 2.88295425e-05, 2.15124054e-05, 1.93128342e-05, 2.17835094e-05, - 2.79490274e-05, 2.97374249e-05, 2.78561944e-05, 2.42457713e-05, - 2.35932219e-05, 2.29745279e-05, 2.06531982e-05, 1.99585371e-05, - 2.25528688e-05, 2.74166000e-05, 3.10932575e-05, 2.85950724e-05, - 2.51136680e-05, 2.20616509e-05, 2.01791105e-05, 2.00293650e-05, - 2.54330684e-05, 2.86857664e-05, 2.91790033e-05, 2.65772169e-05, - 2.38835123e-05, 2.20762588e-05, 1.98831544e-05, 2.06852024e-05, - 2.19933872e-05, 2.48008323e-05, 3.01731271e-05, 3.31229273e-05, - 2.93717020e-05, 2.31068669e-05, 1.99955081e-05, 1.84530739e-05, - 1.83510999e-05, 1.94416927e-05, 2.59736878e-05, 2.77634210e-05, - 2.87806709e-05, 2.60343211e-05, 2.21331155e-05, 2.33496956e-05, - 2.19394148e-05, 1.93016333e-05, 2.68879994e-05, 2.82772169e-05, - 2.81636739e-05, 2.79211045e-05, 2.64487541e-05, 2.21281582e-05, - 2.02450641e-05, 2.12250290e-05, 2.72884087e-05, 3.04956842e-05, - 3.03316188e-05, 2.52863190e-05, 2.00422936e-05, 1.99350599e-05, - 2.07338521e-05, 2.45265643e-05, 2.76044337e-05, 2.99463559e-05, - 2.95531961e-05, 2.64456589e-05, 2.36626054e-05, 2.15146879e-05, - 1.93709542e-05, - 2.41621529e-05, 1.97638885e-05, 1.87736543e-05, 2.04436688e-05, - 2.35167342e-05, 2.72115058e-05, 2.91954689e-05, 2.95390352e-05, - 2.97376023e-05, 2.48798780e-05, 2.21215097e-05, 2.29995457e-05, - 2.43904874e-05, 2.46126146e-05, 2.51714127e-05, 2.70982679e-05, - 2.88660341e-05, 2.90497212e-05, 2.90224458e-05, 2.98475915e-05, - 2.28590653e-05, 2.01107288e-05, 2.07266094e-05, 2.33956451e-05, - 2.48956838e-05, 2.58210676e-05, 2.84450576e-05, 3.04274940e-05, - 3.10240580e-05, 2.04533013e-05, 1.55982605e-05, 1.75774573e-05, - 2.38706364e-05, 2.78257769e-05, 2.93185287e-05, 3.00840505e-05, - 3.04682578e-05, 3.05014062e-05, 2.40986173e-05, 1.92249263e-05, - 1.82770518e-05, 2.23861750e-05, 2.60668000e-05, 2.68692360e-05, - 2.71399434e-05, 2.87937485e-05, 3.04763646e-05, 2.80738937e-05, - 2.42471830e-05, 1.85264967e-05, 1.59103496e-05, 1.86543064e-05, - 2.43001664e-05, 2.95142864e-05, 3.14712951e-05, 3.10815931e-05, - 2.12444917e-05, 1.68497610e-05, 1.76869668e-05, 2.18953038e-05, - 2.68818302e-05, 3.02716824e-05, 3.13383156e-05, 3.07590202e-05, - 1.99519795e-05, 1.59285021e-05, 1.74328576e-05, 2.25183492e-05, - 2.85368297e-05, 3.13053537e-05, 3.11779442e-05, 3.03380426e-05, - 1.84939174e-05, 1.43662788e-05, 1.84157009e-05, 2.35871808e-05, - 2.68340141e-05, 2.91432075e-05, 3.02228905e-05, 2.21061192e-05, - 1.90870691e-05, 1.88314754e-05, 2.07745422e-05, 2.57136107e-05, - 2.96378157e-05, 3.04830141e-05, 3.01533703e-05, 2.28392766e-05, - 2.00140901e-05, 2.02429897e-05, 2.22780042e-05, 2.45067158e-05, - 2.66055589e-05, 2.91198054e-05, 3.00389842e-05, 2.35495146e-05, - 2.02386729e-05, 2.03999307e-05, 2.13469202e-05, 2.26942537e-05, - 2.59082669e-05, 2.89842724e-05, 3.03018556e-05, 3.01965271e-05, - 2.38385902e-05, 1.85307462e-05, 1.49032658e-05, 1.66715174e-05, - 2.29268839e-05, 2.95073964e-05, 3.08691769e-05, 2.95283035e-05, - 2.11057790e-05, 1.79721494e-05, 2.02323286e-05, 2.41712432e-05, - 2.56634564e-05, 2.73022499e-05, 2.94094001e-05, 2.99348257e-05, - 2.40788559e-05, 2.02697126e-05, 1.82160436e-05, 2.10791391e-05, - 2.46504713e-05, 2.82015551e-05, 3.00975984e-05, 2.99139229e-05, - 2.39236886e-05, 2.01777112e-05, 1.96419001e-05, 2.18461717e-05, - 2.47074622e-05, 2.73937250e-05, 2.98447707e-05, 2.96762256e-05, - 2.90798270e-05, 2.35054978e-05, 1.83454808e-05, 1.65577564e-05, - 2.06331427e-05, 2.58834197e-05, 2.89028046e-05, 3.10067947e-05, - 3.13369216e-05, 3.05135300e-05, 2.15160674e-05, 1.85387621e-05, - 1.89572385e-05, 2.29874221e-05, 2.78537961e-05, 2.88756403e-05, - 3.00359362e-05, 3.11512885e-05, 2.30064356e-05, 1.97471229e-05, - 1.94541573e-05, 2.08398641e-05, 2.33666841e-05, 2.72594724e-05, - 2.92654616e-05, 2.92834595e-05, 1.99576985e-05, 1.60325231e-05, - 1.86768345e-05, 2.51547993e-05, 2.98561152e-05, 3.00245479e-05, - 2.96597067e-05, 2.36327955e-05, 2.00476459e-05, 1.84043895e-05, - 1.99193072e-05, 2.42523311e-05, 2.74166969e-05, 2.90373123e-05, - 3.03974588e-05, - 2.50830104e-05, 2.35291844e-05, 2.30549382e-05, 2.37732583e-05, - 2.47321196e-05, 2.54640159e-05, 2.56276350e-05, 2.57149282e-05, - 2.58438158e-05, 2.52852323e-05, 2.44959619e-05, 2.47960777e-05, - 2.51262569e-05, 2.51663851e-05, 2.52959721e-05, 2.54765856e-05, - 2.55337267e-05, 2.56979934e-05, 2.58061750e-05, 2.58176822e-05, - 2.46754005e-05, 2.36666053e-05, 2.39587714e-05, 2.48266063e-05, - 2.51419839e-05, 2.54436998e-05, 2.57999938e-05, 2.57140920e-05, - 2.56412424e-05, 2.38187109e-05, 2.12138771e-05, 2.24179376e-05, - 2.48153194e-05, 2.51756686e-05, 2.55567359e-05, 2.58243025e-05, - 2.57932478e-05, 2.57707167e-05, 2.48039235e-05, 2.31921558e-05, - 2.27822514e-05, 2.44726923e-05, 2.53195439e-05, 2.56626591e-05, - 2.58528678e-05, 2.59733509e-05, 2.58839885e-05, 2.53643794e-05, - 2.48757622e-05, 2.29184025e-05, 2.14117373e-05, 2.29953641e-05, - 2.50739116e-05, 2.56565346e-05, 2.56607888e-05, 2.57783610e-05, - 2.41756227e-05, 2.19944749e-05, 2.24624827e-05, 2.42788081e-05, - 2.53358831e-05, 2.54158936e-05, 2.54510351e-05, 2.57186346e-05, - 2.36499836e-05, 2.14290591e-05, 2.23151617e-05, 2.44889924e-05, - 2.54212610e-05, 2.54035830e-05, 2.57168270e-05, 2.58081322e-05, - 2.28983412e-05, 2.03726323e-05, 2.28167165e-05, 2.46523101e-05, - 2.54594763e-05, 2.60121584e-05, 2.60242661e-05, 2.44004454e-05, - 2.31364633e-05, 2.30372245e-05, 2.39661809e-05, 2.55142567e-05, - 2.57991342e-05, 2.57750257e-05, 2.58177613e-05, 2.46326894e-05, - 2.35652292e-05, 2.36708184e-05, 2.44421488e-05, 2.51796677e-05, - 2.57427267e-05, 2.59217859e-05, 2.58236291e-05, 2.48381563e-05, - 2.36979999e-05, 2.37716266e-05, 2.41039047e-05, 2.46072587e-05, - 2.55154395e-05, 2.58954816e-05, 2.58240328e-05, 2.58155652e-05, - 2.45538841e-05, 2.27801920e-05, 2.07512696e-05, 2.18911174e-05, - 2.48768616e-05, 2.60387565e-05, 2.58377879e-05, 2.60981420e-05, - 2.40446714e-05, 2.25849387e-05, 2.36383185e-05, 2.49081959e-05, - 2.53232970e-05, 2.57254884e-05, 2.58330957e-05, 2.57956739e-05, - 2.46319365e-05, 2.36259465e-05, 2.27584332e-05, 2.40743739e-05, - 2.51861357e-05, 2.58140860e-05, 2.58847545e-05, 2.58078124e-05, - 2.49626917e-05, 2.36628441e-05, 2.34293128e-05, 2.42590452e-05, - 2.50469410e-05, 2.55952707e-05, 2.57571137e-05, 2.59033739e-05, - 2.60284588e-05, 2.47345817e-05, 2.28023974e-05, 2.18222398e-05, - 2.39135472e-05, 2.53193136e-05, 2.55612857e-05, 2.56328456e-05, - 2.56692681e-05, 2.57957597e-05, 2.40641410e-05, 2.27952772e-05, - 2.30659356e-05, 2.46715403e-05, 2.57333696e-05, 2.62180000e-05, - 2.62497330e-05, 2.58929341e-05, 2.47595467e-05, 2.34325662e-05, - 2.32824411e-05, 2.39231206e-05, 2.48591422e-05, 2.55666994e-05, - 2.57067634e-05, 2.59253384e-05, 2.34699456e-05, 2.14735217e-05, - 2.29840298e-05, 2.53806746e-05, 2.57977001e-05, 2.58103180e-05, - 2.59102431e-05, 2.47485166e-05, 2.35344327e-05, 2.28262151e-05, - 2.35827647e-05, 2.51899767e-05, 2.58683731e-05, 2.59238678e-05, - 2.57527094e-05, - 2.53422436e-05, 2.61698185e-05, 2.62021896e-05, 2.62842146e-05, - 2.56409820e-05, 2.41073376e-05, 2.30633527e-05, 2.29140662e-05, - 2.28736510e-05, 2.50945193e-05, 2.58181826e-05, 2.56182283e-05, - 2.52770006e-05, 2.52083332e-05, 2.50083516e-05, 2.41718063e-05, - 2.32012033e-05, 2.31886229e-05, 2.32603187e-05, 2.27951461e-05, - 2.57456602e-05, 2.62151919e-05, 2.60390420e-05, 2.56061883e-05, - 2.51283584e-05, 2.47580167e-05, 2.35751211e-05, 2.23881214e-05, - 2.19786871e-05, 2.61589861e-05, 2.59473517e-05, 2.61865897e-05, - 2.55216749e-05, 2.36032380e-05, 2.29463975e-05, 2.26616021e-05, - 2.24165983e-05, 2.23821811e-05, 2.54492047e-05, 2.65843375e-05, - 2.63613759e-05, 2.59237990e-05, 2.46458580e-05, 2.43257214e-05, - 2.42173367e-05, 2.34546160e-05, 2.24695277e-05, 2.35696495e-05, - 2.53891086e-05, 2.62967067e-05, 2.57741978e-05, 2.61953825e-05, - 2.53208656e-05, 2.28930513e-05, 2.17242132e-05, 2.20430485e-05, - 2.59484460e-05, 2.62410506e-05, 2.64088966e-05, 2.60804034e-05, - 2.42355229e-05, 2.22674854e-05, 2.16408948e-05, 2.21934336e-05, - 2.59644327e-05, 2.61158070e-05, 2.64837038e-05, 2.59146921e-05, - 2.33283627e-05, 2.16226289e-05, 2.19416772e-05, 2.25028691e-05, - 2.63243013e-05, 2.58309909e-05, 2.65926551e-05, 2.56433558e-05, - 2.43027398e-05, 2.32845165e-05, 2.26959269e-05, 2.59672850e-05, - 2.65687403e-05, 2.64915610e-05, 2.60742939e-05, 2.47836954e-05, - 2.29058520e-05, 2.23959187e-05, 2.26171378e-05, 2.57872418e-05, - 2.64187508e-05, 2.63633098e-05, 2.59456286e-05, 2.52265997e-05, - 2.44336379e-05, 2.32599909e-05, 2.26874536e-05, 2.55821700e-05, - 2.62811497e-05, 2.62434715e-05, 2.61745704e-05, 2.58059983e-05, - 2.47179273e-05, 2.33225542e-05, 2.25341407e-05, 2.25905365e-05, - 2.55489745e-05, 2.69302516e-05, 2.60004973e-05, 2.58480982e-05, - 2.54512531e-05, 2.30996112e-05, 2.22094929e-05, 2.31128156e-05, - 2.61612596e-05, 2.66395881e-05, 2.64342329e-05, 2.54093159e-05, - 2.48243703e-05, 2.41352068e-05, 2.30554813e-05, 2.27313100e-05, - 2.54522818e-05, 2.64877552e-05, 2.62887064e-05, 2.60721200e-05, - 2.51911832e-05, 2.37093110e-05, 2.26896800e-05, 2.27507781e-05, - 2.54510434e-05, 2.63169706e-05, 2.63728397e-05, 2.60957744e-05, - 2.52065284e-05, 2.40570735e-05, 2.27605406e-05, 2.29410910e-05, - 2.33241265e-05, 2.56425847e-05, 2.64715386e-05, 2.59860066e-05, - 2.60718300e-05, 2.47298891e-05, 2.31960085e-05, 2.19828766e-05, - 2.18113178e-05, 2.23915219e-05, 2.62672611e-05, 2.68973262e-05, - 2.66163158e-05, 2.57515245e-05, 2.38633249e-05, 2.34767297e-05, - 2.29021406e-05, 2.20803194e-05, 2.56651801e-05, 2.65027069e-05, - 2.65995481e-05, 2.62460035e-05, 2.55794126e-05, 2.41173343e-05, - 2.30687521e-05, 2.31717106e-05, 2.65963732e-05, 2.67451830e-05, - 2.63686469e-05, 2.49870239e-05, 2.27783970e-05, 2.26878217e-05, - 2.29540320e-05, 2.56065284e-05, 2.65247533e-05, 2.65082850e-05, - 2.62317657e-05, 2.52553801e-05, 2.41006807e-05, 2.33058107e-05, - 2.24318335e-05, - 2.36348300e-05, 1.84735110e-05, 1.73571624e-05, 2.00036057e-05, - 2.43265834e-05, 2.83322876e-05, 3.04064558e-05, 3.03991198e-05, - 3.00113528e-05, 2.42493271e-05, 2.09527892e-05, 2.18844106e-05, - 2.40132020e-05, 2.43731078e-05, 2.49837460e-05, 2.80598038e-05, - 3.04496553e-05, 2.98782299e-05, 2.92962952e-05, 3.02645542e-05, - 2.24563596e-05, 1.91461429e-05, 1.93928418e-05, 2.31516355e-05, - 2.53418666e-05, 2.56021424e-05, 2.84997455e-05, 3.13530000e-05, - 3.22033589e-05, 1.94558347e-05, 1.40347288e-05, 1.61005044e-05, - 2.47965980e-05, 3.08044690e-05, 3.08915488e-05, 3.04961034e-05, - 3.10370564e-05, 3.11711297e-05, 2.55370639e-05, 1.92899215e-05, - 1.72755577e-05, 2.24004063e-05, 2.69645563e-05, 2.65061157e-05, - 2.58473821e-05, 2.80823168e-05, 3.06305344e-05, 3.02197431e-05, - 2.54477884e-05, 1.73612111e-05, 1.39270278e-05, 1.72045885e-05, - 2.41436567e-05, 3.06482047e-05, 3.24729970e-05, 3.16668734e-05, - 1.98728387e-05, 1.55868110e-05, 1.67850630e-05, 2.21233766e-05, - 2.84654692e-05, 3.25069567e-05, 3.32246619e-05, 3.16428751e-05, - 1.80179372e-05, 1.45923949e-05, 1.67328432e-05, 2.27881326e-05, - 3.05709670e-05, 3.33899575e-05, 3.20103251e-05, 3.08385230e-05, - 1.74072991e-05, 1.30571670e-05, 1.81779712e-05, 2.51376267e-05, - 2.76693345e-05, 2.83837065e-05, 2.96938654e-05, 2.18812840e-05, - 1.90149563e-05, 1.83655047e-05, 1.96230544e-05, 2.48384888e-05, - 3.01101947e-05, 3.11338171e-05, 3.06012778e-05, 2.27657712e-05, - 1.98692096e-05, 2.00171659e-05, 2.22309999e-05, 2.39514017e-05, - 2.54089877e-05, 2.88302880e-05, 3.04501393e-05, 2.35939041e-05, - 1.96304586e-05, 1.97368816e-05, 2.12945087e-05, 2.24201943e-05, - 2.53210393e-05, 2.87796053e-05, 3.07281784e-05, 3.06572900e-05, - 2.65198289e-05, 1.96904445e-05, 1.36743723e-05, 1.46055106e-05, - 2.06749457e-05, 2.87433591e-05, 3.12189632e-05, 2.84590453e-05, - 2.06694400e-05, 1.77869704e-05, 2.03511129e-05, 2.50019713e-05, - 2.60331635e-05, 2.69757070e-05, 2.96647895e-05, 3.04671580e-05, - 2.66399715e-05, 2.07168719e-05, 1.69995835e-05, 2.01555470e-05, - 2.43342773e-05, 2.80400422e-05, 3.02252608e-05, 3.03864319e-05, - 2.38307513e-05, 1.96868215e-05, 1.90643708e-05, 2.20950224e-05, - 2.55044880e-05, 2.79100799e-05, 3.05488436e-05, 2.96459228e-05, - 2.82046094e-05, 2.42715639e-05, 1.76908980e-05, 1.47986676e-05, - 1.93794069e-05, 2.65650007e-05, 3.03623907e-05, 3.22245163e-05, - 3.23359937e-05, 3.10701834e-05, 2.24741036e-05, 1.95525953e-05, - 1.90120071e-05, 2.29893956e-05, 2.79196491e-05, 2.68121899e-05, - 2.83264545e-05, 3.12283372e-05, 2.22663068e-05, 1.97919809e-05, - 1.97329130e-05, 2.05763298e-05, 2.27606901e-05, 2.78341636e-05, - 3.01083629e-05, 2.90339877e-05, 2.06694630e-05, 1.60889600e-05, - 1.77575031e-05, 2.43120385e-05, 3.03694605e-05, 3.04969956e-05, - 2.95916779e-05, 2.45680112e-05, 2.04615220e-05, 1.78799849e-05, - 1.89234749e-05, 2.30391078e-05, 2.63138461e-05, 2.87043764e-05, - 3.11502926e-05, - 2.30265263e-05, 1.68864903e-05, 1.56379840e-05, 1.85226039e-05, - 2.36313395e-05, 2.90109981e-05, 3.20408621e-05, 3.21325974e-05, - 3.17147575e-05, 2.38467451e-05, 1.97982760e-05, 2.09329084e-05, - 2.34837420e-05, 2.39228533e-05, 2.47161786e-05, 2.86638302e-05, - 3.19973492e-05, 3.13547681e-05, 3.06435587e-05, 3.20576484e-05, - 2.15035415e-05, 1.76091134e-05, 1.79634582e-05, 2.23482482e-05, - 2.50481370e-05, 2.55507301e-05, 2.95348329e-05, 3.35866536e-05, - 3.48566508e-05, 1.79774361e-05, 1.20622081e-05, 1.42551099e-05, - 2.42185175e-05, 3.21245775e-05, 3.26736517e-05, 3.24131838e-05, - 3.32026167e-05, 3.33809467e-05, 2.50792457e-05, 1.75931332e-05, - 1.54785214e-05, 2.13490116e-05, 2.71437675e-05, 2.68185743e-05, - 2.61353112e-05, 2.91331834e-05, 3.26972886e-05, 3.14888957e-05, - 2.50155278e-05, 1.56013549e-05, 1.20091064e-05, 1.54722473e-05, - 2.36053036e-05, 3.24318578e-05, 3.53516686e-05, 3.41894595e-05, - 1.85375826e-05, 1.36644597e-05, 1.49167518e-05, 2.09616268e-05, - 2.90796221e-05, 3.49997129e-05, 3.62854133e-05, 3.40566318e-05, - 1.64727622e-05, 1.26144549e-05, 1.48265721e-05, 2.17821481e-05, - 3.20490545e-05, 3.64906174e-05, 3.46591539e-05, 3.29148108e-05, - 1.56401488e-05, 1.10194552e-05, 1.63680090e-05, 2.45252757e-05, - 2.81434137e-05, 2.95835538e-05, 3.14655285e-05, 2.07527318e-05, - 1.72987230e-05, 1.66209283e-05, 1.82019632e-05, 2.46782029e-05, - 3.18069242e-05, 3.33284521e-05, 3.25641608e-05, 2.18247486e-05, - 1.83095585e-05, 1.84992513e-05, 2.11504341e-05, 2.34420247e-05, - 2.55165132e-05, 3.01107003e-05, 3.23429550e-05, 2.28520676e-05, - 1.81126787e-05, 1.82479784e-05, 1.99996656e-05, 2.14321855e-05, - 2.52576082e-05, 3.00131584e-05, 3.27663888e-05, 3.26466034e-05, - 2.61017231e-05, 1.78603218e-05, 1.16410093e-05, 1.27342720e-05, - 1.96644257e-05, 3.01120972e-05, 3.35549194e-05, 2.97768322e-05, - 1.93168561e-05, 1.59167230e-05, 1.88316777e-05, 2.45099475e-05, - 2.59955637e-05, 2.74620974e-05, 3.11979505e-05, 3.23331400e-05, - 2.62931367e-05, 1.92063904e-05, 1.52055163e-05, 1.87922056e-05, - 2.38889174e-05, 2.89281019e-05, 3.20825536e-05, 3.22273134e-05, - 2.31861290e-05, 1.81577531e-05, 1.74455041e-05, 2.09223743e-05, - 2.51842115e-05, 2.85661775e-05, 3.24073540e-05, 3.12508099e-05, - 2.93536505e-05, 2.35696081e-05, 1.58874206e-05, 1.28946818e-05, - 1.79334216e-05, 2.66463127e-05, 3.19015744e-05, 3.48781646e-05, - 3.51299673e-05, 3.32580084e-05, 2.12486476e-05, 1.77266054e-05, - 1.72727950e-05, 2.20912689e-05, 2.86964508e-05, 2.76636337e-05, - 2.97544474e-05, 3.36545876e-05, 2.13339346e-05, 1.81838678e-05, - 1.80717057e-05, 1.91724675e-05, 2.19278301e-05, 2.84432783e-05, - 3.16968286e-05, 3.04001040e-05, 1.90993453e-05, 1.40018412e-05, - 1.60068891e-05, 2.39754734e-05, 3.21893512e-05, 3.23966203e-05, - 3.11800789e-05, 2.39176211e-05, 1.89077347e-05, 1.60789863e-05, - 1.73555441e-05, 2.24067950e-05, 2.67317752e-05, 2.99376358e-05, - 3.33228111e-05, - 2.54073919e-05, 2.60203922e-05, 2.60083215e-05, 2.58907770e-05, - 2.52511430e-05, 2.41291075e-05, 2.33119896e-05, 2.32696125e-05, - 2.33639284e-05, 2.52677193e-05, 2.58627105e-05, 2.57353763e-05, - 2.53255178e-05, 2.52442509e-05, 2.50948189e-05, 2.42139205e-05, - 2.33387240e-05, 2.34938971e-05, 2.36733541e-05, 2.32695589e-05, - 2.56250593e-05, 2.59764209e-05, 2.60012903e-05, 2.55009148e-05, - 2.50161286e-05, 2.49266131e-05, 2.39709243e-05, 2.28319430e-05, - 2.24448647e-05, 2.59690488e-05, 2.55480953e-05, 2.59096050e-05, - 2.51487190e-05, 2.33381433e-05, 2.31423408e-05, 2.31623545e-05, - 2.29293786e-05, 2.28801763e-05, 2.49743661e-05, 2.58528642e-05, - 2.59427588e-05, 2.56176281e-05, 2.45714914e-05, 2.46456036e-05, - 2.47923000e-05, 2.40519187e-05, 2.30598733e-05, 2.34963445e-05, - 2.49963200e-05, 2.59729763e-05, 2.56183293e-05, 2.60044129e-05, - 2.52974427e-05, 2.31941005e-05, 2.22693113e-05, 2.26179352e-05, - 2.59754243e-05, 2.57981080e-05, 2.58849653e-05, 2.56448171e-05, - 2.41147582e-05, 2.24670178e-05, 2.20272943e-05, 2.26812828e-05, - 2.60874328e-05, 2.56257955e-05, 2.58431533e-05, 2.55474221e-05, - 2.33384503e-05, 2.19739143e-05, 2.24838802e-05, 2.30142596e-05, - 2.59641337e-05, 2.51972792e-05, 2.58743503e-05, 2.50648061e-05, - 2.43398199e-05, 2.39260093e-05, 2.33930046e-05, 2.57014910e-05, - 2.58710833e-05, 2.59153332e-05, 2.59744642e-05, 2.51111612e-05, - 2.33467974e-05, 2.28953550e-05, 2.31185570e-05, 2.55640585e-05, - 2.58665412e-05, 2.58688603e-05, 2.56449384e-05, 2.53379961e-05, - 2.49336673e-05, 2.37995349e-05, 2.31835523e-05, 2.54116291e-05, - 2.59244417e-05, 2.59252619e-05, 2.57588779e-05, 2.56263956e-05, - 2.49904398e-05, 2.38304058e-05, 2.30554359e-05, 2.30941684e-05, - 2.47258659e-05, 2.56913688e-05, 2.53660479e-05, 2.57836211e-05, - 2.59345905e-05, 2.37767478e-05, 2.28042217e-05, 2.38565825e-05, - 2.58452474e-05, 2.58438879e-05, 2.58164122e-05, 2.51024297e-05, - 2.48267201e-05, 2.44929334e-05, 2.35142055e-05, 2.31932087e-05, - 2.46970269e-05, 2.57611215e-05, 2.59559134e-05, 2.59226422e-05, - 2.52524555e-05, 2.41257221e-05, 2.32460467e-05, 2.32217571e-05, - 2.53650794e-05, 2.59103015e-05, 2.59354757e-05, 2.56472240e-05, - 2.49798005e-05, 2.42332765e-05, 2.31801009e-05, 2.34847945e-05, - 2.39845767e-05, 2.52632747e-05, 2.59149479e-05, 2.57597794e-05, - 2.59951766e-05, 2.46834660e-05, 2.33616643e-05, 2.24406148e-05, - 2.23423354e-05, 2.29113658e-05, 2.55522267e-05, 2.57134371e-05, - 2.58532760e-05, 2.55239806e-05, 2.41918727e-05, 2.43880488e-05, - 2.38267848e-05, 2.27528008e-05, 2.56654378e-05, 2.58474414e-05, - 2.58198939e-05, 2.58384802e-05, 2.55786353e-05, 2.42646246e-05, - 2.33961727e-05, 2.37196003e-05, 2.57344167e-05, 2.55906588e-05, - 2.59580925e-05, 2.52478072e-05, 2.32353214e-05, 2.31707719e-05, - 2.35035579e-05, 2.51983883e-05, 2.57787794e-05, 2.59049313e-05, - 2.59843986e-05, 2.55293927e-05, 2.46551076e-05, 2.38460786e-05, - 2.29034437e-05, - 2.55216143e-05, 2.68724336e-05, 2.70326621e-05, 2.64137864e-05, - 2.51320503e-05, 2.36033517e-05, 2.26034868e-05, 2.25896875e-05, - 2.27632307e-05, 2.53253740e-05, 2.63766762e-05, 2.61271173e-05, - 2.53802246e-05, 2.52440037e-05, 2.50237239e-05, 2.37270962e-05, - 2.25964666e-05, 2.28602991e-05, 2.31362138e-05, 2.26356885e-05, - 2.58567614e-05, 2.66879015e-05, 2.67390508e-05, 2.56344408e-05, - 2.48384635e-05, 2.47940545e-05, 2.35254840e-05, 2.20692747e-05, - 2.15977628e-05, 2.66463948e-05, 2.70731496e-05, 2.71198222e-05, - 2.49697423e-05, 2.24518584e-05, 2.23663567e-05, 2.25090021e-05, - 2.22187695e-05, 2.21510837e-05, 2.46659545e-05, 2.63776636e-05, - 2.69026193e-05, 2.58006389e-05, 2.41903075e-05, 2.44341756e-05, - 2.47413037e-05, 2.37124679e-05, 2.24143731e-05, 2.27246243e-05, - 2.47234701e-05, 2.69514737e-05, 2.72554301e-05, 2.70556998e-05, - 2.53122734e-05, 2.24721536e-05, 2.14141636e-05, 2.18547008e-05, - 2.66562754e-05, 2.70368262e-05, 2.68903621e-05, 2.58290190e-05, - 2.35342239e-05, 2.15217085e-05, 2.10573215e-05, 2.18986310e-05, - 2.71085399e-05, 2.70191824e-05, 2.68160780e-05, 2.56545734e-05, - 2.25495062e-05, 2.09791205e-05, 2.16760150e-05, 2.23252642e-05, - 2.69222081e-05, 2.68018860e-05, 2.65818419e-05, 2.47796595e-05, - 2.39001514e-05, 2.35605732e-05, 2.28830714e-05, 2.59747352e-05, - 2.64508298e-05, 2.66406616e-05, 2.66543447e-05, 2.51301027e-05, - 2.27219067e-05, 2.21707138e-05, 2.24535253e-05, 2.57184618e-05, - 2.63589476e-05, 2.63568338e-05, 2.58548530e-05, 2.54201779e-05, - 2.49221381e-05, 2.33519365e-05, 2.25341976e-05, 2.54613587e-05, - 2.65188076e-05, 2.65152432e-05, 2.60741890e-05, 2.58453834e-05, - 2.49261755e-05, 2.33805805e-05, 2.23812813e-05, 2.24234177e-05, - 2.41906157e-05, 2.59862437e-05, 2.68636268e-05, 2.73343809e-05, - 2.66322035e-05, 2.33762079e-05, 2.20944878e-05, 2.35089209e-05, - 2.62886878e-05, 2.65884431e-05, 2.62122063e-05, 2.49146641e-05, - 2.45888069e-05, 2.42302302e-05, 2.29455877e-05, 2.25331086e-05, - 2.41658406e-05, 2.60656078e-05, 2.69923832e-05, 2.65007572e-05, - 2.52651511e-05, 2.37428847e-05, 2.26378587e-05, 2.25731372e-05, - 2.54060420e-05, 2.64792667e-05, 2.65941364e-05, 2.58316240e-05, - 2.47471935e-05, 2.38015435e-05, 2.24998753e-05, 2.29406018e-05, - 2.36466338e-05, 2.51549509e-05, 2.67577246e-05, 2.72158074e-05, - 2.67223022e-05, 2.43617307e-05, 2.26365058e-05, 2.15892011e-05, - 2.14977622e-05, 2.21989126e-05, 2.55984754e-05, 2.60475507e-05, - 2.64116504e-05, 2.56442261e-05, 2.38003547e-05, 2.42989853e-05, - 2.35436299e-05, 2.20617317e-05, 2.59628450e-05, 2.63182509e-05, - 2.62591463e-05, 2.62670720e-05, 2.58015486e-05, 2.38344904e-05, - 2.27419472e-05, 2.32494835e-05, 2.60026824e-05, 2.64868934e-05, - 2.68401685e-05, 2.53221686e-05, 2.25849946e-05, 2.25127318e-05, - 2.29672755e-05, 2.50404918e-05, 2.61161440e-05, 2.67004368e-05, - 2.67293565e-05, 2.57939616e-05, 2.45348154e-05, 2.34140620e-05, - 2.21699034e-05, - 2.49212048e-05, 3.52771820e-05, 3.79589082e-05, 3.24436255e-05, - 2.46160734e-05, 1.82061718e-05, 1.53170665e-05, 1.51276773e-05, - 1.53152364e-05, 2.37249810e-05, 2.97437509e-05, 2.78577281e-05, - 2.43354717e-05, 2.37844456e-05, 2.27438202e-05, 1.85172509e-05, - 1.54697566e-05, 1.58177030e-05, 1.63021526e-05, 1.50557634e-05, - 2.72753757e-05, 3.39644199e-05, 3.30570693e-05, 2.60430003e-05, - 2.25630560e-05, 2.16658250e-05, 1.73093256e-05, 1.39111008e-05, - 1.29750662e-05, 3.32116406e-05, 4.72636504e-05, 4.12680093e-05, - 2.38493573e-05, 1.57698943e-05, 1.48720982e-05, 1.47437204e-05, - 1.41216039e-05, 1.40040994e-05, 2.28990211e-05, 3.45351044e-05, - 3.85776016e-05, 2.77093568e-05, 2.01750269e-05, 2.00870023e-05, - 2.05287816e-05, 1.74483051e-05, 1.44200278e-05, 1.61023362e-05, - 2.28933213e-05, 3.81945092e-05, 4.71143159e-05, 3.83226063e-05, - 2.42581380e-05, 1.49494133e-05, 1.25480064e-05, 1.33249286e-05, - 3.19296723e-05, 4.29433584e-05, 3.99784610e-05, 2.84341548e-05, - 1.82885449e-05, 1.31605445e-05, 1.21031642e-05, 1.35182452e-05, - 3.57831173e-05, 4.58010250e-05, 4.03190439e-05, 2.71357832e-05, - 1.55594567e-05, 1.20083701e-05, 1.30285080e-05, 1.43421583e-05, - 3.81514415e-05, 5.07070732e-05, 3.69828217e-05, 2.36726870e-05, - 1.90331405e-05, 1.69795692e-05, 1.52802587e-05, 2.85736698e-05, - 3.50722929e-05, 3.63053171e-05, 3.26902484e-05, 2.25125170e-05, - 1.52956806e-05, 1.40418323e-05, 1.46246442e-05, 2.69189529e-05, - 3.30026774e-05, 3.25959936e-05, 2.80021428e-05, 2.43183028e-05, - 2.13178738e-05, 1.66246969e-05, 1.48043259e-05, 2.54196586e-05, - 3.31510979e-05, 3.28585778e-05, 2.99353699e-05, 2.74468994e-05, - 2.18873144e-05, 1.67482247e-05, 1.44451916e-05, 1.45579299e-05, - 2.20411772e-05, 3.45142452e-05, 4.87862764e-05, 4.49424549e-05, - 2.94153715e-05, 1.64615917e-05, 1.37651974e-05, 1.66812540e-05, - 3.09658670e-05, 3.80260133e-05, 3.21331644e-05, 2.34193403e-05, - 2.13434401e-05, 1.93684652e-05, 1.57785432e-05, 1.48504896e-05, - 2.17651143e-05, 3.15906485e-05, 3.90930851e-05, 3.16866661e-05, - 2.37990745e-05, 1.78520679e-05, 1.49428557e-05, 1.49241897e-05, - 2.48777716e-05, 3.31234339e-05, 3.45052404e-05, 2.85081132e-05, - 2.25225847e-05, 1.84676815e-05, 1.48390739e-05, 1.56375010e-05, - 1.71680691e-05, 2.46855928e-05, 3.78333864e-05, 4.47109041e-05, - 3.31599009e-05, 2.06772575e-05, 1.55177354e-05, 1.29694017e-05, - 1.27147188e-05, 1.40718851e-05, 2.82819798e-05, 3.47190237e-05, - 3.51910378e-05, 2.65406180e-05, 1.81729953e-05, 1.84909366e-05, - 1.64777216e-05, 1.36020615e-05, 2.73895079e-05, 3.33424180e-05, - 3.36782714e-05, 3.13141581e-05, 2.65214751e-05, 1.86188668e-05, - 1.55109948e-05, 1.63599685e-05, 3.19105079e-05, 4.28463374e-05, - 3.74114653e-05, 2.34596676e-05, 1.49701406e-05, 1.47767978e-05, - 1.56900310e-05, 2.42660205e-05, 3.21305026e-05, 3.74720004e-05, - 3.44641038e-05, 2.55221336e-05, 1.99040961e-05, 1.67782951e-05, - 1.40771299e-05, - 2.54978260e-05, 3.17987227e-05, 3.32450950e-05, 3.00308020e-05, - 2.50751595e-05, 2.05764949e-05, 1.83177072e-05, 1.81967623e-05, - 1.84045287e-05, 2.47221887e-05, 2.86291947e-05, 2.74704638e-05, - 2.50885402e-05, 2.47008530e-05, 2.39909239e-05, 2.08276119e-05, - 1.84050281e-05, 1.87577766e-05, 1.91992214e-05, 1.81788263e-05, - 2.69752461e-05, 3.10017370e-05, 3.05868329e-05, 2.61721786e-05, - 2.37730902e-05, 2.32509082e-05, 2.00122278e-05, 1.71801781e-05, - 1.63572994e-05, 3.05932612e-05, 3.76974740e-05, 3.49152406e-05, - 2.45567964e-05, 1.85043998e-05, 1.79217674e-05, 1.79218437e-05, - 1.73882324e-05, 1.72804709e-05, 2.38465940e-05, 3.10455642e-05, - 3.34383871e-05, 2.71631106e-05, 2.20451349e-05, 2.21448033e-05, - 2.25839538e-05, 2.02019526e-05, 1.76747986e-05, 1.88510657e-05, - 2.38801008e-05, 3.32928765e-05, 3.77975336e-05, 3.34411380e-05, - 2.50018050e-05, 1.80256273e-05, 1.59972193e-05, 1.67073766e-05, - 2.99543546e-05, 3.56401081e-05, 3.41030357e-05, 2.75598025e-05, - 2.05834983e-05, 1.64327561e-05, 1.55374982e-05, 1.68493888e-05, - 3.22382322e-05, 3.69668713e-05, 3.42038495e-05, 2.67618620e-05, - 1.84327497e-05, 1.54386221e-05, 1.64309820e-05, 1.75794520e-05, - 3.32479176e-05, 3.90278589e-05, 3.24047703e-05, 2.43385735e-05, - 2.12247322e-05, 1.98400879e-05, 1.84500585e-05, 2.77350838e-05, - 3.13669493e-05, 3.21210343e-05, 3.03372799e-05, 2.39328429e-05, - 1.83700182e-05, 1.73139495e-05, 1.78198148e-05, 2.66921721e-05, - 3.02698185e-05, 3.00644995e-05, 2.73536368e-05, 2.51058547e-05, - 2.31390394e-05, 1.95118448e-05, 1.79721039e-05, 2.57236610e-05, - 3.04653716e-05, 3.03160071e-05, 2.85077618e-05, 2.70571833e-05, - 2.34573524e-05, 1.96007835e-05, 1.76721366e-05, 1.77631665e-05, - 2.30801327e-05, 3.07365910e-05, 3.82062665e-05, 3.68503675e-05, - 2.86474830e-05, 1.94297935e-05, 1.71044015e-05, 1.96353421e-05, - 2.91902040e-05, 3.29155567e-05, 2.97238749e-05, 2.42885445e-05, - 2.29431509e-05, 2.16137766e-05, 1.87820642e-05, 1.79993126e-05, - 2.29134397e-05, 2.93424036e-05, 3.37620258e-05, 2.97139105e-05, - 2.47226808e-05, 2.04539498e-05, 1.81121829e-05, 1.80655161e-05, - 2.53970989e-05, 3.04214227e-05, 3.11979733e-05, 2.75999348e-05, - 2.36927868e-05, 2.08430877e-05, 1.79743311e-05, 1.86953816e-05, - 2.00002484e-05, 2.51274832e-05, 3.29593404e-05, 3.66335272e-05, - 3.06256240e-05, 2.24313836e-05, 1.84556085e-05, 1.63493596e-05, - 1.61440320e-05, 1.73473326e-05, 2.73196050e-05, 3.08835590e-05, - 3.13949668e-05, 2.64419373e-05, 2.06729972e-05, 2.11541766e-05, - 1.95357285e-05, 1.69870468e-05, 2.71092871e-05, 3.04086342e-05, - 3.05308908e-05, 2.93511115e-05, 2.65400895e-05, 2.09492089e-05, - 1.85096769e-05, 1.92975522e-05, 2.94570264e-05, 3.51200773e-05, - 3.28210927e-05, 2.45759539e-05, 1.80996263e-05, 1.79438160e-05, - 1.87415559e-05, 2.48272686e-05, 2.96512332e-05, 3.27376001e-05, - 3.12827754e-05, 2.60040886e-05, 2.21036746e-05, 1.96376415e-05, - 1.73350182e-05, - 2.39874077e-05, 1.92184207e-05, 1.81704550e-05, 1.99180863e-05, - 2.32412417e-05, 2.74096629e-05, 2.97205765e-05, 3.01269181e-05, - 3.03631719e-05, 2.47906894e-05, 2.17580100e-05, 2.27175119e-05, - 2.42382132e-05, 2.44831504e-05, 2.51083792e-05, 2.72809200e-05, - 2.93319998e-05, 2.95500573e-05, 2.95207105e-05, 3.04930925e-05, - 2.25434811e-05, 1.95778761e-05, 2.02522002e-05, 2.31308195e-05, - 2.47865718e-05, 2.58414393e-05, 2.88476874e-05, 3.11840605e-05, - 3.19027632e-05, 1.99466529e-05, 1.48614629e-05, 1.69132847e-05, - 2.36320086e-05, 2.81117703e-05, 2.98655589e-05, 3.07738593e-05, - 3.12320965e-05, 3.12719375e-05, 2.38768473e-05, 1.85973666e-05, - 1.76296647e-05, 2.20137163e-05, 2.61023694e-05, 2.70355357e-05, - 2.73607417e-05, 2.92613180e-05, 3.12414923e-05, 2.84028839e-05, - 2.40468403e-05, 1.78992968e-05, 1.52029997e-05, 1.80455052e-05, - 2.41326026e-05, 3.00973106e-05, 3.24435344e-05, 3.19688653e-05, - 2.08123088e-05, 1.61441867e-05, 1.70049315e-05, 2.14715526e-05, - 2.70262055e-05, 3.10034668e-05, 3.22904486e-05, 3.15816633e-05, - 1.94437336e-05, 1.51917533e-05, 1.67306789e-05, 2.21522081e-05, - 2.89446452e-05, 3.22525813e-05, 3.20865855e-05, 3.10764438e-05, - 1.78618573e-05, 1.35875025e-05, 1.77484367e-05, 2.33053315e-05, - 2.69789553e-05, 2.96700373e-05, 3.09410739e-05, 2.17137266e-05, - 1.84549930e-05, 1.81966683e-05, 2.02975656e-05, 2.57329158e-05, - 3.02445743e-05, 3.12498878e-05, 3.08563110e-05, 2.25132664e-05, - 1.94474539e-05, 1.96956513e-05, 2.18968780e-05, 2.43719092e-05, - 2.67496436e-05, 2.96386581e-05, 3.07202848e-05, 2.32941681e-05, - 1.97031705e-05, 1.98781873e-05, 2.08824517e-05, 2.23590529e-05, - 2.59469807e-05, 2.94792620e-05, 3.10332401e-05, 3.09076973e-05, - 2.35676673e-05, 1.78265347e-05, 1.41323721e-05, 1.59946943e-05, - 2.26733949e-05, 3.00972817e-05, 3.17122648e-05, 3.01244184e-05, - 2.06323390e-05, 1.72784655e-05, 1.96737563e-05, 2.39687337e-05, - 2.56529523e-05, 2.75309977e-05, 2.99757030e-05, 3.05964164e-05, - 2.38377920e-05, 1.97044589e-05, 1.75736692e-05, 2.06187315e-05, - 2.45271247e-05, 2.85668148e-05, 3.07903656e-05, 3.05716794e-05, - 2.37122754e-05, 1.96339329e-05, 1.90631264e-05, 2.14174188e-05, - 2.45690998e-05, 2.76256615e-05, 3.04893419e-05, 3.02917280e-05, - 2.95970069e-05, 2.32296816e-05, 1.76889649e-05, 1.58623625e-05, - 2.01488246e-05, 2.58971849e-05, 2.93754802e-05, 3.18821584e-05, - 3.22803167e-05, 3.12862393e-05, 2.10399777e-05, 1.78392228e-05, - 1.83128345e-05, 2.26744433e-05, 2.81615855e-05, 2.93741003e-05, - 3.07277461e-05, 3.20509599e-05, 2.27145673e-05, 1.91555909e-05, - 1.88352467e-05, 2.03396949e-05, 2.31079547e-05, 2.74704585e-05, - 2.98039455e-05, 2.98303762e-05, 1.93617568e-05, 1.52430368e-05, - 1.80490238e-05, 2.51035559e-05, 3.05030322e-05, 3.07030643e-05, - 3.02723903e-05, 2.33674908e-05, 1.94667421e-05, 1.77465113e-05, - 1.93739973e-05, 2.41047754e-05, 2.76743234e-05, 2.95423695e-05, - 3.11477365e-05, - 2.40642459e-05, 1.95182992e-05, 1.85025653e-05, 2.03748835e-05, - 2.36898259e-05, 2.74301791e-05, 2.94213294e-05, 2.96943176e-05, - 2.97756384e-05, 2.47580757e-05, 2.18964809e-05, 2.27833246e-05, - 2.43224927e-05, 2.45718750e-05, 2.51390185e-05, 2.72863702e-05, - 2.91658739e-05, 2.92015972e-05, 2.90645911e-05, 2.99134984e-05, - 2.27911566e-05, 1.99335389e-05, 2.04698797e-05, 2.33583814e-05, - 2.49917340e-05, 2.57796486e-05, 2.84464383e-05, 3.05902408e-05, - 3.12325589e-05, 2.02684483e-05, 1.52973193e-05, 1.72946143e-05, - 2.40652453e-05, 2.83945582e-05, 2.96137938e-05, 3.01475617e-05, - 3.05604882e-05, 3.06133742e-05, 2.43919108e-05, 1.92619072e-05, - 1.80953860e-05, 2.24045819e-05, 2.62471290e-05, 2.67938650e-05, - 2.68712910e-05, 2.86376593e-05, 3.04860394e-05, 2.84853496e-05, - 2.44939527e-05, 1.83096370e-05, 1.55158098e-05, 1.83762034e-05, - 2.42774639e-05, 2.97233033e-05, 3.16421275e-05, 3.11731440e-05, - 2.09785531e-05, 1.66138730e-05, 1.75272183e-05, 2.19582311e-05, - 2.71916865e-05, 3.06878806e-05, 3.16811889e-05, 3.09114904e-05, - 1.95666659e-05, 1.56773241e-05, 1.73159208e-05, 2.25877095e-05, - 2.89246857e-05, 3.16862870e-05, 3.13175627e-05, 3.04175517e-05, - 1.82938588e-05, 1.41211500e-05, 1.83928000e-05, 2.39037754e-05, - 2.69986054e-05, 2.89753823e-05, 3.00961263e-05, 2.20768909e-05, - 1.90965893e-05, 1.87608633e-05, 2.05564529e-05, 2.55379914e-05, - 2.97159676e-05, 3.05913625e-05, 3.02235831e-05, 2.28384951e-05, - 2.00067510e-05, 2.02186059e-05, 2.22843664e-05, 2.44017982e-05, - 2.63593050e-05, 2.90480572e-05, 3.01025896e-05, 2.35701557e-05, - 2.01356385e-05, 2.02851413e-05, 2.13549195e-05, 2.26531738e-05, - 2.57912676e-05, 2.89304559e-05, 3.03668708e-05, 3.02690284e-05, - 2.43674465e-05, 1.87850890e-05, 1.46756598e-05, 1.62586397e-05, - 2.24666268e-05, 2.93366471e-05, 3.09153980e-05, 2.92944639e-05, - 2.10360817e-05, 1.79607907e-05, 2.02778283e-05, 2.43460812e-05, - 2.57411236e-05, 2.72323005e-05, 2.94456759e-05, 3.00231063e-05, - 2.45846771e-05, 2.03808048e-05, 1.79886826e-05, 2.09083494e-05, - 2.45939702e-05, 2.81606221e-05, 3.01042852e-05, 2.99904660e-05, - 2.39152517e-05, 2.00990848e-05, 1.95465556e-05, 2.19134079e-05, - 2.48736369e-05, 2.74926475e-05, 2.99675409e-05, 2.96536931e-05, - 2.88885182e-05, 2.36700207e-05, 1.82366154e-05, 1.62134949e-05, - 2.03936607e-05, 2.60220097e-05, 2.91785109e-05, 3.12228881e-05, - 3.15081535e-05, 3.06030724e-05, 2.17244652e-05, 1.87648848e-05, - 1.89927201e-05, 2.30014191e-05, 2.78604741e-05, 2.84359353e-05, - 2.96655151e-05, 3.11412167e-05, 2.28684995e-05, 1.97788734e-05, - 1.95335883e-05, 2.08062820e-05, 2.32553272e-05, 2.73706129e-05, - 2.94189463e-05, 2.92189194e-05, 2.01218577e-05, 1.60731184e-05, - 1.85118984e-05, 2.49880863e-05, 2.99411035e-05, 3.01004137e-05, - 2.96296745e-05, 2.38300606e-05, 2.01526606e-05, 1.83224800e-05, - 1.97359324e-05, 2.40115005e-05, 2.71864395e-05, 2.89572056e-05, - 3.05264640e-05, - 2.51586155e-05, 2.51640608e-05, 2.50078424e-05, 2.57683225e-05, - 2.59438985e-05, 2.47708905e-05, 2.38703552e-05, 2.36343126e-05, - 2.34289843e-05, 2.49388826e-05, 2.51489313e-05, 2.50707158e-05, - 2.51749644e-05, 2.51809993e-05, 2.50505725e-05, 2.47743529e-05, - 2.41048364e-05, 2.38696549e-05, 2.37662660e-05, 2.34011281e-05, - 2.54879775e-05, 2.54104844e-05, 2.51300056e-05, 2.54661383e-05, - 2.53905135e-05, 2.48448934e-05, 2.39689893e-05, 2.31791028e-05, - 2.28731684e-05, 2.53778323e-05, 2.42418969e-05, 2.48029973e-05, - 2.58963358e-05, 2.48969273e-05, 2.38691020e-05, 2.32815651e-05, - 2.31069231e-05, 2.31037309e-05, 2.60406642e-05, 2.61958633e-05, - 2.53218837e-05, 2.58013643e-05, 2.51591631e-05, 2.44506647e-05, - 2.40373280e-05, 2.36269926e-05, 2.30394077e-05, 2.46115396e-05, - 2.58970058e-05, 2.52016526e-05, 2.38668921e-05, 2.49683634e-05, - 2.52984496e-05, 2.36943194e-05, 2.25930914e-05, 2.27752446e-05, - 2.50842856e-05, 2.48798693e-05, 2.53519289e-05, 2.60085053e-05, - 2.50369388e-05, 2.34221706e-05, 2.27409890e-05, 2.29911328e-05, - 2.46658243e-05, 2.45904443e-05, 2.55071455e-05, 2.59140263e-05, - 2.43551600e-05, 2.27739351e-05, 2.27483325e-05, 2.31651762e-05, - 2.52663645e-05, 2.41096160e-05, 2.59701291e-05, 2.62490786e-05, - 2.48448531e-05, 2.34713943e-05, 2.30435854e-05, 2.57144973e-05, - 2.60980218e-05, 2.57939945e-05, 2.52572212e-05, 2.46150697e-05, - 2.35148496e-05, 2.31108952e-05, 2.32522187e-05, 2.56679262e-05, - 2.60018408e-05, 2.59297228e-05, 2.57867927e-05, 2.50648072e-05, - 2.42344433e-05, 2.35949889e-05, 2.33042147e-05, 2.55750390e-05, - 2.56631384e-05, 2.56164474e-05, 2.59277135e-05, 2.55875831e-05, - 2.46757139e-05, 2.36739814e-05, 2.31723999e-05, 2.32321851e-05, - 2.66098556e-05, 2.70423862e-05, 2.44019750e-05, 2.40084246e-05, - 2.44052355e-05, 2.33161047e-05, 2.28618819e-05, 2.32346221e-05, - 2.57147604e-05, 2.59999334e-05, 2.61649000e-05, 2.57673311e-05, - 2.51165082e-05, 2.43098531e-05, 2.35826354e-05, 2.33775082e-05, - 2.64760046e-05, 2.63784962e-05, 2.51279908e-05, 2.53967659e-05, - 2.51371578e-05, 2.40133937e-05, 2.32257126e-05, 2.33777499e-05, - 2.54207350e-05, 2.57491087e-05, 2.57057845e-05, 2.60288570e-05, - 2.55893359e-05, 2.45280154e-05, 2.34523967e-05, 2.33992327e-05, - 2.34682763e-05, 2.59268935e-05, 2.56228456e-05, 2.43036726e-05, - 2.51895169e-05, 2.51525563e-05, 2.40634495e-05, 2.28871044e-05, - 2.26724398e-05, 2.30811166e-05, 2.64896618e-05, 2.69350176e-05, - 2.61976237e-05, 2.56774413e-05, 2.42161027e-05, 2.32109858e-05, - 2.28692978e-05, 2.26734712e-05, 2.52784190e-05, 2.61529234e-05, - 2.63385584e-05, 2.58532889e-05, 2.52857221e-05, 2.45987429e-05, - 2.37673513e-05, 2.35321464e-05, 2.65887566e-05, 2.60499109e-05, - 2.54197441e-05, 2.47757313e-05, 2.34138867e-05, 2.33219033e-05, - 2.33993675e-05, 2.59683789e-05, 2.63809341e-05, 2.57344432e-05, - 2.53896534e-05, 2.48039278e-05, 2.40149616e-05, 2.36204591e-05, - 2.31712374e-05, - 2.52496960e-05, 2.76416970e-05, 2.80365038e-05, 2.79572395e-05, - 2.63916081e-05, 2.32701051e-05, 2.14613773e-05, 2.11078073e-05, - 2.08665979e-05, 2.46596124e-05, 2.63139069e-05, 2.57645576e-05, - 2.51465581e-05, 2.50358705e-05, 2.46166022e-05, 2.33374656e-05, - 2.18094915e-05, 2.15530321e-05, 2.15024998e-05, 2.07826304e-05, - 2.62844787e-05, 2.77332384e-05, 2.70537902e-05, 2.59711590e-05, - 2.50866928e-05, 2.40852381e-05, 2.19700215e-05, 2.02861024e-05, - 1.97267841e-05, 2.74970987e-05, 2.90852465e-05, 2.85163120e-05, - 2.61436998e-05, 2.29686893e-05, 2.13780821e-05, 2.05679290e-05, - 2.02280114e-05, 2.02033437e-05, 2.61528644e-05, 2.92065564e-05, - 2.87325582e-05, 2.68802957e-05, 2.42346297e-05, 2.31908373e-05, - 2.26920020e-05, 2.15275712e-05, 2.01916256e-05, 2.26313939e-05, - 2.59300600e-05, 2.84273464e-05, 2.83651551e-05, 2.80595206e-05, - 2.53170229e-05, 2.11561566e-05, 1.92953980e-05, 1.96592428e-05, - 2.67152015e-05, 2.90875171e-05, 2.91474937e-05, 2.73836187e-05, - 2.36683650e-05, 2.04762906e-05, 1.94118975e-05, 1.99722347e-05, - 2.69374883e-05, 2.93276233e-05, 2.95126578e-05, 2.69259545e-05, - 2.21709939e-05, 1.94387426e-05, 1.95745607e-05, 2.03432049e-05, - 2.85279545e-05, 2.97933029e-05, 2.94505343e-05, 2.66532500e-05, - 2.35428311e-05, 2.12287868e-05, 2.03489847e-05, 2.69435212e-05, - 2.91762154e-05, 2.89681241e-05, 2.71745548e-05, 2.39251298e-05, - 2.09779529e-05, 2.02193122e-05, 2.05079305e-05, 2.64858717e-05, - 2.84864580e-05, 2.82640512e-05, 2.69254214e-05, 2.49763558e-05, - 2.31298995e-05, 2.13300654e-05, 2.06087490e-05, 2.59997539e-05, - 2.79553809e-05, 2.78063225e-05, 2.76114420e-05, 2.64804898e-05, - 2.38838893e-05, 2.14602650e-05, 2.03708456e-05, 2.04696302e-05, - 2.68443657e-05, 3.06868606e-05, 2.98017355e-05, 2.80577460e-05, - 2.50807986e-05, 2.09243099e-05, 1.98464734e-05, 2.08554594e-05, - 2.75108781e-05, 2.97789215e-05, 2.85437202e-05, 2.58481549e-05, - 2.44172163e-05, 2.28469126e-05, 2.11571207e-05, 2.07143531e-05, - 2.65719746e-05, 2.87675815e-05, 2.85277064e-05, 2.71640137e-05, - 2.49729701e-05, 2.21353840e-05, 2.05294231e-05, 2.07278742e-05, - 2.56405534e-05, 2.80920802e-05, 2.83617512e-05, 2.74341648e-05, - 2.53782588e-05, 2.29768506e-05, 2.08120589e-05, 2.08852366e-05, - 2.12596163e-05, 2.63809037e-05, 2.90648160e-05, 2.85215939e-05, - 2.71753779e-05, 2.43301085e-05, 2.17617542e-05, 1.97438696e-05, - 1.94246001e-05, 2.01854972e-05, 2.81315796e-05, 3.05511634e-05, - 2.93795445e-05, 2.64140814e-05, 2.24797366e-05, 2.11582730e-05, - 2.03333897e-05, 1.95749244e-05, 2.59825657e-05, 2.88279591e-05, - 2.92314758e-05, 2.78225567e-05, 2.57989056e-05, 2.31073650e-05, - 2.13574261e-05, 2.11960710e-05, 2.92059388e-05, 3.12059011e-05, - 2.86046892e-05, 2.43603716e-05, 2.07842468e-05, 2.06273085e-05, - 2.08949604e-05, 2.63500677e-05, 2.89081970e-05, 2.91658599e-05, - 2.78202787e-05, 2.48431681e-05, 2.25371206e-05, 2.13931885e-05, - 2.03047322e-05, - 2.33229984e-05, 3.97001900e-05, 4.45443106e-05, 3.52143899e-05, - 2.32755299e-05, 1.47675949e-05, 1.14276362e-05, 1.11805801e-05, - 1.13204989e-05, 2.16050661e-05, 3.04026769e-05, 2.74819727e-05, - 2.25299115e-05, 2.17907669e-05, 2.03657243e-05, 1.51216438e-05, - 1.16401141e-05, 1.19390428e-05, 1.24153814e-05, 1.10543020e-05, - 2.68487144e-05, 3.75666531e-05, 3.57923516e-05, 2.50476346e-05, - 2.02725603e-05, 1.89108393e-05, 1.35409514e-05, 9.88906586e-06, - 8.95149208e-06, 3.62379531e-05, 6.35816232e-05, 5.09370909e-05, - 2.22008606e-05, 1.21508785e-05, 1.09797182e-05, 1.07180983e-05, - 1.00752878e-05, 9.96204383e-06, 2.09904568e-05, 3.92085241e-05, - 4.60390671e-05, 2.76696705e-05, 1.71949071e-05, 1.68422249e-05, - 1.72256908e-05, 1.35958877e-05, 1.03485509e-05, 1.24257887e-05, - 2.09203252e-05, 4.51781607e-05, 6.27209884e-05, 4.52075927e-05, - 2.24814864e-05, 1.10162731e-05, 8.51102797e-06, 9.25537484e-06, - 3.38720649e-05, 5.45726006e-05, 4.88663167e-05, 2.88921446e-05, - 1.49433449e-05, 9.23036882e-06, 8.14036359e-06, 9.47873543e-06, - 4.02065046e-05, 6.06154317e-05, 4.97257799e-05, 2.68764635e-05, - 1.17942320e-05, 8.06222430e-06, 8.97660714e-06, 1.03004510e-05, - 4.51555690e-05, 7.19571756e-05, 4.35621953e-05, 2.21232943e-05, - 1.57373212e-05, 1.30513471e-05, 1.11951143e-05, 2.89316276e-05, - 4.01028114e-05, 4.21207031e-05, 3.52627445e-05, 1.98908248e-05, - 1.13211556e-05, 9.99965507e-06, 1.05946609e-05, 2.64218909e-05, - 3.63454592e-05, 3.55921852e-05, 2.81029048e-05, 2.24564456e-05, - 1.82504720e-05, 1.27089966e-05, 1.07829000e-05, 2.42185267e-05, - 3.63464752e-05, 3.58097731e-05, 3.11945948e-05, 2.71575565e-05, - 1.91232168e-05, 1.28601611e-05, 1.04019759e-05, 1.05249712e-05, - 2.01058632e-05, 3.98877243e-05, 6.75207906e-05, 5.79323225e-05, - 2.94513321e-05, 1.24659346e-05, 9.68484484e-06, 1.26743382e-05, - 3.27178615e-05, 4.56135390e-05, 3.49765423e-05, 2.15629511e-05, - 1.86122093e-05, 1.59519645e-05, 1.18276150e-05, 1.08451270e-05, - 1.96899932e-05, 3.42143618e-05, 4.68659433e-05, 3.36850282e-05, - 2.17909017e-05, 1.41463184e-05, 1.09018953e-05, 1.09181583e-05, - 2.33874388e-05, 3.63633229e-05, 3.87549524e-05, 2.90182006e-05, - 2.03029839e-05, 1.49885576e-05, 1.08509045e-05, 1.16390196e-05, - 1.32512395e-05, 2.33638686e-05, 4.48753858e-05, 5.77745971e-05, - 3.60108092e-05, 1.78027792e-05, 1.16790351e-05, 8.94896419e-06, - 8.67614268e-06, 1.00221341e-05, 2.89467681e-05, 4.01722190e-05, - 4.04051579e-05, 2.58744202e-05, 1.45620956e-05, 1.46174535e-05, - 1.23690377e-05, 9.49335118e-06, 2.69027877e-05, 3.70526481e-05, - 3.77907210e-05, 3.33839017e-05, 2.56412503e-05, 1.51824166e-05, - 1.15997028e-05, 1.24154737e-05, 3.49092234e-05, 5.57664913e-05, - 4.38749720e-05, 2.11841178e-05, 1.09720621e-05, 1.07597624e-05, - 1.16924467e-05, 2.28036780e-05, 3.51307837e-05, 4.42820407e-05, - 3.84298836e-05, 2.39856767e-05, 1.64792569e-05, 1.28777663e-05, - 1.00462788e-05, - 2.46941732e-05, 3.70815656e-05, 4.04497045e-05, 3.31676823e-05, - 2.38500011e-05, 1.70277203e-05, 1.40727360e-05, 1.39442421e-05, - 1.42395171e-05, 2.34105076e-05, 3.04570188e-05, 2.82553325e-05, - 2.39901309e-05, 2.33353089e-05, 2.21840737e-05, 1.73854417e-05, - 1.41587426e-05, 1.46490457e-05, 1.52516690e-05, 1.39494432e-05, - 2.72656482e-05, 3.52844345e-05, 3.44499073e-05, 2.58231675e-05, - 2.17799511e-05, 2.10281965e-05, 1.63398266e-05, 1.27106502e-05, - 1.17424498e-05, 3.44161109e-05, 5.24661406e-05, 4.46313313e-05, - 2.29882942e-05, 1.42007263e-05, 1.35639579e-05, 1.36332452e-05, - 1.29783229e-05, 1.28440562e-05, 2.18082464e-05, 3.52507501e-05, - 4.08560207e-05, 2.75591549e-05, 1.91224346e-05, 1.93742263e-05, - 2.01129377e-05, 1.66537616e-05, 1.33478599e-05, 1.46850359e-05, - 2.18813491e-05, 4.05276888e-05, 5.28211614e-05, 4.09267870e-05, - 2.38231124e-05, 1.37168341e-05, 1.13450428e-05, 1.21760287e-05, - 3.31347555e-05, 4.65280038e-05, 4.24792824e-05, 2.82630028e-05, - 1.70043322e-05, 1.17745585e-05, 1.07936107e-05, 1.23247337e-05, - 3.81758375e-05, 5.02665183e-05, 4.27081794e-05, 2.68085983e-05, - 1.41663318e-05, 1.06767037e-05, 1.18446090e-05, 1.32118679e-05, - 4.04087585e-05, 5.66761456e-05, 3.83197140e-05, 2.25808283e-05, - 1.79501413e-05, 1.61695466e-05, 1.43489899e-05, 2.86390515e-05, - 3.59662958e-05, 3.76970676e-05, 3.38985773e-05, 2.21598501e-05, - 1.41837411e-05, 1.28849744e-05, 1.35064085e-05, 2.67211625e-05, - 3.36276303e-05, 3.32110596e-05, 2.79137476e-05, 2.40377373e-05, - 2.09492424e-05, 1.56993799e-05, 1.36949194e-05, 2.50181326e-05, - 3.40944402e-05, 3.37882686e-05, 3.00838476e-05, 2.73991493e-05, - 2.13829898e-05, 1.58105787e-05, 1.33282761e-05, 1.34366711e-05, - 2.05253000e-05, 3.44802431e-05, 5.40150796e-05, 5.00254636e-05, - 3.06451462e-05, 1.56257216e-05, 1.26536992e-05, 1.59198855e-05, - 3.14651391e-05, 3.95066840e-05, 3.24725339e-05, 2.25638994e-05, - 2.05040730e-05, 1.85977532e-05, 1.47172068e-05, 1.37209037e-05, - 2.02818407e-05, 3.16669549e-05, 4.16752577e-05, 3.25807525e-05, - 2.33788868e-05, 1.69552433e-05, 1.38850804e-05, 1.38060197e-05, - 2.44778518e-05, 3.39871282e-05, 3.56581883e-05, 2.83350064e-05, - 2.16223987e-05, 1.74403157e-05, 1.36797925e-05, 1.46259442e-05, - 1.63934119e-05, 2.39410903e-05, 3.96645839e-05, 4.93568980e-05, - 3.45206073e-05, 1.97088096e-05, 1.42293304e-05, 1.17314331e-05, - 1.15101538e-05, 1.29301888e-05, 2.77460771e-05, 3.48077475e-05, - 3.60136290e-05, 2.62694953e-05, 1.72391406e-05, 1.80901172e-05, - 1.58362054e-05, 1.25309389e-05, 2.75477658e-05, 3.38960741e-05, - 3.41275669e-05, 3.17650035e-05, 2.65104531e-05, 1.75836058e-05, - 1.43351750e-05, 1.54157394e-05, 3.18693522e-05, 4.50140562e-05, - 3.93729095e-05, 2.31932073e-05, 1.38455566e-05, 1.36564754e-05, - 1.46871292e-05, 2.34290565e-05, 3.22925401e-05, 3.91266480e-05, - 3.58987851e-05, 2.56404017e-05, 1.93795138e-05, 1.58685900e-05, - 1.29042152e-05, - 2.54422626e-05, 2.51209402e-05, 2.49112868e-05, 2.46058436e-05, - 2.43341428e-05, 2.44410020e-05, 2.43131011e-05, 2.45306524e-05, - 2.49299133e-05, 2.56037579e-05, 2.56156045e-05, 2.57360304e-05, - 2.53545635e-05, 2.52747892e-05, 2.52920181e-05, 2.45524840e-05, - 2.40765921e-05, 2.45935936e-05, 2.49927836e-05, 2.48150858e-05, - 2.51416597e-05, 2.49452279e-05, 2.54296000e-05, 2.51106835e-05, - 2.47906753e-05, 2.53653916e-05, 2.51860912e-05, 2.43814683e-05, - 2.41114144e-05, 2.50707397e-05, 2.37208448e-05, 2.45216150e-05, - 2.43053859e-05, 2.31703282e-05, 2.40511051e-05, 2.47913521e-05, - 2.46291081e-05, 2.45525045e-05, 2.39693256e-05, 2.38098492e-05, - 2.43650718e-05, 2.47236587e-05, 2.45590195e-05, 2.55166592e-05, - 2.62290243e-05, 2.57334495e-05, 2.49258852e-05, 2.37248217e-05, - 2.41609367e-05, 2.46010893e-05, 2.42853375e-05, 2.48995853e-05, - 2.51740908e-05, 2.43399347e-05, 2.41555817e-05, 2.45221205e-05, - 2.55910999e-05, 2.40197692e-05, 2.40471736e-05, 2.44507041e-05, - 2.41095533e-05, 2.34951447e-05, 2.35635480e-05, 2.43624498e-05, - 2.57446554e-05, 2.36636072e-05, 2.37646541e-05, 2.45541628e-05, - 2.37846447e-05, 2.34334211e-05, 2.43295673e-05, 2.46957093e-05, - 2.45199849e-05, 2.28167211e-05, 2.37638089e-05, 2.38089723e-05, - 2.46370178e-05, 2.57439602e-05, 2.54595066e-05, 2.48509971e-05, - 2.38730992e-05, 2.41086093e-05, 2.52872717e-05, 2.58601854e-05, - 2.47972775e-05, 2.45685672e-05, 2.47571377e-05, 2.48811511e-05, - 2.42383200e-05, 2.43731715e-05, 2.47485705e-05, 2.55058098e-05, - 2.61479947e-05, 2.53966873e-05, 2.47973987e-05, 2.49136624e-05, - 2.46846905e-05, 2.47765997e-05, 2.45374334e-05, 2.50097935e-05, - 2.56501120e-05, 2.53443543e-05, 2.47536199e-05, 2.47425169e-05, - 2.30642118e-05, 2.26909056e-05, 2.30361281e-05, 2.47075443e-05, - 2.66759476e-05, 2.57149934e-05, 2.47259469e-05, 2.59423136e-05, - 2.47825710e-05, 2.35459418e-05, 2.40937204e-05, 2.44189024e-05, - 2.49161687e-05, 2.54934692e-05, 2.49749938e-05, 2.47226962e-05, - 2.31837880e-05, 2.38466640e-05, 2.45324261e-05, 2.51746890e-05, - 2.53376649e-05, 2.53548974e-05, 2.49947133e-05, 2.47678797e-05, - 2.50749603e-05, 2.45699812e-05, 2.44765549e-05, 2.44232828e-05, - 2.45120823e-05, 2.48744008e-05, 2.46102526e-05, 2.51566936e-05, - 2.58358691e-05, 2.43645843e-05, 2.40897979e-05, 2.43591612e-05, - 2.53367045e-05, 2.47035778e-05, 2.41603308e-05, 2.40873746e-05, - 2.41828518e-05, 2.46314038e-05, 2.38042064e-05, 2.28063352e-05, - 2.37235326e-05, 2.48502749e-05, 2.51977793e-05, 2.67659566e-05, - 2.63738474e-05, 2.48756696e-05, 2.54352335e-05, 2.40010900e-05, - 2.37170352e-05, 2.45731540e-05, 2.53890000e-05, 2.48316981e-05, - 2.45668816e-05, 2.53538885e-05, 2.35438970e-05, 2.24616297e-05, - 2.44400037e-05, 2.57938638e-05, 2.47450752e-05, 2.47551612e-05, - 2.51858874e-05, 2.42611321e-05, 2.38040848e-05, 2.40009178e-05, - 2.49148666e-05, 2.59950801e-05, 2.60812157e-05, 2.54349832e-05, - 2.45078526e-05, - 2.46393896e-05, 2.15207052e-05, 2.07468389e-05, 2.21244220e-05, - 2.43269954e-05, 2.65031345e-05, 2.75000219e-05, 2.76585985e-05, - 2.77467944e-05, 2.50785677e-05, 2.32329999e-05, 2.38339557e-05, - 2.47939717e-05, 2.49415952e-05, 2.52855100e-05, 2.64378279e-05, - 2.73460967e-05, 2.74277279e-05, 2.74067282e-05, 2.77985228e-05, - 2.38057969e-05, 2.18199009e-05, 2.22265051e-05, 2.41712253e-05, - 2.51581026e-05, 2.56689831e-05, 2.71149052e-05, 2.80562102e-05, - 2.83028907e-05, 2.20676151e-05, 1.81175259e-05, 1.97885249e-05, - 2.45577316e-05, 2.68477572e-05, 2.75582750e-05, 2.79059798e-05, - 2.80760158e-05, 2.80898851e-05, 2.47294034e-05, 2.12810485e-05, - 2.04168573e-05, 2.35264271e-05, 2.58660605e-05, 2.62599617e-05, - 2.63629055e-05, 2.72696430e-05, 2.80804324e-05, 2.69653475e-05, - 2.48073190e-05, 2.05895193e-05, 1.83106215e-05, 2.06490848e-05, - 2.47535244e-05, 2.76480903e-05, 2.84850653e-05, 2.83359610e-05, - 2.25950600e-05, 1.92266394e-05, 1.99626447e-05, 2.32127831e-05, - 2.63398406e-05, 2.79720445e-05, 2.84091274e-05, 2.81978750e-05, - 2.15759719e-05, 1.84408358e-05, 1.97874671e-05, 2.36365296e-05, - 2.71906596e-05, 2.83901026e-05, 2.83716206e-05, 2.80191996e-05, - 2.05750252e-05, 1.70789616e-05, 2.06265992e-05, 2.44181331e-05, - 2.62905163e-05, 2.74431725e-05, 2.79626839e-05, 2.33155002e-05, - 2.11611446e-05, 2.09184920e-05, 2.22829940e-05, 2.55653074e-05, - 2.77020540e-05, 2.80820264e-05, 2.79371818e-05, 2.38209454e-05, - 2.18436443e-05, 2.20020992e-05, 2.34481876e-05, 2.48533388e-05, - 2.60657094e-05, 2.74432161e-05, 2.78856373e-05, 2.42930998e-05, - 2.19560700e-05, 2.20675719e-05, 2.28079370e-05, 2.37074523e-05, - 2.56983477e-05, 2.73784192e-05, 2.80032987e-05, 2.79564801e-05, - 2.46321701e-05, 2.08763255e-05, 1.75709886e-05, 1.89433442e-05, - 2.36671976e-05, 2.76214692e-05, 2.82495197e-05, 2.76241961e-05, - 2.25995430e-05, 2.02868618e-05, 2.20312585e-05, 2.47387824e-05, - 2.56091508e-05, 2.65002723e-05, 2.75925392e-05, 2.78388242e-05, - 2.47729658e-05, 2.20919652e-05, 2.03382831e-05, 2.25280201e-05, - 2.49596129e-05, 2.69839606e-05, 2.79109747e-05, 2.78291022e-05, - 2.45213905e-05, 2.19248313e-05, 2.15182716e-05, 2.31810687e-05, - 2.50647106e-05, 2.65816078e-05, 2.77983780e-05, 2.77149470e-05, - 2.74084062e-05, 2.43168842e-05, 2.05178511e-05, 1.89012210e-05, - 2.21681620e-05, 2.57518182e-05, 2.73629046e-05, 2.82951483e-05, - 2.84321583e-05, 2.80957404e-05, 2.30160302e-05, 2.08669375e-05, - 2.10776398e-05, 2.39248081e-05, 2.68101405e-05, 2.72603297e-05, - 2.78526294e-05, 2.83703644e-05, 2.38734567e-05, 2.16680164e-05, - 2.14764632e-05, 2.24284957e-05, 2.41222748e-05, 2.65117513e-05, - 2.75305309e-05, 2.75238875e-05, 2.18922158e-05, 1.87464106e-05, - 2.07402753e-05, 2.52314798e-05, 2.78029001e-05, 2.78792888e-05, - 2.77066938e-05, 2.44088350e-05, 2.19276148e-05, 2.05809841e-05, - 2.16741544e-05, 2.46411340e-05, 2.65265631e-05, 2.74016233e-05, - 2.80443146e-05, - 2.50778002e-05, 2.42273238e-05, 2.38898312e-05, 2.48577635e-05, - 2.56126889e-05, 2.52748021e-05, 2.48086823e-05, 2.46531777e-05, - 2.45013133e-05, 2.50210085e-05, 2.46893607e-05, 2.47911987e-05, - 2.51326192e-05, 2.51774533e-05, 2.51663345e-05, 2.52589633e-05, - 2.49634126e-05, 2.47852387e-05, 2.46899538e-05, 2.44932545e-05, - 2.51102213e-05, 2.44989578e-05, 2.43984416e-05, 2.51933426e-05, - 2.54041716e-05, 2.51043309e-05, 2.47778617e-05, 2.43828399e-05, - 2.41972104e-05, 2.45437482e-05, 2.25508178e-05, 2.34601347e-05, - 2.56399023e-05, 2.54865062e-05, 2.48269530e-05, 2.44225123e-05, - 2.43240938e-05, 2.43262392e-05, 2.58028448e-05, 2.49379686e-05, - 2.40300985e-05, 2.52773419e-05, 2.54137996e-05, 2.49428012e-05, - 2.46308804e-05, 2.45324611e-05, 2.42646580e-05, 2.52791011e-05, - 2.57106830e-05, 2.39901851e-05, 2.23340549e-05, 2.38322102e-05, - 2.52198269e-05, 2.47025958e-05, 2.40095959e-05, 2.41167465e-05, - 2.44649375e-05, 2.33516219e-05, 2.39192289e-05, 2.53500557e-05, - 2.54484329e-05, 2.45779632e-05, 2.41255158e-05, 2.42637416e-05, - 2.38638001e-05, 2.29033239e-05, 2.39822927e-05, 2.53958171e-05, - 2.51304954e-05, 2.41508440e-05, 2.41068561e-05, 2.43567346e-05, - 2.40344918e-05, 2.21354687e-05, 2.45758654e-05, 2.58792112e-05, - 2.52754610e-05, 2.44488750e-05, 2.42308064e-05, 2.51510843e-05, - 2.48292184e-05, 2.45299268e-05, 2.45116083e-05, 2.48906947e-05, - 2.45623507e-05, 2.43298998e-05, 2.44067735e-05, 2.52551155e-05, - 2.49550518e-05, 2.49457904e-05, 2.52441894e-05, 2.50609654e-05, - 2.47140459e-05, 2.45541401e-05, 2.44359132e-05, 2.53125804e-05, - 2.47298034e-05, 2.47258287e-05, 2.51734416e-05, 2.51609736e-05, - 2.49752362e-05, 2.46029011e-05, 2.43577491e-05, 2.43953802e-05, - 2.62268596e-05, 2.54502318e-05, 2.24998300e-05, 2.26243887e-05, - 2.42250219e-05, 2.43666306e-05, 2.41634037e-05, 2.42977052e-05, - 2.49510450e-05, 2.44969374e-05, 2.51329928e-05, 2.55883306e-05, - 2.53078373e-05, 2.48920646e-05, 2.45874744e-05, 2.44854811e-05, - 2.61617311e-05, 2.53129108e-05, 2.38623290e-05, 2.46868095e-05, - 2.51473587e-05, 2.47783774e-05, 2.43746910e-05, 2.44825176e-05, - 2.52534150e-05, 2.47863328e-05, 2.46371686e-05, 2.53568438e-05, - 2.55374282e-05, 2.50952705e-05, 2.45384748e-05, 2.44656089e-05, - 2.44365492e-05, 2.55964511e-05, 2.42844956e-05, 2.28301479e-05, - 2.44278364e-05, 2.53765267e-05, 2.49328174e-05, 2.42072621e-05, - 2.40617859e-05, 2.43077202e-05, 2.56653020e-05, 2.53674112e-05, - 2.48794073e-05, 2.52913153e-05, 2.48995416e-05, 2.41798285e-05, - 2.40483047e-05, 2.40346946e-05, 2.49646665e-05, 2.50186600e-05, - 2.51028017e-05, 2.50089610e-05, 2.50380641e-05, 2.51343066e-05, - 2.47285798e-05, 2.45236754e-05, 2.54139747e-05, 2.40618378e-05, - 2.41973386e-05, 2.49311910e-05, 2.45059095e-05, 2.44495126e-05, - 2.44632331e-05, 2.56549973e-05, 2.52669018e-05, 2.43864083e-05, - 2.44419389e-05, 2.47967025e-05, 2.46557027e-05, 2.45639569e-05, - 2.43711827e-05, - 2.49979802e-05, 2.40842569e-05, 2.37302201e-05, 2.49634294e-05, - 2.59202434e-05, 2.54277573e-05, 2.48573732e-05, 2.46131124e-05, - 2.43370565e-05, 2.48841519e-05, 2.45114225e-05, 2.45986662e-05, - 2.50816125e-05, 2.51514980e-05, 2.51269336e-05, 2.53838586e-05, - 2.51065860e-05, 2.47670249e-05, 2.45622493e-05, 2.43509125e-05, - 2.51212310e-05, 2.44504583e-05, 2.42143152e-05, 2.52234106e-05, - 2.55365983e-05, 2.50265338e-05, 2.46343807e-05, 2.43043089e-05, - 2.41297513e-05, 2.44732454e-05, 2.23928010e-05, 2.33050328e-05, - 2.59561554e-05, 2.59887505e-05, 2.49383511e-05, 2.42669066e-05, - 2.41775649e-05, 2.41965355e-05, 2.62373917e-05, 2.52652955e-05, - 2.40278313e-05, 2.54284451e-05, 2.55869097e-05, 2.47830107e-05, - 2.42499665e-05, 2.42145553e-05, 2.40408296e-05, 2.55909668e-05, - 2.60738388e-05, 2.39234533e-05, 2.20072461e-05, 2.36639754e-05, - 2.52300423e-05, 2.47168982e-05, 2.38851748e-05, 2.39406125e-05, - 2.42542544e-05, 2.32906943e-05, 2.39705045e-05, 2.55885839e-05, - 2.57249515e-05, 2.47479771e-05, 2.41610783e-05, 2.41588158e-05, - 2.35084877e-05, 2.28316533e-05, 2.41158316e-05, 2.56126314e-05, - 2.53861334e-05, 2.42223524e-05, 2.39693367e-05, 2.42044351e-05, - 2.39960294e-05, 2.20967843e-05, 2.48374666e-05, 2.63794545e-05, - 2.53881243e-05, 2.41069830e-05, 2.38897574e-05, 2.52471128e-05, - 2.51169537e-05, 2.46944426e-05, 2.43825082e-05, 2.46597144e-05, - 2.44417353e-05, 2.41977095e-05, 2.42543234e-05, 2.53588343e-05, - 2.51743760e-05, 2.51284016e-05, 2.53831902e-05, 2.49590669e-05, - 2.43737748e-05, 2.43082726e-05, 2.42824821e-05, 2.54129399e-05, - 2.47905635e-05, 2.47628144e-05, 2.53570104e-05, 2.52154918e-05, - 2.48054704e-05, 2.43803915e-05, 2.41935017e-05, 2.42430888e-05, - 2.70029626e-05, 2.61965565e-05, 2.24883624e-05, 2.22625968e-05, - 2.37194009e-05, 2.40092133e-05, 2.39559232e-05, 2.38787005e-05, - 2.50293792e-05, 2.47971246e-05, 2.54262092e-05, 2.58610257e-05, - 2.53791372e-05, 2.47208480e-05, 2.44363215e-05, 2.43605815e-05, - 2.68860972e-05, 2.57089221e-05, 2.37859841e-05, 2.46175065e-05, - 2.51001280e-05, 2.46012859e-05, 2.41644476e-05, 2.43473202e-05, - 2.52985244e-05, 2.48870684e-05, 2.47315880e-05, 2.56041140e-05, - 2.57687542e-05, 2.51051830e-05, 2.44512144e-05, 2.42453178e-05, - 2.40736599e-05, 2.58929636e-05, 2.44021744e-05, 2.25854340e-05, - 2.42713295e-05, 2.55097368e-05, 2.50489805e-05, 2.41476154e-05, - 2.39445545e-05, 2.41565393e-05, 2.61419563e-05, 2.60620060e-05, - 2.52167975e-05, 2.54086071e-05, 2.47877030e-05, 2.35789076e-05, - 2.34857609e-05, 2.37641155e-05, 2.48757165e-05, 2.53128360e-05, - 2.54897190e-05, 2.51522422e-05, 2.49711663e-05, 2.51644846e-05, - 2.47008386e-05, 2.42784204e-05, 2.59137934e-05, 2.45442769e-05, - 2.42112889e-05, 2.47300741e-05, 2.43815831e-05, 2.43084685e-05, - 2.42363629e-05, 2.59887463e-05, 2.56649695e-05, 2.45476609e-05, - 2.43897623e-05, 2.45346303e-05, 2.43074036e-05, 2.43130226e-05, - 2.42625075e-05, - 2.52524577e-05, 2.83227237e-05, 2.88860250e-05, 2.84912152e-05, - 2.64022259e-05, 2.28280725e-05, 2.08313391e-05, 2.04681024e-05, - 2.02416550e-05, 2.45785297e-05, 2.66285689e-05, 2.59533011e-05, - 2.51118718e-05, 2.49655553e-05, 2.44752122e-05, 2.29160560e-05, - 2.11871986e-05, 2.09559249e-05, 2.09376679e-05, 2.01413258e-05, - 2.64543917e-05, 2.83447023e-05, 2.75842675e-05, 2.60587328e-05, - 2.49419512e-05, 2.38697737e-05, 2.14688052e-05, 1.95739349e-05, - 1.89595008e-05, 2.80553232e-05, 3.05056947e-05, 2.95743892e-05, - 2.61003972e-05, 2.23610760e-05, 2.07184810e-05, 1.99082060e-05, - 1.95309504e-05, 1.94986974e-05, 2.60491627e-05, 2.99211562e-05, - 2.96546481e-05, 2.70942967e-05, 2.39269224e-05, 2.28685495e-05, - 2.23930594e-05, 2.10361640e-05, 1.95150483e-05, 2.20481182e-05, - 2.58215972e-05, 2.93110952e-05, 2.97257477e-05, 2.89302766e-05, - 2.52812335e-05, 2.05039634e-05, 1.85069440e-05, 1.89172340e-05, - 2.71685567e-05, 3.02732024e-05, 3.01722215e-05, 2.76578293e-05, - 2.32332416e-05, 1.97089691e-05, 1.85896358e-05, 1.92380929e-05, - 2.76128853e-05, 3.06861662e-05, 3.05786730e-05, 2.71066580e-05, - 2.15525229e-05, 1.86091063e-05, 1.88138057e-05, 1.96594077e-05, - 2.94148272e-05, 3.14552163e-05, 3.03214234e-05, 2.66100628e-05, - 2.31559809e-05, 2.07088233e-05, 1.97269539e-05, 2.72112750e-05, - 2.99209664e-05, 2.97739061e-05, 2.76894615e-05, 2.37590367e-05, - 2.03506760e-05, 1.95169884e-05, 1.98409696e-05, 2.66403548e-05, - 2.90765034e-05, 2.88202809e-05, 2.71584497e-05, 2.49371083e-05, - 2.28822634e-05, 2.07870283e-05, 1.99525964e-05, 2.60503657e-05, - 2.85302826e-05, 2.83578040e-05, 2.79838687e-05, 2.66664461e-05, - 2.36793979e-05, 2.09245530e-05, 1.96935945e-05, 1.97986763e-05, - 2.66978800e-05, 3.14760265e-05, 3.13589652e-05, 2.92831136e-05, - 2.53366583e-05, 2.03731433e-05, 1.91311343e-05, 2.03185922e-05, - 2.79402652e-05, 3.07289599e-05, 2.90848369e-05, 2.57714581e-05, - 2.41859467e-05, 2.24776874e-05, 2.05602240e-05, 2.00600980e-05, - 2.64017898e-05, 2.92858609e-05, 2.94669525e-05, 2.76213877e-05, - 2.49023191e-05, 2.16687449e-05, 1.98833570e-05, 2.00783898e-05, - 2.56495818e-05, 2.86714644e-05, 2.90334371e-05, 2.77145744e-05, - 2.52360007e-05, 2.25509290e-05, 2.01559718e-05, 2.02812894e-05, - 2.07514100e-05, 2.63956137e-05, 2.99634097e-05, 2.97656670e-05, - 2.77167991e-05, 2.40555916e-05, 2.11430569e-05, 1.89758765e-05, - 1.86450818e-05, 1.94856884e-05, 2.84223719e-05, 3.13458106e-05, - 3.01416495e-05, 2.65436875e-05, 2.20337736e-05, 2.07315770e-05, - 1.97873182e-05, 1.88531069e-05, 2.61504098e-05, 2.94537374e-05, - 2.98963424e-05, 2.82848123e-05, 2.59104530e-05, 2.26916525e-05, - 2.07412571e-05, 2.06367383e-05, 2.97628749e-05, 3.25286506e-05, - 2.94542138e-05, 2.42579955e-05, 2.01372248e-05, 1.99691082e-05, - 2.02943588e-05, 2.63377097e-05, 2.94652125e-05, 3.00493727e-05, - 2.84640612e-05, 2.48722703e-05, 2.21993184e-05, 2.08597021e-05, - 1.96035838e-05, - 2.52413918e-05, 2.81989573e-05, 2.87334565e-05, 2.84255923e-05, - 2.64393577e-05, 2.29098979e-05, 2.09283752e-05, 2.05572337e-05, - 2.03157552e-05, 2.45731400e-05, 2.65569566e-05, 2.58993343e-05, - 2.51100468e-05, 2.49721697e-05, 2.44907846e-05, 2.29917706e-05, - 2.12931929e-05, 2.10411411e-05, 2.10065319e-05, 2.02201383e-05, - 2.64298823e-05, 2.82453388e-05, 2.74781464e-05, 2.60489478e-05, - 2.49789977e-05, 2.38918291e-05, 2.15264155e-05, 1.96697446e-05, - 1.90644775e-05, 2.79609574e-05, 3.02630454e-05, 2.93896887e-05, - 2.61461575e-05, 2.25045124e-05, 2.08263038e-05, 1.99884346e-05, - 1.96177029e-05, 1.95882668e-05, 2.61182837e-05, 2.98617169e-05, - 2.95147371e-05, 2.70818709e-05, 2.39921243e-05, 2.28972225e-05, - 2.23930875e-05, 2.10736202e-05, 1.95909739e-05, 2.21671698e-05, - 2.58823147e-05, 2.91672285e-05, 2.94645831e-05, 2.87730717e-05, - 2.52872120e-05, 2.06005634e-05, 1.86094968e-05, 1.90078243e-05, - 2.70708281e-05, 3.00834917e-05, 3.00250189e-05, 2.76485374e-05, - 2.33282524e-05, 1.98377033e-05, 1.87125479e-05, 1.93345082e-05, - 2.74593629e-05, 3.04677536e-05, 3.04382335e-05, 2.71078169e-05, - 2.16701334e-05, 1.87365480e-05, 1.89109718e-05, 1.97435908e-05, - 2.92747764e-05, 3.11949914e-05, 3.02296026e-05, 2.66794898e-05, - 2.32253745e-05, 2.07482672e-05, 1.97826519e-05, 2.71835901e-05, - 2.98512887e-05, 2.96768083e-05, 2.75934889e-05, 2.37554120e-05, - 2.04296240e-05, 1.96059626e-05, 1.99226069e-05, 2.66303154e-05, - 2.90190358e-05, 2.87624203e-05, 2.71416334e-05, 2.49296531e-05, - 2.28787180e-05, 2.08401335e-05, 2.00325086e-05, 2.60550697e-05, - 2.84521461e-05, 2.82797698e-05, 2.79528733e-05, 2.66452846e-05, - 2.36889241e-05, 2.09789859e-05, 1.97755907e-05, 1.98809300e-05, - 2.68163499e-05, 3.14700387e-05, 3.11198205e-05, 2.90385504e-05, - 2.52313707e-05, 2.04159293e-05, 1.92146073e-05, 2.03527541e-05, - 2.78862771e-05, 3.06316909e-05, 2.90451009e-05, 2.58163393e-05, - 2.42280844e-05, 2.25122212e-05, 2.06314483e-05, 2.01426334e-05, - 2.65165780e-05, 2.92641938e-05, 2.93130386e-05, 2.75426183e-05, - 2.49063558e-05, 2.17174746e-05, 1.99559759e-05, 2.01591596e-05, - 2.56533302e-05, 2.85984097e-05, 2.89457555e-05, 2.77055897e-05, - 2.52849081e-05, 2.26142726e-05, 2.02426334e-05, 2.03464324e-05, - 2.07867919e-05, 2.64307454e-05, 2.98454394e-05, 2.95369908e-05, - 2.76128554e-05, 2.41113431e-05, 2.12456582e-05, 1.90817239e-05, - 1.87470046e-05, 1.95723883e-05, 2.84435258e-05, 3.13311254e-05, - 3.00769643e-05, 2.65390657e-05, 2.20865220e-05, 2.07287243e-05, - 1.98084388e-05, 1.89314186e-05, 2.61131373e-05, 2.94020545e-05, - 2.98528124e-05, 2.82350863e-05, 2.58845786e-05, 2.27557952e-05, - 2.08282438e-05, 2.06924265e-05, 2.97509562e-05, 3.24080286e-05, - 2.93278165e-05, 2.42480706e-05, 2.02187390e-05, 2.00505877e-05, - 2.03583115e-05, 2.63814204e-05, 2.94384324e-05, 2.99403189e-05, - 2.83592267e-05, 2.48343938e-05, 2.22091826e-05, 2.09107975e-05, - 1.96947399e-05}; +// pre-saved output result +float outputP[229 * 177] = { + 2.46442479e-05, 3.62009617e-05, 3.92805445e-05, 3.31105267e-05, 2.44610352e-05, 1.75168153e-05, + 1.44777033e-05, 1.42619684e-05, 1.44256744e-05, 2.33214435e-05, 2.99236955e-05, 2.78217067e-05, + 2.40172106e-05, 2.34277891e-05, 2.22964534e-05, 1.78370132e-05, 1.46574172e-05, 1.49789081e-05, + 1.54532469e-05, 1.41642524e-05, 2.72690126e-05, 3.47562524e-05, 3.36469828e-05, 2.59178471e-05, + 2.21619259e-05, 2.11235337e-05, 1.64959420e-05, 1.30077730e-05, 1.20597531e-05, 3.38864719e-05, + 5.02849103e-05, 4.31467475e-05, 2.36252856e-05, 1.50520325e-05, 1.40335571e-05, 1.38412257e-05, + 1.32075826e-05, 1.30914952e-05, 2.26312708e-05, 3.56262526e-05, 4.01062343e-05, 2.78118735e-05, + 1.96103207e-05, 1.94129410e-05, 1.98097588e-05, 1.65930717e-05, 1.34947934e-05, 1.53536951e-05, + 2.26003245e-05, 3.96166436e-05, 4.99489629e-05, 3.96964926e-05, 2.39565814e-05, 1.40911249e-05, + 1.16174600e-05, 1.23917415e-05, 3.23581886e-05, 4.51986705e-05, 4.17825601e-05, 2.86584918e-05, + 1.76376738e-05, 1.22950013e-05, 1.12000393e-05, 1.26026018e-05, 3.66475641e-05, 4.86016461e-05, + 4.22416834e-05, 2.72035730e-05, 1.47764258e-05, 1.11113020e-05, 1.20997196e-05, 1.34313365e-05, + 3.95855971e-05, 5.45908413e-05, 3.84210014e-05, 2.34986280e-05, 1.83787526e-05, 1.60994793e-05, + 1.43472775e-05, 2.87492245e-05, 3.62227971e-05, 3.75741363e-05, 3.32621927e-05, 2.19785358e-05, + 1.44159244e-05, 1.31294032e-05, 1.37200507e-05, 2.69149552e-05, 3.38086601e-05, 3.33251612e-05, + 2.81320872e-05, 2.39788080e-05, 2.06619087e-05, 1.57570698e-05, 1.39038052e-05, 2.52617372e-05, + 3.38908683e-05, 3.35448560e-05, 3.03151908e-05, 2.74780421e-05, 2.13293104e-05, 1.58912820e-05, + 1.35339022e-05, 1.36518387e-05, 2.18114936e-05, 3.58375602e-05, 5.22680335e-05, 4.73230483e-05, + 2.93944210e-05, 1.55590860e-05, 1.28316631e-05, 1.57698241e-05, 3.14234114e-05, 3.96628636e-05, + 3.28567929e-05, 2.31406106e-05, 2.08278162e-05, 1.86489096e-05, 1.49060567e-05, 1.39576809e-05, + 2.14946981e-05, 3.22923390e-05, 4.06564801e-05, 3.21599676e-05, 2.34356595e-05, 1.70535119e-05, + 1.40325872e-05, 1.40308912e-05, 2.46462488e-05, 3.38814557e-05, 3.54577281e-05, 2.87450834e-05, + 2.21524701e-05, 1.77522488e-05, 1.39546040e-05, 1.47437400e-05, 1.62893751e-05, 2.45330707e-05, + 3.93189778e-05, 4.71486445e-05, 3.37792038e-05, 2.01343432e-05, 1.47007211e-05, 1.20555822e-05, + 1.17869007e-05, 1.31558888e-05, 2.85944295e-05, 3.60464756e-05, 3.63889603e-05, 2.65026290e-05, + 1.74080173e-05, 1.75971986e-05, 1.55212658e-05, 1.26525981e-05, 2.73510167e-05, 3.42379060e-05, + 3.46739713e-05, 3.18499013e-05, 2.64033817e-05, 1.79173319e-05, 1.46597919e-05, 1.54831293e-05, + 3.27095867e-05, 4.55029367e-05, 3.87607603e-05, 2.30101128e-05, 1.40805548e-05, 1.38784434e-05, + 1.47962230e-05, 2.40873419e-05, 3.29083090e-05, 3.89264907e-05, 3.53248621e-05, 2.52257061e-05, + 1.91594181e-05, 1.59149924e-05, 1.31705002e-05, 2.54597212e-05, 3.45772037e-05, 3.68741094e-05, + 3.12028853e-05, 2.40349077e-05, 1.88272324e-05, 1.63827971e-05, 1.63853146e-05, 1.68275859e-05, + 2.45728577e-05, 3.00206570e-05, 2.84291124e-05, 2.48520731e-05, 2.42886621e-05, 2.34032420e-05, + 1.91738078e-05, 1.63351233e-05, 1.69943546e-05, 1.76931871e-05, 1.65302673e-05, 2.72134658e-05, + 3.30757563e-05, 3.28886277e-05, 2.60895485e-05, 2.27590610e-05, 2.25435029e-05, 1.86851618e-05, + 1.52931875e-05, 1.43608534e-05, 3.25418114e-05, 4.43134701e-05, 3.95450068e-05, 2.33622213e-05, + 1.59174770e-05, 1.58389562e-05, 1.62563189e-05, 1.56328955e-05, 1.54846478e-05, 2.22438891e-05, + 3.20169023e-05, 3.66204361e-05, 2.71167734e-05, 2.05463692e-05, 2.13239509e-05, 2.23570202e-05, + 1.92426016e-05, 1.60836201e-05, 1.65812802e-05, 2.24247624e-05, 3.66188744e-05, 4.52675416e-05, + 3.72152611e-05, 2.45971764e-05, 1.61047736e-05, 1.40457964e-05, 1.49105792e-05, 3.20369974e-05, + 4.03731253e-05, 3.74727893e-05, 2.74333528e-05, 1.86238908e-05, 1.41126618e-05, 1.33260519e-05, + 1.49622924e-05, 3.59950748e-05, 4.26592695e-05, 3.73420663e-05, 2.64237990e-05, 1.61958731e-05, + 1.31728851e-05, 1.45443428e-05, 1.58594170e-05, 3.64499062e-05, 4.61791629e-05, 3.41864876e-05, + 2.27205685e-05, 1.96696628e-05, 1.88488476e-05, 1.71849993e-05, 2.80282955e-05, 3.25922112e-05, + 3.40679773e-05, 3.23467724e-05, 2.37605397e-05, 1.67151122e-05, 1.55263654e-05, 1.61342371e-05, + 2.66031633e-05, 3.12196165e-05, 3.10320135e-05, 2.74027553e-05, 2.49946529e-05, 2.29810739e-05, + 1.82740588e-05, 1.63105032e-05, 2.53314846e-05, 3.19581792e-05, 3.18126563e-05, 2.88582413e-05, + 2.72145093e-05, 2.30071466e-05, 1.83376441e-05, 1.59842474e-05, 1.60691474e-05, 2.07001119e-05, + 3.04569861e-05, 4.45713120e-05, 4.37223253e-05, 3.10397952e-05, 1.83824157e-05, 1.54065489e-05, + 1.87487580e-05, 3.00894355e-05, 3.48246677e-05, 3.02485839e-05, 2.31155961e-05, 2.18469593e-05, + 2.06869431e-05, 1.72448533e-05, 1.62954796e-05, 2.05929740e-05, 2.94507214e-05, 3.73906570e-05, + 3.12579873e-05, 2.43656121e-05, 1.92790153e-05, 1.65656162e-05, 1.63881778e-05, 2.50323716e-05, + 3.17769911e-05, 3.29233516e-05, 2.74656534e-05, 2.24558865e-05, 1.93998510e-05, 1.62064391e-05, + 1.72621932e-05, 1.90841146e-05, 2.41249711e-05, 3.54774366e-05, 4.28204669e-05, 3.28585427e-05, + 2.10928982e-05, 1.64341423e-05, 1.43408917e-05, 1.41971772e-05, 1.55937912e-05, 2.65505266e-05, + 3.07911857e-05, 3.24881407e-05, 2.62376753e-05, 1.94209754e-05, 2.10188315e-05, 1.89105974e-05, + 1.53728286e-05, 2.76530072e-05, 3.12062321e-05, 3.11220201e-05, 3.01359857e-05, 2.68221797e-05, + 1.94900387e-05, 1.67241597e-05, 1.80174916e-05, 2.93415714e-05, 3.75759014e-05, 3.56116762e-05, + 2.45324185e-05, 1.64096975e-05, 1.62579367e-05, 1.73277891e-05, 2.36661067e-05, 2.98693250e-05, + 3.49999999e-05, 3.35045549e-05, 2.65950025e-05, 2.16712347e-05, 1.84338709e-05, 1.55137547e-05, + 2.43839683e-05, 3.83619688e-05, 4.22958465e-05, 3.37828119e-05, 2.33718957e-05, 1.61402691e-05, + 1.31069160e-05, 1.29886860e-05, 1.33093679e-05, 2.29988885e-05, 3.08083279e-05, 2.83467341e-05, + 2.36084331e-05, 2.28905282e-05, 2.16483766e-05, 1.65185155e-05, 1.31811302e-05, 1.37068672e-05, + 1.43443741e-05, 1.30092202e-05, 2.71893384e-05, 3.62540883e-05, 3.53458913e-05, 2.55933611e-05, + 2.11755948e-05, 2.04144351e-05, 1.54746544e-05, 1.17408692e-05, 1.07648424e-05, 3.52664660e-05, + 5.67227788e-05, 4.72419745e-05, 2.24373231e-05, 1.31745928e-05, 1.25797203e-05, 1.26884616e-05, + 1.20213059e-05, 1.18829027e-05, 2.11432996e-05, 3.60858250e-05, 4.27066875e-05, 2.74762600e-05, + 1.83356349e-05, 1.86675699e-05, 1.95018694e-05, 1.58332135e-05, 1.24078636e-05, 1.36951074e-05, + 2.12361443e-05, 4.23481677e-05, 5.72558679e-05, 4.28601190e-05, 2.34117996e-05, 1.27489156e-05, + 1.03743643e-05, 1.12146543e-05, 3.38525166e-05, 4.94662095e-05, 4.45954868e-05, 2.82330334e-05, + 1.60953362e-05, 1.07676587e-05, 9.80614279e-06, 1.13549135e-05, 3.97191822e-05, 5.39888061e-05, + 4.48310310e-05, 2.66297647e-05, 1.31730167e-05, 9.68613028e-06, 1.08763111e-05, 1.22591499e-05, + 4.21969429e-05, 6.18554260e-05, 3.96445375e-05, 2.19594230e-05, 1.71121323e-05, 1.53326686e-05, + 1.34496675e-05, 2.86904591e-05, 3.69194156e-05, 3.89585811e-05, 3.46953633e-05, 2.16666395e-05, + 1.32455617e-05, 1.19246895e-05, 1.25587607e-05, 2.65627781e-05, 3.42689281e-05, 3.38071803e-05, + 2.78724835e-05, 2.36728700e-05, 2.03885060e-05, 1.48272549e-05, 1.27510280e-05, 2.46931219e-05, + 3.48533582e-05, 3.45120999e-05, 3.02789718e-05, 2.73252373e-05, 2.08155205e-05, 1.49385408e-05, + 1.23792017e-05, 1.24877391e-05, 1.97111468e-05, 3.50760149e-05, 5.85457500e-05, 5.38525296e-05, + 3.11302513e-05, 1.47703074e-05, 1.17011294e-05, 1.50868802e-05, 3.18635500e-05, 4.10098732e-05, + 3.29352795e-05, 2.19889388e-05, 1.98226194e-05, 1.78474766e-05, 1.37975815e-05, 1.27732998e-05, + 1.94622081e-05, 3.19952282e-05, 4.37016450e-05, 3.31738719e-05, 2.29428893e-05, 1.61223948e-05, + 1.29537410e-05, 1.28616708e-05, 2.41165484e-05, 3.47174313e-05, 3.66324431e-05, 2.83106147e-05, + 2.09856331e-05, 1.65961304e-05, 1.27258534e-05, 1.37147755e-05, 1.55697907e-05, 2.34732395e-05, + 4.12636321e-05, 5.29748228e-05, 3.54168834e-05, 1.89641783e-05, 1.32571005e-05, 1.07528123e-05, + 1.05385355e-05, 1.19731708e-05, 2.75983947e-05, 3.54641701e-05, 3.69569644e-05, 2.60616190e-05, + 1.64074702e-05, 1.73994186e-05, 1.50264040e-05, 1.15858593e-05, 2.75298558e-05, 3.45503659e-05, + 3.47844391e-05, 3.21818299e-05, 2.63759020e-05, 1.67425688e-05, 1.33865513e-05, 1.45334202e-05, + 3.21931001e-05, 4.74181169e-05, 4.09640569e-05, 2.27785889e-05, 1.29004092e-05, 1.27099896e-05, + 1.37787552e-05, 2.29099542e-05, 3.27001632e-05, 4.06196518e-05, 3.69618775e-05, 2.54703133e-05, + 1.87127283e-05, 1.50036554e-05, 1.19408929e-05, 2.44535165e-05, 3.77886350e-05, 4.14898468e-05, + 3.36309437e-05, 2.36782021e-05, 1.64981453e-05, 1.34543802e-05, 1.33088922e-05, 1.35865812e-05, + 2.30801151e-05, 3.05714845e-05, 2.82034460e-05, 2.37179089e-05, 2.30342625e-05, 2.18188323e-05, + 1.68613695e-05, 1.35578482e-05, 1.40284614e-05, 1.46219260e-05, 1.32965985e-05, 2.72204204e-05, + 3.58688621e-05, 3.48916336e-05, 2.56881224e-05, 2.14419032e-05, 2.05974303e-05, 1.57304515e-05, + 1.20566507e-05, 1.10864900e-05, 3.49098261e-05, 5.49768428e-05, 4.61425623e-05, 2.27674184e-05, + 1.36605276e-05, 1.29487175e-05, 1.29745357e-05, 1.23153694e-05, 1.21828763e-05, 2.15527674e-05, + 3.60154973e-05, 4.20347113e-05, 2.75848328e-05, 1.86726493e-05, 1.88544348e-05, 1.95643312e-05, + 1.60154576e-05, 1.26750454e-05, 1.41232845e-05, 2.16108835e-05, 4.16318263e-05, 5.52314103e-05, + 4.20126543e-05, 2.35602108e-05, 1.30876243e-05, 1.06812233e-05, 1.15047485e-05, 3.34501642e-05, + 4.83356149e-05, 4.38749511e-05, 2.83726186e-05, 1.64993303e-05, 1.11523365e-05, 1.01529299e-05, + 1.16646816e-05, 3.88719453e-05, 5.25503895e-05, 4.41827193e-05, 2.68035983e-05, 1.35845472e-05, + 1.00411022e-05, 1.11785852e-05, 1.25497652e-05, 4.15168389e-05, 5.99068289e-05, 3.93711557e-05, + 2.23873760e-05, 1.74424039e-05, 1.55156193e-05, 1.36656564e-05, 2.87241780e-05, 3.67839865e-05, + 3.86301247e-05, 3.43180727e-05, 2.17387992e-05, 1.35377335e-05, 1.22236704e-05, 1.28469432e-05, + 2.66710175e-05, 3.41846577e-05, 3.37129795e-05, 2.79609066e-05, 2.37523918e-05, 2.04441478e-05, + 1.50554224e-05, 1.30372343e-05, 2.48549182e-05, 3.46212576e-05, 3.42760094e-05, 3.03159499e-05, + 2.73788152e-05, 2.09433071e-05, 1.51734906e-05, 1.26651957e-05, 1.27765599e-05, 2.02853388e-05, + 3.53618159e-05, 5.68754415e-05, 5.20404964e-05, 3.06340730e-05, 1.49581890e-05, 1.19791727e-05, + 1.52451945e-05, 3.17683112e-05, 4.07105345e-05, 3.29560181e-05, 2.23064752e-05, 2.00886383e-05, + 1.80476843e-05, 1.40737029e-05, 1.30683472e-05, 2.00163793e-05, 3.21212451e-05, 4.28995432e-05, + 3.29138409e-05, 2.30738440e-05, 1.63543919e-05, 1.32197260e-05, 1.31526872e-05, 2.42640080e-05, + 3.45227911e-05, 3.63492697e-05, 2.84533267e-05, 2.13029096e-05, 1.68934537e-05, 1.30331220e-05, + 1.39683730e-05, 1.57397989e-05, 2.37716070e-05, 4.07825229e-05, 5.13819359e-05, 3.49820772e-05, + 1.92739400e-05, 1.36250339e-05, 1.10765832e-05, 1.08470927e-05, 1.22661581e-05, 2.79012418e-05, + 3.57000893e-05, 3.68607460e-05, 2.61932537e-05, 1.66600757e-05, 1.74226925e-05, 1.51303627e-05, + 1.18460071e-05, 2.74858036e-05, 3.45126695e-05, 3.48090878e-05, 3.21213298e-05, 2.63869065e-05, + 1.70456421e-05, 1.37076882e-05, 1.47665170e-05, 3.23854102e-05, 4.70047111e-05, 4.04000527e-05, + 2.28319679e-05, 1.31945495e-05, 1.30004743e-05, 1.40292577e-05, 2.32393374e-05, 3.28046945e-05, + 4.02105225e-05, 3.65393924e-05, 2.53952476e-05, 1.88130490e-05, 1.52270124e-05, 1.22467828e-05, + 2.53267956e-05, 3.33285493e-05, 3.52734913e-05, 3.10679348e-05, 2.48828214e-05, 1.95681751e-05, + 1.70243712e-05, 1.68819679e-05, 1.70979032e-05, 2.43787770e-05, 2.91979550e-05, 2.77358703e-05, + 2.48354647e-05, 2.43719872e-05, 2.35194961e-05, 1.98511279e-05, 1.71306729e-05, 1.75039300e-05, + 1.79828066e-05, 1.68517600e-05, 2.71606424e-05, 3.22988192e-05, 3.17180065e-05, 2.61717420e-05, + 2.32877637e-05, 2.26361762e-05, 1.88925034e-05, 1.57680935e-05, 1.48824636e-05, 3.17562926e-05, + 4.16029742e-05, 3.75868236e-05, 2.42571643e-05, 1.72790658e-05, 1.65953258e-05, 1.65685446e-05, + 1.59874251e-05, 1.58720192e-05, 2.34245553e-05, 3.24613944e-05, 3.55896217e-05, 2.74233899e-05, + 2.12610921e-05, 2.13301000e-05, 2.18096180e-05, 1.90857892e-05, 1.62918823e-05, 1.76436076e-05, + 2.34528666e-05, 3.53689396e-05, 4.16714124e-05, 3.55385430e-05, 2.47412907e-05, 1.66994570e-05, + 1.44929766e-05, 1.52485716e-05, 3.08887286e-05, 3.86496132e-05, 3.65263692e-05, 2.79387957e-05, + 1.95917597e-05, 1.49844211e-05, 1.40181164e-05, 1.54079969e-05, 3.38536622e-05, 4.05644420e-05, + 3.66962380e-05, 2.69371502e-05, 1.71732374e-05, 1.39164146e-05, 1.49552457e-05, 1.61949241e-05, + 3.53167005e-05, 4.36778230e-05, 3.42649063e-05, 2.40258351e-05, 2.03045935e-05, 1.86755799e-05, + 1.71297279e-05, 2.81285025e-05, 3.28775607e-05, 3.38514603e-05, 3.14066330e-05, 2.34196341e-05, + 1.70644053e-05, 1.59081169e-05, 1.64572361e-05, 2.68279500e-05, 3.14095009e-05, 3.11316927e-05, + 2.76590292e-05, 2.48474897e-05, 2.24649323e-05, 1.83186805e-05, 1.66238078e-05, 2.56351576e-05, + 3.16235581e-05, 3.14219864e-05, 2.91259881e-05, 2.72714295e-05, 2.28657550e-05, 1.84209044e-05, + 1.62948020e-05, 1.63953461e-05, 2.25668015e-05, 3.21702771e-05, 4.24382644e-05, 4.02669500e-05, + 2.91480171e-05, 1.82144226e-05, 1.56739685e-05, 1.84372352e-05, 2.99741687e-05, 3.49731196e-05, + 3.07167940e-05, 2.39270145e-05, 2.22963429e-05, 2.07144306e-05, 1.75165498e-05, 1.66564971e-05, + 2.23611840e-05, 3.02481605e-05, 3.60099343e-05, 3.06128910e-05, 2.43946282e-05, 1.93879056e-05, + 1.67716688e-05, 1.67280649e-05, 2.52268437e-05, 3.15765935e-05, 3.25977856e-05, 2.79911431e-05, + 2.32080818e-05, 1.98541025e-05, 1.66329042e-05, 1.74131877e-05, 1.88531641e-05, 2.49443948e-05, + 3.49733177e-05, 4.00025628e-05, 3.17759733e-05, 2.17055809e-05, 1.71837183e-05, 1.48746455e-05, + 1.46501148e-05, 1.59425541e-05, 2.76881014e-05, 3.23510384e-05, 3.29293755e-05, 2.65210279e-05, + 1.96448235e-05, 2.01316111e-05, 1.83097671e-05, 1.55413337e-05, 2.73070226e-05, 3.16114210e-05, + 3.17973748e-05, 3.01969820e-05, 2.66061797e-05, 1.99779800e-05, 1.72282595e-05, 1.80793768e-05, + 3.04227877e-05, 3.81253282e-05, 3.47517532e-05, 2.41923281e-05, 1.67666047e-05, 1.65940628e-05, + 1.74635839e-05, 2.45869453e-05, 3.06491430e-05, 3.46851599e-05, 3.26690406e-05, 2.59107597e-05, + 2.12562600e-05, 1.84589514e-05, 1.59332324e-05, 2.54296260e-05, 2.86160966e-05, 2.92161952e-05, + 2.82393063e-05, 2.58216582e-05, 2.26179335e-05, 2.08204592e-05, 2.06012340e-05, 2.05743128e-05, + 2.48678399e-05, 2.69998310e-05, 2.63535976e-05, 2.52347044e-05, 2.50421834e-05, 2.45816092e-05, + 2.27516612e-05, 2.10215788e-05, 2.10513803e-05, 2.12120217e-05, 2.04384173e-05, 2.64405190e-05, + 2.84270454e-05, 2.79702303e-05, 2.60136537e-05, 2.47252978e-05, 2.40510829e-05, 2.17699873e-05, + 1.97701483e-05, 1.91396210e-05, 2.81894069e-05, 3.08292859e-05, 2.98923933e-05, 2.55148378e-05, + 2.15993589e-05, 2.06098814e-05, 2.02259092e-05, 1.98332166e-05, 1.97745627e-05, 2.52520365e-05, + 2.91446189e-05, 2.96091071e-05, 2.67896813e-05, 2.36598351e-05, 2.32000054e-05, 2.31215597e-05, + 2.16314089e-05, 1.99392575e-05, 2.15961910e-05, 2.51614976e-05, 2.94208723e-05, 3.04936197e-05, + 2.92807766e-05, 2.52857282e-05, 2.05505374e-05, 1.87728007e-05, 1.92631583e-05, 2.76116780e-05, + 3.03534184e-05, 2.99888998e-05, 2.71631734e-05, 2.28070176e-05, 1.95252540e-05, 1.86178010e-05, + 1.94752553e-05, 2.83912730e-05, 3.07851631e-05, 3.01910685e-05, 2.66734093e-05, 2.12019322e-05, + 1.85844968e-05, 1.91002102e-05, 1.99711179e-05, 2.94575777e-05, 3.14494366e-05, 2.96626808e-05, + 2.56693982e-05, 2.30083102e-05, 2.13405405e-05, 2.03426570e-05, 2.70129316e-05, 2.92275477e-05, + 2.93515116e-05, 2.79542555e-05, 2.42247415e-05, 2.06131225e-05, 1.97967719e-05, 2.01534525e-05, + 2.64402287e-05, 2.85659611e-05, 2.83963222e-05, 2.68759342e-05, 2.51585112e-05, 2.35434929e-05, + 2.12572599e-05, 2.02669631e-05, 2.58698617e-05, 2.83725049e-05, 2.82549047e-05, 2.75873374e-05, + 2.65625898e-05, 2.40303465e-05, 2.13566222e-05, 2.00243000e-05, 2.01107847e-05, 2.52686805e-05, + 2.97313923e-05, 3.12867667e-05, 3.01297155e-05, 2.63903795e-05, 2.10260194e-05, 1.95268850e-05, + 2.10749399e-05, 2.77602267e-05, 2.99636439e-05, 2.84213848e-05, 2.52767710e-05, 2.40938599e-05, + 2.28286702e-05, 2.08725008e-05, 2.03291701e-05, 2.50798439e-05, 2.84039247e-05, 2.95969778e-05, + 2.77575521e-05, 2.50197511e-05, 2.20275579e-05, 2.02884108e-05, 2.03639238e-05, 2.55822227e-05, + 2.84247136e-05, 2.87894110e-05, 2.72006404e-05, 2.48327049e-05, 2.25870641e-05, 2.03651236e-05, + 2.07052945e-05, 2.14197010e-05, 2.58357507e-05, 2.96367913e-05, 3.03119795e-05, 2.80417001e-05, + 2.38557282e-05, 2.10210155e-05, 1.91441485e-05, 1.89003772e-05, 1.97951157e-05, 2.74305312e-05, + 2.97159435e-05, 2.93316239e-05, 2.63193872e-05, 2.22811210e-05, 2.18182719e-05, 2.07760014e-05, + 1.93449683e-05, 2.63397430e-05, 2.87705410e-05, 2.89978675e-05, 2.79607552e-05, 2.60575328e-05, + 2.26916875e-05, 2.08533191e-05, 2.11046891e-05, 2.86447021e-05, 3.12264873e-05, 2.93764557e-05, + 2.46696019e-05, 2.04054600e-05, 2.02637651e-05, 2.07292324e-05, 2.57112451e-05, 2.85690556e-05, + 2.96226438e-05, 2.85528401e-05, 2.54068408e-05, 2.28648880e-05, 2.13390687e-05, 1.98467196e-05, + 2.50645333e-05, 2.39746575e-05, 2.35888597e-05, 2.45501112e-05, 2.54261917e-05, 2.53837298e-05, + 2.50825409e-05, 2.49758838e-05, 2.48734890e-05, 2.50722669e-05, 2.45865006e-05, 2.47462446e-05, + 2.51237919e-05, 2.51741496e-05, 2.52031340e-05, 2.53689239e-05, 2.51875056e-05, 2.50688884e-05, + 2.50043903e-05, 2.48662218e-05, 2.49840184e-05, 2.42297363e-05, 2.42163260e-05, 2.50939453e-05, + 2.53661165e-05, 2.51954145e-05, 2.50593783e-05, 2.47759081e-05, 2.46271747e-05, 2.43027143e-05, + 2.20878352e-05, 2.30937699e-05, 2.54737491e-05, 2.55347742e-05, 2.50911104e-05, 2.48148989e-05, + 2.47391879e-05, 2.47387309e-05, 2.56129526e-05, 2.44750454e-05, 2.36396518e-05, 2.50722057e-05, + 2.54397850e-05, 2.51277486e-05, 2.49051427e-05, 2.48903359e-05, 2.47025105e-05, 2.53996241e-05, + 2.55540480e-05, 2.36388965e-05, 2.19581226e-05, 2.35282053e-05, 2.51843967e-05, 2.50079036e-05, + 2.44851270e-05, 2.45807047e-05, 2.43227791e-05, 2.29092133e-05, 2.34754169e-05, 2.50832394e-05, + 2.54972499e-05, 2.48915408e-05, 2.45490146e-05, 2.46863596e-05, 2.37046582e-05, 2.24194894e-05, + 2.34919941e-05, 2.51759968e-05, 2.52994576e-05, 2.45625665e-05, 2.45664406e-05, 2.47648899e-05, + 2.36702418e-05, 2.15651372e-05, 2.40904691e-05, 2.56334164e-05, 2.53715730e-05, 2.48363695e-05, + 2.46867451e-05, 2.49480269e-05, 2.43729773e-05, 2.41056404e-05, 2.43113867e-05, 2.50260643e-05, + 2.49151373e-05, 2.47418808e-05, 2.48028065e-05, 2.50950679e-05, 2.45795200e-05, 2.45975958e-05, + 2.50365525e-05, 2.50768747e-05, 2.49416445e-05, 2.49106589e-05, 2.48247040e-05, 2.51986030e-05, + 2.44267608e-05, 2.44412015e-05, 2.48920809e-05, 2.50091573e-05, 2.51023339e-05, 2.49435583e-05, + 2.47669611e-05, 2.47942089e-05, 2.59095894e-05, 2.47904288e-05, 2.19419735e-05, 2.22991695e-05, + 2.42908456e-05, 2.47819948e-05, 2.46222402e-05, 2.47333314e-05, 2.46932188e-05, 2.39713388e-05, + 2.47434293e-05, 2.54564342e-05, 2.53399114e-05, 2.51084255e-05, 2.49342733e-05, 2.48591165e-05, + 2.58776298e-05, 2.48882218e-05, 2.34979852e-05, 2.44819697e-05, 2.51536714e-05, 2.50544904e-05, + 2.47838984e-05, 2.48577689e-05, 2.51821653e-05, 2.44647175e-05, 2.42864744e-05, 2.50838474e-05, + 2.54545034e-05, 2.52604923e-05, 2.48952304e-05, 2.48503811e-05, 2.48265402e-05, 2.54129316e-05, + 2.38507569e-05, 2.24497491e-05, 2.42298338e-05, 2.54030650e-05, 2.51672472e-05, 2.46339176e-05, + 2.45263776e-05, 2.47271316e-05, 2.52908339e-05, 2.47270195e-05, 2.43968198e-05, 2.51358613e-05, + 2.51327960e-05, 2.46327063e-05, 2.45599633e-05, 2.45298705e-05, 2.48830168e-05, 2.45993446e-05, + 2.46314938e-05, 2.47112466e-05, 2.49707913e-05, 2.52843583e-05, 2.50294275e-05, 2.48905496e-05, + 2.49323669e-05, 2.33573806e-05, 2.38226134e-05, 2.50215522e-05, 2.48741819e-05, 2.48337545e-05, + 2.48488956e-05, 2.54673461e-05, 2.48277464e-05, 2.39390501e-05, 2.41631031e-05, 2.48525388e-05, + 2.49364928e-05, 2.49167164e-05, 2.47707969e-05, 2.44432231e-05, 2.10575919e-05, 2.02301081e-05, + 2.21602416e-05, 2.49189243e-05, 2.69825222e-05, 2.78531322e-05, 2.78100039e-05, 2.75947059e-05, + 2.47854748e-05, 2.27626631e-05, 2.33586688e-05, 2.46691317e-05, 2.48804859e-05, 2.52192676e-05, + 2.68447245e-05, 2.79114791e-05, 2.76058486e-05, 2.73118999e-05, 2.77074671e-05, 2.37494868e-05, + 2.15477409e-05, 2.17070079e-05, 2.41771324e-05, 2.54556913e-05, 2.55453102e-05, 2.69540742e-05, + 2.81599164e-05, 2.84704623e-05, 2.17631811e-05, 1.75509616e-05, 1.92569053e-05, 2.51895422e-05, + 2.81980448e-05, 2.80759559e-05, 2.77927670e-05, 2.80055479e-05, 2.80648333e-05, 2.56255851e-05, + 2.16802630e-05, 2.01783347e-05, 2.37361384e-05, 2.63208630e-05, 2.59922838e-05, 2.55852108e-05, + 2.66945045e-05, 2.78097063e-05, 2.78820931e-05, 2.55624922e-05, 2.02394383e-05, 1.74546396e-05, + 2.01138266e-05, 2.47569817e-05, 2.79349095e-05, 2.85269323e-05, 2.82191364e-05, 2.20354011e-05, + 1.88488204e-05, 1.98040822e-05, 2.35739988e-05, 2.70840756e-05, 2.87086722e-05, 2.88715994e-05, + 2.82514570e-05, 2.07055184e-05, 1.80268872e-05, 1.97670380e-05, 2.39860749e-05, 2.80075545e-05, + 2.89465247e-05, 2.83622577e-05, 2.79271676e-05, 2.02761250e-05, 1.66954029e-05, 2.08703005e-05, + 2.54151680e-05, 2.66531899e-05, 2.68201394e-05, 2.73785632e-05, 2.34011253e-05, 2.14814024e-05, + 2.10025807e-05, 2.18731604e-05, 2.50915554e-05, 2.76555451e-05, 2.80495477e-05, 2.78355069e-05, + 2.39550366e-05, 2.20781095e-05, 2.21769226e-05, 2.36283166e-05, 2.46226748e-05, 2.53686786e-05, + 2.70589389e-05, 2.77757693e-05, 2.44535522e-05, 2.18979205e-05, 2.19694953e-05, 2.30337904e-05, + 2.37339434e-05, 2.53701656e-05, 2.70467125e-05, 2.78786009e-05, 2.78573671e-05, 2.62224858e-05, + 2.19880771e-05, 1.72405924e-05, 1.80292132e-05, 2.25281280e-05, 2.69713765e-05, 2.80396078e-05, + 2.68190182e-05, 2.26084009e-05, 2.05807696e-05, 2.24155661e-05, 2.52969165e-05, 2.58126476e-05, + 2.62234458e-05, 2.74578401e-05, 2.77966244e-05, 2.62770977e-05, 2.26723883e-05, 1.99630271e-05, + 2.22451337e-05, 2.48537867e-05, 2.67306824e-05, 2.76582743e-05, 2.77595710e-05, 2.45825482e-05, + 2.19408900e-05, 2.15023511e-05, 2.35571626e-05, 2.55663658e-05, 2.67360778e-05, 2.78473141e-05, + 2.74180479e-05, 2.67308994e-05, 2.48851466e-05, 2.04992425e-05, 1.81948149e-05, 2.17006820e-05, + 2.61060389e-05, 2.78642128e-05, 2.84823392e-05, 2.84856723e-05, 2.80155055e-05, 2.38247221e-05, + 2.18880690e-05, 2.14825160e-05, 2.40937919e-05, 2.66985038e-05, 2.59837145e-05, 2.66927211e-05, + 2.80065364e-05, 2.36151010e-05, 2.20307384e-05, 2.19965733e-05, 2.25531861e-05, 2.39232611e-05, + 2.67065795e-05, 2.76972479e-05, 2.71477130e-05, 2.26491590e-05, 1.92664831e-05, 2.05428471e-05, + 2.48059288e-05, 2.77581216e-05, 2.78004047e-05, 2.73924250e-05, 2.50625001e-05, 2.24998127e-05, + 2.06432927e-05, 2.13892465e-05, 2.40533916e-05, 2.58340449e-05, 2.70014613e-05, 2.80682475e-05, + 2.34482381e-05, 1.79520763e-05, 1.67882816e-05, 1.95081624e-05, 2.40872258e-05, 2.85530355e-05, + 3.09410923e-05, 3.09724463e-05, 3.05852127e-05, 2.41352511e-05, 2.05855107e-05, 2.15879041e-05, + 2.38513087e-05, 2.42361410e-05, 2.49084495e-05, 2.82584989e-05, 3.09491259e-05, 3.03679935e-05, + 2.97533826e-05, 3.08651945e-05, 2.21479394e-05, 1.86383057e-05, 1.89295887e-05, 2.28927399e-05, + 2.52467653e-05, 2.56009412e-05, 2.88576628e-05, 3.20878824e-05, 3.30692242e-05, 1.89698213e-05, + 1.33669071e-05, 1.54840415e-05, 2.45956251e-05, 3.12031078e-05, 3.14678878e-05, 3.11372501e-05, + 3.17561983e-05, 3.19028364e-05, 2.53682801e-05, 1.87080445e-05, 1.66717434e-05, 2.20505423e-05, + 2.70219157e-05, 2.66302505e-05, 2.59787786e-05, 2.84585700e-05, 3.13248768e-05, 3.06173203e-05, + 2.52920263e-05, 1.67736511e-05, 1.32854459e-05, 1.66311769e-05, 2.39750003e-05, 3.12330093e-05, + 3.34144793e-05, 3.25011991e-05, 1.94441164e-05, 1.49375217e-05, 1.61527146e-05, 2.17310935e-05, + 2.86563008e-05, 3.33017697e-05, 3.42084937e-05, 3.24367738e-05, 1.75208688e-05, 1.39208714e-05, + 1.60832708e-05, 2.24499278e-05, 3.10393159e-05, 3.43829173e-05, 3.28809542e-05, 3.15298938e-05, + 1.68159329e-05, 1.23575160e-05, 1.75586688e-05, 2.49137278e-05, 2.78268438e-05, 2.88099918e-05, + 3.03038835e-05, 2.15081849e-05, 1.84280174e-05, 1.77739176e-05, 1.91600990e-05, 2.48112720e-05, + 3.06783854e-05, 3.18609374e-05, 3.12567046e-05, 2.24560483e-05, 1.93406770e-05, 1.95050320e-05, + 2.18718927e-05, 2.37993827e-05, 2.54779442e-05, 2.92751329e-05, 3.10833980e-05, 2.33515546e-05, + 1.91242769e-05, 1.92420097e-05, 2.08596608e-05, 2.20973359e-05, 2.53219713e-05, 2.92075518e-05, + 3.14084826e-05, 3.13210897e-05, 2.63417198e-05, 1.90421640e-05, 1.29774629e-05, 1.39845551e-05, + 2.03750326e-05, 2.92253490e-05, 3.19971496e-05, 2.89293965e-05, 2.02201291e-05, 1.71442302e-05, + 1.98329811e-05, 2.48322607e-05, 2.60265269e-05, 2.71575732e-05, 3.01832440e-05, 3.10895383e-05, + 2.64884830e-05, 2.01966667e-05, 1.63997147e-05, 1.97099558e-05, 2.42002793e-05, 2.83529700e-05, + 3.08519025e-05, 3.10016837e-05, 2.36243669e-05, 1.91747477e-05, 1.85208464e-05, 2.16985448e-05, + 2.53941866e-05, 2.81340438e-05, 3.11657492e-05, 3.01928485e-05, 2.86160733e-05, 2.40306491e-05, + 1.70799377e-05, 1.41615924e-05, 1.89089568e-05, 2.65931496e-05, 3.08613336e-05, 3.30898055e-05, + 3.32503304e-05, 3.17967599e-05, 2.20469678e-05, 1.89081947e-05, 1.84146589e-05, 2.26933974e-05, + 2.81916824e-05, 2.71445730e-05, 2.88436236e-05, 3.20404672e-05, 2.19705234e-05, 1.92428547e-05, + 1.91607395e-05, 2.01059021e-05, 2.24974920e-05, 2.80414255e-05, 3.06345631e-05, 2.95063501e-05, + 2.01234009e-05, 1.53588900e-05, 1.71700849e-05, 2.42240919e-05, 3.09771466e-05, 3.11313942e-05, + 3.01338581e-05, 2.43419507e-05, 1.99262265e-05, 1.72681389e-05, 1.84048019e-05, 2.28553743e-05, + 2.64858069e-05, 2.91344281e-05, 3.18684321e-05, 2.37343549e-05, 1.87868717e-05, 1.77014271e-05, + 2.03475592e-05, 2.45512862e-05, 2.82306650e-05, 3.00796532e-05, 3.00216012e-05, 2.95964897e-05, + 2.42875245e-05, 2.11521227e-05, 2.20322751e-05, 2.41032245e-05, 2.44527852e-05, 2.50200343e-05, + 2.79642161e-05, 3.01728063e-05, 2.95596611e-05, 2.89665630e-05, 2.98391833e-05, 2.26568196e-05, + 1.94679805e-05, 1.96574599e-05, 2.33239298e-05, 2.54331946e-05, 2.55807586e-05, 2.82289960e-05, + 3.08624379e-05, 3.16344980e-05, 1.97583960e-05, 1.44544045e-05, 1.64805026e-05, 2.49995290e-05, + 3.06956729e-05, 3.05578176e-05, 3.00410332e-05, 3.05353534e-05, 3.06666906e-05, 2.57493779e-05, + 1.97344444e-05, 1.76725128e-05, 2.26589920e-05, 2.69702624e-05, 2.63822111e-05, 2.56619040e-05, + 2.77511316e-05, 3.01209163e-05, 3.00550526e-05, 2.56343330e-05, 1.77352638e-05, 1.43016061e-05, + 1.75506332e-05, 2.42525663e-05, 3.02798508e-05, 3.18385610e-05, 3.10831684e-05, 2.01080712e-05, + 1.60065357e-05, 1.72114002e-05, 2.24285007e-05, 2.84164958e-05, 3.20580188e-05, 3.26166102e-05, + 3.11070676e-05, 1.82748496e-05, 1.50273645e-05, 1.71854587e-05, 2.30539694e-05, 3.03467108e-05, + 3.27882931e-05, 3.14160424e-05, 3.03526169e-05, 1.77890673e-05, 1.35198998e-05, 1.86338107e-05, + 2.53996480e-05, 2.75962113e-05, 2.80130234e-05, 2.92034508e-05, 2.21428307e-05, 1.94549016e-05, + 1.87847388e-05, 1.98982150e-05, 2.47963775e-05, 2.97118877e-05, 3.06315012e-05, 3.01381021e-05, + 2.29878146e-05, 2.02578060e-05, 2.03876624e-05, 2.24928739e-05, 2.40229438e-05, 2.52756522e-05, + 2.84746063e-05, 3.00007322e-05, 2.37716548e-05, 1.99725718e-05, 2.00666809e-05, 2.16150245e-05, + 2.26397882e-05, 2.52753335e-05, 2.84414857e-05, 3.02456389e-05, 3.01888539e-05, 2.68245345e-05, + 2.02602375e-05, 1.41382039e-05, 1.49574963e-05, 2.07593806e-05, 2.83317667e-05, 3.06609792e-05, + 2.80376783e-05, 2.09772812e-05, 1.82652650e-05, 2.07481176e-05, 2.51748140e-05, 2.60529140e-05, + 2.68112018e-05, 2.92891092e-05, 3.00332421e-05, 2.69158431e-05, 2.11366144e-05, 1.73807308e-05, + 2.04306951e-05, 2.44069343e-05, 2.77889517e-05, 2.97630032e-05, 2.99539336e-05, 2.39723687e-05, + 2.00408158e-05, 1.94380998e-05, 2.24047429e-05, 2.56299844e-05, 2.77671741e-05, 3.01297316e-05, + 2.92317791e-05, 2.78378010e-05, 2.44945995e-05, 1.81144033e-05, 1.51807491e-05, 1.96544223e-05, + 2.65786218e-05, 3.00778198e-05, 3.16585222e-05, 3.17208577e-05, 3.05623466e-05, 2.28539708e-05, + 2.01094671e-05, 1.94683621e-05, 2.32056338e-05, 2.77128150e-05, 2.64335991e-05, 2.78334580e-05, + 3.06290623e-05, 2.24362837e-05, 2.02089663e-05, 2.01832712e-05, 2.09115141e-05, 2.29138640e-05, + 2.77073528e-05, 2.97641003e-05, 2.86606724e-05, 2.11270384e-05, 1.66556106e-05, 1.81459499e-05, + 2.43175791e-05, 2.99450195e-05, 3.00506006e-05, 2.91786587e-05, 2.47907435e-05, 2.08911084e-05, + 1.83121115e-05, 1.92520665e-05, 2.30948921e-05, 2.61095811e-05, 2.83568452e-05, 3.06608999e-05, + 2.57182364e-05, 2.90512694e-05, 2.97021465e-05, 2.77333241e-05, 2.48103538e-05, 2.22682805e-05, + 2.08326673e-05, 2.08696145e-05, 2.12033603e-05, 2.53656620e-05, 2.76093863e-05, 2.70278281e-05, + 2.54299554e-05, 2.51587896e-05, 2.47572453e-05, 2.24787115e-05, 2.07641794e-05, 2.12486050e-05, + 2.17283943e-05, 2.10038211e-05, 2.63769388e-05, 2.84932767e-05, 2.85863911e-05, 2.59028516e-05, + 2.43385080e-05, 2.43668765e-05, 2.23291262e-05, 2.01588467e-05, 1.95045166e-05, 2.83516780e-05, + 3.12514049e-05, 3.03374550e-05, 2.45001466e-05, 2.03521449e-05, 2.04542424e-05, 2.08309757e-05, + 2.04137066e-05, 2.03074276e-05, 2.38985417e-05, 2.77501350e-05, 2.94244478e-05, 2.62218517e-05, + 2.32012417e-05, 2.37971623e-05, 2.44591125e-05, 2.27369352e-05, 2.07434194e-05, 2.08514436e-05, + 2.40305308e-05, 2.95112743e-05, 3.17339282e-05, 2.98014049e-05, 2.52723680e-05, 2.06659968e-05, + 1.92958123e-05, 1.99288020e-05, 2.83391368e-05, 3.03650730e-05, 2.95575841e-05, 2.62708372e-05, + 2.20915816e-05, 1.92496406e-05, 1.87161238e-05, 1.99404057e-05, 2.97192653e-05, 3.08144633e-05, + 2.94092086e-05, 2.58917553e-05, 2.06296755e-05, 1.85905013e-05, 1.96580721e-05, 2.05676104e-05, + 2.94299683e-05, 3.12688932e-05, 2.84468925e-05, 2.40806915e-05, 2.27611450e-05, 2.25188598e-05, + 2.15027538e-05, 2.66216163e-05, 2.79659307e-05, 2.85336967e-05, 2.83532568e-05, 2.50533605e-05, + 2.11138626e-05, 2.03365747e-05, 2.07496589e-05, 2.60557016e-05, 2.76196029e-05, 2.75975200e-05, + 2.63439701e-05, 2.55301114e-05, 2.47468989e-05, 2.21329607e-05, 2.08655386e-05, 2.55280335e-05, + 2.80241503e-05, 2.80032310e-05, 2.68505570e-05, 2.63411323e-05, 2.46518177e-05, 2.21603818e-05, + 2.06550783e-05, 2.07067069e-05, 2.29346710e-05, 2.68221752e-05, 3.10003050e-05, 3.15310052e-05, + 2.82928203e-05, 2.22486308e-05, 2.02821970e-05, 2.24957052e-05, 2.73862681e-05, 2.85667028e-05, + 2.72267607e-05, 2.44153235e-05, 2.39292322e-05, 2.34660683e-05, 2.14613144e-05, 2.08446297e-05, + 2.29111858e-05, 2.68567023e-05, 2.97181545e-05, 2.79324967e-05, 2.52086357e-05, 2.26888756e-05, + 2.10535710e-05, 2.09089871e-05, 2.54395228e-05, 2.79235880e-05, 2.82849283e-05, 2.62757046e-05, + 2.41295786e-05, 2.26638247e-05, 2.07718679e-05, 2.15012418e-05, 2.26666376e-05, 2.48582296e-05, + 2.89723317e-05, 3.11537323e-05, 2.85463759e-05, 2.35090143e-05, 2.08384853e-05, 1.94877173e-05, + 1.94031459e-05, 2.03890411e-05, 2.57287425e-05, 2.69784731e-05, 2.78786208e-05, 2.58956421e-05, + 2.27371014e-05, 2.38789712e-05, 2.26583144e-05, 2.02814395e-05, 2.66351664e-05, 2.75361095e-05, + 2.74108674e-05, 2.73384299e-05, 2.62827574e-05, 2.27040304e-05, 2.10818786e-05, 2.19778772e-05, + 2.67183513e-05, 2.89420045e-05, 2.91422761e-05, 2.53923112e-05, 2.09186822e-05, 2.08263928e-05, + 2.15450758e-05, 2.46265712e-05, 2.69954932e-05, 2.87908306e-05, 2.86275385e-05, 2.63436780e-05, + 2.40866358e-05, 2.22308322e-05, 2.03195043e-05, 2.57083097e-05, 2.69165060e-05, 2.70546124e-05, + 2.57704806e-05, 2.42310976e-05, 2.34027209e-05, 2.28111670e-05, 2.30469912e-05, 2.35634247e-05, + 2.57290986e-05, 2.67051769e-05, 2.65635469e-05, 2.55019567e-05, 2.53122515e-05, 2.51715900e-05, + 2.35876508e-05, 2.25474856e-05, 2.32283702e-05, 2.37928862e-05, 2.33830024e-05, 2.56837800e-05, + 2.64668638e-05, 2.69849911e-05, 2.54513162e-05, 2.45026242e-05, 2.50965896e-05, 2.41887256e-05, + 2.26829834e-05, 2.22193752e-05, 2.65193604e-05, 2.68519100e-05, 2.70367179e-05, 2.40799154e-05, + 2.15033727e-05, 2.24279407e-05, 2.33063210e-05, 2.30143232e-05, 2.29037169e-05, 2.35144906e-05, + 2.50166946e-05, 2.63903310e-05, 2.52020919e-05, 2.38470584e-05, 2.50405467e-05, 2.60235043e-05, + 2.48954544e-05, 2.34210392e-05, 2.22161473e-05, 2.37548071e-05, 2.66588087e-05, 2.76534627e-05, + 2.70966629e-05, 2.52560144e-05, 2.27885212e-05, 2.22092065e-05, 2.27647750e-05, 2.70240043e-05, + 2.65907629e-05, 2.61653334e-05, 2.49547861e-05, 2.30070160e-05, 2.15132711e-05, 2.14416868e-05, + 2.26012720e-05, 2.78669271e-05, 2.65343089e-05, 2.58240835e-05, 2.48936351e-05, 2.22085427e-05, + 2.12748101e-05, 2.24887104e-05, 2.31286603e-05, 2.65390639e-05, 2.60844550e-05, 2.53188816e-05, + 2.34260698e-05, 2.37709695e-05, 2.48339381e-05, 2.42106102e-05, 2.55020232e-05, 2.51816672e-05, + 2.56867892e-05, 2.67317120e-05, 2.58680345e-05, 2.33979209e-05, 2.29288667e-05, 2.32464276e-05, + 2.52869531e-05, 2.53622209e-05, 2.54814055e-05, 2.52795173e-05, 2.56958292e-05, 2.60474545e-05, + 2.43437619e-05, 2.33229569e-05, 2.50986133e-05, 2.59858654e-05, 2.60648203e-05, 2.52961275e-05, + 2.55370491e-05, 2.54967922e-05, 2.42980048e-05, 2.32147996e-05, 2.32184470e-05, 2.22656361e-05, + 2.35270157e-05, 2.61000111e-05, 2.79081216e-05, 2.80910921e-05, 2.47151790e-05, 2.30778135e-05, + 2.50353345e-05, 2.57798813e-05, 2.51773339e-05, 2.50386831e-05, 2.41597541e-05, 2.44748412e-05, + 2.48975603e-05, 2.36901553e-05, 2.32388532e-05, 2.23738362e-05, 2.46310627e-05, 2.67050063e-05, + 2.64195938e-05, 2.53958361e-05, 2.44843408e-05, 2.35855830e-05, 2.33052225e-05, 2.52239628e-05, + 2.58266390e-05, 2.59125979e-05, 2.49300460e-05, 2.41429248e-05, 2.39799792e-05, 2.31001387e-05, + 2.38921857e-05, 2.49795130e-05, 2.42803935e-05, 2.58941163e-05, 2.73627756e-05, 2.68743030e-05, + 2.41046001e-05, 2.26559789e-05, 2.21897986e-05, 2.22663833e-05, 2.30095824e-05, 2.40913445e-05, + 2.37076553e-05, 2.49978236e-05, 2.51885109e-05, 2.43379536e-05, 2.63791265e-05, 2.55466375e-05, + 2.32348559e-05, 2.60891222e-05, 2.50955877e-05, 2.47660439e-05, 2.55536547e-05, 2.58909813e-05, + 2.39500178e-05, 2.31492016e-05, 2.42490018e-05, 2.42789702e-05, 2.43939624e-05, 2.63122870e-05, + 2.59339430e-05, 2.32843953e-05, 2.32672151e-05, 2.39363730e-05, 2.40857705e-05, 2.46541743e-05, + 2.57167784e-05, 2.65040303e-05, 2.65303962e-05, 2.57318293e-05, 2.44156180e-05, 2.28606699e-05, + 2.47730740e-05, 2.17303612e-05, 2.09775349e-05, 2.18025589e-05, 2.35690492e-05, 2.61020643e-05, + 2.73842485e-05, 2.77878560e-05, 2.82257417e-05, 2.53654293e-05, 2.35639326e-05, 2.42178747e-05, + 2.48616936e-05, 2.49521046e-05, 2.53367857e-05, 2.61055542e-05, 2.69792488e-05, 2.74884927e-05, + 2.77643430e-05, 2.82188724e-05, 2.37084101e-05, 2.18263733e-05, 2.25450805e-05, 2.40352788e-05, + 2.47949670e-05, 2.58263100e-05, 2.75008667e-05, 2.83119221e-05, 2.85416835e-05, 2.21263612e-05, + 1.83011947e-05, 1.99920153e-05, 2.37786862e-05, 2.56023197e-05, 2.72778883e-05, 2.83706097e-05, + 2.85260620e-05, 2.84927731e-05, 2.36913479e-05, 2.05137416e-05, 2.03089681e-05, 2.31121060e-05, + 2.54113741e-05, 2.66500645e-05, 2.73593351e-05, 2.81522458e-05, 2.87539230e-05, 2.61734139e-05, + 2.39226901e-05, 2.06181228e-05, 1.88502708e-05, 2.08966841e-05, 2.46735732e-05, 2.76291847e-05, + 2.89008687e-05, 2.88909103e-05, 2.29851801e-05, 1.92273100e-05, 1.97429146e-05, 2.26100450e-05, + 2.56381816e-05, 2.75428849e-05, 2.83613891e-05, 2.85370388e-05, 2.22749512e-05, 1.84552560e-05, + 1.94050775e-05, 2.30790848e-05, 2.65365563e-05, 2.82405660e-05, 2.88168471e-05, 2.84819037e-05, + 2.05439653e-05, 1.70191917e-05, 1.99927246e-05, 2.32480841e-05, 2.59866561e-05, 2.84084163e-05, + 2.89707602e-05, 2.30212621e-05, 2.04720324e-05, 2.04738810e-05, 2.24771978e-05, 2.61114645e-05, + 2.80558916e-05, 2.84914948e-05, 2.83948763e-05, 2.35133015e-05, 2.12861775e-05, 2.15193732e-05, + 2.30601274e-05, 2.50466697e-05, 2.69304049e-05, 2.81330425e-05, 2.83427779e-05, 2.39969128e-05, + 2.17284772e-05, 2.18917424e-05, 2.23225907e-05, 2.35095909e-05, 2.60912398e-05, 2.79980274e-05, + 2.84990792e-05, 2.84149879e-05, 2.28924054e-05, 1.93545971e-05, 1.74622605e-05, 1.95756325e-05, + 2.48372289e-05, 2.86470430e-05, 2.88890673e-05, 2.88323638e-05, 2.23388621e-05, 1.95825506e-05, + 2.13234241e-05, 2.40546075e-05, 2.53968223e-05, 2.69314211e-05, 2.80253666e-05, 2.82124986e-05, + 2.31300350e-05, 2.11796394e-05, 2.03838335e-05, 2.25920210e-05, 2.50221151e-05, 2.74548538e-05, + 2.85321528e-05, 2.82311785e-05, 2.43554683e-05, 2.16124910e-05, 2.12173953e-05, 2.25599583e-05, + 2.44726349e-05, 2.65420728e-05, 2.80645050e-05, 2.83508445e-05, 2.84318519e-05, 2.35830625e-05, + 2.01668930e-05, 1.92782936e-05, 2.24221057e-05, 2.53919076e-05, 2.70664174e-05, 2.85112023e-05, + 2.88229981e-05, 2.85604658e-05, 2.19271114e-05, 1.94350737e-05, 2.02934002e-05, 2.35874453e-05, + 2.70967550e-05, 2.89827131e-05, 2.95242888e-05, 2.92074650e-05, 2.40102779e-05, 2.09615745e-05, + 2.05915397e-05, 2.20280936e-05, 2.42125941e-05, 2.64187242e-05, 2.76209480e-05, 2.82175483e-05, + 2.07838422e-05, 1.77409436e-05, 2.06015843e-05, 2.56863666e-05, 2.81728599e-05, 2.83009432e-05, + 2.83608013e-05, 2.35931937e-05, 2.10139361e-05, 2.01433424e-05, 2.16865266e-05, 2.52274646e-05, + 2.74427855e-05, 2.81029655e-05, 2.83845146e-05, 2.41452643e-05, 1.96476810e-05, 1.86439486e-05, + 2.01684316e-05, 2.31722491e-05, 2.71282139e-05, 2.93148020e-05, 2.97674573e-05, 3.01054737e-05, + 2.49423040e-05, 2.21056261e-05, 2.30286403e-05, 2.43589926e-05, 2.45693581e-05, 2.51632299e-05, + 2.70345590e-05, 2.88758134e-05, 2.92253000e-05, 2.93043008e-05, 3.02007925e-05, 2.27208139e-05, + 1.99359390e-05, 2.06685949e-05, 2.32607603e-05, 2.47328050e-05, 2.58759211e-05, 2.87053776e-05, + 3.07567070e-05, 3.13864977e-05, 2.03033638e-05, 1.54073696e-05, 1.74183027e-05, 2.35294064e-05, + 2.74641789e-05, 2.93845072e-05, 3.04680934e-05, 3.08715130e-05, 3.08895007e-05, 2.36743738e-05, + 1.87811767e-05, 1.80303658e-05, 2.21271507e-05, 2.59159785e-05, 2.70522110e-05, 2.75503700e-05, + 2.92521603e-05, 3.09620828e-05, 2.78890407e-05, 2.38808909e-05, 1.83275983e-05, 1.58320875e-05, + 1.85277424e-05, 2.42145183e-05, 2.96871037e-05, 3.19305446e-05, 3.15646901e-05, 2.12235587e-05, + 1.66166644e-05, 1.73958178e-05, 2.15600370e-05, 2.66763854e-05, 3.03383899e-05, 3.16161871e-05, + 3.11406416e-05, 1.99989149e-05, 1.56890495e-05, 1.70869016e-05, 2.22144202e-05, 2.84247622e-05, + 3.15430706e-05, 3.16272761e-05, 3.07375171e-05, 1.82753814e-05, 1.40917493e-05, 1.80028626e-05, + 2.31023755e-05, 2.67687990e-05, 2.96517364e-05, 3.08141743e-05, 2.18800727e-05, 1.86665121e-05, + 1.84858442e-05, 2.06768209e-05, 2.58999520e-05, 2.99540512e-05, 3.08723286e-05, 3.05392399e-05, + 2.26290876e-05, 1.96527032e-05, 1.99106500e-05, 2.20249386e-05, 2.45227792e-05, 2.69435483e-05, + 2.95275083e-05, 3.04174661e-05, 2.33646472e-05, 1.99900253e-05, 2.01717679e-05, 2.10378001e-05, + 2.25171008e-05, 2.60493409e-05, 2.93587756e-05, 3.07111280e-05, 3.05854260e-05, 2.31620746e-05, + 1.78328815e-05, 1.46173453e-05, 1.66324084e-05, 2.32183334e-05, 3.00596907e-05, 3.13687809e-05, + 3.01478839e-05, 2.08657387e-05, 1.75308160e-05, 1.98256916e-05, 2.38722200e-05, 2.55821800e-05, + 2.75203894e-05, 2.97408576e-05, 3.02763266e-05, 2.34426608e-05, 1.97963156e-05, 1.80172314e-05, + 2.09460406e-05, 2.46265952e-05, 2.84794569e-05, 3.05397152e-05, 3.02645199e-05, 2.37956148e-05, + 1.98999863e-05, 1.93572100e-05, 2.15035174e-05, 2.44581462e-05, 2.74483322e-05, 3.01414339e-05, + 3.00975123e-05, 2.96055796e-05, 2.31689894e-05, 1.80222483e-05, 1.64378864e-05, 2.05515740e-05, + 2.57588307e-05, 2.89402189e-05, 3.13596525e-05, 3.17773381e-05, 3.09251290e-05, 2.10084382e-05, + 1.78701230e-05, 1.85038473e-05, 2.27714429e-05, 2.80476455e-05, 2.96398600e-05, 3.08556046e-05, + 3.17431386e-05, 2.29520997e-05, 1.93320053e-05, 1.89757534e-05, 2.05473731e-05, 2.33080430e-05, + 2.72886752e-05, 2.94639512e-05, 2.97021415e-05, 1.94141844e-05, 1.54784774e-05, 1.84269772e-05, + 2.52862705e-05, 3.01914305e-05, 3.03891514e-05, 3.00866086e-05, 2.32718214e-05, 1.95698097e-05, + 1.80543060e-05, 1.97422889e-05, 2.43941146e-05, 2.78127351e-05, 2.94443940e-05, 3.07557964e-05, + 2.33634612e-05, 1.75794995e-05, 1.63833861e-05, 1.86029703e-05, 2.28644338e-05, 2.82055940e-05, + 3.13191845e-05, 3.17445045e-05, 3.18482692e-05, 2.43133314e-05, 2.05154893e-05, 2.16597150e-05, + 2.37156866e-05, 2.40587329e-05, 2.48469601e-05, 2.79838921e-05, 3.09264088e-05, 3.09474288e-05, + 3.07051063e-05, 3.20803268e-05, 2.16663924e-05, 1.80729825e-05, 1.87334064e-05, 2.24153257e-05, + 2.46483133e-05, 2.57522257e-05, 2.97263213e-05, 3.32325542e-05, 3.43466323e-05, 1.84809146e-05, + 1.28101281e-05, 1.50006556e-05, 2.33747812e-05, 2.97715452e-05, 3.16507195e-05, 3.24650689e-05, + 3.31614427e-05, 3.32562668e-05, 2.38297371e-05, 1.72493529e-05, 1.59010796e-05, 2.11612892e-05, + 2.64463304e-05, 2.72188163e-05, 2.73172285e-05, 2.99989618e-05, 3.30136786e-05, 2.98727358e-05, + 2.39669784e-05, 1.61528683e-05, 1.30601403e-05, 1.62373479e-05, 2.36553018e-05, 3.18059266e-05, + 3.50490355e-05, 3.42039688e-05, 1.93623826e-05, 1.42330908e-05, 1.52480510e-05, 2.05847127e-05, + 2.78618539e-05, 3.34843992e-05, 3.51869916e-05, 3.37747960e-05, 1.76524251e-05, 1.32105153e-05, + 1.50034317e-05, 2.13994754e-05, 3.05632005e-05, 3.52124083e-05, 3.44699278e-05, 3.29182121e-05, + 1.61326509e-05, 1.15628736e-05, 1.62295147e-05, 2.31626223e-05, 2.75499645e-05, 3.05260733e-05, + 3.23349047e-05, 2.07388178e-05, 1.70545509e-05, 1.66645339e-05, 1.88366066e-05, 2.54018677e-05, + 3.17606314e-05, 3.32181028e-05, 3.25927256e-05, 2.17279177e-05, 1.81494511e-05, 1.84088313e-05, + 2.10056670e-05, 2.38234175e-05, 2.65726394e-05, 3.06571058e-05, 3.23907943e-05, 2.26988715e-05, + 1.83127027e-05, 1.84960747e-05, 1.98184767e-05, 2.14855865e-05, 2.57641390e-05, 3.04744967e-05, + 3.28296163e-05, 3.26687809e-05, 2.38198043e-05, 1.66706857e-05, 1.21387516e-05, 1.38690292e-05, + 2.12616704e-05, 3.10980540e-05, 3.37483712e-05, 3.10203366e-05, 1.94215656e-05, 1.57280428e-05, + 1.84775455e-05, 2.37581755e-05, 2.57063071e-05, 2.78686294e-05, 3.13133964e-05, 3.22661020e-05, + 2.41188302e-05, 1.86011713e-05, 1.57836284e-05, 1.92683142e-05, 2.40886647e-05, 2.92778485e-05, + 3.23792661e-05, 3.22093712e-05, 2.31631047e-05, 1.82664588e-05, 1.75997811e-05, 2.05271698e-05, + 2.44882699e-05, 2.82809942e-05, 3.21836207e-05, 3.16364642e-05, 3.03858744e-05, 2.28373603e-05, + 1.60563972e-05, 1.38084094e-05, 1.86385268e-05, 2.61154961e-05, 3.09404925e-05, 3.43325749e-05, + 3.48136976e-05, 3.32323227e-05, 2.02845734e-05, 1.66481970e-05, 1.69294508e-05, 2.19423737e-05, + 2.88253884e-05, 2.96532329e-05, 3.15914445e-05, 3.41172892e-05, 2.17689955e-05, 1.78707040e-05, + 1.75720843e-05, 1.91335505e-05, 2.22786124e-05, 2.80988956e-05, 3.12972942e-05, 3.09297263e-05, + 1.82815324e-05, 1.36014277e-05, 1.63822996e-05, 2.46311810e-05, 3.21304040e-05, 3.23903756e-05, + 3.15959700e-05, 2.30551776e-05, 1.83215333e-05, 1.61532927e-05, 1.78348856e-05, 2.32918962e-05, + 2.77851105e-05, 3.05120551e-05, 3.31149766e-05, 2.43719884e-05, 2.07870757e-05, 1.99247741e-05, + 2.19261204e-05, 2.48460329e-05, 2.71205374e-05, 2.81176125e-05, 2.80846776e-05, 2.78619899e-05, + 2.47475316e-05, 2.25857017e-05, 2.32208699e-05, 2.46125598e-05, 2.48382744e-05, 2.52070043e-05, + 2.69711818e-05, 2.81674285e-05, 2.78478919e-05, 2.75337149e-05, 2.79868345e-05, 2.36191248e-05, + 2.12937453e-05, 2.14714139e-05, 2.40750854e-05, 2.54448378e-05, 2.55665902e-05, 2.71332074e-05, + 2.84959613e-05, 2.88570895e-05, 2.15216819e-05, 1.71593836e-05, 1.89148628e-05, 2.51372614e-05, + 2.84343958e-05, 2.83611181e-05, 2.80874364e-05, 2.83313508e-05, 2.83965336e-05, 2.55976528e-05, + 2.14061659e-05, 1.98605026e-05, 2.35923342e-05, 2.63859103e-05, 2.60670889e-05, 2.56493809e-05, + 2.68706501e-05, 2.81211372e-05, 2.81062074e-05, 2.55364339e-05, 1.99282519e-05, 1.70700975e-05, + 1.98043927e-05, 2.47009952e-05, 2.82175219e-05, 2.89382553e-05, 2.85872829e-05, 2.18193720e-05, + 1.84877028e-05, 1.94686456e-05, 2.34121106e-05, 2.72165593e-05, 2.90828480e-05, 2.93081744e-05, + 2.86085713e-05, 2.04345994e-05, 1.76426432e-05, 1.94252532e-05, 2.38534005e-05, 2.82576424e-05, + 2.93886104e-05, 2.87464210e-05, 2.82417964e-05, 1.99645472e-05, 1.62791821e-05, 2.05638902e-05, + 2.53633109e-05, 2.67603931e-05, 2.70159178e-05, 2.76495311e-05, 2.32402082e-05, 2.12005525e-05, + 2.07082052e-05, 2.16419026e-05, 2.50904172e-05, 2.79232179e-05, 2.83793196e-05, 2.81360111e-05, + 2.38303489e-05, 2.18313256e-05, 2.19379638e-05, 2.34784276e-05, 2.45677929e-05, 2.54064459e-05, + 2.72683879e-05, 2.80674464e-05, 2.43651060e-05, 2.16534567e-05, 2.17305098e-05, 2.28428926e-05, + 2.35985685e-05, 2.53865582e-05, 2.72505448e-05, 2.81881683e-05, 2.81611801e-05, 2.62124688e-05, + 2.17016788e-05, 1.68341535e-05, 1.76617135e-05, 2.23667572e-05, 2.71893693e-05, 2.83844794e-05, + 2.70284135e-05, 2.24010473e-05, 2.02599360e-05, 2.21812098e-05, 2.52577897e-05, 2.58409137e-05, + 2.63237598e-05, 2.77034678e-05, 2.80857250e-05, 2.62770360e-05, 2.24445395e-05, 1.96416160e-05, + 2.20291657e-05, 2.48116781e-05, 2.68884164e-05, 2.79438546e-05, 2.80452057e-05, 2.45093402e-05, + 2.16956775e-05, 2.12357872e-05, 2.33934659e-05, 2.55544345e-05, 2.68665516e-05, 2.81365373e-05, + 2.76710190e-05, 2.69191585e-05, 2.48106905e-05, 2.01865603e-05, 1.78250149e-05, 2.14626018e-05, + 2.61548202e-05, 2.81182850e-05, 2.88692242e-05, 2.88873790e-05, 2.83439103e-05, 2.36595439e-05, + 2.16001271e-05, 2.11984230e-05, 2.39775786e-05, 2.68425231e-05, 2.61235659e-05, 2.69125931e-05, + 2.83605291e-05, 2.34848363e-05, 2.17762058e-05, 2.17339066e-05, 2.23376315e-05, 2.38123047e-05, + 2.68309065e-05, 2.79536078e-05, 2.73686216e-05, 2.24126291e-05, 1.88882918e-05, 2.02387383e-05, + 2.47768605e-05, 2.80414047e-05, 2.80932903e-05, 2.76430676e-05, 2.49983487e-05, 2.22624267e-05, + 2.03337502e-05, 2.11277837e-05, 2.39715032e-05, 2.59187603e-05, 2.72044223e-05, 2.83959666e-05, + 2.52895236e-05, 2.83639635e-05, 2.89298219e-05, 2.84253375e-05, 2.62831773e-05, 2.27982815e-05, + 2.08476126e-05, 2.05140359e-05, 2.03276441e-05, 2.46407196e-05, 2.66961199e-05, 2.60303082e-05, + 2.51389364e-05, 2.49842051e-05, 2.45019292e-05, 2.28951171e-05, 2.11714945e-05, 2.09930261e-05, + 2.10102374e-05, 2.02205692e-05, 2.64477594e-05, 2.83450608e-05, 2.76485952e-05, 2.60480505e-05, + 2.49025783e-05, 2.39138133e-05, 2.15450679e-05, 1.96346464e-05, 1.90184176e-05, 2.80677598e-05, + 3.05313683e-05, 2.96096252e-05, 2.59818111e-05, 2.22209579e-05, 2.07155138e-05, 1.99921116e-05, + 1.96127387e-05, 1.95753500e-05, 2.58880637e-05, 2.97413883e-05, 2.96198753e-05, 2.70266924e-05, + 2.38816850e-05, 2.29460057e-05, 2.25495757e-05, 2.11713129e-05, 1.96208728e-05, 2.19721169e-05, + 2.56892810e-05, 2.93091416e-05, 2.98425924e-05, 2.89775688e-05, 2.52841792e-05, 2.05325855e-05, + 1.85838012e-05, 1.90090341e-05, 2.72466444e-05, 3.02563827e-05, 3.01062230e-05, 2.75492170e-05, + 2.31585702e-05, 1.96934297e-05, 1.86190517e-05, 1.93076978e-05, 2.77518799e-05, 3.06680720e-05, + 3.04694300e-05, 2.70134126e-05, 2.14985052e-05, 1.86279176e-05, 1.88940852e-05, 1.97427491e-05, + 2.93991182e-05, 3.14067417e-05, 3.01616931e-05, 2.64171770e-05, 2.31375290e-05, 2.08520293e-05, + 1.98696864e-05, 2.71640292e-05, 2.97576527e-05, 2.96650377e-05, 2.77297070e-05, 2.38592345e-05, + 2.04225293e-05, 1.95943715e-05, 1.99240151e-05, 2.65959596e-05, 2.89556038e-05, 2.87182727e-05, + 2.70948626e-05, 2.49843477e-05, 2.30239464e-05, 2.08985144e-05, 2.00357320e-05, 2.60129432e-05, + 2.84825750e-05, 2.83220266e-05, 2.78927822e-05, 2.66409290e-05, 2.37575181e-05, 2.10281667e-05, + 1.97805968e-05, 1.98817534e-05, 2.64042977e-05, 3.10898273e-05, 3.13000389e-05, 2.94196814e-05, + 2.55423394e-05, 2.05214063e-05, 1.92322649e-05, 2.04870623e-05, 2.78921657e-05, 3.05447672e-05, + 2.89335815e-05, 2.56726928e-05, 2.41745932e-05, 2.25603890e-05, 2.06413367e-05, 2.01340215e-05, + 2.61316790e-05, 2.90896548e-05, 2.94675024e-05, 2.76371521e-05, 2.49292967e-05, 2.17557080e-05, + 1.99845116e-05, 2.01555162e-05, 2.56365563e-05, 2.86053428e-05, 2.89652166e-05, 2.76017883e-05, + 2.51580122e-05, 2.25712292e-05, 2.02177996e-05, 2.03851258e-05, 2.09015968e-05, 2.62807577e-05, + 2.98716150e-05, 2.98415146e-05, 2.77684602e-05, 2.40232912e-05, 2.11362203e-05, 1.90324053e-05, + 1.87195656e-05, 1.95689974e-05, 2.82095038e-05, 3.09839258e-05, 2.99535349e-05, 2.64950230e-05, + 2.20976165e-05, 2.09623305e-05, 2.00019173e-05, 1.89737099e-05, 2.61852699e-05, 2.92959574e-05, + 2.96925171e-05, 2.82061260e-05, 2.59383180e-05, 2.27042905e-05, 2.07822612e-05, 2.07482069e-05, + 2.95159867e-05, 3.22211753e-05, 2.94149615e-05, 2.43455077e-05, 2.02107838e-05, 2.00483147e-05, + 2.04002916e-05, 2.62097441e-05, 2.92649334e-05, 2.99373587e-05, 2.84647975e-05, 2.49808481e-05, + 2.23443442e-05, 2.09727647e-05, 1.96735159e-05, 2.52943891e-05, 2.83451318e-05, 2.89052156e-05, + 2.83981153e-05, 2.62677164e-05, 2.28100516e-05, 2.08717975e-05, 2.05424051e-05, 2.03607251e-05, + 2.46517839e-05, 2.66938261e-05, 2.60337240e-05, 2.51438339e-05, 2.49892726e-05, 2.45105342e-05, + 2.29073192e-05, 2.11912680e-05, 2.10187906e-05, 2.10395065e-05, 2.02533308e-05, 2.64410899e-05, + 2.83235126e-05, 2.76381466e-05, 2.60437760e-05, 2.49027849e-05, 2.39272519e-05, 2.15726248e-05, + 1.96674072e-05, 1.90528099e-05, 2.80496697e-05, 3.04835667e-05, 2.95763355e-05, 2.59682995e-05, + 2.22241683e-05, 2.07382084e-05, 2.00261110e-05, 1.96477351e-05, 1.96099344e-05, 2.58712208e-05, + 2.96932113e-05, 2.95826300e-05, 2.70106453e-05, 2.38868151e-05, 2.29675046e-05, 2.25805328e-05, + 2.12062015e-05, 1.96583098e-05, 2.19827629e-05, 2.56762888e-05, 2.92774623e-05, 2.98085635e-05, + 2.89526373e-05, 2.52860089e-05, 2.05591298e-05, 1.86212497e-05, 1.90468655e-05, 2.72407337e-05, + 3.02118187e-05, 3.00612872e-05, 2.75257937e-05, 2.31643116e-05, 1.97181349e-05, 1.86514450e-05, + 1.93423638e-05, 2.77457711e-05, 3.06170100e-05, 3.04175138e-05, 2.69952630e-05, 2.15131897e-05, + 1.86591762e-05, 1.89310460e-05, 1.97774963e-05, 2.93655746e-05, 3.13406523e-05, 3.01104392e-05, + 2.63941594e-05, 2.31488577e-05, 2.08889601e-05, 1.99100802e-05, 2.71486813e-05, 2.97104812e-05, + 2.96225815e-05, 2.77167327e-05, 2.38782086e-05, 2.04538478e-05, 1.96289722e-05, 1.99581494e-05, + 2.65849925e-05, 2.89193655e-05, 2.86856491e-05, 2.70786553e-05, 2.49920073e-05, 2.30511717e-05, + 2.09321028e-05, 2.00695088e-05, 2.60065394e-05, 2.84562041e-05, 2.82980182e-05, 2.78681089e-05, + 2.66312678e-05, 2.37749816e-05, 2.10604758e-05, 1.98155986e-05, 1.99160281e-05, 2.63720340e-05, + 3.10128958e-05, 3.12365027e-05, 2.93931536e-05, 2.55599677e-05, 2.05600784e-05, 1.92704101e-05, + 2.05278828e-05, 2.78709525e-05, 3.04875623e-05, 2.88952306e-05, 2.56628903e-05, 2.41814317e-05, + 2.25842045e-05, 2.06728201e-05, 2.01665324e-05, 2.61032266e-05, 2.90464057e-05, 2.94341272e-05, + 2.76231069e-05, 2.49354496e-05, 2.17834604e-05, 2.00202949e-05, 2.01882815e-05, 2.56347528e-05, + 2.85764628e-05, 2.89327557e-05, 2.75776125e-05, 2.51531682e-05, 2.25889213e-05, 2.02487969e-05, + 2.04198144e-05, 2.09390319e-05, 2.62656899e-05, 2.98279766e-05, 2.98065734e-05, 2.77559947e-05, + 2.40289355e-05, 2.11570204e-05, 1.90665101e-05, 1.87564028e-05, 1.96042858e-05, 2.81722062e-05, + 3.09098620e-05, 2.99025960e-05, 2.64843883e-05, 2.21216483e-05, 2.10074702e-05, 2.00491069e-05, + 1.90146234e-05, 2.61840049e-05, 2.92537519e-05, 2.96430700e-05, 2.81798338e-05, 2.59381507e-05, + 2.27206376e-05, 2.08091851e-05, 2.07823553e-05, 2.94649313e-05, 3.21349414e-05, 2.93797747e-05, + 2.43605957e-05, 2.02430000e-05, 2.00816491e-05, 2.04351387e-05, 2.61939476e-05, 2.92197870e-05, + 2.98916993e-05, 2.84421341e-05, 2.49940111e-05, 2.23751667e-05, 2.10062289e-05, 1.97071046e-05, + 2.48982001e-05, 2.37630106e-05, 2.33602918e-05, 2.48893812e-05, 2.61580626e-05, 2.56746455e-05, + 2.50868087e-05, 2.47695834e-05, 2.43802432e-05, 2.47595916e-05, 2.42443364e-05, 2.43510889e-05, + 2.50175825e-05, 2.51196762e-05, 2.51048912e-05, 2.55985579e-05, 2.54154174e-05, 2.49244840e-05, + 2.46118958e-05, 2.44199234e-05, 2.50542370e-05, 2.42253633e-05, 2.38909798e-05, 2.51952486e-05, + 2.56657080e-05, 2.49944284e-05, 2.46453954e-05, 2.44598830e-05, 2.43212094e-05, 2.42410240e-05, + 2.19235376e-05, 2.28993159e-05, 2.62173739e-05, 2.66110115e-05, 2.52352552e-05, 2.43325856e-05, + 2.42677940e-05, 2.43046691e-05, 2.66224175e-05, 2.53460881e-05, 2.37782769e-05, 2.54723085e-05, + 2.58043770e-05, 2.47153731e-05, 2.39858729e-05, 2.40727683e-05, 2.40557421e-05, 2.60328372e-05, + 2.63963647e-05, 2.36260469e-05, 2.14065505e-05, 2.32825286e-05, 2.52195294e-05, 2.49259063e-05, + 2.40384697e-05, 2.40266878e-05, 2.39259432e-05, 2.29423033e-05, 2.37474792e-05, 2.56939351e-05, + 2.60785967e-05, 2.51455744e-05, 2.44693670e-05, 2.43020244e-05, 2.30087823e-05, 2.24451095e-05, + 2.39563105e-05, 2.57231267e-05, 2.57925433e-05, 2.45656410e-05, 2.40975296e-05, 2.42836887e-05, + 2.37222540e-05, 2.16922092e-05, 2.48276860e-05, 2.68054961e-05, 2.55797188e-05, 2.39559413e-05, + 2.37812772e-05, 2.52288446e-05, 2.51563092e-05, 2.46128359e-05, 2.41097501e-05, 2.44802129e-05, + 2.45233884e-05, 2.43026412e-05, 2.43259083e-05, 2.53768631e-05, 2.51872178e-05, 2.51166235e-05, + 2.54114821e-05, 2.48523335e-05, 2.41271253e-05, 2.42479354e-05, 2.43484536e-05, 2.54564733e-05, + 2.46681400e-05, 2.46250127e-05, 2.53893881e-05, 2.51821557e-05, 2.46905287e-05, 2.43370866e-05, + 2.42595784e-05, 2.43165861e-05, 2.77113156e-05, 2.66377593e-05, 2.21220451e-05, 2.16546512e-05, + 2.31901905e-05, 2.38574472e-05, 2.40025820e-05, 2.36693041e-05, 2.49558699e-05, 2.48055466e-05, + 2.55153489e-05, 2.60934146e-05, 2.54819184e-05, 2.46596005e-05, 2.44789443e-05, 2.44502059e-05, + 2.75544204e-05, 2.58946411e-05, 2.34695537e-05, 2.44094118e-05, 2.50499385e-05, 2.45702925e-05, + 2.41774155e-05, 2.44260162e-05, 2.53055024e-05, 2.47984435e-05, 2.46171392e-05, 2.57156122e-05, + 2.59843597e-05, 2.52209078e-05, 2.45740291e-05, 2.42316953e-05, 2.39002691e-05, 2.61197919e-05, + 2.42609989e-05, 2.20718425e-05, 2.39691145e-05, 2.56809771e-05, 2.53326092e-05, 2.43461407e-05, + 2.40994538e-05, 2.42440459e-05, 2.64552433e-05, 2.64550083e-05, 2.52963759e-05, 2.54452245e-05, + 2.48051871e-05, 2.31754953e-05, 2.31601840e-05, 2.37602749e-05, 2.47226653e-05, 2.53837087e-05, + 2.56342100e-05, 2.51277116e-05, 2.48522598e-05, 2.52941843e-05, 2.48579806e-05, 2.42251414e-05, + 2.61834452e-05, 2.46453055e-05, 2.39900517e-05, 2.45566645e-05, 2.44685456e-05, 2.43859624e-05, + 2.42157244e-05, 2.62565148e-05, 2.58435834e-05, 2.44474378e-05, 2.41544457e-05, 2.42709014e-05, + 2.40841206e-05, 2.42445744e-05, 2.43870789e-05, 2.48280435e-05, 3.52757991e-05, 3.79856894e-05, + 3.26081656e-05, 2.47568772e-05, 1.81638957e-05, 1.52068877e-05, 1.49822010e-05, 1.51212783e-05, + 2.35847328e-05, 2.96360120e-05, 2.77187496e-05, 2.42538433e-05, 2.37118056e-05, 2.26519338e-05, + 1.84655735e-05, 1.53972449e-05, 1.56836270e-05, 1.61247032e-05, 1.48702707e-05, 2.72731136e-05, + 3.40270301e-05, 3.29856869e-05, 2.60351613e-05, 2.25663016e-05, 2.15422262e-05, 1.71278298e-05, + 1.37484386e-05, 1.28155543e-05, 3.32417092e-05, 4.74757600e-05, 4.13595830e-05, 2.39795596e-05, + 1.58384472e-05, 1.47830990e-05, 1.45529031e-05, 1.39341945e-05, 1.38228857e-05, 2.30756570e-05, + 3.49411500e-05, 3.87784659e-05, 2.78113554e-05, 2.01663703e-05, 1.99090275e-05, 2.02349085e-05, + 1.71879647e-05, 1.42033382e-05, 1.61022312e-05, 2.30305354e-05, 3.83210090e-05, 4.70912208e-05, + 3.83466606e-05, 2.42131594e-05, 1.48241460e-05, 1.23696229e-05, 1.31276150e-05, 3.18211187e-05, + 4.31800377e-05, 4.02690148e-05, 2.86121566e-05, 1.83027421e-05, 1.30814093e-05, 1.19764004e-05, + 1.33458969e-05, 3.55841068e-05, 4.60932832e-05, 4.07065683e-05, 2.72710966e-05, 1.55311511e-05, + 1.18926527e-05, 1.28450669e-05, 1.41525676e-05, 3.83059246e-05, 5.11770974e-05, 3.74021947e-05, + 2.39040310e-05, 1.89813132e-05, 1.67090795e-05, 1.50150485e-05, 2.86531460e-05, 3.54594106e-05, + 3.66142476e-05, 3.26614100e-05, 2.23079258e-05, 1.51190475e-05, 1.38597097e-05, 1.44350102e-05, + 2.69741364e-05, 3.32747034e-05, 3.28275623e-05, 2.81013527e-05, 2.42049962e-05, 2.10468800e-05, + 1.63970832e-05, 1.46143652e-05, 2.54475584e-05, 3.32929514e-05, 3.29742704e-05, 3.01065987e-05, + 2.74774252e-05, 2.17142008e-05, 1.65308267e-05, 1.42510818e-05, 1.43683456e-05, 2.23761119e-05, + 3.52750068e-05, 4.92396025e-05, 4.48409197e-05, 2.90466237e-05, 1.61855333e-05, 1.35558198e-05, + 1.63771363e-05, 3.10777462e-05, 3.85146245e-05, 3.24428785e-05, 2.35160894e-05, 2.12972122e-05, + 1.91813653e-05, 1.55903492e-05, 1.46715737e-05, 2.20658027e-05, 3.19662994e-05, 3.92279243e-05, + 3.16926012e-05, 2.37137938e-05, 1.76568985e-05, 1.47307454e-05, 1.47413634e-05, 2.48627019e-05, + 3.32986812e-05, 3.47059777e-05, 2.86939264e-05, 2.25800822e-05, 1.83623689e-05, 1.46746190e-05, + 1.54209259e-05, 1.68876367e-05, 2.48212027e-05, 3.81371524e-05, 4.47575173e-05, 3.31141476e-05, + 2.06550713e-05, 1.54351055e-05, 1.28125338e-05, 1.25385210e-05, 1.38827724e-05, 2.86210699e-05, + 3.54449784e-05, 3.56256986e-05, 2.65982845e-05, 1.80092220e-05, 1.80895118e-05, 1.61103448e-05, + 1.33701896e-05, 2.73191941e-05, 3.36859172e-05, 3.41091599e-05, 3.14845614e-05, 2.64555296e-05, + 1.85242401e-05, 1.53717794e-05, 1.61326722e-05, 3.23767102e-05, 4.37023491e-05, 3.76024389e-05, + 2.32784179e-05, 1.47915847e-05, 1.45915985e-05, 1.54707311e-05, 2.44150552e-05, 3.25236699e-05, + 3.78089452e-05, 3.45325337e-05, 2.53156624e-05, 1.96276507e-05, 1.65484548e-05, 1.39036461e-05, + 2.57013476e-05, 3.05692201e-05, 3.16232209e-05, 2.88368879e-05, 2.47948847e-05, 2.13524296e-05, + 1.95333422e-05, 1.95300552e-05, 1.98618536e-05, 2.51686385e-05, 2.82948854e-05, 2.74307792e-05, + 2.53318042e-05, 2.49845630e-05, 2.44328058e-05, 2.15989694e-05, 1.95013931e-05, 1.99975866e-05, + 2.05169038e-05, 1.96351304e-05, 2.67130052e-05, 2.98167216e-05, 2.97691205e-05, 2.60611492e-05, + 2.40118946e-05, 2.38847182e-05, 2.12439059e-05, 1.86682281e-05, 1.79115947e-05, 2.95619381e-05, + 3.45579435e-05, 3.27544111e-05, 2.43776326e-05, 1.91911278e-05, 1.91138438e-05, 1.94220269e-05, + 1.89332210e-05, 1.88168389e-05, 2.36582464e-05, 2.91682237e-05, 3.14353302e-05, 2.66342019e-05, + 2.25509535e-05, 2.30823469e-05, 2.37698797e-05, 2.16373693e-05, 1.92817862e-05, 1.96967463e-05, + 2.37803404e-05, 3.14662464e-05, 3.50401945e-05, 3.17772811e-05, 2.51705999e-05, 1.93157757e-05, + 1.76446292e-05, 1.83511128e-05, 2.93508472e-05, 3.30252653e-05, 3.17743460e-05, 2.67959816e-05, + 2.12071225e-05, 1.77264588e-05, 1.70534339e-05, 1.83996254e-05, 3.13114098e-05, 3.38962908e-05, + 3.16732209e-05, 2.62270634e-05, 1.93987729e-05, 1.69259360e-05, 1.80559077e-05, 1.91117130e-05, + 3.13780989e-05, 3.50582874e-05, 3.02208871e-05, 2.39556843e-05, 2.19477573e-05, 2.13531285e-05, + 2.01208544e-05, 2.71553010e-05, 2.94613804e-05, 3.02080084e-05, 2.94831035e-05, 2.46692076e-05, + 1.97786957e-05, 1.88498297e-05, 1.93271469e-05, 2.63487398e-05, 2.88102757e-05, 2.87269784e-05, + 2.67978525e-05, 2.54232070e-05, 2.41758907e-05, 2.09398205e-05, 1.94642947e-05, 2.56038237e-05, + 2.92304123e-05, 2.91651857e-05, 2.75901104e-05, 2.67063819e-05, 2.41874206e-05, 2.09876329e-05, + 1.92088468e-05, 1.92762982e-05, 2.26209028e-05, 2.82485040e-05, 3.45091387e-05, 3.45155728e-05, + 2.89040496e-05, 2.10126458e-05, 1.87476464e-05, 2.12759305e-05, 2.82703296e-05, 3.04925058e-05, + 2.82936628e-05, 2.42270728e-05, 2.34239083e-05, 2.26507451e-05, 2.01796045e-05, 1.94547297e-05, + 2.25536304e-05, 2.78500897e-05, 3.18073559e-05, 2.89151106e-05, 2.50337964e-05, 2.16687209e-05, + 1.96573871e-05, 1.95258561e-05, 2.54310037e-05, 2.91273115e-05, 2.96926618e-05, 2.68122930e-05, + 2.38105792e-05, 2.17580813e-05, 1.93882108e-05, 2.01882663e-05, 2.15215547e-05, 2.48513302e-05, + 3.08715482e-05, 3.40917150e-05, 2.97456361e-05, 2.29210753e-05, 1.95763899e-05, 1.78958503e-05, + 1.77713388e-05, 1.89018052e-05, 2.62516557e-05, 2.84324917e-05, 2.93923702e-05, 2.61351471e-05, + 2.17711258e-05, 2.28666052e-05, 2.13829358e-05, 1.87145925e-05, 2.69784767e-05, 2.87793619e-05, + 2.87062829e-05, 2.82775663e-05, 2.65006927e-05, 2.18217926e-05, 1.97913093e-05, 2.07509604e-05, + 2.77632856e-05, 3.15544313e-05, 3.09798631e-05, 2.51485501e-05, 1.95432856e-05, 1.94243785e-05, + 2.02373217e-05, 2.45647482e-05, 2.80671175e-05, 3.06366009e-05, 3.00254943e-05, 2.63934600e-05, + 2.33152956e-05, 2.10565073e-05, 1.88417477e-05, 2.48644288e-05, 2.23438245e-05, 2.16827426e-05, + 2.26628217e-05, 2.42814024e-05, 2.60093543e-05, 2.67584324e-05, 2.69561070e-05, 2.71560763e-05, + 2.52572066e-05, 2.38198174e-05, 2.43243155e-05, 2.49582937e-05, 2.50490411e-05, 2.53231186e-05, + 2.59936618e-05, 2.65586716e-05, 2.67914544e-05, 2.69032323e-05, 2.71607357e-05, 2.41242313e-05, + 2.25257341e-05, 2.29815465e-05, 2.43988108e-05, 2.50679076e-05, 2.56463558e-05, 2.67320827e-05, + 2.72286610e-05, 2.73416830e-05, 2.27542307e-05, 1.93110569e-05, 2.08289639e-05, 2.44508617e-05, + 2.58678013e-05, 2.67198254e-05, 2.72398523e-05, 2.73251305e-05, 2.73115553e-05, 2.44784683e-05, + 2.17805736e-05, 2.12731258e-05, 2.37815655e-05, 2.55473944e-05, 2.61588084e-05, 2.64626005e-05, + 2.70298026e-05, 2.74247289e-05, 2.61420283e-05, 2.45988014e-05, 2.14733687e-05, 1.96117298e-05, + 2.16034198e-05, 2.48713807e-05, 2.68858059e-05, 2.75056156e-05, 2.75023743e-05, 2.33154312e-05, + 2.02544701e-05, 2.08323803e-05, 2.34568988e-05, 2.57746745e-05, 2.68707134e-05, 2.72497091e-05, + 2.73376908e-05, 2.25639244e-05, 1.95473849e-05, 2.06179682e-05, 2.38153679e-05, 2.63399240e-05, + 2.71913970e-05, 2.74690230e-05, 2.73005962e-05, 2.14392987e-05, 1.82632999e-05, 2.12642690e-05, + 2.41881970e-05, 2.59048255e-05, 2.71723304e-05, 2.75007914e-05, 2.36566220e-05, 2.17068295e-05, + 2.15879360e-05, 2.29843113e-05, 2.57181384e-05, 2.70772656e-05, 2.73103821e-05, 2.72540316e-05, + 2.40572726e-05, 2.23385272e-05, 2.25001969e-05, 2.37285446e-05, 2.50509723e-05, 2.62018905e-05, + 2.70617865e-05, 2.72253601e-05, 2.44334237e-05, 2.25556849e-05, 2.26687355e-05, 2.31704789e-05, + 2.40081399e-05, 2.57578825e-05, 2.69931371e-05, 2.73064466e-05, 2.72649236e-05, 2.41171048e-05, + 2.11429719e-05, 1.87037256e-05, 2.02196481e-05, 2.44708887e-05, 2.73065737e-05, 2.74977880e-05, + 2.73810124e-05, 2.30821529e-05, 2.09407651e-05, 2.24404099e-05, 2.46263436e-05, 2.54591179e-05, + 2.63415105e-05, 2.70464901e-05, 2.71633971e-05, 2.42632610e-05, 2.24138520e-05, 2.12591536e-05, + 2.31419171e-05, 2.50824518e-05, 2.66815537e-05, 2.73095337e-05, 2.71701579e-05, 2.46602134e-05, + 2.24981107e-05, 2.21568449e-05, 2.34241684e-05, 2.49082663e-05, 2.62097138e-05, 2.70943793e-05, + 2.72033770e-05, 2.71735674e-05, 2.42830041e-05, 2.12734421e-05, 2.00932511e-05, 2.29093063e-05, + 2.55037944e-05, 2.65993006e-05, 2.73275090e-05, 2.74709651e-05, 2.73418993e-05, 2.31098190e-05, + 2.11698931e-05, 2.15992610e-05, 2.41284115e-05, 2.64934919e-05, 2.73470223e-05, 2.77024782e-05, + 2.76450860e-05, 2.42651439e-05, 2.21338339e-05, 2.19034154e-05, 2.28881107e-05, 2.44450326e-05, + 2.61409866e-05, 2.68650936e-05, 2.71128666e-05, 2.21707367e-05, 1.94532998e-05, 2.15447217e-05, + 2.54353911e-05, 2.71416469e-05, 2.72065762e-05, 2.72061009e-05, 2.43220126e-05, 2.22751315e-05, + 2.12968876e-05, 2.24039388e-05, 2.50335187e-05, 2.65465983e-05, 2.70406526e-05, 2.72600659e-05, + 2.54111587e-05, 2.63910102e-05, 2.64610249e-05, 2.62877631e-05, 2.54282134e-05, 2.39394318e-05, + 2.29340667e-05, 2.28422355e-05, 2.28886865e-05, 2.51921066e-05, 2.60119959e-05, 2.58031454e-05, + 2.53184972e-05, 2.52256914e-05, 2.50241497e-05, 2.40263470e-05, 2.30106140e-05, 2.31102687e-05, + 2.32627530e-05, 2.27918525e-05, 2.57719846e-05, 2.63502887e-05, 2.62712540e-05, 2.56061709e-05, + 2.50196611e-05, 2.47893998e-05, 2.36010865e-05, 2.23272347e-05, 2.18987897e-05, 2.63041969e-05, + 2.62813533e-05, 2.64704647e-05, 2.52959606e-05, 2.31812312e-05, 2.27703339e-05, 2.26633465e-05, + 2.24041466e-05, 2.23568551e-05, 2.51332116e-05, 2.64380725e-05, 2.65000671e-05, 2.58512814e-05, + 2.44845374e-05, 2.43973517e-05, 2.44550917e-05, 2.36053433e-05, 2.25136141e-05, 2.32741993e-05, + 2.51222655e-05, 2.64833556e-05, 2.62506736e-05, 2.64644026e-05, 2.53170176e-05, 2.27825360e-05, + 2.16766641e-05, 2.20401730e-05, 2.61901237e-05, 2.64616145e-05, 2.65163265e-05, 2.59506200e-05, + 2.39848855e-05, 2.20344575e-05, 2.14830542e-05, 2.21452796e-05, 2.63605247e-05, 2.63668128e-05, + 2.65287529e-05, 2.57891986e-05, 2.30644553e-05, 2.14404822e-05, 2.19090402e-05, 2.24971768e-05, + 2.64881346e-05, 2.60885601e-05, 2.65140347e-05, 2.52886510e-05, 2.41711816e-05, 2.34459183e-05, + 2.28330340e-05, 2.59432458e-05, 2.64561695e-05, 2.64820884e-05, 2.62599928e-05, 2.49362457e-05, + 2.28907745e-05, 2.23727534e-05, 2.26151966e-05, 2.57419405e-05, 2.63414426e-05, 2.63101988e-05, + 2.58846634e-05, 2.53051577e-05, 2.46517658e-05, 2.33487604e-05, 2.26884975e-05, 2.55248057e-05, + 2.63249553e-05, 2.63028366e-05, 2.60981225e-05, 2.58018825e-05, 2.48182867e-05, 2.33965800e-05, + 2.25379005e-05, 2.25876264e-05, 2.49964599e-05, 2.64772115e-05, 2.62225066e-05, 2.63360959e-05, + 2.58974406e-05, 2.32648515e-05, 2.22336564e-05, 2.33250795e-05, 2.61723448e-05, 2.65390031e-05, + 2.62949629e-05, 2.52101941e-05, 2.47461970e-05, 2.42062296e-05, 2.30674541e-05, 2.27135204e-05, + 2.49320609e-05, 2.62687686e-05, 2.64906228e-05, 2.62019984e-05, 2.52241435e-05, 2.37656211e-05, + 2.27314226e-05, 2.27409333e-05, 2.54282877e-05, 2.63301149e-05, 2.64025249e-05, 2.59602727e-05, + 2.50279354e-05, 2.39902298e-05, 2.27170765e-05, 2.29989673e-05, 2.35031107e-05, 2.54382179e-05, + 2.65101834e-05, 2.63728302e-05, 2.62834385e-05, 2.46013866e-05, 2.30239066e-05, 2.18977397e-05, + 2.17611356e-05, 2.23815741e-05, 2.59651649e-05, 2.64826780e-05, 2.64673334e-05, 2.56927148e-05, + 2.38778062e-05, 2.38485071e-05, 2.32150406e-05, 2.21452152e-05, 2.57670355e-05, 2.63721613e-05, + 2.64026989e-05, 2.62114782e-05, 2.56557798e-05, 2.40381675e-05, 2.29931983e-05, 2.32565416e-05, + 2.63042794e-05, 2.65355715e-05, 2.64849608e-05, 2.51288304e-05, 2.27617345e-05, 2.26800743e-05, + 2.30171648e-05, 2.53722629e-05, 2.63083059e-05, 2.65103562e-05, 2.63742506e-05, 2.54666947e-05, + 2.43062292e-05, 2.34001708e-05, 2.23932695e-05, 2.45054802e-05, 2.10887075e-05, 2.02598719e-05, + 2.18848420e-05, 2.44246878e-05, 2.67918018e-05, 2.78871645e-05, 2.79988823e-05, 2.79916672e-05, + 2.49517053e-05, 2.29012072e-05, 2.35434512e-05, 2.46972261e-05, 2.48793182e-05, 2.52539735e-05, + 2.66932894e-05, 2.77846753e-05, 2.77407145e-05, 2.76191246e-05, 2.80740737e-05, 2.36499999e-05, + 2.14648629e-05, 2.18153812e-05, 2.40645296e-05, 2.52354005e-05, 2.56566037e-05, 2.72620329e-05, + 2.84486762e-05, 2.87678185e-05, 2.17162561e-05, 1.75190018e-05, 1.92563226e-05, 2.46888673e-05, + 2.74868849e-05, 2.80143329e-05, 2.81916437e-05, 2.84075578e-05, 2.84408171e-05, 2.49629684e-05, + 2.11086959e-05, 2.00028045e-05, 2.34358280e-05, 2.60700504e-05, 2.62628669e-05, 2.62023622e-05, + 2.72919718e-05, 2.83387341e-05, 2.74698799e-05, 2.50020216e-05, 2.01480738e-05, 1.76270556e-05, + 2.01518009e-05, 2.46956196e-05, 2.80356525e-05, 2.89407807e-05, 2.86998701e-05, 2.21930277e-05, + 1.87217871e-05, 1.95542785e-05, 2.31480574e-05, 2.66986745e-05, 2.85843106e-05, 2.90107195e-05, + 2.85986529e-05, 2.10163637e-05, 1.78990664e-05, 1.94150028e-05, 2.35993935e-05, 2.76943542e-05, + 2.90239033e-05, 2.87835227e-05, 2.83324945e-05, 2.01490525e-05, 1.65113395e-05, 2.03729069e-05, + 2.46557576e-05, 2.65126721e-05, 2.74728203e-05, 2.80858713e-05, 2.31694684e-05, 2.09578123e-05, + 2.06289960e-05, 2.19104168e-05, 2.54243832e-05, 2.79778575e-05, 2.84287514e-05, 2.82324664e-05, + 2.37282279e-05, 2.16506172e-05, 2.17994106e-05, 2.33422555e-05, 2.47267998e-05, 2.59003819e-05, + 2.75578866e-05, 2.81690375e-05, 2.42470210e-05, 2.16768091e-05, 2.17820520e-05, 2.26718988e-05, + 2.35711000e-05, 2.56199668e-05, 2.75023709e-05, 2.83017285e-05, 2.82560716e-05, 2.50828969e-05, + 2.09033711e-05, 1.70311766e-05, 1.82606288e-05, 2.31462568e-05, 2.76674289e-05, 2.85615533e-05, + 2.76149699e-05, 2.23805472e-05, 2.00331306e-05, 2.18965128e-05, 2.48623182e-05, 2.57006396e-05, + 2.65281128e-05, 2.78190659e-05, 2.81389510e-05, 2.52095835e-05, 2.20226937e-05, 1.98778092e-05, + 2.22110190e-05, 2.48841404e-05, 2.70809134e-05, 2.81465020e-05, 2.81176187e-05, 2.44621389e-05, + 2.16673427e-05, 2.12280961e-05, 2.31188481e-05, 2.52005806e-05, 2.67682133e-05, 2.81248549e-05, + 2.79023266e-05, 2.74137539e-05, 2.44059893e-05, 2.01772510e-05, 1.82825441e-05, 2.17703669e-05, + 2.59092545e-05, 2.77812481e-05, 2.87659245e-05, 2.88808482e-05, 2.84272813e-05, 2.30800996e-05, + 2.08656543e-05, 2.08964214e-05, 2.38515594e-05, 2.69337323e-05, 2.70334520e-05, 2.77496063e-05, + 2.86479164e-05, 2.36569196e-05, 2.15053992e-05, 2.13524960e-05, 2.22356929e-05, 2.39445388e-05, + 2.67035023e-05, 2.78555802e-05, 2.76533732e-05, 2.18662637e-05, 1.85011433e-05, 2.03538422e-05, + 2.50745753e-05, 2.80960176e-05, 2.81729254e-05, 2.78864963e-05, 2.45338138e-05, 2.18458480e-05, + 2.02685808e-05, 2.13070782e-05, 2.43776300e-05, 2.64140569e-05, 2.75045944e-05, 2.84050056e-05, + 2.36836706e-05, 1.85400989e-05, 1.74286035e-05, 1.98758614e-05, 2.40064542e-05, 2.81548852e-05, + 3.03571713e-05, 3.04616736e-05, 3.02280643e-05, 2.43601618e-05, 2.10695402e-05, 2.20240316e-05, + 2.40365186e-05, 2.43738837e-05, 2.50018219e-05, 2.79138182e-05, 3.02836630e-05, 2.99086572e-05, + 2.94562212e-05, 3.04568678e-05, 2.24131643e-05, 1.91411806e-05, 1.95001790e-05, 2.30930923e-05, + 2.51872854e-05, 2.56647314e-05, 2.86681854e-05, 3.14763222e-05, 3.23222999e-05, 1.94701013e-05, + 1.40843969e-05, 1.61602138e-05, 2.44648639e-05, 3.02087651e-05, 3.07655061e-05, 3.07093427e-05, + 3.12469508e-05, 3.13605337e-05, 2.50854435e-05, 1.89918613e-05, 1.72295752e-05, 2.22311323e-05, + 2.67665487e-05, 2.66671591e-05, 2.62454441e-05, 2.84557906e-05, 3.09368769e-05, 2.98524815e-05, + 2.50657450e-05, 1.73630518e-05, 1.40863057e-05, 1.72814289e-05, 2.41076614e-05, 3.06436869e-05, + 3.26756733e-05, 3.19281126e-05, 2.00071792e-05, 1.55783366e-05, 1.67000575e-05, 2.18784432e-05, + 2.81500963e-05, 3.23065523e-05, 3.32099438e-05, 3.18057216e-05, 1.82492860e-05, 1.45882041e-05, + 1.65899767e-05, 2.25593027e-05, 3.02682390e-05, 3.33256944e-05, 3.22238207e-05, 3.10529209e-05, + 1.73883117e-05, 1.30291810e-05, 1.79369943e-05, 2.46291470e-05, 2.75365665e-05, 2.87939376e-05, + 3.01354177e-05, 2.17610199e-05, 1.87489298e-05, 1.81953160e-05, 1.96865787e-05, 2.50537500e-05, + 3.02722644e-05, 3.13259892e-05, 3.08120499e-05, 2.26387487e-05, 1.96509253e-05, 1.98274660e-05, + 2.20726991e-05, 2.40244759e-05, 2.57521399e-05, 2.91298034e-05, 3.06597895e-05, 2.34702376e-05, + 1.95389709e-05, 1.96646829e-05, 2.10998342e-05, 2.23374092e-05, 2.54780358e-05, 2.90490779e-05, + 3.09566578e-05, 3.08687504e-05, 2.57265173e-05, 1.90764747e-05, 1.36302910e-05, 1.47962634e-05, + 2.10854846e-05, 2.91820840e-05, 3.15148820e-05, 2.89691326e-05, 2.05640435e-05, 1.75209383e-05, + 2.00713854e-05, 2.47105479e-05, 2.59417979e-05, 2.71558247e-05, 2.98593631e-05, 3.06397826e-05, + 2.58927440e-05, 2.03521369e-05, 1.70070535e-05, 2.01724801e-05, 2.43559696e-05, 2.82421912e-05, + 3.05056285e-05, 3.05712878e-05, 2.37599070e-05, 1.95632906e-05, 1.89462864e-05, 2.18426847e-05, + 2.52510011e-05, 2.78932757e-05, 3.06736607e-05, 2.99284722e-05, 2.86368207e-05, 2.39621177e-05, + 1.75570992e-05, 1.49111769e-05, 1.94637569e-05, 2.64094547e-05, 3.02294296e-05, 3.23329184e-05, + 3.25263006e-05, 3.12868673e-05, 2.20227370e-05, 1.89788898e-05, 1.87087424e-05, 2.28499796e-05, + 2.80432587e-05, 2.75001329e-05, 2.90194325e-05, 3.16118712e-05, 2.23137448e-05, 1.95154752e-05, + 1.93853988e-05, 2.04170682e-05, 2.27910300e-05, 2.77939789e-05, 3.01526419e-05, 2.93366675e-05, + 2.02234870e-05, 1.57177457e-05, 1.77003179e-05, 2.44889794e-05, 3.05399450e-05, 3.06911477e-05, + 2.98816670e-05, 2.42215429e-05, 2.00978269e-05, 1.77138064e-05, 1.89205155e-05, 2.32597687e-05, + 2.66849044e-05, 2.90077887e-05, 3.13112143e-05, 2.49658440e-05, 2.36571847e-05, 2.32236480e-05, + 2.44785232e-05, 2.56593548e-05, 2.56299874e-05, 2.53138979e-05, 2.51348272e-05, 2.49183049e-05, + 2.49482318e-05, 2.43206906e-05, 2.44991946e-05, 2.50608516e-05, 2.51433529e-05, 2.51820333e-05, + 2.55834380e-05, 2.54968266e-05, 2.52284360e-05, 2.50555873e-05, 2.49372512e-05, 2.49186011e-05, + 2.40085652e-05, 2.38952958e-05, 2.50669676e-05, 2.54947056e-05, 2.51641432e-05, 2.50714211e-05, + 2.49346561e-05, 2.48225603e-05, 2.40740373e-05, 2.16278500e-05, 2.26943813e-05, 2.57298853e-05, + 2.61443024e-05, 2.53893718e-05, 2.48826310e-05, 2.48319652e-05, 2.48496575e-05, 2.59880498e-05, + 2.45538723e-05, 2.33961068e-05, 2.51161794e-05, 2.56559433e-05, 2.50603754e-05, 2.46360111e-05, + 2.47461233e-05, 2.47186302e-05, 2.58371114e-05, 2.58696474e-05, 2.33472180e-05, 2.13622440e-05, + 2.31515090e-05, 2.51748631e-05, 2.52193020e-05, 2.46424184e-05, 2.46695427e-05, 2.39958998e-05, + 2.25689144e-05, 2.32588523e-05, 2.51869683e-05, 2.58470960e-05, 2.52905110e-05, 2.48616957e-05, + 2.48329009e-05, 2.32038927e-05, 2.20424571e-05, 2.33381761e-05, 2.52850430e-05, 2.57035472e-05, + 2.49099615e-05, 2.46980935e-05, 2.48464830e-05, 2.34022699e-05, 2.11728708e-05, 2.40819266e-05, + 2.60464741e-05, 2.55630894e-05, 2.46823297e-05, 2.45760132e-05, 2.49309712e-05, 2.44119049e-05, + 2.40272353e-05, 2.40415325e-05, 2.48456093e-05, 2.49988756e-05, 2.48495572e-05, 2.48765523e-05, + 2.51137464e-05, 2.45929143e-05, 2.45870296e-05, 2.50652508e-05, 2.49710249e-05, 2.46912660e-05, + 2.48499827e-05, 2.48927180e-05, 2.52424933e-05, 2.43075775e-05, 2.43067014e-05, 2.49246397e-05, + 2.49771566e-05, 2.49874386e-05, 2.49003330e-05, 2.48351690e-05, 2.48699098e-05, 2.65871201e-05, + 2.52069933e-05, 2.15869788e-05, 2.16937531e-05, 2.37521709e-05, 2.46269166e-05, 2.46708422e-05, + 2.45182792e-05, 2.46219316e-05, 2.39803432e-05, 2.48307035e-05, 2.56850826e-05, 2.54429855e-05, + 2.50473918e-05, 2.49784487e-05, 2.49510382e-05, 2.65189091e-05, 2.50681270e-05, 2.31876553e-05, + 2.42768459e-05, 2.51045102e-05, 2.50239567e-05, 2.47980094e-05, 2.49386280e-05, 2.51899952e-05, + 2.43788926e-05, 2.41754900e-05, 2.51935117e-05, 2.56674432e-05, 2.53773110e-05, 2.50205891e-05, + 2.48373559e-05, 2.46494017e-05, 2.56354793e-05, 2.37142799e-05, 2.19423485e-05, 2.39303729e-05, + 2.55737365e-05, 2.54518209e-05, 2.48363898e-05, 2.46851820e-05, 2.48171692e-05, 2.55934875e-05, + 2.50991351e-05, 2.44743760e-05, 2.51728413e-05, 2.51513380e-05, 2.42140069e-05, 2.42218725e-05, + 2.45267798e-05, 2.47315124e-05, 2.46688250e-05, 2.47714101e-05, 2.46881666e-05, 2.48533275e-05, + 2.54149929e-05, 2.51888274e-05, 2.48370499e-05, 2.51915648e-05, 2.34539787e-05, 2.36067874e-05, + 2.48477847e-05, 2.49633778e-05, 2.49134400e-05, 2.48287050e-05, 2.57294887e-05, 2.50006790e-05, + 2.38426440e-05, 2.39319082e-05, 2.45874833e-05, 2.47093412e-05, 2.48477627e-05, 2.48982748e-05, + 2.46511890e-05, 2.20874188e-05, 2.14070553e-05, 2.32247520e-05, 2.54622956e-05, 2.65296842e-05, + 2.68004619e-05, 2.66343829e-05, 2.63327860e-05, 2.48034140e-05, 2.33459306e-05, 2.37582960e-05, + 2.48394544e-05, 2.50116370e-05, 2.52131218e-05, 2.64132849e-05, 2.69800211e-05, 2.65803869e-05, + 2.62664483e-05, 2.64177026e-05, 2.42863922e-05, 2.25776554e-05, 2.25462160e-05, 2.46090309e-05, + 2.55921641e-05, 2.53656951e-05, 2.60667329e-05, 2.67053823e-05, 2.68280003e-05, 2.27196513e-05, + 1.91435229e-05, 2.06097546e-05, 2.56549399e-05, 2.76732948e-05, 2.69999650e-05, 2.64295581e-05, + 2.65271920e-05, 2.65790433e-05, 2.60919612e-05, 2.30959615e-05, 2.15341993e-05, 2.44468549e-05, + 2.61812021e-05, 2.55180627e-05, 2.49588997e-05, 2.56600009e-05, 2.63154821e-05, 2.72310591e-05, + 2.59600644e-05, 2.15151026e-05, 1.88896980e-05, 2.13031910e-05, 2.49770791e-05, 2.67785007e-05, + 2.67333674e-05, 2.65453264e-05, 2.27654688e-05, 2.03632694e-05, 2.12821249e-05, 2.44339102e-05, + 2.67642124e-05, 2.73408023e-05, 2.71343059e-05, 2.66889426e-05, 2.15702279e-05, 1.96455349e-05, + 2.13367894e-05, 2.47039833e-05, 2.72029258e-05, 2.72227083e-05, 2.66623924e-05, 2.64876836e-05, + 2.15753612e-05, 1.84987959e-05, 2.23776688e-05, 2.60352369e-05, 2.62887011e-05, 2.56831708e-05, + 2.59365541e-05, 2.41396609e-05, 2.28957214e-05, 2.23808166e-05, 2.27369823e-05, 2.48724072e-05, + 2.64327528e-05, 2.65690332e-05, 2.64520272e-05, 2.45449357e-05, 2.32888229e-05, 2.33241360e-05, + 2.43550060e-05, 2.47423698e-05, 2.48895545e-05, 2.59546159e-05, 2.64265247e-05, 2.48870128e-05, + 2.29722137e-05, 2.30005741e-05, 2.39730519e-05, 2.43285282e-05, 2.51306076e-05, 2.59866983e-05, + 2.64479687e-05, 2.64608725e-05, 2.69090394e-05, 2.37850771e-05, 1.90131357e-05, 1.93523571e-05, + 2.27722539e-05, 2.57292767e-05, 2.64279192e-05, 2.55551335e-05, 2.35336678e-05, 2.21823847e-05, + 2.36310803e-05, 2.56708276e-05, 2.57343560e-05, 2.56335915e-05, 2.62949492e-05, 2.64843824e-05, + 2.68795557e-05, 2.39421021e-05, 2.12786876e-05, 2.30890069e-05, 2.49662651e-05, 2.58998794e-05, + 2.62801078e-05, 2.64514932e-05, 2.49049539e-05, 2.30503270e-05, 2.27014584e-05, 2.44319604e-05, + 2.57926048e-05, 2.61851989e-05, 2.65698248e-05, 2.61613973e-05, 2.56054523e-05, 2.54256795e-05, + 2.19237752e-05, 1.96154744e-05, 2.25731563e-05, 2.59976817e-05, 2.69151990e-05, 2.68463423e-05, + 2.67365790e-05, 2.65224436e-05, 2.48939833e-05, 2.36512630e-05, 2.29499676e-05, 2.46589974e-05, + 2.59827812e-05, 2.48413762e-05, 2.52526223e-05, 2.62985734e-05, 2.40683083e-05, 2.33347397e-05, + 2.34093453e-05, 2.35666599e-05, 2.43117968e-05, 2.61988517e-05, 2.66059123e-05, 2.59974516e-05, + 2.40390309e-05, 2.12644185e-05, 2.18482926e-05, 2.47309153e-05, 2.64695873e-05, 2.64579617e-05, + 2.61390323e-05, 2.55918320e-05, 2.38121549e-05, 2.20872055e-05, 2.24497875e-05, 2.41521670e-05, + 2.51506548e-05, 2.59188480e-05, 2.66180769e-05, 2.45268309e-05, 3.67493916e-05, 4.00572082e-05, + 3.33896662e-05, 2.42651041e-05, 1.71326336e-05, 1.40548952e-05, 1.38462196e-05, 1.40257712e-05, + 2.31601938e-05, 3.00882047e-05, 2.78768788e-05, 2.38682271e-05, 2.32507029e-05, 2.20790818e-05, + 1.74634657e-05, 1.42265466e-05, 1.45701407e-05, 1.50646034e-05, 1.37585298e-05, 2.72526378e-05, + 3.51801093e-05, 3.40369486e-05, 2.58347575e-05, 2.19110957e-05, 2.08716698e-05, 1.61285376e-05, + 1.25837357e-05, 1.16291703e-05, 3.42604010e-05, 5.20120406e-05, 4.42289738e-05, 2.33961201e-05, + 1.45876853e-05, 1.35991658e-05, 1.34331336e-05, 1.27921324e-05, 1.26733157e-05, 2.23477380e-05, + 3.60029558e-05, 4.08929514e-05, 2.77923730e-05, 1.92742735e-05, 1.91202681e-05, 1.95638299e-05, + 1.62505037e-05, 1.30902734e-05, 1.49132794e-05, 2.23271278e-05, 4.03877755e-05, 5.17227562e-05, + 4.05077083e-05, 2.37939142e-05, 1.36675644e-05, 1.11907387e-05, 1.19732029e-05, 3.26742671e-05, + 4.64185013e-05, 4.26801804e-05, 2.86619629e-05, 1.72403072e-05, 1.18433404e-05, 1.07587179e-05, + 1.21783676e-05, 3.72934895e-05, 5.01303282e-05, 4.31469132e-05, 2.71418502e-05, 1.43349050e-05, + 1.06669854e-05, 1.16759156e-05, 1.30185752e-05, 4.03450713e-05, 5.66922728e-05, 3.90024136e-05, + 2.32343181e-05, 1.80194540e-05, 1.57495995e-05, 1.39665448e-05, 2.87879533e-05, 3.66486211e-05, + 3.81256665e-05, 3.36126112e-05, 2.17825359e-05, 1.40109902e-05, 1.27117970e-05, 1.33102782e-05, + 2.68626776e-05, 3.41008263e-05, 3.35975259e-05, 2.81307182e-05, 2.38376956e-05, 2.04376391e-05, + 1.53882437e-05, 1.34961903e-05, 2.51363565e-05, 3.42296286e-05, 3.38684336e-05, 3.04161585e-05, + 2.74626267e-05, 2.10995875e-05, 1.55220501e-05, 1.31234293e-05, 1.32413191e-05, 2.14507787e-05, + 3.61187006e-05, 5.41208901e-05, 4.88601726e-05, 2.96101688e-05, 1.52005664e-05, 1.24193144e-05, + 1.54232834e-05, 3.16104458e-05, 4.03203912e-05, 3.30738034e-05, 2.29011072e-05, 2.05427037e-05, + 1.83363874e-05, 1.45114934e-05, 1.35475866e-05, 2.11323185e-05, 3.24523776e-05, 4.15102851e-05, + 3.24269494e-05, 2.32626997e-05, 1.67023577e-05, 1.36327509e-05, 1.36227715e-05, 2.45053341e-05, + 3.42090232e-05, 3.58873419e-05, 2.87509859e-05, 2.18852728e-05, 1.73919971e-05, 1.35404069e-05, + 1.43547851e-05, 1.59462197e-05, 2.43419107e-05, 4.00084789e-05, 4.86179677e-05, 3.41699855e-05, + 1.98188646e-05, 1.42733052e-05, 1.16242532e-05, 1.13599937e-05, 1.27404640e-05, 2.85454139e-05, + 3.63533744e-05, 3.68119134e-05, 2.64286447e-05, 1.70561533e-05, 1.73195193e-05, 1.51884790e-05, + 1.22452861e-05, 2.73598454e-05, 3.45369159e-05, 3.49757184e-05, 3.20454906e-05, 2.63620701e-05, + 1.75581972e-05, 1.42477008e-05, 1.51092511e-05, 3.28685464e-05, 4.65462558e-05, 3.94424032e-05, + 2.28482328e-05, 1.36718363e-05, 1.34691953e-05, 1.44088292e-05, 2.38724686e-05, 3.31027715e-05, + 3.95740442e-05, 3.57871957e-05, 2.51698787e-05, 1.88880780e-05, 1.55497886e-05, 1.27508328e-05, + 2.56916178e-05, 3.19600853e-05, 3.34052191e-05, 2.96347161e-05, 2.45185568e-05, 2.04868169e-05, + 1.84493498e-05, 1.84639810e-05, 1.88619192e-05, 2.50513854e-05, 2.89668448e-05, 2.78672059e-05, + 2.52337351e-05, 2.48063040e-05, 2.41421321e-05, 2.07755665e-05, 1.83948726e-05, 1.89830590e-05, + 1.95921960e-05, 1.86032269e-05, 2.69301361e-05, 3.09426273e-05, 3.08923747e-05, 2.61156990e-05, + 2.36050138e-05, 2.34934684e-05, 2.04233238e-05, 1.75161095e-05, 1.66842687e-05, 3.06061608e-05, + 3.76833505e-05, 3.50031360e-05, 2.40125438e-05, 1.79836530e-05, 1.79699928e-05, 1.83682454e-05, + 1.78233896e-05, 1.76910533e-05, 2.31315586e-05, 3.00557541e-05, 3.31441198e-05, 2.68100235e-05, + 2.18704845e-05, 2.25603310e-05, 2.34228215e-05, 2.09143097e-05, 1.82272214e-05, 1.85811168e-05, + 2.32886409e-05, 3.31866218e-05, 3.83744850e-05, 3.36197144e-05, 2.50258482e-05, 1.82139031e-05, + 1.64057605e-05, 1.71883178e-05, 3.03436009e-05, 3.54059495e-05, 3.36211248e-05, 2.70009451e-05, + 2.02970047e-05, 1.64351647e-05, 1.57334754e-05, 1.72261923e-05, 3.29844929e-05, 3.66979403e-05, + 3.34834988e-05, 2.62921885e-05, 1.82589082e-05, 1.55892403e-05, 1.68566529e-05, 1.80224381e-05, + 3.30642678e-05, 3.85244155e-05, 3.14730051e-05, 2.34768193e-05, 2.11805607e-05, 2.05934533e-05, + 1.91932951e-05, 2.74736140e-05, 3.04479665e-05, 3.14568713e-05, 3.05080092e-05, 2.44657600e-05, + 1.87591777e-05, 1.77280479e-05, 1.82618794e-05, 2.64606974e-05, 2.95900098e-05, 2.94838880e-05, + 2.70170559e-05, 2.53550039e-05, 2.38973980e-05, 2.00988527e-05, 1.84148933e-05, 2.55400213e-05, + 3.01559187e-05, 3.00721279e-05, 2.80144819e-05, 2.69149708e-05, 2.38739818e-05, 2.01480644e-05, + 1.81329047e-05, 1.82052701e-05, 2.18535470e-05, 2.88257496e-05, 3.76622525e-05, 3.75655051e-05, + 2.98080761e-05, 2.02078213e-05, 1.76316848e-05, 2.05235315e-05, 2.89007831e-05, 3.18450590e-05, + 2.89092884e-05, 2.38385264e-05, 2.29166617e-05, 2.20566175e-05, 1.92162803e-05, 1.83980179e-05, + 2.17820959e-05, 2.83261017e-05, 3.36626021e-05, 2.97556502e-05, 2.48701076e-05, 2.09184592e-05, + 1.86431159e-05, 1.84796019e-05, 2.53375857e-05, 3.00165542e-05, 3.07667256e-05, 2.70203196e-05, + 2.33469684e-05, 2.09818440e-05, 1.83157961e-05, 1.92413955e-05, 2.07917292e-05, 2.45888395e-05, + 3.23643324e-05, 3.69523433e-05, 3.08582779e-05, 2.23117119e-05, 1.84839031e-05, 1.66654723e-05, + 1.65419938e-05, 1.77896426e-05, 2.62886055e-05, 2.90693624e-05, 3.03539329e-05, 2.61931242e-05, + 2.10223290e-05, 2.24118100e-05, 2.06822360e-05, 1.76093995e-05, 2.72794442e-05, 2.95439405e-05, + 2.94420738e-05, 2.89028757e-05, 2.66780013e-05, 2.10512784e-05, 1.87535698e-05, 1.98838183e-05, + 2.82057027e-05, 3.33556163e-05, 3.25137830e-05, 2.50398878e-05, 1.84967011e-05, 1.83676870e-05, + 1.92981854e-05, 2.42356221e-05, 2.86066100e-05, 3.20414163e-05, 3.12218220e-05, 2.65808921e-05, + 2.28769311e-05, 2.02330744e-05, 1.77140530e-05, 2.52313931e-05, 2.36615977e-05, 2.31937680e-05, + 2.32603244e-05, 2.38165880e-05, 2.51063835e-05, 2.56570957e-05, 2.60201766e-05, 2.65339072e-05, + 2.56328027e-05, 2.48307365e-05, 2.52146371e-05, 2.52035660e-05, 2.51834103e-05, 2.53772803e-05, + 2.51903757e-05, 2.52809051e-05, 2.59130452e-05, 2.63444411e-05, 2.64469969e-05, 2.45113989e-05, + 2.35514691e-05, 2.42485744e-05, 2.46336238e-05, 2.47366923e-05, 2.56664723e-05, 2.63538629e-05, + 2.61830520e-05, 2.61108363e-05, 2.37776469e-05, 2.12339584e-05, 2.24984708e-05, 2.38910955e-05, + 2.39390414e-05, 2.54147332e-05, 2.65079112e-05, 2.64713890e-05, 2.63991825e-05, 2.35952276e-05, + 2.20853908e-05, 2.24745314e-05, 2.39148744e-05, 2.48561531e-05, 2.61801751e-05, 2.70718559e-05, + 2.70892505e-05, 2.68032854e-05, 2.46213531e-05, 2.38481629e-05, 2.27920673e-05, 2.19188631e-05, + 2.31536506e-05, 2.49756283e-05, 2.58015370e-05, 2.63302618e-05, 2.65848036e-05, 2.45651720e-05, + 2.17937324e-05, 2.19950215e-05, 2.34779816e-05, 2.46340897e-05, 2.51575012e-05, 2.56321641e-05, + 2.62864462e-05, 2.44090630e-05, 2.12272678e-05, 2.16305463e-05, 2.37663819e-05, 2.48472542e-05, + 2.54782635e-05, 2.64091755e-05, 2.64963973e-05, 2.26946710e-05, 2.00397278e-05, 2.18451315e-05, + 2.32681911e-05, 2.51945774e-05, 2.72266239e-05, 2.73038866e-05, 2.39763793e-05, 2.21211309e-05, + 2.23182357e-05, 2.41017095e-05, 2.61845896e-05, 2.63504615e-05, 2.64100318e-05, 2.64957089e-05, + 2.42177388e-05, 2.27474765e-05, 2.29532046e-05, 2.39117388e-05, 2.54076839e-05, 2.68007636e-05, + 2.68290153e-05, 2.64979401e-05, 2.44615379e-05, 2.32950145e-05, 2.34376357e-05, 2.34230111e-05, + 2.43180682e-05, 2.60122042e-05, 2.67218525e-05, 2.65470025e-05, 2.64955390e-05, 2.25460226e-05, + 2.07166571e-05, 2.03624449e-05, 2.25298495e-05, 2.62581817e-05, 2.73264003e-05, 2.67295636e-05, + 2.75901260e-05, 2.36282355e-05, 2.15080596e-05, 2.26448711e-05, 2.41058764e-05, 2.51182426e-05, + 2.63005217e-05, 2.64642539e-05, 2.63768482e-05, 2.27457731e-05, 2.23858347e-05, 2.26467194e-05, + 2.40558634e-05, 2.52649594e-05, 2.64562626e-05, 2.67385440e-05, 2.64191345e-05, 2.47516013e-05, + 2.31530257e-05, 2.29166679e-05, 2.34343785e-05, 2.43725532e-05, 2.56445447e-05, 2.62195419e-05, + 2.67634826e-05, 2.73071347e-05, 2.38464364e-05, 2.21861551e-05, 2.21166519e-05, 2.41204945e-05, + 2.49552225e-05, 2.53853830e-05, 2.60779271e-05, 2.63086014e-05, 2.64908784e-05, 2.26706859e-05, + 2.08414102e-05, 2.19274494e-05, 2.42265866e-05, 2.61604431e-05, 2.82892161e-05, 2.82668935e-05, + 2.70032218e-05, 2.48803017e-05, 2.24215653e-05, 2.20404168e-05, 2.33272473e-05, 2.49340305e-05, + 2.55518603e-05, 2.59611009e-05, 2.68403361e-05, 2.19788748e-05, 1.99351845e-05, 2.26475586e-05, + 2.59318966e-05, 2.63726481e-05, 2.64458480e-05, 2.67899522e-05, 2.37716319e-05, 2.22829614e-05, + 2.21018650e-05, 2.34700884e-05, 2.58778487e-05, 2.69991337e-05, 2.68421163e-05, 2.63110707e-05, + 2.32480022e-05, 1.72720262e-05, 1.60525800e-05, 1.81825485e-05, 2.24591569e-05, 2.81833348e-05, + 3.16091308e-05, 3.21548879e-05, 3.23915967e-05, 2.42911668e-05, 2.03350583e-05, 2.15404983e-05, + 2.35972415e-05, 2.39396129e-05, 2.47802665e-05, 2.79712122e-05, 3.10976650e-05, 3.12720457e-05, + 3.11153682e-05, 3.26218291e-05, 2.14094212e-05, 1.77257268e-05, 1.84876254e-05, 2.21775903e-05, + 2.44427461e-05, 2.57677932e-05, 3.00733078e-05, 3.38112666e-05, 3.50171364e-05, 1.81587165e-05, + 1.24171445e-05, 1.46371490e-05, 2.29834997e-05, 2.95511692e-05, 3.19065245e-05, 3.30544556e-05, + 3.38051003e-05, 3.38909486e-05, 2.33767508e-05, 1.66806266e-05, 1.54768038e-05, 2.07940748e-05, + 2.63042419e-05, 2.73964620e-05, 2.76960399e-05, 3.05350592e-05, 3.37254969e-05, 2.98205439e-05, + 2.35676442e-05, 1.57670756e-05, 1.27485678e-05, 1.59076024e-05, 2.34893657e-05, 3.21679696e-05, + 3.58511549e-05, 3.49794038e-05, 1.91563450e-05, 1.38110616e-05, 1.47860992e-05, 2.01441471e-05, + 2.77173712e-05, 3.38295340e-05, 3.58251198e-05, 3.44315509e-05, 1.74723166e-05, 1.27822215e-05, + 1.44987597e-05, 2.09992567e-05, 3.06061875e-05, 3.58136201e-05, 3.52290115e-05, 3.35454497e-05, + 1.57316349e-05, 1.11128748e-05, 1.56785826e-05, 2.26425648e-05, 2.75205524e-05, 3.11316950e-05, + 3.31067334e-05, 2.03911513e-05, 1.65028135e-05, 1.61689652e-05, 1.85609915e-05, 2.55189025e-05, + 3.22524014e-05, 3.38518740e-05, 3.31903888e-05, 2.14123983e-05, 1.76546956e-05, 1.79402510e-05, + 2.06405266e-05, 2.37481126e-05, 2.68605034e-05, 3.11786917e-05, 3.29712534e-05, 2.24255838e-05, + 1.79099025e-05, 1.81119148e-05, 1.93874161e-05, 2.11926210e-05, 2.58544088e-05, 3.09576744e-05, + 3.34612212e-05, 3.32731851e-05, 2.31442935e-05, 1.58949165e-05, 1.16783314e-05, 1.35883991e-05, + 2.13452692e-05, 3.17708474e-05, 3.45134049e-05, 3.17493835e-05, 1.90407742e-05, 1.51525368e-05, + 1.79498539e-05, 2.34121852e-05, 2.56022786e-05, 2.81016984e-05, 3.17973432e-05, 3.28062192e-05, + 2.34852857e-05, 1.80205774e-05, 1.53951362e-05, 1.89712310e-05, 2.39868518e-05, 2.96212110e-05, + 3.30174942e-05, 3.27549818e-05, 2.29487800e-05, 1.78399246e-05, 1.71603515e-05, 2.00795435e-05, + 2.42035307e-05, 2.83850914e-05, 3.26783289e-05, 3.22179084e-05, 3.10001090e-05, 2.24383288e-05, + 1.55741661e-05, 1.34686376e-05, 1.83726909e-05, 2.59861816e-05, 3.11378832e-05, 3.49932761e-05, + 3.55842771e-05, 3.38875057e-05, 1.96959067e-05, 1.58959655e-05, 1.63507986e-05, 2.16264337e-05, + 2.90750199e-05, 3.04419068e-05, 3.25284153e-05, 3.49887981e-05, 2.15836595e-05, 1.73300856e-05, + 1.69781118e-05, 1.87062110e-05, 2.21013430e-05, 2.81734827e-05, 3.16590133e-05, 3.14742027e-05, + 1.76407107e-05, 1.29380627e-05, 1.59590870e-05, 2.46770445e-05, 3.26580048e-05, 3.29580549e-05, + 3.21804963e-05, 2.26398570e-05, 1.77345497e-05, 1.56508358e-05, 1.74829295e-05, 2.33072261e-05, + 2.81702451e-05, 3.10262425e-05, 3.37145352e-05, 2.37961695e-05, 1.87654088e-05, 1.76738772e-05, + 1.98133168e-05, 2.36080647e-05, 2.78433835e-05, 3.01501181e-05, 3.04044471e-05, 3.03925600e-05, + 2.45440749e-05, 2.13275313e-05, 2.22970093e-05, 2.41058836e-05, 2.44044916e-05, 2.50417787e-05, + 2.76520192e-05, 2.99203566e-05, 2.98260228e-05, 2.95676158e-05, 3.05794296e-05, 2.24239751e-05, + 1.92585427e-05, 1.97697526e-05, 2.30693380e-05, 2.49857958e-05, 2.57501785e-05, 2.88165925e-05, + 3.14665129e-05, 3.22741876e-05, 1.96096609e-05, 1.43256082e-05, 1.64013638e-05, 2.40407761e-05, + 2.92752499e-05, 3.04398004e-05, 3.08521162e-05, 3.13655978e-05, 3.14465173e-05, 2.44872554e-05, + 1.87106104e-05, 1.73128320e-05, 2.20725065e-05, 2.64660984e-05, 2.68635589e-05, 2.67882518e-05, + 2.88989768e-05, 3.12015222e-05, 2.92329298e-05, 2.45605444e-05, 1.75114454e-05, 1.44838235e-05, + 1.75358958e-05, 2.40934594e-05, 3.04879835e-05, 3.27292464e-05, 3.20925487e-05, 2.03072715e-05, + 1.57285154e-05, 1.67345337e-05, 2.16236228e-05, 2.76526936e-05, 3.18237637e-05, 3.29430043e-05, + 3.18381867e-05, 1.87122822e-05, 1.47509591e-05, 1.65459401e-05, 2.23135710e-05, 2.97212106e-05, + 3.29865586e-05, 3.23103527e-05, 3.11849371e-05, 1.75074105e-05, 1.31654713e-05, 1.77456622e-05, + 2.39664001e-05, 2.73035581e-05, 2.92785417e-05, 3.06193758e-05, 2.16779514e-05, 1.85139379e-05, + 1.80970810e-05, 1.98918568e-05, 2.53678387e-05, 3.03592092e-05, 3.14170939e-05, 3.09477193e-05, + 2.25300332e-05, 1.94682396e-05, 1.96810470e-05, 2.19319731e-05, 2.41632598e-05, 2.62297733e-05, + 2.94470525e-05, 3.07993275e-05, 2.33493558e-05, 1.95310820e-05, 1.96815726e-05, 2.09266947e-05, + 2.22951370e-05, 2.56997949e-05, 2.93267223e-05, 3.11117772e-05, 3.10033422e-05, 2.46665164e-05, + 1.83778157e-05, 1.37420565e-05, 1.52347932e-05, 2.17632665e-05, 2.96945246e-05, 3.17435058e-05, + 2.95904132e-05, 2.05216137e-05, 1.73004244e-05, 1.97995193e-05, 2.43349981e-05, 2.58080509e-05, + 2.73653664e-05, 3.00055869e-05, 3.07285496e-05, 2.48879666e-05, 1.99620725e-05, 1.71669799e-05, + 2.03053482e-05, 2.44159364e-05, 2.84507517e-05, 3.07493647e-05, 3.06794630e-05, 2.37053130e-05, + 1.95110404e-05, 1.89099455e-05, 2.15785041e-05, 2.49138996e-05, 2.78086657e-05, 3.06949727e-05, + 3.01953110e-05, 2.91577170e-05, 2.35790289e-05, 1.75158427e-05, 1.52367334e-05, 1.97015020e-05, + 2.61760973e-05, 2.99127497e-05, 3.22698686e-05, 3.25687274e-05, 3.14134851e-05, 2.14892163e-05, + 1.83337732e-05, 1.84241915e-05, 2.27201807e-05, 2.81483002e-05, 2.84252458e-05, 2.99027063e-05, + 3.19597175e-05, 2.24521326e-05, 1.92560463e-05, 1.90325809e-05, 2.03032142e-05, 2.28963044e-05, + 2.76801497e-05, 3.00808524e-05, 2.96516049e-05, 1.97275728e-05, 1.53735827e-05, 1.77630147e-05, + 2.47625806e-05, 3.06292573e-05, 3.08080078e-05, 3.01605364e-05, 2.37831498e-05, 1.97130542e-05, + 1.76265596e-05, 1.90436303e-05, 2.36223827e-05, 2.71770928e-05, 2.93344688e-05, 3.13595213e-05, + 2.52927485e-05, 2.66858157e-05, 2.68447342e-05, 2.69722211e-05, 2.60531187e-05, 2.38470541e-05, + 2.24623695e-05, 2.22018609e-05, 2.20397988e-05, 2.48922804e-05, 2.59560429e-05, 2.56182204e-05, + 2.52233331e-05, 2.51474215e-05, 2.48576854e-05, 2.39034610e-05, 2.27152866e-05, 2.25526473e-05, + 2.25393311e-05, 2.19661718e-05, 2.59709637e-05, 2.67858961e-05, 2.63690369e-05, 2.57721072e-05, + 2.51737625e-05, 2.44843494e-05, 2.29102892e-05, 2.15428386e-05, 2.10749705e-05, 2.66541867e-05, + 2.70602272e-05, 2.70113095e-05, 2.58872946e-05, 2.35340924e-05, 2.23788127e-05, 2.17952625e-05, + 2.15143060e-05, 2.14892224e-05, 2.58864976e-05, 2.77087468e-05, 2.72645467e-05, 2.63591005e-05, + 2.45606801e-05, 2.38421096e-05, 2.35017446e-05, 2.26017286e-05, 2.15058840e-05, 2.33196493e-05, + 2.57393669e-05, 2.70857585e-05, 2.66170546e-05, 2.68452722e-05, 2.53379724e-05, 2.22263412e-05, + 2.07294944e-05, 2.10509882e-05, 2.61753549e-05, 2.72920926e-05, 2.74676282e-05, 2.66788260e-05, + 2.41227212e-05, 2.16264566e-05, 2.07778358e-05, 2.12908178e-05, 2.62094293e-05, 2.72929739e-05, + 2.76812302e-05, 2.63945225e-05, 2.29724369e-05, 2.07890819e-05, 2.09685690e-05, 2.16106000e-05, + 2.71515642e-05, 2.72876869e-05, 2.77786059e-05, 2.62209906e-05, 2.40598540e-05, 2.23717865e-05, + 2.16657229e-05, 2.63899202e-05, 2.76726815e-05, 2.74997516e-05, 2.64578933e-05, 2.43830516e-05, + 2.21183187e-05, 2.15030900e-05, 2.17454661e-05, 2.61072639e-05, 2.72968277e-05, 2.71653770e-05, + 2.63853656e-05, 2.51083474e-05, 2.38196915e-05, 2.24303798e-05, 2.18279234e-05, 2.57935502e-05, + 2.69524048e-05, 2.68641071e-05, 2.68033315e-05, 2.60988974e-05, 2.43487884e-05, 2.25280010e-05, + 2.16365662e-05, 2.17141331e-05, 2.63274523e-05, 2.86278197e-05, 2.74128299e-05, 2.65393974e-05, + 2.51332479e-05, 2.21334491e-05, 2.12161187e-05, 2.20925424e-05, 2.67179683e-05, 2.79434870e-05, + 2.73555496e-05, 2.56892497e-05, 2.47062728e-05, 2.35870608e-05, 2.22699995e-05, 2.19061401e-05, + 2.61459872e-05, 2.75105275e-05, 2.71133720e-05, 2.64758964e-05, 2.51049824e-05, 2.30456318e-05, + 2.17785113e-05, 2.19198741e-05, 2.55550817e-05, 2.70411122e-05, 2.71738735e-05, 2.67106684e-05, + 2.53688034e-05, 2.36529299e-05, 2.19753471e-05, 2.20690914e-05, 2.24006786e-05, 2.60461644e-05, + 2.75040616e-05, 2.68460227e-05, 2.64458455e-05, 2.46357810e-05, 2.26843571e-05, 2.10869048e-05, + 2.08363299e-05, 2.14805941e-05, 2.71628916e-05, 2.85383102e-05, 2.77965727e-05, 2.60626990e-05, + 2.32976176e-05, 2.23678945e-05, 2.17065870e-05, 2.10081430e-05, 2.57691821e-05, 2.75046524e-05, + 2.77499092e-05, 2.69121897e-05, 2.56542606e-05, 2.37478583e-05, 2.23990416e-05, 2.23238779e-05, + 2.77799311e-05, 2.85986466e-05, 2.72289407e-05, 2.46872572e-05, 2.19627085e-05, 2.18396979e-05, + 2.20785599e-05, 2.60249797e-05, 2.75869239e-05, 2.75815944e-05, 2.68271476e-05, 2.50158332e-05, + 2.33816940e-05, 2.24814615e-05, 2.15667637e-05, 2.52413340e-05, 2.54047689e-05, 2.52863587e-05, + 2.57658690e-05, 2.56938455e-05, 2.45797900e-05, 2.37289309e-05, 2.35632222e-05, 2.34626329e-05, + 2.50567034e-05, 2.53674515e-05, 2.52822142e-05, 2.52265904e-05, 2.52051434e-05, 2.50742948e-05, + 2.46103003e-05, 2.38879051e-05, 2.37898305e-05, 2.37833012e-05, 2.34131158e-05, 2.55180078e-05, + 2.55563290e-05, 2.53864572e-05, 2.54670300e-05, 2.52669135e-05, 2.48884565e-05, 2.40126361e-05, + 2.31228088e-05, 2.27947103e-05, 2.55361510e-05, 2.45889999e-05, 2.51041907e-05, 2.56311572e-05, + 2.43900633e-05, 2.36705071e-05, 2.33000897e-05, 2.31092130e-05, 2.30905826e-05, 2.56661539e-05, + 2.60177089e-05, 2.54657891e-05, 2.57154453e-05, 2.49744627e-05, 2.45439614e-05, 2.43228217e-05, + 2.38178017e-05, 2.31093753e-05, 2.42641584e-05, 2.55824841e-05, 2.53996704e-05, 2.43665068e-05, + 2.52575854e-05, 2.52970951e-05, 2.35762314e-05, 2.25548071e-05, 2.27903105e-05, 2.53531599e-05, + 2.51091930e-05, 2.54590994e-05, 2.58544787e-05, 2.47444137e-05, 2.31535903e-05, 2.25669047e-05, + 2.29508638e-05, 2.50987678e-05, 2.48494598e-05, 2.55437018e-05, 2.57661910e-05, 2.40472520e-05, + 2.25695540e-05, 2.27276328e-05, 2.31753207e-05, 2.54389607e-05, 2.43696801e-05, 2.58685895e-05, + 2.58269383e-05, 2.46971814e-05, 2.36756388e-05, 2.32226863e-05, 2.56843736e-05, 2.59587187e-05, + 2.57725520e-05, 2.54620012e-05, 2.47985757e-05, 2.35122822e-05, 2.31003155e-05, 2.32664754e-05, + 2.56147818e-05, 2.59052626e-05, 2.58616147e-05, 2.57141281e-05, 2.51596189e-05, 2.44957799e-05, + 2.37143792e-05, 2.33218041e-05, 2.55093584e-05, 2.57061233e-05, 2.56775884e-05, 2.58349946e-05, + 2.55819828e-05, 2.47997057e-05, 2.37756827e-05, 2.31938050e-05, 2.32453713e-05, 2.59411884e-05, + 2.64995283e-05, 2.46256831e-05, 2.45239693e-05, 2.49057011e-05, 2.35259019e-05, 2.29089627e-05, + 2.34988764e-05, 2.57226633e-05, 2.58722224e-05, 2.59967192e-05, 2.55345135e-05, 2.50306358e-05, + 2.44036011e-05, 2.36118970e-05, 2.33722981e-05, 2.58478907e-05, 2.61167147e-05, 2.53417895e-05, + 2.55398367e-05, 2.51795546e-05, 2.40922388e-05, 2.32919961e-05, 2.33820289e-05, 2.53964052e-05, + 2.57569483e-05, 2.57310589e-05, 2.58680153e-05, 2.53819099e-05, 2.44589985e-05, 2.34161186e-05, + 2.34836343e-05, 2.36926962e-05, 2.56868992e-05, 2.56547238e-05, 2.47114590e-05, 2.54227154e-05, + 2.50070283e-05, 2.38692764e-05, 2.28022172e-05, 2.26307198e-05, 2.30865100e-05, 2.61301669e-05, + 2.64384869e-05, 2.60158309e-05, 2.56088457e-05, 2.42447680e-05, 2.36541045e-05, 2.32503640e-05, + 2.27698257e-05, 2.53956141e-05, 2.59940223e-05, 2.61016704e-05, 2.58080212e-05, 2.53747722e-05, + 2.45147284e-05, 2.36912847e-05, 2.36473422e-05, 2.62398526e-05, 2.57931570e-05, 2.55399482e-05, + 2.49451848e-05, 2.34098686e-05, 2.33289282e-05, 2.34899458e-05, 2.56926263e-05, 2.61218452e-05, + 2.57250471e-05, 2.55431682e-05, 2.50495096e-05, 2.42646388e-05, 2.37461896e-05, 2.31419129e-05, + 2.37191101e-05, 1.85294680e-05, 1.74153268e-05, 1.95392482e-05, 2.34030606e-05, 2.78922518e-05, + 3.03844582e-05, 3.06925534e-05, 3.07311338e-05, 2.45201963e-05, 2.11818069e-05, 2.21926415e-05, + 2.40333182e-05, 2.43373405e-05, 2.50091596e-05, 2.77000011e-05, 3.01018948e-05, 3.00646212e-05, + 2.98322676e-05, 3.09226621e-05, 2.22622169e-05, 1.90104889e-05, 1.95738107e-05, 2.29270070e-05, + 2.48938477e-05, 2.57662025e-05, 2.90368457e-05, 3.18502822e-05, 3.27178800e-05, 1.93774084e-05, + 1.40102728e-05, 1.61155342e-05, 2.38503261e-05, 2.92826006e-05, 3.06693572e-05, 3.12214361e-05, + 3.17706875e-05, 3.18507050e-05, 2.42791740e-05, 1.83530928e-05, 1.70070474e-05, 2.18565878e-05, + 2.64329112e-05, 2.69696969e-05, 2.69729356e-05, 2.91946936e-05, 3.16272283e-05, 2.93066448e-05, + 2.43771862e-05, 1.72257242e-05, 1.42087554e-05, 1.72764363e-05, 2.40005800e-05, 3.07599501e-05, + 3.32365796e-05, 3.25693268e-05, 2.01359748e-05, 1.54091801e-05, 1.64051172e-05, 2.13676821e-05, + 2.76470864e-05, 3.21305229e-05, 3.33971169e-05, 3.22627941e-05, 1.85330996e-05, 1.44211923e-05, + 1.61942081e-05, 2.20871687e-05, 2.98466042e-05, 3.34285159e-05, 3.27880608e-05, 3.15784047e-05, + 1.72145417e-05, 1.28153538e-05, 1.73846504e-05, 2.37182962e-05, 2.73362584e-05, 2.96106622e-05, + 3.10506804e-05, 2.14642115e-05, 1.81619017e-05, 1.77664096e-05, 1.96841779e-05, 2.54175607e-05, + 3.06771740e-05, 3.18200408e-05, 3.13229803e-05, 2.23445634e-05, 1.91553522e-05, 1.93831326e-05, + 2.17146373e-05, 2.41099296e-05, 2.63663024e-05, 2.97513709e-05, 3.11637240e-05, 2.31967260e-05, + 1.92612526e-05, 1.94222220e-05, 2.06639607e-05, 2.21155408e-05, 2.57453642e-05, 2.96130861e-05, + 3.15047011e-05, 3.13827931e-05, 2.43649219e-05, 1.79163834e-05, 1.33899235e-05, 1.49790790e-05, + 2.17370120e-05, 3.00631439e-05, 3.22054947e-05, 2.99776173e-05, 2.02754619e-05, 1.69225247e-05, + 1.94760320e-05, 2.41699877e-05, 2.57759458e-05, 2.75051673e-05, 3.03106056e-05, 3.10755852e-05, + 2.46098207e-05, 1.96164400e-05, 1.68765195e-05, 2.00936348e-05, 2.43562813e-05, 2.86603111e-05, + 3.11341414e-05, 3.10271539e-05, 2.35845505e-05, 1.92301020e-05, 1.86153151e-05, 2.13186637e-05, + 2.47869438e-05, 2.79075299e-05, 3.10237614e-05, 3.05428356e-05, 2.94900228e-05, 2.33761879e-05, + 1.71848706e-05, 1.49530158e-05, 1.94957357e-05, 2.61416178e-05, 3.01042855e-05, 3.27097756e-05, + 3.30591247e-05, 3.18243539e-05, 2.11641667e-05, 1.78832129e-05, 1.80582842e-05, 2.25378199e-05, + 2.83134528e-05, 2.88060245e-05, 3.03762241e-05, 3.24678188e-05, 2.23218521e-05, 1.89189810e-05, + 1.86674617e-05, 2.00328863e-05, 2.27769626e-05, 2.77640236e-05, 3.03409705e-05, 2.99701519e-05, + 1.93503300e-05, 1.49322058e-05, 1.74624921e-05, 2.47711300e-05, 3.09686467e-05, 3.11678194e-05, + 3.05082655e-05, 2.35771727e-05, 1.93607949e-05, 1.72872321e-05, 1.87907768e-05, 2.35972120e-05, + 2.73728750e-05, 2.96329758e-05, 3.17478544e-05, 2.38862490e-05, 1.91133536e-05, 1.80579734e-05, + 2.03485911e-05, 2.41399626e-05, 2.78622684e-05, 2.97877952e-05, 2.98874481e-05, 2.97001909e-05, + 2.45069836e-05, 2.14899919e-05, 2.23755883e-05, 2.42043376e-05, 2.45078686e-05, 2.50769127e-05, + 2.76534925e-05, 2.97140323e-05, 2.94086445e-05, 2.90290323e-05, 2.98945743e-05, 2.27138034e-05, + 1.96725078e-05, 2.00232081e-05, 2.33357193e-05, 2.52258830e-05, 2.56771692e-05, 2.83444901e-05, + 3.07587387e-05, 3.14731856e-05, 1.99842376e-05, 1.48251486e-05, 1.68409197e-05, 2.45546167e-05, + 2.96090904e-05, 3.01312426e-05, 3.01126376e-05, 3.05709865e-05, 3.06658628e-05, 2.51023391e-05, + 1.94971118e-05, 1.78538967e-05, 2.25322721e-05, 2.66338721e-05, 2.65814481e-05, 2.62292381e-05, + 2.81776566e-05, 3.03147930e-05, 2.93232936e-05, 2.50921237e-05, 1.79871160e-05, 1.48407228e-05, + 1.79181481e-05, 2.42626171e-05, 3.00376479e-05, 3.17762012e-05, 3.11523596e-05, 2.05016577e-05, + 1.62710099e-05, 1.73421794e-05, 2.21984413e-05, 2.78444358e-05, 3.14337854e-05, 3.22054752e-05, + 3.10410773e-05, 1.88571047e-05, 1.53102641e-05, 1.72294477e-05, 2.28275088e-05, 2.96881570e-05, + 3.22979504e-05, 3.13978165e-05, 3.04061355e-05, 1.80087288e-05, 1.37788621e-05, 1.85046840e-05, + 2.46839667e-05, 2.73223747e-05, 2.84759669e-05, 2.96396204e-05, 2.21040344e-05, 1.92714925e-05, + 1.87586122e-05, 2.01931797e-05, 2.51439088e-05, 2.97334541e-05, 3.06367331e-05, 3.02002480e-05, + 2.29118122e-05, 2.01269847e-05, 2.02959953e-05, 2.23874930e-05, 2.41986637e-05, 2.57834570e-05, + 2.87583116e-05, 3.00699302e-05, 2.36731616e-05, 2.00366762e-05, 2.01569724e-05, 2.14829533e-05, + 2.26397455e-05, 2.55193299e-05, 2.86854774e-05, 3.03252141e-05, 3.02487470e-05, 2.56415533e-05, + 1.95387355e-05, 1.43682990e-05, 1.55369826e-05, 2.15369942e-05, 2.88159270e-05, 3.08055352e-05, + 2.86371496e-05, 2.09945270e-05, 1.81053759e-05, 2.05139877e-05, 2.47812775e-05, 2.59094847e-05, + 2.70165243e-05, 2.93806969e-05, 3.00496509e-05, 2.57957501e-05, 2.07665876e-05, 1.76475423e-05, + 2.06429260e-05, 2.44938490e-05, 2.79750777e-05, 2.99438750e-05, 2.99920279e-05, 2.39428282e-05, + 2.00557847e-05, 1.94754846e-05, 2.21645675e-05, 2.52727632e-05, 2.76480171e-05, 3.00745605e-05, + 2.94479683e-05, 2.83409588e-05, 2.41008304e-05, 1.81559167e-05, 1.56390757e-05, 1.99863509e-05, + 2.63204342e-05, 2.96703626e-05, 3.14812759e-05, 3.16500998e-05, 3.06054942e-05, 2.23080642e-05, + 1.94515370e-05, 1.92290266e-05, 2.31042236e-05, 2.77932421e-05, 2.73673943e-05, 2.86964001e-05, + 3.08946609e-05, 2.26323194e-05, 1.99928557e-05, 1.98620687e-05, 2.08511953e-05, 2.30687770e-05, + 2.75583732e-05, 2.96201984e-05, 2.89381104e-05, 2.06367044e-05, 1.63605430e-05, 1.83015918e-05, + 2.46304063e-05, 2.99639370e-05, 3.00954522e-05, 2.94082551e-05, 2.43324162e-05, 2.05288524e-05, + 1.83013305e-05, 1.94646815e-05, 2.35179866e-05, 2.66174855e-05, 2.86526078e-05, 3.06215852e-05, + 2.31683053e-05, 1.72197830e-05, 1.59959351e-05, 1.87895025e-05, 2.36963318e-05, 2.88321010e-05, + 3.16958975e-05, 3.17969880e-05, 3.14271590e-05, 2.39634980e-05, 2.00631894e-05, 2.11645840e-05, + 2.36033983e-05, 2.40209769e-05, 2.47821551e-05, 2.85087879e-05, 3.16391105e-05, 3.10646335e-05, + 3.04153413e-05, 3.17445806e-05, 2.16898175e-05, 1.79161814e-05, 1.82776616e-05, 2.25013441e-05, + 2.50748433e-05, 2.55846477e-05, 2.93739023e-05, 3.31615195e-05, 3.43406718e-05, 1.82782852e-05, + 1.24557299e-05, 1.46318179e-05, 2.42569480e-05, 3.16980168e-05, 3.22765495e-05, 3.20796292e-05, + 3.28155668e-05, 3.29789178e-05, 2.50623038e-05, 1.78592180e-05, 1.58227835e-05, 2.15229338e-05, + 2.70627092e-05, 2.68042836e-05, 2.61876529e-05, 2.90234320e-05, 3.23573772e-05, 3.11351308e-05, + 2.50114320e-05, 1.59502330e-05, 1.24178982e-05, 1.58337402e-05, 2.37116002e-05, 3.20674513e-05, + 3.48104082e-05, 3.37405059e-05, 1.88408410e-05, 1.40383632e-05, 1.52643525e-05, 2.11381684e-05, + 2.88774521e-05, 3.44302071e-05, 3.56447016e-05, 3.36039339e-05, 1.68374483e-05, 1.29976481e-05, + 1.51673770e-05, 2.19321743e-05, 3.16684906e-05, 3.58274892e-05, 3.41701386e-05, 3.25479073e-05, + 1.59854553e-05, 1.14044529e-05, 1.66687073e-05, 2.45250282e-05, 2.80187738e-05, 2.94527917e-05, + 3.12241935e-05, 2.09539553e-05, 1.75761708e-05, 1.69265520e-05, 1.85040628e-05, 2.47733702e-05, + 3.15059785e-05, 3.29304022e-05, 3.22202624e-05, 2.19876492e-05, 1.85692339e-05, 1.87580127e-05, + 2.13328097e-05, 2.35703678e-05, 2.55909461e-05, 2.99337540e-05, 3.20135498e-05, 2.29764930e-05, + 1.83952935e-05, 1.85298666e-05, 2.02145771e-05, 2.16154074e-05, 2.53183537e-05, 2.98379348e-05, + 3.24113709e-05, 3.22973050e-05, 2.59874604e-05, 1.80747452e-05, 1.20229987e-05, 1.31435460e-05, + 1.99741186e-05, 2.99539459e-05, 3.31551585e-05, 2.96482300e-05, 1.95648759e-05, 1.62224081e-05, + 1.90687026e-05, 2.45413931e-05, 2.59867189e-05, 2.74173055e-05, 3.09401262e-05, 3.19993670e-05, + 2.61762464e-05, 1.94207851e-05, 1.55616492e-05, 1.90721962e-05, 2.39914143e-05, 2.88065589e-05, + 3.17797756e-05, 3.19021513e-05, 2.33046866e-05, 1.84347120e-05, 1.77405014e-05, 2.10991918e-05, + 2.51906936e-05, 2.84345839e-05, 3.20621998e-05, 3.10016186e-05, 2.92392178e-05, 2.36386846e-05, + 1.62122858e-05, 1.32920813e-05, 1.82451587e-05, 2.65964613e-05, 3.15540844e-05, 3.43592077e-05, + 3.46034761e-05, 3.28680847e-05, 2.13858608e-05, 1.79500813e-05, 1.75455441e-05, 2.22426057e-05, + 2.85770854e-05, 2.76774769e-05, 2.96516905e-05, 3.32595671e-05, 2.15389208e-05, 1.84385102e-05, + 1.83190839e-05, 1.94170288e-05, 2.21091199e-05, 2.83152107e-05, 3.13868687e-05, 3.02061735e-05, + 1.93051693e-05, 1.43211764e-05, 1.63403306e-05, 2.40959766e-05, 3.18647263e-05, 3.20615778e-05, + 3.09363393e-05, 2.39668359e-05, 1.91306980e-05, 1.63957803e-05, 1.76687779e-05, 2.25967372e-05, + 2.67508263e-05, 2.97715234e-05, 3.29209376e-05, 2.40369749e-05, 1.96709920e-05, 1.86772066e-05, + 2.10286160e-05, 2.46538446e-05, 2.77273324e-05, 2.92054412e-05, 2.91731647e-05, 2.88602633e-05, + 2.45209575e-05, 2.18063300e-05, 2.25851972e-05, 2.43464586e-05, 2.46388134e-05, 2.51212079e-05, + 2.75178201e-05, 2.92637527e-05, 2.88101242e-05, 2.83606932e-05, 2.90459407e-05, 2.30874761e-05, + 2.02697763e-05, 2.04702910e-05, 2.36612505e-05, 2.54338766e-05, 2.55990923e-05, 2.77770959e-05, + 2.98241239e-05, 3.04054269e-05, 2.05369427e-05, 1.56143129e-05, 1.75386928e-05, 2.50316283e-05, + 2.96133239e-05, 2.95660928e-05, 2.92040139e-05, 2.95828015e-05, 2.96810891e-05, 2.56374488e-05, + 2.04298116e-05, 1.86167287e-05, 2.30597265e-05, 2.67003686e-05, 2.62798788e-05, 2.57249379e-05, + 2.74227085e-05, 2.92743750e-05, 2.91457615e-05, 2.55557285e-05, 1.86885664e-05, 1.55025205e-05, + 1.85394637e-05, 2.44611710e-05, 2.93653606e-05, 3.05627567e-05, 3.00022704e-05, 2.08818178e-05, + 1.70726067e-05, 1.81775786e-05, 2.28402692e-05, 2.78544032e-05, 3.06970200e-05, 3.11235574e-05, + 3.00127111e-05, 1.92478818e-05, 1.61453291e-05, 1.81359252e-05, 2.33886748e-05, 2.93816271e-05, + 3.12464195e-05, 3.02487370e-05, 2.94435176e-05, 1.87322266e-05, 1.46858521e-05, 1.94442608e-05, + 2.53307830e-05, 2.72222886e-05, 2.76366031e-05, 2.85779994e-05, 2.26208206e-05, 2.01856622e-05, + 1.96029376e-05, 2.06755600e-05, 2.49708902e-05, 2.89439692e-05, 2.96545318e-05, 2.92785140e-05, + 2.33552538e-05, 2.09237606e-05, 2.10479906e-05, 2.29175906e-05, 2.42883889e-05, 2.53949924e-05, + 2.79894478e-05, 2.91725785e-05, 2.40315736e-05, 2.07016564e-05, 2.07913903e-05, 2.21382992e-05, + 2.30634653e-05, 2.53615882e-05, 2.79594305e-05, 2.93628352e-05, 2.93176033e-05, 2.64611835e-05, + 2.08127770e-05, 1.52792139e-05, 1.61396702e-05, 2.15273865e-05, 2.78931715e-05, 2.96857499e-05, + 2.76683706e-05, 2.15962920e-05, 1.90983404e-05, 2.13462104e-05, 2.51883549e-05, 2.59630887e-05, + 2.66344325e-05, 2.86180573e-05, 2.91938922e-05, 2.65469914e-05, 2.16696038e-05, 1.83621893e-05, + 2.11406202e-05, 2.46042117e-05, 2.74295489e-05, 2.89960625e-05, 2.91339144e-05, 2.42148996e-05, + 2.07544365e-05, 2.02119813e-05, 2.28176661e-05, 2.55787736e-05, 2.73793327e-05, 2.92633854e-05, + 2.85832190e-05, 2.74996180e-05, 2.46079716e-05, 1.89987123e-05, 1.63281154e-05, 2.04616030e-05, + 2.63860370e-05, 2.91940179e-05, 3.04226187e-05, 3.04746010e-05, 2.96039962e-05, 2.31600359e-05, + 2.06885901e-05, 2.01871889e-05, 2.35408442e-05, 2.73568962e-05, 2.64012081e-05, 2.75270406e-05, + 2.96683809e-05, 2.29165018e-05, 2.08638716e-05, 2.08208906e-05, 2.15238888e-05, 2.33270609e-05, + 2.73273328e-05, 2.89712201e-05, 2.81369636e-05, 2.16388164e-05, 1.75678631e-05, 1.90499605e-05, + 2.45595200e-05, 2.91255292e-05, 2.92094734e-05, 2.85425169e-05, 2.48514898e-05, 2.14510330e-05, + 1.91710638e-05, 2.00748543e-05, 2.35244189e-05, 2.60899096e-05, 2.78965663e-05, 2.96741350e-05, + 2.56286797e-05, 2.85117894e-05, 2.90449177e-05, 2.75771146e-05, 2.51021474e-05, 2.26228514e-05, + 2.11928060e-05, 2.11640028e-05, 2.13875186e-05, 2.52628055e-05, 2.72348816e-05, 2.67090565e-05, + 2.53906073e-05, 2.51639039e-05, 2.47864582e-05, 2.27999229e-05, 2.11944951e-05, 2.15380550e-05, + 2.19085745e-05, 2.12157815e-05, 2.62959303e-05, 2.81127309e-05, 2.80796833e-05, 2.58840627e-05, + 2.45352610e-05, 2.43981695e-05, 2.24590833e-05, 2.04623361e-05, 1.98470680e-05, 2.79722977e-05, + 3.02703348e-05, 2.95678404e-05, 2.48227310e-05, 2.10432863e-05, 2.08775802e-05, 2.10428049e-05, + 2.06548375e-05, 2.05663905e-05, 2.43515089e-05, 2.77657899e-05, 2.89408659e-05, 2.62679289e-05, + 2.35110591e-05, 2.38089530e-05, 2.42359268e-05, 2.27022948e-05, 2.09093175e-05, 2.13938933e-05, + 2.44224444e-05, 2.89617111e-05, 3.05114895e-05, 2.91200813e-05, 2.52961122e-05, 2.10102333e-05, + 1.96075953e-05, 2.01732701e-05, 2.78436763e-05, 2.96617612e-05, 2.90933009e-05, 2.63803415e-05, + 2.25449693e-05, 1.97659138e-05, 1.91629495e-05, 2.02357466e-05, 2.88938691e-05, 3.00023506e-05, + 2.90336048e-05, 2.60207848e-05, 2.11442298e-05, 1.90662666e-05, 1.99436817e-05, 2.07963032e-05, + 2.89166044e-05, 3.03465450e-05, 2.83196747e-05, 2.45682098e-05, 2.30553911e-05, 2.24806353e-05, + 2.15334404e-05, 2.65835148e-05, 2.79238069e-05, 2.83187783e-05, 2.79248508e-05, 2.49019519e-05, + 2.13356826e-05, 2.05922154e-05, 2.09683254e-05, 2.60806698e-05, 2.75673619e-05, 2.75190344e-05, + 2.63683782e-05, 2.54403993e-05, 2.45323340e-05, 2.21969119e-05, 2.10770516e-05, 2.55998393e-05, + 2.77952612e-05, 2.77577789e-05, 2.68575873e-05, 2.62987105e-05, 2.45857431e-05, 2.22406401e-05, + 2.08702166e-05, 2.09278498e-05, 2.36847357e-05, 2.72552193e-05, 3.01757036e-05, 3.03381280e-05, + 2.75443256e-05, 2.22169293e-05, 2.04854606e-05, 2.23970186e-05, 2.72496125e-05, 2.84516759e-05, + 2.72780359e-05, 2.47119658e-05, 2.41107009e-05, 2.34941904e-05, 2.16400513e-05, 2.10783842e-05, + 2.36277356e-05, 2.70274050e-05, 2.91256435e-05, 2.76088849e-05, 2.51923495e-05, 2.27685776e-05, + 2.12119261e-05, 2.11315697e-05, 2.54758619e-05, 2.77396991e-05, 2.80488112e-05, 2.63915041e-05, + 2.44168987e-05, 2.28879513e-05, 2.10371961e-05, 2.16252277e-05, 2.26009844e-05, 2.51379001e-05, + 2.86557209e-05, 3.01387513e-05, 2.80685531e-05, 2.37679359e-05, 2.12461103e-05, 1.98365269e-05, + 1.97151431e-05, 2.06280662e-05, 2.60694340e-05, 2.73575363e-05, 2.78858500e-05, 2.59466564e-05, + 2.28638848e-05, 2.35184185e-05, 2.24290830e-05, 2.04378252e-05, 2.64457673e-05, 2.75522157e-05, + 2.75129499e-05, 2.72592843e-05, 2.61481331e-05, 2.29406925e-05, 2.13736553e-05, 2.20525058e-05, + 2.69817480e-05, 2.88995975e-05, 2.87171571e-05, 2.52343320e-05, 2.11487528e-05, 2.10492478e-05, + 2.16613391e-05, 2.49523918e-05, 2.71528522e-05, 2.85358552e-05, 2.82252069e-05, 2.60405299e-05, + 2.39224155e-05, 2.22843046e-05, 2.05931152e-05, 2.54992168e-05, 2.54481035e-05, 2.52981477e-05, + 2.48128247e-05, 2.43079806e-05, 2.42490772e-05, 2.40380511e-05, 2.42630154e-05, 2.46902700e-05, + 2.56381276e-05, 2.58227823e-05, 2.58980084e-05, 2.53889077e-05, 2.52882036e-05, 2.52774931e-05, + 2.43754710e-05, 2.37923131e-05, 2.43474874e-05, 2.47829098e-05, 2.45619592e-05, 2.52436546e-05, + 2.52209310e-05, 2.57177373e-05, 2.51759756e-05, 2.47381398e-05, 2.53256520e-05, 2.50149568e-05, + 2.40744578e-05, 2.37665103e-05, 2.53349407e-05, 2.42704395e-05, 2.49703246e-05, 2.42566750e-05, + 2.28454645e-05, 2.37501777e-05, 2.45287710e-05, 2.43413114e-05, 2.42574020e-05, 2.38741640e-05, + 2.40146583e-05, 2.47242200e-05, 2.48081961e-05, 2.44269599e-05, 2.54428282e-05, 2.62155664e-05, + 2.56004715e-05, 2.46627796e-05, 2.34375548e-05, 2.40774431e-05, 2.49688570e-05, 2.48829398e-05, + 2.52959236e-05, 2.51938902e-05, 2.40569474e-05, 2.38027449e-05, 2.42083233e-05, 2.58594811e-05, + 2.44728131e-05, 2.44193613e-05, 2.45361076e-05, 2.39005184e-05, 2.31224087e-05, 2.31691745e-05, + 2.40445790e-05, 2.61383666e-05, 2.41663117e-05, 2.41231281e-05, 2.46111978e-05, 2.34867467e-05, + 2.30302545e-05, 2.39978180e-05, 2.44173193e-05, 2.48798507e-05, 2.33815025e-05, 2.40312145e-05, + 2.37244922e-05, 2.44789301e-05, 2.55987840e-05, 2.52507419e-05, 2.49684836e-05, 2.40971100e-05, + 2.43841948e-05, 2.55535908e-05, 2.58778931e-05, 2.45493560e-05, 2.42753238e-05, 2.44895131e-05, + 2.49548185e-05, 2.44332831e-05, 2.45669883e-05, 2.48429440e-05, 2.55501615e-05, 2.61515284e-05, + 2.52200451e-05, 2.45367324e-05, 2.49480098e-05, 2.49173333e-05, 2.50080878e-05, 2.46701087e-05, + 2.51072053e-05, 2.56356778e-05, 2.51678114e-05, 2.44811863e-05, 2.44723360e-05, 2.28934607e-05, + 2.28153888e-05, 2.35668474e-05, 2.52802370e-05, 2.69569538e-05, 2.55538439e-05, 2.44346498e-05, + 2.58016660e-05, 2.49616446e-05, 2.38247132e-05, 2.42544362e-05, 2.43658151e-05, 2.48382524e-05, + 2.53981476e-05, 2.47501896e-05, 2.44589055e-05, 2.30126910e-05, 2.39751302e-05, 2.49199779e-05, + 2.54036345e-05, 2.53557794e-05, 2.52089971e-05, 2.47491675e-05, 2.45086032e-05, 2.51052723e-05, + 2.47931259e-05, 2.47309180e-05, 2.45087994e-05, 2.44406219e-05, 2.47154924e-05, 2.43397166e-05, + 2.49390193e-05, 2.57017515e-05, 2.43422757e-05, 2.44059782e-05, 2.48930201e-05, 2.56204061e-05, + 2.45940475e-05, 2.38819172e-05, 2.37410405e-05, 2.38354946e-05, 2.43424773e-05, 2.38415718e-05, + 2.29440254e-05, 2.39395729e-05, 2.49113115e-05, 2.50508173e-05, 2.67312512e-05, 2.62557575e-05, + 2.45888452e-05, 2.55616189e-05, 2.41878020e-05, 2.38920667e-05, 2.47464295e-05, 2.54874335e-05, + 2.46742688e-05, 2.43112451e-05, 2.51674734e-05, 2.36596785e-05, 2.27836553e-05, 2.47725363e-05, + 2.58339568e-05, 2.44856687e-05, 2.44913416e-05, 2.49713612e-05, 2.42208244e-05, 2.39439802e-05, + 2.43001120e-05, 2.52023266e-05, 2.61088270e-05, 2.60398422e-05, 2.52648707e-05, 2.42120820e-05, + 2.51362106e-05, 3.49266142e-05, 3.74289855e-05, 3.19569980e-05, 2.44600138e-05, 1.85097156e-05, + 1.57803404e-05, 1.56530565e-05, 1.59207063e-05, 2.40547501e-05, 2.98092186e-05, 2.80468755e-05, + 2.45498932e-05, 2.40008153e-05, 2.30220616e-05, 1.88303430e-05, 1.58677627e-05, 1.63145135e-05, + 1.68652129e-05, 1.56501677e-05, 2.72621815e-05, 3.35727640e-05, 3.29228200e-05, 2.60815749e-05, + 2.26899665e-05, 2.20258313e-05, 1.78624676e-05, 1.44794414e-05, 1.35461031e-05, 3.29065194e-05, + 4.58958247e-05, 4.04550797e-05, 2.37335399e-05, 1.59303935e-05, 1.53051963e-05, 1.53510995e-05, + 1.47301740e-05, 1.46032640e-05, 2.27357810e-05, 3.35726590e-05, 3.77380700e-05, 2.75119216e-05, + 2.03817126e-05, 2.05769313e-05, 2.12038126e-05, 1.81331256e-05, 1.50756292e-05, 1.63712089e-05, + 2.27936345e-05, 3.74931013e-05, 4.61283004e-05, 3.77780632e-05, 2.44147524e-05, 1.54427675e-05, + 1.31544723e-05, 1.39581747e-05, 3.19055531e-05, 4.18040979e-05, 3.89223255e-05, 2.80881913e-05, + 1.84973227e-05, 1.35934439e-05, 1.26234544e-05, 1.41068556e-05, 3.57280768e-05, 4.44007334e-05, + 3.90921276e-05, 2.69052483e-05, 1.58825251e-05, 1.25102202e-05, 1.36402731e-05, 1.49520840e-05, + 3.74077769e-05, 4.87050477e-05, 3.58812814e-05, 2.33999032e-05, 1.93360272e-05, 1.76902622e-05, + 1.60086560e-05, 2.83806135e-05, 3.41143075e-05, 3.54107175e-05, 3.25034383e-05, 2.29845769e-05, + 1.58718518e-05, 1.46421682e-05, 1.52314159e-05, 2.68251841e-05, 3.23207456e-05, 3.19960667e-05, + 2.77985321e-05, 2.45854513e-05, 2.19339921e-05, 1.72680190e-05, 1.54095044e-05, 2.54206867e-05, + 3.26694650e-05, 3.24317728e-05, 2.95424797e-05, 2.73743566e-05, 2.23239135e-05, 1.73720510e-05, + 1.50617083e-05, 1.51653962e-05, 2.16491184e-05, 3.30039848e-05, 4.69412148e-05, 4.42197386e-05, + 2.99252773e-05, 1.71907152e-05, 1.44151829e-05, 1.74550661e-05, 3.06262169e-05, 3.67634518e-05, + 3.14296102e-05, 2.33700846e-05, 2.15837469e-05, 1.98900514e-05, 1.63677268e-05, 1.54362265e-05, + 2.14343457e-05, 3.08063322e-05, 3.83309901e-05, 3.14872584e-05, 2.40358160e-05, 1.84183885e-05, + 1.55842675e-05, 1.55156963e-05, 2.49661618e-05, 3.25897744e-05, 3.38680082e-05, 2.81469090e-05, + 2.25621401e-05, 1.88709863e-05, 1.54002871e-05, 1.62771902e-05, 1.78924727e-05, 2.45357377e-05, + 3.68700620e-05, 4.37661166e-05, 3.29795008e-05, 2.08944050e-05, 1.59320667e-05, 1.35359463e-05, + 1.33163037e-05, 1.46838986e-05, 2.76859139e-05, 3.32524739e-05, 3.41530074e-05, 2.64559368e-05, + 1.86801259e-05, 1.93980762e-05, 1.73649256e-05, 1.42925287e-05, 2.74831676e-05, 3.25325864e-05, + 3.27162472e-05, 3.08664014e-05, 2.66386193e-05, 1.90013267e-05, 1.60207466e-05, 1.70070579e-05, + 3.09709037e-05, 4.07534569e-05, 3.66479621e-05, 2.38654431e-05, 1.55537834e-05, 1.53741667e-05, + 1.63336315e-05, 2.41074287e-05, 3.12957528e-05, 3.64749688e-05, 3.40399364e-05, 2.59048868e-05, + 2.05646180e-05, 1.74228496e-05, 1.46623055e-05, 2.56127111e-05, 2.93125283e-05, 3.00523645e-05, + 2.82431323e-05, 2.51948860e-05, 2.21455659e-05, 2.04615559e-05, 2.03906288e-05, 2.05875619e-05, + 2.51292024e-05, 2.75755763e-05, 2.68909232e-05, 2.53371982e-05, 2.50744746e-05, 2.46078268e-05, + 2.23380518e-05, 2.05041655e-05, 2.08226294e-05, 2.11936217e-05, 2.04041326e-05, 2.65049431e-05, + 2.88444955e-05, 2.86861432e-05, 2.59989001e-05, 2.44008664e-05, 2.41191682e-05, 2.18150170e-05, + 1.95895155e-05, 1.89132540e-05, 2.86349203e-05, 3.19940360e-05, 3.08362598e-05, 2.48551084e-05, + 2.04839626e-05, 2.01332106e-05, 2.02043263e-05, 1.97750846e-05, 1.96837889e-05, 2.43440033e-05, + 2.86819359e-05, 3.00590877e-05, 2.65622897e-05, 2.31968219e-05, 2.33754945e-05, 2.37585699e-05, + 2.20091600e-05, 2.00254744e-05, 2.08031680e-05, 2.43914337e-05, 3.00245050e-05, 3.21518929e-05, + 3.01527827e-05, 2.52579713e-05, 2.02411286e-05, 1.86275080e-05, 1.92288626e-05, 2.83488855e-05, + 3.10977452e-05, 3.03427219e-05, 2.67649223e-05, 2.21134375e-05, 1.89172277e-05, 1.82028110e-05, + 1.93272445e-05, 2.96498946e-05, 3.16519938e-05, 3.03413460e-05, 2.62907589e-05, 2.04952367e-05, + 1.81107335e-05, 1.89914869e-05, 1.99302597e-05, 2.99870324e-05, 3.23739847e-05, 2.94099633e-05, + 2.46457158e-05, 2.26302885e-05, 2.17438165e-05, 2.06718301e-05, 2.69294301e-05, 2.88694200e-05, + 2.93189792e-05, 2.85229640e-05, 2.46366959e-05, 2.05485784e-05, 1.97114644e-05, 2.01223424e-05, + 2.62933841e-05, 2.83201306e-05, 2.82254184e-05, 2.66825698e-05, 2.53674642e-05, 2.41320994e-05, + 2.14665078e-05, 2.02436346e-05, 2.56882328e-05, 2.85022577e-05, 2.84322155e-05, 2.73464597e-05, + 2.65373486e-05, 2.42922315e-05, 2.15274261e-05, 2.00076116e-05, 2.00771525e-05, 2.37121905e-05, + 2.83130283e-05, 3.20732482e-05, 3.18008061e-05, 2.77300771e-05, 2.14360905e-05, 1.95611573e-05, + 2.16109559e-05, 2.77851104e-05, 2.96396054e-05, 2.79860152e-05, 2.46945429e-05, 2.38567686e-05, + 2.30001602e-05, 2.08784148e-05, 2.02575603e-05, 2.36166627e-05, 2.77266573e-05, 3.02555778e-05, + 2.81484378e-05, 2.50966239e-05, 2.21547127e-05, 2.03698511e-05, 2.03127245e-05, 2.55005734e-05, + 2.84592039e-05, 2.88779554e-05, 2.67852176e-05, 2.43122503e-05, 2.23845580e-05, 2.02276995e-05, + 2.08302747e-05, 2.18709933e-05, 2.52326971e-05, 2.97606926e-05, 3.16340718e-05, 2.86940102e-05, + 2.34809697e-05, 2.05509398e-05, 1.89047621e-05, 1.87483367e-05, 1.97433214e-05, 2.65223003e-05, + 2.84150027e-05, 2.88588415e-05, 2.61330378e-05, 2.22968871e-05, 2.28022743e-05, 2.15767735e-05, + 1.94817451e-05, 2.66278717e-05, 2.83594278e-05, 2.83802614e-05, 2.78467784e-05, 2.62673837e-05, + 2.24558446e-05, 2.06324080e-05, 2.13025433e-05, 2.77428361e-05, 3.05344559e-05, 2.97490891e-05, + 2.50561222e-05, 2.03367617e-05, 2.02178795e-05, 2.08680403e-05, 2.50249174e-05, 2.78972103e-05, + 2.96283255e-05, 2.89958282e-05, 2.60067372e-05, 2.34078845e-05, 2.15636938e-05, 1.97223730e-05, + 2.48744233e-05, 2.27838161e-05, 2.21988863e-05, 2.34569701e-05, 2.50488738e-05, 2.59928912e-05, + 2.62389654e-05, 2.62167132e-05, 2.61514410e-05, 2.50641723e-05, 2.39206234e-05, 2.42862089e-05, + 2.49886447e-05, 2.50934884e-05, 2.52650268e-05, 2.59449216e-05, 2.62632890e-05, 2.61744559e-05, + 2.60884925e-05, 2.61783105e-05, 2.44674305e-05, 2.30926943e-05, 2.32399496e-05, 2.47061854e-05, + 2.53524058e-05, 2.54251445e-05, 2.59833823e-05, 2.62640982e-05, 2.62909168e-05, 2.32445836e-05, + 2.01186354e-05, 2.14707935e-05, 2.51873301e-05, 2.63569487e-05, 2.62928020e-05, 2.61913841e-05, + 2.62260915e-05, 2.62382652e-05, 2.53823116e-05, 2.30689895e-05, 2.21099273e-05, 2.44260715e-05, + 2.57367148e-05, 2.56297720e-05, 2.54731439e-05, 2.58928306e-05, 2.61776925e-05, 2.62692545e-05, + 2.53646001e-05, 2.21756484e-05, 2.01005824e-05, 2.21166898e-05, 2.50230837e-05, 2.62502495e-05, + 2.62663043e-05, 2.62370284e-05, 2.34649265e-05, 2.11235008e-05, 2.18149888e-05, 2.43083322e-05, + 2.60233245e-05, 2.63858674e-05, 2.63315198e-05, 2.62648472e-05, 2.26016921e-05, 2.04751620e-05, + 2.17596610e-05, 2.45551692e-05, 2.62961218e-05, 2.63447248e-05, 2.62590742e-05, 2.62137411e-05, + 2.21932445e-05, 1.93595620e-05, 2.25247167e-05, 2.52651904e-05, 2.58744590e-05, 2.59300352e-05, + 2.60727262e-05, 2.42410975e-05, 2.29448343e-05, 2.26494500e-05, 2.33349046e-05, 2.52310524e-05, + 2.61716291e-05, 2.62356885e-05, 2.61993753e-05, 2.45641323e-05, 2.33694291e-05, 2.34455728e-05, + 2.43656452e-05, 2.49737243e-05, 2.53739273e-05, 2.60079742e-05, 2.61888530e-05, 2.48432861e-05, + 2.32962366e-05, 2.33508567e-05, 2.39938361e-05, 2.44481193e-05, 2.53555005e-05, 2.60065314e-05, + 2.62034469e-05, 2.62029974e-05, 2.56033235e-05, 2.31482757e-05, 1.98084699e-05, 2.05802652e-05, + 2.38567768e-05, 2.59717419e-05, 2.62114244e-05, 2.59219433e-05, 2.37549322e-05, 2.23043090e-05, + 2.35696731e-05, 2.52499229e-05, 2.55279330e-05, 2.57240333e-05, 2.61226626e-05, 2.61985560e-05, + 2.56379457e-05, 2.37060760e-05, 2.19755895e-05, 2.35622494e-05, 2.50835903e-05, 2.59097125e-05, + 2.61553036e-05, 2.61896494e-05, 2.49242365e-05, 2.33131411e-05, 2.30186713e-05, 2.42960362e-05, + 2.53894072e-05, 2.59100528e-05, 2.62153230e-05, 2.61032899e-05, 2.59012687e-05, 2.50333775e-05, + 2.23046973e-05, 2.06715107e-05, 2.32277203e-05, 2.56499096e-05, 2.62496980e-05, 2.62943920e-05, + 2.62699947e-05, 2.62260528e-05, 2.43958015e-05, 2.30965278e-05, 2.29301492e-05, 2.46399204e-05, + 2.58990048e-05, 2.56363507e-05, 2.58673063e-05, 2.61862835e-05, 2.44126590e-05, 2.33156138e-05, + 2.32648030e-05, 2.37015210e-05, 2.45848130e-05, 2.58986198e-05, 2.61945722e-05, 2.60324903e-05, + 2.36609275e-05, 2.12592609e-05, 2.23696454e-05, 2.50852066e-05, 2.61915074e-05, 2.61958720e-05, + 2.60963450e-05, 2.51184889e-05, 2.35939145e-05, 2.23945288e-05, 2.29855792e-05, 2.46983683e-05, + 2.55760766e-05, 2.59910996e-05, 2.62445923e-05, 2.52791123e-05, 2.84198231e-05, 2.90019999e-05, + 2.84949870e-05, 2.63153328e-05, 2.27627559e-05, 2.07818281e-05, 2.04393305e-05, 2.02434990e-05, + 2.46153553e-05, 2.67083236e-05, 2.60274965e-05, 2.51275421e-05, 2.49715871e-05, 2.44802160e-05, + 2.28591821e-05, 2.11150648e-05, 2.09247281e-05, 2.09354150e-05, 2.01367054e-05, 2.64654880e-05, + 2.84048242e-05, 2.76831882e-05, 2.60587599e-05, 2.48982781e-05, 2.38802446e-05, 2.14753027e-05, + 1.95491413e-05, 1.89282610e-05, 2.81189729e-05, 3.06666535e-05, 2.97052490e-05, 2.60085847e-05, + 2.21993697e-05, 2.06521392e-05, 1.99052506e-05, 1.95229432e-05, 1.94862344e-05, 2.59203260e-05, + 2.98593361e-05, 2.97202593e-05, 2.70650634e-05, 2.38631958e-05, 2.28930971e-05, 2.24775792e-05, + 2.10865572e-05, 1.95264890e-05, 2.19356007e-05, 2.57133890e-05, 2.93969375e-05, 2.99476179e-05, + 2.90509670e-05, 2.52791475e-05, 2.04613810e-05, 1.84868237e-05, 1.89123238e-05, 2.72698480e-05, + 3.03788076e-05, 3.02252799e-05, 2.76044683e-05, 2.31357675e-05, 1.96233884e-05, 1.85317920e-05, + 1.92177330e-05, 2.77811040e-05, 3.08085379e-05, 3.06041174e-05, 2.70553492e-05, 2.14527553e-05, + 1.85428459e-05, 1.87987509e-05, 1.96537775e-05, 2.94908817e-05, 3.15865151e-05, 3.02900209e-05, + 2.64638031e-05, 2.31042358e-05, 2.07623613e-05, 1.97704404e-05, 2.72022711e-05, 2.98742593e-05, + 2.97733382e-05, 2.77691696e-05, 2.38153479e-05, 2.03419884e-05, 1.95052756e-05, 1.98367058e-05, + 2.66222672e-05, 2.90454802e-05, 2.87997536e-05, 2.71340378e-05, 2.49670911e-05, 2.29609371e-05, + 2.08152370e-05, 1.99494155e-05, 2.60271838e-05, 2.85514757e-05, 2.83854107e-05, 2.79530785e-05, + 2.66652901e-05, 2.37158415e-05, 2.09477175e-05, 1.96912488e-05, 1.97940601e-05, 2.64677569e-05, + 3.12698164e-05, 3.14717276e-05, 2.95055568e-05, 2.55116421e-05, 2.04273909e-05, 1.91355171e-05, + 2.03889296e-05, 2.79466618e-05, 3.06875420e-05, 2.90266443e-05, 2.56909151e-05, 2.41543834e-05, + 2.25015395e-05, 2.05611637e-05, 2.00503769e-05, 2.61865971e-05, 2.91923825e-05, 2.95602530e-05, + 2.76774022e-05, 2.49144105e-05, 2.16863559e-05, 1.98942664e-05, 2.00714542e-05, 2.56401903e-05, + 2.86795913e-05, 2.90492614e-05, 2.76587642e-05, 2.51643020e-05, 2.25237602e-05, 2.01372546e-05, + 2.02981350e-05, 2.08111604e-05, 2.63121926e-05, 2.99847415e-05, 2.99453963e-05, 2.78075299e-05, + 2.40045275e-05, 2.10777390e-05, 1.89428291e-05, 1.86240590e-05, 1.94785326e-05, 2.82941469e-05, + 3.11580459e-05, 3.00784523e-05, 2.65200250e-05, 2.20364870e-05, 2.08578606e-05, 1.98903743e-05, + 1.88710751e-05, 2.61916874e-05, 2.93991942e-05, 2.98118690e-05, 2.82720400e-05, 2.59410603e-05, + 2.26598634e-05, 2.07111077e-05, 2.06633835e-05, 2.96360004e-05, 3.24342033e-05, 2.95092007e-05, + 2.43112530e-05, 2.01279192e-05, 1.99628690e-05, 2.03130499e-05, 2.62420400e-05, 2.93725939e-05, + 3.00543212e-05, 2.85277014e-05, 2.49538160e-05, 2.22716923e-05, 2.08899704e-05, 1.95865470e-05, + 2.51420443e-05, 2.52288743e-05, 2.50893054e-05, 2.59017873e-05, 2.60646189e-05, 2.47514418e-05, + 2.37743180e-05, 2.35059577e-05, 2.32620010e-05, 2.48879753e-05, 2.51481490e-05, 2.50451992e-05, + 2.51620165e-05, 2.51705677e-05, 2.50228110e-05, 2.47495240e-05, 2.40427187e-05, 2.37583538e-05, + 2.36249395e-05, 2.32378329e-05, 2.55311646e-05, 2.54996769e-05, 2.51589118e-05, 2.55024261e-05, + 2.54219063e-05, 2.47903192e-05, 2.38358751e-05, 2.30207053e-05, 2.27048653e-05, 2.54514849e-05, + 2.43930285e-05, 2.49126765e-05, 2.60105024e-05, 2.49611944e-05, 2.37875092e-05, 2.31095696e-05, + 2.29292395e-05, 2.29299020e-05, 2.61853684e-05, 2.64360458e-05, 2.54703613e-05, 2.59013144e-05, + 2.51737847e-05, 2.43477765e-05, 2.38632099e-05, 2.34367752e-05, 2.28405453e-05, 2.46159846e-05, + 2.60157589e-05, 2.53214994e-05, 2.39480669e-05, 2.50494571e-05, 2.53066859e-05, 2.35815007e-05, + 2.24002224e-05, 2.25767355e-05, 2.50925603e-05, 2.50400042e-05, 2.55334417e-05, 2.61493194e-05, + 2.50614716e-05, 2.33340865e-05, 2.25930294e-05, 2.28184923e-05, 2.46533424e-05, 2.47669941e-05, + 2.57243437e-05, 2.60317982e-05, 2.43323054e-05, 2.26361084e-05, 2.25581229e-05, 2.29886854e-05, + 2.53969550e-05, 2.43321441e-05, 2.62084070e-05, 2.64280725e-05, 2.48228585e-05, 2.32671766e-05, + 2.28177505e-05, 2.58035766e-05, 2.63281206e-05, 2.59877480e-05, 2.53035961e-05, 2.45165687e-05, + 2.33620785e-05, 2.29367845e-05, 2.30796109e-05, 2.57413207e-05, 2.61846030e-05, 2.60942149e-05, + 2.58855439e-05, 2.50333253e-05, 2.40836580e-05, 2.34183516e-05, 2.31337757e-05, 2.56297843e-05, + 2.57864437e-05, 2.57277728e-05, 2.60645343e-05, 2.56487553e-05, 2.45914051e-05, 2.35067993e-05, + 2.29934210e-05, 2.30587024e-05, 2.68667876e-05, 2.74468075e-05, 2.46235731e-05, 2.40614936e-05, + 2.42800542e-05, 2.31001101e-05, 2.26593430e-05, 2.30009085e-05, 2.58227171e-05, 2.62632329e-05, + 2.63670463e-05, 2.58601696e-05, 2.51105734e-05, 2.41939684e-05, 2.34263395e-05, 2.32171301e-05, + 2.67100781e-05, 2.66142896e-05, 2.52515651e-05, 2.54561115e-05, 2.51192547e-05, 2.38760143e-05, + 2.30384437e-05, 2.32149941e-05, 2.54489507e-05, 2.58874808e-05, 2.58551970e-05, 2.61737891e-05, + 2.56556906e-05, 2.44628011e-05, 2.33043049e-05, 2.32180297e-05, 2.32594081e-05, 2.60444452e-05, + 2.58121489e-05, 2.44024038e-05, 2.52298867e-05, 2.51598212e-05, 2.39929556e-05, 2.27212510e-05, + 2.24842840e-05, 2.29012137e-05, 2.67182372e-05, 2.73212516e-05, 2.64483214e-05, 2.57514955e-05, + 2.41051763e-05, 2.29381763e-05, 2.25855349e-05, 2.24482211e-05, 2.52860247e-05, 2.63680648e-05, + 2.65931493e-05, 2.59895172e-05, 2.52919077e-05, 2.45425554e-05, 2.36485327e-05, 2.33522360e-05, + 2.68680602e-05, 2.64299570e-05, 2.55645072e-05, 2.46988094e-05, 2.32553649e-05, 2.31551688e-05, + 2.32166845e-05, 2.60942478e-05, 2.66233959e-05, 2.59376741e-05, 2.54820962e-05, 2.47282011e-05, + 2.38446779e-05, 2.34441322e-05, 2.30053276e-05, 2.33281669e-05, 1.76405534e-05, 1.64504081e-05, + 1.92358725e-05, 2.39862478e-05, 2.87023985e-05, 3.12602588e-05, 3.12993150e-05, 3.08910236e-05, + 2.40488137e-05, 2.03533609e-05, 2.13928594e-05, 2.37489053e-05, 2.41511851e-05, 2.48569820e-05, + 2.83904417e-05, 3.12634381e-05, 3.06491277e-05, 2.99970306e-05, 3.11904839e-05, 2.19701874e-05, + 1.83433418e-05, 1.86449554e-05, 2.27453811e-05, 2.52071057e-05, 2.55866848e-05, 2.90409538e-05, + 3.25037676e-05, 3.35651743e-05, 1.86844728e-05, 1.29807397e-05, 1.51223906e-05, 2.45184481e-05, + 3.15171871e-05, 3.18228790e-05, 3.14840252e-05, 3.21505008e-05, 3.23075867e-05, 2.53261527e-05, + 1.84098540e-05, 1.63296634e-05, 2.18658620e-05, 2.70775046e-05, 2.66761636e-05, 2.59969732e-05, + 2.86247267e-05, 3.16908163e-05, 3.08986278e-05, 2.52479759e-05, 1.64343605e-05, 1.28999121e-05, + 1.62902079e-05, 2.38766317e-05, 3.15761260e-05, 3.39447113e-05, 3.29580945e-05, 1.91752285e-05, + 1.45670244e-05, 1.58002521e-05, 2.15323076e-05, 2.88070023e-05, 3.37994746e-05, 3.47951685e-05, + 3.28828848e-05, 1.72020004e-05, 1.35387839e-05, 1.57287976e-05, 2.22798333e-05, 3.13540620e-05, + 3.49821796e-05, 3.33665592e-05, 3.19067967e-05, 1.64771811e-05, 1.19652930e-05, 1.72326804e-05, + 2.48473188e-05, 2.79325766e-05, 2.90009140e-05, 3.06004158e-05, 2.13037930e-05, 1.81229136e-05, + 1.74540290e-05, 1.88812361e-05, 2.47612993e-05, 3.09883536e-05, 3.22625291e-05, 3.16124280e-05, + 2.22886780e-05, 1.90617059e-05, 1.92314779e-05, 2.16804896e-05, 2.36960356e-05, 2.54669409e-05, + 2.94922677e-05, 3.14259191e-05, 2.32224063e-05, 1.88413292e-05, 1.89628580e-05, 2.06301144e-05, + 2.19165867e-05, 2.52962287e-05, 2.94187213e-05, 3.17767511e-05, 3.16817658e-05, 2.63412200e-05, + 1.87483976e-05, 1.25878338e-05, 1.36054396e-05, 2.01429068e-05, 2.94456053e-05, 3.24151984e-05, + 2.91329728e-05, 1.99707419e-05, 1.68087281e-05, 1.95678074e-05, 2.47677583e-05, 2.60299662e-05, + 2.72349079e-05, 3.04588608e-05, 3.14306441e-05, 2.64971728e-05, 1.99414760e-05, 1.60531485e-05, + 1.94467689e-05, 2.41142374e-05, 2.85048882e-05, 3.11806470e-05, 3.13368003e-05, 2.35088740e-05, + 1.88926610e-05, 1.82206613e-05, 2.14983577e-05, 2.53591058e-05, 2.82631889e-05, 3.15101973e-05, + 3.04734005e-05, 2.87951733e-05, 2.39273263e-05, 1.67449560e-05, 1.37832972e-05, 1.86232693e-05, + 2.66257452e-05, 3.11707157e-05, 3.35868834e-05, 3.37657650e-05, 3.21946113e-05, 2.18558790e-05, + 1.86113054e-05, 1.81086220e-05, 2.25355360e-05, 2.83300755e-05, 2.72421905e-05, 2.90502749e-05, + 3.24668963e-05, 2.17880080e-05, 1.89599979e-05, 1.88743223e-05, 1.98516958e-05, 2.23358591e-05, + 2.81638849e-05, 3.09356428e-05, 2.97394883e-05, 1.98644202e-05, 1.49902298e-05, 1.68382190e-05, + 2.41439644e-05, 3.13097023e-05, 3.14767516e-05, 3.04105390e-05, 2.42522339e-05, 1.96624532e-05, + 1.69367438e-05, 1.81036083e-05, 2.27141477e-05, 2.65314585e-05, 2.93422006e-05, 3.22689470e-05, + 2.54933965e-05, 2.69469339e-05, 2.71294364e-05, 2.65860119e-05, 2.52892387e-05, 2.35844619e-05, + 2.24899568e-05, 2.24327538e-05, 2.25514564e-05, 2.52510130e-05, 2.63627059e-05, 2.60805533e-05, + 2.53581818e-05, 2.52264805e-05, 2.49841284e-05, 2.37004032e-05, 2.25277655e-05, 2.27242698e-05, + 2.29565929e-05, 2.24302937e-05, 2.59084209e-05, 2.67981636e-05, 2.67636374e-05, 2.56780491e-05, + 2.48799035e-05, 2.47194300e-05, 2.33535690e-05, 2.18758266e-05, 2.13948777e-05, 2.67351633e-05, + 2.72697541e-05, 2.72562357e-05, 2.51187288e-05, 2.25430213e-05, 2.22736144e-05, 2.22927056e-05, + 2.19973352e-05, 2.19356395e-05, 2.48538946e-05, 2.66923306e-05, 2.70950222e-05, 2.59292282e-05, + 2.42129097e-05, 2.42956237e-05, 2.44966638e-05, 2.34572935e-05, 2.21612552e-05, 2.27407966e-05, + 2.48786351e-05, 2.71034412e-05, 2.73468321e-05, 2.71517139e-05, 2.53197755e-05, 2.23371607e-05, + 2.11791809e-05, 2.16077140e-05, 2.66522057e-05, 2.72459976e-05, 2.71290585e-05, 2.60116576e-05, + 2.35726220e-05, 2.14259250e-05, 2.08862107e-05, 2.16871466e-05, 2.70676510e-05, 2.72524742e-05, + 2.71039708e-05, 2.58071215e-05, 2.25317909e-05, 2.08220118e-05, 2.14422964e-05, 2.21044721e-05, + 2.70894399e-05, 2.71035296e-05, 2.68958453e-05, 2.50104545e-05, 2.38761523e-05, 2.32868615e-05, + 2.25859783e-05, 2.60881520e-05, 2.67527393e-05, 2.68949314e-05, 2.67046229e-05, 2.49904010e-05, + 2.25303045e-05, 2.19546955e-05, 2.22369107e-05, 2.58118037e-05, 2.65974554e-05, 2.65709178e-05, + 2.59816773e-05, 2.53720994e-05, 2.47093811e-05, 2.31204265e-05, 2.23198282e-05, 2.55308463e-05, + 2.66769721e-05, 2.66569782e-05, 2.62513475e-05, 2.59216187e-05, 2.48088008e-05, 2.31622143e-05, + 2.21564753e-05, 2.22058735e-05, 2.45136814e-05, 2.65046747e-05, 2.71626851e-05, 2.73837470e-05, + 2.64313101e-05, 2.30875403e-05, 2.18394542e-05, 2.31924328e-05, 2.64265633e-05, 2.69361851e-05, + 2.64759045e-05, 2.50362792e-05, 2.45819133e-05, 2.40754688e-05, 2.27469604e-05, 2.23327324e-05, + 2.44617748e-05, 2.63723790e-05, 2.71494541e-05, 2.65705134e-05, 2.52371944e-05, 2.35628418e-05, + 2.23988314e-05, 2.23690867e-05, 2.54400785e-05, 2.66580720e-05, 2.67879088e-05, 2.60196704e-05, + 2.48349510e-05, 2.37204240e-05, 2.23167497e-05, 2.27070072e-05, 2.33650568e-05, 2.53080225e-05, + 2.70064924e-05, 2.73348600e-05, 2.67634220e-05, 2.43737481e-05, 2.25565678e-05, 2.13897280e-05, + 2.12685258e-05, 2.19745788e-05, 2.58936082e-05, 2.65446804e-05, 2.67404786e-05, 2.57387660e-05, + 2.36566852e-05, 2.39115922e-05, 2.31509651e-05, 2.17747560e-05, 2.59645648e-05, 2.65995286e-05, + 2.65916712e-05, 2.64432280e-05, 2.58026137e-05, 2.37652970e-05, 2.25966976e-05, 2.30144229e-05, + 2.63646448e-05, 2.69909555e-05, 2.70274052e-05, 2.52111064e-05, 2.23867052e-05, 2.23037262e-05, + 2.27313008e-05, 2.52043958e-05, 2.64318464e-05, 2.69679621e-05, 2.68439276e-05, 2.56792295e-05, + 2.42985199e-05, 2.31823137e-05, 2.19652323e-05, 2.55993561e-05, 2.82725395e-05, 2.87521702e-05, + 2.74681728e-05, 2.51844377e-05, 2.27759781e-05, 2.13709345e-05, 2.13247163e-05, 2.15151680e-05, + 2.52395986e-05, 2.70857242e-05, 2.65908836e-05, 2.53803680e-05, 2.51708584e-05, 2.48088793e-05, + 2.29408790e-05, 2.13916828e-05, 2.16918323e-05, 2.20271443e-05, 2.13534446e-05, 2.62497429e-05, + 2.79283695e-05, 2.78669694e-05, 2.58656360e-05, 2.46070684e-05, 2.44301169e-05, 2.25551232e-05, + 2.06352392e-05, 2.00383959e-05, 2.77941555e-05, 2.98200072e-05, 2.92190433e-05, 2.49201952e-05, + 2.13141762e-05, 2.10774974e-05, 2.11829078e-05, 2.08082182e-05, 2.07257955e-05, 2.44945609e-05, + 2.76896693e-05, 2.86921960e-05, 2.62544465e-05, 2.36350908e-05, 2.38484590e-05, 2.42053990e-05, + 2.27504704e-05, 2.10388652e-05, 2.16185888e-05, 2.45478198e-05, 2.86973588e-05, 2.99954208e-05, + 2.88178507e-05, 2.53044639e-05, 2.11867014e-05, 1.97932959e-05, 2.03337791e-05, 2.76430474e-05, + 2.93193334e-05, 2.88396598e-05, 2.63791757e-05, 2.27260194e-05, 2.00061005e-05, 1.93909051e-05, + 2.04093508e-05, 2.85709581e-05, 2.96092418e-05, 2.88025258e-05, 2.60357074e-05, 2.13651512e-05, + 1.93033093e-05, 2.01182426e-05, 2.09443961e-05, 2.86627505e-05, 2.98893605e-05, 2.81840376e-05, + 2.47149793e-05, 2.31843430e-05, 2.25316463e-05, 2.16177335e-05, 2.65390182e-05, 2.78270117e-05, + 2.81632832e-05, 2.77370137e-05, 2.48750860e-05, 2.14742528e-05, 2.07503743e-05, 2.11113250e-05, + 2.60675711e-05, 2.74836732e-05, 2.74310324e-05, 2.63463342e-05, 2.54160076e-05, 2.44976362e-05, + 2.22797620e-05, 2.12165840e-05, 2.56123625e-05, 2.76601356e-05, 2.76202509e-05, 2.68150465e-05, + 2.62621052e-05, 2.45882084e-05, 2.23271161e-05, 2.10136228e-05, 2.10720843e-05, 2.39218570e-05, + 2.73000816e-05, 2.97586296e-05, 2.98454613e-05, 2.72935040e-05, 2.22740180e-05, 2.06307920e-05, + 2.24334195e-05, 2.71579077e-05, 2.83116981e-05, 2.72307775e-05, 2.48054683e-05, 2.41881996e-05, + 2.35442915e-05, 2.17624360e-05, 2.12239129e-05, 2.38572321e-05, 2.70187410e-05, 2.88424976e-05, + 2.74585088e-05, 2.51930952e-05, 2.28458566e-05, 2.13351841e-05, 2.12733167e-05, 2.54827044e-05, + 2.76175625e-05, 2.79011002e-05, 2.63915497e-05, 2.45150899e-05, 2.30014111e-05, 2.11918608e-05, + 2.17331386e-05, 2.26427040e-05, 2.52161230e-05, 2.84598088e-05, 2.96968705e-05, 2.78631312e-05, + 2.38731719e-05, 2.14363495e-05, 2.00296994e-05, 1.98996533e-05, 2.07812329e-05, 2.61361656e-05, + 2.73850839e-05, 2.78022861e-05, 2.59440781e-05, 2.29519341e-05, 2.34665087e-05, 2.24305170e-05, + 2.05710531e-05, 2.63679162e-05, 2.74854391e-05, 2.74682606e-05, 2.71811871e-05, 2.60928846e-05, + 2.30565044e-05, 2.15305601e-05, 2.21405416e-05, 2.69973558e-05, 2.87453856e-05, 2.84937423e-05, + 2.51977365e-05, 2.12922773e-05, 2.11922417e-05, 2.17666295e-05, 2.50473773e-05, 2.71361125e-05, + 2.83601495e-05, 2.80308147e-05, 2.59459416e-05, 2.39136820e-05, 2.23629276e-05, 2.07561493e-05, + 2.56859285e-05, 2.75109570e-05, 2.77904959e-05, 2.64837492e-05, 2.46249613e-05, 2.31424718e-05, + 2.22045769e-05, 2.23223132e-05, 2.27033473e-05, 2.55491548e-05, 2.68974722e-05, 2.66082347e-05, + 2.54719485e-05, 2.52719065e-05, 2.50381251e-05, 2.33207034e-05, 2.20589488e-05, 2.25843139e-05, + 2.30559898e-05, 2.25294179e-05, 2.59381785e-05, 2.70963254e-05, 2.73872287e-05, 2.56408766e-05, + 2.45546165e-05, 2.48360022e-05, 2.35117620e-05, 2.18157578e-05, 2.12909514e-05, 2.70740473e-05, + 2.80994235e-05, 2.79690939e-05, 2.44265353e-05, 2.14086096e-05, 2.18563602e-05, 2.24116426e-05, + 2.20814617e-05, 2.19821206e-05, 2.39112636e-05, 2.61050642e-05, 2.73569352e-05, 2.56476658e-05, + 2.37624868e-05, 2.45588887e-05, 2.52860575e-05, 2.40059867e-05, 2.24153469e-05, 2.19582840e-05, + 2.40788735e-05, 2.75248597e-05, 2.86678846e-05, 2.78429971e-05, 2.52932666e-05, 2.21131040e-05, + 2.11787271e-05, 2.17322591e-05, 2.73190847e-05, 2.77335560e-05, 2.72764224e-05, 2.55466949e-05, + 2.28864328e-05, 2.08685110e-05, 2.05636575e-05, 2.16711506e-05, 2.82112727e-05, 2.78157132e-05, + 2.70489029e-05, 2.53714081e-05, 2.18483326e-05, 2.04297600e-05, 2.14802540e-05, 2.22062010e-05, + 2.74370302e-05, 2.76489310e-05, 2.64884764e-05, 2.39454007e-05, 2.35306761e-05, 2.38759094e-05, + 2.31203611e-05, 2.59453610e-05, 2.62620369e-05, 2.67094567e-05, 2.71802271e-05, 2.54790050e-05, + 2.25899688e-05, 2.20072319e-05, 2.23461958e-05, 2.56236436e-05, 2.62381856e-05, 2.62908615e-05, + 2.57319416e-05, 2.56025948e-05, 2.54247881e-05, 2.34839241e-05, 2.24357701e-05, 2.53245032e-05, + 2.66931781e-05, 2.67255933e-05, 2.59306209e-05, 2.58543602e-05, 2.51391500e-05, 2.34777774e-05, + 2.22857588e-05, 2.23131177e-05, 2.29182194e-05, 2.50163179e-05, 2.76049512e-05, 2.87621980e-05, + 2.78127284e-05, 2.36957826e-05, 2.20409636e-05, 2.39491420e-05, 2.63647933e-05, 2.64501369e-05, + 2.59375346e-05, 2.44286206e-05, 2.43655867e-05, 2.43463603e-05, 2.28829901e-05, 2.23903338e-05, + 2.29593578e-05, 2.56008360e-05, 2.76119375e-05, 2.68769004e-05, 2.53310830e-05, 2.38080381e-05, + 2.26384556e-05, 2.24499647e-05, 2.53471568e-05, 2.65781863e-05, 2.67447062e-05, 2.55364839e-05, + 2.43005333e-05, 2.35779782e-05, 2.22962843e-05, 2.29872569e-05, 2.40079670e-05, 2.46677267e-05, + 2.69562382e-05, 2.83653135e-05, 2.73184046e-05, 2.40144762e-05, 2.21414114e-05, 2.12701749e-05, + 2.12577627e-05, 2.20670580e-05, 2.49183026e-05, 2.51635419e-05, 2.61375875e-05, 2.55138066e-05, + 2.37675258e-05, 2.51713204e-05, 2.42402200e-05, 2.21047482e-05, 2.62311860e-05, 2.60736019e-05, + 2.58616363e-05, 2.62354500e-05, 2.59989188e-05, 2.35833788e-05, 2.24695595e-05, 2.33691369e-05, + 2.53729978e-05, 2.61239401e-05, 2.72290012e-05, 2.56533695e-05, 2.24460761e-05, 2.23930886e-05, + 2.30272244e-05, 2.44813217e-05, 2.56613988e-05, 2.68063017e-05, 2.71605305e-05, 2.63203776e-05, + 2.49912416e-05, 2.35613181e-05, 2.19704133e-05, 2.47196264e-05, 2.15550310e-05, 2.07793270e-05, + 2.17086955e-05, 2.36083993e-05, 2.62166997e-05, 2.75388460e-05, 2.79248612e-05, 2.83254554e-05, + 2.53143659e-05, 2.34289085e-05, 2.40995042e-05, 2.48234295e-05, 2.49278296e-05, 2.53247818e-05, + 2.62073603e-05, 2.71528277e-05, 2.76143539e-05, 2.78506613e-05, 2.83308429e-05, 2.36469410e-05, + 2.16840912e-05, 2.23774601e-05, 2.39935716e-05, 2.48265409e-05, 2.58218691e-05, 2.75608455e-05, + 2.84703266e-05, 2.87290067e-05, 2.19851903e-05, 1.80570047e-05, 1.97753206e-05, 2.38309729e-05, + 2.58467134e-05, 2.74588119e-05, 2.84867947e-05, 2.86607397e-05, 2.86350986e-05, 2.37824933e-05, + 2.04484836e-05, 2.01437477e-05, 2.30775402e-05, 2.54926410e-05, 2.66515496e-05, 2.72921349e-05, + 2.81612521e-05, 2.88595638e-05, 2.63700079e-05, 2.39993376e-05, 2.04405331e-05, 1.85652330e-05, + 2.06940362e-05, 2.46512302e-05, 2.77843939e-05, 2.90854398e-05, 2.90390680e-05, 2.28207641e-05, + 1.90241021e-05, 1.95810134e-05, 2.25860854e-05, 2.57789541e-05, 2.77839437e-05, 2.86011802e-05, + 2.86991531e-05, 2.20416549e-05, 1.82367396e-05, 1.92589709e-05, 2.30658272e-05, 2.67337608e-05, + 2.84922723e-05, 2.89839225e-05, 2.86092534e-05, 2.03732199e-05, 1.67909769e-05, 1.98951704e-05, + 2.33403406e-05, 2.60754194e-05, 2.84203904e-05, 2.90214462e-05, 2.29643988e-05, 2.03943821e-05, + 2.03610325e-05, 2.23263819e-05, 2.60538547e-05, 2.81677761e-05, 2.86321497e-05, 2.85149305e-05, + 2.34776199e-05, 2.12118819e-05, 2.14409225e-05, 2.30194399e-05, 2.49960198e-05, 2.68616555e-05, + 2.81800490e-05, 2.84580257e-05, 2.39796828e-05, 2.16182677e-05, 2.17787079e-05, 2.22703540e-05, + 2.34562424e-05, 2.60596363e-05, 2.80487861e-05, 2.86205226e-05, 2.85367856e-05, 2.30617467e-05, + 1.93668242e-05, 1.72460746e-05, 1.92898976e-05, 2.46162494e-05, 2.86657441e-05, 2.90164810e-05, + 2.88279274e-05, 2.22528589e-05, 1.94854460e-05, 2.12724934e-05, 2.41040624e-05, 2.54340589e-05, + 2.69430108e-05, 2.81175499e-05, 2.83342460e-05, 2.32948413e-05, 2.11546236e-05, 2.01983140e-05, + 2.24647649e-05, 2.49924265e-05, 2.74945395e-05, 2.86283961e-05, 2.83483308e-05, 2.43327581e-05, + 2.15114634e-05, 2.11033063e-05, 2.25370166e-05, 2.45270073e-05, 2.66173042e-05, 2.81964888e-05, + 2.84274999e-05, 2.84336966e-05, 2.36190981e-05, 2.00331424e-05, 1.90232496e-05, 2.22604862e-05, + 2.54550601e-05, 2.72324319e-05, 2.87007381e-05, 2.90046150e-05, 2.86951951e-05, 2.19533407e-05, + 1.94366951e-05, 2.02247973e-05, 2.35595438e-05, 2.71471315e-05, 2.88847187e-05, 2.94794116e-05, + 2.93213912e-05, 2.39233681e-05, 2.08998159e-05, 2.05454202e-05, 2.19531465e-05, 2.41415872e-05, + 2.64959053e-05, 2.77517263e-05, 2.82706206e-05, 2.07757719e-05, 1.76492392e-05, 2.04477694e-05, + 2.56225001e-05, 2.82917705e-05, 2.84202215e-05, 2.84343928e-05, 2.36430505e-05, 2.09841226e-05, + 2.00214141e-05, 2.15393189e-05, 2.51191506e-05, 2.73958491e-05, 2.81451864e-05, 2.85305231e-05, + 2.30346336e-05, 1.67713691e-05, 1.55163968e-05, 1.76966334e-05, 2.21704320e-05, 2.83314233e-05, + 3.20964273e-05, 3.27049579e-05, 3.29738197e-05, 2.41514194e-05, 1.99640328e-05, 2.12337638e-05, + 2.34044126e-05, 2.37677777e-05, 2.46678238e-05, 2.81021818e-05, 3.15268951e-05, 3.17273560e-05, + 3.15605709e-05, 3.32280920e-05, 2.10802430e-05, 1.72338120e-05, 1.80346315e-05, 2.18906373e-05, + 2.42946713e-05, 2.57311401e-05, 3.04152441e-05, 3.45492871e-05, 3.58991031e-05, 1.76843853e-05, + 1.18207628e-05, 1.40682185e-05, 2.27265511e-05, 2.98096454e-05, 3.24227069e-05, 3.37095048e-05, + 3.45454194e-05, 3.46404943e-05, 2.31378737e-05, 1.61291661e-05, 1.49149202e-05, 2.04223611e-05, + 2.62928729e-05, 2.74964307e-05, 2.78379764e-05, 3.09338705e-05, 3.44603530e-05, 3.01133283e-05, + 2.33455087e-05, 1.52167536e-05, 1.21664101e-05, 1.53682219e-05, 2.32850968e-05, 3.27168351e-05, + 3.68391780e-05, 3.58608118e-05, 1.87332283e-05, 1.32219412e-05, 1.42057516e-05, 1.97340884e-05, + 2.78176364e-05, 3.45607438e-05, 3.68055454e-05, 3.52439043e-05, 1.69949957e-05, 1.21825408e-05, + 1.39076727e-05, 2.06338588e-05, 3.09798666e-05, 3.67918148e-05, 3.61395698e-05, 3.42560658e-05, + 1.51784318e-05, 1.05065841e-05, 1.51041276e-05, 2.23534195e-05, 2.76132100e-05, 3.15921176e-05, + 3.37779163e-05, 2.00028103e-05, 1.59486217e-05, 1.56133635e-05, 1.81067538e-05, 2.54747049e-05, + 3.28171619e-05, 3.45969773e-05, 3.38605856e-05, 2.10768622e-05, 1.71418186e-05, 1.74400707e-05, + 2.02617605e-05, 2.35689773e-05, 2.69296479e-05, 3.16375835e-05, 3.36168696e-05, 2.21484409e-05, + 1.74169017e-05, 1.76280927e-05, 1.89459118e-05, 2.08485891e-05, 2.58310375e-05, 3.13925438e-05, + 3.41627713e-05, 3.39527438e-05, 2.28718850e-05, 1.52976126e-05, 1.10698540e-05, 1.30178429e-05, + 2.10539037e-05, 3.22984311e-05, 3.53399215e-05, 3.22789318e-05, 1.85913820e-05, 1.45636922e-05, + 1.74428114e-05, 2.31854099e-05, 2.55428509e-05, 2.82630752e-05, 3.23150146e-05, 3.34319868e-05, + 2.32377452e-05, 1.75096931e-05, 1.48365233e-05, 1.85294674e-05, 2.38197312e-05, 2.99218009e-05, + 3.36712577e-05, 3.33755861e-05, 2.27075177e-05, 1.73416117e-05, 1.66390661e-05, 1.96657993e-05, + 2.40324488e-05, 2.85596684e-05, 3.32880349e-05, 3.27844727e-05, 3.14486204e-05, 2.21490439e-05, + 1.50064871e-05, 1.28878918e-05, 1.79130431e-05, 2.59522613e-05, 3.15725509e-05, 3.58720450e-05, + 3.65383777e-05, 3.46376244e-05, 1.92497540e-05, 1.53014870e-05, 1.57891799e-05, 2.13018178e-05, + 2.93201082e-05, 3.08531611e-05, 3.31511276e-05, 3.58754413e-05, 2.12714171e-05, 1.68012438e-05, + 1.64320718e-05, 1.82383920e-05, 2.18169461e-05, 2.83279728e-05, 3.21553884e-05, 3.19635580e-05, + 1.71098621e-05, 1.23060523e-05, 1.54080396e-05, 2.45691610e-05, 3.32673249e-05, 3.36015660e-05, + 3.27434175e-05, 2.23604806e-05, 1.72131518e-05, 1.50821391e-05, 1.69827563e-05, 2.31116272e-05, + 2.83506051e-05, 3.14698927e-05, 3.44426290e-05, 2.21723270e-05, 1.49844214e-05, 1.36283761e-05, + 1.62057596e-05, 2.15932651e-05, 2.91082232e-05, 3.39210735e-05, 3.45613570e-05, 3.46591094e-05, + 2.34392348e-05, 1.84911014e-05, 1.99285703e-05, 2.26504128e-05, 2.31198071e-05, 2.41962357e-05, + 2.87640211e-05, 3.33396500e-05, 3.32862836e-05, 3.28435012e-05, 3.50503529e-05, 1.99720702e-05, + 1.55653905e-05, 1.63285703e-05, 2.09441832e-05, 2.39673113e-05, 2.54503472e-05, 3.13029782e-05, + 3.70048398e-05, 3.89183551e-05, 1.60419788e-05, 9.84229411e-06, 1.21170691e-05, 2.22772431e-05, + 3.16869064e-05, 3.44964508e-05, 3.56748491e-05, 3.68400852e-05, 3.70106718e-05, 2.29224982e-05, + 1.46482721e-05, 1.31046554e-05, 1.93524129e-05, 2.65200676e-05, 2.75288149e-05, 2.75977158e-05, + 3.16459436e-05, 3.65428407e-05, 3.17498738e-05, 2.30915575e-05, 1.33785588e-05, 1.00899253e-05, + 1.34654024e-05, 2.25832187e-05, 3.46932672e-05, 4.01013919e-05, 3.85915229e-05, 1.70772324e-05, + 1.13072170e-05, 1.23949002e-05, 1.86401723e-05, 2.86414292e-05, 3.76060835e-05, 4.04767850e-05, + 3.79069821e-05, 1.50503144e-05, 1.02497072e-05, 1.21357720e-05, 1.96670445e-05, 3.28177568e-05, + 4.05524061e-05, 3.90794256e-05, 3.64291264e-05, 1.33580912e-05, 8.61566652e-06, 1.34879548e-05, + 2.20356803e-05, 2.81131346e-05, 3.24559625e-05, 3.53509878e-05, 1.88106542e-05, 1.44214495e-05, + 1.39681062e-05, 1.64570966e-05, 2.49155428e-05, 3.45414590e-05, 3.69447747e-05, 3.58878664e-05, + 2.00676063e-05, 1.56828626e-05, 1.59844935e-05, 1.91534026e-05, 2.27837972e-05, 2.65374139e-05, + 3.27084933e-05, 3.55536517e-05, 2.13300742e-05, 1.58577073e-05, 1.60714573e-05, 1.76823631e-05, + 1.97484755e-05, 2.54404657e-05, 3.24325257e-05, 3.62738530e-05, 3.60140390e-05, 2.29988827e-05, + 1.40275442e-05, 9.17810178e-06, 1.09163754e-05, 1.93759138e-05, 3.33502552e-05, 3.77905160e-05, + 3.31963436e-05, 1.71842793e-05, 1.29351480e-05, 1.60785975e-05, 2.27845902e-05, 2.54296278e-05, + 2.84795398e-05, 3.38018285e-05, 3.53655126e-05, 2.33970320e-05, 1.62379839e-05, 1.29707256e-05, + 1.69807435e-05, 2.31553284e-05, 3.05980108e-05, 3.55005634e-05, 3.52661220e-05, 2.19326743e-05, + 1.58075788e-05, 1.50296125e-05, 1.85695618e-05, 2.37727517e-05, 2.91640142e-05, 3.52524217e-05, + 3.42845027e-05, 3.22268113e-05, 2.15549045e-05, 1.32846071e-05, 1.08574968e-05, 1.62191202e-05, + 2.60312556e-05, 3.33475439e-05, 3.88998613e-05, 3.96939791e-05, 3.69561459e-05, 1.83031533e-05, + 1.39969903e-05, 1.42833586e-05, 2.03465356e-05, 2.99363530e-05, 3.09928320e-05, 3.40306869e-05, + 3.83752224e-05, 2.00860269e-05, 1.53644587e-05, 1.50267136e-05, 1.68445868e-05, 2.07475435e-05, + 2.88989064e-05, 3.38432059e-05, 3.31400024e-05, 1.58707411e-05, 1.06737920e-05, 1.36395810e-05, + 2.38577560e-05, 3.51429909e-05, 3.55604543e-05, 3.42155394e-05, 2.18530674e-05, 1.59060297e-05, + 1.33953663e-05, 1.52878762e-05, 2.20386657e-05, 2.82926743e-05, 3.24777305e-05, 3.67868959e-05, + 2.25984868e-05, 1.58866678e-05, 1.45736452e-05, 1.74222418e-05, 2.28274477e-05, 2.92369234e-05, + 3.30699766e-05, 3.33458612e-05, 3.30598744e-05, 2.36067453e-05, 1.90874675e-05, 2.03658102e-05, + 2.30840841e-05, 2.35545606e-05, 2.44826331e-05, 2.88678940e-05, 3.28479005e-05, 3.23477805e-05, + 3.16697323e-05, 3.34451402e-05, 2.07804203e-05, 1.65783759e-05, 1.70836854e-05, 2.17040330e-05, + 2.46433843e-05, 2.55011348e-05, 3.03426920e-05, 3.52347410e-05, 3.68193114e-05, 1.69944221e-05, + 1.08783739e-05, 1.31224195e-05, 2.34767346e-05, 3.23924304e-05, 3.37340058e-05, 3.39145002e-05, + 3.48878214e-05, 3.50786972e-05, 2.43064747e-05, 1.62419754e-05, 1.42827017e-05, 2.04595587e-05, + 2.70110135e-05, 2.71078511e-05, 2.66268331e-05, 3.01507267e-05, 3.44060243e-05, 3.19437547e-05, + 2.43203015e-05, 1.44614376e-05, 1.09321431e-05, 1.44057148e-05, 2.31479247e-05, 3.36149759e-05, + 3.75759306e-05, 3.62000676e-05, 1.77340515e-05, 1.24459087e-05, 1.36577606e-05, 1.99436735e-05, + 2.91311165e-05, 3.65094691e-05, 3.84204239e-05, 3.58819482e-05, 1.56280981e-05, 1.13823157e-05, + 1.35050340e-05, 2.08691347e-05, 3.27148508e-05, 3.86037912e-05, 3.67171470e-05, 3.45371217e-05, + 1.44800456e-05, 9.76448359e-06, 1.50091800e-05, 2.36074489e-05, 2.82706350e-05, 3.07464301e-05, + 3.30874000e-05, 1.98589776e-05, 1.59640443e-05, 1.53500234e-05, 1.72911742e-05, 2.46928959e-05, + 3.30924681e-05, 3.50175407e-05, 3.40973756e-05, 2.10374074e-05, 1.70931390e-05, 1.73282970e-05, + 2.02529702e-05, 2.30990048e-05, 2.58309655e-05, 3.12247267e-05, 3.38224513e-05, 2.21899044e-05, + 1.70219948e-05, 1.71887074e-05, 1.89475624e-05, 2.06540371e-05, 2.52853412e-05, 3.10633968e-05, + 3.43742886e-05, 3.42003885e-05, 2.50501841e-05, 1.61894045e-05, 1.03666293e-05, 1.16973997e-05, + 1.92883209e-05, 3.14282949e-05, 3.54582185e-05, 3.11252227e-05, 1.83060904e-05, 1.45107353e-05, + 1.75861590e-05, 2.38573289e-05, 2.58156933e-05, 2.78905510e-05, 3.23948321e-05, 3.37552272e-05, + 2.53260288e-05, 1.78957328e-05, 1.40539465e-05, 1.78760980e-05, 2.35422484e-05, 2.96626150e-05, + 3.36067171e-05, 3.36429703e-05, 2.26307183e-05, 1.70348741e-05, 1.62797028e-05, 1.98919042e-05, + 2.46741558e-05, 2.89281896e-05, 3.37757294e-05, 3.25882762e-05, 3.05004194e-05, 2.27708959e-05, + 1.46180184e-05, 1.17820252e-05, 1.70255492e-05, 2.64871324e-05, 3.27786390e-05, 3.68300973e-05, + 3.72756282e-05, 3.49670250e-05, 2.00208623e-05, 1.60903880e-05, 1.58968017e-05, 2.13193959e-05, + 2.92765556e-05, 2.88370828e-05, 3.13665202e-05, 3.57179605e-05, 2.07004548e-05, 1.68947928e-05, + 1.66979032e-05, 1.80885889e-05, 2.13415967e-05, 2.87505181e-05, 3.27852964e-05, 3.15804123e-05, + 1.76909338e-05, 1.24305188e-05, 1.48240630e-05, 2.38376890e-05, 3.35748925e-05, 3.38655764e-05, + 3.25126741e-05, 2.31182994e-05, 1.75753212e-05, 1.47846446e-05, 1.63097915e-05, 2.21126951e-05, + 2.72903193e-05, 3.10208125e-05, 3.49632188e-05, 2.27930074e-05, 1.63320887e-05, 1.50458604e-05, + 1.79460363e-05, 2.32583139e-05, 2.91779750e-05, 3.26160362e-05, 3.27835378e-05, 3.24045859e-05, + 2.37046944e-05, 1.93967252e-05, 2.06065866e-05, 2.32704993e-05, 2.37309992e-05, 2.45948866e-05, + 2.88127016e-05, 3.25003434e-05, 3.18943361e-05, 3.11747711e-05, 3.27749954e-05, 2.11238972e-05, + 1.70499098e-05, 1.74695406e-05, 2.20152267e-05, 2.48654348e-05, 2.55213608e-05, 2.99475439e-05, + 3.44568492e-05, 3.58948014e-05, 1.74418637e-05, 1.14022095e-05, 1.36252478e-05, 2.38824899e-05, + 3.23993088e-05, 3.32813861e-05, 3.31867775e-05, 3.40745383e-05, 3.42637770e-05, 2.47489941e-05, + 1.69029746e-05, 1.48314393e-05, 2.08995862e-05, 2.71189100e-05, 2.69540345e-05, 2.63345019e-05, + 2.96174634e-05, 3.35617637e-05, 3.18187297e-05, 2.47152045e-05, 1.49781147e-05, 1.13928835e-05, + 1.48778890e-05, 2.33713201e-05, 3.30804234e-05, 3.65105012e-05, 3.52229943e-05, 1.80814966e-05, + 1.29961386e-05, 1.42395191e-05, 2.04537567e-05, 2.91788030e-05, 3.58641822e-05, 3.74435803e-05, + 3.50126885e-05, 1.59771495e-05, 1.19361224e-05, 1.41230033e-05, 2.13305643e-05, 3.24802267e-05, + 3.76478820e-05, 3.57277969e-05, 3.37524245e-05, 1.50089845e-05, 1.03285762e-05, 1.56619101e-05, + 2.41244477e-05, 2.82478590e-05, 3.01378069e-05, 3.22564832e-05, 2.02918404e-05, 1.66120416e-05, + 1.59533377e-05, 1.76983531e-05, 2.46551718e-05, 3.24761391e-05, 3.42061105e-05, 3.33552090e-05, + 2.14247151e-05, 1.76830254e-05, 1.78936386e-05, 2.06944724e-05, 2.32506502e-05, 2.56311774e-05, + 3.06609047e-05, 3.31056881e-05, 2.25211396e-05, 1.75349812e-05, 1.76846994e-05, 1.94630200e-05, + 2.10291376e-05, 2.52524777e-05, 3.05353569e-05, 3.35934497e-05, 3.34484372e-05, 2.56814740e-05, + 1.70415699e-05, 1.09427923e-05, 1.21364257e-05, 1.93952040e-05, 3.07419781e-05, 3.45244782e-05, + 3.04096139e-05, 1.87872151e-05, 1.51870891e-05, 1.81999295e-05, 2.42159789e-05, 2.59243391e-05, + 2.76688730e-05, 3.18133127e-05, 3.30729259e-05, 2.59116231e-05, 1.85530548e-05, 1.45743953e-05, + 1.82938838e-05, 2.37050369e-05, 2.92948930e-05, 3.28545429e-05, 3.29611726e-05, 2.29045390e-05, + 1.75674967e-05, 1.68294926e-05, 2.04087899e-05, 2.49621831e-05, 2.87753474e-05, 3.31283348e-05, + 3.19232360e-05, 2.98950355e-05, 2.31974509e-05, 1.52136335e-05, 1.22664057e-05, 1.74277795e-05, + 2.65987462e-05, 3.24120964e-05, 3.59128573e-05, 3.62498863e-05, 3.41411541e-05, 2.06601235e-05, + 1.69206229e-05, 1.65688825e-05, 2.17021687e-05, 2.89957537e-05, 2.81695712e-05, 3.04900036e-05, + 3.46903899e-05, 2.09875325e-05, 1.75260991e-05, 1.73778715e-05, 1.86111468e-05, 2.16106219e-05, + 2.86273731e-05, 3.22847307e-05, 3.09849441e-05, 1.84045139e-05, 1.31895829e-05, 1.53695823e-05, + 2.38768774e-05, 3.29101208e-05, 3.31569268e-05, 3.18484160e-05, 2.35521897e-05, 1.82414645e-05, + 1.53966747e-05, 1.67874257e-05, 2.22152833e-05, 2.69718673e-05, 3.04706454e-05, 3.41811057e-05, + 2.34963968e-05, 1.80414374e-05, 1.68847828e-05, 1.94708989e-05, 2.39002841e-05, 2.84146427e-05, + 3.08576566e-05, 3.09598082e-05, 3.06750463e-05, 2.42171990e-05, 2.06936206e-05, 2.17045959e-05, + 2.38806284e-05, 2.42485005e-05, 2.49264181e-05, 2.81429763e-05, 3.07913824e-05, 3.03417708e-05, + 2.98160960e-05, 3.09363830e-05, 2.21475891e-05, 1.86808272e-05, 1.90399400e-05, 2.28778376e-05, + 2.51537856e-05, 2.56412204e-05, 2.89349936e-05, 3.21008022e-05, 3.30671033e-05, 1.90226733e-05, + 1.34578196e-05, 1.55771193e-05, 2.43972606e-05, 3.07692815e-05, 3.13293519e-05, 3.12186938e-05, + 3.18283419e-05, 3.19601645e-05, 2.50882329e-05, 1.85701026e-05, 1.66968620e-05, 2.19725129e-05, + 2.68857478e-05, 2.67237251e-05, 2.62269392e-05, 2.86696903e-05, 3.14635462e-05, 3.03356826e-05, + 2.50562075e-05, 1.68276470e-05, 1.34426535e-05, 1.67314796e-05, 2.39663468e-05, 3.11746444e-05, + 3.34615201e-05, 3.25972039e-05, 1.95687889e-05, 1.49904539e-05, 1.61557338e-05, 2.16082427e-05, + 2.84296513e-05, 3.30923923e-05, 3.41056096e-05, 3.24706723e-05, 1.77129221e-05, 1.39784286e-05, + 1.60512509e-05, 2.23321739e-05, 3.07935888e-05, 3.42458455e-05, 3.29417188e-05, 3.16075603e-05, + 1.68570532e-05, 1.24026248e-05, 1.74611261e-05, 2.46021763e-05, 2.77239861e-05, 2.90410710e-05, + 3.05398736e-05, 2.14640783e-05, 1.83111326e-05, 1.77187957e-05, 1.92424162e-05, 2.49535903e-05, + 3.07324126e-05, 3.19205309e-05, 3.13352124e-05, 2.24015365e-05, 1.92485188e-05, 1.94296093e-05, + 2.18018562e-05, 2.38601681e-05, 2.56954721e-05, 2.94313918e-05, 3.11631665e-05, 2.32928059e-05, + 1.91112824e-05, 1.92403150e-05, 2.07734696e-05, 2.20727149e-05, 2.54237795e-05, 2.93454266e-05, + 3.14965357e-05, 3.13992974e-05, 2.58384040e-05, 1.87084236e-05, 1.30122846e-05, 1.41600481e-05, + 2.06662010e-05, 2.94704835e-05, 3.21213759e-05, 2.92227044e-05, 2.01928369e-05, 1.70331183e-05, + 1.97002824e-05, 2.46571105e-05, 2.59665035e-05, 2.72584154e-05, 3.02633782e-05, 3.11456481e-05, + 2.60125650e-05, 2.00094269e-05, 1.64583675e-05, 1.97608890e-05, 2.42259901e-05, 2.84566062e-05, + 3.09793213e-05, 3.10665833e-05, 2.35965615e-05, 1.91417760e-05, 1.84943649e-05, 2.15713189e-05, + 2.52379784e-05, 2.81013674e-05, 3.11905312e-05, 3.03288218e-05, 2.88629387e-05, 2.38508287e-05, + 1.70499096e-05, 1.42894216e-05, 1.90052409e-05, 2.64877046e-05, 3.07256219e-05, 3.30806777e-05, + 3.32915646e-05, 3.18727583e-05, 2.17939360e-05, 1.85999454e-05, 1.82749888e-05, 2.26295405e-05, + 2.82471926e-05, 2.75663505e-05, 2.92538978e-05, 3.22201712e-05, 2.20276304e-05, 1.91153813e-05, + 1.89900311e-05, 2.00459818e-05, 2.25405944e-05, 2.79948934e-05, 3.06141511e-05, 2.96622762e-05, + 1.98865094e-05, 1.51904127e-05, 1.71865762e-05, 2.43467552e-05, 3.10331711e-05, 3.12007420e-05, + 3.02751905e-05, 2.41364897e-05, 1.97412355e-05, 1.72175718e-05, 1.84495793e-05, 2.30147295e-05, + 2.67128523e-05, 2.92945686e-05, 3.19079918e-05, 2.57275539e-05, 2.83500585e-05, 2.88238037e-05, + 2.71237350e-05, 2.46808231e-05, 2.26645442e-05, 2.14745534e-05, 2.15620457e-05, 2.19373582e-05, + 2.54872350e-05, 2.73144122e-05, 2.68750596e-05, 2.54691813e-05, 2.52271618e-05, 2.49070784e-05, + 2.28642767e-05, 2.13566001e-05, 2.18843472e-05, 2.23781997e-05, 2.17457308e-05, 2.61762657e-05, + 2.78420429e-05, 2.80588678e-05, 2.57831954e-05, 2.44286557e-05, 2.46117534e-05, 2.29154821e-05, + 2.09495265e-05, 2.03513884e-05, 2.77627749e-05, 2.97613299e-05, 2.92343845e-05, 2.44228981e-05, + 2.07848525e-05, 2.11005266e-05, 2.15998667e-05, 2.12201729e-05, 2.11142638e-05, 2.38448430e-05, + 2.69062231e-05, 2.84358855e-05, 2.59312033e-05, 2.34478406e-05, 2.41926791e-05, 2.49259157e-05, + 2.33934152e-05, 2.15646208e-05, 2.13329498e-05, 2.40045349e-05, 2.85761778e-05, 3.03291212e-05, + 2.89021523e-05, 2.52907303e-05, 2.13474135e-05, 2.01944601e-05, 2.08006037e-05, 2.79033442e-05, + 2.91107637e-05, 2.84524460e-05, 2.58927099e-05, 2.24323588e-05, 1.99861523e-05, 1.95746335e-05, + 2.07683285e-05, 2.90809652e-05, 2.93801293e-05, 2.82479306e-05, 2.56158012e-05, 2.11708735e-05, + 1.94400936e-05, 2.05319137e-05, 2.13619577e-05, 2.84856637e-05, 2.95153369e-05, 2.74600096e-05, + 2.39461472e-05, 2.31148106e-05, 2.32195426e-05, 2.23202300e-05, 2.62915270e-05, 2.71000779e-05, + 2.76314646e-05, 2.78268762e-05, 2.53058169e-05, 2.18298545e-05, 2.11420068e-05, 2.15251605e-05, + 2.58416580e-05, 2.69246797e-05, 2.69458452e-05, 2.60372026e-05, 2.55929819e-05, 2.51372163e-05, + 2.28136012e-05, 2.16293782e-05, 2.54239563e-05, 2.73834534e-05, 2.73930678e-05, 2.63870299e-05, + 2.61095834e-05, 2.49216583e-05, 2.28217159e-05, 2.14478481e-05, 2.14866165e-05, 2.28200181e-05, + 2.58292281e-05, 2.93533888e-05, 3.02815642e-05, 2.81784264e-05, 2.29927531e-05, 2.11393389e-05, + 2.32541747e-05, 2.68925927e-05, 2.74941496e-05, 2.65638703e-05, 2.43864813e-05, 2.41333877e-05, + 2.39183932e-05, 2.21577300e-05, 2.15927411e-05, 2.28345281e-05, 2.61926269e-05, 2.87263503e-05, + 2.74507055e-05, 2.52851927e-05, 2.32519742e-05, 2.18335056e-05, 2.16566542e-05, 2.53980019e-05, + 2.72682297e-05, 2.75356173e-05, 2.58887866e-05, 2.41824139e-05, 2.31011444e-05, 2.15042816e-05, + 2.22384364e-05, 2.33641175e-05, 2.47279894e-05, 2.79846430e-05, 2.98650752e-05, 2.79991618e-05, + 2.37356523e-05, 2.14386401e-05, 2.03316037e-05, 2.02881291e-05, 2.12008598e-05, 2.52698719e-05, + 2.59889968e-05, 2.69855081e-05, 2.57033175e-05, 2.32482901e-05, 2.46015516e-05, 2.35022367e-05, + 2.11778917e-05, 2.64697018e-05, 2.67879980e-05, 2.66038615e-05, 2.67932178e-05, 2.61703516e-05, + 2.31219324e-05, 2.17428128e-05, 2.26766403e-05, 2.59931470e-05, 2.74838958e-05, 2.82261532e-05, + 2.55622635e-05, 2.16584444e-05, 2.15866013e-05, 2.22816612e-05, 2.45122248e-05, 2.62926141e-05, + 2.78101591e-05, 2.79430033e-05, 2.63920163e-05, 2.45827232e-05, 2.29030917e-05, 2.11122926e-05, + 2.55850187e-05, 2.66305091e-05, 2.67245675e-05, 2.59259225e-05, 2.47089305e-05, 2.36665947e-05, + 2.29323702e-05, 2.30373743e-05, 2.33604377e-05, 2.55164623e-05, 2.63856774e-05, 2.62292548e-05, + 2.54292574e-05, 2.52829718e-05, 2.51253037e-05, 2.38099750e-05, 2.28036981e-05, 2.32482412e-05, + 2.36410781e-05, 2.32164393e-05, 2.57004049e-05, 2.63563934e-05, 2.66352764e-05, 2.55035123e-05, + 2.47255211e-05, 2.49934210e-05, 2.40051779e-05, 2.26220152e-05, 2.21804497e-05, 2.63733779e-05, + 2.64816285e-05, 2.66992401e-05, 2.45705984e-05, 2.22333344e-05, 2.26407667e-05, 2.31210879e-05, + 2.28476875e-05, 2.27639812e-05, 2.41692724e-05, 2.55185375e-05, 2.63445118e-05, 2.54413224e-05, + 2.41358989e-05, 2.48120737e-05, 2.54074438e-05, 2.44203812e-05, 2.31296444e-05, 2.27026310e-05, + 2.43116656e-05, 2.64990205e-05, 2.69370490e-05, 2.67485524e-05, 2.52830668e-05, 2.28607888e-05, + 2.20873998e-05, 2.25577921e-05, 2.66319003e-05, 2.64237535e-05, 2.62093861e-05, 2.53270522e-05, + 2.34450713e-05, 2.18111640e-05, 2.15563379e-05, 2.25026933e-05, 2.71700328e-05, 2.63369928e-05, + 2.60085715e-05, 2.52348746e-05, 2.26197747e-05, 2.14401593e-05, 2.23436380e-05, 2.29514629e-05, + 2.64303308e-05, 2.59341109e-05, 2.57172611e-05, 2.41699060e-05, 2.39738859e-05, 2.43218250e-05, + 2.37168210e-05, 2.56521119e-05, 2.56224907e-05, 2.59301451e-05, 2.64839818e-05, 2.55018685e-05, + 2.32637642e-05, 2.27850328e-05, 2.30669958e-05, 2.54538545e-05, 2.56986358e-05, 2.57604956e-05, + 2.54991588e-05, 2.55387361e-05, 2.54975593e-05, 2.39979845e-05, 2.31407157e-05, 2.52644561e-05, + 2.60651809e-05, 2.61051649e-05, 2.55814976e-05, 2.56238361e-05, 2.52398739e-05, 2.39899081e-05, + 2.30181144e-05, 2.30397353e-05, 2.33516217e-05, 2.46180336e-05, 2.60066999e-05, 2.71315527e-05, + 2.71453420e-05, 2.41812534e-05, 2.28179611e-05, 2.43905402e-05, 2.58945801e-05, 2.56355710e-05, + 2.54901124e-05, 2.45882869e-05, 2.46083600e-05, 2.46549617e-05, 2.35047113e-05, 2.31009267e-05, + 2.33966251e-05, 2.52355136e-05, 2.65241718e-05, 2.62823560e-05, 2.53318582e-05, 2.42425886e-05, + 2.33118372e-05, 2.31507462e-05, 2.53044252e-05, 2.59722857e-05, 2.60443118e-05, 2.53154417e-05, + 2.45125494e-05, 2.40305050e-05, 2.30203909e-05, 2.35965880e-05, 2.44289026e-05, 2.47422735e-05, + 2.60569110e-05, 2.68313423e-05, 2.65745917e-05, 2.43335167e-05, 2.28738074e-05, 2.21625138e-05, + 2.21543503e-05, 2.28360493e-05, 2.48086056e-05, 2.47312446e-05, 2.55147083e-05, 2.53777667e-05, + 2.41996435e-05, 2.53713518e-05, 2.46401732e-05, 2.28748452e-05, 2.59380907e-05, 2.55475889e-05, + 2.53573645e-05, 2.57725749e-05, 2.57815038e-05, 2.40307989e-05, 2.31562185e-05, 2.39064436e-05, + 2.50320295e-05, 2.51312432e-05, 2.62986933e-05, 2.56129772e-05, 2.31465748e-05, 2.31045969e-05, + 2.36296093e-05, 2.46011772e-05, 2.52617064e-05, 2.59527079e-05, 2.63850898e-05, 2.60871856e-05, + 2.51805020e-05, 2.40601204e-05, 2.27528078e-05, 2.43161535e-05, 2.02644557e-05, 1.93307741e-05, + 2.08896797e-05, 2.36998979e-05, 2.69959950e-05, 2.87166023e-05, 2.90242862e-05, 2.92161759e-05, + 2.49677180e-05, 2.24605882e-05, 2.32677643e-05, 2.45196870e-05, 2.47173296e-05, 2.52194855e-05, + 2.69013783e-05, 2.84196459e-05, 2.86051294e-05, 2.86012298e-05, 2.93048976e-05, 2.31250580e-05, + 2.05857927e-05, 2.11675488e-05, 2.36126096e-05, 2.49558594e-05, 2.58023768e-05, 2.81082887e-05, + 2.97782377e-05, 3.02701860e-05, 2.09071258e-05, 1.62853513e-05, 1.81921993e-05, 2.40185944e-05, + 2.74706062e-05, 2.88086327e-05, 2.95068565e-05, 2.98271413e-05, 2.98511522e-05, 2.42126682e-05, + 1.97383937e-05, 1.88546132e-05, 2.26826382e-05, 2.59911125e-05, 2.67383367e-05, 2.70038992e-05, + 2.84365346e-05, 2.98505025e-05, 2.77150094e-05, 2.43527201e-05, 1.90934572e-05, 1.65904944e-05, + 1.92179420e-05, 2.44328666e-05, 2.89928069e-05, 3.06518691e-05, 3.03439117e-05, 2.16509014e-05, + 1.74924192e-05, 1.82912443e-05, 2.22263314e-05, 2.66917922e-05, 2.95924152e-05, 3.05010823e-05, + 3.00599510e-05, 2.04496235e-05, 1.66041154e-05, 1.80463181e-05, 2.27990276e-05, 2.81195250e-05, + 3.04645662e-05, 3.04141643e-05, 2.97194265e-05, 1.90616351e-05, 1.50825879e-05, 1.89772631e-05, + 2.37467709e-05, 2.66723767e-05, 2.87410975e-05, 2.96610062e-05, 2.24293202e-05, 1.96103111e-05, + 1.93740594e-05, 2.12095888e-05, 2.57229973e-05, 2.91233425e-05, 2.98363440e-05, 2.95645035e-05, + 2.31003218e-05, 2.04831277e-05, 2.06987064e-05, 2.25843030e-05, 2.46289258e-05, 2.65272892e-05, + 2.87048556e-05, 2.94684818e-05, 2.37467128e-05, 2.07004857e-05, 2.08522092e-05, 2.17241436e-05, + 2.29713270e-05, 2.58898363e-05, 2.85847508e-05, 2.96916156e-05, 2.96007260e-05, 2.39466806e-05, + 1.90672689e-05, 1.56071127e-05, 1.73268373e-05, 2.32217703e-05, 2.90557543e-05, 3.01749556e-05, + 2.90843391e-05, 2.15068072e-05, 1.85551445e-05, 2.06833198e-05, 2.42930530e-05, 2.56460913e-05, + 2.71196505e-05, 2.89352748e-05, 2.93750079e-05, 2.41665988e-05, 2.07129501e-05, 1.87989217e-05, + 2.14899670e-05, 2.47533160e-05, 2.79031788e-05, 2.95292971e-05, 2.93594485e-05, 2.40900408e-05, + 2.06416431e-05, 2.01400306e-05, 2.21805901e-05, 2.47777288e-05, 2.71747420e-05, 2.92915929e-05, + 2.91747673e-05, 2.86901041e-05, 2.36906657e-05, 1.89156710e-05, 1.72150632e-05, 2.10790462e-05, + 2.58339259e-05, 2.84558181e-05, 3.02540505e-05, 3.05398709e-05, 2.98659748e-05, 2.18621727e-05, + 1.90769640e-05, 1.94859990e-05, 2.32344440e-05, 2.75920780e-05, 2.85509060e-05, 2.95435677e-05, + 3.04238878e-05, 2.32668042e-05, 2.02298601e-05, 1.99510919e-05, 2.12564939e-05, 2.35936982e-05, + 2.70549846e-05, 2.87902366e-05, 2.88447547e-05, 2.04168232e-05, 1.66934068e-05, 1.92332254e-05, + 2.52204363e-05, 2.93085350e-05, 2.94538225e-05, 2.91619688e-05, 2.38025371e-05, 2.05058255e-05, + 1.89700543e-05, 2.04065791e-05, 2.44129579e-05, 2.72430649e-05, 2.86350131e-05, 2.97597682e-05, + 2.48903475e-05, 2.25043033e-05, 2.18679641e-05, 2.28512562e-05, 2.44047943e-05, 2.59576864e-05, + 2.65972241e-05, 2.67612690e-05, 2.69267507e-05, 2.52441756e-05, 2.38986917e-05, 2.43697467e-05, + 2.49813572e-05, 2.50686095e-05, 2.53183227e-05, 2.59415663e-05, 2.64308716e-05, 2.66240914e-05, + 2.67152641e-05, 2.69305698e-05, 2.42154144e-05, 2.26946612e-05, 2.31045720e-05, 2.44746178e-05, + 2.51072413e-05, 2.56079328e-05, 2.65675067e-05, 2.69828233e-05, 2.70678618e-05, 2.29084748e-05, + 1.95724564e-05, 2.10462776e-05, 2.45629197e-05, 2.58516864e-05, 2.65647257e-05, 2.69954825e-05, + 2.70636438e-05, 2.70518127e-05, 2.46030981e-05, 2.20447334e-05, 2.15023871e-05, 2.39158686e-05, + 2.55477016e-05, 2.60601826e-05, 2.63053673e-05, 2.68126450e-05, 2.71469934e-05, 2.60815079e-05, + 2.47052799e-05, 2.16836106e-05, 1.98326349e-05, 2.17901612e-05, 2.49099473e-05, 2.67027874e-05, + 2.71973821e-05, 2.72039178e-05, 2.34165782e-05, 2.05076018e-05, 2.10867836e-05, 2.36238660e-05, + 2.57600427e-05, 2.66800007e-05, 2.69793725e-05, 2.70699683e-05, 2.26749520e-05, 1.98187232e-05, + 2.08938089e-05, 2.39573598e-05, 2.62481416e-05, 2.69295140e-05, 2.71734075e-05, 2.70444033e-05, + 2.16558920e-05, 1.85705380e-05, 2.15385528e-05, 2.43429796e-05, 2.58616898e-05, 2.69337643e-05, + 2.72107421e-05, 2.37900165e-05, 2.19677911e-05, 2.18336420e-05, 2.31169639e-05, 2.56525849e-05, + 2.68616121e-05, 2.70510562e-05, 2.70069082e-05, 2.41669883e-05, 2.25608213e-05, 2.27089848e-05, + 2.38642542e-05, 2.50594086e-05, 2.60762500e-05, 2.68448298e-05, 2.69836351e-05, 2.45171902e-05, + 2.27418320e-05, 2.28454787e-05, 2.33452133e-05, 2.41135012e-05, 2.56971785e-05, 2.67874045e-05, + 2.70496115e-05, 2.70157127e-05, 2.43085358e-05, 2.14954967e-05, 1.90065825e-05, 2.04164088e-05, + 2.44513590e-05, 2.70474743e-05, 2.72037345e-05, 2.71073897e-05, 2.32448605e-05, 2.12332124e-05, + 2.26695616e-05, 2.47193541e-05, 2.54564292e-05, 2.62219560e-05, 2.68355320e-05, 2.69325320e-05, + 2.44374825e-05, 2.26600166e-05, 2.14757164e-05, 2.32768702e-05, 2.50963465e-05, 2.65210848e-05, + 2.70532767e-05, 2.69382255e-05, 2.47196453e-05, 2.26936347e-05, 2.23669086e-05, 2.35943543e-05, + 2.49733668e-05, 2.61226514e-05, 2.68754452e-05, 2.69654266e-05, 2.69333939e-05, 2.44048057e-05, + 2.15234517e-05, 2.03167788e-05, 2.30408459e-05, 2.55040572e-05, 2.64647020e-05, 2.70561030e-05, + 2.71711668e-05, 2.70772138e-05, 2.33313338e-05, 2.15139962e-05, 2.18725250e-05, 2.42355017e-05, + 2.63619277e-05, 2.70624066e-05, 2.73719721e-05, 2.73235781e-05, 2.43313834e-05, 2.23773720e-05, + 2.21715949e-05, 2.30713938e-05, 2.45028037e-05, 2.60637117e-05, 2.66857018e-05, 2.68883559e-05, + 2.24438881e-05, 1.98208667e-05, 2.17664743e-05, 2.53983660e-05, 2.69147180e-05, 2.69680731e-05, + 2.69675697e-05, 2.44459128e-05, 2.25282115e-05, 2.15533669e-05, 2.25778355e-05, 2.50185363e-05, + 2.63845276e-05, 2.68264804e-05, 2.70097206e-05, 2.21179591e-05, 1.48802163e-05, 1.35196272e-05, + 1.61133593e-05, 2.15476426e-05, 2.91469403e-05, 3.40289177e-05, 3.46742349e-05, 3.47653365e-05, + 2.33949859e-05, 1.84039447e-05, 1.98510760e-05, 2.26017390e-05, 2.30767978e-05, 2.41639720e-05, + 2.87963943e-05, 3.34437057e-05, 3.33793291e-05, 3.29225635e-05, 3.51646539e-05, 1.99018013e-05, + 1.54659214e-05, 1.62289869e-05, 2.08827090e-05, 2.39396853e-05, 2.54304639e-05, 3.13574115e-05, + 3.71580156e-05, 3.91081603e-05, 1.59441035e-05, 9.73173367e-06, 1.20058726e-05, 2.22387784e-05, + 3.17847357e-05, 3.46182102e-05, 3.57989304e-05, 3.69853174e-05, 3.71602033e-05, 2.28953052e-05, + 1.45540346e-05, 1.29981727e-05, 1.92818310e-05, 2.65246519e-05, 2.75302526e-05, 2.75888584e-05, + 3.16950797e-05, 3.66771754e-05, 3.18377909e-05, 2.30634837e-05, 1.32712942e-05, 9.97610233e-06, + 1.33560786e-05, 2.25362613e-05, 3.48120126e-05, 4.03096145e-05, 3.87666173e-05, 1.69806909e-05, + 1.11973779e-05, 1.22882042e-05, 1.85668938e-05, 2.86798063e-05, 3.77887545e-05, 4.07056994e-05, + 3.80747805e-05, 1.49409527e-05, 1.01400701e-05, 1.20303176e-05, 1.96010810e-05, 3.29199883e-05, + 4.07858352e-05, 3.92667882e-05, 3.65666263e-05, 1.32513996e-05, 8.50973222e-06, 1.33880945e-05, + 2.20014321e-05, 2.81358675e-05, 3.25156729e-05, 3.54566151e-05, 1.87342549e-05, 1.43253852e-05, + 1.38676285e-05, 1.63596534e-05, 2.48828092e-05, 3.46486400e-05, 3.70929358e-05, 3.60158619e-05, + 2.00012147e-05, 1.55907418e-05, 1.58929561e-05, 1.90809024e-05, 2.27344308e-05, 2.65179141e-05, + 3.27780611e-05, 3.56757944e-05, 2.12745547e-05, 1.57623955e-05, 1.59765682e-05, 1.76007771e-05, + 1.96778736e-05, 2.54163206e-05, 3.24992972e-05, 3.64077590e-05, 3.61442450e-05, 2.29853837e-05, + 1.39399354e-05, 9.07112282e-06, 1.08009875e-05, 1.92837831e-05, 3.34226480e-05, 3.79483881e-05, + 3.32623770e-05, 1.70965863e-05, 1.28345762e-05, 1.59903956e-05, 2.27497592e-05, 2.54161540e-05, + 2.84927044e-05, 3.38947792e-05, 3.54863937e-05, 2.33862694e-05, 1.61533013e-05, 1.28623850e-05, + 1.68877185e-05, 2.31118298e-05, 3.06401538e-05, 3.56178414e-05, 3.53845897e-05, 2.18807516e-05, + 1.57130555e-05, 1.49314399e-05, 1.84960260e-05, 2.37469907e-05, 2.91960098e-05, 3.53739411e-05, + 3.43807875e-05, 3.22817831e-05, 2.15085150e-05, 1.31811127e-05, 1.07443291e-05, 1.61197712e-05, + 2.60278570e-05, 3.34500422e-05, 3.90899241e-05, 3.98948184e-05, 3.71031195e-05, 1.82344181e-05, + 1.39081563e-05, 1.41878815e-05, 2.02829326e-05, 2.99726819e-05, 3.10156596e-05, 3.40999741e-05, + 3.85389365e-05, 2.00132848e-05, 1.52726451e-05, 1.49355352e-05, 1.67567022e-05, 2.06809595e-05, + 2.89282584e-05, 3.39448227e-05, 3.32163242e-05, 1.57865990e-05, 1.05732593e-05, 1.35347608e-05, + 2.38151121e-05, 3.52600986e-05, 3.56835756e-05, 3.43102605e-05, 2.18109495e-05, 1.58195487e-05, + 1.32930963e-05, 1.51871368e-05, 2.19760819e-05, 2.82941627e-05, 3.25434346e-05, 3.69339312e-05, + 1.80163284e-05, 8.91538921e-06, 7.55233123e-06, 1.04453218e-05, 1.77681260e-05, 3.05436161e-05, + 4.05712837e-05, 4.16941741e-05, 4.13879663e-05, 1.98404451e-05, 1.28751053e-05, 1.47023885e-05, + 1.87808911e-05, 1.95442079e-05, 2.12247052e-05, 2.97815342e-05, 3.96075398e-05, 3.88451683e-05, + 3.74342649e-05, 4.23987981e-05, 1.50289257e-05, 9.60528081e-06, 1.03252715e-05, 1.64040018e-05, + 2.11850255e-05, 2.32229590e-05, 3.40814215e-05, 4.74733433e-05, 5.25197744e-05, 1.01077394e-05, + 4.34418922e-06, 6.17514080e-06, 1.88249766e-05, 3.71820023e-05, 4.21934430e-05, 4.38243697e-05, + 4.67184603e-05, 4.72296177e-05, 2.00460541e-05, 8.91447762e-06, 7.15395834e-06, 1.43748888e-05, + 2.56695674e-05, 2.66789042e-05, 2.62363653e-05, 3.41927156e-05, 4.56040447e-05, 3.66374577e-05, + 2.01918400e-05, 7.37318575e-06, 4.46355439e-06, 7.39176830e-06, 1.87826952e-05, 4.22413131e-05, + 5.54033670e-05, 5.10392890e-05, 1.11481867e-05, 5.53355995e-06, 6.53140088e-06, 1.35412792e-05, + 2.99701221e-05, 5.03252569e-05, 5.74576454e-05, 4.96446910e-05, 8.81945256e-06, 4.68416487e-06, + 6.34277273e-06, 1.48821829e-05, 3.88470758e-05, 5.79039510e-05, 5.25490638e-05, 4.56726295e-05, + 7.37133028e-06, 3.51611438e-06, 7.68432997e-06, 1.87511421e-05, 2.84857291e-05, 3.57987172e-05, + 4.22179860e-05, 1.35964966e-05, 8.64749947e-06, 8.09857003e-06, 1.05187858e-05, 2.20091378e-05, + 4.13019620e-05, 4.70518044e-05, 4.43521726e-05, 1.52823507e-05, 9.95490854e-06, 1.02620291e-05, + 1.40958313e-05, 1.88961287e-05, 2.44836877e-05, 3.66940989e-05, 4.35439579e-05, 1.70624110e-05, + 1.00162395e-05, 1.02338807e-05, 1.22677132e-05, 1.47836094e-05, 2.30071673e-05, 3.61876804e-05, + 4.52344108e-05, 4.46585571e-05, 2.07781791e-05, 8.55028647e-06, 3.91409803e-06, 5.08094111e-06, + 1.35883780e-05, 3.76562591e-05, 4.88003428e-05, 3.70851283e-05, 1.15573156e-05, 7.17231021e-06, + 1.04645717e-05, 1.95437270e-05, 2.35111036e-05, 2.84058260e-05, 3.94785045e-05, 4.32242881e-05, + 2.13535445e-05, 1.07388878e-05, 6.98504741e-06, 1.11737838e-05, 1.95614482e-05, 3.25224740e-05, + 4.31584933e-05, 4.29412295e-05, 1.78621790e-05, 9.99442858e-06, 9.14483517e-06, 1.34596444e-05, + 2.10554881e-05, 3.02358590e-05, 4.31240801e-05, 4.02887867e-05, 3.52404052e-05, 1.76935209e-05, + 7.39748667e-06, 5.08614302e-06, 1.02284404e-05, 2.46997176e-05, 3.95179364e-05, 5.25148155e-05, + 5.43284153e-05, 4.69849316e-05, 1.33721320e-05, 8.48328393e-06, 8.53869502e-06, 1.56866095e-05, + 3.13993887e-05, 3.19265793e-05, 3.83148911e-05, 4.99572344e-05, 1.50503029e-05, 9.66317996e-06, + 9.36570847e-06, 1.12179440e-05, 1.59879840e-05, 2.97751103e-05, 4.00764163e-05, 3.76335990e-05, + 1.04029239e-05, 5.24642185e-06, 7.67507872e-06, 2.03747008e-05, 4.26977382e-05, 4.36169404e-05, + 4.01045016e-05, 1.82020664e-05, 1.03570677e-05, 7.53120770e-06, 9.30489656e-06, 1.75259434e-05, + 2.75757040e-05, 3.61797025e-05, 4.67741436e-05, 1.95995466e-05, 1.08496231e-05, 9.42634365e-06, + 1.25497671e-05, 1.97364280e-05, 3.06667980e-05, 3.85199987e-05, 3.92204016e-05, 3.87460845e-05, + 2.11736814e-05, 1.47395660e-05, 1.64549952e-05, 2.03167204e-05, 2.10254392e-05, 2.24988417e-05, + 2.99959475e-05, 3.79403087e-05, 3.70532514e-05, 3.57547448e-05, 3.95609642e-05, 1.69301281e-05, + 1.16075003e-05, 1.22477063e-05, 1.82274047e-05, 2.26500511e-05, 2.41931282e-05, 3.30807587e-05, + 4.35220503e-05, 4.72790523e-05, 1.21014552e-05, 5.90129902e-06, 7.95409322e-06, 2.07143721e-05, + 3.66256824e-05, 3.98948654e-05, 4.06170980e-05, 4.28118126e-05, 4.32296313e-05, 2.19404688e-05, + 1.11072745e-05, 9.08025541e-06, 1.64247404e-05, 2.65982768e-05, 2.70213391e-05, 2.63542804e-05, + 3.28795123e-05, 4.18140408e-05, 3.58740351e-05, 2.20012376e-05, 9.28297977e-06, 5.97994155e-06, + 9.25273423e-06, 2.03790470e-05, 3.97457550e-05, 4.92373602e-05, 4.59410323e-05, 1.30433205e-05, + 7.28602750e-06, 8.43239160e-06, 1.56917081e-05, 3.03663234e-05, 4.61956273e-05, 5.11200982e-05, + 4.50777826e-05, 1.06299121e-05, 6.32224314e-06, 8.26145540e-06, 1.69592436e-05, 3.75403126e-05, + 5.15329891e-05, 4.71349681e-05, 4.20165445e-05, 9.29476739e-06, 4.96280623e-06, 9.77350584e-06, + 2.08200999e-05, 2.89001729e-05, 3.40989869e-05, 3.90276341e-05, 1.56380167e-05, 1.08067730e-05, + 1.01657111e-05, 1.24754713e-05, 2.29664099e-05, 3.87643971e-05, 4.30915687e-05, 4.10224399e-05, + 1.72450161e-05, 1.21212125e-05, 1.24116502e-05, 1.61490981e-05, 2.03690933e-05, 2.49437378e-05, + 3.49671848e-05, 4.04091797e-05, 1.88978126e-05, 1.20892336e-05, 1.22945293e-05, 1.44118676e-05, + 1.67349662e-05, 2.38982676e-05, 3.46119032e-05, 4.16624457e-05, 4.12538939e-05, 2.29441741e-05, + 1.09363219e-05, 5.44564122e-06, 6.66315916e-06, 1.51553573e-05, 3.55135622e-05, 4.42237406e-05, + 3.49598770e-05, 1.36407702e-05, 9.24017931e-06, 1.26838669e-05, 2.13253384e-05, 2.46178350e-05, + 2.84392206e-05, 3.73022289e-05, 4.02239428e-05, 2.34167032e-05, 1.30245822e-05, 8.86452026e-06, + 1.31635185e-05, 2.10189897e-05, 3.17797919e-05, 4.00025237e-05, 3.99881738e-05, 1.95790754e-05, + 1.20911287e-05, 1.12190881e-05, 1.56192107e-05, 2.26401066e-05, 3.02059645e-05, 4.02227230e-05, + 3.77961964e-05, 3.36259462e-05, 1.96575399e-05, 9.39776572e-06, 6.71426670e-06, 1.21686784e-05, + 2.57173763e-05, 3.78214958e-05, 4.72937804e-05, 4.84775191e-05, 4.30007361e-05, 1.57006265e-05, + 1.08391004e-05, 1.07181704e-05, 1.76355285e-05, 3.09748157e-05, 3.06205846e-05, 3.56340610e-05, + 4.49301464e-05, 1.68667620e-05, 1.18655237e-05, 1.16097699e-05, 1.33471060e-05, 1.77572306e-05, + 2.98556726e-05, 3.79941816e-05, 3.57000557e-05, 1.27440919e-05, 7.16340441e-06, 9.64265699e-06, + 2.15761703e-05, 3.98243877e-05, 4.04895110e-05, 3.76422454e-05, 2.01601348e-05, 1.26371717e-05, + 9.56158628e-06, 1.12997358e-05, 1.89806369e-05, 2.75053388e-05, 3.45560725e-05, 4.29344770e-05, + 2.24849511e-05, 1.56895840e-05, 1.43647042e-05, 1.75102991e-05, 2.32894543e-05, 2.96072239e-05, + 3.33055513e-05, 3.33879151e-05, 3.28210313e-05, 2.34083096e-05, 1.88378249e-05, 2.00917153e-05, + 2.30163583e-05, 2.35285238e-05, 2.44424829e-05, 2.91767866e-05, 3.32855569e-05, 3.24261123e-05, + 3.15071430e-05, 3.32567959e-05, 2.07850711e-05, 1.64851891e-05, 1.68354611e-05, 2.17441219e-05, + 2.48809667e-05, 2.54042655e-05, 3.01429636e-05, 3.52065708e-05, 3.68337828e-05, 1.68772676e-05, + 1.06936720e-05, 1.29255852e-05, 2.39706353e-05, 3.35758510e-05, 3.41228471e-05, 3.36970681e-05, + 3.46945358e-05, 3.49265051e-05, 2.50084636e-05, 1.65538257e-05, 1.42302840e-05, 2.06489100e-05, + 2.73664155e-05, 2.68724450e-05, 2.59950051e-05, 2.95946611e-05, 3.40286817e-05, 3.27117270e-05, + 2.49124684e-05, 1.43458097e-05, 1.06109242e-05, 1.41890033e-05, 2.31736556e-05, 3.37829973e-05, + 3.74501848e-05, 3.59373008e-05, 1.74506770e-05, 1.23361143e-05, 1.36533815e-05, 2.02374281e-05, + 2.97325782e-05, 3.71092563e-05, 3.87253855e-05, 3.57947381e-05, 1.52025726e-05, 1.12649360e-05, + 1.35758652e-05, 2.11544688e-05, 3.33912647e-05, 3.90077278e-05, 3.65532515e-05, 3.43290409e-05, + 1.43925300e-05, 9.67558369e-06, 1.52261393e-05, 2.43811508e-05, 2.85444806e-05, 3.01335161e-05, + 3.24471526e-05, 1.99666924e-05, 1.62275869e-05, 1.54744760e-05, 1.71062955e-05, 2.43405173e-05, + 3.29517302e-05, 3.48590965e-05, 3.38877340e-05, 2.11719578e-05, 1.73053188e-05, 1.75031472e-05, + 2.04228203e-05, 2.29537914e-05, 2.52826325e-05, 3.08107991e-05, 3.36098162e-05, 2.23369513e-05, + 1.70543858e-05, 1.71954929e-05, 1.91518504e-05, 2.07165655e-05, 2.50331765e-05, 3.06995712e-05, + 3.41376550e-05, 3.39913961e-05, 2.63171532e-05, 1.69380729e-05, 1.02975385e-05, 1.13333014e-05, + 1.86069270e-05, 3.07733026e-05, 3.51178942e-05, 3.03421322e-05, 1.83723891e-05, 1.47554229e-05, + 1.78925549e-05, 2.42960941e-05, 2.59731600e-05, 2.76341596e-05, 3.21838022e-05, 3.36079942e-05, + 2.65283511e-05, 1.83285677e-05, 1.39289091e-05, 1.77620379e-05, 2.34831804e-05, 2.93944083e-05, + 3.32631033e-05, 3.34716461e-05, 2.27030160e-05, 1.71126215e-05, 1.63418709e-05, 2.01957614e-05, + 2.50699561e-05, 2.90200093e-05, 3.37148916e-05, 3.22244498e-05, 2.98466614e-05, 2.32151777e-05, + 1.46860328e-05, 1.15170854e-05, 1.68095470e-05, 2.67619497e-05, 3.31559624e-05, 3.68644527e-05, + 3.71667106e-05, 3.47628521e-05, 2.06220271e-05, 1.67811652e-05, 1.62107913e-05, 2.14769551e-05, + 2.91363362e-05, 2.77322238e-05, 3.02646169e-05, 3.52206879e-05, 2.05677943e-05, 1.71861723e-05, + 1.70858001e-05, 1.82298053e-05, 2.12417350e-05, 2.88784177e-05, 3.28482093e-05, 3.11659929e-05, + 1.82358409e-05, 1.27866378e-05, 1.47902317e-05, 2.35375126e-05, 3.34281078e-05, 3.36816502e-05, + 3.21344725e-05, 2.36274144e-05, 1.80009846e-05, 1.48978933e-05, 1.62118533e-05, 2.17288546e-05, + 2.67087991e-05, 3.05972424e-05, 3.48607463e-05, 2.37229316e-05, 1.87377102e-05, 1.76470471e-05, + 2.02674709e-05, 2.44687760e-05, 2.82276272e-05, 3.01345669e-05, 3.00999952e-05, 2.97011361e-05, + 2.42954105e-05, 2.11307959e-05, 2.20234677e-05, 2.40903007e-05, 2.44388983e-05, 2.50164289e-05, + 2.79640849e-05, 3.02036616e-05, 2.96231663e-05, 2.90484772e-05, 2.99426881e-05, 2.26147298e-05, + 1.94079876e-05, 1.96227088e-05, 2.32851374e-05, 2.53971678e-05, 2.55935326e-05, 2.83011616e-05, + 3.09691962e-05, 3.17550148e-05, 1.97045267e-05, 1.43827649e-05, 1.64178118e-05, 2.49196198e-05, + 3.06400291e-05, 3.06042533e-05, 3.01525946e-05, 3.06550142e-05, 3.07842825e-05, 2.56520821e-05, + 1.96128822e-05, 1.75929217e-05, 2.25896755e-05, 2.69446187e-05, 2.64264335e-05, 2.57472973e-05, + 2.78601163e-05, 3.02540859e-05, 3.00393420e-05, 2.55509725e-05, 1.76662388e-05, 1.42527289e-05, + 1.74966114e-05, 2.42285156e-05, 3.03480800e-05, 3.19815270e-05, 3.12242088e-05, 2.00822890e-05, + 1.59274129e-05, 1.71210992e-05, 2.23405515e-05, 2.83859257e-05, 3.21162096e-05, 3.27274815e-05, + 3.12270575e-05, 1.82574184e-05, 1.49458257e-05, 1.70825546e-05, 2.29755543e-05, 3.03503481e-05, + 3.28917503e-05, 3.15530441e-05, 3.04699573e-05, 1.77158764e-05, 1.34297801e-05, 1.85175094e-05, + 2.52854928e-05, 2.75936052e-05, 2.81338115e-05, 2.93499637e-05, 2.20793054e-05, 1.93384108e-05, + 1.86847400e-05, 1.98558523e-05, 2.48323855e-05, 2.98066374e-05, 3.07490524e-05, 3.02508353e-05, + 2.29308516e-05, 2.01574238e-05, 2.02944640e-05, 2.24243595e-05, 2.40198225e-05, 2.53445897e-05, + 2.85788141e-05, 3.01108083e-05, 2.37234415e-05, 1.98975372e-05, 1.99964822e-05, 2.15306917e-05, + 2.25890020e-05, 2.53046164e-05, 2.85387132e-05, 3.03641290e-05, 3.03026346e-05, 2.66648114e-05, + 2.00725962e-05, 1.40458307e-05, 1.49169659e-05, 2.07966958e-05, 2.84635675e-05, 3.08016625e-05, + 2.81801273e-05, 2.09069391e-05, 1.81413197e-05, 2.06381075e-05, 2.51058095e-05, 2.60383604e-05, + 2.68653145e-05, 2.93838042e-05, 3.01358364e-05, 2.67677154e-05, 2.10111141e-05, 1.73110795e-05, + 2.03823338e-05, 2.43970329e-05, 2.78617595e-05, 2.98842864e-05, 3.00578053e-05, 2.39377301e-05, + 1.99593652e-05, 1.93535963e-05, 2.23149576e-05, 2.55747893e-05, 2.77923079e-05, 3.02236022e-05, + 2.93445483e-05, 2.79606217e-05, 2.44137934e-05, 1.80183148e-05, 1.51244475e-05, 1.96147656e-05, + 2.65569655e-05, 3.01143110e-05, 3.17771922e-05, 3.18587600e-05, 3.06839780e-05, 2.27247881e-05, + 1.99297009e-05, 1.93438259e-05, 2.31481594e-05, 2.77675681e-05, 2.65902421e-05, 2.80115120e-05, + 3.07881718e-05, 2.24115509e-05, 2.00955367e-05, 2.00541084e-05, 2.08289986e-05, 2.28900732e-05, + 2.77265305e-05, 2.98340795e-05, 2.87685007e-05, 2.09835649e-05, 1.65003795e-05, 1.80665363e-05, + 2.43399241e-05, 3.00456112e-05, 3.01581811e-05, 2.92921539e-05, 2.47051788e-05, 2.07638450e-05, + 1.82101484e-05, 1.91910546e-05, 2.31134946e-05, 2.61950345e-05, 2.84600506e-05, 3.07721686e-05, + 2.57144624e-05, 3.04528090e-05, 3.14723020e-05, 2.87281235e-05, 2.47696252e-05, 2.14223010e-05, + 1.96445319e-05, 1.96517392e-05, 1.99941452e-05, 2.52033670e-05, 2.82573414e-05, 2.74197178e-05, + 2.53490301e-05, 2.50059026e-05, 2.44686158e-05, 2.16680456e-05, 1.96020677e-05, 2.01102181e-05, + 2.06356388e-05, 1.97676912e-05, 2.66851390e-05, 2.97060136e-05, 2.96882055e-05, 2.60472357e-05, + 2.40313559e-05, 2.39379385e-05, 2.13538057e-05, 1.88051465e-05, 1.80556604e-05, 2.94642959e-05, + 3.42780804e-05, 3.25572326e-05, 2.43615415e-05, 1.92564800e-05, 1.92235559e-05, 1.95588820e-05, + 1.90748984e-05, 1.89579133e-05, 2.36427707e-05, 2.90044153e-05, 3.12548709e-05, 2.65846161e-05, + 2.25956576e-05, 2.31632489e-05, 2.38711738e-05, 2.17647023e-05, 1.94285478e-05, 1.97751738e-05, + 2.37719653e-05, 3.12995895e-05, 3.47880202e-05, 3.16225437e-05, 2.51819000e-05, 1.94339274e-05, + 1.77976230e-05, 1.85026958e-05, 2.92885101e-05, 3.27917052e-05, 3.15673157e-05, 2.67269145e-05, + 2.12641109e-05, 1.78471766e-05, 1.71952139e-05, 1.85425955e-05, 3.12172690e-05, 3.36243098e-05, + 3.14508416e-05, 2.61779099e-05, 1.94881311e-05, 1.70652726e-05, 1.82062189e-05, 1.92519581e-05, + 3.12083086e-05, 3.47130347e-05, 3.00300497e-05, 2.39236474e-05, 2.20120884e-05, 2.14879142e-05, + 2.02720299e-05, 2.71003601e-05, 2.92945247e-05, 3.00383861e-05, 2.94000006e-05, 2.47296975e-05, + 1.99067481e-05, 1.89908091e-05, 1.94647975e-05, 2.63149981e-05, 2.86804037e-05, 2.86070332e-05, + 2.67456985e-05, 2.54464874e-05, 2.42633547e-05, 2.10676992e-05, 1.96003612e-05, 2.55901553e-05, + 2.91173081e-05, 2.90590012e-05, 2.75067198e-05, 2.66712336e-05, 2.42483171e-05, 2.11117549e-05, + 1.93493429e-05, 1.94145533e-05, 2.25850830e-05, 2.80399919e-05, 3.41868502e-05, 3.42984602e-05, + 2.89142299e-05, 2.11543124e-05, 1.88985649e-05, 2.14223421e-05, 2.81850692e-05, 3.02822688e-05, + 2.81674902e-05, 2.42210247e-05, 2.34649278e-05, 2.27410899e-05, 2.03060184e-05, 1.95874942e-05, + 2.25260494e-05, 2.77201489e-05, 3.16295178e-05, 2.88380007e-05, 2.50573476e-05, 2.17764044e-05, + 1.97979375e-05, 1.96589527e-05, 2.54304839e-05, 2.90097565e-05, 2.95567252e-05, 2.67412593e-05, + 2.38202666e-05, 2.18393432e-05, 1.95173398e-05, 2.03232280e-05, 2.16567831e-05, 2.48262961e-05, + 3.06862122e-05, 3.38599659e-05, 2.96597308e-05, 2.29637597e-05, 1.96791110e-05, 1.80392266e-05, + 1.79222960e-05, 1.90443927e-05, 2.61593580e-05, 2.82262887e-05, 2.92181227e-05, 2.61048909e-05, + 2.18683654e-05, 2.30165006e-05, 2.15479241e-05, 1.88732904e-05, 2.69608844e-05, 2.86361401e-05, + 2.85478968e-05, 2.81799107e-05, 2.64917702e-05, 2.18992636e-05, 1.99079804e-05, 2.08814370e-05, + 2.76176947e-05, 3.12535152e-05, 3.08135603e-05, 2.51940517e-05, 1.96748525e-05, 1.95594581e-05, + 2.03724620e-05, 2.45414108e-05, 2.79293613e-05, 3.04509581e-05, 2.99084065e-05, 2.64207585e-05, + 2.34197215e-05, 2.11833724e-05, 1.89800956e-05, 2.50048181e-05, 3.63259836e-05, 3.93327805e-05, + 3.25132355e-05, 2.38834754e-05, 1.76142969e-05, 1.48251921e-05, 1.47479202e-05, 1.51064845e-05, + 2.38605225e-05, 3.04063391e-05, 2.84072788e-05, 2.43244129e-05, 2.36927608e-05, 2.26286025e-05, + 1.79734668e-05, 1.48580560e-05, 1.54237396e-05, 1.60744367e-05, 1.48094073e-05, 2.72871152e-05, + 3.45957469e-05, 3.40284721e-05, 2.59448739e-05, 2.21113686e-05, 2.15731915e-05, 1.71408981e-05, + 1.35552764e-05, 1.25902994e-05, 3.38492784e-05, 4.97309321e-05, 4.29859289e-05, 2.30839400e-05, + 1.47121785e-05, 1.42957135e-05, 1.45058048e-05, 1.38548688e-05, 1.37133677e-05, 2.19036059e-05, + 3.40815400e-05, 3.94438076e-05, 2.74146217e-05, 1.95885972e-05, 2.00677695e-05, 2.09458318e-05, + 1.75600213e-05, 1.42615028e-05, 1.52765709e-05, 2.20255184e-05, 3.92564074e-05, 5.04010599e-05, + 3.97665477e-05, 2.41147573e-05, 1.44960967e-05, 1.22209825e-05, 1.30744174e-05, 3.28771018e-05, + 4.44588430e-05, 4.07712174e-05, 2.79649475e-05, 1.75151496e-05, 1.25119539e-05, 1.15985186e-05, + 1.31866130e-05, 3.76152853e-05, 4.76801971e-05, 4.08373544e-05, 2.66680002e-05, 1.48058535e-05, + 1.14664383e-05, 1.27255252e-05, 1.40886115e-05, 3.91085196e-05, 5.30135057e-05, 3.68472667e-05, + 2.25636532e-05, 1.85192968e-05, 1.71041098e-05, 1.53169822e-05, 2.84514456e-05, 3.47587045e-05, + 3.64383102e-05, 3.34610077e-05, 2.27676368e-05, 1.50270973e-05, 1.37551119e-05, 1.43791638e-05, + 2.66974183e-05, 3.27843297e-05, 3.24589998e-05, 2.77489557e-05, 2.44146345e-05, 2.17117629e-05, + 1.65834415e-05, 1.45653191e-05, 2.51386450e-05, 3.33944953e-05, 3.31513846e-05, 2.96631489e-05, + 2.73654043e-05, 2.19824959e-05, 1.66771071e-05, 1.42098970e-05, 1.43103542e-05, 2.04788240e-05, + 3.29073837e-05, 5.07250549e-05, 4.80643275e-05, 3.09725866e-05, 1.65823281e-05, 1.35650956e-05, + 1.69107198e-05, 3.10219043e-05, 3.78221201e-05, 3.16733173e-05, 2.27274337e-05, 2.09638805e-05, + 1.93340744e-05, 1.55667888e-05, 1.45752322e-05, 2.02903116e-05, 3.08432978e-05, 4.02762274e-05, + 3.22005366e-05, 2.37519333e-05, 1.77581120e-05, 1.47841010e-05, 1.46645441e-05, 2.46902709e-05, + 3.32489646e-05, 3.47388691e-05, 2.80211636e-05, 2.18871147e-05, 1.81008161e-05, 1.45143500e-05, + 1.55179847e-05, 1.73365573e-05, 2.39764021e-05, 3.82234626e-05, 4.72470017e-05, 3.40554885e-05, + 2.01696472e-05, 1.49411381e-05, 1.25756478e-05, 1.23824580e-05, 1.38097137e-05, 2.72663180e-05, + 3.32505344e-05, 3.47363575e-05, 2.62713103e-05, 1.79884324e-05, 1.91630215e-05, 1.69244571e-05, + 1.34758864e-05, 2.76477342e-05, 3.29311871e-05, 3.30233268e-05, 3.12158826e-05, 2.66716493e-05, + 1.82244976e-05, 1.51231576e-05, 1.63061618e-05, 3.09077266e-05, 4.22402357e-05, 3.81216684e-05, + 2.37141556e-05, 1.46973940e-05, 1.45207021e-05, 1.55818713e-05, 2.34751137e-05, 3.13943782e-05, + 3.76913306e-05, 3.51476445e-05, 2.60595932e-05, 2.02164034e-05, 1.67516394e-05, 1.37619330e-05, + 2.54444504e-05, 2.51745263e-05, 2.49756149e-05, 2.46723317e-05, 2.43764495e-05, 2.44218000e-05, + 2.42585154e-05, 2.44638482e-05, 2.48493033e-05, 2.55912448e-05, 2.56358119e-05, 2.57433751e-05, + 2.53562447e-05, 2.52756840e-05, 2.52842668e-05, 2.45325600e-05, 2.40341939e-05, 2.45353092e-05, + 2.49251986e-05, 2.47349946e-05, 2.51689877e-05, 2.50029058e-05, 2.54672300e-05, 2.51325480e-05, + 2.48010139e-05, 2.53455447e-05, 2.51248933e-05, 2.42992592e-05, 2.40221114e-05, 2.51221470e-05, + 2.38222209e-05, 2.46007436e-05, 2.43436454e-05, 2.31685684e-05, 2.40000116e-05, 2.47068461e-05, + 2.45402327e-05, 2.44647117e-05, 2.40131343e-05, 2.39088529e-05, 2.44494179e-05, 2.47687527e-05, + 2.45568760e-05, 2.54752878e-05, 2.61626277e-05, 2.56509653e-05, 2.48297084e-05, 2.37061644e-05, + 2.41976391e-05, 2.46768069e-05, 2.43670081e-05, 2.49645746e-05, 2.51822593e-05, 2.42781350e-05, + 2.40551528e-05, 2.44222253e-05, 2.56196097e-05, 2.41158704e-05, 2.41431154e-05, 2.45090630e-05, + 2.41044042e-05, 2.34358061e-05, 2.34788387e-05, 2.42734047e-05, 2.57755089e-05, 2.37691729e-05, + 2.38703479e-05, 2.46027089e-05, 2.37554819e-05, 2.33521415e-05, 2.42319149e-05, 2.46080682e-05, + 2.45985773e-05, 2.29418304e-05, 2.38677889e-05, 2.38641604e-05, 2.46196739e-05, 2.56543546e-05, + 2.53553495e-05, 2.48952883e-05, 2.39708505e-05, 2.41999720e-05, 2.53293433e-05, 2.58277472e-05, + 2.47219983e-05, 2.44807978e-05, 2.46719826e-05, 2.49164701e-05, 2.43192876e-05, 2.44483774e-05, + 2.47941078e-05, 2.55014375e-05, 2.60929100e-05, 2.53167870e-05, 2.47137023e-05, 2.49393305e-05, + 2.47500754e-05, 2.48379513e-05, 2.45986094e-05, 2.50429551e-05, 2.56207807e-05, 2.52685117e-05, + 2.46653710e-05, 2.46567921e-05, 2.31339368e-05, 2.28267567e-05, 2.31580381e-05, 2.47771458e-05, + 2.66528506e-05, 2.56188920e-05, 2.46259983e-05, 2.58396362e-05, 2.48383560e-05, 2.36581710e-05, + 2.41775779e-05, 2.44498887e-05, 2.49112095e-05, 2.54451936e-05, 2.49000323e-05, 2.46430078e-05, + 2.32471175e-05, 2.39376049e-05, 2.46110512e-05, 2.52182093e-05, 2.53362048e-05, 2.52939083e-05, + 2.49049467e-05, 2.46875407e-05, 2.50910878e-05, 2.46394358e-05, 2.45522258e-05, 2.44829520e-05, + 2.45327443e-05, 2.48409463e-05, 2.45351583e-05, 2.50716861e-05, 2.57450140e-05, 2.44062126e-05, + 2.41833184e-05, 2.44416684e-05, 2.53780785e-05, 2.47007174e-05, 2.41152603e-05, 2.39989913e-05, + 2.40848874e-05, 2.45414904e-05, 2.38849057e-05, 2.29388590e-05, 2.38265788e-05, 2.48847492e-05, + 2.51474519e-05, 2.66524721e-05, 2.62488831e-05, 2.47658831e-05, 2.54519223e-05, 2.40911243e-05, + 2.38175496e-05, 2.46376369e-05, 2.54028863e-05, 2.48017756e-05, 2.45048522e-05, 2.52718292e-05, + 2.36460683e-05, 2.26093238e-05, 2.45208796e-05, 2.57717421e-05, 2.46665044e-05, 2.46727923e-05, + 2.51004809e-05, 2.43038468e-05, 2.38979759e-05, 2.40972262e-05, 2.49746333e-05, 2.59792391e-05, + 2.60143640e-05, 2.53557156e-05, 2.44233633e-05, 2.42715744e-05, 2.00649058e-05, 1.91073596e-05, + 2.05908442e-05, 2.34182895e-05, 2.69939616e-05, 2.89166489e-05, 2.93075557e-05, 2.95965200e-05, + 2.49944342e-05, 2.23718686e-05, 2.32278566e-05, 2.44708737e-05, 2.46662023e-05, 2.52064758e-05, + 2.69084573e-05, 2.85367456e-05, 2.88357949e-05, 2.88994483e-05, 2.96800969e-05, 2.29680543e-05, + 2.03510038e-05, 2.10241122e-05, 2.34700009e-05, 2.48319226e-05, 2.58492266e-05, 2.83720889e-05, + 3.01615757e-05, 3.07002230e-05, 2.06953208e-05, 1.59841104e-05, 1.79329668e-05, 2.37480553e-05, + 2.73095638e-05, 2.89793182e-05, 2.99110867e-05, 3.02591622e-05, 3.02749198e-05, 2.38922655e-05, + 1.93018401e-05, 1.85423193e-05, 2.24329633e-05, 2.59085549e-05, 2.69006241e-05, 2.73246414e-05, + 2.88412136e-05, 3.03353147e-05, 2.76770886e-05, 2.40751422e-05, 1.88181052e-05, 1.63723487e-05, + 1.89951170e-05, 2.43453187e-05, 2.92395170e-05, 3.11627635e-05, 3.08524169e-05, 2.15421811e-05, + 1.71727351e-05, 1.79400349e-05, 2.19140817e-05, 2.65989266e-05, 2.98033075e-05, 3.08926902e-05, + 3.04904962e-05, 2.03666238e-05, 1.62709371e-05, 1.76532430e-05, 2.25216037e-05, 2.81458098e-05, + 3.08296641e-05, 3.09056328e-05, 3.01437079e-05, 1.87720438e-05, 1.47123864e-05, 1.85500606e-05, + 2.33722952e-05, 2.66699764e-05, 2.91904351e-05, 3.02033174e-05, 2.21962590e-05, 1.91877739e-05, + 1.90000669e-05, 2.10394856e-05, 2.58546020e-05, 2.94667239e-05, 3.02601223e-05, 2.99726633e-05, + 2.28938891e-05, 2.01170495e-05, 2.03567603e-05, 2.23363786e-05, 2.46150412e-05, 2.67845734e-05, + 2.90879971e-05, 2.98673724e-05, 2.35738446e-05, 2.04165377e-05, 2.05852419e-05, 2.14187219e-05, + 2.27842018e-05, 2.59965551e-05, 2.89415590e-05, 3.01206685e-05, 3.00125481e-05, 2.34502271e-05, + 1.84418777e-05, 1.52323236e-05, 1.71432585e-05, 2.33594820e-05, 2.95463670e-05, 3.06848094e-05, + 2.96192538e-05, 2.12443461e-05, 1.81016864e-05, 2.02896645e-05, 2.40586435e-05, 2.55978760e-05, + 2.73183863e-05, 2.92797688e-05, 2.97461460e-05, 2.37037668e-05, 2.02737120e-05, 1.85195256e-05, + 2.13008206e-05, 2.47161825e-05, 2.81701532e-05, 2.99711839e-05, 2.97355790e-05, 2.39645848e-05, + 2.03364688e-05, 1.98211300e-05, 2.18622530e-05, 2.45908640e-05, 2.72689851e-05, 2.96305143e-05, + 2.95870886e-05, 2.91484207e-05, 2.34141696e-05, 1.85504582e-05, 1.69729608e-05, 2.09176970e-05, + 2.57632980e-05, 2.85920701e-05, 3.06773012e-05, 3.10328605e-05, 3.03051658e-05, 2.14238591e-05, + 1.84721697e-05, 1.90384716e-05, 2.30274057e-05, 2.77925643e-05, 2.91579280e-05, 3.02260861e-05, + 3.10040719e-05, 2.31701919e-05, 1.98218753e-05, 1.94941182e-05, 2.09528719e-05, 2.35021760e-05, + 2.71282149e-05, 2.90437789e-05, 2.92408848e-05, 1.99233179e-05, 1.61364711e-05, 1.89241622e-05, + 2.53005659e-05, 2.96726200e-05, 2.98432740e-05, 2.95772805e-05, 2.35126812e-05, 2.00594968e-05, + 1.85867846e-05, 2.01671272e-05, 2.44777275e-05, 2.75625575e-05, 2.90148187e-05, 3.01603352e-05, + 2.53145483e-05, 2.49418766e-05, 2.47141478e-05, 2.49006958e-05, 2.49361974e-05, 2.46956630e-05, + 2.43383228e-05, 2.43821139e-05, 2.45354266e-05, 2.53502228e-05, 2.53265382e-05, 2.54023242e-05, + 2.52791523e-05, 2.52439346e-05, 2.52250094e-05, 2.47583329e-05, 2.42812125e-05, 2.44957858e-05, + 2.46835188e-05, 2.44621138e-05, 2.52137096e-05, 2.49497660e-05, 2.51509110e-05, 2.52093941e-05, + 2.50526307e-05, 2.52118874e-05, 2.48559794e-05, 2.41426857e-05, 2.38830397e-05, 2.50260045e-05, + 2.35735645e-05, 2.43520537e-05, 2.49155890e-05, 2.40098886e-05, 2.41893074e-05, 2.44078845e-05, + 2.42567442e-05, 2.42126973e-05, 2.47768336e-05, 2.45283076e-05, 2.44907942e-05, 2.50673050e-05, + 2.48724244e-05, 2.51820790e-05, 2.54302735e-05, 2.50410060e-05, 2.43986175e-05, 2.42421268e-05, + 2.48445080e-05, 2.45956967e-05, 2.37725629e-05, 2.46865637e-05, 2.52183996e-05, 2.42948778e-05, + 2.38086735e-05, 2.40800761e-05, 2.52491665e-05, 2.40522458e-05, 2.42861654e-05, 2.49621022e-05, + 2.45901597e-05, 2.37200585e-05, 2.35236666e-05, 2.40664516e-05, 2.51149132e-05, 2.36882280e-05, + 2.41636795e-05, 2.50147739e-05, 2.41952580e-05, 2.34603607e-05, 2.39622443e-05, 2.43142586e-05, + 2.45711580e-05, 2.29293518e-05, 2.43803445e-05, 2.47361302e-05, 2.48255662e-05, 2.49949759e-05, + 2.46939684e-05, 2.50977398e-05, 2.45242512e-05, 2.45413480e-05, 2.51199201e-05, 2.54012320e-05, + 2.44908748e-05, 2.42242033e-05, 2.43786890e-05, 2.51287392e-05, 2.47501072e-05, 2.48140298e-05, + 2.50719545e-05, 2.53284110e-05, 2.54451934e-05, 2.48481671e-05, 2.44190492e-05, 2.51417875e-05, + 2.48984467e-05, 2.49421784e-05, 2.49598124e-05, 2.51677019e-05, 2.53124321e-05, 2.48459023e-05, + 2.43491025e-05, 2.43636114e-05, 2.44216566e-05, 2.41123656e-05, 2.31954842e-05, 2.41079265e-05, + 2.56671386e-05, 2.49268960e-05, 2.42248348e-05, 2.50214791e-05, 2.50142139e-05, 2.42389901e-05, + 2.47336005e-05, 2.49469687e-05, 2.50504583e-05, 2.51283046e-05, 2.46124137e-05, 2.44025263e-05, + 2.44569240e-05, 2.46646516e-05, 2.45128169e-05, 2.51216803e-05, 2.52649107e-05, 2.49620235e-05, + 2.45015990e-05, 2.44278204e-05, 2.51925109e-05, 2.48603200e-05, 2.47644526e-05, 2.49512392e-05, + 2.49563932e-05, 2.48608238e-05, 2.43652016e-05, 2.46506282e-05, 2.50433337e-05, 2.49475611e-05, + 2.44437854e-05, 2.40162979e-05, 2.51160940e-05, 2.49480455e-05, 2.43152832e-05, 2.38743035e-05, + 2.38524140e-05, 2.42490310e-05, 2.47342722e-05, 2.41469672e-05, 2.44644724e-05, 2.51203247e-05, + 2.49408043e-05, 2.54475725e-05, 2.51251385e-05, 2.42411276e-05, 2.53099309e-05, 2.46516305e-05, + 2.45347204e-05, 2.49308646e-05, 2.53008151e-05, 2.48588853e-05, 2.44469326e-05, 2.48037762e-05, + 2.45428940e-05, 2.35019569e-05, 2.45906559e-05, 2.54057323e-05, 2.44274496e-05, 2.44015810e-05, + 2.46667423e-05, 2.49064033e-05, 2.46297956e-05, 2.44350355e-05, 2.49153819e-05, 2.54965109e-05, + 2.53477428e-05, 2.48775001e-05, 2.42110947e-05, 2.48142184e-05, 2.25314843e-05, 2.19089100e-05, + 2.32841872e-05, 2.50568650e-05, 2.61450418e-05, 2.64673047e-05, 2.64357995e-05, 2.63414452e-05, + 2.50215200e-05, 2.37497485e-05, 2.41476357e-05, 2.49461527e-05, 2.50676725e-05, 2.52616834e-05, + 2.60829519e-05, 2.65029417e-05, 2.63736765e-05, 2.62519749e-05, 2.63813215e-05, 2.43725435e-05, + 2.28734364e-05, 2.30137229e-05, 2.46395073e-05, 2.53815175e-05, 2.54422012e-05, 2.61118382e-05, + 2.65201191e-05, 2.65847426e-05, 2.30333427e-05, 1.97351541e-05, 2.11434593e-05, 2.52144639e-05, + 2.66471931e-05, 2.65480156e-05, 2.64029339e-05, 2.64617403e-05, 2.64813617e-05, 2.54508028e-05, + 2.28962077e-05, 2.18353816e-05, 2.43443509e-05, 2.58350209e-05, 2.56744401e-05, 2.54673500e-05, + 2.59856103e-05, 2.63881027e-05, 2.65160913e-05, 2.54221461e-05, 2.18964291e-05, 1.96944419e-05, + 2.18209816e-05, 2.49922609e-05, 2.64854016e-05, 2.65662737e-05, 2.64968976e-05, 2.32522022e-05, + 2.07923872e-05, 2.15315421e-05, 2.42258274e-05, 2.61936143e-05, 2.67159766e-05, 2.66797134e-05, + 2.65307367e-05, 2.23100831e-05, 2.01159305e-05, 2.14839334e-05, 2.44949883e-05, 2.65521322e-05, + 2.67035622e-05, 2.65376467e-05, 2.64402864e-05, 2.19186793e-05, 1.89670017e-05, 2.23081644e-05, + 2.53248423e-05, 2.59951904e-05, 2.60329002e-05, 2.62310981e-05, 2.41342389e-05, 2.27585298e-05, + 2.24281982e-05, 2.31227836e-05, 2.52012646e-05, 2.63702763e-05, 2.64769319e-05, 2.64157416e-05, + 2.44909044e-05, 2.32045214e-05, 2.32817375e-05, 2.42763380e-05, 2.49233137e-05, 2.53549244e-05, + 2.61396280e-05, 2.63986587e-05, 2.48010361e-05, 2.31056345e-05, 2.31612580e-05, 2.38752050e-05, + 2.43566365e-05, 2.53514759e-05, 2.61384842e-05, 2.64240580e-05, 2.64217770e-05, 2.57456390e-05, + 2.30339654e-05, 1.94333295e-05, 2.01872377e-05, 2.36386590e-05, 2.60881039e-05, 2.64488057e-05, + 2.60198650e-05, 2.36024496e-05, 2.20795697e-05, 2.34295270e-05, 2.52804888e-05, 2.55780632e-05, + 2.57866126e-05, 2.62993000e-05, 2.64119735e-05, 2.57798078e-05, 2.35898770e-05, 2.16841219e-05, + 2.33752938e-05, 2.50539651e-05, 2.60155271e-05, 2.63497413e-05, 2.63985808e-05, 2.48851059e-05, + 2.31289045e-05, 2.28126603e-05, 2.42134318e-05, 2.54353804e-05, 2.60300075e-05, 2.64360256e-05, + 2.62720396e-05, 2.59944194e-05, 2.50380782e-05, 2.20566411e-05, 2.02974650e-05, 2.30041681e-05, + 2.57279096e-05, 2.64829520e-05, 2.65899003e-05, 2.65647041e-05, 2.64626596e-05, 2.43516720e-05, + 2.29720893e-05, 2.27491810e-05, 2.45765647e-05, 2.60066598e-05, 2.56460774e-05, 2.59444695e-05, + 2.64177560e-05, 2.42997185e-05, 2.31562433e-05, 2.31134977e-05, 2.35528938e-05, 2.44927912e-05, + 2.60175548e-05, 2.64025632e-05, 2.61727834e-05, 2.35541964e-05, 2.10034264e-05, 2.21120249e-05, + 2.50379961e-05, 2.64008154e-05, 2.64089319e-05, 2.62621177e-05, 2.51385823e-05, 2.34689759e-05, + 2.21573234e-05, 2.27584422e-05, 2.45953527e-05, 2.55927235e-05, 2.61169359e-05, 2.64888944e-05, + 2.50397329e-05, 2.40968569e-05, 2.37389857e-05, 2.48226991e-05, 2.56995252e-05, 2.53728252e-05, + 2.49043721e-05, 2.47222722e-05, 2.45279746e-05, 2.49747695e-05, 2.45836098e-05, 2.46944355e-05, + 2.51085599e-05, 2.51660125e-05, 2.51596422e-05, 2.53448196e-05, 2.50878547e-05, 2.48537259e-05, + 2.47177167e-05, 2.45299340e-05, 2.50822223e-05, 2.44060274e-05, 2.42686770e-05, 2.51810046e-05, + 2.54536864e-05, 2.50950389e-05, 2.47898599e-05, 2.44533617e-05, 2.42824145e-05, 2.44486569e-05, + 2.23568185e-05, 2.32936271e-05, 2.57360771e-05, 2.57224472e-05, 2.49479519e-05, 2.44583765e-05, + 2.43700058e-05, 2.43789973e-05, 2.59446381e-05, 2.49582879e-05, 2.39248429e-05, 2.52900992e-05, + 2.54985261e-05, 2.49219059e-05, 2.45345188e-05, 2.44864438e-05, 2.42819123e-05, 2.54505580e-05, + 2.58300896e-05, 2.38669835e-05, 2.20885000e-05, 2.36767115e-05, 2.52158499e-05, 2.47913207e-05, + 2.40813109e-05, 2.41622504e-05, 2.43340592e-05, 2.32062755e-05, 2.38231456e-05, 2.53847081e-05, + 2.55850275e-05, 2.47381453e-05, 2.42550072e-05, 2.43302553e-05, 2.36637772e-05, 2.27419454e-05, + 2.39098409e-05, 2.54336229e-05, 2.52900632e-05, 2.42932431e-05, 2.41685126e-05, 2.43982348e-05, + 2.39203109e-05, 2.19650614e-05, 2.45611463e-05, 2.60346608e-05, 2.53521867e-05, 2.43998658e-05, + 2.42001363e-05, 2.51400476e-05, 2.48339660e-05, 2.44891460e-05, 2.44014684e-05, 2.48248076e-05, + 2.46034210e-05, 2.43814104e-05, 2.44450117e-05, 2.52590856e-05, 2.49517062e-05, 2.49336954e-05, + 2.52509216e-05, 2.50208690e-05, 2.46236231e-05, 2.45401028e-05, 2.44718030e-05, 2.53274747e-05, + 2.46761316e-05, 2.46666190e-05, 2.51799078e-05, 2.51453727e-05, 2.49345114e-05, 2.45951538e-05, + 2.43941770e-05, 2.44344263e-05, 2.64834300e-05, 2.55994300e-05, 2.23448778e-05, 2.23768863e-05, + 2.40174596e-05, 2.43179558e-05, 2.41935051e-05, 2.42266051e-05, 2.49173823e-05, 2.44881615e-05, + 2.51583550e-05, 2.56745630e-05, 2.53490678e-05, 2.48743987e-05, 2.46133031e-05, 2.45301407e-05, + 2.64048027e-05, 2.53738454e-05, 2.37313293e-05, 2.46020021e-05, 2.51290303e-05, 2.47739135e-05, + 2.43905051e-05, 2.45229967e-05, 2.52553117e-05, 2.47453047e-05, 2.45854617e-05, 2.53936738e-05, + 2.56186113e-05, 2.51447951e-05, 2.45955040e-05, 2.44704846e-05, 2.43787513e-05, 2.56792278e-05, + 2.42204794e-05, 2.26199850e-05, 2.43061001e-05, 2.54437279e-05, 2.50480195e-05, 2.42950854e-05, + 2.41338437e-05, 2.43526863e-05, 2.57753319e-05, 2.54994784e-05, 2.48987626e-05, 2.53025306e-05, + 2.49128863e-05, 2.40310445e-05, 2.39322148e-05, 2.40459951e-05, 2.49042227e-05, 2.50363275e-05, + 2.51469858e-05, 2.49932080e-05, 2.49912826e-05, 2.51888019e-05, 2.47973800e-05, 2.45126414e-05, + 2.55048106e-05, 2.40835294e-05, 2.41035271e-05, 2.48666875e-05, 2.45494098e-05, 2.44897473e-05, + 2.44653932e-05, 2.57530589e-05, 2.53247816e-05, 2.43378984e-05, 2.43447815e-05, 2.46957612e-05, + 2.45757201e-05, 2.45466563e-05, 2.44299542e-05, 2.52566720e-05, 2.60352127e-05, 2.60525512e-05, + 2.64232545e-05, 2.59640253e-05, 2.42386174e-05, 2.30788293e-05, 2.28421796e-05, 2.26804248e-05, + 2.49456634e-05, 2.56355710e-05, 2.54166946e-05, 2.52205693e-05, 2.51768617e-05, 2.49597484e-05, + 2.42763938e-05, 2.33095154e-05, 2.31403430e-05, 2.31051579e-05, 2.26229591e-05, 2.57640625e-05, + 2.61855540e-05, 2.58544047e-05, 2.56412304e-05, 2.52583976e-05, 2.46664269e-05, 2.34063263e-05, + 2.22754030e-05, 2.18741040e-05, 2.61028290e-05, 2.58111319e-05, 2.60467349e-05, 2.58495606e-05, + 2.40619461e-05, 2.30209628e-05, 2.24758358e-05, 2.22385188e-05, 2.22201841e-05, 2.58940049e-05, + 2.69795622e-05, 2.63955324e-05, 2.60950117e-05, 2.48069333e-05, 2.41457842e-05, 2.38088078e-05, + 2.31103247e-05, 2.22166244e-05, 2.38460667e-05, 2.57601100e-05, 2.62552827e-05, 2.54311225e-05, + 2.60362085e-05, 2.53290498e-05, 2.28736070e-05, 2.15643062e-05, 2.18349953e-05, 2.57323835e-05, + 2.62155733e-05, 2.65088605e-05, 2.63491688e-05, 2.44907066e-05, 2.23896739e-05, 2.16310935e-05, + 2.20542976e-05, 2.55861854e-05, 2.60824576e-05, 2.66805210e-05, 2.61541058e-05, 2.35466095e-05, + 2.16462183e-05, 2.17702070e-05, 2.23195922e-05, 2.63155443e-05, 2.58461133e-05, 2.69246422e-05, + 2.61614349e-05, 2.43972927e-05, 2.29159103e-05, 2.23281466e-05, 2.60821492e-05, 2.69220191e-05, + 2.67104352e-05, 2.59511254e-05, 2.45334499e-05, 2.27554876e-05, 2.22315898e-05, 2.24342354e-05, + 2.59043538e-05, 2.66865099e-05, 2.65885625e-05, 2.61049379e-05, 2.51161035e-05, 2.40676742e-05, + 2.29875970e-05, 2.25039253e-05, 2.56900228e-05, 2.63723136e-05, 2.63071244e-05, 2.63901468e-05, + 2.58719649e-05, 2.45309440e-05, 2.30736677e-05, 2.23394098e-05, 2.24076655e-05, 2.63362952e-05, + 2.77914346e-05, 2.60456603e-05, 2.54623614e-05, 2.49039828e-05, 2.27154035e-05, 2.19717527e-05, + 2.26665922e-05, 2.62649878e-05, 2.70200586e-05, 2.67800906e-05, 2.56894301e-05, 2.48861600e-05, + 2.39422263e-05, 2.28760286e-05, 2.25757751e-05, 2.61845235e-05, 2.69440475e-05, 2.62378599e-05, + 2.60139268e-05, 2.51372922e-05, 2.35077076e-05, 2.24506912e-05, 2.25853249e-05, 2.54982411e-05, + 2.64528108e-05, 2.65061354e-05, 2.63743348e-05, 2.54390020e-05, 2.40457314e-05, 2.26417472e-05, + 2.26930543e-05, 2.29343331e-05, 2.59544082e-05, 2.66420566e-05, 2.57422613e-05, 2.59185559e-05, + 2.48525494e-05, 2.32782086e-05, 2.18857364e-05, 2.16586074e-05, 2.22088355e-05, 2.67914677e-05, + 2.77027592e-05, 2.70259714e-05, 2.58817598e-05, 2.37282615e-05, 2.28421890e-05, 2.23112484e-05, + 2.17812815e-05, 2.55756090e-05, 2.68552976e-05, 2.70569762e-05, 2.64227232e-05, 2.55116344e-05, + 2.41269687e-05, 2.30101256e-05, 2.28996642e-05, 2.71683883e-05, 2.73592253e-05, 2.64186424e-05, + 2.47696332e-05, 2.26236814e-05, 2.25163528e-05, 2.26995449e-05, 2.59550630e-05, 2.69862536e-05, + 2.67275823e-05, 2.61991014e-05, 2.49754120e-05, 2.37259793e-05, 2.30284950e-05, 2.22903664e-05, + 2.34967580e-05, 1.80528649e-05, 1.68973845e-05, 1.95130089e-05, 2.39640697e-05, 2.84360082e-05, + 3.08441429e-05, 3.09255354e-05, 3.06143668e-05, 2.42041557e-05, 2.06903559e-05, 2.16945437e-05, + 2.38842031e-05, 2.42547898e-05, 2.49272364e-05, 2.81599485e-05, 3.07992495e-05, 3.03165626e-05, + 2.97702034e-05, 3.08787144e-05, 2.21682782e-05, 1.87033687e-05, 1.90422785e-05, 2.28990371e-05, + 2.51842703e-05, 2.56314571e-05, 2.88919477e-05, 3.20491418e-05, 3.30105181e-05, 1.90411843e-05, + 1.34779457e-05, 1.55935719e-05, 2.44614719e-05, 3.08542319e-05, 3.13271867e-05, 3.11556694e-05, + 3.17624825e-05, 3.18972799e-05, 2.51711157e-05, 1.86432553e-05, 1.67298999e-05, 2.20156972e-05, + 2.69172873e-05, 2.66920382e-05, 2.61549146e-05, 2.85909335e-05, 3.13821911e-05, 3.03819557e-05, + 2.51270162e-05, 1.68522941e-05, 1.34441717e-05, 1.67433930e-05, 2.39800809e-05, 3.11513517e-05, + 3.33871746e-05, 3.25174462e-05, 1.95652394e-05, 1.50191981e-05, 1.61961807e-05, 2.16655590e-05, + 2.84755173e-05, 3.30938006e-05, 3.40670145e-05, 3.24096474e-05, 1.76964516e-05, 1.40073299e-05, + 1.61016859e-05, 2.23847250e-05, 3.08260171e-05, 3.42154219e-05, 3.28686078e-05, 3.15421411e-05, + 1.68852280e-05, 1.24363240e-05, 1.75263533e-05, 2.46965985e-05, 2.77404334e-05, 2.89538141e-05, + 3.04390321e-05, 2.15001093e-05, 1.83792576e-05, 1.77715154e-05, 1.92519157e-05, 2.49193319e-05, + 3.06813348e-05, 3.18573703e-05, 3.12719873e-05, 2.24361380e-05, 1.93066954e-05, 1.94824932e-05, + 2.18435981e-05, 2.38550356e-05, 2.56354917e-05, 2.93622144e-05, 3.11011024e-05, 2.33241297e-05, + 1.91478888e-05, 1.92733204e-05, 2.08241792e-05, 2.21005365e-05, 2.53980816e-05, 2.92821189e-05, + 3.14291815e-05, 3.13355882e-05, 2.59783863e-05, 1.88351706e-05, 1.30484862e-05, 1.41556159e-05, + 2.06114580e-05, 2.93758644e-05, 3.20381124e-05, 2.91163974e-05, 2.02294656e-05, 1.71032378e-05, + 1.97681024e-05, 2.47133925e-05, 2.59827828e-05, 2.72210127e-05, 3.02089032e-05, 3.10904076e-05, + 2.61439270e-05, 2.00912138e-05, 1.64825944e-05, 1.97773054e-05, 2.42286668e-05, 2.84097838e-05, + 3.09054141e-05, 3.10095563e-05, 2.36176481e-05, 1.91838482e-05, 1.85367735e-05, 2.16300162e-05, + 2.52855793e-05, 2.80954605e-05, 3.11437218e-05, 3.02580496e-05, 2.87725918e-05, 2.39129039e-05, + 1.70974506e-05, 1.42982291e-05, 1.90116441e-05, 2.65133128e-05, 3.07278827e-05, 3.30259354e-05, + 3.32205459e-05, 3.18054060e-05, 2.18865114e-05, 1.87200309e-05, 1.83495441e-05, 2.26656393e-05, + 2.82154661e-05, 2.74359560e-05, 2.91141043e-05, 3.21202879e-05, 2.20328036e-05, 1.91838262e-05, + 1.90708863e-05, 2.00922717e-05, 2.25472379e-05, 2.79936412e-05, 3.05850213e-05, 2.95913454e-05, + 1.99824913e-05, 1.52803374e-05, 1.72207905e-05, 2.43215432e-05, 3.09789364e-05, 3.11412866e-05, + 3.02033535e-05, 2.42041252e-05, 1.98234009e-05, 1.72703955e-05, 1.84722331e-05, 2.29863650e-05, + 2.66435874e-05, 2.92253781e-05, 3.18505952e-05, 2.51305126e-05, 2.36127295e-05, 2.31480730e-05, + 2.36897533e-05, 2.45176715e-05, 2.53532507e-05, 2.55920358e-05, 2.57441086e-05, 2.59656635e-05, + 2.53748584e-05, 2.46088591e-05, 2.49214368e-05, 2.51538593e-05, 2.51767746e-05, 2.53167234e-05, + 2.53850783e-05, 2.54309659e-05, 2.57103413e-05, 2.58987997e-05, 2.59233520e-05, 2.46576928e-05, + 2.36857947e-05, 2.40729888e-05, 2.47965100e-05, 2.50436041e-05, 2.54929051e-05, 2.59028808e-05, + 2.57735311e-05, 2.56937965e-05, 2.38534227e-05, 2.13003387e-05, 2.25057776e-05, 2.45951416e-05, + 2.48325577e-05, 2.54767069e-05, 2.59405921e-05, 2.59037481e-05, 2.58686213e-05, 2.45080699e-05, + 2.29673400e-05, 2.27681682e-05, 2.43603027e-05, 2.51943168e-05, 2.57736334e-05, 2.61316201e-05, + 2.62094790e-05, 2.60534061e-05, 2.51459800e-05, 2.46252218e-05, 2.29477087e-05, 2.16156452e-05, + 2.30942380e-05, 2.50586479e-05, 2.56461393e-05, 2.57573039e-05, 2.59131325e-05, 2.43098406e-05, + 2.20176921e-05, 2.24127339e-05, 2.41091780e-05, 2.51412673e-05, 2.52953282e-05, 2.54281019e-05, + 2.57985831e-05, 2.38853042e-05, 2.14582767e-05, 2.22123555e-05, 2.43334916e-05, 2.52407967e-05, + 2.53544153e-05, 2.58224708e-05, 2.59226309e-05, 2.29086098e-05, 2.03786244e-05, 2.26331678e-05, + 2.43159535e-05, 2.53761941e-05, 2.62682508e-05, 2.62839659e-05, 2.43244731e-05, 2.29363177e-05, + 2.29149249e-05, 2.40419202e-05, 2.56746788e-05, 2.58880150e-05, 2.58747534e-05, 2.59318627e-05, + 2.45521341e-05, 2.34079854e-05, 2.35371414e-05, 2.43377117e-05, 2.52434875e-05, 2.59882129e-05, + 2.61036593e-05, 2.59381549e-05, 2.47604265e-05, 2.36439911e-05, 2.37335817e-05, 2.39698408e-05, + 2.45597301e-05, 2.56313414e-05, 2.60591518e-05, 2.59474650e-05, 2.59296659e-05, 2.40504853e-05, + 2.23097158e-05, 2.07401112e-05, 2.21219526e-05, 2.52358727e-05, 2.63084492e-05, 2.59959205e-05, + 2.64166893e-05, 2.39797048e-05, 2.23777389e-05, 2.34342046e-05, 2.47162502e-05, 2.52674385e-05, + 2.58459860e-05, 2.59442045e-05, 2.58885028e-05, 2.41584990e-05, 2.33578567e-05, 2.27937847e-05, + 2.41092455e-05, 2.52115237e-05, 2.59413316e-05, 2.60425490e-05, 2.59082986e-05, 2.49229101e-05, + 2.35824146e-05, 2.33526936e-05, 2.40837781e-05, 2.48822285e-05, 2.55846869e-05, 2.58216976e-05, + 2.60675114e-05, 2.63007326e-05, 2.45272677e-05, 2.27100234e-05, 2.19699453e-05, 2.40081528e-05, + 2.52211242e-05, 2.54774918e-05, 2.56795393e-05, 2.57599761e-05, 2.59099015e-05, 2.37451069e-05, + 2.23540022e-05, 2.28351106e-05, 2.45820001e-05, 2.58115082e-05, 2.66812505e-05, 2.66875471e-05, + 2.61009462e-05, 2.48113572e-05, 2.32280726e-05, 2.30207618e-05, 2.38151630e-05, 2.48961374e-05, + 2.55415610e-05, 2.57264269e-05, 2.61072763e-05, 2.31391899e-05, 2.11601200e-05, 2.29596098e-05, + 2.55176050e-05, 2.58899000e-05, 2.59154843e-05, 2.60793488e-05, 2.45171656e-05, 2.32653063e-05, + 2.27059318e-05, 2.36041813e-05, 2.53692477e-05, 2.61229389e-05, 2.61093416e-05, 2.58345648e-05, + 2.54594545e-05, 2.50939865e-05, 2.48763430e-05, 2.44891678e-05, 2.41933006e-05, 2.44181831e-05, + 2.43636901e-05, 2.46221979e-05, 2.50762796e-05, 2.56566455e-05, 2.56407878e-05, 2.57817405e-05, + 2.53637409e-05, 2.52775184e-05, 2.53094930e-05, 2.45382502e-05, 2.40856239e-05, 2.46680458e-05, + 2.51115749e-05, 2.49540381e-05, 2.51006700e-05, 2.48842226e-05, 2.54352595e-05, 2.50709643e-05, + 2.47364579e-05, 2.54094040e-05, 2.53017270e-05, 2.45037627e-05, 2.42393411e-05, 2.50241164e-05, + 2.36401262e-05, 2.44671065e-05, 2.41673757e-05, 2.30372314e-05, 2.40797915e-05, 2.49399281e-05, + 2.47803733e-05, 2.46972571e-05, 2.37947806e-05, 2.35933561e-05, 2.42573959e-05, 2.46209389e-05, + 2.45093216e-05, 2.56125810e-05, 2.64282467e-05, 2.59314735e-05, 2.51104845e-05, 2.36595697e-05, + 2.40129830e-05, 2.45233450e-05, 2.42847609e-05, 2.48665670e-05, 2.51571731e-05, 2.44093985e-05, + 2.43146206e-05, 2.46963899e-05, 2.56164908e-05, 2.39152174e-05, 2.39095766e-05, 2.43078622e-05, + 2.40362929e-05, 2.35183370e-05, 2.36558257e-05, 2.45012593e-05, 2.58153956e-05, 2.35507450e-05, + 2.35917085e-05, 2.44293297e-05, 2.37471012e-05, 2.35112694e-05, 2.44891044e-05, 2.48472005e-05, + 2.44301691e-05, 2.26699481e-05, 2.35582634e-05, 2.36043085e-05, 2.46229243e-05, 2.59588865e-05, + 2.56923658e-05, 2.47645883e-05, 2.36684002e-05, 2.39447886e-05, 2.52701503e-05, 2.59674928e-05, + 2.49235516e-05, 2.47140495e-05, 2.49055547e-05, 2.48037465e-05, 2.40725039e-05, 2.42244149e-05, + 2.46486331e-05, 2.55378525e-05, 2.63193715e-05, 2.55679400e-05, 2.49442876e-05, 2.48492211e-05, + 2.45821166e-05, 2.46858618e-05, 2.44058377e-05, 2.49489969e-05, 2.57341476e-05, 2.55030563e-05, + 2.49095666e-05, 2.48916000e-05, 2.27791000e-05, 2.23298371e-05, 2.28850724e-05, 2.47336987e-05, + 2.68659557e-05, 2.59432658e-05, 2.49101050e-05, 2.61998824e-05, 2.46868869e-05, 2.33201121e-05, + 2.39048130e-05, 2.43012521e-05, 2.48981357e-05, 2.56015625e-05, 2.51102267e-05, 2.48558071e-05, + 2.29178929e-05, 2.36227861e-05, 2.44540323e-05, 2.51374515e-05, 2.53496276e-05, 2.54807005e-05, + 2.51669624e-05, 2.49049523e-05, 2.50380599e-05, 2.44510153e-05, 2.43516722e-05, 2.42764940e-05, + 2.44182258e-05, 2.49095593e-05, 2.47262188e-05, 2.53261627e-05, 2.60594318e-05, 2.42274372e-05, + 2.39363023e-05, 2.43296352e-05, 2.53290107e-05, 2.46656612e-05, 2.41801169e-05, 2.42118300e-05, + 2.43366054e-05, 2.47854044e-05, 2.35732846e-05, 2.24607386e-05, 2.34994597e-05, 2.47701319e-05, + 2.52901379e-05, 2.71027581e-05, 2.67106947e-05, 2.50923753e-05, 2.54371840e-05, 2.38042718e-05, + 2.34835610e-05, 2.44484866e-05, 2.53877634e-05, 2.48566029e-05, 2.46488174e-05, 2.55276455e-05, + 2.32807153e-05, 2.21466438e-05, 2.43318371e-05, 2.58788184e-05, 2.48766088e-05, 2.48965730e-05, + 2.53579504e-05, 2.41130775e-05, 2.35760332e-05, 2.38318812e-05, 2.48523868e-05, 2.60918836e-05, + 2.62699226e-05, 2.56070759e-05, 2.46420673e-05, 2.38320782e-05, 1.87524488e-05, 1.76585797e-05, + 1.94257273e-05, 2.29206660e-05, 2.75342821e-05, 3.01679490e-05, 3.06563249e-05, 3.09623063e-05, + 2.47240220e-05, 2.14558631e-05, 2.24902395e-05, 2.40967211e-05, 2.43565403e-05, 2.50437307e-05, + 2.73983173e-05, 2.97004854e-05, 2.99924016e-05, 2.99904518e-05, 3.11048262e-05, 2.22463115e-05, + 1.91061434e-05, 1.98544656e-05, 2.28738817e-05, 2.46442122e-05, 2.58601732e-05, 2.92325831e-05, + 3.18821180e-05, 3.27128060e-05, 1.95008958e-05, 1.42408754e-05, 1.63501409e-05, 2.33408362e-05, + 2.82314270e-05, 3.03163664e-05, 3.14311265e-05, 3.19567461e-05, 3.19980161e-05, 2.35766658e-05, + 1.79866878e-05, 1.70558347e-05, 2.16411356e-05, 2.60780919e-05, 2.72062895e-05, 2.76369940e-05, + 2.97537864e-05, 3.19900088e-05, 2.86059027e-05, 2.37787541e-05, 1.73522428e-05, 1.46311012e-05, + 1.75303686e-05, 2.39647293e-05, 3.06073735e-05, 3.33596917e-05, 3.28196825e-05, 2.04562134e-05, + 1.55332494e-05, 1.63951843e-05, 2.10399566e-05, 2.70743296e-05, 3.16079400e-05, 3.31389226e-05, + 3.23497787e-05, 1.90475467e-05, 1.45584099e-05, 1.60927767e-05, 2.17726644e-05, 2.92319422e-05, + 3.30856747e-05, 3.29460956e-05, 3.17786916e-05, 1.73062480e-05, 1.29193584e-05, 1.71175190e-05, + 2.29426131e-05, 2.70655123e-05, 3.02253876e-05, 3.16791810e-05, 2.13345625e-05, 1.78470974e-05, + 1.76062424e-05, 1.98876196e-05, 2.57858828e-05, 3.08138352e-05, 3.19732313e-05, 3.15250769e-05, + 2.21891577e-05, 1.89024073e-05, 1.91723511e-05, 2.15192369e-05, 2.42568000e-05, 2.69439420e-05, + 3.01598683e-05, 3.13688996e-05, 2.30314177e-05, 1.92103467e-05, 1.94008977e-05, 2.04269677e-05, + 2.20365418e-05, 2.60034708e-05, 2.99716054e-05, 3.17323063e-05, 3.15841927e-05, 2.31622005e-05, + 1.70955490e-05, 1.34654922e-05, 1.54536400e-05, 2.25369356e-05, 3.07171614e-05, 3.25303238e-05, + 3.07678797e-05, 2.01881132e-05, 1.66216618e-05, 1.91228630e-05, 2.37168667e-05, 2.56105928e-05, + 2.77620009e-05, 3.05154796e-05, 3.12183647e-05, 2.34660673e-05, 1.91312713e-05, 1.70157627e-05, + 2.02121267e-05, 2.44104902e-05, 2.89257417e-05, 3.14661088e-05, 3.11929305e-05, 2.34987871e-05, + 1.91274404e-05, 1.85290770e-05, 2.09801027e-05, 2.43806653e-05, 2.78150464e-05, 3.10847298e-05, + 3.08971303e-05, 3.01490175e-05, 2.29109687e-05, 1.70888646e-05, 1.52877043e-05, 1.97375241e-05, + 2.58625592e-05, 2.97570814e-05, 3.26867154e-05, 3.31667690e-05, 3.20206505e-05, 2.05238176e-05, + 1.71191156e-05, 1.76875993e-05, 2.23588578e-05, 2.84505629e-05, 2.99752336e-05, 3.15062072e-05, + 3.29424438e-05, 2.24577863e-05, 1.85783938e-05, 1.82217766e-05, 1.98617839e-05, 2.28758290e-05, + 2.76359574e-05, 3.02841418e-05, 3.03779145e-05, 1.87479171e-05, 1.44930130e-05, 1.74883842e-05, + 2.50854308e-05, 3.11110244e-05, 3.13455255e-05, 3.08769804e-05, 2.30504177e-05, 1.88809618e-05, + 1.71384945e-05, 1.88924447e-05, 2.40127870e-05, 2.79768528e-05, 3.00519555e-05, 3.18485783e-05, + 2.33853626e-05, 1.76739992e-05, 1.64854450e-05, 1.88622726e-05, 2.32336219e-05, 2.83299495e-05, + 3.12326921e-05, 3.15353591e-05, 3.14822826e-05, 2.42564527e-05, 2.05235928e-05, 2.16269318e-05, + 2.37547256e-05, 2.41120715e-05, 2.48672349e-05, 2.80845128e-05, 3.09638623e-05, 3.07950118e-05, + 3.04325853e-05, 3.17311686e-05, 2.18054494e-05, 1.82276807e-05, 1.87760489e-05, 2.25556188e-05, + 2.48342687e-05, 2.57095616e-05, 2.94750555e-05, 3.29131659e-05, 3.39917695e-05, 1.86131930e-05, + 1.29535784e-05, 1.51244407e-05, 2.37453984e-05, 3.02371215e-05, 3.16277671e-05, 3.20819131e-05, + 3.27576199e-05, 3.28697829e-05, 2.42978334e-05, 1.76703318e-05, 1.61135617e-05, 2.14233849e-05, + 2.66329734e-05, 2.70444236e-05, 2.69026703e-05, 2.95326532e-05, 3.25169896e-05, 3.01287077e-05, + 2.43714791e-05, 1.63204211e-05, 1.31026356e-05, 1.63357487e-05, 2.37513072e-05, 3.16605224e-05, + 3.45834786e-05, 3.37105020e-05, 1.93710247e-05, 1.44228092e-05, 1.54996220e-05, 2.09226737e-05, + 2.81226157e-05, 3.34727495e-05, 3.49338414e-05, 3.33966211e-05, 1.75904964e-05, 1.34006932e-05, + 1.53068300e-05, 2.17112342e-05, 3.07399947e-05, 3.50070769e-05, 3.40151917e-05, 3.25183262e-05, + 1.63191372e-05, 1.17766179e-05, 1.66095307e-05, 2.36913259e-05, 2.76492002e-05, 3.00055340e-05, + 3.17221994e-05, 2.09630804e-05, 1.74498047e-05, 1.69803184e-05, 1.89188708e-05, 2.52188923e-05, + 3.14523063e-05, 3.28301705e-05, 3.22077069e-05, 2.19428058e-05, 1.84934866e-05, 1.87251260e-05, + 2.12602568e-05, 2.38130069e-05, 2.62333760e-05, 3.02458189e-05, 3.20137748e-05, 2.28940341e-05, + 1.85429199e-05, 1.87068414e-05, 2.01223080e-05, 2.16640540e-05, 2.56297717e-05, 3.00993508e-05, + 3.24185686e-05, 3.22804643e-05, 2.45787871e-05, 1.73544695e-05, 1.23661443e-05, 1.38783471e-05, + 2.09690706e-05, 3.05296774e-05, 3.32361226e-05, 3.03799361e-05, 1.96508009e-05, 1.61324739e-05, + 1.88714799e-05, 2.40859020e-05, 2.58106810e-05, 2.76583046e-05, 3.09870677e-05, 3.19304781e-05, + 2.48347396e-05, 1.90666112e-05, 1.59490817e-05, 1.93880617e-05, 2.41216230e-05, 2.90062365e-05, + 3.19310344e-05, 3.18633871e-05, 2.33010669e-05, 1.85258123e-05, 1.78613154e-05, 2.08724621e-05, + 2.47677994e-05, 2.82512219e-05, 3.18984703e-05, 3.12108869e-05, 2.98470100e-05, 2.31975375e-05, + 1.63451675e-05, 1.38908721e-05, 1.87039237e-05, 2.62704131e-05, 3.09460591e-05, 3.39887745e-05, + 3.43695996e-05, 3.28191482e-05, 2.08051036e-05, 1.73000739e-05, 1.73573533e-05, 2.21649835e-05, + 2.86443970e-05, 2.88666383e-05, 3.07370138e-05, 3.35011757e-05, 2.18218031e-05, 1.82678334e-05, + 1.80323003e-05, 1.94145974e-05, 2.23384771e-05, 2.80963326e-05, 3.11203848e-05, 3.05065889e-05, + 1.88182813e-05, 1.40996090e-05, 1.66009009e-05, 2.45033101e-05, 3.18014589e-05, 3.20289660e-05, + 3.11641637e-05, 2.34444079e-05, 1.87887916e-05, 1.64695286e-05, 1.79904354e-05, 2.31496978e-05, + 2.73854818e-05, 3.01013590e-05, 3.27620664e-05, 2.53769293e-05, 2.88398271e-05, 2.95081449e-05, + 2.85484202e-05, 2.59890516e-05, 2.24823303e-05, 2.05461537e-05, 2.02800332e-05, 2.01997462e-05, + 2.47450944e-05, 2.70325585e-05, 2.63205058e-05, 2.51809621e-05, 2.49859189e-05, 2.44851634e-05, + 2.26115871e-05, 2.07962461e-05, 2.07595390e-05, 2.08807886e-05, 2.00675034e-05, 2.65176938e-05, + 2.86779577e-05, 2.80980382e-05, 2.60628152e-05, 2.47206933e-05, 2.39000394e-05, 2.14583088e-05, + 1.93993608e-05, 1.87504992e-05, 2.84012612e-05, 3.13935267e-05, 3.02857659e-05, 2.56600028e-05, + 2.15537893e-05, 2.03520254e-05, 1.98409206e-05, 1.94369441e-05, 1.93830167e-05, 2.54307512e-05, + 2.96810923e-05, 3.00394440e-05, 2.69692033e-05, 2.35986852e-05, 2.29577301e-05, 2.27718737e-05, + 2.12360799e-05, 1.95149373e-05, 2.14710549e-05, 2.52993627e-05, 2.97902768e-05, 3.09070186e-05, + 2.95769859e-05, 2.52656320e-05, 2.02498034e-05, 1.83489399e-05, 1.88346196e-05, 2.76875990e-05, + 3.08726178e-05, 3.05050045e-05, 2.74231463e-05, 2.27371118e-05, 1.92448048e-05, 1.82515613e-05, + 1.90828811e-05, 2.84750389e-05, 3.13811202e-05, 3.07823395e-05, 2.68743999e-05, 2.10324825e-05, + 1.82310576e-05, 1.86817619e-05, 1.95776506e-05, 2.98470574e-05, 3.22188196e-05, 3.02380939e-05, + 2.59147912e-05, 2.28782666e-05, 2.09216589e-05, 1.98839104e-05, 2.71865161e-05, 2.97548966e-05, + 2.98321758e-05, 2.81092407e-05, 2.40123829e-05, 2.02586000e-05, 1.94050324e-05, 1.97669391e-05, + 2.65635175e-05, 2.89725629e-05, 2.87635325e-05, 2.70577284e-05, 2.50742047e-05, 2.32368478e-05, + 2.08768618e-05, 1.98845051e-05, 2.59412390e-05, 2.86739585e-05, 2.85302855e-05, 2.78638243e-05, + 2.66726106e-05, 2.38345348e-05, 2.09908607e-05, 1.96279065e-05, 1.97226781e-05, 2.56061892e-05, + 3.05640562e-05, 3.20238418e-05, 3.04560016e-05, 2.61984074e-05, 2.05870247e-05, 1.90945945e-05, + 2.06108960e-05, 2.80016670e-05, 3.06044000e-05, 2.88482268e-05, 2.53815136e-05, 2.40153617e-05, + 2.25599460e-05, 2.05161111e-05, 1.99611225e-05, 2.53773541e-05, 2.88808610e-05, 2.99866691e-05, + 2.79225411e-05, 2.49515364e-05, 2.17137979e-05, 1.98829841e-05, 1.99929766e-05, 2.56027200e-05, + 2.87530753e-05, 2.91592045e-05, 2.74687920e-05, 2.48827085e-05, 2.23863732e-05, 2.00142466e-05, + 2.03123324e-05, 2.09949655e-05, 2.59990837e-05, 3.01338009e-05, 3.07305431e-05, 2.81918841e-05, + 2.37895486e-05, 2.07843593e-05, 1.87582961e-05, 1.84834533e-05, 1.93955167e-05, 2.78365540e-05, + 3.05202354e-05, 2.98988367e-05, 2.64384337e-05, 2.20094614e-05, 2.13030025e-05, 2.02369864e-05, + 1.88807347e-05, 2.63578428e-05, 2.92410892e-05, 2.95452918e-05, 2.82574928e-05, 2.60623636e-05, + 2.25060072e-05, 2.05484126e-05, 2.07178764e-05, 2.92038607e-05, 3.21828742e-05, 2.97820183e-05, + 2.45016493e-05, 2.00407540e-05, 1.98863529e-05, 2.03344483e-05, 2.58815416e-05, 2.90672903e-05, + 3.01402331e-05, 2.88168375e-05, 2.52622896e-05, 2.25166018e-05, 2.09600956e-05, 1.94665020e-05, + 2.51830001e-05, 2.60458841e-05, 2.60788283e-05, 2.66688827e-05, 2.62862122e-05, 2.42749484e-05, + 2.29579238e-05, 2.26352916e-05, 2.23623113e-05, 2.47944612e-05, 2.55325187e-05, 2.52711224e-05, + 2.51668047e-05, 2.51393925e-05, 2.48908070e-05, 2.42917520e-05, 2.32799839e-05, 2.29667089e-05, + 2.28380274e-05, 2.23205248e-05, 2.58235674e-05, 2.62834324e-05, 2.57902935e-05, 2.57000802e-05, + 2.53601074e-05, 2.45405198e-05, 2.31418220e-05, 2.20108360e-05, 2.16023980e-05, 2.61656450e-05, + 2.59444056e-05, 2.61179176e-05, 2.61652828e-05, 2.43796005e-05, 2.29493837e-05, 2.21558472e-05, + 2.19160398e-05, 2.19109001e-05, 2.63121024e-05, 2.75081095e-05, 2.66096047e-05, 2.63104419e-05, + 2.49028876e-05, 2.39124913e-05, 2.33673060e-05, 2.26837464e-05, 2.18291015e-05, 2.39898239e-05, + 2.61044308e-05, 2.63903776e-05, 2.53601250e-05, 2.60571542e-05, 2.53367230e-05, 2.27135997e-05, + 2.12342174e-05, 2.14722198e-05, 2.56242748e-05, 2.64168323e-05, 2.68038085e-05, 2.66712580e-05, + 2.46490714e-05, 2.23358406e-05, 2.14346337e-05, 2.17587875e-05, 2.53671939e-05, 2.63040597e-05, + 2.70762272e-05, 2.64291419e-05, 2.36248005e-05, 2.14797793e-05, 2.14368492e-05, 2.19956912e-05, + 2.64823990e-05, 2.61609365e-05, 2.74187876e-05, 2.66648784e-05, 2.44109710e-05, 2.24598526e-05, + 2.18475077e-05, 2.62536984e-05, 2.74147406e-05, 2.70826829e-05, 2.59422457e-05, 2.42686190e-05, + 2.24772579e-05, 2.19207150e-05, 2.21150752e-05, 2.60556382e-05, 2.70674829e-05, 2.69218964e-05, + 2.63126029e-05, 2.50100220e-05, 2.36770508e-05, 2.26155618e-05, 2.21869700e-05, 2.58113199e-05, + 2.65793206e-05, 2.64833397e-05, 2.66794649e-05, 2.59802943e-05, 2.43172129e-05, 2.27254447e-05, + 2.20064148e-05, 2.20874980e-05, 2.70881841e-05, 2.87994532e-05, 2.63735795e-05, 2.53300486e-05, + 2.44505617e-05, 2.22372527e-05, 2.15882252e-05, 2.21346479e-05, 2.64569205e-05, 2.75755750e-05, + 2.72284174e-05, 2.59513988e-05, 2.49033004e-05, 2.36859389e-05, 2.25779795e-05, 2.22857554e-05, + 2.68756661e-05, 2.74968673e-05, 2.63735391e-05, 2.60560132e-05, 2.50783853e-05, 2.32205451e-05, + 2.20841303e-05, 2.22871548e-05, 2.55526289e-05, 2.67037421e-05, 2.67714522e-05, 2.67071923e-05, + 2.56405737e-05, 2.39486770e-05, 2.23860648e-05, 2.23287130e-05, 2.24614835e-05, 2.62664542e-05, + 2.69836071e-05, 2.57458779e-05, 2.58860918e-05, 2.49187641e-05, 2.32243603e-05, 2.16209191e-05, + 2.13378270e-05, 2.18812814e-05, 2.73682377e-05, 2.86552143e-05, 2.75772464e-05, 2.60407098e-05, + 2.35088018e-05, 2.21645079e-05, 2.16446392e-05, 2.13385867e-05, 2.55317388e-05, 2.73258279e-05, + 2.76379003e-05, 2.66914033e-05, 2.54771589e-05, 2.40523677e-05, 2.28218404e-05, 2.25239468e-05, + 2.78432447e-05, 2.82089737e-05, 2.66353263e-05, 2.45493152e-05, 2.23362954e-05, 2.22102545e-05, + 2.23299966e-05, 2.62974856e-05, 2.75514222e-05, 2.71138779e-05, 2.62999759e-05, 2.47239432e-05, + 2.33070254e-05, 2.26541910e-05, 2.20014411e-05, 2.44971229e-05, 2.14227153e-05, 2.06481983e-05, + 2.26643800e-05, 2.53238460e-05, 2.68924184e-05, 2.74469751e-05, 2.72962704e-05, 2.69672214e-05, + 2.47277549e-05, 2.29231816e-05, 2.34337541e-05, 2.47228882e-05, 2.49315582e-05, 2.52051624e-05, + 2.67468303e-05, 2.76151800e-05, 2.71702241e-05, 2.68012172e-05, 2.70811716e-05, 2.39894874e-05, + 2.19596958e-05, 2.19722720e-05, 2.43840048e-05, 2.55974379e-05, 2.54362715e-05, 2.65027557e-05, + 2.75011444e-05, 2.77365796e-05, 2.21339629e-05, 1.81400372e-05, 1.97496173e-05, 2.55683504e-05, + 2.82932293e-05, 2.76988638e-05, 2.71260857e-05, 2.72938420e-05, 2.73603482e-05, 2.60723043e-05, + 2.24357696e-05, 2.07450367e-05, 2.41220977e-05, 2.63723157e-05, 2.57105246e-05, 2.51119619e-05, + 2.60757413e-05, 2.70430989e-05, 2.78069528e-05, 2.59410584e-05, 2.07426152e-05, 1.79041783e-05, + 2.05329425e-05, 2.48651548e-05, 2.74630742e-05, 2.76902034e-05, 2.74025556e-05, 2.22414095e-05, + 1.94509619e-05, 2.04452130e-05, 2.40666275e-05, 2.71228375e-05, 2.82452793e-05, 2.81629080e-05, + 2.75288359e-05, 2.08983535e-05, 1.86655357e-05, 2.04838902e-05, 2.44104464e-05, 2.78341548e-05, + 2.82671491e-05, 2.75585623e-05, 2.72289833e-05, 2.08025177e-05, 1.74212366e-05, 2.16269910e-05, + 2.59595312e-05, 2.65759952e-05, 2.61416167e-05, 2.65637917e-05, 2.37689048e-05, 2.22159527e-05, + 2.16605523e-05, 2.21761807e-05, 2.48802412e-05, 2.70718516e-05, 2.73458284e-05, 2.71618607e-05, + 2.42665151e-05, 2.26986905e-05, 2.27535832e-05, 2.40142228e-05, 2.46272805e-05, 2.49832491e-05, + 2.64517127e-05, 2.71165630e-05, 2.46993198e-05, 2.23830064e-05, 2.24250540e-05, 2.35286044e-05, + 2.40209092e-05, 2.51839664e-05, 2.64729205e-05, 2.71769154e-05, 2.71780974e-05, 2.69534595e-05, + 2.31040456e-05, 1.79669340e-05, 1.84158580e-05, 2.23758064e-05, 2.62366131e-05, 2.72309511e-05, + 2.60381211e-05, 2.30424654e-05, 2.13925941e-05, 2.30765431e-05, 2.56145101e-05, 2.58307704e-05, + 2.58850945e-05, 2.68817314e-05, 2.71712068e-05, 2.69458038e-05, 2.34084896e-05, 2.04778103e-05, + 2.25700736e-05, 2.48852934e-05, 2.62841520e-05, 2.69514595e-05, 2.71296391e-05, 2.47523499e-05, + 2.24604514e-05, 2.20544405e-05, 2.40603908e-05, 2.58009050e-05, 2.65199298e-05, 2.72602785e-05, + 2.67588525e-05, 2.60452114e-05, 2.52827517e-05, 2.11519092e-05, 1.86745215e-05, 2.19936226e-05, + 2.61472497e-05, 2.75437777e-05, 2.77562692e-05, 2.76731727e-05, 2.72944281e-05, 2.45282245e-05, + 2.29643462e-05, 2.22628326e-05, 2.44025590e-05, 2.63402054e-05, 2.51533712e-05, 2.57473198e-05, + 2.71155542e-05, 2.37671943e-05, 2.27263391e-05, 2.27820266e-05, 2.30564140e-05, 2.40599737e-05, + 2.65206420e-05, 2.72274529e-05, 2.65205454e-05, 2.34859134e-05, 2.03136711e-05, 2.10972888e-05, + 2.46732575e-05, 2.71434273e-05, 2.71518109e-05, 2.67306936e-05, 2.54765806e-05, 2.32531869e-05, + 2.13251640e-05, 2.18118971e-05, 2.39628458e-05, 2.53537626e-05, 2.64008185e-05, 2.73925161e-05, + 2.44539204e-05, 2.11837718e-05, 2.03752233e-05, 2.23810039e-05, 2.51371339e-05, 2.69784125e-05, + 2.77021562e-05, 2.75977171e-05, 2.73113940e-05, 2.47410785e-05, 2.28004132e-05, 2.33591997e-05, + 2.46847450e-05, 2.48993982e-05, 2.52095801e-05, 2.68320565e-05, 2.78236190e-05, 2.74296443e-05, + 2.70837727e-05, 2.74289042e-05, 2.38503414e-05, 2.17072863e-05, 2.17864555e-05, 2.42680891e-05, + 2.55391942e-05, 2.54904068e-05, 2.67473561e-05, 2.78806437e-05, 2.81626234e-05, 2.19028337e-05, + 1.77652427e-05, 1.94327941e-05, 2.53994035e-05, 2.83377662e-05, 2.79493739e-05, 2.74949333e-05, + 2.76908876e-05, 2.77564997e-05, 2.58839862e-05, 2.20343998e-05, 2.04062679e-05, 2.39186660e-05, + 2.63764813e-05, 2.58522186e-05, 2.53267250e-05, 2.63860042e-05, 2.74570708e-05, 2.79159809e-05, + 2.57812224e-05, 2.04324704e-05, 1.75898567e-05, 2.02580965e-05, 2.48051358e-05, 2.77504988e-05, + 2.81650288e-05, 2.78551094e-05, 2.20866034e-05, 1.90819268e-05, 2.00692972e-05, 2.38131869e-05, + 2.71549997e-05, 2.85599316e-05, 2.85955885e-05, 2.79406168e-05, 2.07299111e-05, 1.82728522e-05, + 2.00742361e-05, 2.41951334e-05, 2.79913959e-05, 2.86900714e-05, 2.80113515e-05, 2.76169574e-05, + 2.04826436e-05, 1.69801140e-05, 2.12135598e-05, 2.57229956e-05, 2.66463763e-05, 2.64821623e-05, + 2.69833243e-05, 2.35669959e-05, 2.18208633e-05, 2.12923715e-05, 2.19764070e-05, 2.49679856e-05, + 2.73987698e-05, 2.77410349e-05, 2.75354125e-05, 2.41001442e-05, 2.23628468e-05, 2.24386232e-05, + 2.38087077e-05, 2.46096278e-05, 2.51540134e-05, 2.67685273e-05, 2.74814509e-05, 2.45722247e-05, + 2.21038493e-05, 2.21599661e-05, 2.32641681e-05, 2.38608682e-05, 2.52675337e-05, 2.67745696e-05, + 2.75645898e-05, 2.75549792e-05, 2.66548119e-05, 2.25481393e-05, 1.75293747e-05, 1.81337223e-05, + 2.23853690e-05, 2.66068593e-05, 2.76726473e-05, 2.64237545e-05, 2.27972539e-05, 2.09510389e-05, + 2.27283962e-05, 2.54750611e-05, 2.58359251e-05, 2.60580653e-05, 2.71982729e-05, 2.75218380e-05, + 2.66761768e-05, 2.30315792e-05, 2.01592336e-05, 2.23666295e-05, 2.48610959e-05, 2.65196652e-05, + 2.73331739e-05, 2.74809049e-05, 2.46614038e-05, 2.21668328e-05, 2.17398947e-05, 2.38019682e-05, + 2.57045921e-05, 2.66540555e-05, 2.75957180e-05, 2.71108270e-05, 2.63860868e-05, 2.50984917e-05, + 2.07793848e-05, 1.83530794e-05, 2.17956078e-05, 2.61500344e-05, 2.77612383e-05, 2.81793111e-05, + 2.81352573e-05, 2.76960471e-05, 2.41868370e-05, 2.24244664e-05, 2.18475973e-05, 2.42402152e-05, + 2.65358587e-05, 2.55353488e-05, 2.62013534e-05, 2.75927302e-05, 2.36639024e-05, 2.23567418e-05, + 2.23723129e-05, 2.27799107e-05, 2.39695592e-05, 2.66405614e-05, 2.75052840e-05, 2.68491083e-05, + 2.30642263e-05, 1.97525808e-05, 2.07684784e-05, 2.47198577e-05, 2.74878633e-05, 2.75128950e-05, + 2.70828967e-05, 2.52891350e-05, 2.28657512e-05, 2.09416574e-05, 2.15524742e-05, 2.39744971e-05, + 2.55782368e-05, 2.67128487e-05, 2.77759598e-05, 2.51830931e-05, 3.37618581e-05, 3.58803222e-05, + 3.15163378e-05, 2.49670590e-05, 1.92500339e-05, 1.65605641e-05, 1.63743299e-05, 1.65395682e-05, + 2.41393982e-05, 2.92496787e-05, 2.76698148e-05, 2.46805440e-05, 2.42051735e-05, 2.32938966e-05, + 1.95314104e-05, 1.67123711e-05, 1.70244264e-05, 1.74662991e-05, 1.62972740e-05, 2.72070614e-05, + 3.27249486e-05, 3.19679770e-05, 2.61608022e-05, 2.31551264e-05, 2.23387835e-05, 1.83974573e-05, + 1.52165948e-05, 1.43185228e-05, 3.21126272e-05, 4.29443857e-05, 3.84454374e-05, 2.43020883e-05, + 1.70237122e-05, 1.61461314e-05, 1.60013285e-05, 1.54115193e-05, 1.53009680e-05, 2.34834626e-05, + 3.32447063e-05, 3.63944664e-05, 2.75930835e-05, 2.10366102e-05, 2.09215319e-05, 2.12908541e-05, + 1.85071607e-05, 1.56883728e-05, 1.73195467e-05, 2.34708959e-05, 3.60827406e-05, 4.27923302e-05, + 3.61633128e-05, 2.46212350e-05, 1.62108977e-05, 1.39004861e-05, 1.46465788e-05, 3.10455225e-05, + 3.97418823e-05, 3.74937352e-05, 2.82154118e-05, 1.93370442e-05, 1.45162079e-05, 1.34798994e-05, + 1.48382684e-05, 3.41246825e-05, 4.18838020e-05, 3.77724661e-05, 2.71159814e-05, 1.68061805e-05, + 1.33899501e-05, 1.43643612e-05, 1.56208647e-05, 3.60543432e-05, 4.54748596e-05, 3.51870797e-05, + 2.41679786e-05, 1.99994833e-05, 1.80726684e-05, 1.64897138e-05, 2.83132924e-05, 3.36700862e-05, + 3.46340973e-05, 3.16794472e-05, 2.30670376e-05, 1.65252270e-05, 1.53367413e-05, 1.58888813e-05, + 2.69171625e-05, 3.19889399e-05, 3.16523208e-05, 2.78385242e-05, 2.46591234e-05, 2.19983874e-05, + 1.77542487e-05, 1.60588467e-05, 2.56354032e-05, 3.20849441e-05, 3.18435344e-05, 2.94625844e-05, + 2.73582077e-05, 2.25237323e-05, 1.78710979e-05, 1.57176519e-05, 1.58256707e-05, 2.27602057e-05, + 3.32867675e-05, 4.40930174e-05, 4.11756057e-05, 2.89225236e-05, 1.75914287e-05, 1.50659788e-05, + 1.77885523e-05, 3.03003054e-05, 3.60155891e-05, 3.12905505e-05, 2.39219189e-05, 2.20697547e-05, + 2.02731358e-05, 1.69753841e-05, 1.61050734e-05, 2.25105770e-05, 3.08600153e-05, 3.67822137e-05, + 3.08699225e-05, 2.42152512e-05, 1.88927287e-05, 1.61844784e-05, 1.61737668e-05, 2.51616905e-05, + 3.20688157e-05, 3.31841531e-05, 2.82787132e-05, 2.31305544e-05, 1.94747453e-05, 1.60976645e-05, + 1.68367058e-05, 1.82443371e-05, 2.50259631e-05, 3.58331694e-05, 4.10312196e-05, 3.20561122e-05, + 2.14825734e-05, 1.67551262e-05, 1.43136846e-05, 1.40626959e-05, 1.53637317e-05, 2.81175672e-05, + 3.34448885e-05, 3.37728694e-05, 2.65969938e-05, 1.91932369e-05, 1.94276547e-05, 1.75842234e-05, + 1.49042668e-05, 2.72896935e-05, 3.22760405e-05, 3.25618384e-05, 3.05967641e-05, 2.65560810e-05, + 1.96145661e-05, 1.67360516e-05, 1.75085077e-05, 3.11366811e-05, 3.97717639e-05, 3.54828057e-05, + 2.38999560e-05, 1.62181388e-05, 1.60339387e-05, 1.68852670e-05, 2.46664931e-05, 3.13031555e-05, + 3.55564105e-05, 3.31265558e-05, 2.56748892e-05, 2.07352650e-05, 1.78960467e-05, 1.53724404e-05, + 2.54147976e-05, 3.27620580e-05, 3.45122319e-05, 3.06552624e-05, 2.49298562e-05, 1.99486707e-05, + 1.75209852e-05, 1.73945499e-05, 1.76193490e-05, 2.45401802e-05, 2.90142366e-05, 2.76717616e-05, + 2.49511963e-05, 2.45136046e-05, 2.37173624e-05, 2.02224337e-05, 1.76117087e-05, 1.79924358e-05, + 1.84684327e-05, 1.73783339e-05, 2.70982167e-05, 3.18080398e-05, 3.13157455e-05, 2.61790983e-05, + 2.34702590e-05, 2.28931605e-05, 1.93447069e-05, 1.63186732e-05, 1.54537765e-05, 3.13222925e-05, + 4.00863762e-05, 3.65676894e-05, 2.43454490e-05, 1.77101463e-05, 1.70983513e-05, 1.71056109e-05, + 1.65402262e-05, 1.64259391e-05, 2.35475161e-05, 3.18611146e-05, 3.47493389e-05, 2.73121429e-05, + 2.15540220e-05, 2.16717641e-05, 2.21628029e-05, 1.95552683e-05, 1.68456860e-05, 1.80844164e-05, + 2.35859508e-05, 3.45709785e-05, 4.02082272e-05, 3.47514808e-05, 2.48520000e-05, 1.72111245e-05, + 1.50790745e-05, 1.58239288e-05, 3.05679432e-05, 3.74746514e-05, 3.55661056e-05, 2.77684849e-05, + 1.99536385e-05, 1.55266541e-05, 1.45960718e-05, 1.59710887e-05, 3.32926198e-05, 3.91531202e-05, + 3.56922038e-05, 2.68505517e-05, 1.76386820e-05, 1.44924686e-05, 1.55329158e-05, 1.67425977e-05, + 3.45163331e-05, 4.18278541e-05, 3.34949503e-05, 2.40979526e-05, 2.06558392e-05, 1.91648456e-05, + 1.76733953e-05, 2.79724884e-05, 3.22452080e-05, 3.31507807e-05, 3.10193579e-05, 2.36572953e-05, + 1.75813000e-05, 1.64613535e-05, 1.69972585e-05, 2.67721497e-05, 3.09378749e-05, 3.06949079e-05, + 2.75316636e-05, 2.49718881e-05, 2.27762728e-05, 1.88079833e-05, 1.71589128e-05, 2.56675217e-05, + 3.11698404e-05, 3.09929019e-05, 2.88683350e-05, 2.71916519e-05, 2.31251836e-05, 1.89030365e-05, + 1.68410800e-05, 1.69371881e-05, 2.26896946e-05, 3.14983649e-05, 4.07536152e-05, 3.89953333e-05, + 2.90432780e-05, 1.87232697e-05, 1.62425340e-05, 1.89466390e-05, 2.96664001e-05, 3.41159876e-05, + 3.02928498e-05, 2.40447683e-05, 2.25480486e-05, 2.10887796e-05, 1.80221089e-05, 1.71869866e-05, + 2.25050711e-05, 2.98441357e-05, 3.51449560e-05, 3.02828381e-05, 2.45386401e-05, 1.98241028e-05, + 1.73094611e-05, 1.72576300e-05, 2.52981626e-05, 3.11176105e-05, 3.20419968e-05, 2.78147672e-05, + 2.33787898e-05, 2.02420362e-05, 1.71593853e-05, 1.79314861e-05, 1.93385351e-05, 2.49891271e-05, + 3.41662960e-05, 3.87228587e-05, 3.13614776e-05, 2.19805468e-05, 1.76662986e-05, 1.54452495e-05, + 1.52321489e-05, 1.64971573e-05, 2.74899208e-05, 3.16728050e-05, 3.22792875e-05, 2.64856226e-05, + 2.00601766e-05, 2.06005344e-05, 1.88445592e-05, 1.61208643e-05, 2.72539555e-05, 3.11026588e-05, + 3.12484070e-05, 2.98546985e-05, 2.66009858e-05, 2.03571393e-05, 1.77276616e-05, 1.85775209e-05, + 2.99793240e-05, 3.68439494e-05, 3.39971132e-05, 2.43773392e-05, 1.72935784e-05, 1.71285137e-05, + 1.79810464e-05, 2.46497593e-05, 3.02074975e-05, 3.38972246e-05, 3.21435017e-05, 2.59940223e-05, + 2.16321477e-05, 1.89436163e-05, 1.64829272e-05, 2.47351001e-05, 3.67504912e-05, 3.99897313e-05, + 3.30521101e-05, 2.40042980e-05, 1.72401871e-05, 1.42903466e-05, 1.41489490e-05, 1.44225202e-05, + 2.34638912e-05, 3.03236017e-05, 2.81783195e-05, 2.40533090e-05, 2.34178345e-05, 2.22850397e-05, + 1.75893208e-05, 1.43903309e-05, 1.48523965e-05, 1.54319035e-05, 1.41381598e-05, 2.72735011e-05, + 3.50498015e-05, 3.41915553e-05, 2.58689017e-05, 2.19274227e-05, 2.11407511e-05, 1.65060765e-05, + 1.29162800e-05, 1.19529836e-05, 3.42008204e-05, 5.14936896e-05, 4.40082627e-05, 2.31586016e-05, + 1.44853414e-05, 1.37935117e-05, 1.38221380e-05, 1.31726866e-05, 1.30416223e-05, 2.20219974e-05, + 3.51541236e-05, 4.04499402e-05, 2.76000682e-05, 1.93160439e-05, 1.94961235e-05, 2.01734443e-05, + 1.67838224e-05, 1.35282195e-05, 1.49399256e-05, 2.20785748e-05, 4.01055138e-05, 5.17297931e-05, + 4.04448459e-05, 2.39050830e-05, 1.39311797e-05, 1.15489447e-05, 1.23701312e-05, 3.29090499e-05, + 4.58734276e-05, 4.20374947e-05, 2.83131198e-05, 1.72388936e-05, 1.20162757e-05, 1.10183272e-05, + 1.25282399e-05, 3.77172056e-05, 4.94449731e-05, 4.22950240e-05, 2.68839605e-05, 1.44148355e-05, + 1.09057057e-05, 1.20453577e-05, 1.34040022e-05, 4.00031979e-05, 5.55735880e-05, 3.81080853e-05, + 2.27987041e-05, 1.81457196e-05, 1.63015047e-05, 1.45020146e-05, 2.86390102e-05, 3.58351528e-05, + 3.74670689e-05, 3.36781954e-05, 2.22154848e-05, 1.43741593e-05, 1.30819612e-05, 1.36966448e-05, + 2.67673919e-05, 3.35382159e-05, 3.31205705e-05, 2.79432100e-05, 2.40869233e-05, 2.10029252e-05, + 1.58544732e-05, 1.38837215e-05, 2.50992767e-05, 3.39363244e-05, 3.36307960e-05, 3.00751247e-05, + 2.74162967e-05, 2.14681754e-05, 1.59685800e-05, 1.35178747e-05, 1.36273898e-05, 2.08230396e-05, + 3.45463486e-05, 5.30569299e-05, 4.90507824e-05, 3.03951359e-05, 1.57616940e-05, 1.28409085e-05, + 1.60408111e-05, 3.13874906e-05, 3.92730838e-05, 3.24385909e-05, 2.27308258e-05, 2.06578647e-05, + 1.87291660e-05, 1.48983460e-05, 1.39139490e-05, 2.05715682e-05, 3.16859519e-05, 4.12060496e-05, + 3.24219049e-05, 2.34552982e-05, 1.71079830e-05, 1.40635541e-05, 1.39968814e-05, 2.45556410e-05, + 3.38463167e-05, 3.54651256e-05, 2.83860318e-05, 2.17943604e-05, 1.76223242e-05, 1.38789024e-05, + 1.47964440e-05, 1.65184772e-05, 2.40911975e-05, 3.93512453e-05, 4.84802933e-05, 3.42702406e-05, + 1.98868805e-05, 1.44564330e-05, 1.19430400e-05, 1.17146178e-05, 1.31241339e-05, 2.78733573e-05, + 3.48490804e-05, 3.58991904e-05, 2.63292013e-05, 1.74006552e-05, 1.81399533e-05, 1.59313402e-05, + 1.27096016e-05, 2.75199180e-05, 3.38249871e-05, 3.40819855e-05, 3.17005291e-05, 2.65139695e-05, + 1.77677789e-05, 1.45392314e-05, 1.55740670e-05, 3.19161548e-05, 4.46776248e-05, 3.90264516e-05, + 2.32349375e-05, 1.40378368e-05, 1.38474606e-05, 1.48559618e-05, 2.35964624e-05, 3.22970875e-05, + 3.88491554e-05, 3.56429597e-05, 2.56100334e-05, 1.94607781e-05, 1.60208470e-05, 1.31045479e-05, + 2.07418151e-05, 4.36473537e-05, 5.13924472e-05, 3.69671880e-05, 2.07930657e-05, 1.11031523e-05, + 7.82417204e-06, 7.58611597e-06, 7.70085468e-06, 1.86437692e-05, 2.99635370e-05, 2.60152848e-05, + 1.97794491e-05, 1.88942512e-05, 1.72069435e-05, 1.14634448e-05, 8.03300651e-06, 8.29428922e-06, + 8.73254796e-06, 7.45912537e-06, 2.52525539e-05, 4.04158785e-05, 3.76815217e-05, 2.29336746e-05, + 1.71391579e-05, 1.55291044e-05, 9.82380438e-06, 6.42286483e-06, 5.61708204e-06, 3.84016739e-05, + 8.57660380e-05, 6.22595513e-05, 1.94788559e-05, 8.55926146e-06, 7.41883021e-06, 7.15247383e-06, + 6.57994964e-06, 6.48194700e-06, 1.80570473e-05, 4.31486314e-05, 5.39779719e-05, 2.63846642e-05, + 1.36756237e-05, 1.32306183e-05, 1.36031494e-05, 9.85335117e-06, 6.81426405e-06, 8.79856729e-06, + 1.79561086e-05, 5.25003868e-05, 8.39086572e-05, 5.24808843e-05, 1.97371556e-05, 7.44159692e-06, + 5.24401616e-06, 5.86567363e-06, 3.48542011e-05, 6.88299887e-05, 5.88183105e-05, 2.80583318e-05, + 1.13037564e-05, 5.87491922e-06, 4.95167365e-06, 6.06370489e-06, 4.43172707e-05, 8.01022750e-05, + 6.03696113e-05, 2.53592175e-05, 8.19093951e-06, 4.89068415e-06, 5.63232269e-06, 6.77871965e-06, + 5.24820339e-05, 1.02914629e-04, 5.00590727e-05, 1.94340733e-05, 1.21036823e-05, 9.31697898e-06, + 7.56585885e-06, 2.80581535e-05, 4.45256426e-05, 4.76601383e-05, 3.69246227e-05, 1.66124095e-05, + 7.70640390e-06, 6.51475593e-06, 7.04165506e-06, 2.47262768e-05, 3.87097732e-05, 3.75653255e-05, + 2.69581954e-05, 1.96765913e-05, 1.47347140e-05, 8.99879859e-06, 7.21125106e-06, 2.19076515e-05, + 3.86304301e-05, 3.78166835e-05, 3.12118875e-05, 2.56731349e-05, 1.57494289e-05, 9.14767404e-06, + 6.86792149e-06, 6.97913331e-06, 1.70975769e-05, 4.44579971e-05, 9.37914592e-05, 7.47489148e-05, + 2.85364604e-05, 8.75160163e-06, 6.23253627e-06, 8.94299101e-06, 3.33235379e-05, 5.34772379e-05, + 3.67071709e-05, 1.86985015e-05, 1.52244858e-05, 1.22805572e-05, 8.17359187e-06, 7.27066385e-06, + 1.66006099e-05, 3.56353939e-05, 5.53148680e-05, 3.46480884e-05, 1.88889056e-05, 1.04217966e-05, + 7.31296756e-06, 7.33586008e-06, 2.08567065e-05, 3.86760290e-05, 4.23140917e-05, 2.82327759e-05, + 1.71981501e-05, 1.13073991e-05, 7.27995296e-06, 7.98931157e-06, 9.50875917e-06, 2.08992821e-05, + 5.21235790e-05, 7.45623602e-05, 3.80199021e-05, 1.43350058e-05, 8.06622844e-06, 5.61561189e-06, + 5.38183084e-06, 6.53267839e-06, 2.82229925e-05, 4.48767259e-05, 4.50316036e-05, 2.40208348e-05, + 1.08518072e-05, 1.08323883e-05, 8.63355461e-06, 6.06119095e-06, 2.52894303e-05, 3.98162072e-05, + 4.09912384e-05, 3.43098102e-05, 2.36614241e-05, 1.15108702e-05, 7.97523731e-06, 8.71772215e-06, + 3.67088049e-05, 7.15100156e-05, 5.04085823e-05, 1.81279201e-05, 7.38609136e-06, 7.19164953e-06, + 8.03829086e-06, 2.02190717e-05, 3.69869066e-05, 5.11735308e-05, 4.17328974e-05, 2.15100706e-05, + 1.28075931e-05, 9.16093109e-06, 6.55809142e-06, 2.33396405e-05, 3.87179790e-05, 4.31752335e-05, + 3.51806770e-05, 2.39720951e-05, 1.52896567e-05, 1.18455451e-05, 1.15194958e-05, 1.15464631e-05, + 2.15875209e-05, 2.98895296e-05, 2.70939928e-05, 2.26245962e-05, 2.19509878e-05, 2.05456197e-05, + 1.56105327e-05, 1.21443968e-05, 1.22940738e-05, 1.26600262e-05, 1.13033643e-05, 2.69107588e-05, + 3.69945405e-05, 3.49415910e-05, 2.52074886e-05, 2.07193594e-05, 1.90737332e-05, 1.37500141e-05, + 1.02003769e-05, 9.27182656e-06, 3.56764772e-05, 6.06656347e-05, 4.91037465e-05, 2.29193670e-05, + 1.29938309e-05, 1.14512927e-05, 1.09594050e-05, 1.03305926e-05, 1.02318797e-05, 2.18981763e-05, + 3.96611370e-05, 4.51271593e-05, 2.79937793e-05, 1.77322315e-05, 1.69510596e-05, 1.70243914e-05, + 1.36155874e-05, 1.05365171e-05, 1.30963903e-05, 2.17172905e-05, 4.40915389e-05, 5.90071647e-05, + 4.37598149e-05, 2.26824289e-05, 1.14035307e-05, 8.79026397e-06, 9.49382279e-06, 3.30713691e-05, + 5.28580249e-05, 4.79837301e-05, 2.93715744e-05, 1.56057619e-05, 9.72784884e-06, 8.52698239e-06, + 9.77053339e-06, 3.85207279e-05, 5.83882219e-05, 4.91096312e-05, 2.73529271e-05, 1.24026844e-05, + 8.47161189e-06, 9.24547304e-06, 1.05489590e-05, 4.41697294e-05, 6.89701123e-05, 4.36740412e-05, + 2.31424023e-05, 1.62082886e-05, 1.30630820e-05, 1.12626136e-05, 2.91017382e-05, 4.04123635e-05, + 4.19742676e-05, 3.45954416e-05, 1.97902751e-05, 1.15866905e-05, 1.02672178e-05, 1.08400448e-05, + 2.66837879e-05, 3.65771410e-05, 3.57497310e-05, 2.83899833e-05, 2.24662559e-05, 1.80586575e-05, + 1.28296554e-05, 1.10253511e-05, 2.45322278e-05, 3.61433144e-05, 3.55657295e-05, 3.14930010e-05, + 2.72978082e-05, 1.91445809e-05, 1.30010555e-05, 1.06394297e-05, 1.07712283e-05, 2.15102419e-05, + 4.15523340e-05, 6.50561412e-05, 5.45472703e-05, 2.82358471e-05, 1.24805506e-05, 9.89493072e-06, + 1.26190387e-05, 3.27121015e-05, 4.57827119e-05, 3.54440737e-05, 2.22147883e-05, 1.89954307e-05, + 1.60716577e-05, 1.20583930e-05, 1.11117472e-05, 2.10075922e-05, 3.49611479e-05, 4.56331671e-05, + 3.32629170e-05, 2.19157934e-05, 1.43056721e-05, 1.10929927e-05, 1.11750368e-05, 2.36236667e-05, + 3.62696079e-05, 3.85401828e-05, 2.95137834e-05, 2.09001289e-05, 1.53453511e-05, 1.11502310e-05, + 1.18080102e-05, 1.32340410e-05, 2.40405858e-05, 4.44473632e-05, 5.49618746e-05, 3.52231539e-05, + 1.82823007e-05, 1.21589061e-05, 9.27500492e-06, 8.96036667e-06, 1.02740957e-05, 2.99337043e-05, + 4.16871027e-05, 4.08555615e-05, 2.61778118e-05, 1.47859112e-05, 1.42691401e-05, 1.21794564e-05, + 9.65624498e-06, 2.67584769e-05, 3.74688523e-05, 3.84475145e-05, 3.35154463e-05, 2.55935012e-05, + 1.55605186e-05, 1.19476965e-05, 1.25437849e-05, 3.59113091e-05, 5.63192692e-05, 4.31460546e-05, + 2.10773455e-05, 1.12379391e-05, 1.10132138e-05, 1.18542221e-05, 2.35480989e-05, 3.58676650e-05, + 4.40303350e-05, 3.77991243e-05, 2.36414158e-05, 1.63546642e-05, 1.29890449e-05, 1.03326346e-05, + 2.53445709e-05, 2.74058533e-05, 2.77246684e-05, 2.74855485e-05, 2.60201887e-05, 2.33936720e-05, + 2.18266316e-05, 2.15710662e-05, 2.14474221e-05, 2.48732032e-05, 2.63388411e-05, 2.58819939e-05, + 2.52309125e-05, 2.51134462e-05, 2.47551030e-05, 2.34773124e-05, 2.20711305e-05, 2.19652947e-05, + 2.20076457e-05, 2.13514435e-05, 2.61648672e-05, 2.74142447e-05, 2.69598668e-05, 2.58810960e-05, + 2.50288788e-05, 2.43146521e-05, 2.24515443e-05, 2.08363941e-05, 2.03027180e-05, 2.72392075e-05, + 2.84459203e-05, 2.80781416e-05, 2.58000536e-05, 2.28399035e-05, 2.16993131e-05, 2.11618713e-05, + 2.08365205e-05, 2.07998925e-05, 2.57131324e-05, 2.83235476e-05, 2.81622457e-05, 2.65599646e-05, + 2.42421286e-05, 2.35786975e-05, 2.33096990e-05, 2.21870541e-05, 2.08646648e-05, 2.26865636e-05, + 2.55777530e-05, 2.79686040e-05, 2.80084837e-05, 2.77471876e-05, 2.53300292e-05, 2.15720639e-05, + 1.99409551e-05, 2.03255676e-05, 2.67002864e-05, 2.84415976e-05, 2.84400579e-05, 2.69143491e-05, + 2.36517691e-05, 2.08163767e-05, 1.99250058e-05, 2.05632457e-05, 2.69861639e-05, 2.85961157e-05, + 2.86642883e-05, 2.65470179e-05, 2.23120595e-05, 1.99221561e-05, 2.02149517e-05, 2.09490625e-05, + 2.80286496e-05, 2.88362690e-05, 2.85513147e-05, 2.60907437e-05, 2.36722774e-05, 2.19297726e-05, + 2.11075184e-05, 2.66561400e-05, 2.83257897e-05, 2.82433625e-05, 2.70186566e-05, 2.42983507e-05, + 2.15156348e-05, 2.08168532e-05, 2.11032656e-05, 2.62629874e-05, 2.78299325e-05, 2.76778215e-05, + 2.66074585e-05, 2.51233386e-05, 2.36736772e-05, 2.19447130e-05, 2.11982331e-05, 2.58492770e-05, + 2.75160597e-05, 2.74127491e-05, 2.71453720e-05, 2.62973425e-05, 2.42106969e-05, 2.20461562e-05, + 2.09845636e-05, 2.10673353e-05, 2.60351031e-05, 2.91878216e-05, 2.88643914e-05, 2.78229042e-05, + 2.55443430e-05, 2.16591443e-05, 2.05270624e-05, 2.16457289e-05, 2.71414872e-05, 2.87741125e-05, + 2.78235513e-05, 2.55795759e-05, 2.44876655e-05, 2.32762225e-05, 2.17068578e-05, 2.12737022e-05, + 2.58427054e-05, 2.79295455e-05, 2.80491446e-05, 2.69658781e-05, 2.50756199e-05, 2.26310704e-05, + 2.11701039e-05, 2.12946295e-05, 2.55832738e-05, 2.75976836e-05, 2.78167686e-05, 2.69497644e-05, + 2.52039871e-05, 2.32451365e-05, 2.13343397e-05, 2.15103582e-05, 2.19757742e-05, 2.60198249e-05, + 2.83444223e-05, 2.81071282e-05, 2.70392551e-05, 2.43596494e-05, 2.20489974e-05, 2.03125966e-05, + 2.00573405e-05, 2.08004039e-05, 2.73524397e-05, 2.91178851e-05, 2.84507504e-05, 2.61910269e-05, + 2.28926410e-05, 2.20801690e-05, 2.12753346e-05, 2.03215883e-05, 2.59862473e-05, 2.80491510e-05, + 2.83033320e-05, 2.73487498e-05, 2.58106417e-05, 2.33467863e-05, 2.17923018e-05, 2.18198752e-05, + 2.82053098e-05, 2.96899222e-05, 2.80565802e-05, 2.46613349e-05, 2.13383749e-05, 2.12055489e-05, + 2.15247808e-05, 2.59636170e-05, 2.80404056e-05, 2.83954526e-05, 2.74864681e-05, 2.51378450e-05, + 2.31410291e-05, 2.20073831e-05, 2.08779860e-05, 2.44602374e-05, 2.12228338e-05, 2.04198793e-05, + 2.24322496e-05, 2.51760101e-05, 2.69672636e-05, 2.76592955e-05, 2.75447333e-05, 2.72480835e-05, + 2.47364174e-05, 2.28186848e-05, 2.33687947e-05, 2.46907584e-05, 2.49048789e-05, 2.52084399e-05, + 2.68204167e-05, 2.77910690e-05, 2.73845151e-05, 2.70321321e-05, 2.73654595e-05, 2.38750519e-05, + 2.17503661e-05, 2.18155793e-05, 2.42891729e-05, 2.55524476e-05, 2.54798269e-05, 2.67020423e-05, + 2.78130670e-05, 2.80871138e-05, 2.19418503e-05, 1.78274569e-05, 1.94850917e-05, 2.54354515e-05, + 2.83418306e-05, 2.79087817e-05, 2.74274634e-05, 2.76186467e-05, 2.76848039e-05, 2.59258636e-05, + 2.21097997e-05, 2.04649617e-05, 2.39571727e-05, 2.63798749e-05, 2.58246275e-05, 2.52817057e-05, + 2.63253369e-05, 2.73800723e-05, 2.79045098e-05, 2.58167338e-05, 2.04851352e-05, 1.76389818e-05, + 2.03029280e-05, 2.48161723e-05, 2.77012177e-05, 2.80795613e-05, 2.77723686e-05, 2.21098560e-05, + 1.91447593e-05, 2.01352520e-05, 2.38619503e-05, 2.71558855e-05, 2.85095958e-05, 2.85213904e-05, + 2.78667393e-05, 2.07530295e-05, 1.83395300e-05, 2.01473582e-05, 2.42369867e-05, 2.79703199e-05, + 2.86184620e-05, 2.79294708e-05, 2.75461861e-05, 2.05374714e-05, 1.70555282e-05, 2.12896999e-05, + 2.57744158e-05, 2.66370325e-05, 2.64156034e-05, 2.69027219e-05, 2.36041519e-05, 2.18944438e-05, + 2.13590906e-05, 2.20089423e-05, 2.49484111e-05, 2.73394826e-05, 2.76694485e-05, 2.74671839e-05, + 2.41313675e-05, 2.24251599e-05, 2.24967007e-05, 2.38473289e-05, 2.46110629e-05, 2.51176103e-05, + 2.67082482e-05, 2.74147291e-05, 2.45966441e-05, 2.21535285e-05, 2.22067972e-05, 2.33137020e-05, + 2.38900293e-05, 2.52499265e-05, 2.67174803e-05, 2.74935986e-05, 2.74861664e-05, 2.67227853e-05, + 2.26574059e-05, 1.76046441e-05, 1.81766836e-05, 2.23744410e-05, 2.65346818e-05, 2.75911064e-05, + 2.63475148e-05, 2.28414704e-05, 2.10325951e-05, 2.27942236e-05, 2.55051705e-05, 2.58369621e-05, + 2.60247447e-05, 2.71401279e-05, 2.74582778e-05, 2.67381568e-05, 2.31042710e-05, 2.02131759e-05, + 2.24008951e-05, 2.48647650e-05, 2.64752224e-05, 2.72621960e-05, 2.74169991e-05, 2.46784857e-05, + 2.22197278e-05, 2.17962286e-05, 2.38517515e-05, 2.57264647e-05, 2.66314085e-05, 2.75356891e-05, + 2.70448879e-05, 2.63190219e-05, 2.51367193e-05, 2.08459679e-05, 1.84047137e-05, 2.18273437e-05, + 2.61528017e-05, 2.77264969e-05, 2.81045152e-05, 2.80522120e-05, 2.76228916e-05, 2.42552729e-05, + 2.25300542e-05, 2.19255023e-05, 2.42710205e-05, 2.64998233e-05, 2.54559915e-05, 2.61098108e-05, + 2.75034418e-05, 2.36804715e-05, 2.24261841e-05, 2.24502789e-05, 2.28307085e-05, 2.39843234e-05, + 2.66208270e-05, 2.74567174e-05, 2.67867632e-05, 2.31464631e-05, 1.98572147e-05, 2.08257649e-05, + 2.47080981e-05, 2.74254075e-05, 2.74471254e-05, 2.70167714e-05, 2.53286903e-05, 2.29402372e-05, + 2.10108955e-05, 2.15966926e-05, 2.39676792e-05, 2.55321558e-05, 2.66533062e-05, 2.77069901e-05, + 2.38383199e-05, 1.90447624e-05, 1.79840504e-05, 2.04617580e-05, 2.44292699e-05, 2.80224771e-05, + 2.98349171e-05, 2.98350057e-05, 2.95097450e-05, 2.44030154e-05, 2.13768725e-05, 2.22423665e-05, + 2.41800954e-05, 2.45045093e-05, 2.50582995e-05, 2.77853681e-05, 2.98650595e-05, 2.93841381e-05, + 2.88879883e-05, 2.97263615e-05, 2.27494819e-05, 1.96711841e-05, 1.99172925e-05, 2.33858394e-05, + 2.53644908e-05, 2.56186981e-05, 2.81944729e-05, 3.06537996e-05, 3.13736042e-05, 1.99651402e-05, + 1.47700946e-05, 1.67772957e-05, 2.48543048e-05, 3.01420685e-05, 3.02470419e-05, 2.99262445e-05, + 3.03886519e-05, 3.05019802e-05, 2.55104651e-05, 1.97688229e-05, 1.78904163e-05, 2.26838606e-05, + 2.68122048e-05, 2.64349062e-05, 2.58665540e-05, 2.78425945e-05, 3.00458697e-05, 2.96534430e-05, + 2.54372104e-05, 1.79786797e-05, 1.46806780e-05, 1.78390372e-05, 2.42926639e-05, 3.00452040e-05, + 3.16032243e-05, 3.09258582e-05, 2.03710596e-05, 1.62717899e-05, 1.74154026e-05, 2.24196370e-05, + 2.81284440e-05, 3.16164964e-05, 3.22252923e-05, 3.09016410e-05, 1.86334989e-05, 1.53067798e-05, + 1.73571873e-05, 2.30337627e-05, 2.99608645e-05, 3.23615366e-05, 3.12143054e-05, 3.02193995e-05, + 1.80198939e-05, 1.37980449e-05, 1.87238671e-05, 2.51440244e-05, 2.74421702e-05, 2.81086326e-05, + 2.92477861e-05, 2.22104646e-05, 1.95135641e-05, 1.89115330e-05, 2.01282990e-05, 2.49454904e-05, + 2.95919070e-05, 3.04703213e-05, 3.00162592e-05, 2.30246285e-05, 2.03242519e-05, 2.04666833e-05, + 2.25289839e-05, 2.41288725e-05, 2.54696721e-05, 2.84913791e-05, 2.98866399e-05, 2.37831026e-05, + 2.01161119e-05, 2.02184828e-05, 2.16580096e-05, 2.27118172e-05, 2.53747032e-05, 2.84453654e-05, + 3.01257376e-05, 3.00642578e-05, 2.63573248e-05, 2.01031266e-05, 1.44028645e-05, 1.53475239e-05, + 2.11508566e-05, 2.84239836e-05, 3.05472622e-05, 2.81803634e-05, 2.10870238e-05, 1.83482514e-05, + 2.07680240e-05, 2.50442403e-05, 2.59910252e-05, 2.68534769e-05, 2.92093432e-05, 2.98993458e-05, + 2.64697569e-05, 2.10990276e-05, 1.76336711e-05, 2.06217521e-05, 2.44713671e-05, 2.77939849e-05, + 2.96971414e-05, 2.98306859e-05, 2.40045447e-05, 2.01650310e-05, 1.95796581e-05, 2.23925826e-05, + 2.55011893e-05, 2.76636541e-05, 2.99669378e-05, 2.91980073e-05, 2.79534050e-05, 2.43804201e-05, + 1.82749123e-05, 1.55244553e-05, 1.99018639e-05, 2.64603007e-05, 2.97919350e-05, 3.13910407e-05, + 3.14877526e-05, 3.04171999e-05, 2.27186627e-05, 1.99788704e-05, 1.95057819e-05, 2.32284557e-05, + 2.76825918e-05, 2.67449078e-05, 2.80749252e-05, 3.05587007e-05, 2.25844626e-05, 2.02442166e-05, + 2.01793857e-05, 2.09935800e-05, 2.30370569e-05, 2.75949725e-05, 2.95836367e-05, 2.86687939e-05, + 2.10442633e-05, 1.67038923e-05, 1.83487108e-05, 2.44661379e-05, 2.98153586e-05, 2.99260456e-05, + 2.91515290e-05, 2.46456127e-05, 2.08605451e-05, 1.84506352e-05, 1.94613876e-05, 2.33117450e-05, + 2.62803969e-05, 2.83819039e-05, 3.04829358e-05, 2.40463549e-05, 1.97437267e-05, 1.87591693e-05, + 2.11705545e-05, 2.48126109e-05, 2.77424818e-05, 2.91184531e-05, 2.90399341e-05, 2.86725354e-05, + 2.44931998e-05, 2.18264316e-05, 2.25822436e-05, 2.43605281e-05, 2.46564102e-05, 2.51204386e-05, + 2.75256382e-05, 2.92244319e-05, 2.87025605e-05, 2.82126903e-05, 2.88623585e-05, 2.31561098e-05, + 2.03671097e-05, 2.05143092e-05, 2.37254600e-05, 2.55010631e-05, 2.55678496e-05, 2.76430466e-05, + 2.96425564e-05, 3.02040072e-05, 2.06218828e-05, 1.57314416e-05, 1.76371266e-05, 2.51866557e-05, + 2.97466780e-05, 2.94991177e-05, 2.90063793e-05, 2.93735565e-05, 2.94769510e-05, 2.58307263e-05, + 2.06589498e-05, 1.87532110e-05, 2.31850228e-05, 2.67538723e-05, 2.61896341e-05, 2.55473765e-05, + 2.72123897e-05, 2.90354701e-05, 2.91969157e-05, 2.57201732e-05, 1.88022579e-05, 1.55689698e-05, + 1.86204125e-05, 2.44987295e-05, 2.92538916e-05, 3.03202390e-05, 2.97565686e-05, 2.09080475e-05, + 1.72066740e-05, 1.83368520e-05, 2.30037532e-05, 2.79253875e-05, 3.06187732e-05, 3.09493165e-05, + 2.98077041e-05, 1.92513536e-05, 1.62844429e-05, 1.83225941e-05, 2.35341004e-05, 2.93967171e-05, + 3.10878261e-05, 3.00137733e-05, 2.92372339e-05, 1.88550017e-05, 1.48446346e-05, 1.96609657e-05, + 2.55572777e-05, 2.72329494e-05, 2.74049239e-05, 2.83054043e-05, 2.27324760e-05, 2.04036308e-05, + 1.97847535e-05, 2.07363845e-05, 2.48882875e-05, 2.87764563e-05, 2.94501757e-05, 2.90793951e-05, + 2.34559218e-05, 2.11085885e-05, 2.12178107e-05, 2.30407107e-05, 2.42819727e-05, 2.52482703e-05, + 2.77939432e-05, 2.89775038e-05, 2.41169213e-05, 2.08320813e-05, 2.09117388e-05, 2.22921059e-05, + 2.31501295e-05, 2.52952335e-05, 2.77774275e-05, 2.91534334e-05, 2.91168672e-05, 2.67850119e-05, + 2.11832087e-05, 1.54426262e-05, 1.61879946e-05, 2.14228232e-05, 2.76422772e-05, 2.94369897e-05, + 2.73941926e-05, 2.17190689e-05, 1.93312414e-05, 2.15523130e-05, 2.53217347e-05, 2.59896074e-05, + 2.65269609e-05, 2.84473975e-05, 2.90136283e-05, 2.68475955e-05, 2.19091200e-05, 1.84767798e-05, + 2.12155568e-05, 2.46134387e-05, 2.72911962e-05, 2.87772540e-05, 2.89505316e-05, 2.42730578e-05, + 2.08986385e-05, 2.03615710e-05, 2.29849204e-05, 2.56858318e-05, 2.73356375e-05, 2.91008555e-05, + 2.83767476e-05, 2.72625910e-05, 2.47630391e-05, 1.91713503e-05, 1.64114651e-05, 2.05160498e-05, + 2.64295310e-05, 2.91430154e-05, 3.02249501e-05, 3.02406757e-05, 2.93911685e-05, 2.34105956e-05, + 2.10421821e-05, 2.04223762e-05, 2.36433118e-05, 2.72539025e-05, 2.60863484e-05, 2.71811485e-05, + 2.93838366e-05, 2.29482394e-05, 2.10763397e-05, 2.10667773e-05, 2.16721987e-05, 2.33586444e-05, + 2.72951481e-05, 2.88524832e-05, 2.79357467e-05, 2.19162856e-05, 1.78687206e-05, 1.91866489e-05, + 2.45023178e-05, 2.89484596e-05, 2.90196535e-05, 2.83342065e-05, 2.50173616e-05, 2.16938824e-05, + 1.93565791e-05, 2.01739109e-05, 2.34690478e-05, 2.59151138e-05, 2.77021539e-05, 2.94821714e-05, + 2.56112572e-05, 2.74870703e-05, 2.77745534e-05, 2.67202918e-05, 2.49552941e-05, 2.32119389e-05, + 2.21262047e-05, 2.21538982e-05, 2.24111728e-05, 2.53946554e-05, 2.67680511e-05, 2.64393735e-05, + 2.54215670e-05, 2.52415028e-05, 2.49785848e-05, 2.33677565e-05, 2.20734643e-05, 2.24476326e-05, + 2.28145262e-05, 2.22565811e-05, 2.59970207e-05, 2.71730575e-05, 2.72875832e-05, 2.57035676e-05, + 2.46740126e-05, 2.47198914e-05, 2.32669456e-05, 2.15921792e-05, 2.10655375e-05, 2.71152252e-05, + 2.81762686e-05, 2.79929007e-05, 2.47522928e-05, 2.17506762e-05, 2.18309994e-05, 2.21211928e-05, + 2.17924161e-05, 2.17086092e-05, 2.43339837e-05, 2.66159028e-05, 2.75450128e-05, 2.58659929e-05, + 2.38843925e-05, 2.43323462e-05, 2.48123158e-05, 2.35728160e-05, 2.20502109e-05, 2.21399060e-05, + 2.44334535e-05, 2.76289197e-05, 2.85053807e-05, 2.78197486e-05, 2.53089316e-05, 2.19956700e-05, + 2.08919186e-05, 2.14033065e-05, 2.71740081e-05, 2.78969208e-05, 2.75464392e-05, 2.58689607e-05, + 2.30755865e-05, 2.08688972e-05, 2.04238421e-05, 2.14161292e-05, 2.79168360e-05, 2.79945212e-05, + 2.74217533e-05, 2.56504960e-05, 2.19688451e-05, 2.03216813e-05, 2.11864968e-05, 2.19140657e-05, + 2.75756544e-05, 2.79193845e-05, 2.69635467e-05, 2.44443081e-05, 2.35739203e-05, 2.34108426e-05, + 2.26387587e-05, 2.61166279e-05, 2.67381623e-05, 2.70657277e-05, 2.71442720e-05, 2.52021862e-05, + 2.23425444e-05, 2.17316957e-05, 2.20574784e-05, 2.57791878e-05, 2.66091297e-05, 2.66155125e-05, + 2.59416320e-05, 2.54951827e-05, 2.50072340e-05, 2.31209913e-05, 2.21483229e-05, 2.54541672e-05, + 2.68880595e-05, 2.68891499e-05, 2.62172796e-05, 2.59638465e-05, 2.49243277e-05, 2.31415587e-05, + 2.19826833e-05, 2.20237181e-05, 2.36290752e-05, 2.59487746e-05, 2.78927986e-05, 2.85329609e-05, + 2.72619086e-05, 2.32079544e-05, 2.16851739e-05, 2.33934548e-05, 2.65501010e-05, 2.69828944e-05, + 2.63751854e-05, 2.47038817e-05, 2.44029913e-05, 2.40981630e-05, 2.26103296e-05, 2.21326841e-05, + 2.36200560e-05, 2.61373548e-05, 2.77140150e-05, 2.69009004e-05, 2.52775506e-05, 2.35343064e-05, + 2.22937096e-05, 2.21827570e-05, 2.54095129e-05, 2.68184607e-05, 2.69963792e-05, 2.58690878e-05, + 2.45194523e-05, 2.35088130e-05, 2.20766055e-05, 2.26401672e-05, 2.35211155e-05, 2.49882323e-05, + 2.72786398e-05, 2.83002280e-05, 2.72541699e-05, 2.41046871e-05, 2.21311016e-05, 2.10522816e-05, + 2.09801546e-05, 2.17726559e-05, 2.54793662e-05, 2.60503068e-05, 2.66691659e-05, 2.56783481e-05, + 2.35676036e-05, 2.44123015e-05, 2.35138774e-05, 2.16814255e-05, 2.61782122e-05, 2.65307740e-05, + 2.64222819e-05, 2.64981864e-05, 2.59599244e-05, 2.35371395e-05, 2.23189240e-05, 2.30037876e-05, + 2.60200061e-05, 2.69254628e-05, 2.74228177e-05, 2.54222400e-05, 2.21905778e-05, 2.21179955e-05, + 2.26737578e-05, 2.48315454e-05, 2.62088237e-05, 2.71745469e-05, 2.72388851e-05, 2.60415979e-05, + 2.45494148e-05, 2.31946642e-05, 2.17190066e-05, 2.56730808e-05, 2.76761932e-05, 2.79972008e-05, + 2.66903049e-05, 2.47411324e-05, 2.30666425e-05, 2.20296566e-05, 2.21129779e-05, 2.24541927e-05, + 2.54899852e-05, 2.69441738e-05, 2.66119687e-05, 2.54575644e-05, 2.52551138e-05, 2.49944016e-05, + 2.32424320e-05, 2.19187103e-05, 2.23976302e-05, 2.28413131e-05, 2.22825564e-05, 2.60073902e-05, + 2.72743172e-05, 2.74948934e-05, 2.56916559e-05, 2.45677192e-05, 2.47552955e-05, 2.33131908e-05, + 2.15667122e-05, 2.10256586e-05, 2.72293852e-05, 2.84601431e-05, 2.82346032e-05, 2.45289836e-05, + 2.13860162e-05, 2.16924029e-05, 2.21533237e-05, 2.18130586e-05, 2.17171659e-05, 2.40306332e-05, + 2.64295475e-05, 2.76368025e-05, 2.57759091e-05, 2.37371174e-05, 2.44141312e-05, 2.50648616e-05, + 2.37449401e-05, 2.21254102e-05, 2.18860291e-05, 2.41755716e-05, 2.77728643e-05, 2.89529101e-05, + 2.80525753e-05, 2.52995658e-05, 2.19184768e-05, 2.08847346e-05, 2.14363935e-05, 2.73947937e-05, + 2.80651642e-05, 2.76013461e-05, 2.57200353e-05, 2.28526740e-05, 2.06854803e-05, 2.03143006e-05, + 2.14045019e-05, 2.82973494e-05, 2.81892573e-05, 2.74105324e-05, 2.55105134e-05, 2.17461569e-05, + 2.01900893e-05, 2.11917994e-05, 2.19404595e-05, 2.76953342e-05, 2.81106668e-05, 2.68362659e-05, + 2.41021892e-05, 2.34597224e-05, 2.35956475e-05, 2.28046234e-05, 2.60717602e-05, 2.65832174e-05, + 2.70103231e-05, 2.73028586e-05, 2.53584913e-05, 2.23560352e-05, 2.17422061e-05, 2.20864525e-05, + 2.57189103e-05, 2.64960162e-05, 2.65279041e-05, 2.58619448e-05, 2.55689532e-05, 2.52363416e-05, + 2.32328027e-05, 2.21795313e-05, 2.53873534e-05, 2.68969210e-05, 2.69149353e-05, 2.61154533e-05, + 2.59428915e-05, 2.50289335e-05, 2.32380294e-05, 2.20179467e-05, 2.20520006e-05, 2.31193456e-05, + 2.54730673e-05, 2.80489782e-05, 2.89981517e-05, 2.77159389e-05, 2.33985574e-05, 2.17431222e-05, + 2.36322441e-05, 2.65325900e-05, 2.68304198e-05, 2.62038612e-05, 2.45074626e-05, 2.43311289e-05, + 2.41819536e-05, 2.26485465e-05, 2.21452648e-05, 2.31395934e-05, 2.58907471e-05, 2.78719455e-05, + 2.70035934e-05, 2.53068254e-05, 2.36088561e-05, 2.23646099e-05, 2.22028207e-05, 2.53790232e-05, + 2.67960492e-05, 2.69865232e-05, 2.57143202e-05, 2.43461608e-05, 2.34592865e-05, 2.20642448e-05, + 2.27245527e-05, 2.37234776e-05, 2.47817646e-05, 2.72679461e-05, 2.86493065e-05, 2.74390442e-05, + 2.39867382e-05, 2.19933907e-05, 2.10074337e-05, 2.09697765e-05, 2.17959379e-05, 2.51666607e-05, + 2.56088432e-05, 2.64779591e-05, 2.56060273e-05, 2.35991505e-05, 2.48163216e-05, 2.38603884e-05, + 2.17803996e-05, 2.62655034e-05, 2.63638650e-05, 2.61895962e-05, 2.64334759e-05, 2.60238837e-05, + 2.34750503e-05, 2.22728638e-05, 2.31125909e-05, 2.57027996e-05, 2.66507197e-05, 2.74942644e-05, + 2.55641435e-05, 2.22037914e-05, 2.21406875e-05, 2.27632112e-05, 2.45984869e-05, 2.59627104e-05, + 2.71273682e-05, 2.73464466e-05, 2.62496226e-05, 2.47700588e-05, 2.33115737e-05, 2.17144253e-05, + 2.54735215e-05, 2.63075937e-05, 2.63480846e-05, 2.59766419e-05, 2.50877946e-05, 2.39286839e-05, + 2.31073712e-05, 2.31093153e-05, 2.32772226e-05, 2.53448601e-05, 2.60787452e-05, 2.59262030e-05, + 2.53631561e-05, 2.52564079e-05, 2.50945336e-05, 2.40352020e-05, 2.30866445e-05, 2.33367877e-05, + 2.35882399e-05, 2.31645629e-05, 2.56803978e-05, 2.61820717e-05, 2.62787514e-05, 2.55225071e-05, + 2.49132443e-05, 2.49272588e-05, 2.39172253e-05, 2.26654513e-05, 2.22510359e-05, 2.61764294e-05, + 2.60153318e-05, 2.62949130e-05, 2.49668794e-05, 2.29073397e-05, 2.28944364e-05, 2.30576796e-05, + 2.28053118e-05, 2.27440441e-05, 2.47112275e-05, 2.58382055e-05, 2.61891694e-05, 2.55976885e-05, + 2.43995080e-05, 2.46616747e-05, 2.49516947e-05, 2.41034670e-05, 2.29862772e-05, 2.31687654e-05, + 2.47715962e-05, 2.62554044e-05, 2.62030415e-05, 2.63553953e-05, 2.52973966e-05, 2.30001148e-05, + 2.20966439e-05, 2.24918711e-05, 2.62508368e-05, 2.61435243e-05, 2.61168917e-05, 2.55864296e-05, + 2.38494536e-05, 2.21516596e-05, 2.17588822e-05, 2.25203149e-05, 2.65240850e-05, 2.60155337e-05, + 2.60275437e-05, 2.54794635e-05, 2.30290243e-05, 2.16846203e-05, 2.23295375e-05, 2.28984980e-05, + 2.62276300e-05, 2.56228935e-05, 2.59338724e-05, 2.47801336e-05, 2.41783645e-05, 2.39810495e-05, + 2.34075453e-05, 2.57289481e-05, 2.58876446e-05, 2.60241938e-05, 2.62104343e-05, 2.52208118e-05, + 2.32350446e-05, 2.27614708e-05, 2.30093759e-05, 2.55580218e-05, 2.58928328e-05, 2.59107569e-05, + 2.56371520e-05, 2.54057480e-05, 2.50851553e-05, 2.37896922e-05, 2.30790447e-05, 2.53805464e-05, + 2.60490077e-05, 2.60598012e-05, 2.57574903e-05, 2.56588165e-05, 2.50501635e-05, 2.38097789e-05, + 2.29487479e-05, 2.29833658e-05, 2.42710898e-05, 2.54396156e-05, 2.57512183e-05, 2.63641388e-05, + 2.63592150e-05, 2.38289478e-05, 2.27060227e-05, 2.39510251e-05, 2.59236886e-05, 2.58946006e-05, + 2.57857398e-05, 2.49369078e-05, 2.47348074e-05, 2.45003483e-05, 2.34306093e-05, 2.30737561e-05, + 2.42635871e-05, 2.56627808e-05, 2.62577750e-05, 2.61039861e-05, 2.52774737e-05, 2.41034478e-05, + 2.31768988e-05, 2.31097496e-05, 2.53562425e-05, 2.60099433e-05, 2.60604742e-05, 2.55850295e-05, + 2.48206732e-05, 2.41174178e-05, 2.30394276e-05, 2.34374638e-05, 2.40565909e-05, 2.51073036e-05, + 2.60747916e-05, 2.62541743e-05, 2.62565440e-05, 2.45435289e-05, 2.31250226e-05, 2.22424280e-05, + 2.21696023e-05, 2.27887473e-05, 2.53569985e-05, 2.54926850e-05, 2.58421808e-05, 2.55032628e-05, + 2.41389172e-05, 2.46392006e-05, 2.40046854e-05, 2.26864895e-05, 2.57834114e-05, 2.58346157e-05, + 2.57579653e-05, 2.58835259e-05, 2.56671564e-05, 2.41405580e-05, 2.32375724e-05, 2.37033335e-05, + 2.55821447e-05, 2.55935259e-05, 2.61771343e-05, 2.53586162e-05, 2.31182687e-05, 2.30586785e-05, + 2.34612254e-05, 2.50143295e-05, 2.56874436e-05, 2.60325952e-05, 2.62003432e-05, 2.57190931e-05, + 2.47805365e-05, 2.38427077e-05, 2.27573348e-05, 2.53214538e-05, 2.52924063e-05, 2.51369487e-05, + 2.53338853e-05, 2.51998144e-05, 2.45495063e-05, 2.39654997e-05, 2.39364293e-05, 2.40110545e-05, + 2.52633856e-05, 2.54564974e-05, 2.54483020e-05, 2.52813913e-05, 2.52398267e-05, 2.51644259e-05, + 2.46088447e-05, 2.39820952e-05, 2.41035752e-05, 2.42394097e-05, 2.39392571e-05, 2.53841311e-05, + 2.53257554e-05, 2.53962950e-05, 2.53425774e-05, 2.51047291e-05, 2.50738442e-05, 2.44540224e-05, + 2.36011440e-05, 2.32953435e-05, 2.53602597e-05, 2.42466626e-05, 2.48743425e-05, 2.51512206e-05, + 2.39653924e-05, 2.38350974e-05, 2.38580446e-05, 2.36784195e-05, 2.36398227e-05, 2.50479968e-05, + 2.51859345e-05, 2.50473045e-05, 2.53536540e-05, 2.48391385e-05, 2.49089801e-05, 2.50134976e-05, + 2.45176053e-05, 2.37808894e-05, 2.40915651e-05, 2.50682753e-05, 2.50939884e-05, 2.43134164e-05, + 2.51139467e-05, 2.52609698e-05, 2.38775737e-05, 2.31553538e-05, 2.34347167e-05, 2.54351186e-05, + 2.46894301e-05, 2.49222036e-05, 2.53374314e-05, 2.45321183e-05, 2.33078780e-05, 2.29568889e-05, + 2.34835389e-05, 2.53214857e-05, 2.43903401e-05, 2.48676214e-05, 2.53231923e-05, 2.39773100e-05, + 2.29127901e-05, 2.33276060e-05, 2.37442478e-05, 2.50886921e-05, 2.37671664e-05, 2.50728216e-05, + 2.50852380e-05, 2.46938344e-05, 2.44289401e-05, 2.40370095e-05, 2.53799742e-05, 2.51729925e-05, + 2.51455078e-05, 2.53932034e-05, 2.51904337e-05, 2.39969737e-05, 2.36516858e-05, 2.38244647e-05, + 2.53500419e-05, 2.52818494e-05, 2.53062014e-05, 2.53616070e-05, 2.52931614e-05, 2.50969084e-05, + 2.43350159e-05, 2.38741707e-05, 2.52980897e-05, 2.53247702e-05, 2.53414400e-05, 2.53554086e-05, + 2.53759049e-05, 2.51179285e-05, 2.43565592e-05, 2.37762487e-05, 2.38057575e-05, 2.48704894e-05, + 2.50408784e-05, 2.40113623e-05, 2.45691796e-05, 2.55338015e-05, 2.43216401e-05, 2.35819430e-05, + 2.43810516e-05, 2.53748685e-05, 2.49899819e-05, 2.52850223e-05, 2.51340085e-05, 2.50030185e-05, + 2.48114287e-05, 2.41229595e-05, 2.38808229e-05, 2.48606028e-05, 2.52654706e-05, 2.50309372e-05, + 2.54029939e-05, 2.52462198e-05, 2.45638928e-05, 2.39230733e-05, 2.39028050e-05, 2.52867628e-05, + 2.53138822e-05, 2.52607046e-05, 2.53354437e-05, 2.50745098e-05, 2.46285765e-05, 2.38698581e-05, + 2.41030287e-05, 2.44713435e-05, 2.52067813e-05, 2.50630059e-05, 2.45620955e-05, 2.53855153e-05, + 2.49117455e-05, 2.40002771e-05, 2.32918153e-05, 2.32140255e-05, 2.36645224e-05, 2.52626404e-05, + 2.50499082e-05, 2.51506714e-05, 2.53355263e-05, 2.46066007e-05, 2.47586731e-05, 2.43622917e-05, + 2.35425158e-05, 2.54131205e-05, 2.52462362e-05, 2.52031836e-05, 2.53497687e-05, 2.53845428e-05, + 2.46486184e-05, 2.40311674e-05, 2.42769168e-05, 2.52235869e-05, 2.45120536e-05, 2.51233090e-05, + 2.52598846e-05, 2.39128279e-05, 2.38641208e-05, 2.41171761e-05, 2.51722228e-05, 2.52514340e-05, + 2.50735942e-05, 2.53055345e-05, 2.53949045e-05, 2.49254792e-05, 2.43687734e-05, 2.36574764e-05, + 2.38988644e-05, 1.90908958e-05, 1.80320304e-05, 2.01794799e-05, 2.38645772e-05, 2.77598138e-05, + 2.98244287e-05, 3.00138596e-05, 2.99445295e-05, 2.45778186e-05, 2.15297118e-05, 2.24433491e-05, + 2.42007456e-05, 2.44904625e-05, 2.50815015e-05, 2.75715879e-05, 2.96583156e-05, 2.94996152e-05, + 2.92145676e-05, 3.01236237e-05, 2.26378659e-05, 1.95961868e-05, 2.00415484e-05, 2.32552513e-05, + 2.50960281e-05, 2.57263216e-05, 2.85235541e-05, 3.09524025e-05, 3.16803610e-05, 1.99262327e-05, + 1.47656290e-05, 1.67981436e-05, 2.42762883e-05, 2.92230859e-05, 3.01157723e-05, 3.03629613e-05, + 3.08287348e-05, 3.09095323e-05, 2.47399571e-05, 1.91849934e-05, 1.77304383e-05, 2.23538422e-05, + 2.64930378e-05, 2.67237218e-05, 2.65581131e-05, 2.85183686e-05, 3.06435896e-05, 2.91041671e-05, + 2.47830960e-05, 1.79035539e-05, 1.48734537e-05, 1.78957623e-05, 2.42124734e-05, 3.01147413e-05, + 3.20566770e-05, 3.14641001e-05, 2.05463489e-05, 1.61690987e-05, 1.71837219e-05, 2.19563303e-05, + 2.76348164e-05, 3.13919957e-05, 3.23269865e-05, 3.12724301e-05, 1.89693065e-05, 1.52077126e-05, + 1.70235205e-05, 2.26057734e-05, 2.95264700e-05, 3.23835472e-05, 3.16775902e-05, 3.06637849e-05, + 1.79083001e-05, 1.36519801e-05, 1.82293171e-05, 2.42715542e-05, 2.72447043e-05, 2.88518279e-05, + 3.00629771e-05, 2.19594174e-05, 1.89826288e-05, 1.85416256e-05, 2.01771375e-05, 2.53080325e-05, + 2.99351178e-05, 3.08819327e-05, 3.04505105e-05, 2.27715261e-05, 1.98836927e-05, 2.00770047e-05, + 2.22160053e-05, 2.42349141e-05, 2.60608531e-05, 2.90500736e-05, 3.03164854e-05, 2.35453802e-05, + 1.98936970e-05, 2.00306071e-05, 2.12722836e-05, 2.25312995e-05, 2.56418219e-05, 2.89517469e-05, + 3.05922558e-05, 3.05006115e-05, 2.50296668e-05, 1.89826999e-05, 1.42296474e-05, 1.55984519e-05, + 2.18205210e-05, 2.92211386e-05, 3.11368631e-05, 2.90971515e-05, 2.08496894e-05, 1.78071046e-05, + 2.02259904e-05, 2.45376587e-05, 2.58401403e-05, 2.71812947e-05, 2.96008485e-05, 3.02664172e-05, + 2.52208856e-05, 2.04146386e-05, 1.75663901e-05, 2.05931130e-05, 2.44929546e-05, 2.81742390e-05, + 3.02440297e-05, 3.02172440e-05, 2.38605769e-05, 1.98872858e-05, 1.93061679e-05, 2.19162343e-05, + 2.50662388e-05, 2.76673308e-05, 3.02540782e-05, 2.97396432e-05, 2.87322306e-05, 2.38331902e-05, + 1.79635318e-05, 1.56349007e-05, 1.99855325e-05, 2.62074304e-05, 2.96393027e-05, 3.16803838e-05, + 3.19177154e-05, 3.08693954e-05, 2.19066041e-05, 1.89253702e-05, 1.89104407e-05, 2.29565419e-05, + 2.79264238e-05, 2.79528733e-05, 2.93076817e-05, 3.12979195e-05, 2.26282400e-05, 1.97022903e-05, + 1.95145328e-05, 2.06619243e-05, 2.30561399e-05, 2.75576343e-05, 2.97265146e-05, 2.92358551e-05, + 2.02203374e-05, 1.59679605e-05, 1.81721338e-05, 2.47563314e-05, 3.01771647e-05, 3.03302633e-05, + 2.97050827e-05, 2.40393821e-05, 2.01752498e-05, 1.80840293e-05, 1.93882430e-05, 2.36651310e-05, + 2.69302109e-05, 2.89455017e-05, 3.08417496e-05, 2.26844913e-05, 1.60773669e-05, 1.47754644e-05, + 1.76302618e-05, 2.29805238e-05, 2.91965703e-05, 3.28749597e-05, 3.31158064e-05, 3.28053291e-05, + 2.36578713e-05, 1.92264109e-05, 2.04784174e-05, 2.31645602e-05, 2.36289576e-05, 2.45317553e-05, + 2.88320411e-05, 3.26866438e-05, 3.21605856e-05, 3.14772623e-05, 3.31820274e-05, 2.09205974e-05, + 1.67744011e-05, 1.72532146e-05, 2.18295139e-05, 2.47233331e-05, 2.55157256e-05, 3.01929291e-05, + 3.49195526e-05, 3.64417130e-05, 1.71820578e-05, 1.10986739e-05, 1.33355633e-05, 2.36182183e-05, + 3.23398991e-05, 3.35321334e-05, 3.36291375e-05, 3.45660843e-05, 3.47542897e-05, 2.44527459e-05, + 1.64933627e-05, 1.45070782e-05, 2.06294158e-05, 2.70390909e-05, 2.70584470e-05, 2.65405269e-05, + 2.99618839e-05, 3.40804994e-05, 3.18573942e-05, 2.44527220e-05, 1.46762636e-05, 1.11344406e-05, + 1.46078837e-05, 2.32387462e-05, 3.33902042e-05, 3.71470080e-05, 3.58142275e-05, 1.78899706e-05, + 1.26733135e-05, 1.38926962e-05, 2.01364356e-05, 2.91229198e-05, 3.62185254e-05, 3.80072964e-05, + 3.55320202e-05, 1.57917087e-05, 1.16112071e-05, 1.37505219e-05, 2.10429143e-05, 3.25882241e-05, + 3.81945462e-05, 3.63214505e-05, 3.42278680e-05, 1.46983461e-05, 9.99538826e-06, 1.52616295e-05, + 2.37801127e-05, 2.82496564e-05, 3.05294392e-05, 3.27802593e-05, 2.00299185e-05, 1.62125742e-05, + 1.55875252e-05, 1.74660976e-05, 2.46965644e-05, 3.28491395e-05, 3.46948731e-05, 3.38056936e-05, + 2.11888313e-05, 1.73213368e-05, 1.75485949e-05, 2.04243573e-05, 2.31692414e-05, 2.57783272e-05, + 3.10163272e-05, 3.35413611e-05, 2.23182271e-05, 1.72283959e-05, 1.73896142e-05, 1.91467359e-05, + 2.08040707e-05, 2.52860185e-05, 3.08672210e-05, 3.40680124e-05, 3.39046505e-05, 2.52452421e-05, + 1.64951570e-05, 1.06015336e-05, 1.18934181e-05, 1.93672887e-05, 3.11814307e-05, 3.50940159e-05, + 3.08726430e-05, 1.84982484e-05, 1.47710240e-05, 1.78193361e-05, 2.39825557e-05, 2.58536883e-05, + 2.78144943e-05, 3.21692228e-05, 3.34851169e-05, 2.55058815e-05, 1.81401245e-05, 1.42706672e-05, + 1.80517918e-05, 2.36127497e-05, 2.95274396e-05, 3.33174543e-05, 3.33742399e-05, 2.27395892e-05, + 1.72468682e-05, 1.64991864e-05, 2.00868884e-05, 2.47730445e-05, 2.88631422e-05, 3.35157571e-05, + 3.23358358e-05, 3.02867818e-05, 2.29230958e-05, 1.48550873e-05, 1.19910132e-05, 1.72000235e-05, + 2.65206219e-05, 3.26125304e-05, 3.64545336e-05, 3.68622645e-05, 3.46406358e-05, 2.02502880e-05, + 1.63902476e-05, 1.61523909e-05, 2.14678871e-05, 2.91706412e-05, 2.86203914e-05, 3.10634455e-05, + 3.53227000e-05, 2.08247101e-05, 1.71355412e-05, 1.69532095e-05, 1.82935876e-05, 2.14569732e-05, + 2.86958094e-05, 3.25795474e-05, 3.13590411e-05, 1.79521796e-05, 1.27170949e-05, 1.50463443e-05, + 2.38700224e-05, 3.33119629e-05, 3.35864234e-05, 3.22612596e-05, 2.32703287e-05, 1.78235003e-05, + 1.50260241e-05, 1.65084561e-05, 2.21749107e-05, 2.71908112e-05, 3.08184933e-05, 3.46498965e-05, + 2.39434875e-05, 1.94158399e-05, 1.83952540e-05, 2.08886662e-05, 2.47245169e-05, 2.79105724e-05, + 2.94462456e-05, 2.93753154e-05, 2.89896581e-05, 2.44273277e-05, 2.15984247e-05, 2.23977180e-05, + 2.42762994e-05, 2.45904597e-05, 2.50899852e-05, 2.76772039e-05, 2.95471467e-05, 2.89960694e-05, + 2.84724794e-05, 2.91969858e-05, 2.29878707e-05, 2.00592115e-05, 2.02221396e-05, 2.35909429e-05, + 2.54805043e-05, 2.55764248e-05, 2.78464725e-05, 3.00577301e-05, 3.06890617e-05, 2.03267211e-05, + 1.52869532e-05, 1.72373552e-05, 2.51239641e-05, 3.00666338e-05, 2.98589495e-05, 2.93604480e-05, + 2.97699710e-05, 2.98825304e-05, 2.58033971e-05, 2.03399861e-05, 1.83802575e-05, 2.30065970e-05, + 2.68298385e-05, 2.62600435e-05, 2.55928988e-05, 2.74013088e-05, 2.94070848e-05, 2.94880484e-05, + 2.56918175e-05, 1.84345545e-05, 1.51286695e-05, 1.82522037e-05, 2.44179062e-05, 2.96036133e-05, + 3.08349058e-05, 3.02080872e-05, 2.06361095e-05, 1.67905473e-05, 1.79474809e-05, 2.28076761e-05, + 2.80934929e-05, 3.11046539e-05, 3.15118305e-05, 3.02495471e-05, 1.89175794e-05, 1.58472130e-05, + 1.79286079e-05, 2.33711574e-05, 2.97190387e-05, 3.16609732e-05, 3.04900816e-05, 2.96182227e-05, + 1.84875402e-05, 1.43813736e-05, 1.93058810e-05, 2.55034028e-05, 2.73591494e-05, 2.76174328e-05, + 2.86153468e-05, 2.25322976e-05, 2.00763049e-05, 1.94398560e-05, 2.04505009e-05, 2.48621311e-05, + 2.90970524e-05, 2.98529736e-05, 2.94414702e-05, 2.32978833e-05, 2.08162592e-05, 2.09329594e-05, + 2.28547930e-05, 2.41975051e-05, 2.52637397e-05, 2.80300986e-05, 2.93277367e-05, 2.40013526e-05, + 2.05375787e-05, 2.06224714e-05, 2.20609035e-05, 2.29777731e-05, 2.52932766e-05, 2.80078031e-05, + 2.95267919e-05, 2.94833747e-05, 2.67964396e-05, 2.08624730e-05, 1.49872301e-05, 1.57617463e-05, + 2.12006535e-05, 2.78823250e-05, 2.98546502e-05, 2.76192615e-05, 2.14658686e-05, 1.89620774e-05, + 2.12759446e-05, 2.52731248e-05, 2.60142724e-05, 2.66285920e-05, 2.87368568e-05, 2.93624106e-05, + 2.68691634e-05, 2.16432634e-05, 1.80986468e-05, 2.09481101e-05, 2.45466490e-05, 2.74651419e-05, + 2.91154426e-05, 2.92939837e-05, 2.41732285e-05, 2.06045036e-05, 2.00442559e-05, 2.27870763e-05, + 2.56686690e-05, 2.74857277e-05, 2.94524121e-05, 2.86712521e-05, 2.74641820e-05, 2.46725763e-05, + 1.88063392e-05, 1.59847193e-05, 2.02220334e-05, 2.64829359e-05, 2.94614175e-05, 3.07109578e-05, + 3.07426431e-05, 2.97907496e-05, 2.32194726e-05, 2.07182947e-05, 2.00929070e-05, 2.34957153e-05, + 2.74142068e-05, 2.62127484e-05, 2.74103842e-05, 2.98091180e-05, 2.27762564e-05, 2.07777369e-05, + 2.07619623e-05, 2.14119845e-05, 2.32098116e-05, 2.74385446e-05, 2.91643288e-05, 2.81867825e-05, + 2.16439517e-05, 1.74455398e-05, 1.88279866e-05, 2.44440959e-05, 2.92895323e-05, 2.93723597e-05, + 2.86252191e-05, 2.49410036e-05, 2.14174008e-05, 1.89958196e-05, 1.98579786e-05, 2.33459682e-05, + 2.59876143e-05, 2.79296102e-05, 2.98839010e-05, 2.39430654e-05, 1.94730304e-05, 1.84601972e-05, + 2.10500793e-05, 2.49384417e-05, 2.79558936e-05, 2.93679105e-05, 2.92322947e-05, 2.87671580e-05, + 2.43796516e-05, 2.15958381e-05, 2.23687708e-05, 2.42850643e-05, 2.46067357e-05, 2.50852014e-05, + 2.77097709e-05, 2.95360879e-05, 2.88838924e-05, 2.82985952e-05, 2.89826032e-05, 2.30619686e-05, + 2.01538229e-05, 2.02441542e-05, 2.36635558e-05, 2.55734748e-05, 2.55339305e-05, 2.76848962e-05, + 2.98566764e-05, 3.04689683e-05, 2.04057309e-05, 1.53890596e-05, 1.73201064e-05, 2.53362657e-05, + 3.03035320e-05, 2.98134788e-05, 2.91287372e-05, 2.95273230e-05, 2.96482828e-05, 2.60758389e-05, + 2.06198532e-05, 1.85204095e-05, 2.31595578e-05, 2.69169633e-05, 2.61426643e-05, 2.53499507e-05, + 2.71306745e-05, 2.91194342e-05, 2.96022264e-05, 2.59226660e-05, 1.85434295e-05, 1.51609302e-05, + 1.83151088e-05, 2.44603459e-05, 2.94934015e-05, 3.05604015e-05, 2.99210125e-05, 2.06360440e-05, + 1.69207582e-05, 1.81172750e-05, 2.30124134e-05, 2.82186769e-05, 3.10602344e-05, 3.13405402e-05, + 3.00187610e-05, 1.88773493e-05, 1.59812260e-05, 1.81364169e-05, 2.35550332e-05, 2.97858197e-05, + 3.15134135e-05, 3.02213475e-05, 2.93777704e-05, 1.86092195e-05, 1.45387205e-05, 1.95624092e-05, + 2.58197358e-05, 2.73922416e-05, 2.73198678e-05, 2.82726540e-05, 2.26627337e-05, 2.03389352e-05, + 1.96483544e-05, 2.04969531e-05, 2.47427227e-05, 2.89035493e-05, 2.96180585e-05, 2.92086970e-05, + 2.34188143e-05, 2.10370170e-05, 2.11334983e-05, 2.30035710e-05, 2.41773469e-05, 2.50600114e-05, + 2.77862423e-05, 2.90991449e-05, 2.41066239e-05, 2.06808324e-05, 2.07522506e-05, 2.22466605e-05, + 2.30767977e-05, 2.51998938e-05, 2.77821848e-05, 2.92809551e-05, 2.92488898e-05, 2.72638359e-05, + 2.13455153e-05, 1.51524152e-05, 1.57709450e-05, 2.10253318e-05, 2.75613189e-05, 2.95589576e-05, + 2.72638929e-05, 2.16043552e-05, 1.92394854e-05, 2.15294460e-05, 2.54564994e-05, 2.60557845e-05, + 2.64910865e-05, 2.85348561e-05, 2.91545539e-05, 2.73042979e-05, 2.19461689e-05, 1.82072400e-05, + 2.10170086e-05, 2.45509838e-05, 2.72936414e-05, 2.88518368e-05, 2.90810273e-05, 2.42421703e-05, + 2.07673102e-05, 2.02112435e-05, 2.29969290e-05, 2.58189721e-05, 2.74448439e-05, 2.92700047e-05, + 2.84194338e-05, 2.71577757e-05, 2.48808594e-05, 1.89987556e-05, 1.60424416e-05, 2.02583953e-05, + 2.65526148e-05, 2.94330900e-05, 3.04963103e-05, 3.04786722e-05, 2.95434481e-05, 2.35496886e-05, + 2.11764166e-05, 2.03797879e-05, 2.36207038e-05, 2.72907703e-05, 2.57890555e-05, 2.69558332e-05, + 2.94640162e-05, 2.27977720e-05, 2.10369331e-05, 2.10679795e-05, 2.15856395e-05, 2.32343290e-05, + 2.74130840e-05, 2.90387428e-05, 2.79368001e-05, 2.20003581e-05, 1.78114366e-05, 1.89705713e-05, + 2.43560693e-05, 2.90851885e-05, 2.91515088e-05, 2.83703670e-05, 2.51668329e-05, 2.17234484e-05, + 1.92071370e-05, 1.99538509e-05, 2.32518814e-05, 2.57519358e-05, 2.76861767e-05, 2.96663757e-05, + 2.56960736e-05, 2.88107249e-05, 2.94052239e-05, 2.76115111e-05, 2.48752166e-05, 2.24185670e-05, + 2.10158135e-05, 2.10411275e-05, 2.13497923e-05, 2.53543592e-05, 2.74683038e-05, 2.69208470e-05, + 2.54255914e-05, 2.51705162e-05, 2.47861923e-05, 2.26184824e-05, 2.09602400e-05, 2.14115880e-05, + 2.18630927e-05, 2.11589105e-05, 2.63297710e-05, 2.83036654e-05, 2.83779004e-05, 2.58834929e-05, + 2.44059321e-05, 2.44086739e-05, 2.24419176e-05, 2.03452294e-05, 1.97086418e-05, 2.81706237e-05, + 3.07819591e-05, 2.99791717e-05, 2.45802873e-05, 2.05986687e-05, 2.06552296e-05, 2.09894244e-05, + 2.05849383e-05, 2.04836088e-05, 2.40173867e-05, 2.76446094e-05, 2.91613527e-05, 2.61980143e-05, + 2.33199880e-05, 2.38529192e-05, 2.44586524e-05, 2.28130367e-05, 2.08957743e-05, 2.10639219e-05, + 2.41363338e-05, 2.92369033e-05, 3.12079209e-05, 2.94949633e-05, 2.52827519e-05, 2.08497899e-05, + 1.94979603e-05, 2.01091241e-05, 2.81458369e-05, 3.00051295e-05, 2.92842879e-05, 2.62529626e-05, + 2.22617488e-05, 1.94873369e-05, 1.89501827e-05, 2.01292196e-05, 2.94068486e-05, 3.03999026e-05, + 2.91530326e-05, 2.58927045e-05, 2.08421831e-05, 1.88313283e-05, 1.98499514e-05, 2.07338995e-05, + 2.91644700e-05, 3.07803194e-05, 2.82828572e-05, 2.41983572e-05, 2.28894193e-05, 2.25995497e-05, + 2.16172522e-05, 2.65693505e-05, 2.78415584e-05, 2.83567307e-05, 2.81667781e-05, 2.50454504e-05, + 2.12683996e-05, 2.05116666e-05, 2.09108213e-05, 2.60360898e-05, 2.75152132e-05, 2.74916260e-05, + 2.63120357e-05, 2.55148546e-05, 2.47390814e-05, 2.22394505e-05, 2.10232650e-05, 2.55357356e-05, + 2.78780770e-05, 2.78566027e-05, 2.67931761e-05, 2.63006025e-05, 2.46698512e-05, 2.22689431e-05, + 2.08174382e-05, 2.08691049e-05, 2.31260803e-05, 2.68108164e-05, 3.05535513e-05, 3.10340966e-05, + 2.80703886e-05, 2.23366063e-05, 2.04493489e-05, 2.25668634e-05, 2.72851903e-05, 2.83945441e-05, + 2.71551608e-05, 2.44946827e-05, 2.40072233e-05, 2.35336168e-05, 2.16015101e-05, 2.10064996e-05, + 2.30985381e-05, 2.68177636e-05, 2.94242448e-05, 2.77810838e-05, 2.52155013e-05, 2.27848218e-05, + 2.11986667e-05, 2.10677263e-05, 2.54455939e-05, 2.77880465e-05, 2.81224477e-05, 2.62584031e-05, + 2.42170284e-05, 2.27835638e-05, 2.09404434e-05, 2.16314703e-05, 2.27393024e-05, 2.49196769e-05, + 2.87557710e-05, 3.07017613e-05, 2.83433634e-05, 2.36112128e-05, 2.10293291e-05, 1.96931832e-05, + 1.96036521e-05, 2.05603645e-05, 2.57635937e-05, 2.69529018e-05, 2.77641993e-05, 2.58860650e-05, + 2.28394479e-05, 2.38724690e-05, 2.27037782e-05, 2.04405733e-05, 2.65625332e-05, 2.74434869e-05, + 2.73340358e-05, 2.72464558e-05, 2.62322533e-05, 2.28247305e-05, 2.12486916e-05, 2.20896114e-05, + 2.66966557e-05, 2.87377501e-05, 2.89051116e-05, 2.53719441e-05, 2.10784869e-05, 2.09867853e-05, + 2.16730938e-05, 2.47027423e-05, 2.69477264e-05, 2.85922944e-05, 2.84274568e-05, 2.62671635e-05, + 2.41063429e-05, 2.23333616e-05, 2.04979486e-05, 2.55585743e-05, 2.67827254e-05, 2.69158768e-05, + 2.61891931e-05, 2.49179750e-05, 2.36184530e-05, 2.27439984e-05, 2.27897301e-05, 2.30394692e-05, + 2.54237936e-05, 2.64004259e-05, 2.61929485e-05, 2.54079894e-05, 2.52648760e-05, 2.50732912e-05, + 2.37532584e-05, 2.26757173e-05, 2.30324726e-05, 2.33692509e-05, 2.29027142e-05, 2.57882453e-05, + 2.65483799e-05, 2.67143970e-05, 2.55752441e-05, 2.47776139e-05, 2.48900404e-05, 2.37492673e-05, + 2.23181600e-05, 2.18584740e-05, 2.65349928e-05, 2.68316458e-05, 2.69531574e-05, 2.47656717e-05, + 2.23146414e-05, 2.24777034e-05, 2.27907375e-05, 2.25067987e-05, 2.24306271e-05, 2.44085364e-05, + 2.59657574e-05, 2.66579150e-05, 2.56288744e-05, 2.41517497e-05, 2.46157853e-05, 2.50704134e-05, + 2.40520195e-05, 2.27469306e-05, 2.26891538e-05, 2.45098782e-05, 2.67605950e-05, 2.71553843e-05, + 2.69403424e-05, 2.52997278e-05, 2.26416867e-05, 2.17189512e-05, 2.21772448e-05, 2.66692354e-05, + 2.67742523e-05, 2.65852858e-05, 2.55856624e-05, 2.34716700e-05, 2.16348498e-05, 2.12728264e-05, + 2.21720152e-05, 2.71763005e-05, 2.67272058e-05, 2.64458871e-05, 2.54499158e-05, 2.25593140e-05, + 2.11751365e-05, 2.19796739e-05, 2.26127001e-05, 2.67107835e-05, 2.64234745e-05, 2.61734940e-05, + 2.44661192e-05, 2.39233606e-05, 2.39253464e-05, 2.32782503e-05, 2.58244652e-05, 2.60564126e-05, + 2.63108766e-05, 2.65943957e-05, 2.53166291e-05, 2.29701371e-05, 2.24511063e-05, 2.27355402e-05, + 2.55931634e-05, 2.60464333e-05, 2.60764237e-05, 2.56858281e-05, 2.54834442e-05, 2.52080295e-05, + 2.36574061e-05, 2.28133387e-05, 2.53663369e-05, 2.63139018e-05, 2.63320612e-05, 2.58399967e-05, + 2.57438471e-05, 2.50811203e-05, 2.36679518e-05, 2.26744387e-05, 2.27066331e-05, 2.37529278e-05, + 2.53072402e-05, 2.64869064e-05, 2.72891394e-05, 2.69123592e-05, 2.37611811e-05, 2.24288423e-05, + 2.39331590e-05, 2.61084408e-05, 2.61366046e-05, 2.58651707e-05, 2.47467773e-05, 2.45919111e-05, + 2.44331918e-05, 2.32042240e-05, 2.27928890e-05, 2.37635880e-05, 2.56608242e-05, 2.67956238e-05, + 2.64132311e-05, 2.53002615e-05, 2.39786650e-05, 2.29514847e-05, 2.28381165e-05, 2.53582973e-05, + 2.62466517e-05, 2.63430746e-05, 2.55811247e-05, 2.46237024e-05, 2.39019971e-05, 2.27357330e-05, + 2.32476141e-05, 2.40226520e-05, 2.49464819e-05, 2.64369345e-05, 2.70760615e-05, 2.66753299e-05, + 2.43382237e-05, 2.27312061e-05, 2.18451687e-05, 2.17947648e-05, 2.24909068e-05, 2.52052251e-05, + 2.53964399e-05, 2.59817397e-05, 2.55168296e-05, 2.39863528e-05, 2.48253864e-05, 2.40748508e-05, + 2.24405251e-05, 2.59622501e-05, 2.59492539e-05, 2.58226761e-05, 2.60358766e-05, 2.58007242e-05, + 2.39188266e-05, 2.29264011e-05, 2.35595279e-05, 2.55254081e-05, 2.58349856e-05, 2.66011117e-05, + 2.54705746e-05, 2.28420455e-05, 2.27843864e-05, 2.32776721e-05, 2.48169718e-05, 2.57001625e-05, + 2.63542901e-05, 2.65846072e-05, 2.59501677e-05, 2.48514610e-05, 2.37200747e-05, 2.24345840e-05, + 2.26370495e-05, 1.59345287e-05, 1.46254827e-05, 1.72129183e-05, 2.23358893e-05, 2.89387962e-05, + 3.29824034e-05, 3.34469217e-05, 3.34217024e-05, 2.37411275e-05, 1.92128482e-05, 2.05288968e-05, + 2.30862383e-05, 2.35243563e-05, 2.44802746e-05, 2.86190112e-05, 3.25673191e-05, 3.23905116e-05, + 3.19253368e-05, 3.37679882e-05, 2.06833527e-05, 1.65321388e-05, 1.71893342e-05, 2.15854540e-05, + 2.43840640e-05, 2.55694722e-05, 3.06039426e-05, 3.54505366e-05, 3.70375442e-05, 1.69740644e-05, + 1.08990561e-05, 1.31571668e-05, 2.29654433e-05, 3.14282742e-05, 3.35200025e-05, 3.42770062e-05, + 3.52521677e-05, 3.54086742e-05, 2.36206268e-05, 1.58194491e-05, 1.41844595e-05, 2.01868449e-05, + 2.66836217e-05, 2.73374112e-05, 2.72337487e-05, 3.07532948e-05, 3.49353545e-05, 3.13406362e-05, + 2.37328671e-05, 1.44236884e-05, 1.10856798e-05, 1.44642408e-05, 2.30629326e-05, 3.36040064e-05, + 3.79491349e-05, 3.66663246e-05, 1.78790468e-05, 1.23960630e-05, 1.35120493e-05, 1.95694408e-05, + 2.86193806e-05, 3.61722696e-05, 3.84103488e-05, 3.61712467e-05, 1.58964550e-05, 1.13385774e-05, + 1.32890054e-05, 2.05131162e-05, 3.22123255e-05, 3.85066029e-05, 3.71026683e-05, 3.49065523e-05, + 1.44157745e-05, 9.69553223e-06, 1.46655454e-05, 2.28480669e-05, 2.80423516e-05, 3.14179533e-05, + 3.38404873e-05, 1.96549761e-05, 1.55834265e-05, 1.50927224e-05, 1.73377129e-05, 2.49927387e-05, + 3.33610617e-05, 3.53518956e-05, 3.44570357e-05, 2.08222911e-05, 1.67669731e-05, 1.70381496e-05, + 1.99958698e-05, 2.31749468e-05, 2.63413721e-05, 3.17123976e-05, 3.41780304e-05, 2.19781215e-05, + 1.68612060e-05, 1.70531547e-05, 1.86448591e-05, 2.05012674e-05, 2.54983586e-05, 3.14988003e-05, + 3.47669568e-05, 3.45620493e-05, 2.38820759e-05, 1.53830710e-05, 1.02778419e-05, 1.18929845e-05, + 1.98407089e-05, 3.21566669e-05, 3.59792902e-05, 3.19736632e-05, 1.81247412e-05, 1.41397174e-05, + 1.71781798e-05, 2.34015269e-05, 2.56502475e-05, 2.81552984e-05, 3.27138813e-05, 3.40464518e-05, + 2.42172108e-05, 1.73765267e-05, 1.40233437e-05, 1.78602290e-05, 2.35430558e-05, 2.99749393e-05, + 3.40831089e-05, 3.39544384e-05, 2.24946523e-05, 1.68320052e-05, 1.60857522e-05, 1.95079063e-05, + 2.42699866e-05, 2.88828711e-05, 3.39850566e-05, 3.30592599e-05, 3.12067727e-05, 2.22946023e-05, + 1.44089998e-05, 1.18803086e-05, 1.70997556e-05, 2.62245917e-05, 3.25522028e-05, 3.70297647e-05, + 3.76241990e-05, 3.53438926e-05, 1.93712462e-05, 1.53332985e-05, 1.54702569e-05, 2.10864737e-05, + 2.94580826e-05, 2.99613440e-05, 3.25409184e-05, 3.63985081e-05, 2.07321377e-05, 1.64951497e-05, + 1.62100721e-05, 1.78358392e-05, 2.13501631e-05, 2.86677551e-05, 3.28530103e-05, 3.20767172e-05, + 1.70706313e-05, 1.19548808e-05, 1.47109392e-05, 2.40734081e-05, 3.38611796e-05, 3.41947040e-05, + 3.29957719e-05, 2.25882238e-05, 1.70600098e-05, 1.45346944e-05, 1.62661148e-05, 2.24043172e-05, + 2.78598681e-05, 3.15132344e-05, 3.52426463e-05, 2.08585238e-05, 1.26935526e-05, 1.12697399e-05, + 1.42834386e-05, 2.08163901e-05, 3.01245165e-05, 3.64286370e-05, 3.70407525e-05, 3.67695527e-05, + 2.22758980e-05, 1.64552108e-05, 1.80568389e-05, 2.14820440e-05, 2.20949257e-05, 2.33859827e-05, + 2.95954965e-05, 3.59070138e-05, 3.53343789e-05, 3.43916435e-05, 3.73858519e-05, 1.84158096e-05, + 1.34137721e-05, 1.40770298e-05, 1.95845434e-05, 2.34346259e-05, 2.48635375e-05, 3.22679173e-05, + 4.03720304e-05, 4.31880086e-05, 1.39015003e-05, 7.55613660e-06, 9.75210788e-06, 2.16713347e-05, + 3.46274584e-05, 3.74432571e-05, 3.82137652e-05, 3.98901990e-05, 4.01940797e-05, 2.26838282e-05, + 1.28232144e-05, 1.08803665e-05, 1.79019835e-05, 2.67633848e-05, 2.73025859e-05, 2.68674289e-05, + 3.22253549e-05, 3.91923885e-05, 3.41730651e-05, 2.27682573e-05, 1.11017929e-05, 7.67191481e-06, + 1.10951554e-05, 2.15100669e-05, 3.74045040e-05, 4.46967917e-05, 4.22869370e-05, 1.48539714e-05, + 9.03013664e-06, 1.02043021e-05, 1.71977343e-05, 2.98054910e-05, 4.21644278e-05, 4.59239369e-05, + 4.15721583e-05, 1.25325384e-05, 8.00012174e-06, 1.00103416e-05, 1.83656269e-05, 3.55133306e-05, + 4.61896209e-05, 4.31460714e-05, 3.92870779e-05, 1.11070958e-05, 6.49430299e-06, 1.15192714e-05, + 2.16849601e-05, 2.87050105e-05, 3.32256790e-05, 3.71305783e-05, 1.71976425e-05, 1.25385050e-05, + 1.19345147e-05, 1.42813518e-05, 2.38853161e-05, 3.67495527e-05, 4.00911091e-05, 3.85236357e-05, + 1.86675342e-05, 1.38378522e-05, 1.41282515e-05, 1.76535352e-05, 2.15509410e-05, 2.56445235e-05, + 3.38515499e-05, 3.80514470e-05, 2.01572616e-05, 1.38518097e-05, 1.40573490e-05, 1.60268280e-05, + 1.82212151e-05, 2.46581603e-05, 3.35510552e-05, 3.90255794e-05, 3.87016289e-05, 2.33901035e-05, + 1.25512684e-05, 7.02945310e-06, 8.42271048e-06, 1.69634383e-05, 3.43693949e-05, 4.10180098e-05, + 3.39727352e-05, 1.53335676e-05, 1.09738637e-05, 1.43575951e-05, 2.22230455e-05, 2.51489966e-05, + 2.84922341e-05, 3.56296010e-05, 3.78851160e-05, 2.38141536e-05, 1.46526578e-05, 1.06768792e-05, + 1.49250505e-05, 2.20989292e-05, 3.12386035e-05, 3.77831072e-05, 3.77111218e-05, 2.07869589e-05, + 1.38422544e-05, 1.29940848e-05, 1.71278849e-05, 2.33794494e-05, 2.98372412e-05, 3.78537431e-05, + 3.60704425e-05, 3.28598853e-05, 2.07513304e-05, 1.11748901e-05, 8.45537772e-06, 1.39920350e-05, + 2.60463793e-05, 3.58346915e-05, 4.31916953e-05, 4.41266862e-05, 4.00383010e-05, 1.71249306e-05, + 1.24690810e-05, 1.24387623e-05, 1.90162641e-05, 3.05412195e-05, 3.05723553e-05, 3.46212398e-05, + 4.16106068e-05, 1.83957566e-05, 1.35699235e-05, 1.32971195e-05, 1.50346198e-05, 1.91983809e-05, + 2.95383347e-05, 3.60775316e-05, 3.44345233e-05, 1.43560869e-05, 8.79837812e-06, 1.14467580e-05, + 2.26591567e-05, 3.75755802e-05, 3.81033641e-05, 3.59546816e-05, 2.11783819e-05, 1.42829473e-05, + 1.13300202e-05, 1.31130748e-05, 2.03832372e-05, 2.78184801e-05, 3.35268140e-05, 3.99511919e-05, + 2.38804924e-05, 1.91779433e-05, 1.81310934e-05, 2.05917408e-05, 2.44945003e-05, 2.79669308e-05, + 2.96993512e-05, 2.96871425e-05, 2.93576209e-05, 2.44247240e-05, 2.14656835e-05, 2.23114561e-05, + 2.42164482e-05, 2.45349409e-05, 2.50723475e-05, 2.77344649e-05, 2.97410933e-05, 2.92572631e-05, + 2.87655693e-05, 2.95684671e-05, 2.28262028e-05, 1.98019813e-05, 2.00329611e-05, 2.34497379e-05, + 2.53880388e-05, 2.56126297e-05, 2.80959997e-05, 3.04657775e-05, 3.11548231e-05, 2.00893073e-05, + 1.49493566e-05, 1.69391468e-05, 2.49097767e-05, 3.00539959e-05, 3.01035167e-05, 2.97580985e-05, + 3.02020285e-05, 3.03129290e-05, 2.55605914e-05, 1.99271711e-05, 1.80501973e-05, 2.27747696e-05, + 2.67980303e-05, 2.63945828e-05, 2.58182321e-05, 2.77341941e-05, 2.98625415e-05, 2.95595356e-05, + 2.54822015e-05, 1.81326568e-05, 1.48498134e-05, 1.79873382e-05, 2.43322719e-05, 2.98963871e-05, + 3.13644853e-05, 3.07106363e-05, 2.04764278e-05, 1.64451953e-05, 1.75846207e-05, 2.25238343e-05, + 2.80839476e-05, 3.14230606e-05, 3.19825901e-05, 3.06986004e-05, 1.87561673e-05, 1.54876737e-05, + 1.75327428e-05, 2.31229767e-05, 2.98480731e-05, 3.21180594e-05, 3.09918476e-05, 3.00392526e-05, + 1.81754105e-05, 1.39899569e-05, 1.88920204e-05, 2.52099195e-05, 2.74011719e-05, 2.79870375e-05, + 2.90809597e-05, 2.23064820e-05, 1.96727086e-05, 1.90700742e-05, 2.02448595e-05, 2.49421511e-05, + 2.94426091e-05, 3.02822829e-05, 2.98447712e-05, 2.31037382e-05, 2.04655993e-05, 2.06027546e-05, + 2.26221228e-05, 2.41613987e-05, 2.54385358e-05, 2.83682132e-05, 2.97204748e-05, 2.38442352e-05, + 2.02483273e-05, 2.03470690e-05, 2.17726563e-05, 2.27933716e-05, 2.53656619e-05, 2.83271098e-05, + 2.99478451e-05, 2.98907547e-05, 2.64185302e-05, 2.02873561e-05, 1.45933922e-05, 1.55090884e-05, + 2.12143527e-05, 2.82880917e-05, 3.03443383e-05, 2.80453934e-05, 2.12036008e-05, 1.85239109e-05, + 2.09077923e-05, 2.50905569e-05, 2.59903063e-05, 2.67982048e-05, 2.90711505e-05, 2.97367758e-05, + 2.65229278e-05, 2.12412857e-05, 1.77912724e-05, 2.07344972e-05, 2.45004992e-05, 2.77056631e-05, + 2.95306591e-05, 2.96694928e-05, 2.40548985e-05, 2.02996233e-05, 1.97231231e-05, 2.24980958e-05, + 2.55311725e-05, 2.76030825e-05, 2.98069613e-05, 2.90505977e-05, 2.78348398e-05, 2.44457933e-05, + 1.84385000e-05, 1.56923271e-05, 2.00200763e-05, 2.64524076e-05, 2.96672122e-05, 3.11726800e-05, + 3.12556884e-05, 3.02286298e-05, 2.28372446e-05, 2.01611339e-05, 1.96687299e-05, 2.33042037e-05, + 2.76064255e-05, 2.66389610e-05, 2.79237341e-05, 3.03454017e-05, 2.26555949e-05, 2.03926979e-05, + 2.03359945e-05, 2.11172633e-05, 2.30999107e-05, 2.75391604e-05, 2.94475970e-05, 2.85388635e-05, + 2.11956130e-05, 1.69086637e-05, 1.85037782e-05, 2.44794063e-05, 2.96563624e-05, 2.97600244e-05, + 2.90050634e-05, 2.47080129e-05, 2.10070245e-05, 1.86151095e-05, 1.95952464e-05, 2.33488799e-05, + 2.62226040e-05, 2.82622327e-05, 3.02978699e-05, 2.37993041e-05, 1.89889134e-05, 1.79239897e-05, + 2.05468850e-05, 2.46533941e-05, 2.81462969e-05, 2.98715463e-05, 2.97946988e-05, 2.93634045e-05, + 2.43210783e-05, 2.12872347e-05, 2.21375091e-05, 2.41594327e-05, 2.45000637e-05, 2.50422372e-05, + 2.78869945e-05, 2.99824818e-05, 2.93651618e-05, 2.87791783e-05, 2.95971171e-05, 2.27747880e-05, + 1.96672528e-05, 1.98329372e-05, 2.34225000e-05, 2.54705576e-05, 2.55720868e-05, 2.80785060e-05, + 3.05735100e-05, 3.12978083e-05, 1.99475286e-05, 1.47243417e-05, 1.67250422e-05, 2.50867064e-05, + 3.05608649e-05, 3.03372010e-05, 2.97831879e-05, 3.02489151e-05, 3.03764157e-05, 2.58289233e-05, + 1.99785507e-05, 1.79155592e-05, 2.27994056e-05, 2.69497595e-05, 2.63209621e-05, 2.55882453e-05, + 2.75856573e-05, 2.98399357e-05, 2.99112255e-05, 2.57056257e-05, 1.79690333e-05, 1.45548115e-05, + 1.77749830e-05, 2.43140039e-05, 3.00513058e-05, 3.14712672e-05, 3.07526514e-05, 2.02678872e-05, + 1.62691197e-05, 1.74690306e-05, 2.25897368e-05, 2.83493450e-05, 3.17595012e-05, 3.22420414e-05, + 3.07950049e-05, 1.84594254e-05, 1.53007659e-05, 1.74533875e-05, 2.31922238e-05, 3.01735649e-05, + 3.24122671e-05, 3.10740821e-05, 3.00762172e-05, 1.80254055e-05, 1.38095441e-05, 1.88920299e-05, + 2.55038374e-05, 2.75342556e-05, 2.78273806e-05, 2.89484014e-05, 2.22906485e-05, 1.96998317e-05, + 1.90275759e-05, 2.00754553e-05, 2.47914819e-05, 2.94830203e-05, 3.03428053e-05, 2.98750820e-05, + 2.31099675e-05, 2.04752565e-05, 2.05968258e-05, 2.26366019e-05, 2.40731101e-05, 2.52282058e-05, + 2.82863325e-05, 2.97459371e-05, 2.38663816e-05, 2.01748916e-05, 2.02633365e-05, 2.17917478e-05, + 2.27653637e-05, 2.52618930e-05, 2.82607067e-05, 2.99727761e-05, 2.99227202e-05, 2.69229840e-05, + 2.05477077e-05, 1.44262963e-05, 1.51993420e-05, 2.08544888e-05, 2.81242521e-05, 3.03496601e-05, + 2.78317575e-05, 2.11561347e-05, 1.85351358e-05, 2.09638180e-05, 2.52477180e-05, 2.60528396e-05, + 2.67270467e-05, 2.90774674e-05, 2.97838904e-05, 2.70015521e-05, 2.13569772e-05, 1.76197929e-05, + 2.06026489e-05, 2.44521451e-05, 2.76540970e-05, 2.95079451e-05, 2.97067474e-05, 2.40503673e-05, + 2.02470538e-05, 1.96576416e-05, 2.25680444e-05, 2.56776162e-05, 2.76749668e-05, 2.98842498e-05, + 2.90061451e-05, 2.76568472e-05, 2.45968660e-05, 1.83643333e-05, 1.54331197e-05, 1.98339304e-05, + 2.65676904e-05, 2.98863738e-05, 3.13224382e-05, 3.13638706e-05, 3.02729205e-05, 2.30388994e-05, + 2.03934145e-05, 1.97195038e-05, 2.33227459e-05, 2.75966014e-05, 2.62723948e-05, 2.76032381e-05, + 3.03020893e-05, 2.25451917e-05, 2.04378614e-05, 2.04253098e-05, 2.11016225e-05, 2.30103277e-05, + 2.76224874e-05, 2.95554525e-05, 2.84620013e-05, 2.13621346e-05, 1.69709876e-05, 1.83821296e-05, + 2.43380600e-05, 2.97011868e-05, 2.97959792e-05, 2.89544994e-05, 2.48886504e-05, 2.11178981e-05, + 1.85638055e-05, 1.94559022e-05, 2.31513999e-05, 2.60215006e-05, 2.81739510e-05, 3.03766919e-05, + 2.57088470e-05, 2.86147453e-05, 2.91576166e-05, 2.74108134e-05, 2.48023054e-05, 2.25258028e-05, + 2.12088562e-05, 2.12580198e-05, 2.15915479e-05, 2.54080852e-05, 2.74007255e-05, 2.68982921e-05, + 2.54441373e-05, 2.51951200e-05, 2.48372886e-05, 2.27250859e-05, 2.11293781e-05, 2.16090920e-05, + 2.20757771e-05, 2.14008220e-05, 2.62673112e-05, 2.81099638e-05, 2.82405611e-05, 2.58437964e-05, + 2.44199756e-05, 2.44931188e-05, 2.26371020e-05, 2.05956043e-05, 1.99749663e-05, 2.79990204e-05, + 3.03474356e-05, 2.96623377e-05, 2.45230152e-05, 2.06873161e-05, 2.08439153e-05, 2.12407699e-05, + 2.08466494e-05, 2.07437809e-05, 2.39560951e-05, 2.73434297e-05, 2.88572640e-05, 2.60913627e-05, + 2.33786364e-05, 2.39922706e-05, 2.46453888e-05, 2.30483127e-05, 2.11696703e-05, 2.11836015e-05, + 2.40906720e-05, 2.89584281e-05, 3.08281253e-05, 2.92422625e-05, 2.52878814e-05, 2.10581661e-05, + 1.97851734e-05, 2.03932834e-05, 2.80400103e-05, 2.96275529e-05, 2.89365508e-05, 2.61090739e-05, + 2.23401354e-05, 1.96989874e-05, 1.92108676e-05, 2.03933443e-05, 2.92613035e-05, 2.99685335e-05, + 2.87764198e-05, 2.57833083e-05, 2.09854700e-05, 1.90862235e-05, 2.01309771e-05, 2.09925482e-05, + 2.88791421e-05, 3.02451180e-05, 2.79443933e-05, 2.41050416e-05, 2.29873197e-05, 2.28506145e-05, + 2.19025600e-05, 2.64567788e-05, 2.75381513e-05, 2.80571777e-05, 2.80222118e-05, 2.51499825e-05, + 2.15003296e-05, 2.07716597e-05, 2.11638334e-05, 2.59586934e-05, 2.72739432e-05, 2.72683556e-05, + 2.62017364e-05, 2.55465818e-05, 2.48981438e-05, 2.24738651e-05, 2.12728767e-05, 2.54928810e-05, + 2.76733508e-05, 2.76643787e-05, 2.66287423e-05, 2.62234679e-05, 2.47723667e-05, 2.24950681e-05, + 2.10768059e-05, 2.11234234e-05, 2.30150156e-05, 2.64155453e-05, 3.00469706e-05, 3.07069623e-05, + 2.81030418e-05, 2.26022219e-05, 2.07322612e-05, 2.28438161e-05, 2.71239176e-05, 2.80241511e-05, + 2.69152905e-05, 2.44570615e-05, 2.40630292e-05, 2.36913882e-05, 2.18306388e-05, 2.12485349e-05, + 2.30041677e-05, 2.65659016e-05, 2.91297221e-05, 2.76421860e-05, 2.52450441e-05, 2.29765938e-05, + 2.14588817e-05, 2.13106531e-05, 2.54283115e-05, 2.75737088e-05, 2.78796516e-05, 2.61107771e-05, + 2.42092537e-05, 2.29175343e-05, 2.11740374e-05, 2.18799952e-05, 2.29918419e-05, 2.48476696e-05, + 2.84355855e-05, 3.03428570e-05, 2.81962013e-05, 2.36676218e-05, 2.12033001e-05, 1.99578845e-05, + 1.98860927e-05, 2.08241391e-05, 2.55686848e-05, 2.65641227e-05, 2.74462124e-05, 2.58138816e-05, + 2.30085622e-05, 2.41617655e-05, 2.30228605e-05, 2.07415531e-05, 2.65230000e-05, 2.71765568e-05, + 2.70376669e-05, 2.70612408e-05, 2.62062537e-05, 2.29506863e-05, 2.14548026e-05, 2.23293549e-05, + 2.64139448e-05, 2.82214368e-05, 2.86211908e-05, 2.54480189e-05, 2.13179507e-05, 2.12340665e-05, + 2.19221321e-05, 2.46319839e-05, 2.66832738e-05, 2.82685751e-05, 2.82240085e-05, 2.63142361e-05, + 2.42977366e-05, 2.25658336e-05, 2.07518509e-05, 2.57623730e-05, 2.80118309e-05, 2.83967666e-05, + 2.66972056e-05, 2.44436954e-05, 2.28224492e-05, 2.18332784e-05, 2.19921722e-05, 2.24515460e-05, + 2.56187336e-05, 2.72272607e-05, 2.68779242e-05, 2.55065568e-05, 2.52689686e-05, 2.50044476e-05, + 2.30277993e-05, 2.16434403e-05, 2.22689237e-05, 2.28227917e-05, 2.22542994e-05, 2.60393317e-05, + 2.74763135e-05, 2.78433579e-05, 2.56843742e-05, 2.44061178e-05, 2.47856288e-05, 2.33288811e-05, + 2.14590827e-05, 2.08918057e-05, 2.74452903e-05, 2.89986756e-05, 2.86802779e-05, 2.42141657e-05, + 2.08289557e-05, 2.14353151e-05, 2.21315113e-05, 2.17709472e-05, 2.16574206e-05, 2.36005407e-05, + 2.62297036e-05, 2.78518330e-05, 2.56697206e-05, 2.35032001e-05, 2.44990095e-05, 2.53957178e-05, + 2.39392591e-05, 2.21616361e-05, 2.14799564e-05, 2.38074005e-05, 2.80604460e-05, 2.97309662e-05, + 2.84689315e-05, 2.52842754e-05, 2.17463138e-05, 2.07932961e-05, 2.14061909e-05, 2.77557145e-05, + 2.84136616e-05, 2.77714292e-05, 2.55363921e-05, 2.25027583e-05, 2.03561571e-05, 2.00789507e-05, + 2.13134124e-05, 2.89135152e-05, 2.85908520e-05, 2.74884184e-05, 2.53312933e-05, 2.13788812e-05, + 1.99240074e-05, 2.11209139e-05, 2.19078787e-05, 2.79478828e-05, 2.85312651e-05, 2.67324823e-05, + 2.36242559e-05, 2.32638756e-05, 2.38046686e-05, 2.29747202e-05, 2.60342192e-05, 2.64301408e-05, + 2.70037382e-05, 2.75791375e-05, 2.55656039e-05, 2.23120114e-05, 2.16854373e-05, 2.20594131e-05, + 2.56494166e-05, 2.63895329e-05, 2.64547481e-05, 2.57720985e-05, 2.56711477e-05, 2.55391327e-05, + 2.33359361e-05, 2.21568483e-05, 2.52991871e-05, 2.69628498e-05, 2.70030761e-05, 2.60065379e-05, + 2.59318566e-05, 2.51583973e-05, 2.33204008e-05, 2.19984535e-05, 2.20235372e-05, 2.24069320e-05, + 2.48764415e-05, 2.84096016e-05, 2.97908584e-05, 2.83996099e-05, 2.36121482e-05, 2.17506579e-05, + 2.39160969e-05, 2.65481951e-05, 2.66970687e-05, 2.60111631e-05, 2.42268730e-05, 2.42093200e-05, + 2.42647014e-05, 2.26423876e-05, 2.20969140e-05, 2.24644236e-05, 2.55906694e-05, 2.81846623e-05, + 2.71938936e-05, 2.53428064e-05, 2.36680683e-05, 2.23984359e-05, 2.21654089e-05, 2.53381617e-05, + 2.68176501e-05, 2.70339299e-05, 2.55230171e-05, 2.40916742e-05, 2.33492307e-05, 2.19811069e-05, + 2.27821527e-05, 2.39588226e-05, 2.44953462e-05, 2.73330441e-05, 2.92699593e-05, 2.77558849e-05, + 2.37966113e-05, 2.17417820e-05, 2.08666781e-05, 2.08750221e-05, 2.17571654e-05, 2.47565056e-05, + 2.50596535e-05, 2.62750440e-05, 2.55173071e-05, 2.36002088e-05, 2.53513222e-05, 2.42975452e-05, + 2.18443337e-05, 2.64069231e-05, 2.61842949e-05, 2.59206683e-05, 2.63848228e-05, 2.61266432e-05, + 2.33485693e-05, 2.21475375e-05, 2.32096242e-05, 2.53075102e-05, 2.63720049e-05, 2.76737147e-05, + 2.57572041e-05, 2.21571440e-05, 2.21059285e-05, 2.28283036e-05, 2.42729078e-05, 2.56664226e-05, + 2.71388913e-05, 2.75603970e-05, 2.65509258e-05, 2.50508456e-05, 2.34229803e-05, 2.16369073e-05, + 2.56926275e-05, 2.87659390e-05, 2.93498661e-05, 2.75861427e-05, 2.48840276e-05, 2.24462133e-05, + 2.10511416e-05, 2.10751100e-05, 2.13802045e-05, 2.53537542e-05, 2.74431628e-05, 2.69024782e-05, + 2.54252415e-05, 2.51729888e-05, 2.47921969e-05, 2.26443548e-05, 2.09971281e-05, 2.14436502e-05, + 2.18908079e-05, 2.11907753e-05, 2.63202680e-05, 2.82673092e-05, 2.83398817e-05, 2.58791742e-05, + 2.44173881e-05, 2.44176604e-05, 2.24655317e-05, 2.03825535e-05, 1.97493504e-05, 2.81362413e-05, + 3.06936065e-05, 2.99119915e-05, 2.45920397e-05, 2.06419923e-05, 2.06934417e-05, 2.10220901e-05, + 2.06200076e-05, 2.05194692e-05, 2.40354849e-05, 2.76193480e-05, 2.91100924e-05, 2.61912441e-05, + 2.33411300e-05, 2.38656193e-05, 2.44632172e-05, 2.28315487e-05, 2.09279894e-05, 2.11023088e-05, + 2.41526570e-05, 2.91844510e-05, 3.11117653e-05, 2.94379150e-05, 2.52845059e-05, 2.08856154e-05, + 1.95388651e-05, 2.01462854e-05, 2.81111215e-05, 2.99361168e-05, 2.92302323e-05, 2.62462271e-05, + 2.22919873e-05, 1.95323108e-05, 1.89957901e-05, 2.01672998e-05, 2.93515645e-05, 3.03205824e-05, + 2.91010425e-05, 2.58899709e-05, 2.08811763e-05, 1.88779309e-05, 1.98889738e-05, 2.07680631e-05, + 2.91132972e-05, 3.06862582e-05, 2.82469932e-05, 2.42154393e-05, 2.29131501e-05, 2.26192243e-05, + 2.16434273e-05, 2.65577242e-05, 2.78131311e-05, 2.83197391e-05, 2.81321949e-05, 2.50466979e-05, + 2.12999195e-05, 2.05473398e-05, 2.09439836e-05, 2.60307669e-05, 2.74916786e-05, 2.74683050e-05, + 2.63038315e-05, 2.55130349e-05, 2.47417262e-05, 2.22630052e-05, 2.10557659e-05, 2.55358216e-05, + 2.78486063e-05, 2.78273609e-05, 2.67793767e-05, 2.62918232e-05, 2.46753504e-05, 2.22926339e-05, + 2.08509617e-05, 2.09025072e-05, 2.31550316e-05, 2.67986960e-05, 3.04670416e-05, 3.09440286e-05, + 2.80344123e-05, 2.23578616e-05, 2.04842700e-05, 2.25856035e-05, 2.72642530e-05, 2.83565207e-05, + 2.71370767e-05, 2.45068070e-05, 2.40215010e-05, 2.35487451e-05, 2.16305601e-05, 2.10395028e-05, + 2.31272382e-05, 2.68047720e-05, 2.93681771e-05, 2.77524186e-05, 2.52172933e-05, 2.28055402e-05, + 2.12293218e-05, 2.11002278e-05, 2.54460615e-05, 2.77600650e-05, 2.80892982e-05, 2.62516670e-05, + 2.42312613e-05, 2.28067860e-05, 2.09743564e-05, 2.16593446e-05, 2.27576778e-05, 2.49279431e-05, + 2.87117379e-05, 3.06182009e-05, 2.83059943e-05, 2.36295380e-05, 2.10654645e-05, 1.97340761e-05, + 1.96441601e-05, 2.05955015e-05, 2.57642936e-05, 2.69385960e-05, 2.77370380e-05, 2.58825378e-05, + 2.28606597e-05, 2.38786197e-05, 2.27193043e-05, 2.04746068e-05, 2.65494043e-05, 2.74212356e-05, + 2.73136354e-05, 2.72264082e-05, 2.62231283e-05, 2.28479096e-05, 2.12816134e-05, 2.21141756e-05, + 2.66857249e-05, 2.86906804e-05, 2.88586256e-05, 2.53704051e-05, 2.11110792e-05, 2.10196738e-05, + 2.17006116e-05, 2.47134895e-05, 2.69329509e-05, 2.85511333e-05, 2.83891287e-05, 2.62555980e-05, + 2.41143713e-05, 2.23562066e-05, 2.05340299e-05, 2.52901949e-05, 3.28030532e-05, 3.45984723e-05, + 3.09426093e-05, 2.51846143e-05, 1.98919395e-05, 1.73333201e-05, 1.71410827e-05, 1.72774819e-05, + 2.43340557e-05, 2.88808768e-05, 2.74829992e-05, 2.48437544e-05, 2.44194180e-05, 2.35882372e-05, + 2.01500080e-05, 1.74934578e-05, 1.77633369e-05, 1.81629162e-05, 1.70504539e-05, 2.71251996e-05, + 3.19427421e-05, 3.12473129e-05, 2.61952109e-05, 2.34991542e-05, 2.27070611e-05, 1.90376599e-05, + 1.60262897e-05, 1.51615516e-05, 3.14073940e-05, 4.04366804e-05, 3.67500909e-05, 2.45835398e-05, + 1.78471321e-05, 1.69478232e-05, 1.67657972e-05, 1.62026119e-05, 1.60992017e-05, 2.38623644e-05, + 3.25036102e-05, 3.50871975e-05, 2.75041776e-05, 2.15592709e-05, 2.13857237e-05, 2.16786734e-05, + 1.91074039e-05, 1.64551682e-05, 1.80985239e-05, 2.38361871e-05, 3.48018076e-05, 4.02389565e-05, + 3.48342503e-05, 2.48044409e-05, 1.69940580e-05, 1.47476994e-05, 1.54618819e-05, 3.04398429e-05, + 3.78605941e-05, 3.60305872e-05, 2.80790804e-05, 1.99957223e-05, 1.53881590e-05, 1.43616634e-05, + 1.56579100e-05, 3.30411288e-05, 3.96131441e-05, 3.62930368e-05, 2.70951409e-05, 1.76010078e-05, + 1.42789326e-05, 1.51952422e-05, 1.64023809e-05, 3.47875502e-05, 4.25172629e-05, 3.41496365e-05, + 2.45004293e-05, 2.05844464e-05, 1.86949731e-05, 1.71991229e-05, 2.81294577e-05, 3.28584630e-05, + 3.36473170e-05, 3.10146107e-05, 2.33381907e-05, 1.72713015e-05, 1.61331549e-05, 1.66588587e-05, + 2.68899158e-05, 3.13857596e-05, 3.10828629e-05, 2.77193529e-05, 2.48123714e-05, 2.23371729e-05, + 1.84133322e-05, 1.68210969e-05, 2.57403036e-05, 3.14228953e-05, 3.12066595e-05, 2.91672668e-05, + 2.72708188e-05, 2.28561859e-05, 1.85277808e-05, 1.64930958e-05, 1.65984355e-05, 2.32657563e-05, + 3.26567918e-05, 4.14253665e-05, 3.89133125e-05, 2.84976448e-05, 1.82390054e-05, 1.58608457e-05, + 1.84129608e-05, 2.98740965e-05, 3.48665282e-05, 3.07987738e-05, 2.42284248e-05, 2.24917940e-05, + 2.07831457e-05, 1.76938165e-05, 1.68700125e-05, 2.30261532e-05, 3.04503865e-05, 3.53879908e-05, + 3.03292899e-05, 2.44236460e-05, 1.94957372e-05, 1.69313656e-05, 1.69338574e-05, 2.53006294e-05, + 3.14207089e-05, 3.23821667e-05, 2.81374386e-05, 2.34976526e-05, 2.00755367e-05, 1.68691996e-05, + 1.75500803e-05, 1.88521573e-05, 2.52354588e-05, 3.46527787e-05, 3.88456569e-05, 3.13320701e-05, + 2.19636283e-05, 1.75297664e-05, 1.51580455e-05, 1.49061696e-05, 1.61559971e-05, 2.80505001e-05, + 3.27796947e-05, 3.29615640e-05, 2.66070760e-05, 1.97893326e-05, 1.99083796e-05, 1.81927033e-05, + 1.56950810e-05, 2.71730090e-05, 3.16561720e-05, 3.19301372e-05, 3.01514914e-05, 2.65248185e-05, + 2.02099116e-05, 1.74876676e-05, 1.81815775e-05, 3.07198947e-05, 3.80823443e-05, 3.43212695e-05, + 2.41019766e-05, 1.69780207e-05, 1.67993820e-05, 1.75949940e-05, 2.49180952e-05, 3.08383116e-05, + 3.44320811e-05, 3.22872909e-05, 2.56867923e-05, 2.11738122e-05, 1.85460009e-05, 1.61712148e-05, + 2.52120675e-05, 3.13251894e-05, 3.27070343e-05, 3.04470029e-05, 2.59165696e-05, 2.08311360e-05, + 1.82906631e-05, 1.79772112e-05, 1.79144931e-05, 2.42669755e-05, 2.80335112e-05, 2.68329510e-05, + 2.48848696e-05, 2.45658925e-05, 2.38101647e-05, 2.10211231e-05, 1.85836973e-05, 1.85885821e-05, + 1.87849279e-05, 1.77384072e-05, 2.69873201e-05, 3.08802911e-05, 2.99601488e-05, 2.62275120e-05, + 2.40652960e-05, 2.29592206e-05, 1.95570070e-05, 1.68789554e-05, 1.60797821e-05, 3.03846199e-05, + 3.71682049e-05, 3.43970228e-05, 2.53955582e-05, 1.94604502e-05, 1.80225610e-05, 1.74550058e-05, + 1.69452556e-05, 1.68732685e-05, 2.49733093e-05, 3.23259688e-05, 3.35493853e-05, 2.76248073e-05, + 2.23924847e-05, 2.16364675e-05, 2.14852246e-05, 1.93290599e-05, 1.70658172e-05, 1.94113848e-05, + 2.48126045e-05, 3.31358973e-05, 3.64308884e-05, 3.28674160e-05, 2.49759966e-05, 1.79216495e-05, + 1.56100374e-05, 1.62108249e-05, 2.92353309e-05, 3.55483724e-05, 3.44586283e-05, 2.83188559e-05, + 2.11334551e-05, 1.66222998e-05, 1.54557308e-05, 1.64954561e-05, 3.09285202e-05, 3.68500560e-05, + 3.49126732e-05, 2.74137347e-05, 1.88549779e-05, 1.54232294e-05, 1.60145560e-05, 1.71227152e-05, + 3.32059034e-05, 3.91243072e-05, 3.35295038e-05, 2.56820086e-05, 2.13978078e-05, 1.89195437e-05, + 1.75699361e-05, 2.80394612e-05, 3.25218426e-05, 3.28488119e-05, 2.99123329e-05, 2.32149639e-05, + 1.79756208e-05, 1.69013580e-05, 1.73606186e-05, 2.69884623e-05, 3.11052474e-05, 3.07574667e-05, + 2.77838205e-05, 2.47529090e-05, 2.21341312e-05, 1.88231916e-05, 1.75094746e-05, 2.59807428e-05, + 3.07343127e-05, 3.04941195e-05, 2.91312279e-05, 2.72089124e-05, 2.29142638e-05, 1.89648710e-05, + 1.71893214e-05, 1.73048073e-05, 2.50610015e-05, 3.35308687e-05, 3.84170971e-05, 3.53494332e-05, + 2.69291144e-05, 1.84845425e-05, 1.65385367e-05, 1.85396402e-05, 2.94812876e-05, 3.42304733e-05, + 3.07903916e-05, 2.49908625e-05, 2.30485580e-05, 2.10797802e-05, 1.83177034e-05, 1.75976458e-05, + 2.47415626e-05, 3.07410320e-05, 3.35721972e-05, 2.94992573e-05, 2.45265852e-05, 1.99152570e-05, + 1.75255568e-05, 1.76413183e-05, 2.54813620e-05, 3.08343875e-05, 3.16167825e-05, 2.83892444e-05, + 2.42539843e-05, 2.07576925e-05, 1.76533249e-05, 1.80780430e-05, 1.90253362e-05, 2.59395716e-05, + 3.35420260e-05, 3.56944975e-05, 3.01006243e-05, 2.26873038e-05, 1.85768636e-05, 1.60872386e-05, + 1.57697730e-05, 1.68950377e-05, 2.88252686e-05, 3.35072179e-05, 3.27391498e-05, 2.67724566e-05, + 2.02908824e-05, 1.95445905e-05, 1.81065769e-05, 1.62935216e-05, 2.68054263e-05, 3.15230119e-05, + 3.19909471e-05, 2.98733297e-05, 2.63014627e-05, 2.09145959e-05, 1.83181557e-05, 1.86140254e-05, + 3.12255492e-05, 3.74181416e-05, 3.29812106e-05, 2.39358224e-05, 1.76986190e-05, 1.75079443e-05, + 1.81088383e-05, 2.57307179e-05, 3.10811323e-05, 3.34843503e-05, 3.11519310e-05, 2.51642393e-05, + 2.11051699e-05, 1.89350154e-05, 1.69710618e-05, 2.52123031e-05, 2.60242062e-05, 2.60469965e-05, + 2.65541819e-05, 2.61528279e-05, 2.42714993e-05, 2.30245421e-05, 2.27373126e-05, 2.25091425e-05, + 2.48576270e-05, 2.55659495e-05, 2.53250186e-05, 2.51889530e-05, 2.51558193e-05, 2.49220042e-05, + 2.42962968e-05, 2.33089773e-05, 2.30538237e-05, 2.29622393e-05, 2.24615029e-05, 2.57940945e-05, + 2.62276201e-05, 2.58026642e-05, 2.56729619e-05, 2.53215060e-05, 2.45970064e-05, 2.32630224e-05, + 2.21387090e-05, 2.17350299e-05, 2.61254359e-05, 2.58568140e-05, 2.60631939e-05, 2.60359657e-05, + 2.42653523e-05, 2.29967704e-05, 2.23045542e-05, 2.20669758e-05, 2.20567211e-05, 2.61421237e-05, + 2.72725433e-05, 2.64991448e-05, 2.62158596e-05, 2.48711293e-05, 2.40157484e-05, 2.35544409e-05, + 2.28704608e-05, 2.20057816e-05, 2.39464908e-05, 2.59650367e-05, 2.63131918e-05, 2.53573758e-05, + 2.60270388e-05, 2.53337656e-05, 2.27968925e-05, 2.13913342e-05, 2.16410268e-05, 2.56564297e-05, + 2.63060548e-05, 2.66578650e-05, 2.65312837e-05, 2.45953167e-05, 2.23794896e-05, 2.15384949e-05, + 2.18999870e-05, 2.54393838e-05, 2.61814050e-05, 2.68878711e-05, 2.63108625e-05, 2.36094965e-05, + 2.15716410e-05, 2.15943409e-05, 2.21467703e-05, 2.63921068e-05, 2.59940113e-05, 2.71939754e-05, + 2.64580214e-05, 2.44152031e-05, 2.26593718e-05, 2.20601548e-05, 2.61758232e-05, 2.71933140e-05, + 2.69096444e-05, 2.59324011e-05, 2.43803603e-05, 2.26079427e-05, 2.20671064e-05, 2.22636795e-05, + 2.59889028e-05, 2.68957251e-05, 2.67705642e-05, 2.62207418e-05, 2.50536651e-05, 2.38421276e-05, + 2.27817334e-05, 2.23343288e-05, 2.57595384e-05, 2.64795500e-05, 2.63967649e-05, 2.65506076e-05, + 2.59304000e-05, 2.44092075e-05, 2.28817257e-05, 2.21609763e-05, 2.22366413e-05, 2.67809478e-05, + 2.83629377e-05, 2.62032494e-05, 2.53550561e-05, 2.46278579e-05, 2.24466706e-05, 2.17645618e-05, + 2.23653705e-05, 2.63667613e-05, 2.73236496e-05, 2.70299877e-05, 2.58451057e-05, 2.49017295e-05, + 2.37999012e-05, 2.27157680e-05, 2.24220993e-05, 2.65943127e-05, 2.72557573e-05, 2.62949066e-05, + 2.60266635e-05, 2.51035866e-05, 2.33499257e-05, 2.22513157e-05, 2.24266608e-05, 2.55293644e-05, + 2.65858049e-05, 2.66454792e-05, 2.65626280e-05, 2.55608806e-05, 2.39993532e-05, 2.25084919e-05, + 2.24936574e-05, 2.26674405e-05, 2.61371443e-05, 2.68211837e-05, 2.57149631e-05, 2.58852724e-05, + 2.48982785e-05, 2.32631973e-05, 2.17507698e-05, 2.14908493e-05, 2.20343708e-05, 2.71226265e-05, + 2.82417608e-05, 2.73312086e-05, 2.59714537e-05, 2.36100112e-05, 2.24506470e-05, 2.19299272e-05, + 2.15391301e-05, 2.55446312e-05, 2.71162701e-05, 2.73817779e-05, 2.65689011e-05, 2.54876350e-05, + 2.40935678e-05, 2.29155299e-05, 2.26921151e-05, 2.75506570e-05, 2.78270817e-05, 2.65253789e-05, + 2.46412174e-05, 2.24713356e-05, 2.23532651e-05, 2.24969491e-05, 2.61563525e-05, 2.73042990e-05, + 2.69333323e-05, 2.62421937e-05, 2.48250516e-05, 2.34861357e-05, 2.28209902e-05, 2.21388653e-05, + 2.52196950e-05, 2.84947936e-05, 2.91087159e-05, 2.87039162e-05, 2.64972304e-05, 2.27159912e-05, + 2.06278846e-05, 2.02384547e-05, 1.99847374e-05, 2.45004847e-05, 2.66663211e-05, 2.59450364e-05, + 2.50758016e-05, 2.49254783e-05, 2.44073540e-05, 2.28029885e-05, 2.10113061e-05, 2.07455131e-05, + 2.07086060e-05, 1.98850182e-05, 2.65073456e-05, 2.85280217e-05, 2.76910557e-05, 2.60898788e-05, + 2.49259432e-05, 2.37659802e-05, 2.12552772e-05, 1.93119744e-05, 1.86833739e-05, 2.82123864e-05, + 3.09242196e-05, 2.98696852e-05, 2.61786880e-05, 2.22887176e-05, 2.05217352e-05, 1.96429769e-05, + 1.92567553e-05, 1.92263730e-05, 2.61435391e-05, 3.02825893e-05, 2.99635505e-05, 2.72097743e-05, + 2.38669161e-05, 2.27065333e-05, 2.21755165e-05, 2.07791632e-05, 1.92278617e-05, 2.19315424e-05, + 2.58912800e-05, 2.95814110e-05, 3.00516118e-05, 2.91568188e-05, 2.52641170e-05, 2.02843811e-05, + 1.82108645e-05, 1.86225108e-05, 2.72405030e-05, 3.06510424e-05, 3.05388198e-05, 2.78248844e-05, + 2.31590535e-05, 1.94913775e-05, 1.83212048e-05, 1.89629392e-05, 2.77048600e-05, 3.11202405e-05, + 3.09934592e-05, 2.72326392e-05, 2.14081873e-05, 1.83469284e-05, 1.85228099e-05, 1.93877639e-05, + 2.96972333e-05, 3.20117668e-05, 3.07156207e-05, 2.67484935e-05, 2.30511238e-05, 2.04372484e-05, + 1.94264651e-05, 2.73268104e-05, 3.02784483e-05, 3.01062762e-05, 2.78107544e-05, 2.36253536e-05, + 2.01041942e-05, 1.92447505e-05, 1.95743508e-05, 2.67189536e-05, 2.93511896e-05, 2.90691323e-05, + 2.72765137e-05, 2.48835579e-05, 2.26915504e-05, 2.05336597e-05, 1.96889904e-05, 2.60917597e-05, + 2.87410099e-05, 2.85516265e-05, 2.81669771e-05, 2.67394658e-05, 2.35517869e-05, 2.06794846e-05, + 1.94209444e-05, 1.95308949e-05, 2.68869074e-05, 3.20299588e-05, 3.18900992e-05, 2.95499943e-05, + 2.52465465e-05, 2.00886223e-05, 1.88366416e-05, 2.00224007e-05, 2.81062304e-05, 3.11680650e-05, + 2.93689454e-05, 2.58236721e-05, 2.41216122e-05, 2.22976864e-05, 2.03151917e-05, 1.98042635e-05, + 2.65645410e-05, 2.95994325e-05, 2.97527141e-05, 2.77445655e-05, 2.48554887e-05, 2.14568462e-05, + 1.96085082e-05, 1.98214044e-05, 2.56587975e-05, 2.88984663e-05, 2.92908875e-05, 2.78869101e-05, + 2.52517394e-05, 2.24037184e-05, 1.99091173e-05, 2.00163901e-05, 2.04777658e-05, 2.64884752e-05, + 3.03111089e-05, 3.00872990e-05, 2.78371353e-05, 2.39951114e-05, 2.09611721e-05, 1.87014196e-05, + 1.83533526e-05, 1.92095231e-05, 2.86791199e-05, 3.18814581e-05, 3.05247746e-05, 2.66181383e-05, + 2.18461747e-05, 2.04186363e-05, 1.94526013e-05, 1.85416098e-05, 2.61694723e-05, 2.97695140e-05, + 3.02618195e-05, 2.84856433e-05, 2.59179922e-05, 2.25535324e-05, 2.05222659e-05, 2.03786822e-05, + 3.01298102e-05, 3.31873953e-05, 2.97439114e-05, 2.41534234e-05, 1.98837452e-05, 1.97079999e-05, + 2.00287759e-05, 2.64329465e-05, 2.97941511e-05, 3.04087375e-05, 2.86571312e-05, 2.47904790e-05, + 2.19793875e-05, 2.06078550e-05, 1.93375194e-05, 2.44914264e-05, 2.15656282e-05, 2.08155996e-05, + 2.29726715e-05, 2.56598353e-05, 2.69054531e-05, 2.72509769e-05, 2.70058524e-05, 2.65646554e-05, + 2.46399653e-05, 2.29397841e-05, 2.33979315e-05, 2.47281662e-05, 2.49451271e-05, 2.51785462e-05, + 2.67436955e-05, 2.75176941e-05, 2.69298760e-05, 2.64753349e-05, 2.66884000e-05, 2.41190010e-05, + 2.21614373e-05, 2.20451144e-05, 2.45030022e-05, 2.57227550e-05, 2.53437366e-05, 2.62017311e-05, + 2.71186796e-05, 2.73200520e-05, 2.23051012e-05, 1.84071984e-05, 1.99612563e-05, 2.58944825e-05, + 2.85608766e-05, 2.75456870e-05, 2.67065504e-05, 2.68545710e-05, 2.69320274e-05, 2.64846975e-05, + 2.29637806e-05, 2.10491431e-05, 2.43842658e-05, 2.64674704e-05, 2.54932530e-05, 2.47069402e-05, + 2.56159112e-05, 2.65425328e-05, 2.78989980e-05, 2.62872572e-05, 2.09891022e-05, 1.80393713e-05, + 2.06981147e-05, 2.49234837e-05, 2.72180205e-05, 2.71954154e-05, 2.68958776e-05, 2.22719564e-05, + 1.97556820e-05, 2.08093854e-05, 2.44201904e-05, 2.72566552e-05, 2.80749939e-05, 2.78057170e-05, + 2.71017475e-05, 2.08738711e-05, 1.89879938e-05, 2.09188543e-05, 2.47191939e-05, 2.78504813e-05, + 2.79414824e-05, 2.70752096e-05, 2.67943363e-05, 2.10716433e-05, 1.78051035e-05, 2.21304027e-05, + 2.64507228e-05, 2.65783944e-05, 2.56403832e-05, 2.59900470e-05, 2.39998748e-05, 2.27174418e-05, + 2.20743377e-05, 2.22891068e-05, 2.46736053e-05, 2.67105663e-05, 2.69168437e-05, 2.67400030e-05, + 2.44702916e-05, 2.31128629e-05, 2.31301135e-05, 2.42716066e-05, 2.45865145e-05, 2.46411244e-05, + 2.60265134e-05, 2.67018635e-05, 2.48667120e-05, 2.26643040e-05, 2.26814949e-05, 2.38616052e-05, + 2.41924185e-05, 2.50141787e-05, 2.60748882e-05, 2.67353863e-05, 2.67533596e-05, 2.76656048e-05, + 2.39911949e-05, 1.83592789e-05, 1.85032759e-05, 2.21060195e-05, 2.56991701e-05, 2.67151269e-05, + 2.54520848e-05, 2.33024947e-05, 2.19402190e-05, 2.35410123e-05, 2.58903849e-05, 2.58658150e-05, + 2.56330350e-05, 2.65116577e-05, 2.67862536e-05, 2.76026751e-05, 2.39537106e-05, 2.07276450e-05, + 2.27162664e-05, 2.48800683e-05, 2.59720588e-05, 2.64880246e-05, 2.67379691e-05, 2.48573620e-05, + 2.27752942e-05, 2.23847076e-05, 2.44230643e-05, 2.60160715e-05, 2.64062732e-05, 2.69114008e-05, + 2.63164329e-05, 2.55319884e-05, 2.56102850e-05, 2.15457927e-05, 1.88511739e-05, 2.20914353e-05, + 2.62201567e-05, 2.74218220e-05, 2.73472298e-05, 2.71940862e-05, 2.68482794e-05, 2.50902147e-05, + 2.38091431e-05, 2.28079404e-05, 2.46102284e-05, 2.61013433e-05, 2.44732543e-05, 2.50183523e-05, + 2.65301004e-05, 2.38113946e-05, 2.32095688e-05, 2.33494231e-05, 2.33784024e-05, 2.41040402e-05, + 2.64313230e-05, 2.69652141e-05, 2.60849859e-05, 2.41261829e-05, 2.10561429e-05, 2.14001384e-05, + 2.45205603e-05, 2.67643314e-05, 2.67478944e-05, 2.62842454e-05, 2.58284282e-05, 2.38082702e-05, + 2.17508049e-05, 2.20182888e-05, 2.38107789e-05, 2.49570471e-05, 2.59770961e-05, 2.69882068e-05, + 2.33781273e-05, 1.78015311e-05, 1.66254280e-05, 1.94756098e-05, 2.42255477e-05, 2.87078942e-05, + 3.10878381e-05, 3.10595193e-05, 3.05788711e-05, 2.40440404e-05, 2.04376902e-05, 2.14414800e-05, + 2.38015594e-05, 2.42051103e-05, 2.48804638e-05, 2.83893281e-05, 3.11595351e-05, 3.04561610e-05, + 2.97559194e-05, 3.08794507e-05, 2.21059706e-05, 1.85317100e-05, 1.87675092e-05, 2.28705100e-05, + 2.53176068e-05, 2.55624763e-05, 2.88335289e-05, 3.21735721e-05, 3.31865782e-05, 1.88566598e-05, + 1.31973594e-05, 1.53184705e-05, 2.47495745e-05, 3.16567423e-05, 3.16710318e-05, 3.11476686e-05, + 3.17856909e-05, 3.19475441e-05, 2.56022739e-05, 1.87566969e-05, 1.65688288e-05, 2.20741127e-05, + 2.71527979e-05, 2.65601506e-05, 2.57702024e-05, 2.83158163e-05, 3.12905180e-05, 3.09286831e-05, + 2.54866520e-05, 1.66466918e-05, 1.30601658e-05, 1.64643602e-05, 2.39589383e-05, 3.13635513e-05, + 3.34972431e-05, 3.25246661e-05, 1.92735531e-05, 1.48040095e-05, 1.60662680e-05, 2.17902786e-05, + 2.88887030e-05, 3.36002278e-05, 3.44345660e-05, 3.25113480e-05, 1.72815870e-05, 1.37806283e-05, + 1.60264956e-05, 2.25114829e-05, 3.13269237e-05, 3.46417591e-05, 3.29414920e-05, 3.15505770e-05, + 1.67001109e-05, 1.22253923e-05, 1.75654831e-05, 2.51697993e-05, 2.79404900e-05, 2.86559634e-05, + 3.01701210e-05, 2.14976907e-05, 1.84566647e-05, 1.77454219e-05, 1.90232808e-05, 2.46769372e-05, + 3.07038741e-05, 3.19029546e-05, 3.12717354e-05, 2.24633351e-05, 1.93540766e-05, 1.95052032e-05, + 2.18869358e-05, 2.37223593e-05, 2.52886099e-05, 2.91911144e-05, 3.10942702e-05, 2.33715562e-05, + 1.90682444e-05, 1.91771489e-05, 2.08796588e-05, 2.20756014e-05, 2.52279603e-05, 2.91379023e-05, + 3.14182062e-05, 3.13375315e-05, 2.67837890e-05, 1.92643221e-05, 1.28547585e-05, 1.37453759e-05, + 2.00723871e-05, 2.90661386e-05, 3.19873015e-05, 2.87253673e-05, 2.01844178e-05, 1.71605542e-05, + 1.98849483e-05, 2.49688835e-05, 2.60789046e-05, 2.70884930e-05, 3.01782233e-05, 3.11204834e-05, + 2.69082017e-05, 2.02986790e-05, 1.62670440e-05, 1.96036889e-05, 2.41574888e-05, 2.82989003e-05, + 3.08185689e-05, 3.10236510e-05, 2.36208114e-05, 1.91361524e-05, 1.84723290e-05, 2.17612083e-05, + 2.55211995e-05, 2.81922375e-05, 3.12245338e-05, 3.01409674e-05, 2.84458626e-05, 2.41621845e-05, + 1.70261420e-05, 1.39626838e-05, 1.87586120e-05, 2.66918538e-05, 3.10513473e-05, 3.32134967e-05, + 3.33346777e-05, 3.18237534e-05, 2.22219855e-05, 1.91069783e-05, 1.84629410e-05, 2.27110325e-05, + 2.81758511e-05, 2.68077248e-05, 2.85413853e-05, 3.19849230e-05, 2.18780212e-05, 1.92860463e-05, + 1.92408340e-05, 2.00972540e-05, 2.24219354e-05, 2.81100621e-05, 3.07223526e-05, 2.94263368e-05, + 2.02681132e-05, 1.54173044e-05, 1.70770144e-05, 2.40995009e-05, 3.10061740e-05, 3.11519095e-05, + 3.00764782e-05, 2.44991568e-05, 2.00242251e-05, 1.72329408e-05, 1.82947937e-05, 2.26851942e-05, + 2.63015320e-05, 2.90449087e-05, 3.19275020e-05, 2.55236231e-05, 2.94298910e-05, 3.02193749e-05, + 2.85747524e-05, 2.54848311e-05, 2.20893071e-05, 2.02380957e-05, 2.00890079e-05, 2.01851417e-05, + 2.49499485e-05, 2.75065397e-05, 2.67573031e-05, 2.52618841e-05, 2.50094077e-05, 2.45008176e-05, + 2.22662277e-05, 2.03622194e-05, 2.05556061e-05, 2.08437870e-05, 2.00150314e-05, 2.65771466e-05, + 2.90410929e-05, 2.86951981e-05, 2.60553502e-05, 2.44559217e-05, 2.39457814e-05, 2.14737271e-05, + 1.92295137e-05, 1.85429595e-05, 2.87841945e-05, 3.24028095e-05, 3.10954380e-05, 2.51273757e-05, + 2.06371951e-05, 1.99495275e-05, 1.97976735e-05, 1.93636672e-05, 1.92839119e-05, 2.46939262e-05, + 2.93342214e-05, 3.04444730e-05, 2.67956792e-05, 2.32172069e-05, 2.30835731e-05, 2.32596213e-05, + 2.15118124e-05, 1.95551258e-05, 2.08166194e-05, 2.46750810e-05, 3.03170757e-05, 3.23066530e-05, + 3.03180813e-05, 2.52426603e-05, 1.99803092e-05, 1.82042491e-05, 1.87782547e-05, 2.82972973e-05, + 3.15292857e-05, 3.08373722e-05, 2.71133495e-05, 2.21663576e-05, 1.87351245e-05, 1.78939822e-05, + 1.89378936e-05, 2.95105038e-05, 3.21465670e-05, 3.09511850e-05, 2.65739843e-05, 2.04468639e-05, + 1.78268340e-05, 1.85666046e-05, 1.95183902e-05, 3.03143457e-05, 3.30488823e-05, 3.00692849e-05, + 2.50845832e-05, 2.25624589e-05, 2.12156694e-05, 2.01151544e-05, 2.71312255e-05, 2.94948919e-05, + 2.98405807e-05, 2.85883553e-05, 2.43317333e-05, 2.01829407e-05, 1.93102927e-05, 1.97159551e-05, + 2.64526711e-05, 2.87984713e-05, 2.86490955e-05, 2.69124219e-05, 2.52395052e-05, 2.36899428e-05, + 2.10189255e-05, 1.98400320e-05, 2.57983785e-05, 2.88038428e-05, 2.86974616e-05, 2.76854078e-05, + 2.66608292e-05, 2.40339213e-05, 2.11032720e-05, 1.95877987e-05, 1.96695659e-05, 2.43329286e-05, + 2.94250748e-05, 3.27356486e-05, 3.18558796e-05, 2.72680779e-05, 2.08846046e-05, 1.90927137e-05, + 2.10064966e-05, 2.80405297e-05, 3.03801074e-05, 2.85175881e-05, 2.49108364e-05, 2.38175477e-05, + 2.26805026e-05, 2.04968985e-05, 1.98789009e-05, 2.41813666e-05, 2.83510556e-05, 3.05606561e-05, + 2.82566793e-05, 2.50105030e-05, 2.17951652e-05, 1.99207634e-05, 1.99269357e-05, 2.55384623e-05, + 2.88061702e-05, 2.92600997e-05, 2.71452512e-05, 2.44600381e-05, 2.22091554e-05, 1.98802861e-05, + 2.03859031e-05, 2.13267966e-05, 2.55142761e-05, 3.02735494e-05, 3.18543436e-05, 2.87390525e-05, + 2.34799901e-05, 2.03881949e-05, 1.85405078e-05, 1.83337823e-05, 1.93270927e-05, 2.71098961e-05, + 2.94800134e-05, 2.95453534e-05, 2.62948030e-05, 2.20041529e-05, 2.20492198e-05, 2.08348515e-05, + 1.89581972e-05, 2.65958233e-05, 2.89333257e-05, 2.90693273e-05, 2.81854764e-05, 2.62353595e-05, + 2.23026503e-05, 2.03500384e-05, 2.08502940e-05, 2.84899099e-05, 3.16671406e-05, 3.01209583e-05, + 2.48042507e-05, 1.99610879e-05, 1.98241406e-05, 2.04189502e-05, 2.53281658e-05, 2.85431764e-05, + 3.01830992e-05, 2.92020952e-05, 2.57397545e-05, 2.29290935e-05, 2.11145978e-05, 1.93412144e-05, + 2.50942402e-05, 2.35599401e-05, 2.30900238e-05, 2.37724696e-05, 2.46984432e-05, 2.54364777e-05, + 2.56064955e-05, 2.57042389e-05, 2.58491108e-05, 2.53016479e-05, 2.45251589e-05, 2.48248196e-05, + 2.51331956e-05, 2.51695222e-05, 2.52991204e-05, 2.54529321e-05, 2.55016242e-05, 2.56860677e-05, + 2.58088248e-05, 2.58196570e-05, 2.46791182e-05, 2.36850141e-05, 2.39922674e-05, 2.48264251e-05, + 2.51246721e-05, 2.54497678e-05, 2.58065699e-05, 2.57055503e-05, 2.56291813e-05, 2.38389084e-05, + 2.12552908e-05, 2.24550981e-05, 2.47794525e-05, 2.51035614e-05, 2.55270763e-05, 2.58273149e-05, + 2.57937811e-05, 2.57688509e-05, 2.47536084e-05, 2.31695541e-05, 2.27996831e-05, 2.44609474e-05, + 2.52934101e-05, 2.56762127e-05, 2.58954081e-05, 2.60025521e-05, 2.58951108e-05, 2.53141626e-05, + 2.48331599e-05, 2.29428646e-05, 2.14730210e-05, 2.30317698e-05, 2.50734780e-05, 2.56387759e-05, + 2.56549750e-05, 2.57809605e-05, 2.42111714e-05, 2.20219935e-05, 2.24750920e-05, 2.42583123e-05, + 2.52943211e-05, 2.53752240e-05, 2.54240275e-05, 2.57125485e-05, 2.37069535e-05, 2.14597165e-05, + 2.23189961e-05, 2.44691054e-05, 2.53762436e-05, 2.53719183e-05, 2.57137936e-05, 2.58098749e-05, + 2.29195224e-05, 2.04024019e-05, 2.28036743e-05, 2.45963451e-05, 2.54382408e-05, 2.60436818e-05, + 2.60525317e-05, 2.43960774e-05, 2.31186540e-05, 2.30339952e-05, 2.39927341e-05, 2.55405414e-05, + 2.57988574e-05, 2.57735584e-05, 2.58201214e-05, 2.46252343e-05, 2.35525054e-05, 2.36616528e-05, + 2.44321620e-05, 2.51926955e-05, 2.57811628e-05, 2.59401128e-05, 2.58264909e-05, 2.48289576e-05, + 2.37030482e-05, 2.37790567e-05, 2.40914412e-05, 2.46061628e-05, 2.55331372e-05, 2.59110326e-05, + 2.58275219e-05, 2.58177644e-05, 2.44666239e-05, 2.27152783e-05, 2.07769772e-05, 2.19554386e-05, + 2.49470600e-05, 2.60714047e-05, 2.58454063e-05, 2.61394346e-05, 2.40452654e-05, 2.25688326e-05, + 2.36165832e-05, 2.48764341e-05, 2.53110472e-05, 2.57392500e-05, 2.58376618e-05, 2.57950099e-05, + 2.45493439e-05, 2.35926218e-05, 2.27847582e-05, 2.40928060e-05, 2.51918311e-05, 2.58259008e-05, + 2.58951908e-05, 2.58086070e-05, 2.49590886e-05, 2.36633615e-05, 2.34320089e-05, 2.42376881e-05, + 2.50183086e-05, 2.55851737e-05, 2.57516861e-05, 2.59164994e-05, 2.60630973e-05, 2.47022284e-05, + 2.28057714e-05, 2.18722907e-05, 2.39438408e-05, 2.52986906e-05, 2.55324909e-05, 2.56197878e-05, + 2.56629202e-05, 2.57967803e-05, 2.40179129e-05, 2.27356233e-05, 2.30429922e-05, 2.46620108e-05, + 2.57376039e-05, 2.62872864e-05, 2.63104305e-05, 2.59084748e-05, 2.47751979e-05, 2.34121460e-05, + 2.32525949e-05, 2.39168226e-05, 2.48710291e-05, 2.55544539e-05, 2.56953657e-05, 2.59430865e-05, + 2.34262468e-05, 2.14431869e-05, 2.29985945e-05, 2.54046198e-05, 2.57972147e-05, 2.58115459e-05, + 2.59243214e-05, 2.47114114e-05, 2.35015639e-05, 2.28244742e-05, 2.36021006e-05, 2.52243620e-05, + 2.59056679e-05, 2.59431366e-05, 2.57483349e-05, 2.52532565e-05, 2.44840507e-05, 2.41721611e-05, + 2.45100768e-05, 2.48360141e-05, 2.49373727e-05, 2.47626791e-05, 2.48318987e-05, 2.49936583e-05, + 2.53524054e-05, 2.50745580e-05, 2.52289214e-05, 2.52406085e-05, 2.52274828e-05, 2.52600358e-05, + 2.49870769e-05, 2.46818196e-05, 2.49005119e-05, 2.50767209e-05, 2.49326602e-05, 2.50369141e-05, + 2.45246952e-05, 2.47751916e-05, 2.50829264e-05, 2.50721091e-05, 2.53055432e-05, 2.51930871e-05, + 2.46742121e-05, 2.44727850e-05, 2.46301033e-05, 2.27814137e-05, 2.37122630e-05, 2.48492753e-05, + 2.43396353e-05, 2.46309719e-05, 2.48998106e-05, 2.47860624e-05, 2.47466798e-05, 2.47393401e-05, + 2.40384309e-05, 2.39109556e-05, 2.48538359e-05, 2.50058361e-05, 2.53690479e-05, 2.56281860e-05, + 2.53979070e-05, 2.49219047e-05, 2.45800062e-05, 2.48167334e-05, 2.40351620e-05, 2.30030572e-05, + 2.41344628e-05, 2.51748379e-05, 2.47469658e-05, 2.44357928e-05, 2.46651303e-05, 2.49180008e-05, + 2.33560092e-05, 2.36588546e-05, 2.47077573e-05, 2.48093976e-05, 2.42597176e-05, 2.41537830e-05, + 2.46272983e-05, 2.46676243e-05, 2.29210514e-05, 2.35172989e-05, 2.48166841e-05, 2.45735133e-05, + 2.40909139e-05, 2.45600867e-05, 2.48306588e-05, 2.40085462e-05, 2.20495475e-05, 2.38188183e-05, + 2.46539298e-05, 2.50280998e-05, 2.53828954e-05, 2.51834022e-05, 2.48560879e-05, 2.40210862e-05, + 2.40124428e-05, 2.47502122e-05, 2.54755561e-05, 2.49432693e-05, 2.47562081e-05, 2.48774878e-05, + 2.49546383e-05, 2.43256668e-05, 2.44084756e-05, 2.48479915e-05, 2.52978714e-05, 2.55959369e-05, + 2.52412626e-05, 2.49068723e-05, 2.50332520e-05, 2.44881688e-05, 2.45452499e-05, 2.46530904e-05, + 2.49778782e-05, 2.54085824e-05, 2.52280065e-05, 2.48610097e-05, 2.48665338e-05, 2.43811648e-05, + 2.35766188e-05, 2.23533592e-05, 2.33953057e-05, 2.54743396e-05, 2.53478087e-05, 2.47868358e-05, + 2.54396147e-05, 2.46814634e-05, 2.36410920e-05, 2.43312758e-05, 2.49064824e-05, 2.51387106e-05, + 2.53552954e-05, 2.50405235e-05, 2.48828774e-05, 2.44362917e-05, 2.42697496e-05, 2.39263512e-05, + 2.47809352e-05, 2.52507846e-05, 2.52735365e-05, 2.49901391e-05, 2.49052954e-05, 2.51158027e-05, + 2.44460729e-05, 2.43031887e-05, 2.46928035e-05, 2.49641646e-05, 2.51093666e-05, 2.48401968e-05, + 2.50983941e-05, 2.54237255e-05, 2.48456948e-05, 2.38724989e-05, 2.32956484e-05, 2.47331016e-05, + 2.50612555e-05, 2.47171461e-05, 2.44631352e-05, 2.44673770e-05, 2.47822493e-05, 2.44564408e-05, + 2.36100313e-05, 2.39516746e-05, 2.49605720e-05, 2.52241819e-05, 2.57919540e-05, 2.55796303e-05, + 2.48241663e-05, 2.51418878e-05, 2.42063570e-05, 2.40670010e-05, 2.45768974e-05, 2.51668167e-05, + 2.50961002e-05, 2.48715417e-05, 2.52123794e-05, 2.41242383e-05, 2.27501397e-05, 2.40446117e-05, + 2.54298397e-05, 2.49003437e-05, 2.48890952e-05, 2.51124058e-05, 2.48186567e-05, 2.42151038e-05, + 2.38698199e-05, 2.44735903e-05, 2.54341129e-05, 2.55735486e-05, 2.52624132e-05, 2.47370344e-05, + 2.53482287e-05, 2.57036578e-05, 2.56321172e-05, 2.57368521e-05, 2.53523764e-05, 2.43365610e-05, + 2.35618821e-05, 2.34914693e-05, 2.35324031e-05, 2.52152212e-05, 2.56487486e-05, 2.55586700e-05, + 2.52925917e-05, 2.52352175e-05, 2.51068398e-05, 2.44022296e-05, 2.36194327e-05, 2.37039344e-05, + 2.38270835e-05, 2.34542501e-05, 2.55463685e-05, 2.57268109e-05, 2.57123850e-05, 2.54590535e-05, + 2.51005383e-05, 2.49512996e-05, 2.40893666e-05, 2.30752585e-05, 2.27205178e-05, 2.57256027e-05, + 2.50134015e-05, 2.54749562e-05, 2.52718059e-05, 2.37396164e-05, 2.34285417e-05, 2.33511981e-05, + 2.31403728e-05, 2.31011699e-05, 2.51651348e-05, 2.57466992e-05, 2.56234505e-05, 2.55853211e-05, + 2.47334718e-05, 2.46797462e-05, 2.47234932e-05, 2.40965450e-05, 2.32318673e-05, 2.38208405e-05, + 2.51605793e-05, 2.56329363e-05, 2.50074888e-05, 2.56175412e-05, 2.52910844e-05, 2.34417791e-05, + 2.25364218e-05, 2.28416388e-05, 2.56991084e-05, 2.53764833e-05, 2.55633217e-05, 2.56307917e-05, + 2.43660781e-05, 2.28247112e-05, 2.23674811e-05, 2.29263707e-05, 2.56665503e-05, 2.51529345e-05, + 2.55505263e-05, 2.55542711e-05, 2.36578491e-05, 2.23300753e-05, 2.27313863e-05, 2.32164030e-05, + 2.56371279e-05, 2.46666022e-05, 2.56950491e-05, 2.52610975e-05, 2.45093988e-05, 2.39745748e-05, + 2.34925147e-05, 2.56274663e-05, 2.57385909e-05, 2.57088526e-05, 2.57169718e-05, 2.50512895e-05, + 2.35327943e-05, 2.31142603e-05, 2.33121806e-05, 2.55310825e-05, 2.57474393e-05, 2.57432029e-05, + 2.56011262e-05, 2.52848154e-05, 2.48602622e-05, 2.38972220e-05, 2.33714298e-05, 2.54128291e-05, + 2.57373514e-05, 2.57343271e-05, 2.56899042e-05, 2.55613610e-05, 2.49721479e-05, 2.39337919e-05, + 2.32498676e-05, 2.32898490e-05, 2.50608155e-05, 2.57478804e-05, 2.48749803e-05, 2.51913952e-05, + 2.55847894e-05, 2.38342856e-05, 2.30024220e-05, 2.38823734e-05, 2.57113430e-05, 2.56612105e-05, + 2.57447257e-05, 2.52194553e-05, 2.49187569e-05, 2.45422674e-05, 2.36741086e-05, 2.33907427e-05, + 2.50204869e-05, 2.57411329e-05, 2.55950753e-05, 2.57119088e-05, 2.52344907e-05, 2.42153456e-05, + 2.34076425e-05, 2.34131232e-05, 2.53574153e-05, 2.57403187e-05, 2.57349682e-05, 2.56349942e-05, + 2.51033620e-05, 2.43789137e-05, 2.33924434e-05, 2.36217347e-05, 2.40190370e-05, 2.53586133e-05, + 2.56602958e-05, 2.52258917e-05, 2.57160325e-05, 2.48169331e-05, 2.36309737e-05, 2.27193758e-05, + 2.26070923e-05, 2.31220642e-05, 2.56337122e-05, 2.57466117e-05, 2.57384586e-05, 2.55052749e-05, + 2.42982285e-05, 2.42836798e-05, 2.37987428e-05, 2.29313524e-05, 2.55430503e-05, 2.57515824e-05, + 2.57542110e-05, 2.57236320e-05, 2.54859026e-05, 2.44139073e-05, 2.36115028e-05, 2.38253005e-05, + 2.57481332e-05, 2.53999729e-05, 2.56674317e-05, 2.51756665e-05, 2.34295226e-05, 2.33642650e-05, + 2.36363415e-05, 2.53180291e-05, 2.57485266e-05, 2.56751798e-05, 2.57230796e-05, 2.53797076e-05, + 2.46172653e-05, 2.39372477e-05, 2.31302978e-05, 2.40910954e-05, 1.97174170e-05, 1.87256668e-05, + 2.08139625e-05, 2.42205542e-05, 2.75305133e-05, 2.91989473e-05, 2.93090720e-05, 2.91887587e-05, + 2.46627983e-05, 2.19349714e-05, 2.27503692e-05, 2.43693441e-05, 2.46345708e-05, 2.51453116e-05, + 2.73583988e-05, 2.91090901e-05, 2.88991690e-05, 2.86096555e-05, 2.93457555e-05, 2.30080622e-05, + 2.02197130e-05, 2.05779597e-05, 2.35668879e-05, 2.52323087e-05, 2.56875791e-05, 2.80295828e-05, + 3.00478181e-05, 3.06333447e-05, 2.05154701e-05, 1.56213489e-05, 1.75658756e-05, 2.45885515e-05, + 2.89170174e-05, 2.94681951e-05, 2.95327389e-05, 2.99126560e-05, 2.99863820e-05, 2.50449829e-05, + 1.99729370e-05, 1.84984764e-05, 2.28088475e-05, 2.64600106e-05, 2.65056485e-05, 2.62583271e-05, + 2.79372455e-05, 2.97226759e-05, 2.87309841e-05, 2.50541308e-05, 1.86384727e-05, 1.56698046e-05, + 1.85949894e-05, 2.44057679e-05, 2.94188015e-05, 3.08987183e-05, 3.04032962e-05, 2.10292451e-05, + 1.70000339e-05, 1.80012550e-05, 2.24839847e-05, 2.74807094e-05, 3.05282469e-05, 3.11973097e-05, + 3.02895009e-05, 1.95243987e-05, 1.60753905e-05, 1.78770170e-05, 2.30609788e-05, 2.90544766e-05, + 3.12607804e-05, 3.05932425e-05, 2.97770885e-05, 1.86528813e-05, 1.45766185e-05, 1.90572946e-05, + 2.46574151e-05, 2.70754217e-05, 2.82007036e-05, 2.91911710e-05, 2.24318575e-05, 1.97708381e-05, + 1.93167044e-05, 2.07234738e-05, 2.52561256e-05, 2.92036801e-05, 2.99629403e-05, 2.96051333e-05, + 2.31649876e-05, 2.05827516e-05, 2.07477887e-05, 2.26800227e-05, 2.43774522e-05, 2.58534528e-05, + 2.84138956e-05, 2.94962890e-05, 2.38535654e-05, 2.05344326e-05, 2.06516753e-05, 2.18425420e-05, + 2.29300605e-05, 2.55728255e-05, 2.83447509e-05, 2.97131877e-05, 2.96456495e-05, 2.54339946e-05, + 1.99227561e-05, 1.51481265e-05, 1.63532137e-05, 2.20591891e-05, 2.84963676e-05, 3.01262080e-05, + 2.83619159e-05, 2.14176734e-05, 1.86729377e-05, 2.09248066e-05, 2.48013563e-05, 2.58523825e-05, + 2.68890000e-05, 2.89149691e-05, 2.94706605e-05, 2.55823275e-05, 2.11350241e-05, 1.83183848e-05, + 2.11270609e-05, 2.46275800e-05, 2.77216457e-05, 2.94077154e-05, 2.94254378e-05, 2.41100033e-05, + 2.05431833e-05, 2.00036992e-05, 2.24510330e-05, 2.52480458e-05, 2.73859578e-05, 2.94801851e-05, + 2.89925966e-05, 2.80910112e-05, 2.41882973e-05, 1.87588633e-05, 1.64281405e-05, 2.05372120e-05, + 2.61966837e-05, 2.90802990e-05, 3.06375572e-05, 3.07935504e-05, 2.99427818e-05, 2.25277518e-05, + 1.98524607e-05, 1.97204759e-05, 2.33359065e-05, 2.75459956e-05, 2.73191534e-05, 2.84561292e-05, + 3.02196226e-05, 2.29586688e-05, 2.04415948e-05, 2.02997656e-05, 2.12704002e-05, 2.33496165e-05, + 2.73027590e-05, 2.90805553e-05, 2.85671065e-05, 2.09921780e-05, 1.69789161e-05, 1.89185651e-05, + 2.47901649e-05, 2.93985827e-05, 2.95139294e-05, 2.89609589e-05, 2.43859863e-05, 2.09151507e-05, + 1.88869096e-05, 2.00262861e-05, 2.38060309e-05, 2.65902799e-05, 2.83250478e-05, 2.99431670e-05, + 2.24751016e-05, 1.56203896e-05, 1.42927664e-05, 1.71312013e-05, 2.26098396e-05, 2.92889996e-05, + 3.33411561e-05, 3.36673833e-05, 3.34170380e-05, 2.35320660e-05, 1.88915079e-05, 2.02061084e-05, + 2.29682451e-05, 2.34470539e-05, 2.44103412e-05, 2.89137840e-05, 3.30706504e-05, 3.26082318e-05, + 3.19382870e-05, 3.38143954e-05, 2.05819189e-05, 1.63043713e-05, 1.68461018e-05, 2.15256405e-05, + 2.45274837e-05, 2.54772196e-05, 3.05506973e-05, 3.56779820e-05, 3.73518425e-05, 1.67317942e-05, + 1.05746990e-05, 1.28268901e-05, 2.32749919e-05, 3.24597994e-05, 3.40145558e-05, 3.43156066e-05, + 3.53408799e-05, 3.55354658e-05, 2.40975629e-05, 1.58920366e-05, 1.39710599e-05, 2.02198040e-05, + 2.69671378e-05, 2.71741127e-05, 2.67461226e-05, 3.04151440e-05, 3.48650135e-05, 3.20597505e-05, + 2.41307936e-05, 1.41627670e-05, 1.06528534e-05, 1.41244515e-05, 2.30174846e-05, 3.39286554e-05, + 3.81825667e-05, 3.67452039e-05, 1.75150655e-05, 1.21313955e-05, 1.33321172e-05, 1.96723460e-05, + 2.91374774e-05, 3.69164272e-05, 3.90031504e-05, 3.63750883e-05, 1.53994165e-05, 1.10666011e-05, + 1.31651286e-05, 2.06236973e-05, 3.28879708e-05, 3.91806718e-05, 3.72761522e-05, 3.49723585e-05, + 1.41765998e-05, 9.44749660e-06, 1.46586671e-05, 2.33620319e-05, 2.82957020e-05, 3.10510581e-05, + 3.35208144e-05, 1.96180300e-05, 1.56182110e-05, 1.50197085e-05, 1.70460051e-05, 2.46849108e-05, + 3.34333771e-05, 3.54718360e-05, 3.45074915e-05, 2.08230605e-05, 1.67744774e-05, 1.70203724e-05, + 2.00111941e-05, 2.29975934e-05, 2.59025623e-05, 3.15165920e-05, 3.42174406e-05, 2.20072830e-05, + 1.67334172e-05, 1.69076237e-05, 1.86678982e-05, 2.04418280e-05, 2.52812954e-05, 3.13377387e-05, + 3.48053441e-05, 3.46163005e-05, 2.47726451e-05, 1.57653601e-05, 1.00436804e-05, 1.14261633e-05, + 1.91763359e-05, 3.17756228e-05, 3.59725295e-05, 3.14810631e-05, 1.80365002e-05, 1.41499115e-05, + 1.72603353e-05, 2.36781672e-05, 2.57584365e-05, 2.79944284e-05, 3.27106725e-05, 3.41343622e-05, + 2.50695417e-05, 1.75542795e-05, 1.37529321e-05, 1.76295650e-05, 2.34402425e-05, 2.98501139e-05, + 3.40137382e-05, 3.40201991e-05, 2.24751617e-05, 1.67385721e-05, 1.59735304e-05, 1.96175210e-05, + 2.45315608e-05, 2.90156974e-05, 3.41401682e-05, 3.29427691e-05, 3.08003822e-05, 2.25545437e-05, + 1.42887922e-05, 1.14930485e-05, 1.67811356e-05, 2.64358848e-05, 3.30084170e-05, 3.73596550e-05, + 3.78598532e-05, 3.54267726e-05, 1.96986944e-05, 1.56744374e-05, 1.55413569e-05, 2.11090002e-05, + 2.94223203e-05, 2.91426548e-05, 3.17954657e-05, 3.62773027e-05, 2.05242721e-05, 1.65590029e-05, + 1.63422783e-05, 1.78013445e-05, 2.11775484e-05, 2.88233725e-05, 3.30721663e-05, 3.18907491e-05, + 1.73264706e-05, 1.20359786e-05, 1.45149444e-05, 2.37894829e-05, 3.39437767e-05, 3.42577220e-05, + 3.28657420e-05, 2.29019950e-05, 1.72288741e-05, 1.44494115e-05, 1.60322895e-05, 2.20230752e-05, + 2.74281325e-05, 3.13040501e-05, 3.54039900e-05, 2.28183069e-05, 1.63966874e-05, 1.51146027e-05, + 1.80431820e-05, 2.33621221e-05, 2.91893052e-05, 3.25506586e-05, 3.26876700e-05, 3.22755502e-05, + 2.37076671e-05, 1.94335348e-05, 2.06297288e-05, 2.32972909e-05, 2.37586851e-05, 2.46104141e-05, + 2.88208682e-05, 3.24657300e-05, 3.18193477e-05, 3.10777662e-05, 3.26465511e-05, 2.11831111e-05, + 1.71259388e-05, 1.75200836e-05, 2.20709445e-05, 2.49178276e-05, 2.55172309e-05, 2.98652967e-05, + 3.43199386e-05, 3.57356244e-05, 1.75119691e-05, 1.14824769e-05, 1.37004889e-05, 2.39837680e-05, + 3.24722853e-05, 3.32256560e-05, 3.30467624e-05, 3.39215011e-05, 3.41129832e-05, 2.48698986e-05, + 1.70398408e-05, 1.49243951e-05, 2.09878771e-05, 2.71585473e-05, 2.69110080e-05, 2.62426633e-05, + 2.94894372e-05, 3.33921769e-05, 3.18430889e-05, 2.48206728e-05, 1.50610569e-05, 1.14524407e-05, + 1.49461265e-05, 2.34105656e-05, 3.29970596e-05, 3.63189702e-05, 3.50380135e-05, 1.81229008e-05, + 1.30859150e-05, 1.43417892e-05, 2.05613722e-05, 2.92231585e-05, 3.57882314e-05, 3.72931737e-05, + 3.48566655e-05, 1.60095424e-05, 1.20262894e-05, 1.42369148e-05, 2.14287941e-05, 3.24798583e-05, + 3.75070212e-05, 3.55467809e-05, 3.36033226e-05, 1.50959995e-05, 1.04230375e-05, 1.57913998e-05, + 2.42633331e-05, 2.82595001e-05, 2.99934627e-05, 3.20729253e-05, 2.03736606e-05, 1.67434532e-05, + 1.60676434e-05, 1.77568225e-05, 2.46247785e-05, 3.23597876e-05, 3.40555247e-05, 3.32132229e-05, + 2.15000356e-05, 1.78002506e-05, 1.80039456e-05, 2.07817952e-05, 2.32664042e-05, 2.55604448e-05, + 3.05365571e-05, 3.29678284e-05, 2.25872165e-05, 1.76266109e-05, 1.77715804e-05, 1.95659788e-05, + 2.10976932e-05, 2.52292942e-05, 3.04202109e-05, 3.34432466e-05, 3.33048312e-05, 2.58717540e-05, + 1.72421466e-05, 1.10406184e-05, 1.21890976e-05, 1.93685210e-05, 3.05818810e-05, 3.43420604e-05, + 3.02365939e-05, 1.88751607e-05, 1.53228883e-05, 1.83275067e-05, 2.43053386e-05, 2.59517028e-05, + 2.76128402e-05, 3.16985453e-05, 3.29449483e-05, 2.60895335e-05, 1.86966738e-05, 1.46574579e-05, + 1.83588226e-05, 2.37282265e-05, 2.92130669e-05, 3.27026070e-05, 3.28317967e-05, 2.29556629e-05, + 1.76656205e-05, 1.69298217e-05, 2.05182851e-05, 2.50362302e-05, 2.87530070e-05, 3.30116165e-05, + 3.17848169e-05, 2.97486882e-05, 2.32993692e-05, 1.53229929e-05, 1.23339338e-05, 1.74833482e-05, + 2.66339959e-05, 3.23704929e-05, 3.57561235e-05, 3.60660760e-05, 3.39853167e-05, 2.08107880e-05, + 1.71134073e-05, 1.67080136e-05, 2.17781338e-05, 2.89368361e-05, 2.79844407e-05, 3.02701060e-05, + 3.44825557e-05, 2.10279409e-05, 1.76560473e-05, 1.75230324e-05, 1.87114254e-05, 2.16499342e-05, + 2.86124345e-05, 3.22007147e-05, 3.08551918e-05, 1.85657191e-05, 1.33489521e-05, 1.54630853e-05, + 2.38631348e-05, 3.27851518e-05, 3.30222126e-05, 3.17092393e-05, 2.36594951e-05, 1.83863103e-05, + 1.55119666e-05, 1.68642670e-05, 2.22071964e-05, 2.68787644e-05, 3.03480174e-05, 3.40389247e-05, + 2.41898275e-05, 2.03432237e-05, 1.94318847e-05, 2.18676139e-05, 2.52805478e-05, 2.75395084e-05, + 2.84799380e-05, 2.82896389e-05, 2.78260973e-05, 2.45025655e-05, 2.21644320e-05, 2.28078727e-05, + 2.44896602e-05, 2.47690715e-05, 2.51438310e-05, 2.73278130e-05, 2.86982475e-05, 2.80626908e-05, + 2.75270361e-05, 2.80025908e-05, 2.35243568e-05, 2.09960002e-05, 2.09964934e-05, 2.40375501e-05, + 2.56662753e-05, 2.54703545e-05, 2.70609353e-05, 2.86844266e-05, 2.91139682e-05, 2.12037532e-05, + 1.66084667e-05, 1.84012015e-05, 2.56113140e-05, 2.96122388e-05, 2.88636862e-05, 2.80910819e-05, + 2.83790100e-05, 2.84818575e-05, 2.62962682e-05, 2.16163486e-05, 1.95681511e-05, 2.36988185e-05, + 2.67592136e-05, 2.58781045e-05, 2.50742523e-05, 2.64811691e-05, 2.80080417e-05, 2.89142548e-05, + 2.61201044e-05, 1.95554262e-05, 1.63185686e-05, 1.92969424e-05, 2.46769962e-05, 2.85331220e-05, + 2.91038217e-05, 2.86130498e-05, 2.13207947e-05, 1.80801963e-05, 1.92304256e-05, 2.36313042e-05, + 2.78487071e-05, 2.97970028e-05, 2.98203568e-05, 2.87646493e-05, 1.96976416e-05, 1.72026821e-05, + 1.92887788e-05, 2.40735357e-05, 2.89925238e-05, 2.99794520e-05, 2.88621155e-05, 2.82687667e-05, + 1.96293515e-05, 1.58530960e-05, 2.06414093e-05, 2.61365596e-05, 2.70748610e-05, 2.65966325e-05, + 2.72834913e-05, 2.32444747e-05, 2.13464398e-05, 2.06667218e-05, 2.12489175e-05, 2.47210529e-05, + 2.79698306e-05, 2.84581457e-05, 2.81506450e-05, 2.38844252e-05, 2.19219477e-05, 2.19849373e-05, + 2.35597604e-05, 2.43647131e-05, 2.48828681e-05, 2.70343603e-05, 2.80726886e-05, 2.44520493e-05, + 2.15198509e-05, 2.15683857e-05, 2.29458749e-05, 2.35657586e-05, 2.51325270e-05, 2.70548924e-05, + 2.81878971e-05, 2.81789391e-05, 2.75035535e-05, 2.24850966e-05, 1.64488316e-05, 1.68730861e-05, + 2.14680449e-05, 2.67567711e-05, 2.83297420e-05, 2.64772951e-05, 2.23307448e-05, 2.03715634e-05, + 2.23934423e-05, 2.56771170e-05, 2.60016640e-05, 2.61361415e-05, 2.76737998e-05, 2.81430199e-05, + 2.74975797e-05, 2.28148207e-05, 1.92473039e-05, 2.17352541e-05, 2.47081342e-05, 2.67377482e-05, + 2.78360786e-05, 2.80799170e-05, 2.45242153e-05, 2.16183824e-05, 2.11270924e-05, 2.36237791e-05, + 2.59380448e-05, 2.70239707e-05, 2.82655148e-05, 2.75183047e-05, 2.64566647e-05, 2.52256014e-05, + 2.00608336e-05, 1.71802607e-05, 2.10250952e-05, 2.64420256e-05, 2.85964172e-05, 2.91418490e-05, + 2.90588414e-05, 2.83848036e-05, 2.42367176e-05, 2.23076779e-05, 2.14095956e-05, 2.40617041e-05, + 2.67965766e-05, 2.52079836e-05, 2.61040628e-05, 2.81897058e-05, 2.32364816e-05, 2.19644596e-05, + 2.20437797e-05, 2.23537114e-05, 2.36150732e-05, 2.70180481e-05, 2.81643429e-05, 2.71445311e-05, + 2.29220907e-05, 1.91576707e-05, 1.99812112e-05, 2.44348450e-05, 2.80946940e-05, 2.81231517e-05, + 2.74762196e-05, 2.54858307e-05, 2.26227563e-05, 2.02706039e-05, 2.08182315e-05, 2.34923102e-05, + 2.54129162e-05, 2.69561553e-05, 2.85184886e-05, 2.35880872e-05, 1.84085687e-05, 1.72876286e-05, + 2.01109045e-05, 2.46087028e-05, 2.84895513e-05, 3.04522921e-05, 3.03465211e-05, 2.98237645e-05, + 2.41487599e-05, 2.08450917e-05, 2.17572773e-05, 2.39891341e-05, 2.43691295e-05, 2.49650030e-05, + 2.81888402e-05, 3.05989855e-05, 2.98532394e-05, 2.91573391e-05, 3.00984565e-05, 2.24898899e-05, + 1.91442685e-05, 1.92926624e-05, 2.31991730e-05, 2.54762196e-05, 2.55448080e-05, 2.83525556e-05, + 3.12483476e-05, 3.21036211e-05, 1.94371613e-05, 1.39836578e-05, 1.60409276e-05, 2.50894742e-05, + 3.13415472e-05, 3.10059009e-05, 3.03120748e-05, 3.08565655e-05, 3.10086226e-05, 2.59391001e-05, + 1.95500986e-05, 1.73092674e-05, 2.25459309e-05, 2.71389518e-05, 2.63635316e-05, 2.54997333e-05, + 2.77574238e-05, 3.03659870e-05, 3.05490131e-05, 2.57865704e-05, 1.73527285e-05, 1.37807727e-05, + 1.71302969e-05, 2.41719376e-05, 3.06548447e-05, 3.23005874e-05, 3.14425757e-05, 1.97493446e-05, + 1.55870004e-05, 1.68532631e-05, 2.23365699e-05, 2.87463570e-05, 3.26894255e-05, 3.32436272e-05, + 3.15040844e-05, 1.78099793e-05, 1.45886633e-05, 1.68526467e-05, 2.29871983e-05, 3.08425852e-05, + 3.34528690e-05, 3.18279040e-05, 3.06538836e-05, 1.74171892e-05, 1.30743396e-05, 1.83862670e-05, + 2.55913813e-05, 2.77862527e-05, 2.80275369e-05, 2.93120444e-05, 2.19828268e-05, 1.92460641e-05, + 1.85101616e-05, 1.95612354e-05, 2.46475209e-05, 2.99702584e-05, 3.09688559e-05, 3.04195138e-05, + 2.28738346e-05, 2.00575116e-05, 2.01798559e-05, 2.23666326e-05, 2.38836393e-05, 2.51081128e-05, + 2.85697670e-05, 3.02691771e-05, 2.36995016e-05, 1.97053378e-05, 1.97946847e-05, 2.14621945e-05, + 2.24887518e-05, 2.51810224e-05, 2.85450013e-05, 3.05311798e-05, 3.04749924e-05, 2.72371110e-05, + 2.02414942e-05, 1.37058088e-05, 1.44321470e-05, 2.03144924e-05, 2.83630983e-05, 3.09641003e-05, + 2.80176388e-05, 2.07571412e-05, 1.80178673e-05, 2.05949680e-05, 2.52586257e-05, 2.61118942e-05, + 2.68169318e-05, 2.94960642e-05, 3.03184311e-05, 2.73143741e-05, 2.10379530e-05, 1.69860453e-05, + 2.01348377e-05, 2.43118676e-05, 2.78630887e-05, 2.99827243e-05, 3.02269621e-05, 2.38896305e-05, + 1.97902352e-05, 1.91626935e-05, 2.23148632e-05, 2.57273900e-05, 2.79245973e-05, 3.04419178e-05, + 2.94008811e-05, 2.78294686e-05, 2.45440096e-05, 1.78028101e-05, 1.46928944e-05, 1.92992782e-05, + 2.67011959e-05, 3.04822674e-05, 3.21340227e-05, 3.21741688e-05, 3.08838311e-05, 2.28746944e-05, + 2.00661239e-05, 1.92768536e-05, 2.31086288e-05, 2.78109829e-05, 2.62194218e-05, 2.77301721e-05, + 3.08979100e-05, 2.22199237e-05, 2.00327591e-05, 2.00381155e-05, 2.07120033e-05, 2.27296161e-05, + 2.78692344e-05, 3.00714656e-05, 2.87709324e-05, 2.10647993e-05, 1.64159552e-05, 1.78012741e-05, + 2.41539471e-05, 3.02224858e-05, 3.03295629e-05, 2.93401473e-05, 2.48740714e-05, 2.07815998e-05, + 1.80209192e-05, 1.89197485e-05, 2.28423172e-05, 2.59896443e-05, 2.84403703e-05, 3.10125719e-05, + 2.54830965e-05, 2.59395975e-05, 2.58972888e-05, 2.55121993e-05, 2.48082401e-05, 2.40868347e-05, + 2.35010190e-05, 2.35822642e-05, 2.38389645e-05, 2.54572439e-05, 2.59587853e-05, 2.58987804e-05, + 2.53763810e-05, 2.52752354e-05, 2.51739068e-05, 2.41983293e-05, 2.34000886e-05, 2.37549721e-05, + 2.40672554e-05, 2.37227041e-05, 2.55096263e-05, 2.57838291e-05, 2.60305900e-05, 2.53916174e-05, + 2.48655564e-05, 2.50901683e-05, 2.43554602e-05, 2.32356518e-05, 2.28646226e-05, 2.58257465e-05, + 2.52674589e-05, 2.57279376e-05, 2.47173718e-05, 2.29450753e-05, 2.32648830e-05, 2.36435168e-05, + 2.34179435e-05, 2.33496831e-05, 2.44211591e-05, 2.51186437e-05, 2.55830570e-05, 2.52963816e-05, + 2.44399316e-05, 2.49701306e-05, 2.54257937e-05, 2.46793601e-05, 2.36452257e-05, 2.33228250e-05, + 2.45338046e-05, 2.57168170e-05, 2.56123397e-05, 2.58993517e-05, 2.52648117e-05, 2.34404979e-05, + 2.27788787e-05, 2.31722354e-05, 2.60699718e-05, 2.54413745e-05, 2.54181284e-05, 2.51855846e-05, + 2.39108282e-05, 2.25744365e-05, 2.23421769e-05, 2.31331308e-05, 2.63247265e-05, 2.52349151e-05, + 2.52501937e-05, 2.51527176e-05, 2.32540829e-05, 2.22461622e-05, 2.29954165e-05, 2.35036493e-05, + 2.56667365e-05, 2.46762868e-05, 2.51727616e-05, 2.44050841e-05, 2.43239012e-05, 2.46018455e-05, + 2.41176709e-05, 2.54332619e-05, 2.51777370e-05, 2.53642446e-05, 2.59295750e-05, 2.54696317e-05, + 2.37626906e-05, 2.33670158e-05, 2.35991768e-05, 2.53290736e-05, 2.53164318e-05, 2.53792672e-05, + 2.53324419e-05, 2.54614390e-05, 2.54852574e-05, 2.43482670e-05, 2.36598210e-05, 2.52223497e-05, + 2.55926316e-05, 2.56342628e-05, 2.53346681e-05, 2.54454843e-05, 2.52778216e-05, 2.43424431e-05, + 2.35578772e-05, 2.35766885e-05, 2.37865919e-05, 2.44173772e-05, 2.48333706e-05, 2.58688933e-05, + 2.65444826e-05, 2.44902194e-05, 2.33874836e-05, 2.46538954e-05, 2.55411186e-05, 2.50658687e-05, + 2.51872811e-05, 2.47406833e-05, 2.47948128e-05, 2.48545761e-05, 2.39567030e-05, 2.36290947e-05, + 2.38278697e-05, 2.50090098e-05, 2.56960607e-05, 2.58127871e-05, 2.53128299e-05, 2.45406658e-05, + 2.37962761e-05, 2.36693190e-05, 2.52668474e-05, 2.55224486e-05, 2.55243498e-05, 2.51742563e-05, + 2.46993008e-05, 2.43722767e-05, 2.35654067e-05, 2.40275594e-05, 2.46855187e-05, 2.48327301e-05, + 2.53967532e-05, 2.56585200e-05, 2.59806655e-05, 2.45889324e-05, 2.34561920e-05, 2.28502296e-05, + 2.28368519e-05, 2.34078472e-05, 2.47851869e-05, 2.44983568e-05, 2.50897973e-05, 2.52806260e-05, + 2.45062209e-05, 2.54119550e-05, 2.48454581e-05, 2.34286302e-05, 2.56893960e-05, 2.51869757e-05, + 2.50268656e-05, 2.54349327e-05, 2.55934161e-05, 2.43716340e-05, 2.36799126e-05, 2.42754430e-05, + 2.48388631e-05, 2.44626041e-05, 2.55988878e-05, 2.55372114e-05, 2.36666154e-05, 2.36309896e-05, + 2.40539169e-05, 2.47318824e-05, 2.50100327e-05, 2.53326192e-05, 2.57860455e-05, 2.58544437e-05, + 2.52572612e-05, 2.43973779e-05, 2.33422015e-05, 2.49368006e-05, 2.23946659e-05, 2.17347889e-05, + 2.23532427e-05, 2.37350863e-05, 2.57888884e-05, 2.67768192e-05, 2.71446787e-05, 2.75809226e-05, + 2.54481834e-05, 2.39918264e-05, 2.45477865e-05, 2.49900770e-05, 2.50463080e-05, 2.53595424e-05, + 2.58160428e-05, 2.64035352e-05, 2.69225266e-05, 2.72305455e-05, 2.75493559e-05, 2.40133435e-05, + 2.24392181e-05, 2.31230552e-05, 2.42718852e-05, 2.48182505e-05, 2.57681902e-05, 2.70649787e-05, + 2.75231142e-05, 2.76406683e-05, 2.27096377e-05, 1.92933044e-05, 2.08466550e-05, 2.38983759e-05, + 2.51115024e-05, 2.66334808e-05, 2.76635150e-05, 2.77485695e-05, 2.77047268e-05, 2.37581024e-05, + 2.11413567e-05, 2.10790178e-05, 2.34444779e-05, 2.52633490e-05, 2.64600937e-05, 2.71812385e-05, + 2.77037067e-05, 2.79961529e-05, 2.56872826e-05, 2.39843721e-05, 2.13790924e-05, 1.98546183e-05, + 2.16658892e-05, 2.48007489e-05, 2.69761659e-05, 2.79321832e-05, 2.80102237e-05, 2.35148941e-05, + 2.01187933e-05, 2.05510896e-05, 2.29813558e-05, 2.53471048e-05, 2.67142881e-05, 2.73710035e-05, + 2.76954908e-05, 2.29633387e-05, 1.94111189e-05, 2.02183821e-05, 2.33833395e-05, 2.59879777e-05, + 2.72459185e-05, 2.79072213e-05, 2.77291799e-05, 2.13024421e-05, 1.80581908e-05, 2.07036799e-05, + 2.33674967e-05, 2.57396899e-05, 2.79091694e-05, 2.82893079e-05, 2.33963408e-05, 2.11192539e-05, + 2.11660054e-05, 2.30394415e-05, 2.61023122e-05, 2.74167475e-05, 2.77074296e-05, 2.76747886e-05, + 2.38020478e-05, 2.18583677e-05, 2.20757696e-05, 2.34072841e-05, 2.51707994e-05, 2.68205808e-05, + 2.76131325e-05, 2.76429735e-05, 2.42003343e-05, 2.23080328e-05, 2.24597715e-05, 2.27645768e-05, + 2.38252018e-05, 2.60413812e-05, 2.74944652e-05, 2.77560082e-05, 2.76872702e-05, 2.29262862e-05, + 1.99734989e-05, 1.84683397e-05, 2.05362252e-05, 2.52421507e-05, 2.80915963e-05, 2.80561745e-05, + 2.82894973e-05, 2.28265612e-05, 2.03238782e-05, 2.18606137e-05, 2.41444377e-05, 2.53280711e-05, + 2.66796546e-05, 2.74329353e-05, 2.75232448e-05, 2.31423896e-05, 2.16945409e-05, 2.11726518e-05, + 2.31110690e-05, 2.51158717e-05, 2.70658968e-05, 2.78373181e-05, 2.75482861e-05, 2.45234123e-05, + 2.21905581e-05, 2.18482959e-05, 2.29351019e-05, 2.45004623e-05, 2.62340894e-05, 2.73809383e-05, + 2.77311859e-05, 2.79483333e-05, 2.37526842e-05, 2.09093952e-05, 2.02243283e-05, 2.30040917e-05, + 2.52787535e-05, 2.64912864e-05, 2.76111730e-05, 2.78776675e-05, 2.77761449e-05, 2.22961107e-05, + 2.00617589e-05, 2.09435888e-05, 2.38558592e-05, 2.67465320e-05, 2.85930132e-05, 2.89344311e-05, + 2.83408761e-05, 2.43180339e-05, 2.15460370e-05, 2.11873248e-05, 2.25312599e-05, 2.44725637e-05, + 2.61265113e-05, 2.70211519e-05, 2.76703958e-05, 2.13113540e-05, 1.85957737e-05, 2.13346690e-05, + 2.57465255e-05, 2.74971125e-05, 2.76003532e-05, 2.77456709e-05, 2.37395158e-05, 2.15505700e-05, + 2.08730450e-05, 2.23185805e-05, 2.54185564e-05, 2.72157701e-05, 2.75979053e-05, 2.76093288e-05, + 2.53465966e-05, 2.50751396e-05, 2.48701716e-05, 2.49505047e-05, 2.48732406e-05, 2.46030993e-05, + 2.42363219e-05, 2.42987088e-05, 2.44843827e-05, 2.53850794e-05, 2.54262385e-05, 2.54896921e-05, + 2.52984945e-05, 2.52518147e-05, 2.52259633e-05, 2.46757013e-05, 2.41592776e-05, 2.44155774e-05, + 2.46355240e-05, 2.44024855e-05, 2.52446669e-05, 2.50492066e-05, 2.52785777e-05, 2.52247201e-05, + 2.50105539e-05, 2.52113500e-05, 2.48237851e-05, 2.40532496e-05, 2.37789282e-05, 2.51254711e-05, + 2.37832798e-05, 2.45278006e-05, 2.48435325e-05, 2.38130005e-05, 2.40674034e-05, 2.43476077e-05, + 2.41863959e-05, 2.41367647e-05, 2.46694306e-05, 2.45405424e-05, 2.46100996e-05, 2.50681596e-05, + 2.47965207e-05, 2.51852114e-05, 2.54951532e-05, 2.50544371e-05, 2.43510933e-05, 2.40899246e-05, + 2.47528379e-05, 2.47290306e-05, 2.40281881e-05, 2.48472647e-05, 2.52219921e-05, 2.41964312e-05, + 2.37125773e-05, 2.40067031e-05, 2.53750929e-05, 2.42130074e-05, 2.44007076e-05, 2.49484719e-05, + 2.44704855e-05, 2.35635918e-05, 2.33840710e-05, 2.39783162e-05, 2.53087674e-05, 2.38673929e-05, + 2.42597999e-05, 2.49952028e-05, 2.40491011e-05, 2.33112855e-05, 2.38756157e-05, 2.42481164e-05, + 2.46969455e-05, 2.31235942e-05, 2.44245495e-05, 2.46216980e-05, 2.47514454e-05, 2.50090339e-05, + 2.46869752e-05, 2.51191160e-05, 2.45494565e-05, 2.46043480e-05, 2.52304764e-05, 2.54479155e-05, + 2.44289178e-05, 2.41493543e-05, 2.43161461e-05, 2.51340651e-05, 2.47767399e-05, 2.48464045e-05, + 2.50781879e-05, 2.53602413e-05, 2.55078395e-05, 2.48334067e-05, 2.43589989e-05, 2.51344808e-05, + 2.49645490e-05, 2.50119819e-05, 2.49713898e-05, 2.51895217e-05, 2.53371171e-05, 2.48267408e-05, + 2.42871857e-05, 2.43001907e-05, 2.42340508e-05, 2.40316568e-05, 2.33737470e-05, 2.43617635e-05, + 2.58526204e-05, 2.49387282e-05, 2.41648723e-05, 2.50521172e-05, 2.50593188e-05, 2.42807855e-05, + 2.47364180e-05, 2.48807327e-05, 2.50105339e-05, 2.51264245e-05, 2.45638346e-05, 2.43360953e-05, + 2.42772165e-05, 2.46397661e-05, 2.46544197e-05, 2.52091817e-05, 2.52781614e-05, 2.49444656e-05, + 2.44572914e-05, 2.43648132e-05, 2.51934796e-05, 2.49164029e-05, 2.48321044e-05, 2.49361846e-05, + 2.48909469e-05, 2.48046797e-05, 2.42895271e-05, 2.46174459e-05, 2.50651054e-05, 2.48877550e-05, + 2.45283065e-05, 2.42361422e-05, 2.52373249e-05, 2.48866577e-05, 2.42001000e-05, 2.37682655e-05, + 2.37567851e-05, 2.41791832e-05, 2.46653041e-05, 2.40786334e-05, 2.44789010e-05, 2.51190649e-05, + 2.49107881e-05, 2.55492438e-05, 2.51919422e-05, 2.41947661e-05, 2.53667481e-05, 2.46631163e-05, + 2.45271871e-05, 2.49629407e-05, 2.53443746e-05, 2.47996050e-05, 2.43652785e-05, 2.47856716e-05, + 2.44971007e-05, 2.35298053e-05, 2.46982697e-05, 2.54542839e-05, 2.43623681e-05, 2.43381602e-05, + 2.46358512e-05, 2.48342850e-05, 2.46084785e-05, 2.45065469e-05, 2.50193892e-05, 2.55807387e-05, + 2.53971590e-05, 2.48658606e-05, 2.41310070e-05, 2.49373952e-05, 2.27818595e-05, 2.21888546e-05, + 2.31482272e-05, 2.45696338e-05, 2.58495763e-05, 2.63231408e-05, 2.64439481e-05, 2.65697930e-05, + 2.52340210e-05, 2.40445247e-05, 2.44621243e-05, 2.50203206e-05, 2.50988738e-05, 2.53100899e-05, + 2.58361099e-05, 2.61994104e-05, 2.63483808e-05, 2.64200586e-05, 2.65694625e-05, 2.43599390e-05, + 2.29758245e-05, 2.33242932e-05, 2.45914013e-05, 2.51516881e-05, 2.55491650e-05, 2.63119674e-05, + 2.65884372e-05, 2.66272709e-05, 2.31674663e-05, 2.00222958e-05, 2.14207715e-05, 2.47077289e-05, + 2.57610637e-05, 2.62927730e-05, 2.66133362e-05, 2.66529688e-05, 2.66417537e-05, 2.47558250e-05, + 2.24470032e-05, 2.18804410e-05, 2.41165824e-05, 2.55228153e-05, 2.59133225e-05, 2.60915208e-05, + 2.64948420e-05, 2.67204263e-05, 2.59398695e-05, 2.48354383e-05, 2.20364395e-05, 2.02320495e-05, + 2.21145623e-05, 2.49673308e-05, 2.63977071e-05, 2.67093222e-05, 2.67381642e-05, 2.36030303e-05, + 2.09327566e-05, 2.15019700e-05, 2.38698683e-05, 2.56983171e-05, 2.63429931e-05, 2.65310870e-05, + 2.66439610e-05, 2.28943405e-05, 2.02762833e-05, 2.13370258e-05, 2.41636464e-05, 2.60618734e-05, + 2.64901770e-05, 2.67071376e-05, 2.66429299e-05, 2.20163803e-05, 1.90868525e-05, 2.19653512e-05, + 2.45394453e-05, 2.57724041e-05, 2.65848948e-05, 2.67799283e-05, 2.39953881e-05, 2.23687869e-05, + 2.22216820e-05, 2.33464723e-05, 2.55681211e-05, 2.65210086e-05, 2.66419835e-05, 2.66199520e-05, + 2.43318601e-05, 2.29028853e-05, 2.30320378e-05, 2.40686862e-05, 2.50803067e-05, 2.59080777e-05, + 2.65181163e-05, 2.66054407e-05, 2.46391550e-05, 2.30398892e-05, 2.31302977e-05, 2.36104216e-05, + 2.42766841e-05, 2.56131570e-05, 2.64756864e-05, 2.66486528e-05, 2.66253981e-05, 2.45374570e-05, + 2.20085036e-05, 1.95122843e-05, 2.07790907e-05, 2.44749674e-05, 2.66679392e-05, 2.67490765e-05, + 2.67128457e-05, 2.35014480e-05, 2.16873969e-05, 2.30153324e-05, 2.48371366e-05, 2.54385785e-05, + 2.60425959e-05, 2.65063497e-05, 2.65680742e-05, 2.46425273e-05, 2.30239039e-05, 2.18403029e-05, + 2.35034632e-05, 2.51197696e-05, 2.62763799e-05, 2.66591797e-05, 2.65733740e-05, 2.48075213e-05, + 2.30031482e-05, 2.27017714e-05, 2.38448332e-05, 2.50492422e-05, 2.59738612e-05, 2.65253313e-05, + 2.66018587e-05, 2.65846813e-05, 2.45682083e-05, 2.19239291e-05, 2.07116125e-05, 2.32716007e-05, + 2.54837848e-05, 2.62254862e-05, 2.66183645e-05, 2.66955930e-05, 2.66620314e-05, 2.36441919e-05, + 2.20174090e-05, 2.22894558e-05, 2.43944481e-05, 2.61557772e-05, 2.66744863e-05, 2.69066884e-05, + 2.68336446e-05, 2.44460347e-05, 2.27477004e-05, 2.25744386e-05, 2.33555049e-05, 2.46008960e-05, + 2.59284353e-05, 2.63917482e-05, 2.65494792e-05, 2.28433145e-05, 2.03884722e-05, 2.21299897e-05, + 2.53567124e-05, 2.65564973e-05, 2.65934464e-05, 2.66039201e-05, 2.46086743e-05, 2.29037894e-05, + 2.19602472e-05, 2.28677594e-05, 2.50201640e-05, 2.61587976e-05, 2.65048713e-05, 2.66119840e-05, + 2.46256921e-05, 2.15885650e-05, 2.08270346e-05, 2.23538108e-05, 2.46249707e-05, 2.65665747e-05, + 2.73999933e-05, 2.74687297e-05, 2.74414485e-05, 2.49954466e-05, 2.32091183e-05, 2.37712423e-05, + 2.47950451e-05, 2.49547200e-05, 2.52690513e-05, 2.64829655e-05, 2.73381984e-05, 2.72778494e-05, + 2.71655395e-05, 2.75069069e-05, 2.39023018e-05, 2.19472793e-05, 2.22386909e-05, 2.42660626e-05, + 2.52843381e-05, 2.55988658e-05, 2.68858432e-05, 2.77922071e-05, 2.80194713e-05, 2.21704360e-05, + 1.82629356e-05, 1.98985539e-05, 2.48525794e-05, 2.71660546e-05, 2.75054146e-05, 2.75916392e-05, + 2.77509436e-05, 2.77778613e-05, 2.51051388e-05, 2.16887703e-05, 2.06183210e-05, 2.37399387e-05, + 2.59854705e-05, 2.60831636e-05, 2.59901762e-05, 2.68759343e-05, 2.76872462e-05, 2.71246013e-05, + 2.51265625e-05, 2.07409136e-05, 1.83351120e-05, 2.07259408e-05, 2.48049165e-05, 2.75053627e-05, + 2.81288896e-05, 2.79541429e-05, 2.25726721e-05, 1.94156151e-05, 2.02122005e-05, 2.35021231e-05, + 2.65126751e-05, 2.79275281e-05, 2.82000186e-05, 2.78948278e-05, 2.14824338e-05, 1.86385081e-05, + 2.00967419e-05, 2.38944838e-05, 2.72875667e-05, 2.82138071e-05, 2.80189657e-05, 2.76954557e-05, + 2.07468594e-05, 1.73205675e-05, 2.10044937e-05, 2.48543615e-05, 2.63354888e-05, 2.70120347e-05, + 2.74787661e-05, 2.34961977e-05, 2.15446860e-05, 2.12232884e-05, 2.23344871e-05, 2.53757846e-05, + 2.74389278e-05, 2.77687340e-05, 2.76222477e-05, 2.39871630e-05, 2.21622275e-05, 2.22902091e-05, + 2.36557291e-05, 2.48107790e-05, 2.57501390e-05, 2.70964493e-05, 2.75753419e-05, 2.44363077e-05, + 2.21584174e-05, 2.22491259e-05, 2.30712755e-05, 2.38412381e-05, 2.55510009e-05, 2.70580234e-05, + 2.76709076e-05, 2.76396033e-05, 2.52592336e-05, 2.15671441e-05, 1.78232835e-05, 1.89275600e-05, + 2.33601693e-05, 2.71589983e-05, 2.78508701e-05, 2.71063503e-05, 2.27933498e-05, 2.06976403e-05, + 2.23963945e-05, 2.49929568e-05, 2.56626175e-05, 2.62964369e-05, 2.73137674e-05, 2.75581458e-05, + 2.53583108e-05, 2.25268413e-05, 2.04896611e-05, 2.26151957e-05, 2.49548925e-05, 2.67371647e-05, + 2.75484314e-05, 2.75405232e-05, 2.46114434e-05, 2.21568966e-05, 2.17579291e-05, 2.34778659e-05, + 2.52721373e-05, 2.65228590e-05, 2.75542893e-05, 2.73640164e-05, 2.69619978e-05, 2.46070536e-05, + 2.08000920e-05, 1.89698780e-05, 2.22033283e-05, 2.58462460e-05, 2.73312134e-05, 2.80194042e-05, + 2.80892658e-05, 2.77643854e-05, 2.34816754e-05, 2.15248986e-05, 2.14968278e-05, 2.40969184e-05, + 2.66327401e-05, 2.66134325e-05, 2.71796524e-05, 2.79009699e-05, 2.38899430e-05, 2.20434922e-05, + 2.19201610e-05, 2.26752548e-05, 2.41443084e-05, 2.64746309e-05, 2.73632315e-05, 2.71699741e-05, + 2.24028581e-05, 1.92973917e-05, 2.09446598e-05, 2.50871798e-05, 2.75264165e-05, 2.75804106e-05, + 2.73508432e-05, 2.47229404e-05, 2.23680810e-05, 2.08916576e-05, 2.18036093e-05, 2.44810488e-05, + 2.61693525e-05, 2.70543357e-05, 2.77556228e-05, 2.51084720e-05, 2.50650283e-05, 2.48960724e-05, + 2.58222160e-05, 2.61225305e-05, 2.48622877e-05, 2.39049542e-05, 2.36192085e-05, 2.33440316e-05, + 2.48569166e-05, 2.50351834e-05, 2.49507209e-05, 2.51423512e-05, 2.51636330e-05, 2.50264980e-05, + 2.48493886e-05, 2.41926929e-05, 2.38659476e-05, 2.37001949e-05, 2.33288607e-05, 2.54889730e-05, + 2.53699076e-05, 2.50086405e-05, 2.54795113e-05, 2.54668750e-05, 2.47998188e-05, 2.38924409e-05, + 2.31442324e-05, 2.28458518e-05, 2.53246431e-05, 2.41227669e-05, 2.46908395e-05, 2.60803360e-05, + 2.51896846e-05, 2.39394915e-05, 2.32024240e-05, 2.30339035e-05, 2.30402587e-05, 2.62948969e-05, + 2.63843381e-05, 2.53058840e-05, 2.58854288e-05, 2.52608585e-05, 2.43605761e-05, 2.38203495e-05, + 2.34519115e-05, 2.29229251e-05, 2.47951020e-05, 2.61089681e-05, 2.51463997e-05, 2.36428606e-05, + 2.48509756e-05, 2.53017814e-05, 2.37099729e-05, 2.25350099e-05, 2.26872515e-05, 2.49483666e-05, + 2.48245272e-05, 2.53680450e-05, 2.61445965e-05, 2.51994746e-05, 2.35268269e-05, 2.27718281e-05, + 2.29422116e-05, 2.44382741e-05, 2.45263829e-05, 2.55740835e-05, 2.60376544e-05, 2.45068234e-05, + 2.28247582e-05, 2.26821962e-05, 2.30885684e-05, 2.52284630e-05, 2.40632360e-05, 2.61175792e-05, + 2.65424450e-05, 2.49124354e-05, 2.32838509e-05, 2.28602623e-05, 2.57650940e-05, 2.62620334e-05, + 2.58818097e-05, 2.51692856e-05, 2.44803402e-05, 2.34543439e-05, 2.30459782e-05, 2.31750406e-05, + 2.57242615e-05, 2.61245499e-05, 2.60302434e-05, 2.58634501e-05, 2.50024646e-05, 2.40390656e-05, + 2.34619670e-05, 2.32261820e-05, 2.56304628e-05, 2.56893614e-05, 2.56284785e-05, 2.60300634e-05, + 2.56142697e-05, 2.45772327e-05, 2.35538431e-05, 2.30889669e-05, 2.31552100e-05, 2.70671182e-05, + 2.74907844e-05, 2.43738882e-05, 2.37652423e-05, 2.40989739e-05, 2.31210213e-05, 2.27557294e-05, + 2.30047048e-05, 2.57530935e-05, 2.61710949e-05, 2.63329373e-05, 2.59257002e-05, 2.51581955e-05, + 2.42143351e-05, 2.35042362e-05, 2.33153200e-05, 2.69021452e-05, 2.66093668e-05, 2.50661084e-05, + 2.53457391e-05, 2.51073448e-05, 2.39169614e-05, 2.31157768e-05, 2.33096909e-05, 2.54440006e-05, + 2.57996013e-05, 2.57516087e-05, 2.61701750e-05, 2.57237154e-05, 2.45371601e-05, 2.34112610e-05, + 2.32823891e-05, 2.32685715e-05, 2.60989457e-05, 2.56811192e-05, 2.41329539e-05, 2.50846161e-05, + 2.52307427e-05, 2.41359732e-05, 2.28641217e-05, 2.26180369e-05, 2.30055990e-05, 2.67694948e-05, + 2.73512222e-05, 2.63922124e-05, 2.57421051e-05, 2.41561908e-05, 2.28750442e-05, 2.25602708e-05, + 2.25328249e-05, 2.52201202e-05, 2.63212682e-05, 2.65637762e-05, 2.59306018e-05, 2.52413888e-05, + 2.46193273e-05, 2.37586681e-05, 2.33999712e-05, 2.68832550e-05, 2.63357264e-05, 2.54145094e-05, + 2.46568218e-05, 2.33518256e-05, 2.32508257e-05, 2.32787498e-05, 2.61626577e-05, 2.66130456e-05, + 2.58197507e-05, 2.53464157e-05, 2.46464915e-05, 2.38177594e-05, 2.34843025e-05, 2.31193368e-05, + 2.51837612e-05, 2.87002221e-05, 2.93745739e-05, 2.89421500e-05, 2.65888137e-05, 2.25787184e-05, + 2.03921520e-05, 1.99769442e-05, 1.96976902e-05, 2.44153964e-05, 2.67171409e-05, 2.59433065e-05, + 2.50346105e-05, 2.48784406e-05, 2.43291412e-05, 2.26658042e-05, 2.08026796e-05, 2.05046669e-05, + 2.04513205e-05, 1.95977694e-05, 2.65655037e-05, 2.87409238e-05, 2.78226211e-05, 2.61218945e-05, + 2.48987989e-05, 2.36485258e-05, 2.10161615e-05, 1.90159232e-05, 1.83711975e-05, 2.83959325e-05, + 3.14216711e-05, 3.02208063e-05, 2.62506945e-05, 2.21819921e-05, 2.02910469e-05, 1.93462825e-05, + 1.89497016e-05, 1.89207520e-05, 2.62283890e-05, 3.06815542e-05, 3.03207836e-05, 2.73327934e-05, + 2.37877605e-05, 2.25265466e-05, 2.19426799e-05, 2.04985439e-05, 1.89093514e-05, 2.17826946e-05, + 2.59512275e-05, 2.98973590e-05, 3.04511215e-05, 2.94277575e-05, 2.52416340e-05, 2.00319752e-05, + 1.78787158e-05, 1.82937688e-05, 2.73329839e-05, 3.10933952e-05, 3.09605282e-05, 2.80029227e-05, + 2.30593427e-05, 1.92353429e-05, 1.80138514e-05, 1.86532303e-05, 2.78295663e-05, 3.16299844e-05, + 3.14666575e-05, 2.73643799e-05, 2.12304605e-05, 1.80452073e-05, 1.81967573e-05, 1.90837785e-05, + 3.00256067e-05, 3.26649971e-05, 3.11567401e-05, 2.68806634e-05, 2.29237636e-05, 2.01412089e-05, + 1.90978241e-05, 2.74528004e-05, 3.06750808e-05, 3.04807982e-05, 2.79560039e-05, 2.34811365e-05, + 1.98270695e-05, 1.89393217e-05, 1.92759790e-05, 2.68018725e-05, 2.96551653e-05, 2.93450991e-05, + 2.74031539e-05, 2.48248445e-05, 2.24874102e-05, 2.02540050e-05, 1.93940234e-05, 2.61319990e-05, + 2.89795131e-05, 2.87717951e-05, 2.83665203e-05, 2.68185095e-05, 2.34115277e-05, 2.04081858e-05, + 1.91163054e-05, 1.92312187e-05, 2.70643513e-05, 3.26299674e-05, 3.25109800e-05, 2.98818396e-05, + 2.51674307e-05, 1.97786443e-05, 1.85093500e-05, 1.97019348e-05, 2.82916470e-05, 3.16595064e-05, + 2.96797525e-05, 2.58678978e-05, 2.40421709e-05, 2.20977725e-05, 2.00409367e-05, 1.95168473e-05, + 2.67143221e-05, 2.99388432e-05, 3.00874394e-05, 2.78885510e-05, 2.48017570e-05, 2.12210338e-05, + 1.93032449e-05, 1.95331118e-05, 2.56648177e-05, 2.91536404e-05, 2.95819539e-05, 2.80705945e-05, + 2.52562114e-05, 2.22328985e-05, 1.96302438e-05, 1.97226884e-05, 2.01803121e-05, 2.65781358e-05, + 3.07064391e-05, 3.04757880e-05, 2.79828816e-05, 2.39172154e-05, 2.07469052e-05, 1.83908047e-05, + 1.80257457e-05, 1.89004552e-05, 2.89484737e-05, 3.24629970e-05, 3.09484877e-05, 2.66955757e-05, + 2.16349856e-05, 2.00874835e-05, 1.90949380e-05, 1.81978393e-05, 2.61937709e-05, 3.01171267e-05, + 3.06621206e-05, 2.87079603e-05, 2.59278194e-05, 2.23921153e-05, 2.02721894e-05, 2.00937206e-05, + 3.05255858e-05, 3.39259886e-05, 3.00775767e-05, 2.40411057e-05, 1.95989388e-05, 1.94153315e-05, + 1.97345792e-05, 2.65235321e-05, 3.01513059e-05, 3.08150862e-05, 2.88816446e-05, 2.47075082e-05, + 2.17422662e-05, 2.03301332e-05, 1.90380569e-05, 2.50103506e-05, 2.43017722e-05, 2.39897621e-05, + 2.52102576e-05, 2.60490855e-05, 2.53201269e-05, 2.46228014e-05, 2.43465626e-05, 2.40415890e-05, + 2.48476047e-05, 2.46058062e-05, 2.46460231e-05, 2.50880521e-05, 2.51513912e-05, 2.50946001e-05, + 2.52776670e-05, 2.49046605e-05, 2.45302677e-05, 2.43100591e-05, 2.40528596e-05, 2.52210310e-05, + 2.46753369e-05, 2.43753953e-05, 2.52992688e-05, 2.55531781e-05, 2.49524213e-05, 2.44101864e-05, + 2.39844040e-05, 2.37792428e-05, 2.46757968e-05, 2.27907482e-05, 2.36198882e-05, 2.60670167e-05, + 2.59034665e-05, 2.47062887e-05, 2.39544566e-05, 2.38461170e-05, 2.38656528e-05, 2.63597559e-05, + 2.56313117e-05, 2.43530672e-05, 2.55846184e-05, 2.55467067e-05, 2.46386816e-05, 2.40520517e-05, + 2.39441581e-05, 2.36982146e-05, 2.54606361e-05, 2.61730959e-05, 2.42194753e-05, 2.23416100e-05, + 2.39266822e-05, 2.52538854e-05, 2.44597050e-05, 2.35034922e-05, 2.35728813e-05, 2.43838427e-05, + 2.36645830e-05, 2.43382270e-05, 2.57910697e-05, 2.56573957e-05, 2.44703990e-05, 2.38064013e-05, + 2.38175873e-05, 2.36627740e-05, 2.32420895e-05, 2.45185700e-05, 2.57765249e-05, 2.52202128e-05, + 2.38738998e-05, 2.36015522e-05, 2.38790592e-05, 2.43012246e-05, 2.25806944e-05, 2.52275056e-05, + 2.65450322e-05, 2.52944114e-05, 2.38150812e-05, 2.35434445e-05, 2.54055285e-05, 2.54797749e-05, + 2.50377066e-05, 2.45548220e-05, 2.45617314e-05, 2.41579867e-05, 2.38674599e-05, 2.39386685e-05, + 2.54802725e-05, 2.54717231e-05, 2.54046906e-05, 2.55423686e-05, 2.49489684e-05, 2.42099814e-05, + 2.40325978e-05, 2.39727199e-05, 2.54957580e-05, 2.50365853e-05, 2.49947879e-05, 2.55758566e-05, + 2.53336204e-05, 2.47092461e-05, 2.41153848e-05, 2.38683558e-05, 2.39251799e-05, 2.72107110e-05, + 2.67101047e-05, 2.29595779e-05, 2.25563610e-05, 2.37001964e-05, 2.36965398e-05, 2.35951302e-05, + 2.35555276e-05, 2.52356024e-05, 2.52199127e-05, 2.57306482e-05, 2.59460276e-05, 2.53419435e-05, + 2.45518936e-05, 2.41600916e-05, 2.40604390e-05, 2.70686326e-05, 2.60369169e-05, 2.40938192e-05, + 2.47894015e-05, 2.50936967e-05, 2.43843629e-05, 2.38434436e-05, 2.40467964e-05, 2.53496386e-05, + 2.51461967e-05, 2.50160980e-05, 2.58112711e-05, 2.58154601e-05, 2.49628666e-05, 2.41613145e-05, + 2.39447464e-05, 2.37816427e-05, 2.60200819e-05, 2.47567634e-05, 2.29182096e-05, 2.44437508e-05, + 2.54722406e-05, 2.48408705e-05, 2.37990492e-05, 2.35709222e-05, 2.38220587e-05, 2.64206507e-05, + 2.65613841e-05, 2.55993603e-05, 2.55251574e-05, 2.45999781e-05, 2.32586387e-05, 2.31159844e-05, + 2.33803226e-05, 2.49457172e-05, 2.56430493e-05, 2.58590983e-05, 2.53879293e-05, 2.50274962e-05, + 2.50329666e-05, 2.44509353e-05, 2.39943955e-05, 2.62846756e-05, 2.51150015e-05, 2.45219224e-05, + 2.46665058e-05, 2.40857011e-05, 2.40012478e-05, 2.39356664e-05, 2.61166407e-05, 2.60054587e-05, + 2.49111719e-05, 2.46230607e-05, 2.45042661e-05, 2.41014422e-05, 2.40408083e-05, 2.39400529e-05, + 2.44894550e-05, 3.65919007e-05, 3.98572978e-05, 3.34243487e-05, 2.44091855e-05, 1.72039773e-05, + 1.40938598e-05, 1.38608477e-05, 1.40049991e-05, 2.31033182e-05, 2.99617578e-05, 2.77594759e-05, + 2.38475392e-05, 2.32439682e-05, 2.20706695e-05, 1.75256804e-05, 1.42917548e-05, 1.45896572e-05, + 1.50503909e-05, 1.37449977e-05, 2.72497191e-05, 3.51027332e-05, 3.38732281e-05, 2.58462701e-05, + 2.19760242e-05, 2.08518449e-05, 1.61050349e-05, 1.25907544e-05, 1.16408343e-05, 3.41733808e-05, + 5.16900257e-05, 4.39927927e-05, 2.35416306e-05, 1.47527917e-05, 1.36550435e-05, 1.34171805e-05, + 1.27809926e-05, 1.26669504e-05, 2.25391239e-05, 3.61860068e-05, 4.08176164e-05, 2.78627822e-05, + 1.93544849e-05, 1.90764118e-05, 1.94301134e-05, 1.61690070e-05, 1.30573241e-05, 1.50275759e-05, + 2.24889247e-05, 4.02621747e-05, 5.12098759e-05, 4.02963035e-05, 2.38019360e-05, 1.36973309e-05, + 1.11900283e-05, 1.19575640e-05, 3.25048164e-05, 4.62527656e-05, 4.26411626e-05, 2.87794644e-05, + 1.73522906e-05, 1.19109761e-05, 1.07944786e-05, 1.21797249e-05, 3.69667837e-05, 4.99228890e-05, + 4.31777321e-05, 2.72467321e-05, 1.44313670e-05, 1.07104885e-05, 1.16707250e-05, 1.30050919e-05, + 4.02431051e-05, 5.64664794e-05, 3.91419145e-05, 2.34583456e-05, 1.80775706e-05, 1.56641476e-05, + 1.38952216e-05, 2.88269854e-05, 3.68051417e-05, 3.81922188e-05, 3.34900945e-05, 2.16925998e-05, + 1.40026573e-05, 1.27046634e-05, 1.32956573e-05, 2.69093412e-05, 3.42090974e-05, 3.36819827e-05, + 2.81943244e-05, 2.37933091e-05, 2.03122269e-05, 1.53360213e-05, 1.34805882e-05, 2.51839779e-05, + 3.42320867e-05, 3.38562629e-05, 3.05030863e-05, 2.74821887e-05, 2.10404460e-05, 1.54763831e-05, + 1.31063542e-05, 1.32270027e-05, 2.17698292e-05, 3.65849732e-05, 5.39488972e-05, 4.83543963e-05, + 2.92877662e-05, 1.51145949e-05, 1.23938973e-05, 1.53157023e-05, 3.16323619e-05, 4.04910178e-05, + 3.32288346e-05, 2.30264651e-05, 2.05838373e-05, 1.82925041e-05, 1.44924866e-05, 1.35396291e-05, + 2.14282529e-05, 3.26694610e-05, 4.13683245e-05, 3.23520790e-05, 2.32462554e-05, 1.66650581e-05, + 1.36008126e-05, 1.36117187e-05, 2.45277488e-05, 3.42384153e-05, 3.59077863e-05, 2.88733337e-05, + 2.19913042e-05, 1.74154234e-05, 1.35427683e-05, 1.43162470e-05, 1.58522637e-05, 2.44811657e-05, + 4.00346769e-05, 4.82418740e-05, 3.40242720e-05, 1.98844307e-05, 1.43310657e-05, 1.16377785e-05, + 1.13605111e-05, 1.27282955e-05, 2.87899750e-05, 3.67877384e-05, 3.70038051e-05, 2.64828884e-05, + 1.70392388e-05, 1.71271619e-05, 1.50369175e-05, 1.22045849e-05, 2.73028787e-05, 3.46948748e-05, + 3.51961610e-05, 3.21066640e-05, 2.63220658e-05, 1.75882585e-05, 1.42650455e-05, 1.50589122e-05, + 3.31509985e-05, 4.68927093e-05, 3.93881317e-05, 2.27639605e-05, 1.36636175e-05, 1.34570891e-05, + 1.43680649e-05, 2.40271655e-05, 3.33235826e-05, 3.96356996e-05, 3.57035103e-05, 2.50379134e-05, + 1.87735838e-05, 1.54949696e-05, 1.27496762e-05, 2.55484719e-05, 3.19300687e-05, 3.34017294e-05, + 2.99738265e-05, 2.49056060e-05, 2.04983524e-05, 1.82869014e-05, 1.82036059e-05, 1.84661703e-05, + 2.48024080e-05, 2.87611722e-05, 2.76032414e-05, 2.51206602e-05, 2.47173231e-05, 2.40127705e-05, + 2.07622269e-05, 1.83344051e-05, 1.87562717e-05, 1.92479675e-05, 1.82298208e-05, 2.69758988e-05, + 3.10568987e-05, 3.07391984e-05, 2.61595269e-05, 2.37014904e-05, 2.32911353e-05, 2.00718939e-05, + 1.72006565e-05, 1.63712070e-05, 3.06624242e-05, 3.78976632e-05, 3.50835631e-05, 2.43850408e-05, + 1.82873178e-05, 1.78648975e-05, 1.79774791e-05, 1.74376959e-05, 1.73224591e-05, 2.36176101e-05, + 3.08325559e-05, 3.34686635e-05, 2.70777926e-05, 2.19549896e-05, 2.22234006e-05, 2.27852545e-05, + 2.03474271e-05, 1.77586752e-05, 1.87087854e-05, 2.36874143e-05, 3.33743575e-05, 3.81678846e-05, + 3.36066597e-05, 2.49984273e-05, 1.80091269e-05, 1.60324214e-05, 1.67661305e-05, 3.01205547e-05, + 3.57313352e-05, 3.40919596e-05, 2.74202751e-05, 2.04488991e-05, 1.63551096e-05, 1.55110017e-05, + 1.68796624e-05, 3.25426795e-05, 3.70772054e-05, 3.41258482e-05, 2.66377459e-05, 1.83154519e-05, + 1.53989154e-05, 1.64729379e-05, 1.76321666e-05, 3.33064003e-05, 3.91209028e-05, 3.22318960e-05, + 2.40719841e-05, 2.11648503e-05, 1.99942358e-05, 1.85917620e-05, 2.76837025e-05, 3.11799245e-05, + 3.20208883e-05, 3.04473907e-05, 2.40620274e-05, 1.84122828e-05, 1.73571039e-05, 1.78736392e-05, + 2.66358097e-05, 3.01345398e-05, 2.99547573e-05, 2.72755661e-05, 2.51677001e-05, 2.33233016e-05, + 1.96172004e-05, 1.80270220e-05, 2.56691914e-05, 3.04401269e-05, 3.03072558e-05, 2.84002295e-05, + 2.70310928e-05, 2.35488754e-05, 1.96956608e-05, 1.77303581e-05, 1.78166754e-05, 2.26930466e-05, + 3.02468634e-05, 3.82669085e-05, 3.72377608e-05, 2.90107732e-05, 1.95877991e-05, 1.71781280e-05, + 1.98253901e-05, 2.91512719e-05, 3.27114257e-05, 2.95410084e-05, 2.41411629e-05, 2.29037967e-05, + 2.16953375e-05, 1.88396138e-05, 1.80420151e-05, 2.25528689e-05, 2.90949427e-05, 3.38542539e-05, + 2.97776524e-05, 2.47513368e-05, 2.05320165e-05, 1.81926256e-05, 1.81129325e-05, 2.53743660e-05, + 3.03680136e-05, 3.11494919e-05, 2.74549318e-05, 2.35692417e-05, 2.08321988e-05, 1.80007862e-05, + 1.87837014e-05, 2.01661996e-05, 2.49637300e-05, 3.28941262e-05, 3.69039936e-05, 3.07579083e-05, + 2.23605255e-05, 1.83962611e-05, 1.63601766e-05, 1.61769127e-05, 1.73985793e-05, 2.70393475e-05, + 3.04250332e-05, 3.11728075e-05, 2.63774611e-05, 2.07203613e-05, 2.14582368e-05, 1.97962483e-05, + 1.70866616e-05, 2.71730568e-05, 3.02218179e-05, 3.02805990e-05, 2.92688060e-05, 2.65874400e-05, + 2.09287513e-05, 1.85118554e-05, 1.94011871e-05, 2.91423711e-05, 3.47552367e-05, 3.28362947e-05, + 2.46926212e-05, 1.81424677e-05, 1.79932588e-05, 1.88331458e-05, 2.46447582e-05, 2.94001442e-05, + 3.26390924e-05, 3.13420241e-05, 2.61690530e-05, 2.22821903e-05, 1.97462576e-05, 1.73684404e-05, + 2.37620267e-05, 1.84993762e-05, 1.73824069e-05, 1.89279023e-05, 2.23216203e-05, 2.73873329e-05, + 3.03936710e-05, 3.10759593e-05, 3.16271930e-05, 2.47906590e-05, 2.13718634e-05, 2.24849012e-05, + 2.40049499e-05, 2.42476271e-05, 2.49975440e-05, 2.72824647e-05, 2.97340422e-05, 3.03112308e-05, + 3.04907031e-05, 3.17469718e-05, 2.19714717e-05, 1.87630271e-05, 1.96959558e-05, 2.26076288e-05, + 2.43434253e-05, 2.59250934e-05, 2.96841726e-05, 3.24972625e-05, 3.34021781e-05, 1.91973228e-05, + 1.38726399e-05, 1.60278216e-05, 2.27482217e-05, 2.76311980e-05, 3.04535611e-05, 3.21327117e-05, + 3.27018947e-05, 3.27176216e-05, 2.28534078e-05, 1.72335515e-05, 1.66008697e-05, 2.11729492e-05, + 2.58071315e-05, 2.74993214e-05, 2.83198923e-05, 3.05532323e-05, 3.28795050e-05, 2.83009776e-05, + 2.31478255e-05, 1.69698515e-05, 1.44308438e-05, 1.72588263e-05, 2.37842884e-05, 3.09310373e-05, + 3.42323988e-05, 3.37222382e-05, 2.03589200e-05, 1.51001044e-05, 1.58739279e-05, 2.04512495e-05, + 2.67217863e-05, 3.17660034e-05, 3.36896607e-05, 3.30651614e-05, 1.90508608e-05, 1.41176224e-05, + 1.54904050e-05, 2.12343545e-05, 2.90549692e-05, 3.35654461e-05, 3.37922509e-05, 3.25137546e-05, + 1.68939512e-05, 1.24325839e-05, 1.64128751e-05, 2.21230506e-05, 2.69439002e-05, 3.11199461e-05, + 3.27466999e-05, 2.09172555e-05, 1.71290918e-05, 1.70013696e-05, 1.96668674e-05, 2.60678045e-05, + 3.13870131e-05, 3.26944675e-05, 3.22316185e-05, 2.17998840e-05, 1.82724387e-05, 1.85866808e-05, + 2.10600522e-05, 2.42436403e-05, 2.74942265e-05, 3.08790894e-05, 3.20596740e-05, 2.26861337e-05, + 1.87532605e-05, 1.89757104e-05, 1.98779771e-05, 2.16989676e-05, 2.62126015e-05, 3.06304314e-05, + 3.24834825e-05, 3.22971216e-05, 2.20439170e-05, 1.59713404e-05, 1.29599539e-05, 1.53131681e-05, + 2.29588903e-05, 3.16970590e-05, 3.34555113e-05, 3.18660181e-05, 1.97459607e-05, 1.58762555e-05, + 1.84238442e-05, 2.31926763e-05, 2.54495947e-05, 2.81212507e-05, 3.11096534e-05, 3.18423729e-05, + 2.24101565e-05, 1.83309533e-05, 1.66333916e-05, 1.99370285e-05, 2.43335116e-05, 2.94026127e-05, + 3.22691360e-05, 3.18321900e-05, 2.32469943e-05, 1.86255171e-05, 1.80161826e-05, 2.03798267e-05, + 2.39390605e-05, 2.79005891e-05, 3.16289667e-05, 3.16531698e-05, 3.10719846e-05, 2.23244884e-05, + 1.65184309e-05, 1.50247064e-05, 1.95415651e-05, 2.56327806e-05, 2.98380749e-05, 3.33588506e-05, + 3.40021362e-05, 3.27815906e-05, 1.96691974e-05, 1.60372928e-05, 1.69208212e-05, 2.19610917e-05, + 2.87781311e-05, 3.13101262e-05, 3.29716245e-05, 3.40388368e-05, 2.23181186e-05, 1.78672012e-05, + 1.74160533e-05, 1.93378147e-05, 2.27318098e-05, 2.76770473e-05, 3.06465614e-05, 3.11199480e-05, + 1.78429783e-05, 1.35954046e-05, 1.70284979e-05, 2.52690633e-05, 3.17223961e-05, 3.20118341e-05, + 3.16423630e-05, 2.24257090e-05, 1.80744525e-05, 1.65276624e-05, 1.85454553e-05, 2.42030398e-05, + 2.86403904e-05, 3.07682123e-05, 3.25135836e-05, 2.32398710e-05, 1.72430927e-05, 1.60217536e-05, + 1.80962177e-05, 2.23308768e-05, 2.81330502e-05, 3.16300116e-05, 3.22199744e-05, 3.25146426e-05, + 2.43102401e-05, 2.03343682e-05, 2.15534215e-05, 2.35826660e-05, 2.39196059e-05, 2.47711601e-05, + 2.79296550e-05, 3.10743665e-05, 3.13175171e-05, 3.12053519e-05, 3.27382504e-05, 2.13616787e-05, + 1.76756128e-05, 1.84760552e-05, 2.21286766e-05, 2.43754084e-05, 2.57802061e-05, 3.01567988e-05, + 3.39148121e-05, 3.51320675e-05, 1.81160469e-05, 1.23738288e-05, 1.45995758e-05, 2.28540741e-05, + 2.93793166e-05, 3.19038567e-05, 3.31829826e-05, 3.39402767e-05, 3.40194827e-05, 2.32137010e-05, + 1.65416038e-05, 1.54084729e-05, 2.07043020e-05, 2.62343936e-05, 2.74549187e-05, 2.78432784e-05, + 3.06983520e-05, 3.38958445e-05, 2.97213275e-05, 2.34259049e-05, 1.57138633e-05, 1.27397916e-05, + 1.58781247e-05, 2.34547071e-05, 3.22095843e-05, 3.60064075e-05, 3.51466151e-05, 1.91563282e-05, + 1.37514427e-05, 1.47050505e-05, 2.00291735e-05, 2.76196014e-05, 3.38197393e-05, 3.59007841e-05, + 3.45561402e-05, 1.74984556e-05, 1.27229722e-05, 1.44006254e-05, 2.08922650e-05, 3.05337693e-05, + 3.58715674e-05, 3.53811741e-05, 3.36795346e-05, 1.56719770e-05, 1.10465282e-05, 1.55540821e-05, + 2.24601971e-05, 2.74800751e-05, 3.13147495e-05, 3.33221930e-05, 2.03147928e-05, 1.63724638e-05, + 1.60653352e-05, 1.85354615e-05, 2.55825385e-05, 3.23541140e-05, 3.39810108e-05, 3.33194159e-05, + 2.13382722e-05, 1.75402404e-05, 1.78348428e-05, 2.05534877e-05, 2.37510338e-05, 2.69804766e-05, + 3.13204010e-05, 3.30976005e-05, 2.23572617e-05, 1.78337175e-05, 1.80422173e-05, 1.92848140e-05, + 2.11313449e-05, 2.58999478e-05, 3.10861182e-05, 3.35996268e-05, 3.34033281e-05, 2.28850137e-05, + 1.56724251e-05, 1.16071989e-05, 1.35909565e-05, 2.14529848e-05, 3.19712491e-05, 3.46884628e-05, + 3.19773940e-05, 1.89639548e-05, 1.50205362e-05, 1.78184263e-05, 2.32969056e-05, 2.55623331e-05, + 2.81725248e-05, 3.19064037e-05, 3.29173173e-05, 2.32394945e-05, 1.78653770e-05, 1.53428689e-05, + 1.89323089e-05, 2.39740473e-05, 2.97128116e-05, 3.31705563e-05, 3.28700248e-05, 2.28999060e-05, + 1.77538748e-05, 1.70741364e-05, 1.99621562e-05, 2.41038934e-05, 2.83897663e-05, 3.27708075e-05, + 3.23635708e-05, 3.11903063e-05, 2.23131457e-05, 1.54800644e-05, 1.34457964e-05, 1.83532020e-05, + 2.59279066e-05, 3.11260314e-05, 3.51041037e-05, 3.57318540e-05, 3.40260749e-05, 1.95203969e-05, + 1.56835170e-05, 1.62098552e-05, 2.15494169e-05, 2.91338865e-05, 3.07283277e-05, 3.28383875e-05, + 3.52027237e-05, 2.15660928e-05, 1.71982552e-05, 1.68258610e-05, 1.86120102e-05, 2.20808136e-05, + 2.81686140e-05, 3.17129339e-05, 3.16199711e-05, 1.74626340e-05, 1.27783535e-05, 1.58883496e-05, + 2.47214259e-05, 3.27668240e-05, 3.30785735e-05, 3.23285566e-05, 2.25045280e-05, 1.75790934e-05, + 1.55474989e-05, 1.74326963e-05, 2.33581076e-05, 2.83113315e-05, 3.11679330e-05, 3.38307528e-05, + 2.51620777e-05, 2.49941620e-05, 2.48013332e-05, 2.55496205e-05, 2.58100107e-05, 2.48505373e-05, + 2.40634633e-05, 2.38625808e-05, 2.36940898e-05, 2.49896351e-05, 2.50915184e-05, 2.50555839e-05, + 2.51805464e-05, 2.51895891e-05, 2.50877101e-05, 2.48557446e-05, 2.42616892e-05, 2.40718619e-05, + 2.39929362e-05, 2.36657745e-05, 2.54073904e-05, 2.52253233e-05, 2.50144415e-05, 2.54043481e-05, + 2.53690959e-05, 2.49209699e-05, 2.41750103e-05, 2.34535882e-05, 2.31701052e-05, 2.52146679e-05, + 2.39058311e-05, 2.45451504e-05, 2.57770364e-05, 2.49226966e-05, 2.40533610e-05, 2.35590351e-05, + 2.33981990e-05, 2.33926299e-05, 2.59004529e-05, 2.58507665e-05, 2.50414889e-05, 2.56584832e-05, + 2.51811809e-05, 2.45935639e-05, 2.42485467e-05, 2.38897271e-05, 2.33483346e-05, 2.46931272e-05, + 2.57831708e-05, 2.49536077e-05, 2.36050432e-05, 2.47597301e-05, 2.52830835e-05, 2.39091427e-05, + 2.29205930e-05, 2.30980810e-05, 2.49991705e-05, 2.45590483e-05, 2.50278066e-05, 2.58170837e-05, + 2.50710514e-05, 2.36357750e-05, 2.30292843e-05, 2.32852151e-05, 2.45727428e-05, 2.42358204e-05, + 2.51438382e-05, 2.57583053e-05, 2.44712431e-05, 2.30533544e-05, 2.30667003e-05, 2.34523804e-05, + 2.50074696e-05, 2.36813845e-05, 2.56083937e-05, 2.60658611e-05, 2.49172808e-05, 2.37540491e-05, + 2.33691118e-05, 2.55748145e-05, 2.57590762e-05, 2.54830771e-05, 2.51264585e-05, 2.47272676e-05, + 2.37657559e-05, 2.33995873e-05, 2.35318385e-05, 2.55596913e-05, 2.57278972e-05, 2.56778649e-05, + 2.56424228e-05, 2.50895993e-05, 2.44131053e-05, 2.38537102e-05, 2.35793277e-05, 2.55004213e-05, + 2.54491683e-05, 2.54171847e-05, 2.57268734e-05, 2.54869198e-05, 2.47799114e-05, 2.39215470e-05, + 2.34607992e-05, 2.35135514e-05, 2.63658704e-05, 2.65300380e-05, 2.39843236e-05, 2.37879688e-05, + 2.44799850e-05, 2.36170526e-05, 2.31830232e-05, 2.35510864e-05, 2.55346501e-05, 2.56049291e-05, + 2.58782527e-05, 2.56742353e-05, 2.51463761e-05, 2.44741663e-05, 2.38310478e-05, 2.36418129e-05, + 2.62581154e-05, 2.60620260e-05, 2.48699183e-05, 2.52607446e-05, 2.51532609e-05, 2.42172916e-05, + 2.35161698e-05, 2.36435263e-05, 2.53786670e-05, 2.55198343e-05, 2.54542208e-05, 2.58325443e-05, + 2.55327334e-05, 2.46510476e-05, 2.37043801e-05, 2.36747689e-05, 2.37534502e-05, 2.57955218e-05, + 2.53054259e-05, 2.40365689e-05, 2.50612452e-05, 2.51763722e-05, 2.42281496e-05, 2.31816434e-05, + 2.29929333e-05, 2.33752906e-05, 2.62101534e-05, 2.64394809e-05, 2.58366359e-05, 2.55721406e-05, + 2.43891996e-05, 2.35466723e-05, 2.32396290e-05, 2.30198079e-05, 2.52333885e-05, 2.58430086e-05, + 2.59855398e-05, 2.56411527e-05, 2.52502841e-05, 2.47108060e-05, 2.39810634e-05, 2.37974377e-05, + 2.62251804e-05, 2.55026282e-05, 2.51513750e-05, 2.48559495e-05, 2.36747763e-05, 2.35936063e-05, + 2.36757570e-05, 2.58328513e-05, 2.60530758e-05, 2.54052355e-05, 2.51972642e-05, 2.48625019e-05, + 2.42290897e-05, 2.38770005e-05, 2.34511563e-05, 2.48572816e-05, 2.32796157e-05, 2.27891076e-05, + 2.43425630e-05, 2.58661644e-05, 2.59083532e-05, 2.56089059e-05, 2.53621756e-05, 2.50343315e-05, + 2.48256386e-05, 2.40232647e-05, 2.42317389e-05, 2.49902819e-05, 2.51073356e-05, 2.51638120e-05, + 2.58281203e-05, 2.58656313e-05, 2.54487170e-05, 2.51670417e-05, 2.50811518e-05, 2.48231791e-05, + 2.37259222e-05, 2.35270389e-05, 2.50166243e-05, 2.56193822e-05, 2.51457007e-05, 2.51351907e-05, + 2.51757364e-05, 2.51101422e-05, 2.37889319e-05, 2.10700426e-05, 2.22138154e-05, 2.59650773e-05, + 2.68041987e-05, 2.57542650e-05, 2.50268616e-05, 2.50072200e-05, 2.50436727e-05, 2.63458873e-05, + 2.45452487e-05, 2.30684176e-05, 2.51198446e-05, 2.58859434e-05, 2.50222636e-05, 2.44060522e-05, + 2.46612764e-05, 2.48172581e-05, 2.63237395e-05, 2.61701753e-05, 2.29778106e-05, 2.06858237e-05, + 2.27048699e-05, 2.51549137e-05, 2.54991941e-05, 2.48983657e-05, 2.48502843e-05, 2.36290544e-05, + 2.21340504e-05, 2.29488908e-05, 2.52415645e-05, 2.62247197e-05, 2.57742264e-05, 2.52741689e-05, + 2.50668346e-05, 2.26591163e-05, 2.15634629e-05, 2.30837724e-05, 2.53541958e-05, 2.61636717e-05, + 2.53576253e-05, 2.49235089e-05, 2.50085050e-05, 2.30545401e-05, 2.06636844e-05, 2.39781109e-05, + 2.64342135e-05, 2.57805644e-05, 2.45929822e-05, 2.45450399e-05, 2.48713083e-05, 2.43628887e-05, + 2.38624960e-05, 2.37219564e-05, 2.46806194e-05, 2.51522654e-05, 2.50400174e-05, 2.50278690e-05, + 2.50995279e-05, 2.45324441e-05, 2.45067645e-05, 2.50524619e-05, 2.48605728e-05, 2.44717229e-05, + 2.48520227e-05, 2.50365393e-05, 2.52634485e-05, 2.41233241e-05, 2.41100994e-05, 2.49019105e-05, + 2.49116330e-05, 2.48887728e-05, 2.49175712e-05, 2.49832170e-05, 2.50238483e-05, 2.72481974e-05, + 2.55185075e-05, 2.11170374e-05, 2.10165990e-05, 2.32102429e-05, 2.45418730e-05, 2.48079208e-05, + 2.43749417e-05, 2.44956197e-05, 2.38872550e-05, 2.48447469e-05, 2.58976609e-05, 2.55542757e-05, + 2.50219454e-05, 2.50888244e-05, 2.51172051e-05, 2.71468622e-05, 2.51728832e-05, 2.27970128e-05, + 2.40225451e-05, 2.50511765e-05, 2.50419714e-05, 2.48888971e-05, 2.50933876e-05, 2.51813563e-05, + 2.42256007e-05, 2.39908202e-05, 2.52531690e-05, 2.58728188e-05, 2.55289998e-05, 2.52189260e-05, + 2.48948916e-05, 2.45365529e-05, 2.58315855e-05, 2.34880285e-05, 2.13519599e-05, 2.35810890e-05, + 2.57554918e-05, 2.57960708e-05, 2.51308994e-05, 2.49405614e-05, 2.49903697e-05, 2.58380021e-05, + 2.53668208e-05, 2.44607295e-05, 2.51786429e-05, 2.52125617e-05, 2.38650448e-05, 2.39664160e-05, + 2.46164199e-05, 2.45553800e-05, 2.46586357e-05, 2.48252339e-05, 2.46043797e-05, 2.47150833e-05, + 2.55783570e-05, 2.54123444e-05, 2.48486177e-05, 2.53693557e-05, 2.34188217e-05, 2.33101970e-05, + 2.46811604e-05, 2.51255982e-05, 2.50687266e-05, 2.48788826e-05, 2.59669118e-05, 2.50953357e-05, + 2.36550741e-05, 2.36372561e-05, 2.43204640e-05, 2.45238346e-05, 2.48404109e-05, 2.51073410e-05, + 2.42339780e-05, 2.03001114e-05, 1.93780751e-05, 2.15198487e-05, 2.47380085e-05, 2.73762994e-05, + 2.85925633e-05, 2.85691479e-05, 2.83203022e-05, 2.46630550e-05, 2.22557435e-05, 2.29573496e-05, + 2.45027847e-05, 2.47559627e-05, 2.51764078e-05, 2.72034297e-05, 2.86363564e-05, 2.82752753e-05, + 2.79134524e-05, 2.84693242e-05, 2.33852715e-05, 2.08418344e-05, 2.10406009e-05, 2.38923404e-05, + 2.54319090e-05, 2.55919747e-05, 2.74344223e-05, 2.90883526e-05, 2.95433197e-05, 2.10894284e-05, + 1.64714439e-05, 1.83075250e-05, 2.50665861e-05, 2.89030007e-05, 2.88801922e-05, 2.85963478e-05, + 2.88978785e-05, 2.89755913e-05, 2.55805501e-05, 2.09475522e-05, 1.93039534e-05, 2.33464198e-05, + 2.65122007e-05, 2.61800388e-05, 2.57227508e-05, 2.71492611e-05, 2.86533680e-05, 2.85337438e-05, + 2.55165253e-05, 1.93783236e-05, 1.63828730e-05, 1.92502358e-05, 2.45975303e-05, 2.87220191e-05, + 2.96636614e-05, 2.92279519e-05, 2.14198598e-05, 1.78552737e-05, 1.88863138e-05, 2.31415815e-05, + 2.74740052e-05, 2.97714930e-05, 3.00976105e-05, 2.92366920e-05, 1.99313017e-05, 1.69718480e-05, + 1.88379009e-05, 2.36323313e-05, 2.87271086e-05, 3.01921716e-05, 2.94205699e-05, 2.87873607e-05, + 1.94159536e-05, 1.55595239e-05, 2.00452039e-05, 2.53090272e-05, 2.69568171e-05, 2.73272990e-05, + 2.80962241e-05, 2.29599769e-05, 2.07274544e-05, 2.02031100e-05, 2.12226771e-05, 2.50623628e-05, + 2.83867150e-05, 2.89545969e-05, 2.86558585e-05, 2.36140346e-05, 2.14117973e-05, 2.15291723e-05, + 2.32208951e-05, 2.44565887e-05, 2.54369997e-05, 2.76139613e-05, 2.85711460e-05, 2.42121480e-05, + 2.12260278e-05, 2.13106827e-05, 2.25174121e-05, 2.33595290e-05, 2.53949657e-05, 2.75883543e-05, + 2.87232678e-05, 2.86870618e-05, 2.62569391e-05, 2.12519895e-05, 1.61314958e-05, 1.69993467e-05, + 2.20370229e-05, 2.75390280e-05, 2.89793004e-05, 2.73564034e-05, 2.20388436e-05, 1.97194032e-05, + 2.17887127e-05, 2.52067826e-05, 2.58921807e-05, 2.64810876e-05, 2.81238969e-05, 2.85877008e-05, + 2.63350552e-05, 2.20711104e-05, 1.90739115e-05, 2.16407022e-05, 2.47276963e-05, 2.71478957e-05, + 2.84305852e-05, 2.85398164e-05, 2.43785289e-05, 2.12699675e-05, 2.07730343e-05, 2.31204690e-05, + 2.55482672e-05, 2.70951118e-05, 2.86426294e-05, 2.80976749e-05, 2.72149673e-05, 2.46989607e-05, + 1.96470885e-05, 1.71664931e-05, 2.10296587e-05, 2.62483284e-05, 2.85810745e-05, 2.95567695e-05, + 2.95959074e-05, 2.89146901e-05, 2.34021428e-05, 2.11440486e-05, 2.07233449e-05, 2.37772390e-05, + 2.70837316e-05, 2.63095107e-05, 2.72446383e-05, 2.89652072e-05, 2.32429262e-05, 2.13488840e-05, + 2.12993781e-05, 2.19662640e-05, 2.36058721e-05, 2.70503431e-05, 2.84060314e-05, 2.77348857e-05, + 2.20318865e-05, 1.82629419e-05, 1.97064149e-05, 2.47023311e-05, 2.85328663e-05, 2.86004726e-05, + 2.80648418e-05, 2.49080548e-05, 2.18725616e-05, 1.98026589e-05, 2.06628886e-05, 2.37992529e-05, + 2.60315628e-05, 2.75378185e-05, 2.89699769e-05, 2.50976746e-05, 2.48429913e-05, 2.46288749e-05, + 2.55903059e-05, 2.60251734e-05, 2.49824808e-05, 2.41366758e-05, 2.38749595e-05, 2.36189882e-05, + 2.48898818e-05, 2.49359268e-05, 2.48973642e-05, 2.51393784e-05, 2.51687967e-05, 2.50620285e-05, + 2.49664127e-05, 2.44000935e-05, 2.40957075e-05, 2.39376716e-05, 2.36074158e-05, 2.53983751e-05, + 2.51479937e-05, 2.48413465e-05, 2.54140810e-05, 2.54668591e-05, 2.48730271e-05, 2.41031256e-05, + 2.34461359e-05, 2.31757607e-05, 2.51239104e-05, 2.37071799e-05, 2.43655384e-05, 2.60013535e-05, + 2.53115028e-05, 2.41726318e-05, 2.34932868e-05, 2.33424192e-05, 2.33491965e-05, 2.62133302e-05, + 2.60477037e-05, 2.49831565e-05, 2.57490681e-05, 2.53183650e-05, 2.44954005e-05, 2.39919954e-05, + 2.36950161e-05, 2.32372293e-05, 2.49466959e-05, 2.60448127e-05, 2.48488497e-05, 2.32806196e-05, + 2.45797214e-05, 2.52860979e-05, 2.39603530e-05, 2.28895373e-05, 2.30266421e-05, 2.48110828e-05, + 2.44445146e-05, 2.50050099e-05, 2.59684443e-05, 2.52898953e-05, 2.38046558e-05, 2.31109925e-05, + 2.32617940e-05, 2.42644325e-05, 2.41055978e-05, 2.51811918e-05, 2.58985902e-05, 2.46878985e-05, + 2.31603510e-05, 2.30237040e-05, 2.33912948e-05, 2.49237099e-05, 2.35641816e-05, 2.57498853e-05, + 2.64232459e-05, 2.50168684e-05, 2.35453765e-05, 2.31714553e-05, 2.56222608e-05, 2.59252751e-05, + 2.55547564e-05, 2.49948465e-05, 2.45663487e-05, 2.37211245e-05, 2.33542092e-05, 2.34689804e-05, + 2.56190237e-05, 2.58500114e-05, 2.57743668e-05, 2.57231492e-05, 2.50120924e-05, 2.41809291e-05, + 2.37141269e-05, 2.35147330e-05, 2.55632864e-05, 2.54546034e-05, 2.54062269e-05, 2.58330119e-05, + 2.55086445e-05, 2.46655750e-05, 2.37975514e-05, 2.33908212e-05, 2.34511963e-05, 2.69272894e-05, + 2.70369472e-05, 2.38919839e-05, 2.34438531e-05, 2.40894164e-05, 2.34007029e-05, 2.30872377e-05, + 2.32905126e-05, 2.55605038e-05, 2.57722022e-05, 2.60572776e-05, 2.58689267e-05, 2.52059388e-05, + 2.43716950e-05, 2.37623925e-05, 2.35967625e-05, 2.67831651e-05, 2.63180766e-05, 2.47552536e-05, + 2.51764328e-05, 2.51171909e-05, 2.41188655e-05, 2.34113209e-05, 2.35908953e-05, 2.54040593e-05, + 2.55546315e-05, 2.54798616e-05, 2.59899962e-05, 2.57013785e-05, 2.46808541e-05, 2.36855477e-05, + 2.35588036e-05, 2.35289959e-05, 2.60024700e-05, 2.53380033e-05, 2.37802006e-05, 2.49079020e-05, + 2.52829648e-05, 2.43474330e-05, 2.31927242e-05, 2.29658185e-05, 2.33165855e-05, 2.65352643e-05, + 2.69075533e-05, 2.60391438e-05, 2.56427480e-05, 2.43348478e-05, 2.31479201e-05, 2.28806167e-05, + 2.28814829e-05, 2.51518017e-05, 2.60190408e-05, 2.62288316e-05, 2.57131631e-05, 2.51882310e-05, + 2.47541474e-05, 2.39999240e-05, 2.36598308e-05, 2.65565247e-05, 2.57948004e-05, 2.51085950e-05, + 2.47116282e-05, 2.36294331e-05, 2.35377723e-05, 2.35549041e-05, 2.60681859e-05, 2.63090360e-05, + 2.54710917e-05, 2.51155109e-05, 2.46648464e-05, 2.39989901e-05, 2.37329860e-05, 2.34218575e-05, + 2.50167027e-05, 2.44994403e-05, 2.42269493e-05, 2.54433362e-05, 2.61765699e-05, 2.52219296e-05, + 2.44046067e-05, 2.40965035e-05, 2.37615237e-05, 2.48066430e-05, 2.46860537e-05, 2.46817060e-05, + 2.50897348e-05, 2.51477195e-05, 2.50604876e-05, 2.51799533e-05, 2.47192263e-05, 2.43080827e-05, + 2.40705239e-05, 2.37710850e-05, 2.53120848e-05, 2.48828538e-05, 2.45183372e-05, 2.53684015e-05, + 2.55698949e-05, 2.48783333e-05, 2.41957947e-05, 2.36846468e-05, 2.34520742e-05, 2.48614439e-05, + 2.31610481e-05, 2.39101337e-05, 2.61778246e-05, 2.58366428e-05, 2.44922642e-05, 2.36592071e-05, + 2.35338940e-05, 2.35544347e-05, 2.64850592e-05, 2.59852122e-05, 2.46578245e-05, 2.57330961e-05, + 2.55117030e-05, 2.44972052e-05, 2.38547817e-05, 2.36824387e-05, 2.33736196e-05, 2.53462640e-05, + 2.62744280e-05, 2.44943029e-05, 2.26456001e-05, 2.41666318e-05, 2.52736797e-05, 2.42198005e-05, + 2.31464959e-05, 2.32269650e-05, 2.44962518e-05, 2.40144236e-05, 2.46854411e-05, 2.59860755e-05, + 2.56001113e-05, 2.42165291e-05, 2.34784968e-05, 2.34977202e-05, 2.37941732e-05, 2.36269830e-05, + 2.49020301e-05, 2.59343152e-05, 2.50712900e-05, 2.35526920e-05, 2.32567143e-05, 2.35721737e-05, + 2.45856827e-05, 2.30381687e-05, 2.56025459e-05, 2.67131782e-05, 2.52078849e-05, 2.35330828e-05, + 2.32121069e-05, 2.55544416e-05, 2.58293961e-05, 2.53647925e-05, 2.47100472e-05, 2.44609563e-05, + 2.38898708e-05, 2.35567429e-05, 2.36406009e-05, 2.55945228e-05, 2.57564739e-05, 2.56682024e-05, + 2.56933161e-05, 2.49336881e-05, 2.40452494e-05, 2.37681676e-05, 2.36799756e-05, 2.55735675e-05, + 2.52675299e-05, 2.52116411e-05, 2.57847044e-05, 2.54432520e-05, 2.46119191e-05, 2.38613647e-05, + 2.35613294e-05, 2.36250705e-05, 2.74274433e-05, 2.72195389e-05, 2.34053755e-05, 2.28203092e-05, + 2.36644265e-05, 2.33952163e-05, 2.32545689e-05, 2.32429033e-05, 2.54292508e-05, 2.56277487e-05, + 2.60244430e-05, 2.60311668e-05, 2.53066507e-05, 2.43873948e-05, 2.38979294e-05, 2.37772757e-05, + 2.72598372e-05, 2.63564226e-05, 2.43796736e-05, 2.49460365e-05, 2.50834825e-05, 2.41756415e-05, + 2.35388320e-05, 2.37629842e-05, 2.53960189e-05, 2.53908438e-05, 2.52847760e-05, 2.60109773e-05, + 2.58633919e-05, 2.48283075e-05, 2.38885784e-05, 2.36584006e-05, 2.34989313e-05, 2.61456003e-05, + 2.50933216e-05, 2.32230451e-05, 2.45982519e-05, 2.54385434e-05, 2.46489481e-05, 2.34738677e-05, + 2.32213980e-05, 2.35069507e-05, 2.66955111e-05, 2.70554558e-05, 2.59694938e-05, 2.56352170e-05, + 2.44199786e-05, 2.29434498e-05, 2.27571165e-05, 2.30171753e-05, 2.50057460e-05, 2.59615565e-05, + 2.62180545e-05, 2.56115522e-05, 2.50753703e-05, 2.49089833e-05, 2.42164444e-05, 2.37223767e-05, + 2.66485465e-05, 2.56724126e-05, 2.48131638e-05, 2.45985150e-05, 2.38064302e-05, 2.37111759e-05, + 2.36490147e-05, 2.62440395e-05, 2.63370069e-05, 2.52576262e-05, 2.48384740e-05, 2.44653164e-05, + 2.38977449e-05, 2.37793843e-05, 2.36370960e-05, 2.54303115e-05, 3.14544510e-05, 3.28189194e-05, + 3.00183024e-05, 2.53509471e-05, 2.07888131e-05, 1.84854077e-05, 1.83082222e-05, 1.84305503e-05, + 2.46255646e-05, 2.83696590e-05, 2.72373016e-05, 2.50571351e-05, 2.47006417e-05, 2.39959426e-05, + 2.10168253e-05, 1.86329167e-05, 1.88758318e-05, 1.92357984e-05, 1.82233622e-05, 2.69514314e-05, + 3.07939732e-05, 3.02459449e-05, 2.61860596e-05, 2.39239586e-05, 2.32413444e-05, 2.00222210e-05, + 1.72808472e-05, 1.64750153e-05, 3.03760398e-05, 3.70456981e-05, 3.44159098e-05, 2.48462906e-05, + 1.89587431e-05, 1.81336484e-05, 1.79619829e-05, 1.74429132e-05, 1.73474997e-05, 2.42380492e-05, + 3.12411506e-05, 3.31936362e-05, 2.72651649e-05, 2.22538912e-05, 2.20956719e-05, 2.23443249e-05, + 2.00804520e-05, 1.76746671e-05, 1.91846227e-05, 2.42147985e-05, 3.29765984e-05, 3.68936010e-05, + 3.29955281e-05, 2.50257219e-05, 1.81745201e-05, 1.60852391e-05, 1.67540041e-05, 2.96100533e-05, + 3.52286855e-05, 3.38979280e-05, 2.77351323e-05, 2.08826455e-05, 1.66905541e-05, 1.57232041e-05, + 1.69380747e-05, 3.16256129e-05, 3.64766540e-05, 3.40954928e-05, 2.69320797e-05, 1.87323955e-05, + 1.56453404e-05, 1.65053796e-05, 1.76273891e-05, 3.29672991e-05, 3.84760490e-05, 3.24983430e-05, + 2.47789183e-05, 2.13997536e-05, 1.97102624e-05, 1.83550583e-05, 2.77723566e-05, 3.15135613e-05, + 3.21134373e-05, 3.00660346e-05, 2.37775726e-05, 1.84257700e-05, 1.73788978e-05, 1.78637196e-05, + 2.67609051e-05, 3.03692423e-05, 3.01308521e-05, 2.74402934e-05, 2.50293560e-05, 2.29155277e-05, + 1.94592360e-05, 1.80128216e-05, 2.58103640e-05, 3.03931683e-05, 3.02231270e-05, 2.86113854e-05, + 2.70719009e-05, 2.33669724e-05, 1.95628514e-05, 1.77108311e-05, 1.78081107e-05, 2.37329822e-05, + 3.13674415e-05, 3.77383001e-05, 3.59594065e-05, 2.80462515e-05, 1.92992555e-05, 1.71249199e-05, + 1.94545164e-05, 2.91727034e-05, 3.30402904e-05, 2.99105763e-05, 2.45457692e-05, 2.30595097e-05, + 2.15683585e-05, 1.88101281e-05, 1.80582775e-05, 2.35275571e-05, 2.96380640e-05, 3.34144923e-05, + 2.95285559e-05, 2.47036523e-05, 2.04303366e-05, 1.81128597e-05, 1.81166512e-05, 2.54423946e-05, + 3.03928438e-05, 3.11399928e-05, 2.77826670e-05, 2.39245698e-05, 2.09488627e-05, 1.80582351e-05, + 1.86779305e-05, 1.98507592e-05, 2.53933011e-05, 3.28729625e-05, 3.59211954e-05, 3.03134844e-05, + 2.26043633e-05, 1.86655952e-05, 1.64718581e-05, 1.62344825e-05, 1.73996894e-05, 2.77165879e-05, + 3.14615338e-05, 3.15942150e-05, 2.65284942e-05, 2.06927560e-05, 2.07845401e-05, 1.92516717e-05, + 1.69695136e-05, 2.69875225e-05, 3.05825257e-05, 3.07982079e-05, 2.93949697e-05, 2.64555916e-05, + 2.10680462e-05, 1.86248823e-05, 1.92501122e-05, 2.98529027e-05, 3.54130061e-05, 3.26186132e-05, + 2.44274909e-05, 1.81573498e-05, 1.79931198e-05, 1.87186616e-05, 2.51279649e-05, 2.99441721e-05, + 3.27083546e-05, 3.10608706e-05, 2.57551121e-05, 2.19055802e-05, 1.95785874e-05, 1.74145602e-05, + 2.56809138e-05, 2.90946400e-05, 2.97642064e-05, 2.78806747e-05, 2.49514061e-05, 2.22570892e-05, + 2.07441715e-05, 2.07426033e-05, 2.10254816e-05, 2.52866711e-05, 2.75737702e-05, 2.69642868e-05, + 2.54001874e-05, 2.51348168e-05, 2.47147660e-05, 2.24595955e-05, 2.07153941e-05, 2.11379601e-05, + 2.15758735e-05, 2.08329618e-05, 2.64124880e-05, 2.85758319e-05, 2.85824388e-05, 2.59330002e-05, + 2.43736090e-05, 2.42939349e-05, 2.21796290e-05, 2.00038804e-05, 1.93452387e-05, 2.84134566e-05, + 3.14093504e-05, 3.04367332e-05, 2.46343065e-05, 2.04433132e-05, 2.03858411e-05, 2.06515568e-05, + 2.02324890e-05, 2.01321869e-05, 2.40696416e-05, 2.80382121e-05, 2.95861271e-05, 2.63318753e-05, + 2.32236570e-05, 2.36684290e-05, 2.42259591e-05, 2.25083891e-05, 2.05318294e-05, 2.08764945e-05, + 2.41714091e-05, 2.96310960e-05, 3.17749796e-05, 2.98620544e-05, 2.52714021e-05, 2.05594857e-05, + 1.91099211e-05, 1.97282857e-05, 2.83082158e-05, 3.05404921e-05, 2.97664492e-05, 2.64324653e-05, + 2.21322137e-05, 1.91840265e-05, 1.85886332e-05, 1.97709691e-05, 2.96397765e-05, 3.10137064e-05, + 2.96691070e-05, 2.60256698e-05, 2.06259620e-05, 1.84755971e-05, 1.94709699e-05, 2.03859477e-05, + 2.95658183e-05, 3.15408836e-05, 2.87341529e-05, 2.42907806e-05, 2.27431887e-05, 2.22750501e-05, + 2.12458856e-05, 2.67155892e-05, 2.82412831e-05, 2.87607274e-05, 2.83765581e-05, 2.49146144e-05, + 2.09545774e-05, 2.01606401e-05, 2.05704968e-05, 2.61326385e-05, 2.78326053e-05, 2.77865145e-05, + 2.64518777e-05, 2.54750327e-05, 2.45414171e-05, 2.19307155e-05, 2.06876039e-05, 2.55844542e-05, + 2.81565581e-05, 2.81194098e-05, 2.70054038e-05, 2.64004753e-05, 2.45370114e-05, 2.19698804e-05, + 2.04692751e-05, 2.05270039e-05, 2.32277608e-05, 2.73081340e-05, 3.12698335e-05, 3.15288713e-05, + 2.80653406e-05, 2.19933375e-05, 2.00721611e-05, 2.22127560e-05, 2.75010736e-05, 2.88880320e-05, + 2.74650545e-05, 2.45243787e-05, 2.39214735e-05, 2.33245982e-05, 2.12934812e-05, 2.06792672e-05, + 2.31800546e-05, 2.71371342e-05, 2.98422227e-05, 2.79776334e-05, 2.51745373e-05, 2.25295455e-05, + 2.08523574e-05, 2.07399437e-05, 2.54628016e-05, 2.80768243e-05, 2.84519102e-05, 2.64424991e-05, + 2.42082460e-05, 2.25946443e-05, 2.06222591e-05, 2.13017166e-05, 2.24143726e-05, 2.49953359e-05, + 2.91929253e-05, 3.12292569e-05, 2.85592849e-05, 2.35205152e-05, 2.07795045e-05, 1.93315030e-05, + 1.92215748e-05, 2.02054236e-05, 2.59980696e-05, 2.74443762e-05, 2.81807445e-05, 2.59743543e-05, + 2.26106394e-05, 2.35164953e-05, 2.23033379e-05, 2.00430988e-05, 2.66211200e-05, 2.77913369e-05, + 2.77165120e-05, 2.74908887e-05, 2.62701487e-05, 2.26454440e-05, 2.09639948e-05, 2.17735560e-05, + 2.70521445e-05, 2.94245052e-05, 2.92997370e-05, 2.52782688e-05, 2.07546979e-05, 2.06534841e-05, + 2.13430916e-05, 2.47742681e-05, 2.72845989e-05, 2.90308088e-05, 2.87137438e-05, 2.62189994e-05, + 2.38645321e-05, 2.20276424e-05, 2.01536800e-05, 2.56588954e-05, 2.92276133e-05, 2.99358224e-05, + 2.80466846e-05, 2.50342528e-05, 2.21846119e-05, 2.05981489e-05, 2.05714623e-05, 2.08251595e-05, + 2.52274430e-05, 2.76024569e-05, 2.69567644e-05, 2.53767525e-05, 2.51092904e-05, 2.46675953e-05, + 2.23852212e-05, 2.05949715e-05, 2.09829107e-05, 2.13998246e-05, 2.06345824e-05, 2.64583505e-05, + 2.87186275e-05, 2.86643435e-05, 2.59630251e-05, 2.43715689e-05, 2.42176059e-05, 2.20147559e-05, + 1.98052436e-05, 1.91362461e-05, 2.85361058e-05, 3.17311381e-05, 3.06640682e-05, 2.47053219e-05, + 2.04116786e-05, 2.02482001e-05, 2.04452482e-05, 2.00197070e-05, 1.99220274e-05, 2.41538803e-05, + 2.83102574e-05, 2.98232213e-05, 2.64270734e-05, 2.31904644e-05, 2.35428391e-05, 2.40421626e-05, + 2.22972361e-05, 2.03032408e-05, 2.08069623e-05, 2.42370828e-05, 2.98393943e-05, 3.20267705e-05, + 3.00365585e-05, 2.52645400e-05, 2.03992562e-05, 1.88813283e-05, 1.94971068e-05, 2.83623922e-05, + 3.08297233e-05, 3.00458049e-05, 2.65662487e-05, 2.20921959e-05, 1.90337934e-05, 1.83921922e-05, + 1.95602489e-05, 2.97052920e-05, 3.13454184e-05, 2.99823369e-05, 2.61295083e-05, 2.05339578e-05, + 1.82861428e-05, 1.92454962e-05, 2.01747900e-05, 2.97832097e-05, 3.19632289e-05, 2.90303312e-05, + 2.44065287e-05, 2.26744276e-05, 2.20503039e-05, 2.09976300e-05, 2.68099100e-05, 2.85110553e-05, + 2.90138727e-05, 2.84708836e-05, 2.48072485e-05, 2.07653376e-05, 1.99503806e-05, 2.03633035e-05, + 2.61998081e-05, 2.80438285e-05, 2.79791342e-05, 2.65487769e-05, 2.54362016e-05, 2.43820651e-05, + 2.17276281e-05, 2.04827252e-05, 2.56240070e-05, 2.83208332e-05, 2.82709614e-05, 2.71503380e-05, + 2.64624165e-05, 2.44377034e-05, 2.17750176e-05, 2.02565005e-05, 2.03189021e-05, 2.33789851e-05, + 2.77004484e-05, 3.16722311e-05, 3.17336992e-05, 2.79768723e-05, 2.17568513e-05, 1.98388997e-05, + 2.19617588e-05, 2.76324073e-05, 2.92151775e-05, 2.76827410e-05, 2.45758189e-05, 2.38813577e-05, + 2.31842983e-05, 2.11033999e-05, 2.04824098e-05, 2.33136194e-05, 2.73748908e-05, 3.00621847e-05, + 2.80746224e-05, 2.51430577e-05, 2.23638680e-05, 2.06346202e-05, 2.05415034e-05, 2.54768441e-05, + 2.82533142e-05, 2.86507482e-05, 2.65801624e-05, 2.42322934e-05, 2.24893580e-05, 2.04348570e-05, + 2.10912125e-05, 2.21863377e-05, 2.50764719e-05, 2.94576601e-05, 3.14772662e-05, 2.86522813e-05, + 2.34855591e-05, 2.06532710e-05, 1.91243300e-05, 1.89969325e-05, 1.99907626e-05, 2.61958406e-05, + 2.78264200e-05, 2.84678793e-05, 2.60387499e-05, 2.24678591e-05, 2.32355367e-05, 2.20074559e-05, + 1.97913589e-05, 2.66383705e-05, 2.80314932e-05, 2.79905716e-05, 2.76484380e-05, 2.62793441e-05, + 2.25480285e-05, 2.08017996e-05, 2.15667650e-05, 2.73255804e-05, 2.98963746e-05, 2.95224773e-05, + 2.51953187e-05, 2.05597276e-05, 2.04514079e-05, 2.11315795e-05, 2.48576817e-05, 2.75330569e-05, + 2.93035077e-05, 2.88638522e-05, 2.61508364e-05, 2.36811149e-05, 2.18254172e-05, 1.99498554e-05, + 2.55253552e-05, 2.75011640e-05, 2.78080071e-05, 2.70173965e-05, 2.53272064e-05, 2.32577733e-05, + 2.19933872e-05, 2.19204319e-05, 2.20427017e-05, 2.52148449e-05, 2.66419592e-05, 2.62616037e-05, + 2.53601908e-05, 2.52000263e-05, 2.48999605e-05, 2.33897131e-05, 2.20451941e-05, 2.22522982e-05, + 2.25058655e-05, 2.19081023e-05, 2.60709154e-05, 2.72949231e-05, 2.72082576e-05, 2.57764861e-05, + 2.47957582e-05, 2.45735144e-05, 2.29590673e-05, 2.12926995e-05, 2.07600556e-05, 2.71940164e-05, + 2.83476936e-05, 2.80833805e-05, 2.51156137e-05, 2.20976809e-05, 2.17553784e-05, 2.17521266e-05, + 2.14222080e-05, 2.13548560e-05, 2.48055944e-05, 2.72383086e-05, 2.78110129e-05, 2.61226092e-05, + 2.39983632e-05, 2.40569097e-05, 2.42697633e-05, 2.30606122e-05, 2.15985534e-05, 2.23036723e-05, + 2.48259348e-05, 2.77982241e-05, 2.84089740e-05, 2.78464217e-05, 2.53211628e-05, 2.18178243e-05, + 2.05175316e-05, 2.09862907e-05, 2.70396351e-05, 2.81510245e-05, 2.79112021e-05, 2.62478242e-05, + 2.32576460e-05, 2.08146534e-05, 2.02089606e-05, 2.10805167e-05, 2.76333422e-05, 2.82762738e-05, + 2.79059721e-05, 2.59742289e-05, 2.20606514e-05, 2.01415517e-05, 2.08065310e-05, 2.15414322e-05, + 2.77838968e-05, 2.83220725e-05, 2.75536994e-05, 2.50082508e-05, 2.35939022e-05, 2.28622408e-05, + 2.20651608e-05, 2.63232906e-05, 2.73221586e-05, 2.75155976e-05, 2.71344674e-05, 2.48823216e-05, + 2.20229244e-05, 2.13758923e-05, 2.16897887e-05, 2.59609371e-05, 2.70629014e-05, 2.70142666e-05, + 2.61896347e-05, 2.53702053e-05, 2.45288210e-05, 2.26812208e-05, 2.17827954e-05, 2.56000790e-05, + 2.71405156e-05, 2.71048035e-05, 2.65614701e-05, 2.60956494e-05, 2.46697944e-05, 2.27313552e-05, + 2.15985651e-05, 2.16549966e-05, 2.44374721e-05, 2.70732961e-05, 2.83090870e-05, 2.83553132e-05, + 2.66743147e-05, 2.26326720e-05, 2.12408825e-05, 2.27464577e-05, 2.67827323e-05, 2.76443514e-05, + 2.69027552e-05, 2.50072026e-05, 2.44267435e-05, 2.37957374e-05, 2.22651988e-05, 2.17999252e-05, + 2.43673476e-05, 2.67781478e-05, 2.78845007e-05, 2.69541574e-05, 2.52102965e-05, 2.31971549e-05, + 2.18663996e-05, 2.18398611e-05, 2.54769836e-05, 2.71225812e-05, 2.73190627e-05, 2.62601736e-05, + 2.47542829e-05, 2.34003351e-05, 2.17854294e-05, 2.22133075e-05, 2.29499024e-05, 2.53491097e-05, + 2.76953942e-05, 2.83036919e-05, 2.72147012e-05, 2.41850177e-05, 2.20751929e-05, 2.07550270e-05, + 2.06164896e-05, 2.13963939e-05, 2.61355531e-05, 2.71202260e-05, 2.73183897e-05, 2.58686955e-05, + 2.33129230e-05, 2.35573703e-05, 2.26851619e-05, 2.11634965e-05, 2.61272054e-05, 2.70858848e-05, + 2.70996738e-05, 2.68206410e-05, 2.59207943e-05, 2.34549183e-05, 2.21067907e-05, 2.25602422e-05, + 2.67922492e-05, 2.79225284e-05, 2.76908811e-05, 2.51567057e-05, 2.18606941e-05, 2.17658406e-05, + 2.22402009e-05, 2.52249230e-05, 2.68645683e-05, 2.76427272e-05, 2.73645822e-05, 2.57327447e-05, + 2.40385686e-05, 2.27515256e-05, 2.13897387e-05, 2.52545998e-05, 2.53304180e-05, 2.51938612e-05, + 2.56293395e-05, 2.55779073e-05, 2.46031568e-05, 2.38289395e-05, 2.36947569e-05, 2.36318160e-05, + 2.51042619e-05, 2.53609158e-05, 2.53012815e-05, 2.52369737e-05, 2.52136866e-05, 2.51005387e-05, + 2.46384162e-05, 2.39551699e-05, 2.39040583e-05, 2.39262975e-05, 2.35789215e-05, 2.54718118e-05, + 2.54599778e-05, 2.53484114e-05, 2.54286686e-05, 2.52370180e-05, 2.49416286e-05, 2.41465813e-05, + 2.32849506e-05, 2.29675154e-05, 2.54552309e-05, 2.44232238e-05, 2.49821757e-05, 2.55222413e-05, + 2.43381878e-05, 2.37571212e-05, 2.34747708e-05, 2.32901107e-05, 2.32677952e-05, 2.55302573e-05, + 2.57803714e-05, 2.53093974e-05, 2.56152723e-05, 2.49632077e-05, 2.46456080e-05, 2.44943129e-05, + 2.40080244e-05, 2.33109598e-05, 2.42675691e-05, 2.54705237e-05, 2.52705576e-05, 2.42675558e-05, + 2.51651412e-05, 2.52873061e-05, 2.36928683e-05, 2.27522276e-05, 2.29925718e-05, 2.53359508e-05, + 2.49381887e-05, 2.52705875e-05, 2.57154012e-05, 2.47261440e-05, 2.32484246e-05, 2.27207300e-05, + 2.31273869e-05, 2.50985439e-05, 2.46608230e-05, 2.53217714e-05, 2.56500153e-05, 2.40770873e-05, + 2.27136355e-05, 2.29219608e-05, 2.33548267e-05, 2.52997540e-05, 2.41345150e-05, 2.56304485e-05, + 2.56585978e-05, 2.47219985e-05, 2.38802526e-05, 2.34504428e-05, 2.55934669e-05, 2.57300381e-05, + 2.55760920e-05, 2.54075437e-05, 2.48936079e-05, 2.36675087e-05, 2.32777687e-05, 2.34418763e-05, + 2.55404063e-05, 2.57223299e-05, 2.56960308e-05, 2.56147577e-05, 2.51878335e-05, 2.46433907e-05, + 2.38918556e-05, 2.34948916e-05, 2.54541999e-05, 2.55784005e-05, 2.55614029e-05, 2.56979644e-05, + 2.55185727e-05, 2.48814811e-05, 2.39436861e-05, 2.33756671e-05, 2.34217001e-05, 2.57047803e-05, + 2.61148582e-05, 2.43927550e-05, 2.44535689e-05, 2.50213425e-05, 2.37427611e-05, 2.31148110e-05, + 2.37333769e-05, 2.56115328e-05, 2.56101532e-05, 2.57968551e-05, 2.54459532e-05, 2.50375281e-05, + 2.45186494e-05, 2.37701058e-05, 2.35354388e-05, 2.56323918e-05, 2.58866633e-05, 2.52083898e-05, + 2.54739364e-05, 2.51952421e-05, 2.42298300e-05, 2.34815848e-05, 2.35474339e-05, 2.53669473e-05, + 2.56151477e-05, 2.55775784e-05, 2.57250337e-05, 2.53191754e-05, 2.45258225e-05, 2.35672207e-05, + 2.36665583e-05, 2.39018020e-05, 2.55738157e-05, 2.54609212e-05, 2.45973013e-05, 2.53735843e-05, + 2.50021433e-05, 2.39444998e-05, 2.29726249e-05, 2.28233232e-05, 2.32696462e-05, 2.59106658e-05, + 2.60696284e-05, 2.57681909e-05, 2.55342620e-05, 2.43561697e-05, 2.39269707e-05, 2.35359460e-05, + 2.29984740e-05, 2.53832369e-05, 2.57809024e-05, 2.58521324e-05, 2.56700741e-05, 2.53646125e-05, + 2.45727083e-05, 2.38131384e-05, 2.38283091e-05, 2.59699530e-05, 2.54209941e-05, 2.53880819e-05, + 2.50182573e-05, 2.35710664e-05, 2.34983936e-05, 2.36742867e-05, 2.55723506e-05, 2.58850970e-05, + 2.55186870e-05, 2.54432803e-05, 2.51195143e-05, 2.44328491e-05, 2.39232155e-05, 2.33112609e-05, + 2.50173106e-05, 2.43398116e-05, 2.40344574e-05, 2.52351576e-05, 2.60447829e-05, 2.52958657e-05, + 2.45892757e-05, 2.43148724e-05, 2.40144431e-05, 2.48520487e-05, 2.46300673e-05, 2.46651253e-05, + 2.50922990e-05, 2.51530983e-05, 2.50930374e-05, 2.52554876e-05, 2.48689684e-05, 2.45009374e-05, + 2.42860439e-05, 2.40239302e-05, 2.52332141e-05, 2.47079073e-05, 2.44088076e-05, 2.53070444e-05, + 2.55463193e-05, 2.49480325e-05, 2.43908199e-05, 2.39484446e-05, 2.37386406e-05, 2.47069390e-05, + 2.28536612e-05, 2.36715784e-05, 2.60597910e-05, 2.58582844e-05, 2.46688788e-05, 2.39245603e-05, + 2.38131869e-05, 2.38316815e-05, 2.63458760e-05, 2.56564836e-05, 2.43956613e-05, 2.55945862e-05, + 2.55297562e-05, 2.46307012e-05, 2.40518060e-05, 2.39303879e-05, 2.36689584e-05, 2.54226919e-05, + 2.61611493e-05, 2.42626402e-05, 2.24075898e-05, 2.39723814e-05, 2.52562538e-05, 2.44255846e-05, + 2.34626824e-05, 2.35372655e-05, 2.44149195e-05, 2.37176301e-05, 2.43827336e-05, 2.58010632e-05, + 2.56298993e-05, 2.44232460e-05, 2.37584252e-05, 2.37806526e-05, 2.37068288e-05, 2.33007209e-05, + 2.45620042e-05, 2.57829945e-05, 2.51815320e-05, 2.38243210e-05, 2.35633811e-05, 2.38472883e-05, + 2.43436623e-05, 2.26468246e-05, 2.52603883e-05, 2.65321883e-05, 2.52746638e-05, 2.38001173e-05, + 2.35214206e-05, 2.54195526e-05, 2.55072788e-05, 2.50711818e-05, 2.45859814e-05, 2.45644997e-05, + 2.41294503e-05, 2.38337342e-05, 2.39081527e-05, 2.54889610e-05, 2.54954032e-05, 2.54281511e-05, + 2.55535551e-05, 2.49544970e-05, 2.42114740e-05, 2.40133940e-05, 2.39430240e-05, 2.54996596e-05, + 2.50644585e-05, 2.50224499e-05, 2.55917566e-05, 2.53452306e-05, 2.47081559e-05, 2.40960094e-05, + 2.38374045e-05, 2.38943647e-05, 2.71840995e-05, 2.67251142e-05, 2.30221267e-05, 2.26193086e-05, + 2.37314757e-05, 2.36799192e-05, 2.35624683e-05, 2.35415906e-05, 2.52570698e-05, 2.52544052e-05, + 2.57501463e-05, 2.59384459e-05, 2.53322795e-05, 2.45414940e-05, 2.41345462e-05, 2.40300853e-05, + 2.70423955e-05, 2.60523552e-05, 2.41391986e-05, 2.48164475e-05, 2.50960190e-05, 2.43681672e-05, + 2.38160626e-05, 2.40170767e-05, 2.53531807e-05, 2.51730436e-05, 2.50467017e-05, 2.58212707e-05, + 2.58057585e-05, 2.49437851e-05, 2.41297744e-05, 2.39206518e-05, 2.37680442e-05, 2.60163144e-05, + 2.47949600e-05, 2.29783891e-05, 2.44767815e-05, 2.54583455e-05, 2.48062041e-05, 2.37581767e-05, + 2.35306643e-05, 2.37890481e-05, 2.64240768e-05, 2.65782087e-05, 2.56259953e-05, 2.55322850e-05, + 2.45831994e-05, 2.32569363e-05, 2.31053855e-05, 2.33488659e-05, 2.49607906e-05, 2.56658448e-05, + 2.58805640e-05, 2.54087922e-05, 2.50392996e-05, 2.50139132e-05, 2.44205559e-05, 2.39740769e-05, + 2.62984632e-05, 2.51561321e-05, 2.45614815e-05, 2.46717466e-05, 2.40558554e-05, 2.39710573e-05, + 2.39119902e-05, 2.61104154e-05, 2.60223815e-05, 2.49475296e-05, 2.46569863e-05, 2.45178978e-05, + 2.40980022e-05, 2.40223848e-05, 2.39057669e-05, 2.52088356e-05, 2.80050102e-05, 2.84978513e-05, + 2.83602311e-05, 2.65439553e-05, 2.30395270e-05, 2.10597052e-05, 2.06641554e-05, 2.03835475e-05, + 2.45377510e-05, 2.64253252e-05, 2.57885946e-05, 2.50949940e-05, 2.49728084e-05, 2.45006870e-05, + 2.31087071e-05, 2.14515290e-05, 2.11462933e-05, 2.10726672e-05, 2.02976435e-05, 2.63971944e-05, + 2.81034599e-05, 2.72991587e-05, 2.60389887e-05, 2.50484896e-05, 2.39034366e-05, 2.15748079e-05, + 1.97798219e-05, 1.91885779e-05, 2.78209290e-05, 2.99088436e-05, 2.91125953e-05, 2.62629482e-05, + 2.27722740e-05, 2.09816835e-05, 2.00659387e-05, 1.97055139e-05, 1.96823770e-05, 2.62874677e-05, + 2.98548356e-05, 2.93307510e-05, 2.70929828e-05, 2.41046089e-05, 2.29037303e-05, 2.23245968e-05, + 2.10676111e-05, 1.96527368e-05, 2.23710231e-05, 2.60266779e-05, 2.89635257e-05, 2.90458683e-05, + 2.85294478e-05, 2.52937875e-05, 2.07258443e-05, 1.87222426e-05, 1.90967870e-05, 2.68977670e-05, + 2.98216605e-05, 2.98442185e-05, 2.76820625e-05, 2.34966793e-05, 2.00289707e-05, 1.88755824e-05, + 1.94415669e-05, 2.71817455e-05, 3.01661766e-05, 3.02856872e-05, 2.71495478e-05, 2.18621900e-05, + 1.89108280e-05, 1.90144452e-05, 1.98270268e-05, 2.90823755e-05, 3.08478350e-05, 3.01678947e-05, + 2.68631675e-05, 2.33321237e-05, 2.07416022e-05, 1.97993977e-05, 2.71640672e-05, 2.98226320e-05, + 2.95854685e-05, 2.74391933e-05, 2.37060603e-05, 2.05105523e-05, 1.96988964e-05, 2.00025114e-05, + 2.66346959e-05, 2.89892381e-05, 2.87238234e-05, 2.71447279e-05, 2.48978157e-05, 2.28115510e-05, + 2.08667415e-05, 2.01098942e-05, 2.60774449e-05, 2.83611336e-05, 2.81837270e-05, 2.79477623e-05, + 2.66255830e-05, 2.36678507e-05, 2.10109166e-05, 1.98542835e-05, 1.99617068e-05, 2.71158741e-05, + 3.16306035e-05, 3.08066568e-05, 2.86346379e-05, 2.49931172e-05, 2.04118413e-05, 1.92892580e-05, + 2.03276353e-05, 2.78297120e-05, 3.05729108e-05, 2.90538344e-05, 2.59231459e-05, 2.42925989e-05, + 2.25248130e-05, 2.06972411e-05, 2.02278142e-05, 2.68002915e-05, 2.93184458e-05, 2.90941049e-05, + 2.74232171e-05, 2.48996932e-05, 2.17484954e-05, 2.00150287e-05, 2.02404026e-05, 2.56636896e-05, + 2.85226032e-05, 2.88501118e-05, 2.77413819e-05, 2.53883642e-05, 2.26953396e-05, 2.03390402e-05, + 2.03935990e-05, 2.07713144e-05, 2.65306272e-05, 2.97171159e-05, 2.91809804e-05, 2.74423882e-05, + 2.42045654e-05, 2.13951846e-05, 1.92081291e-05, 1.88598784e-05, 1.96594592e-05, 2.85664973e-05, + 3.14684215e-05, 3.00662598e-05, 2.65530393e-05, 2.21333695e-05, 2.06242740e-05, 1.97449107e-05, + 1.89901701e-05, 2.60442936e-05, 2.93966085e-05, 2.98791644e-05, 2.81978955e-05, 2.58349592e-05, + 2.28413649e-05, 2.09342359e-05, 2.07227362e-05, 2.98414602e-05, 3.23699299e-05, 2.91648416e-05, + 2.41952577e-05, 2.03026107e-05, 2.01319423e-05, 2.04028600e-05, 2.64993942e-05, 2.94871612e-05, + 2.98333962e-05, 2.82094508e-05, 2.47328235e-05, 2.21596202e-05, 2.09338466e-05, 1.97940743e-05, + 2.51736351e-05, 2.56692140e-05, 2.56199573e-05, 2.62967377e-05, 2.61612686e-05, 2.44935879e-05, + 2.33434917e-05, 2.30523700e-05, 2.28015451e-05, 2.48532496e-05, 2.53666939e-05, 2.51821546e-05, + 2.51724829e-05, 2.51602968e-05, 2.49605969e-05, 2.45035910e-05, 2.36338213e-05, 2.33454322e-05, + 2.32222544e-05, 2.27664074e-05, 2.56872722e-05, 2.59153645e-05, 2.55063769e-05, 2.56076650e-05, + 2.53837498e-05, 2.46689384e-05, 2.34838396e-05, 2.24951923e-05, 2.21287837e-05, 2.58329221e-05, + 2.52111832e-05, 2.55538194e-05, 2.60717065e-05, 2.46227316e-05, 2.33406946e-05, 2.26195328e-05, + 2.24066244e-05, 2.24030080e-05, 2.62230442e-05, 2.69702788e-05, 2.60653547e-05, 2.61074030e-05, + 2.50228433e-05, 2.41343810e-05, 2.36336664e-05, 2.30656167e-05, 2.23242023e-05, 2.42675774e-05, + 2.60389754e-05, 2.58855418e-05, 2.47090360e-05, 2.55901576e-05, 2.53257869e-05, 2.31255906e-05, + 2.17937385e-05, 2.20069704e-05, 2.53903404e-05, 2.57612963e-05, 2.61912663e-05, 2.64071693e-05, + 2.48284857e-05, 2.27976568e-05, 2.19797937e-05, 2.22680003e-05, 2.50570558e-05, 2.55708036e-05, + 2.64171538e-05, 2.62267195e-05, 2.39447950e-05, 2.20215448e-05, 2.19766823e-05, 2.24773291e-05, + 2.59672422e-05, 2.52810324e-05, 2.68186614e-05, 2.65180205e-05, 2.46020434e-05, 2.28686473e-05, + 2.23316780e-05, 2.60351938e-05, 2.68729604e-05, 2.65466725e-05, 2.56505208e-05, 2.44074533e-05, + 2.29065437e-05, 2.24116383e-05, 2.25835507e-05, 2.59017518e-05, 2.66302684e-05, 2.65143549e-05, + 2.61018750e-05, 2.50328709e-05, 2.38985911e-05, 2.30154971e-05, 2.26473001e-05, 2.57212763e-05, + 2.61982316e-05, 2.61221685e-05, 2.63747744e-05, 2.58219164e-05, 2.44639262e-05, 2.31137635e-05, + 2.24861077e-05, 2.25590505e-05, 2.69278759e-05, 2.80907698e-05, 2.55304327e-05, 2.47518707e-05, + 2.44118679e-05, 2.26728927e-05, 2.21097337e-05, 2.25761696e-05, 2.61511271e-05, 2.69224446e-05, + 2.67958219e-05, 2.58915235e-05, 2.50005881e-05, 2.39428329e-05, 2.29924550e-05, 2.27369505e-05, + 2.67461275e-05, 2.70458768e-05, 2.58436464e-05, 2.57782720e-05, 2.51054892e-05, 2.35469238e-05, + 2.25518775e-05, 2.27374257e-05, 2.55039585e-05, 2.63081830e-05, 2.63279132e-05, 2.64368990e-05, + 2.56345904e-05, 2.41953670e-05, 2.28285475e-05, 2.27670414e-05, 2.28673912e-05, 2.61421489e-05, + 2.64140271e-05, 2.51216066e-05, 2.55880599e-05, 2.50275065e-05, 2.35828454e-05, 2.21457859e-05, + 2.18878703e-05, 2.23752987e-05, 2.70238088e-05, 2.79598535e-05, 2.70108637e-05, 2.58978218e-05, + 2.38028587e-05, 2.25759353e-05, 2.21306174e-05, 2.18821370e-05, 2.54254150e-05, 2.68463057e-05, + 2.71086580e-05, 2.63478480e-05, 2.53980364e-05, 2.42863316e-05, 2.32175773e-05, 2.29356911e-05, + 2.73389885e-05, 2.73110958e-05, 2.61230891e-05, 2.46394055e-05, 2.27817419e-05, 2.26688485e-05, + 2.27675647e-05, 2.61793597e-05, 2.70781626e-05, 2.65384886e-05, 2.59156980e-05, 2.47497667e-05, + 2.35905726e-05, 2.30485077e-05, 2.24851076e-05, 2.52461356e-05, 2.45025343e-05, 2.41953850e-05, + 2.45673878e-05, 2.49008413e-05, 2.49430973e-05, 2.47323632e-05, 2.47830634e-05, 2.49209643e-05, + 2.53286786e-05, 2.50672000e-05, 2.52113947e-05, 2.52366153e-05, 2.52259596e-05, 2.52511652e-05, + 2.49891257e-05, 2.46705331e-05, 2.48600228e-05, 2.50171802e-05, 2.48628856e-05, 2.50572722e-05, + 2.45575812e-05, 2.47782919e-05, 2.51019561e-05, 2.50954630e-05, 2.52840428e-05, 2.51360193e-05, + 2.46103723e-05, 2.44053112e-05, 2.46562341e-05, 2.28280005e-05, 2.37453939e-05, 2.49123673e-05, + 2.43956265e-05, 2.46101272e-05, 2.48254698e-05, 2.47097865e-05, 2.46730992e-05, 2.48193776e-05, + 2.41430422e-05, 2.39666380e-05, 2.49024978e-05, 2.50254415e-05, 2.53233702e-05, 2.55388210e-05, + 2.53055830e-05, 2.48315821e-05, 2.46037691e-05, 2.48840376e-05, 2.40773292e-05, 2.30151756e-05, + 2.41570071e-05, 2.51824403e-05, 2.47077829e-05, 2.43541046e-05, 2.45778420e-05, 2.49118978e-05, + 2.34117864e-05, 2.37285292e-05, 2.47753713e-05, 2.48385763e-05, 2.42396366e-05, 2.41011039e-05, + 2.45557152e-05, 2.46444268e-05, 2.29813760e-05, 2.36032408e-05, 2.48752844e-05, 2.45838385e-05, + 2.40446228e-05, 2.44788130e-05, 2.47545578e-05, 2.40560703e-05, 2.21261696e-05, 2.39189769e-05, + 2.47489038e-05, 2.50305066e-05, 2.52828676e-05, 2.50736628e-05, 2.48977300e-05, 2.41202717e-05, + 2.40929188e-05, 2.47630597e-05, 2.54271854e-05, 2.48793154e-05, 2.46823554e-05, 2.48030714e-05, + 2.49912742e-05, 2.44058947e-05, 2.44806160e-05, 2.48955258e-05, 2.52837541e-05, 2.55191106e-05, + 2.51593748e-05, 2.48333389e-05, 2.50631008e-05, 2.45393660e-05, 2.45909568e-05, 2.47161558e-05, + 2.50072675e-05, 2.53697261e-05, 2.51516529e-05, 2.47830990e-05, 2.47917461e-05, 2.45155950e-05, + 2.37524651e-05, 2.24314914e-05, 2.33953355e-05, 2.53971410e-05, 2.52415204e-05, 2.46958535e-05, + 2.53213581e-05, 2.47285280e-05, 2.37511222e-05, 2.44220225e-05, 2.49597575e-05, 2.51447141e-05, + 2.53036263e-05, 2.49732148e-05, 2.48154107e-05, 2.45608938e-05, 2.43769685e-05, 2.39691594e-05, + 2.48021185e-05, 2.52451615e-05, 2.52126221e-05, 2.49057923e-05, 2.48361848e-05, 2.51328164e-05, + 2.45047219e-05, 2.43651077e-05, 2.47622960e-05, 2.50057946e-05, 2.50890254e-05, 2.47802400e-05, + 2.50160962e-05, 2.53202937e-05, 2.49088157e-05, 2.39487287e-05, 2.33192346e-05, 2.47420754e-05, + 2.50758184e-05, 2.47009918e-05, 2.43971876e-05, 2.43882193e-05, 2.47047204e-05, 2.45659585e-05, + 2.37780349e-05, 2.40600889e-05, 2.49982454e-05, 2.51781944e-05, 2.56436230e-05, 2.54285554e-05, + 2.47190185e-05, 2.51431949e-05, 2.43012601e-05, 2.41794724e-05, 2.46373796e-05, 2.51689614e-05, + 2.50804971e-05, 2.48273944e-05, 2.51291057e-05, 2.42506056e-05, 2.29041836e-05, 2.41000804e-05, + 2.53919403e-05, 2.48337082e-05, 2.48179150e-05, 2.50290558e-05, 2.48867160e-05, 2.43245004e-05, + 2.39530927e-05, 2.45073665e-05, 2.53928121e-05, 2.54879322e-05, 2.51803454e-05, 2.46681555e-05, + 2.53119151e-05, 2.48039369e-05, 2.45482620e-05, 2.47204282e-05, 2.48160422e-05, 2.47466362e-05, + 2.44864394e-05, 2.45638017e-05, 2.47546842e-05, 2.53878823e-05, 2.52781055e-05, 2.53883237e-05, + 2.52772990e-05, 2.52436958e-05, 2.52482141e-05, 2.48116829e-05, 2.43954035e-05, 2.46544185e-05, + 2.48678689e-05, 2.46798956e-05, 2.51416658e-05, 2.47980014e-05, 2.50564756e-05, 2.51515936e-05, + 2.50237349e-05, 2.52681345e-05, 2.50234163e-05, 2.43658825e-05, 2.41252211e-05, 2.48916605e-05, + 2.33096723e-05, 2.41468301e-05, 2.48063201e-05, 2.40073871e-05, 2.43274323e-05, 2.46374792e-05, + 2.44979511e-05, 2.44509748e-05, 2.46493009e-05, 2.42518964e-05, 2.42660900e-05, 2.49436664e-05, + 2.48766589e-05, 2.52968908e-05, 2.56133867e-05, 2.52659251e-05, 2.46593766e-05, 2.42893130e-05, + 2.47383654e-05, 2.43963599e-05, 2.35672980e-05, 2.45192176e-05, 2.51978913e-05, 2.44627342e-05, + 2.40806697e-05, 2.43506564e-05, 2.51795774e-05, 2.37983446e-05, 2.40283240e-05, 2.47999051e-05, + 2.46007990e-05, 2.38801863e-05, 2.37532884e-05, 2.43080157e-05, 2.50430724e-05, 2.34095641e-05, + 2.38763129e-05, 2.48799589e-05, 2.42720353e-05, 2.36806191e-05, 2.42268350e-05, 2.45521923e-05, + 2.43631508e-05, 2.25971777e-05, 2.40927126e-05, 2.45753283e-05, 2.48721015e-05, 2.52387098e-05, + 2.49758973e-05, 2.49777698e-05, 2.42527106e-05, 2.42916888e-05, 2.50121525e-05, 2.54932747e-05, + 2.46957183e-05, 2.44624250e-05, 2.46100018e-05, 2.50328316e-05, 2.45268300e-05, 2.46076545e-05, + 2.49474414e-05, 2.53437296e-05, 2.55982688e-05, 2.50659198e-05, 2.46464803e-05, 2.50720722e-05, + 2.47225751e-05, 2.47779126e-05, 2.47915589e-05, 2.50788702e-05, 2.53953601e-05, 2.50527910e-05, + 2.45886873e-05, 2.45964411e-05, 2.42124468e-05, 2.37171499e-05, 2.28705891e-05, 2.39353744e-05, + 2.57390465e-05, 2.51877182e-05, 2.44955729e-05, 2.52996187e-05, 2.48636979e-05, 2.39272703e-05, + 2.44999477e-05, 2.48586972e-05, 2.50641588e-05, 2.52616088e-05, 2.48165699e-05, 2.46191598e-05, + 2.42672137e-05, 2.44080371e-05, 2.43060694e-05, 2.50083614e-05, 2.52713985e-05, 2.51291802e-05, + 2.47453411e-05, 2.46462329e-05, 2.51498241e-05, 2.46721892e-05, 2.45597304e-05, 2.47852089e-05, + 2.48972953e-05, 2.49523391e-05, 2.45693831e-05, 2.48817885e-05, 2.52904186e-05, 2.48295492e-05, + 2.41899852e-05, 2.38055793e-05, 2.50109577e-05, 2.49549477e-05, 2.44370087e-05, 2.41140034e-05, + 2.41178285e-05, 2.44930148e-05, 2.45033446e-05, 2.37632259e-05, 2.41765775e-05, 2.50263593e-05, + 2.50789571e-05, 2.57538663e-05, 2.54610419e-05, 2.45378768e-05, 2.52687596e-05, 2.44010141e-05, + 2.42519981e-05, 2.47548546e-05, 2.52666325e-05, 2.49406183e-05, 2.46157073e-05, 2.50272358e-05, + 2.42515444e-05, 2.30844648e-05, 2.43746804e-05, 2.54700002e-05, 2.46410974e-05, 2.46254292e-05, + 2.48989845e-05, 2.47844557e-05, 2.43649647e-05, 2.41720661e-05, 2.47581488e-05, 2.55451894e-05, + 2.55317833e-05, 2.50936050e-05, 2.44404906e-05, 2.49530585e-05, 2.28864893e-05, 2.23103176e-05, + 2.32654691e-05, 2.46391314e-05, 2.58102854e-05, 2.62180252e-05, 2.63203411e-05, 2.64282268e-05, + 2.52262627e-05, 2.40966370e-05, 2.44930378e-05, 2.50334573e-05, 2.51091674e-05, 2.53051777e-05, + 2.57972332e-05, 2.61126653e-05, 2.62411351e-05, 2.63028788e-05, 2.64268269e-05, 2.44154725e-05, + 2.30837748e-05, 2.34052780e-05, 2.46365093e-05, 2.51708223e-05, 2.55238819e-05, 2.62095862e-05, + 2.64346389e-05, 2.64562156e-05, 2.32662304e-05, 2.01953927e-05, 2.15636636e-05, 2.47696051e-05, + 2.57358949e-05, 2.61898764e-05, 2.64623887e-05, 2.64913961e-05, 2.64808100e-05, 2.48231535e-05, + 2.26101264e-05, 2.20276968e-05, 2.41969338e-05, 2.55159972e-05, 2.58522719e-05, 2.59996890e-05, + 2.63646257e-05, 2.65509947e-05, 2.58911364e-05, 2.48925660e-05, 2.21724145e-05, 2.03816360e-05, + 2.22372485e-05, 2.49889164e-05, 2.62800010e-05, 2.65189608e-05, 2.65550084e-05, 2.36703854e-05, + 2.10977175e-05, 2.16650485e-05, 2.39696988e-05, 2.56794956e-05, 2.62166723e-05, 2.63595358e-05, + 2.64775499e-05, 2.29716515e-05, 2.04540804e-05, 2.15128415e-05, 2.42474974e-05, 2.59948562e-05, + 2.63228456e-05, 2.65247056e-05, 2.64847155e-05, 2.21559496e-05, 1.92890823e-05, 2.21369912e-05, + 2.46250892e-05, 2.57394821e-05, 2.64422490e-05, 2.66060869e-05, 2.40764509e-05, 2.25306627e-05, + 2.23760907e-05, 2.34324364e-05, 2.55295457e-05, 2.63866823e-05, 2.64813559e-05, 2.64672500e-05, + 2.43972423e-05, 2.30401335e-05, 2.31610705e-05, 2.41502485e-05, 2.50853442e-05, 2.58347535e-05, + 2.63861789e-05, 2.64560467e-05, 2.46877361e-05, 2.31566749e-05, 2.32413918e-05, 2.37167009e-05, + 2.43404003e-05, 2.55761063e-05, 2.63500167e-05, 2.64903534e-05, 2.64714233e-05, 2.46410802e-05, + 2.22232055e-05, 1.97106587e-05, 2.09132350e-05, 2.44722444e-05, 2.65132280e-05, 2.65693771e-05, + 2.65509428e-05, 2.36022501e-05, 2.18706608e-05, 2.31554623e-05, 2.48876230e-05, 2.54323145e-05, + 2.59687933e-05, 2.63756689e-05, 2.64245693e-05, 2.47358746e-05, 2.31731392e-05, 2.19807690e-05, + 2.35894992e-05, 2.51269563e-05, 2.61773801e-05, 2.65024063e-05, 2.64294800e-05, 2.48416894e-05, + 2.31252407e-05, 2.28337571e-05, 2.39465913e-05, 2.50826144e-05, 2.59158292e-05, 2.63881556e-05, + 2.64564671e-05, 2.64415995e-05, 2.46369242e-05, 2.20823957e-05, 2.08609245e-05, 2.33574955e-05, + 2.54779019e-05, 2.61351821e-05, 2.64485727e-05, 2.65101235e-05, 2.64986385e-05, 2.37748779e-05, + 2.22273819e-05, 2.24585830e-05, 2.44577941e-05, 2.60730276e-05, 2.65107177e-05, 2.67143533e-05, + 2.66390666e-05, 2.44878271e-05, 2.28975508e-05, 2.27389031e-05, 2.34684216e-05, 2.46366946e-05, + 2.58760388e-05, 2.62773275e-05, 2.64129150e-05, 2.30085296e-05, 2.06204577e-05, 2.22717757e-05, + 2.53353530e-05, 2.64153787e-05, 2.64456982e-05, 2.64583432e-05, 2.46778886e-05, 2.30576790e-05, + 2.21220840e-05, 2.29790957e-05, 2.50142532e-05, 2.60631514e-05, 2.63747645e-05, 2.64562104e-05, + 2.44692109e-05, 2.08701575e-05, 2.00113906e-05, 2.15587153e-05, 2.41320380e-05, 2.68124098e-05, + 2.81202722e-05, 2.83153144e-05, 2.84031987e-05, 2.49922781e-05, 2.28109290e-05, 2.35078977e-05, + 2.46573958e-05, 2.48379352e-05, 2.52545239e-05, 2.67227184e-05, 2.79337364e-05, 2.80034195e-05, + 2.79480498e-05, 2.84810743e-05, 2.34893830e-05, 2.12086557e-05, 2.16615115e-05, 2.39215150e-05, + 2.51186307e-05, 2.57214443e-05, 2.75549208e-05, 2.88658960e-05, 2.92323125e-05, 2.14867258e-05, + 1.71707271e-05, 1.89633840e-05, 2.44100732e-05, 2.73462566e-05, 2.82189261e-05, 2.86275486e-05, + 2.88716416e-05, 2.88971380e-05, 2.46309697e-05, 2.06197569e-05, 1.96522666e-05, 2.31727082e-05, + 2.60020530e-05, 2.64488304e-05, 2.65465906e-05, 2.77235004e-05, 2.88531846e-05, 2.74579595e-05, + 2.47175190e-05, 1.98404299e-05, 1.73752752e-05, 1.99035610e-05, 2.46147277e-05, 2.83161622e-05, + 2.94838842e-05, 2.92391387e-05, 2.20783758e-05, 1.83569705e-05, 1.91565790e-05, 2.28136779e-05, + 2.66238787e-05, 2.88332150e-05, 2.94399009e-05, 2.90625139e-05, 2.09253672e-05, 1.75148618e-05, + 1.89675023e-05, 2.33064520e-05, 2.77503015e-05, 2.94275325e-05, 2.93070566e-05, 2.87886490e-05, + 1.98251830e-05, 1.60767171e-05, 1.98905172e-05, 2.42613182e-05, 2.65311782e-05, 2.79485450e-05, + 2.86538869e-05, 2.29232900e-05, 2.04843842e-05, 2.02103012e-05, 2.17277255e-05, 2.55752318e-05, + 2.83532279e-05, 2.88850079e-05, 2.86724222e-05, 2.35141962e-05, 2.12466736e-05, 2.14239101e-05, + 2.30805678e-05, 2.47238874e-05, 2.61802435e-05, 2.79697724e-05, 2.85996295e-05, 2.40722494e-05, + 2.13664387e-05, 2.14912862e-05, 2.23425096e-05, 2.33773472e-05, 2.57462539e-05, 2.78882371e-05, + 2.87623082e-05, 2.86997155e-05, 2.45537131e-05, 2.01857814e-05, 1.65934849e-05, 1.80500296e-05, + 2.32947551e-05, 2.81838790e-05, 2.91012645e-05, 2.81735968e-05, 2.20977508e-05, 1.95175753e-05, + 2.14622610e-05, 2.46241758e-05, 2.56666297e-05, 2.67521738e-05, 2.81946060e-05, 2.85423811e-05, + 2.47198099e-05, 2.15364223e-05, 1.95643999e-05, 2.20086762e-05, 2.48575356e-05, 2.73759937e-05, + 2.86185695e-05, 2.85257835e-05, 2.43395794e-05, 2.13329436e-05, 2.08758846e-05, 2.27774681e-05, + 2.50160876e-05, 2.68876772e-05, 2.84967462e-05, 2.83444307e-05, 2.78978673e-05, 2.41188650e-05, + 1.97663752e-05, 1.80055608e-05, 2.15967116e-05, 2.58528640e-05, 2.79496267e-05, 2.92238662e-05, + 2.94064763e-05, 2.88984008e-05, 2.26020021e-05, 2.01730880e-05, 2.03932522e-05, 2.36375162e-05, + 2.71616475e-05, 2.76580918e-05, 2.84484107e-05, 2.92549526e-05, 2.35614076e-05, 2.10522232e-05, + 2.08411139e-05, 2.19059846e-05, 2.38557836e-05, 2.68011072e-05, 2.81417196e-05, 2.80784112e-05, + 2.13153223e-05, 1.78489970e-05, 2.00086364e-05, 2.51710514e-05, 2.84923160e-05, 2.85943752e-05, + 2.83314136e-05, 2.42327441e-05, 2.13501565e-05, 1.98371469e-05, 2.10449643e-05, 2.44552593e-05, + 2.67579729e-05, 2.79129496e-05, 2.88386589e-05, 2.54280950e-05, 2.77647768e-05, 2.81538671e-05, + 2.75532750e-05, 2.57643045e-05, 2.31464225e-05, 2.16037572e-05, 2.14117266e-05, 2.13867909e-05, + 2.49797735e-05, 2.66141132e-05, 2.61291511e-05, 2.52770234e-05, 2.51264092e-05, 2.47574436e-05, + 2.32583369e-05, 2.17794733e-05, 2.18036657e-05, 2.19409069e-05, 2.12683004e-05, 2.62179054e-05, + 2.76563081e-05, 2.73119044e-05, 2.58923154e-05, 2.48829863e-05, 2.43260119e-05, 2.24196518e-05, + 2.06804684e-05, 2.01191733e-05, 2.74870840e-05, 2.90507560e-05, 2.85678321e-05, 2.55232129e-05, + 2.22814944e-05, 2.14204082e-05, 2.10818692e-05, 2.07359198e-05, 2.06841337e-05, 2.53206197e-05, + 2.82199068e-05, 2.84479037e-05, 2.64971640e-05, 2.40164507e-05, 2.36227607e-05, 2.35467748e-05, + 2.22964580e-05, 2.08289330e-05, 2.22778150e-05, 2.52447836e-05, 2.83107116e-05, 2.87907964e-05, + 2.81921907e-05, 2.53219021e-05, 2.13678806e-05, 1.97901178e-05, 2.02294512e-05, 2.70532163e-05, + 2.88664961e-05, 2.86979761e-05, 2.67871210e-05, 2.33084323e-05, 2.04628906e-05, 1.96497275e-05, + 2.04186206e-05, 2.75616243e-05, 2.90834018e-05, 2.88459663e-05, 2.64153925e-05, 2.19367493e-05, + 1.96193893e-05, 2.00839117e-05, 2.08576562e-05, 2.83420535e-05, 2.93718369e-05, 2.85509194e-05, + 2.56556808e-05, 2.34731884e-05, 2.20466245e-05, 2.11816756e-05, 2.66590527e-05, 2.82685628e-05, + 2.83252062e-05, 2.73111037e-05, 2.44575589e-05, 2.14212211e-05, 2.07037737e-05, 2.10182296e-05, + 2.62269272e-05, 2.78017272e-05, 2.76766341e-05, 2.65609804e-05, 2.52129091e-05, 2.38964114e-05, + 2.19774605e-05, 2.11179313e-05, 2.57867979e-05, 2.76391373e-05, 2.75525573e-05, 2.70949468e-05, + 2.63152071e-05, 2.43039218e-05, 2.20635103e-05, 2.09044429e-05, 2.09806999e-05, 2.53475798e-05, + 2.86899017e-05, 2.93388486e-05, 2.85991364e-05, 2.61131781e-05, 2.17753326e-05, 2.04640907e-05, + 2.18159120e-05, 2.72065539e-05, 2.87532509e-05, 2.77115883e-05, 2.53318609e-05, 2.43684196e-05, + 2.33132398e-05, 2.16465679e-05, 2.11727894e-05, 2.51938671e-05, 2.77138564e-05, 2.84179478e-05, + 2.71817532e-05, 2.51070797e-05, 2.26381074e-05, 2.11361024e-05, 2.12031478e-05, 2.55577887e-05, + 2.76827028e-05, 2.79333619e-05, 2.68160625e-05, 2.49745704e-05, 2.31167141e-05, 2.12046702e-05, + 2.15001041e-05, 2.21139361e-05, 2.57746167e-05, 2.84986485e-05, 2.87557833e-05, 2.73673313e-05, + 2.41762165e-05, 2.17787646e-05, 2.01232173e-05, 1.99047731e-05, 2.07021942e-05, 2.70109118e-05, + 2.86711064e-05, 2.83482749e-05, 2.61356718e-05, 2.28549539e-05, 2.24446002e-05, 2.15534601e-05, + 2.03019388e-05, 2.61305524e-05, 2.79568252e-05, 2.81297418e-05, 2.73605995e-05, 2.59169858e-05, + 2.32053235e-05, 2.16315796e-05, 2.18458903e-05, 2.78993785e-05, 2.95596721e-05, 2.83046348e-05, + 2.48169622e-05, 2.12396482e-05, 2.11152496e-05, 2.15208198e-05, 2.56792444e-05, 2.78315616e-05, + 2.85008017e-05, 2.77419059e-05, 2.53938353e-05, 2.33355746e-05, 2.20477386e-05, 2.07480844e-05, + 2.52110452e-05, 2.72482460e-05, 2.75555573e-05, 2.77287841e-05, 2.64840679e-05, 2.35291391e-05, + 2.17830767e-05, 2.14082020e-05, 2.11228668e-05, 2.46435766e-05, 2.60863659e-05, 2.55943052e-05, + 2.51363334e-05, 2.50518220e-05, 2.46633635e-05, 2.35773186e-05, 2.21556719e-05, 2.18377381e-05, + 2.17376815e-05, 2.10539903e-05, 2.61954065e-05, 2.74093136e-05, 2.67179613e-05, 2.59288841e-05, + 2.51928989e-05, 2.41564518e-05, 2.21671052e-05, 2.06135942e-05, 2.00869041e-05, 2.71903891e-05, + 2.83345147e-05, 2.79375871e-05, 2.62646753e-05, 2.34190823e-05, 2.17336427e-05, 2.08453045e-05, + 2.05280456e-05, 2.05122395e-05, 2.63436887e-05, 2.89805231e-05, 2.82794978e-05, 2.68203099e-05, + 2.44340050e-05, 2.32900574e-05, 2.27096573e-05, 2.16671444e-05, 2.04586486e-05, 2.30101178e-05, + 2.60981686e-05, 2.79666912e-05, 2.75714601e-05, 2.75649990e-05, 2.53282521e-05, 2.14790834e-05, + 1.96512059e-05, 1.99753575e-05, 2.64073837e-05, 2.84872325e-05, 2.86681695e-05, 2.73271065e-05, + 2.39636203e-05, 2.09041292e-05, 1.98301552e-05, 2.03040071e-05, 2.64662368e-05, 2.86424030e-05, + 2.90479674e-05, 2.69055774e-05, 2.25495983e-05, 1.98709185e-05, 1.99116295e-05, 2.06344557e-05, + 2.80770372e-05, 2.89829424e-05, 2.91271214e-05, 2.68392490e-05, 2.37615911e-05, 2.13766945e-05, + 2.05529118e-05, 2.68378768e-05, 2.89207490e-05, 2.86357032e-05, 2.68668168e-05, 2.39212047e-05, + 2.12481827e-05, 2.05262528e-05, 2.07900937e-05, 2.64373095e-05, 2.82753577e-05, 2.80545429e-05, + 2.68519811e-05, 2.49511145e-05, 2.31332121e-05, 2.15186563e-05, 2.08848374e-05, 2.60000826e-05, + 2.76904964e-05, 2.75434955e-05, 2.74883994e-05, 2.63991686e-05, 2.39195369e-05, 2.16518588e-05, + 2.06551637e-05, 2.07539815e-05, 2.71756705e-05, 3.05967380e-05, 2.90510369e-05, 2.73146698e-05, + 2.47674119e-05, 2.10846656e-05, 2.01392604e-05, 2.09901572e-05, 2.73216373e-05, 2.94352969e-05, + 2.83837387e-05, 2.59697485e-05, 2.45453992e-05, 2.29667730e-05, 2.14022972e-05, 2.09976657e-05, + 2.68954538e-05, 2.86577388e-05, 2.80369587e-05, 2.69064037e-05, 2.49818829e-05, 2.23041638e-05, + 2.07837612e-05, 2.10056646e-05, 2.56418325e-05, 2.78403551e-05, 2.80642274e-05, 2.73779673e-05, + 2.55169388e-05, 2.31825515e-05, 2.11072628e-05, 2.11139777e-05, 2.13949821e-05, 2.64675218e-05, + 2.86707734e-05, 2.78177355e-05, 2.68445147e-05, 2.45000623e-05, 2.20979392e-05, 2.01065581e-05, + 1.97775083e-05, 2.04856925e-05, 2.81560047e-05, 3.04374884e-05, 2.91359445e-05, 2.63823167e-05, + 2.26577580e-05, 2.11791191e-05, 2.04322864e-05, 1.98537698e-05, 2.58591046e-05, 2.86294515e-05, + 2.90515665e-05, 2.76421311e-05, 2.57109146e-05, 2.33142956e-05, 2.16491879e-05, 2.13935703e-05, + 2.91190269e-05, 3.07740781e-05, 2.81921478e-05, 2.43337076e-05, 2.10638766e-05, 2.09080620e-05, + 2.11199917e-05, 2.64626189e-05, 2.87815442e-05, 2.87962779e-05, 2.74794885e-05, 2.47292660e-05, + 2.25854925e-05, 2.15751738e-05, 2.06177374e-05, 2.42588083e-05, 2.05508949e-05, 1.96639370e-05, + 2.19860068e-05, 2.52295765e-05, 2.73946697e-05, 2.82882531e-05, 2.81249095e-05, 2.77129222e-05, + 2.45687457e-05, 2.23265586e-05, 2.29510392e-05, 2.45405339e-05, 2.48030062e-05, 2.51630394e-05, + 2.72007579e-05, 2.84764948e-05, 2.79109553e-05, 2.74287674e-05, 2.78735979e-05, 2.36030455e-05, + 2.11688429e-05, 2.11946630e-05, 2.40923715e-05, 2.56289641e-05, 2.54808475e-05, 2.69951113e-05, + 2.84948511e-05, 2.88873386e-05, 2.13748782e-05, 1.68881506e-05, 1.86529955e-05, 2.55430459e-05, + 2.92677908e-05, 2.86341439e-05, 2.79575232e-05, 2.82224160e-05, 2.83150093e-05, 2.61720770e-05, + 2.17011317e-05, 1.97681921e-05, 2.37445570e-05, 2.66570430e-05, 2.58825549e-05, 2.51586349e-05, + 2.64792100e-05, 2.78901497e-05, 2.86510610e-05, 2.60179783e-05, 1.97676263e-05, 1.66315779e-05, + 1.95334852e-05, 2.47083492e-05, 2.83425018e-05, 2.88842986e-05, 2.84414835e-05, 2.15148152e-05, + 1.83206008e-05, 1.94280674e-05, 2.36633145e-05, 2.76636159e-05, 2.94831494e-05, 2.95187871e-05, + 2.85719266e-05, 1.99600988e-05, 1.74590038e-05, 1.94701020e-05, 2.40920548e-05, 2.87321252e-05, + 2.96592550e-05, 2.86651216e-05, 2.81214258e-05, 1.98346762e-05, 1.61203904e-05, 2.07662893e-05, + 2.60085328e-05, 2.69650593e-05, 2.65916815e-05, 2.72341549e-05, 2.33177923e-05, 2.14466669e-05, + 2.08089008e-05, 2.14297148e-05, 2.47948176e-05, 2.78400143e-05, 2.82934844e-05, 2.80122252e-05, + 2.39316883e-05, 2.20173991e-05, 2.20852546e-05, 2.36131469e-05, 2.44303903e-05, 2.49690655e-05, + 2.69867701e-05, 2.79401768e-05, 2.44764696e-05, 2.16572451e-05, 2.17087716e-05, 2.30136461e-05, + 2.36347181e-05, 2.51760261e-05, 2.70022653e-05, 2.80483199e-05, 2.80383830e-05, 2.72515756e-05, + 2.24638016e-05, 1.67045840e-05, 1.71857951e-05, 2.17132713e-05, 2.67444340e-05, 2.81849498e-05, + 2.64920546e-05, 2.24393706e-05, 2.04964275e-05, 2.24597755e-05, 2.56136460e-05, 2.59584696e-05, + 2.61287935e-05, 2.75692542e-05, 2.80012763e-05, 2.72552629e-05, 2.28474774e-05, 1.94679932e-05, + 2.18904819e-05, 2.47487132e-05, 2.66971324e-05, 2.77288924e-05, 2.79442741e-05, 2.45557868e-05, + 2.17453524e-05, 2.12696235e-05, 2.36544449e-05, 2.58691656e-05, 2.69347648e-05, 2.81093584e-05, + 2.74348790e-05, 2.64635660e-05, 2.51792220e-05, 2.02271888e-05, 1.74678850e-05, 2.12173096e-05, + 2.63644279e-05, 2.83861775e-05, 2.89119151e-05, 2.88425442e-05, 2.82283762e-05, 2.42000239e-05, + 2.23020121e-05, 2.14987258e-05, 2.40992765e-05, 2.67415045e-05, 2.53244138e-05, 2.61643153e-05, + 2.80639640e-05, 2.33447397e-05, 2.20445942e-05, 2.21040819e-05, 2.24494147e-05, 2.37048249e-05, + 2.69257454e-05, 2.80068559e-05, 2.70897879e-05, 2.29315412e-05, 1.92783522e-05, 2.01686489e-05, + 2.45158327e-05, 2.79564107e-05, 2.79851663e-05, 2.73966559e-05, 2.54203610e-05, 2.26617124e-05, + 2.04236926e-05, 2.09966164e-05, 2.36232777e-05, 2.54747010e-05, 2.69143125e-05, 2.83459937e-05, + 2.45335083e-05, 2.16460350e-05, 2.09044676e-05, 2.29336751e-05, 2.55025580e-05, 2.68102244e-05, + 2.72052155e-05, 2.70102526e-05, 2.66398405e-05, 2.47098074e-05, 2.30341415e-05, 2.34984754e-05, + 2.47548652e-05, 2.49582066e-05, 2.51969872e-05, 2.66649273e-05, 2.74183589e-05, 2.69235026e-05, + 2.65313945e-05, 2.67508255e-05, 2.41185501e-05, 2.21971360e-05, 2.21437350e-05, 2.44911163e-05, + 2.56510854e-05, 2.53806302e-05, 2.62679422e-05, 2.71424555e-05, 2.73352450e-05, 2.23505241e-05, + 1.84968557e-05, 2.00489097e-05, 2.57301744e-05, 2.82556183e-05, 2.74624224e-05, 2.67760610e-05, + 2.69179753e-05, 2.69855552e-05, 2.62544143e-05, 2.28229333e-05, 2.10672939e-05, 2.43147003e-05, + 2.63674775e-05, 2.55714870e-05, 2.49016212e-05, 2.57775313e-05, 2.66505272e-05, 2.77056735e-05, + 2.60948594e-05, 2.10361551e-05, 1.81997551e-05, 2.07909537e-05, 2.49187517e-05, 2.71908761e-05, + 2.72432657e-05, 2.69752530e-05, 2.23827054e-05, 1.98026249e-05, 2.08045873e-05, 2.43085874e-05, + 2.70931882e-05, 2.79503488e-05, 2.77570886e-05, 2.71400377e-05, 2.10511479e-05, 1.90407150e-05, + 2.08773960e-05, 2.46153605e-05, 2.76868724e-05, 2.78708630e-05, 2.71316196e-05, 2.68613827e-05, + 2.11058715e-05, 1.78455271e-05, 2.20253799e-05, 2.61888703e-05, 2.65078541e-05, 2.58150627e-05, + 2.61644443e-05, 2.39593175e-05, 2.25965149e-05, 2.20133670e-05, 2.23617500e-05, 2.47908407e-05, + 2.67610583e-05, 2.69718680e-05, 2.68075459e-05, 2.44228954e-05, 2.30204206e-05, 2.30545154e-05, + 2.42086690e-05, 2.46391298e-05, 2.48145281e-05, 2.61484471e-05, 2.67702221e-05, 2.48180700e-05, + 2.26476762e-05, 2.26757826e-05, 2.37804867e-05, 2.41705636e-05, 2.50993340e-05, 2.61840286e-05, + 2.68094141e-05, 2.68207155e-05, 2.72467675e-05, 2.36486834e-05, 1.83876177e-05, 1.86793530e-05, + 2.23567157e-05, 2.58824245e-05, 2.68131486e-05, 2.56689098e-05, 2.32744315e-05, 2.18192061e-05, + 2.34111517e-05, 2.57475057e-05, 2.58234863e-05, 2.57166405e-05, 2.65800850e-05, 2.68384433e-05, + 2.72103693e-05, 2.37724375e-05, 2.07795300e-05, 2.27598942e-05, 2.49040974e-05, 2.60573045e-05, + 2.65887760e-05, 2.67961368e-05, 2.48358548e-05, 2.27396486e-05, 2.23539637e-05, 2.43072789e-05, + 2.58921795e-05, 2.63904424e-05, 2.69421076e-05, 2.64234534e-05, 2.57180647e-05, 2.54589554e-05, + 2.15085377e-05, 1.89776814e-05, 2.21771753e-05, 2.61431177e-05, 2.73381332e-05, 2.73578118e-05, + 2.72380148e-05, 2.69142838e-05, 2.48585516e-05, 2.34924891e-05, 2.26637617e-05, 2.45552631e-05, + 2.61514297e-05, 2.47851679e-05, 2.53133311e-05, 2.66643106e-05, 2.38606676e-05, 2.30819407e-05, + 2.31780480e-05, 2.33194885e-05, 2.41414517e-05, 2.64047641e-05, 2.69635044e-05, 2.62064206e-05, + 2.38949891e-05, 2.08616162e-05, 2.14099233e-05, 2.46230119e-05, 2.68163922e-05, 2.68091617e-05, + 2.63949888e-05, 2.56563725e-05, 2.36274644e-05, 2.16930385e-05, 2.20561061e-05, 2.39448072e-05, + 2.51348096e-05, 2.61019093e-05, 2.70297386e-05, 2.54282214e-05, 2.54198733e-05, 2.52746841e-05, + 2.50754434e-05, 2.47073035e-05, 2.43641728e-05, 2.39749329e-05, 2.40854022e-05, 2.43547246e-05, + 2.54746914e-05, 2.56840262e-05, 2.57156759e-05, 2.53470905e-05, 2.52706817e-05, 2.52272652e-05, + 2.44622177e-05, 2.38465327e-05, 2.42100643e-05, 2.45131235e-05, 2.42507406e-05, 2.53222892e-05, + 2.53045990e-05, 2.56092462e-05, 2.52619473e-05, 2.48998227e-05, 2.52093411e-05, 2.47418036e-05, + 2.38252209e-05, 2.35137578e-05, 2.53812193e-05, 2.43293757e-05, 2.49840774e-05, 2.46544310e-05, + 2.33087752e-05, 2.37551455e-05, 2.41943960e-05, 2.40075369e-05, 2.39435452e-05, 2.43896469e-05, + 2.45660929e-05, 2.49165965e-05, 2.50667483e-05, 2.45994469e-05, 2.51936944e-05, 2.56655566e-05, + 2.50914855e-05, 2.42311859e-05, 2.36992404e-05, 2.45135772e-05, 2.50729634e-05, 2.46983763e-05, + 2.52641568e-05, 2.52294013e-05, 2.39444472e-05, 2.34683670e-05, 2.38205874e-05, 2.57015783e-05, + 2.46287288e-05, 2.46941150e-05, 2.49089241e-05, 2.41617416e-05, 2.31640830e-05, 2.30284846e-05, + 2.37539247e-05, 2.58152876e-05, 2.43316919e-05, 2.45042468e-05, 2.49407570e-05, 2.36742325e-05, + 2.29315321e-05, 2.36554676e-05, 2.40799896e-05, 2.50208113e-05, 2.36274168e-05, 2.45330824e-05, + 2.43234489e-05, 2.45596467e-05, 2.50480263e-05, 2.46720304e-05, 2.51710198e-05, 2.46087831e-05, + 2.47625894e-05, 2.55158318e-05, 2.55692631e-05, 2.42709755e-05, 2.39589099e-05, 2.41571450e-05, + 2.51447072e-05, 2.48405831e-05, 2.49254697e-05, 2.50907048e-05, 2.54416000e-05, 2.56718962e-05, + 2.47972896e-05, 2.42063324e-05, 2.51128354e-05, 2.51321290e-05, 2.51894386e-05, 2.49970391e-05, + 2.52430993e-05, 2.54010219e-05, 2.47790654e-05, 2.41299310e-05, 2.41389619e-05, 2.37496678e-05, + 2.38156913e-05, 2.38349997e-05, 2.50275165e-05, 2.63391555e-05, 2.49722292e-05, 2.40131606e-05, + 2.51347914e-05, 2.51724834e-05, 2.43826360e-05, 2.47382574e-05, 2.47069084e-05, 2.49060569e-05, + 2.51222282e-05, 2.44402630e-05, 2.41668687e-05, 2.38130560e-05, 2.45695689e-05, 2.50200970e-05, + 2.54338595e-05, 2.53110772e-05, 2.49002690e-05, 2.43453770e-05, 2.42044031e-05, 2.51937172e-05, + 2.50575903e-05, 2.50032588e-05, 2.48928904e-05, 2.47196341e-05, 2.46597692e-05, 2.40963929e-05, + 2.45339846e-05, 2.51241943e-05, 2.47299440e-05, 2.47428444e-05, 2.48100707e-05, 2.55508436e-05, + 2.47268632e-05, 2.39046648e-05, 2.34981415e-05, 2.35136552e-05, 2.40016545e-05, 2.44821092e-05, + 2.38945568e-05, 2.45099549e-05, 2.51126718e-05, 2.48339350e-05, 2.58181947e-05, 2.53699661e-05, + 2.40784559e-05, 2.55123087e-05, 2.46871533e-05, 2.45014028e-05, 2.50417360e-05, 2.54554567e-05, + 2.46464729e-05, 2.41562353e-05, 2.47410053e-05, 2.43724434e-05, 2.35935814e-05, 2.49741067e-05, + 2.55800374e-05, 2.41965541e-05, 2.41767799e-05, 2.45583172e-05, 2.46448145e-05, 2.45473580e-05, + 2.46868383e-05, 2.52866984e-05, 2.57995382e-05, 2.55271844e-05, 2.48377877e-05, 2.39269971e-05, + 2.55128220e-05, 2.64099564e-05, 2.64666659e-05, 2.59477792e-05, 2.49495724e-05, 2.38422215e-05, + 2.30570778e-05, 2.30967768e-05, 2.33205726e-05, 2.54074757e-05, 2.61819905e-05, 2.60304739e-05, + 2.53868830e-05, 2.52666174e-05, 2.51077265e-05, 2.39617039e-05, 2.29967635e-05, 2.33171353e-05, + 2.36190517e-05, 2.31969965e-05, 2.56835264e-05, 2.62325958e-05, 2.63957236e-05, 2.55131637e-05, + 2.48474968e-05, 2.49547838e-05, 2.39591557e-05, 2.26651905e-05, 2.22424229e-05, 2.62359657e-05, + 2.61568629e-05, 2.64200052e-05, 2.48233336e-05, 2.26734116e-05, 2.28161734e-05, 2.30947806e-05, + 2.28358010e-05, 2.27666003e-05, 2.45156357e-05, 2.57093424e-05, 2.62277759e-05, 2.55363900e-05, + 2.43095703e-05, 2.47219118e-05, 2.51209057e-05, 2.42276253e-05, 2.30527755e-05, 2.30108598e-05, + 2.46060798e-05, 2.63261276e-05, 2.64398681e-05, 2.64795505e-05, 2.52921626e-05, 2.29633785e-05, + 2.21109721e-05, 2.25321590e-05, 2.63779440e-05, 2.62225538e-05, 2.61314296e-05, 2.54867767e-05, + 2.37108864e-05, 2.20443573e-05, 2.17036512e-05, 2.25300444e-05, 2.67411764e-05, 2.61066434e-05, + 2.60015429e-05, 2.53868519e-05, 2.28928085e-05, 2.16142459e-05, 2.23515493e-05, 2.29324644e-05, + 2.62837089e-05, 2.57060999e-05, 2.58397906e-05, 2.45584122e-05, 2.41116477e-05, 2.41145032e-05, + 2.35323822e-05, 2.56953747e-05, 2.57780142e-05, 2.59752683e-05, 2.62980970e-05, 2.53245102e-05, + 2.32587196e-05, 2.27852788e-05, 2.30445740e-05, 2.55166805e-05, 2.58113289e-05, 2.58456666e-05, + 2.55821434e-05, 2.54536261e-05, 2.52376886e-05, 2.38760871e-05, 2.31154208e-05, 2.53368717e-05, + 2.60434881e-05, 2.60651603e-05, 2.56862645e-05, 2.56418409e-05, 2.51219170e-05, 2.38858362e-05, + 2.29884804e-05, 2.30182184e-05, 2.39373674e-05, 2.51268342e-05, 2.58160716e-05, 2.66148160e-05, + 2.66337757e-05, 2.39673520e-05, 2.27622301e-05, 2.41203273e-05, 2.59044117e-05, 2.57840082e-05, + 2.56683852e-05, 2.48113583e-05, 2.46930593e-05, 2.45631814e-05, 2.34699322e-05, 2.30975779e-05, + 2.39497078e-05, 2.54980704e-05, 2.63357219e-05, 2.61586579e-05, 2.52977141e-05, 2.41630140e-05, + 2.32395186e-05, 2.31384571e-05, 2.53365916e-05, 2.59850066e-05, 2.60417168e-05, 2.54815680e-05, + 2.47111456e-05, 2.40942718e-05, 2.30465330e-05, 2.35077015e-05, 2.42010593e-05, 2.49740392e-05, + 2.60517584e-05, 2.64375365e-05, 2.63596096e-05, 2.44723761e-05, 2.30466462e-05, 2.22304366e-05, + 2.21814839e-05, 2.28210986e-05, 2.51519864e-05, 2.52018507e-05, 2.57097460e-05, 2.54546851e-05, + 2.41696807e-05, 2.49100168e-05, 2.42442610e-05, 2.27705273e-05, 2.58349660e-05, 2.57189853e-05, + 2.56005715e-05, 2.58342062e-05, 2.57053255e-05, 2.41088920e-05, 2.32210128e-05, 2.37882787e-05, + 2.53721189e-05, 2.54041210e-05, 2.62048281e-05, 2.54513756e-05, 2.31423111e-05, 2.30894014e-05, + 2.35347181e-05, 2.48640511e-05, 2.55226576e-05, 2.59875344e-05, 2.62540412e-05, 2.58497990e-05, + 2.49307168e-05, 2.39321450e-05, 2.27709134e-05, 2.55330404e-05, 2.77962631e-05, 2.81724900e-05, + 2.72614950e-05, 2.53637912e-05, 2.30843846e-05, 2.17227439e-05, 2.16362467e-05, 2.17529763e-05, + 2.51811920e-05, 2.67798031e-05, 2.63437731e-05, 2.53533355e-05, 2.51791896e-05, 2.48465501e-05, + 2.32232982e-05, 2.17874548e-05, 2.19907864e-05, 2.22490322e-05, 2.16126271e-05, 2.61571929e-05, + 2.75647004e-05, 2.74382832e-05, 2.58284487e-05, 2.47535252e-05, 2.44838425e-05, 2.27311589e-05, + 2.09690198e-05, 2.04100503e-05, 2.74406898e-05, 2.89425859e-05, 2.85333072e-05, 2.51298751e-05, + 2.18799226e-05, 2.14768436e-05, 2.14461948e-05, 2.10987242e-05, 2.10294088e-05, 2.48020476e-05, + 2.75636399e-05, 2.82093768e-05, 2.62357506e-05, 2.38871707e-05, 2.39115477e-05, 2.41159970e-05, + 2.28204789e-05, 2.12769405e-05, 2.20798654e-05, 2.48155671e-05, 2.81793610e-05, 2.89796698e-05, + 2.82194166e-05, 2.53180782e-05, 2.15331136e-05, 2.01503712e-05, 2.06369561e-05, 2.72355114e-05, + 2.86536753e-05, 2.83518447e-05, 2.63909087e-05, 2.30979238e-05, 2.04902226e-05, 1.98427032e-05, + 2.07430291e-05, 2.79180144e-05, 2.88470383e-05, 2.83645209e-05, 2.60770734e-05, 2.18154073e-05, + 1.97755973e-05, 2.04520099e-05, 2.12239276e-05, 2.81670732e-05, 2.90099571e-05, 2.79386365e-05, + 2.50344094e-05, 2.34421577e-05, 2.26057798e-05, 2.17582117e-05, 2.64560558e-05, 2.76581194e-05, + 2.78719704e-05, 2.73603615e-05, 2.48029940e-05, 2.17365555e-05, 2.10513336e-05, 2.13806137e-05, + 2.60461227e-05, 2.73345054e-05, 2.72706784e-05, 2.63101192e-05, 2.53577465e-05, 2.44027652e-05, + 2.24231642e-05, 2.14788550e-05, 2.56405599e-05, 2.73995862e-05, 2.73532203e-05, 2.67424810e-05, + 2.61913647e-05, 2.45777896e-05, 2.24791841e-05, 2.12830336e-05, 2.13438625e-05, 2.44384558e-05, + 2.74404015e-05, 2.89568061e-05, 2.88705658e-05, 2.67671361e-05, 2.23592691e-05, 2.09015627e-05, + 2.24737505e-05, 2.69823268e-05, 2.80611902e-05, 2.71575704e-05, 2.50043017e-05, 2.43416448e-05, + 2.36275315e-05, 2.19905059e-05, 2.14999107e-05, 2.43551835e-05, 2.70280162e-05, 2.82879421e-05, + 2.71585101e-05, 2.51877914e-05, 2.29825084e-05, 2.15614449e-05, 2.15411146e-05, 2.54958542e-05, + 2.73851193e-05, 2.76190535e-05, 2.64062891e-05, 2.47202304e-05, 2.32218272e-05, 2.14884339e-05, + 2.19280854e-05, 2.26970829e-05, 2.53867293e-05, 2.80874481e-05, 2.88276863e-05, 2.74505884e-05, + 2.40854644e-05, 2.18165396e-05, 2.04055299e-05, 2.02547107e-05, 2.10710374e-05, 2.62976283e-05, + 2.74879098e-05, 2.76627829e-05, 2.59440868e-05, 2.31141165e-05, 2.33207117e-05, 2.23925944e-05, + 2.08138218e-05, 2.62065697e-05, 2.73747230e-05, 2.74074032e-05, 2.70368579e-05, 2.59770350e-05, + 2.32828972e-05, 2.18351972e-05, 2.22943084e-05, 2.70616099e-05, 2.84833253e-05, 2.80603928e-05, + 2.51086799e-05, 2.15642884e-05, 2.14621938e-05, 2.19559419e-05, 2.52534481e-05, 2.71299668e-05, + 2.80299431e-05, 2.76476275e-05, 2.57395497e-05, 2.38692958e-05, 2.24976041e-05, 2.10682931e-05, + 2.55403698e-05, 2.76478561e-05, 2.79869271e-05, 2.71045422e-05, 2.53017212e-05, 2.31661687e-05, + 2.18739473e-05, 2.18060070e-05, 2.19413088e-05, 2.52202838e-05, 2.67269256e-05, 2.63248638e-05, + 2.53649949e-05, 2.51954487e-05, 2.48834645e-05, 2.33044623e-05, 2.19198962e-05, 2.21448488e-05, + 2.24141105e-05, 2.18014566e-05, 2.61061847e-05, 2.74160329e-05, 2.73336920e-05, 2.57947055e-05, + 2.47609466e-05, 2.45468541e-05, 2.28818378e-05, 2.11660172e-05, 2.06207126e-05, 2.73087936e-05, + 2.86243562e-05, 2.82979178e-05, 2.50800037e-05, 2.19476574e-05, 2.16251885e-05, 2.16425898e-05, + 2.13039014e-05, 2.12336295e-05, 2.47479475e-05, 2.73262297e-05, 2.79786914e-05, 2.61493217e-05, + 2.39298838e-05, 2.40174928e-05, 2.42574508e-05, 2.30011161e-05, 2.14907007e-05, 2.21726064e-05, + 2.47744716e-05, 2.79690467e-05, 2.87059858e-05, 2.80303937e-05, 2.53190759e-05, 2.16965851e-05, + 2.03775165e-05, 2.08603147e-05, 2.71545936e-05, 2.83719267e-05, 2.80878774e-05, 2.62746931e-05, + 2.31566326e-05, 2.06587188e-05, 2.00507395e-05, 2.09510568e-05, 2.78104011e-05, 2.85275805e-05, + 2.80769569e-05, 2.59876872e-05, 2.19273767e-05, 1.99794022e-05, 2.06735970e-05, 2.14264430e-05, + 2.79510238e-05, 2.86165583e-05, 2.76751836e-05, 2.49542212e-05, 2.35162658e-05, 2.27987179e-05, + 2.19789357e-05, 2.63658302e-05, 2.74200694e-05, 2.76400451e-05, 2.72495161e-05, 2.48813742e-05, + 2.19175103e-05, 2.12553564e-05, 2.15784465e-05, 2.59827043e-05, 2.71447127e-05, 2.70952103e-05, + 2.62210545e-05, 2.53797682e-05, 2.45229814e-05, 2.26042000e-05, 2.16738544e-05, 2.56037959e-05, + 2.72405254e-05, 2.72039538e-05, 2.66114627e-05, 2.61286867e-05, 2.46547620e-05, 2.26538564e-05, + 2.14859189e-05, 2.15427815e-05, 2.43409133e-05, 2.71198167e-05, 2.85820604e-05, 2.86345505e-05, + 2.67913171e-05, 2.25636659e-05, 2.11231760e-05, 2.26861280e-05, 2.68554913e-05, 2.77729151e-05, + 2.69672091e-05, 2.49702558e-05, 2.43821445e-05, 2.37479899e-05, 2.21686854e-05, 2.16891387e-05, + 2.42717273e-05, 2.68262869e-05, 2.80662702e-05, 2.70508910e-05, 2.52079532e-05, 2.31300609e-05, + 2.17641619e-05, 2.17309042e-05, 2.54792892e-05, 2.72180626e-05, 2.74309403e-05, 2.62870720e-05, + 2.47099911e-05, 2.33244925e-05, 2.16712983e-05, 2.21210211e-05, 2.28908549e-05, 2.53254777e-05, + 2.78416079e-05, 2.85655066e-05, 2.73382906e-05, 2.41264053e-05, 2.19527105e-05, 2.06149791e-05, + 2.04779617e-05, 2.12778442e-05, 2.61380841e-05, 2.71738469e-05, 2.74124916e-05, 2.58845313e-05, + 2.32441237e-05, 2.35393649e-05, 2.26357360e-05, 2.10490865e-05, 2.61739597e-05, 2.71639024e-05, + 2.71720981e-05, 2.68908208e-05, 2.59545563e-05, 2.33792291e-05, 2.19962241e-05, 2.24796744e-05, + 2.68339302e-05, 2.80808377e-05, 2.78439673e-05, 2.51650768e-05, 2.17513993e-05, 2.16554840e-05, + 2.21491845e-05, 2.51928078e-05, 2.69186006e-05, 2.77802646e-05, 2.74918416e-05, 2.57737653e-05, + 2.40147261e-05, 2.26769911e-05, 2.12676781e-05, 2.45333646e-05, 2.12256130e-05, 2.04154223e-05, + 2.20479774e-05, 2.45375703e-05, 2.67509996e-05, 2.77467718e-05, 2.78287696e-05, 2.77922136e-05, + 2.49463459e-05, 2.29727472e-05, 2.35874204e-05, 2.47227170e-05, 2.49018424e-05, 2.52555087e-05, + 2.66522938e-05, 2.76739400e-05, 2.75958518e-05, 2.74573530e-05, 2.78732532e-05, 2.37331110e-05, + 2.16099398e-05, 2.19223442e-05, 2.41349541e-05, 2.52752091e-05, 2.56289884e-05, 2.71221348e-05, + 2.82312467e-05, 2.85231687e-05, 2.18494527e-05, 1.77296556e-05, 1.94358572e-05, 2.47922286e-05, + 2.74768394e-05, 2.78785116e-05, 2.79777988e-05, 2.81772205e-05, 2.82116316e-05, 2.50782742e-05, + 2.13356715e-05, 2.01949802e-05, 2.35560068e-05, 2.60757106e-05, 2.61827811e-05, 2.60733955e-05, + 2.71076758e-05, 2.80953717e-05, 2.74197859e-05, 2.51010531e-05, 2.03244780e-05, 1.78044738e-05, + 2.03083237e-05, 2.47344522e-05, 2.78754633e-05, 2.86647294e-05, 2.84351267e-05, 2.22822786e-05, + 1.89297934e-05, 1.97664584e-05, 2.32962202e-05, 2.66907371e-05, 2.84133402e-05, 2.87661036e-05, + 2.83610726e-05, 2.11118504e-05, 1.81194969e-05, 1.96452251e-05, 2.37267423e-05, 2.76157529e-05, + 2.87864126e-05, 2.85201692e-05, 2.81073616e-05, 2.03308778e-05, 1.67568699e-05, 2.06057451e-05, + 2.47975802e-05, 2.64798176e-05, 2.72694947e-05, 2.78347066e-05, 2.32882231e-05, 2.11813040e-05, + 2.08377168e-05, 2.20257092e-05, 2.53740943e-05, 2.77901111e-05, 2.82000380e-05, 2.80159299e-05, + 2.38275515e-05, 2.18426192e-05, 2.19800602e-05, 2.34634410e-05, 2.47397828e-05, 2.57986982e-05, + 2.73720144e-05, 2.79576282e-05, 2.43246126e-05, 2.18373151e-05, 2.19347389e-05, 2.28254772e-05, + 2.36663392e-05, 2.55734367e-05, 2.73262985e-05, 2.80763407e-05, 2.80375557e-05, 2.52601909e-05, + 2.12100054e-05, 1.72750519e-05, 1.84201236e-05, 2.31364230e-05, 2.74455968e-05, 2.83021158e-05, + 2.73815638e-05, 2.25227757e-05, 2.02806000e-05, 2.20955134e-05, 2.49490453e-05, 2.57038198e-05, + 2.64294745e-05, 2.76364570e-05, 2.79370090e-05, 2.53712658e-05, 2.22374193e-05, 2.00587169e-05, + 2.23289290e-05, 2.49017902e-05, 2.69453894e-05, 2.79230180e-05, 2.79149452e-05, 2.45188417e-05, + 2.18359576e-05, 2.14079025e-05, 2.32697717e-05, 2.52630447e-05, 2.66966354e-05, 2.79331876e-05, + 2.76962967e-05, 2.72095151e-05, 2.45174099e-05, 2.03879936e-05, 1.84641738e-05, 2.18844172e-05, + 2.59149335e-05, 2.76645809e-05, 2.85233574e-05, 2.86127309e-05, 2.81940405e-05, 2.32769138e-05, + 2.11642247e-05, 2.11306077e-05, 2.39488304e-05, 2.68234031e-05, 2.67956635e-05, 2.74685395e-05, + 2.83644658e-05, 2.37186380e-05, 2.17156516e-05, 2.15841270e-05, 2.23954272e-05, 2.39993130e-05, + 2.66405611e-05, 2.76996803e-05, 2.74604993e-05, 2.21047136e-05, 1.88086619e-05, 2.05407792e-05, + 2.50488034e-05, 2.78977698e-05, 2.79642141e-05, 2.76801025e-05, 2.46474099e-05, 2.20660454e-05, + 2.04853240e-05, 2.14559673e-05, 2.43709277e-05, 2.62802015e-05, 2.73214148e-05, 2.81841502e-05, + 2.33923105e-05, 1.77594714e-05, 1.65785454e-05, 1.91896503e-05, 2.37410794e-05, 2.85167272e-05, + 3.11452339e-05, 3.12786963e-05, 3.10074705e-05, 2.41572553e-05, 2.04967110e-05, 2.15474051e-05, + 2.37881132e-05, 2.41679001e-05, 2.48807811e-05, 2.82353758e-05, 3.10493973e-05, 3.06108774e-05, + 3.00777288e-05, 3.12818733e-05, 2.19711030e-05, 1.84012542e-05, 1.87912424e-05, 2.27268773e-05, + 2.50844443e-05, 2.56396268e-05, 2.91415717e-05, 3.25164218e-05, 3.35568730e-05, 1.87557925e-05, + 1.31011157e-05, 1.52459470e-05, 2.42577607e-05, 3.09357332e-05, 3.16338237e-05, 3.15889676e-05, + 3.22426430e-05, 3.23798062e-05, 2.49572549e-05, 1.82332159e-05, 1.63652508e-05, 2.17650822e-05, + 2.68963081e-05, 2.67991060e-05, 2.63251095e-05, 2.89036208e-05, 3.18722240e-05, 3.05202537e-05, + 2.49372969e-05, 1.65073622e-05, 1.31056324e-05, 1.64232627e-05, 2.38658103e-05, 3.14942590e-05, + 3.40020764e-05, 3.30817606e-05, 1.93402326e-05, 1.46386596e-05, 1.58073170e-05, 2.13731304e-05, + 2.85042885e-05, 3.35134363e-05, 3.46505570e-05, 3.29233592e-05, 1.74545322e-05, 1.36163175e-05, + 1.56905920e-05, 2.21267826e-05, 3.10228020e-05, 3.47914853e-05, 3.34427249e-05, 3.20064640e-05, + 1.65334886e-05, 1.20266667e-05, 1.71091194e-05, 2.44376738e-05, 2.77946912e-05, 2.93063913e-05, + 3.09123296e-05, 2.12477062e-05, 1.79737765e-05, 1.73853273e-05, 1.89909520e-05, 2.49492916e-05, + 3.10569323e-05, 3.23378079e-05, 3.17133778e-05, 2.22184539e-05, 1.89441288e-05, 1.91355801e-05, + 2.15902789e-05, 2.37766887e-05, 2.57544231e-05, 2.96978774e-05, 3.15286519e-05, 2.31460909e-05, + 1.88268521e-05, 1.89630568e-05, 2.05194051e-05, 2.18857175e-05, 2.54305831e-05, 2.95998400e-05, + 3.18903831e-05, 3.17822775e-05, 2.56775860e-05, 1.83177875e-05, 1.26360693e-05, 1.38350744e-05, + 2.05262295e-05, 2.97698209e-05, 3.25769625e-05, 2.95215119e-05, 1.99372188e-05, 1.66678423e-05, + 1.93971802e-05, 2.45373303e-05, 2.59501846e-05, 2.73674452e-05, 3.05625644e-05, 3.15017524e-05, + 2.58692154e-05, 1.96996081e-05, 1.61321957e-05, 1.95154733e-05, 2.41485524e-05, 2.86407149e-05, + 3.13471989e-05, 3.14197076e-05, 2.34730491e-05, 1.88521627e-05, 1.81888496e-05, 2.13334879e-05, + 2.51530458e-05, 2.82180734e-05, 3.15393981e-05, 3.06516433e-05, 2.91217133e-05, 2.36915582e-05, + 1.67090263e-05, 1.39514627e-05, 1.87512090e-05, 2.64855312e-05, 3.09861179e-05, 3.35691717e-05, + 3.38154615e-05, 3.22918887e-05, 2.15264184e-05, 1.82138433e-05, 1.79299490e-05, 2.24529227e-05, + 2.84019990e-05, 2.78016562e-05, 2.95951445e-05, 3.27030245e-05, 2.18643251e-05, 1.87965788e-05, + 1.86548215e-05, 1.97756750e-05, 2.23936550e-05, 2.81004616e-05, 3.09049240e-05, 2.99445893e-05, + 1.95580775e-05, 1.47765454e-05, 1.68625502e-05, 2.43060850e-05, 3.13807661e-05, 3.15655274e-05, + 3.05959604e-05, 2.39824982e-05, 1.94237498e-05, 1.68741479e-05, 1.81644905e-05, 2.29247321e-05, + 2.68316018e-05, 2.95530235e-05, 3.23174105e-05, 2.43957324e-05, 2.09205710e-05, 2.00765270e-05, + 2.21048357e-05, 2.49877801e-05, 2.70883887e-05, 2.79722972e-05, 2.79017408e-05, 2.76398655e-05, + 2.47324195e-05, 2.26485552e-05, 2.32538577e-05, 2.46357852e-05, 2.48601310e-05, 2.52058183e-05, + 2.69367744e-05, 2.80603337e-05, 2.76932529e-05, 2.73539040e-05, 2.77646372e-05, 2.37072548e-05, + 2.14423793e-05, 2.15708836e-05, 2.41512800e-05, 2.54963306e-05, 2.55320265e-05, 2.69755679e-05, + 2.82601689e-05, 2.85930065e-05, 2.16563743e-05, 1.73682496e-05, 1.90918074e-05, 2.52697052e-05, + 2.84621431e-05, 2.82250583e-05, 2.78505687e-05, 2.80775183e-05, 2.81449786e-05, 2.57521811e-05, + 2.16683837e-05, 2.00613903e-05, 2.37296257e-05, 2.64044085e-05, 2.59716620e-05, 2.54886208e-05, + 2.66552149e-05, 2.78487319e-05, 2.80761880e-05, 2.56680706e-05, 2.01081515e-05, 1.72333672e-05, + 1.99565640e-05, 2.47425701e-05, 2.80487908e-05, 2.86371186e-05, 2.82950284e-05, 2.18985564e-05, + 1.87007038e-05, 1.96941566e-05, 2.35853690e-05, 2.72285211e-05, 2.89134908e-05, 2.90508431e-05, + 2.83496411e-05, 2.05108918e-05, 1.78676589e-05, 1.96755709e-05, 2.40032144e-05, 2.81930258e-05, + 2.91413064e-05, 2.84580079e-05, 2.79931381e-05, 2.01520910e-05, 1.65322475e-05, 2.08268941e-05, + 2.55511006e-05, 2.67337131e-05, 2.67789511e-05, 2.73619874e-05, 2.33718826e-05, 2.14559910e-05, + 2.09387122e-05, 2.17538258e-05, 2.50218087e-05, 2.77162899e-05, 2.81281108e-05, 2.78964806e-05, + 2.39422482e-05, 2.20487470e-05, 2.21407478e-05, 2.36158595e-05, 2.45743499e-05, 2.52768673e-05, + 2.70556186e-05, 2.78333025e-05, 2.44539594e-05, 2.18260899e-05, 2.18932500e-05, 2.30175568e-05, + 2.37025638e-05, 2.53258875e-05, 2.70495898e-05, 2.79384964e-05, 2.79195559e-05, 2.64614464e-05, + 2.20816285e-05, 1.70875456e-05, 1.78041812e-05, 2.23238173e-05, 2.69319333e-05, 2.80959762e-05, + 2.67552627e-05, 2.25559331e-05, 2.05410850e-05, 2.24117186e-05, 2.53693334e-05, 2.58493134e-05, + 2.62079880e-05, 2.75000492e-05, 2.78634413e-05, 2.65050336e-05, 2.26996738e-05, 1.98255011e-05, + 2.21479913e-05, 2.48269164e-05, 2.67332521e-05, 2.76933772e-05, 2.78214916e-05, 2.45722101e-05, + 2.18797260e-05, 2.14309958e-05, 2.35702893e-05, 2.56372520e-05, 2.67915705e-05, 2.79275896e-05, + 2.74384479e-05, 2.66800087e-05, 2.49500320e-05, 2.04155788e-05, 1.79980350e-05, 2.15713464e-05, + 2.61703767e-05, 2.80029437e-05, 2.86078621e-05, 2.85951445e-05, 2.80867006e-05, 2.39027678e-05, + 2.19671875e-05, 2.14688999e-05, 2.40883361e-05, 2.67182630e-05, 2.58360929e-05, 2.65815187e-05, + 2.80427904e-05, 2.35434766e-05, 2.20184596e-05, 2.20057874e-05, 2.25156416e-05, 2.38651919e-05, + 2.67664862e-05, 2.77866007e-05, 2.71484729e-05, 2.27009707e-05, 1.92457816e-05, 2.04353840e-05, + 2.47360036e-05, 2.78230831e-05, 2.78627912e-05, 2.74097090e-05, 2.51429251e-05, 2.25233986e-05, + 2.05722989e-05, 2.12801255e-05, 2.39467529e-05, 2.57547830e-05, 2.69941955e-05, 2.81546017e-05, + 2.37878169e-05, 1.88568468e-05, 1.77763692e-05, 2.02051292e-05, 2.42037665e-05, 2.80450151e-05, + 3.00347226e-05, 3.00960531e-05, 2.98346199e-05, 2.44084430e-05, 2.12778031e-05, 2.21831557e-05, + 2.41293276e-05, 2.44547794e-05, 2.50412943e-05, 2.78120216e-05, 3.00029664e-05, 2.95992317e-05, + 2.91437231e-05, 3.00515882e-05, 2.26093154e-05, 1.94597959e-05, 1.97723315e-05, 2.32603634e-05, + 2.52677830e-05, 2.56505950e-05, 2.84146167e-05, 3.10025760e-05, 3.17709128e-05, 1.97714820e-05, + 1.45046305e-05, 1.65422050e-05, 2.46401691e-05, 3.00632684e-05, 3.04315258e-05, 3.02758388e-05, + 3.07670390e-05, 3.08767667e-05, 2.52602970e-05, 1.94028785e-05, 1.76180112e-05, 2.24736986e-05, + 2.67601547e-05, 2.65585517e-05, 2.60914589e-05, 2.81548451e-05, 3.04544704e-05, 2.96682228e-05, + 2.52212197e-05, 1.77335932e-05, 1.44731679e-05, 1.76314694e-05, 2.42144800e-05, 3.02830716e-05, + 3.20638612e-05, 3.13696885e-05, 2.02525401e-05, 1.59926783e-05, 1.71133823e-05, 2.21598483e-05, + 2.80820025e-05, 3.18551672e-05, 3.26126714e-05, 3.12894258e-05, 1.85248635e-05, 1.50178961e-05, + 1.70231700e-05, 2.28039593e-05, 3.00301972e-05, 3.27320401e-05, 3.16523614e-05, 3.05889179e-05, + 1.77644494e-05, 1.34834148e-05, 1.83640699e-05, 2.48472431e-05, 2.74576948e-05, 2.84558012e-05, + 2.96796102e-05, 2.20105806e-05, 1.91584825e-05, 1.85937522e-05, 1.99653018e-05, 2.50300649e-05, + 2.98920139e-05, 3.08444798e-05, 3.03703712e-05, 2.28491658e-05, 2.00153993e-05, 2.01769926e-05, + 2.23193860e-05, 2.41028634e-05, 2.56465511e-05, 2.88000144e-05, 3.02316933e-05, 2.36376372e-05, + 1.98696757e-05, 1.99850820e-05, 2.14004641e-05, 2.25490680e-05, 2.54466200e-05, 2.87349312e-05, + 3.04967854e-05, 3.04218970e-05, 2.59623892e-05, 1.95768389e-05, 1.40839579e-05, 1.51635969e-05, + 2.12029386e-05, 2.88047845e-05, 3.09838540e-05, 2.85861627e-05, 2.08600728e-05, 1.79671221e-05, + 2.04384786e-05, 2.48598727e-05, 2.59569293e-05, 2.70082733e-05, 2.95034494e-05, 3.02248977e-05, + 2.61049346e-05, 2.07334874e-05, 1.73851018e-05, 2.04471108e-05, 2.44315446e-05, 2.80102382e-05, + 3.00688180e-05, 3.01585152e-05, 2.38961128e-05, 1.99027074e-05, 1.93053953e-05, 2.21279122e-05, + 2.53572616e-05, 2.77538406e-05, 3.02706394e-05, 2.95395790e-05, 2.83038521e-05, 2.41586760e-05, + 1.79630535e-05, 1.53005837e-05, 1.97441752e-05, 2.64138870e-05, 2.99432477e-05, 3.17837915e-05, + 3.19329538e-05, 3.08012548e-05, 2.23584354e-05, 1.94708805e-05, 1.91305867e-05, 2.30537129e-05, + 2.78500716e-05, 2.71703041e-05, 2.85747819e-05, 3.10444444e-05, 2.24872814e-05, 1.99020566e-05, + 1.97975120e-05, 2.07350256e-05, 2.29466214e-05, 2.76687924e-05, 2.98187286e-05, 2.89895349e-05, + 2.06336541e-05, 1.62370303e-05, 1.80793880e-05, 2.45098171e-05, 3.01343166e-05, 3.02651461e-05, + 2.94943241e-05, 2.44148312e-05, 2.04886738e-05, 1.81250572e-05, 1.92459480e-05, 2.33337931e-05, + 2.65103928e-05, 2.86863383e-05, 3.08407458e-05, 2.49401200e-05, 3.43402217e-05, 3.67114800e-05, + 3.21623649e-05, 2.51007573e-05, 1.87917292e-05, 1.58968272e-05, 1.56448671e-05, 1.57317150e-05, + 2.37551857e-05, 2.92683370e-05, 2.75190400e-05, 2.44257785e-05, 2.39370401e-05, 2.29418661e-05, + 1.90681026e-05, 1.61177263e-05, 1.63329963e-05, 1.67145224e-05, 1.54971895e-05, 2.72477371e-05, + 3.33109172e-05, 3.22706680e-05, 2.61216038e-05, 2.29547415e-05, 2.18827543e-05, 1.76705835e-05, + 1.44292086e-05, 1.35187726e-05, 3.25916743e-05, 4.48838048e-05, 3.96534371e-05, 2.43790003e-05, + 1.66824549e-05, 1.55078958e-05, 1.51843250e-05, 1.45859639e-05, 1.44835371e-05, 2.35933456e-05, + 3.44354639e-05, 3.75561190e-05, 2.78328857e-05, 2.07106914e-05, 2.03049301e-05, 2.04986629e-05, + 1.76512468e-05, 1.48192554e-05, 1.68675582e-05, 2.35133477e-05, 3.70935601e-05, 4.43468496e-05, + 3.70191726e-05, 2.44237665e-05, 1.55118106e-05, 1.30610638e-05, 1.37877008e-05, 3.12087823e-05, + 4.13267268e-05, 3.89139662e-05, 2.86252680e-05, 1.89786583e-05, 1.38596596e-05, 1.27240548e-05, + 1.40262075e-05, 3.44224198e-05, 4.38137506e-05, 3.93776402e-05, 2.73780215e-05, 1.62905415e-05, + 1.26522292e-05, 1.35240731e-05, 1.47964934e-05, 3.71069818e-05, 4.81561089e-05, 3.65802128e-05, + 2.44081426e-05, 1.95550038e-05, 1.71839197e-05, 1.55592804e-05, 2.85675033e-05, 3.48682999e-05, + 3.57951305e-05, 3.20255898e-05, 2.25151268e-05, 1.57465591e-05, 1.45185559e-05, 1.50710366e-05, + 2.70327931e-05, 3.28506951e-05, 3.24192929e-05, 2.80910583e-05, 2.43505650e-05, 2.12795428e-05, + 1.69268389e-05, 1.52447972e-05, 2.56216308e-05, 3.27427580e-05, 3.24379630e-05, 2.99539791e-05, + 2.74634783e-05, 2.19947801e-05, 1.70649400e-05, 1.48878844e-05, 1.50063248e-05, 2.31030353e-05, + 3.50657684e-05, 4.65599065e-05, 4.24029763e-05, 2.84942243e-05, 1.66767541e-05, 1.41950124e-05, + 1.68333487e-05, 3.07601006e-05, 3.76022516e-05, 3.21553786e-05, 2.39209452e-05, 2.17297873e-05, + 1.96119241e-05, 1.61900511e-05, 1.53111329e-05, 2.27823152e-05, 3.17983800e-05, 3.78787531e-05, + 3.12036865e-05, 2.39266943e-05, 1.81611638e-05, 1.53359019e-05, 1.53749389e-05, 2.50468555e-05, + 3.27795427e-05, 3.40350691e-05, 2.87060698e-05, 2.30201298e-05, 1.89180259e-05, 1.53283115e-05, + 1.59989244e-05, 1.73450129e-05, 2.51544764e-05, 3.71030134e-05, 4.24713540e-05, 3.24078274e-05, + 2.11545103e-05, 1.61442388e-05, 1.35184263e-05, 1.32296864e-05, 1.45341564e-05, 2.87884663e-05, + 3.51799541e-05, 3.50580646e-05, 2.66951714e-05, 1.85263677e-05, 1.83727723e-05, 1.65160553e-05, + 1.39913028e-05, 2.72242266e-05, 3.32794365e-05, 3.37332765e-05, 3.11762590e-05, 2.64472533e-05, + 1.90816015e-05, 1.60273918e-05, 1.66734762e-05, 3.22471393e-05, 4.23494763e-05, 3.65363629e-05, + 2.34338729e-05, 1.54277968e-05, 1.52273917e-05, 1.60443001e-05, 2.47962245e-05, 3.23064337e-05, + 3.68522413e-05, 3.37582760e-05, 2.52767287e-05, 1.99455898e-05, 1.70696986e-05, 1.45699127e-05, + 2.55861745e-05, 3.10488232e-05, 3.22614144e-05, 2.94220745e-05, 2.50452225e-05, 2.10594683e-05, + 1.90020429e-05, 1.89173710e-05, 1.91530365e-05, 2.49222805e-05, 2.83713174e-05, 2.73726816e-05, + 2.52106920e-05, 2.48552937e-05, 2.42273064e-05, 2.12995377e-05, 1.90534147e-05, 1.94351312e-05, + 1.98837208e-05, 1.89338707e-05, 2.68427875e-05, 3.03255051e-05, 3.00506161e-05, 2.61311655e-05, + 2.39617660e-05, 2.35783543e-05, 2.06444120e-05, 1.79718164e-05, 1.71871680e-05, 2.99930320e-05, + 3.58365450e-05, 3.36237821e-05, 2.45838906e-05, 1.90337990e-05, 1.86112680e-05, 1.86964574e-05, + 1.81899485e-05, 1.80826989e-05, 2.39067975e-05, 3.01557341e-05, 3.23226709e-05, 2.69407129e-05, + 2.23908821e-05, 2.26089312e-05, 2.30979458e-05, 2.08835130e-05, 1.84855924e-05, 1.94147832e-05, + 2.39647363e-05, 3.22431123e-05, 3.60454525e-05, 3.24284576e-05, 2.51070804e-05, 1.87393538e-05, + 1.68603615e-05, 1.75533385e-05, 2.95268412e-05, 3.41427620e-05, 3.28310313e-05, 2.72432663e-05, + 2.10227693e-05, 1.71893205e-05, 1.63743447e-05, 1.76664324e-05, 3.15440458e-05, 3.52008270e-05, + 3.28605642e-05, 2.65617258e-05, 1.90436699e-05, 1.62695830e-05, 1.72783716e-05, 1.83724940e-05, + 3.21887042e-05, 3.67629295e-05, 3.13169516e-05, 2.43165982e-05, 2.16670512e-05, 2.05561772e-05, + 1.92554969e-05, 2.74624045e-05, 3.04446034e-05, 3.11388885e-05, 2.98083222e-05, 2.42560919e-05, + 1.91061988e-05, 1.81151580e-05, 1.85993081e-05, 2.65527199e-05, 2.95638364e-05, 2.94100439e-05, + 2.71116755e-05, 2.52484252e-05, 2.35856244e-05, 2.02161314e-05, 1.87430738e-05, 2.57054596e-05, + 2.98133347e-05, 2.96999929e-05, 2.80851267e-05, 2.68937748e-05, 2.38022394e-05, 2.02906390e-05, + 1.84638272e-05, 1.85458529e-05, 2.30964187e-05, 2.96788450e-05, 3.61162629e-05, 3.53238497e-05, + 2.85593835e-05, 2.01793866e-05, 1.79403319e-05, 2.03935536e-05, 2.87216655e-05, 3.17128326e-05, + 2.90650284e-05, 2.43639495e-05, 2.32413274e-05, 2.21286753e-05, 1.95022960e-05, 1.87594009e-05, + 2.29671027e-05, 2.86906565e-05, 3.26339650e-05, 2.92455177e-05, 2.48838734e-05, 2.10649800e-05, + 1.88935669e-05, 1.88250204e-05, 2.54418151e-05, 2.97547148e-05, 3.04105326e-05, 2.72738003e-05, + 2.38502642e-05, 2.13550707e-05, 1.87237244e-05, 1.94445910e-05, 2.07128187e-05, 2.50959637e-05, + 3.18569271e-05, 3.50646308e-05, 3.00681044e-05, 2.27554769e-05, 1.91092710e-05, 1.71772818e-05, + 1.69985387e-05, 1.81527319e-05, 2.69263193e-05, 2.98269301e-05, 3.04406164e-05, 2.63279386e-05, + 2.12430749e-05, 2.18745247e-05, 2.03534244e-05, 1.78488039e-05, 2.70071654e-05, 2.96410372e-05, + 2.96946340e-05, 2.88256216e-05, 2.64985948e-05, 2.14450192e-05, 1.92064522e-05, 2.00161797e-05, + 2.87357942e-05, 3.33692511e-05, 3.18054382e-05, 2.48197590e-05, 1.88535438e-05, 1.87124165e-05, + 1.94900888e-05, 2.48157024e-05, 2.89504188e-05, 3.16489799e-05, 3.05638639e-05, 2.61174293e-05, + 2.26462771e-05, 2.03350310e-05, 1.81276942e-05, 2.54199633e-05, 2.53078504e-05, 2.51403424e-05, + 2.49608119e-05, 2.46557506e-05, 2.44162618e-05, 2.40836650e-05, 2.42087585e-05, 2.44919477e-05, + 2.54887847e-05, 2.56325403e-05, 2.56871604e-05, 2.53424011e-05, 2.52697215e-05, 2.52413458e-05, + 2.45133113e-05, 2.39408125e-05, 2.43197631e-05, 2.46299917e-05, 2.43890501e-05, 2.52745877e-05, + 2.51934337e-05, 2.55239578e-05, 2.52263047e-05, 2.48947791e-05, 2.52425839e-05, 2.48455226e-05, + 2.39731748e-05, 2.36755316e-05, 2.52801298e-05, 2.41226966e-05, 2.48213895e-05, 2.46112978e-05, + 2.33553703e-05, 2.38627805e-05, 2.43394921e-05, 2.41613818e-05, 2.40969758e-05, 2.43449844e-05, + 2.44061671e-05, 2.47578227e-05, 2.49971581e-05, 2.46212934e-05, 2.52593702e-05, 2.57557036e-05, + 2.52173627e-05, 2.43909931e-05, 2.37630870e-05, 2.44770640e-05, 2.49251846e-05, 2.45136215e-05, + 2.51277115e-05, 2.52179400e-05, 2.40634281e-05, 2.36450508e-05, 2.39915667e-05, 2.56311533e-05, + 2.44415912e-05, 2.45173477e-05, 2.48210333e-05, 2.41975877e-05, 2.32916590e-05, 2.31909387e-05, + 2.39118722e-05, 2.57259438e-05, 2.41248754e-05, 2.43153414e-05, 2.48699744e-05, 2.37531685e-05, + 2.30908329e-05, 2.38259694e-05, 2.42310698e-05, 2.48700098e-05, 2.33846605e-05, 2.43581328e-05, + 2.42618301e-05, 2.46049005e-05, 2.51844520e-05, 2.48348313e-05, 2.50983112e-05, 2.44481905e-05, + 2.46044864e-05, 2.54272466e-05, 2.56115999e-05, 2.44025291e-05, 2.41120707e-05, 2.43037095e-05, + 2.50898135e-05, 2.47073178e-05, 2.48003971e-05, 2.50192500e-05, 2.54436599e-05, 2.57453671e-05, + 2.49255011e-05, 2.43501619e-05, 2.50760379e-05, 2.50157686e-05, 2.50788018e-05, 2.48992173e-05, + 2.51880923e-05, 2.54434222e-05, 2.49021253e-05, 2.42810053e-05, 2.42865732e-05, 2.36792311e-05, + 2.36130063e-05, 2.36011508e-05, 2.48627119e-05, 2.63359064e-05, 2.51188626e-05, 2.41813071e-05, + 2.52870437e-05, 2.50761753e-05, 2.41944585e-05, 2.46053071e-05, 2.46741982e-05, 2.49246161e-05, + 2.51995890e-05, 2.45684266e-05, 2.43060484e-05, 2.37515157e-05, 2.44307813e-05, 2.48657719e-05, + 2.53480252e-05, 2.53126393e-05, 2.50004682e-05, 2.44948901e-05, 2.43438202e-05, 2.51702640e-05, + 2.49367919e-05, 2.48698520e-05, 2.48031795e-05, 2.47032147e-05, 2.47261564e-05, 2.42306399e-05, + 2.46739222e-05, 2.52607788e-05, 2.46788171e-05, 2.45765621e-05, 2.46320386e-05, 2.54610154e-05, + 2.47467365e-05, 2.40016205e-05, 2.36589492e-05, 2.36865633e-05, 2.41569475e-05, 2.43693864e-05, + 2.36950336e-05, 2.43428579e-05, 2.50605423e-05, 2.49205921e-05, 2.59704951e-05, 2.55470724e-05, + 2.42582602e-05, 2.54758159e-05, 2.45422087e-05, 2.43431273e-05, 2.49341676e-05, 2.54262861e-05, + 2.47080755e-05, 2.42719534e-05, 2.48732022e-05, 2.42193873e-05, 2.33482726e-05, 2.48235501e-05, + 2.56060292e-05, 2.43337555e-05, 2.43193442e-05, 2.46983525e-05, 2.45945337e-05, 2.44029471e-05, + 2.45187583e-05, 2.51711682e-05, 2.58078884e-05, 2.56214745e-05, 2.49643593e-05, 2.40763636e-05, + 2.36973387e-05, 1.84421799e-05, 1.73197475e-05, 1.93659271e-05, 2.31943207e-05, 2.78474863e-05, + 3.04709010e-05, 3.08447048e-05, 3.09642006e-05, 2.45454628e-05, 2.11535558e-05, 2.21916623e-05, + 2.40043577e-05, 2.43027285e-05, 2.49965945e-05, 2.76658816e-05, 3.01222182e-05, 3.01819382e-05, + 3.00094769e-05, 3.11487415e-05, 2.21688553e-05, 1.88919909e-05, 1.95193765e-05, 2.28369849e-05, + 2.47928397e-05, 2.57921515e-05, 2.91965155e-05, 3.20696233e-05, 3.29637247e-05, 1.92728535e-05, + 1.38820938e-05, 1.60036713e-05, 2.36441183e-05, 2.90764548e-05, 3.07260847e-05, 3.14676109e-05, + 3.20323943e-05, 3.21042879e-05, 2.40249728e-05, 1.80854883e-05, 1.68485086e-05, 2.16946473e-05, + 2.63434484e-05, 2.70735638e-05, 2.72036209e-05, 2.94675701e-05, 3.19352266e-05, 2.92074532e-05, + 2.41571607e-05, 1.70929902e-05, 1.41386667e-05, 1.71824270e-05, 2.39410484e-05, 3.08800916e-05, + 3.35436818e-05, 3.28841719e-05, 2.01026261e-05, 1.52581642e-05, 1.62226177e-05, 2.11619791e-05, + 2.75295825e-05, 3.21966901e-05, 3.35987077e-05, 3.25160249e-05, 1.85326323e-05, 1.42673195e-05, + 1.59820439e-05, 2.19000373e-05, 2.97932532e-05, 3.36064282e-05, 3.30852799e-05, 3.18363492e-05, + 1.70712303e-05, 1.26446948e-05, 1.71348886e-05, 2.34277919e-05, 2.72997930e-05, 2.99148698e-05, + 3.14136696e-05, 2.13203004e-05, 1.79074181e-05, 1.75537436e-05, 1.96084439e-05, 2.55156018e-05, + 3.08801061e-05, 3.20740797e-05, 3.15710137e-05, 2.22109602e-05, 1.89338539e-05, 1.91779330e-05, + 2.15558703e-05, 2.41078414e-05, 2.65532988e-05, 2.99998061e-05, 3.14062385e-05, 2.30790831e-05, + 1.91024657e-05, 1.92748507e-05, 2.04724826e-05, 2.20001126e-05, 2.58197007e-05, 2.98416713e-05, + 3.17677005e-05, 3.16330518e-05, 2.39596378e-05, 1.75034185e-05, 1.32125524e-05, 1.49293068e-05, + 2.18755256e-05, 3.03955992e-05, 3.25265827e-05, 3.03469723e-05, 2.01222980e-05, 1.66572478e-05, + 1.92290872e-05, 2.39888080e-05, 2.57244548e-05, 2.76317645e-05, 3.05196395e-05, 3.12960730e-05, + 2.42291027e-05, 1.93315329e-05, 1.67437271e-05, 1.99992452e-05, 2.43326386e-05, 2.88276106e-05, + 3.14129906e-05, 3.12525268e-05, 2.34999450e-05, 1.90552229e-05, 1.84363257e-05, 2.11087188e-05, + 2.46358200e-05, 2.79429026e-05, 3.12179005e-05, 3.08050370e-05, 2.98029152e-05, 2.31720279e-05, + 1.69846632e-05, 1.48615498e-05, 1.94284529e-05, 2.60664123e-05, 3.01409394e-05, 3.29499319e-05, + 3.33535953e-05, 3.20913332e-05, 2.08593115e-05, 1.74873537e-05, 1.77854128e-05, 2.24012836e-05, + 2.84308229e-05, 2.92445669e-05, 3.08600824e-05, 3.28443548e-05, 2.22753018e-05, 1.86673106e-05, + 1.83800960e-05, 1.98502776e-05, 2.27292012e-05, 2.77840636e-05, 3.04733714e-05, 3.02264582e-05, + 1.90253117e-05, 1.46067629e-05, 1.73022836e-05, 2.48358158e-05, 3.11847524e-05, 3.14023598e-05, + 3.07733991e-05, 2.33591016e-05, 1.90734343e-05, 1.70722480e-05, 1.86708587e-05, 2.36627789e-05, + 2.75982026e-05, 2.98801815e-05, 3.19833339e-05, 2.23732722e-05, 1.53866682e-05, 1.40485468e-05, + 1.66748915e-05, 2.20004316e-05, 2.90938854e-05, 3.35354611e-05, 3.40657573e-05, 3.40636087e-05, + 2.35543193e-05, 1.87859638e-05, 2.01659018e-05, 2.28452253e-05, 2.33067690e-05, 2.43269545e-05, + 2.87518768e-05, 3.30601295e-05, 3.28968952e-05, 3.24071959e-05, 3.44418798e-05, 2.03001716e-05, + 1.59904914e-05, 1.66845485e-05, 2.12464679e-05, 2.41981292e-05, 2.54981704e-05, 3.09618139e-05, + 3.62950705e-05, 3.80635124e-05, 1.64486243e-05, 1.02878054e-05, 1.25564194e-05, 2.26648966e-05, + 3.17462486e-05, 3.41161266e-05, 3.50083844e-05, 3.60892119e-05, 3.62596445e-05, 2.33432280e-05, + 1.52183257e-05, 1.35831035e-05, 1.97613735e-05, 2.66541293e-05, 2.74146111e-05, 2.73426422e-05, + 3.11598595e-05, 3.57540214e-05, 3.16833833e-05, 2.34721570e-05, 1.38331072e-05, 1.04891982e-05, + 1.38850561e-05, 2.28114510e-05, 3.42282515e-05, 3.90984170e-05, 3.76729358e-05, 1.74021447e-05, + 1.17793802e-05, 1.28955686e-05, 1.91052517e-05, 2.87267896e-05, 3.70460771e-05, 3.95798640e-05, + 3.71039032e-05, 1.53722924e-05, 1.07193404e-05, 1.26621709e-05, 2.00947442e-05, 3.26489705e-05, + 3.96799694e-05, 3.81523039e-05, 3.57062779e-05, 1.38221388e-05, 9.08265833e-06, 1.40465866e-05, + 2.25162085e-05, 2.81295647e-05, 3.18936354e-05, 3.45652209e-05, 1.92122082e-05, 1.49807449e-05, + 1.44916930e-05, 1.68313146e-05, 2.49055561e-05, 3.39874932e-05, 3.61970105e-05, 3.52073231e-05, + 2.04337075e-05, 1.62025375e-05, 1.64859564e-05, 1.95630842e-05, 2.29470251e-05, 2.63724359e-05, + 3.21971678e-05, 3.48982292e-05, 2.16508720e-05, 1.63171314e-05, 1.65178090e-05, 1.81490931e-05, + 2.01033255e-05, 2.54370882e-05, 3.19578518e-05, 3.55538310e-05, 3.53237871e-05, 2.35756638e-05, + 1.47324498e-05, 9.65743992e-06, 1.13018194e-05, 1.94887598e-05, 3.27091487e-05, 3.69127833e-05, + 3.25209246e-05, 1.76216155e-05, 1.35084109e-05, 1.66182523e-05, 2.31330604e-05, 2.55608142e-05, + 2.83014784e-05, 3.32797310e-05, 3.47464097e-05, 2.39380778e-05, 1.68117904e-05, 1.34268040e-05, + 1.73651058e-05, 2.33298559e-05, 3.02812042e-05, 3.48052828e-05, 3.46467120e-05, 2.22044115e-05, + 1.62825507e-05, 1.55156729e-05, 1.90399961e-05, 2.40620281e-05, 2.90581324e-05, 3.46705175e-05, + 3.36751063e-05, 3.16662188e-05, 2.19583121e-05, 1.37995415e-05, 1.12778985e-05, 1.65886262e-05, + 2.61671513e-05, 3.30486589e-05, 3.80530543e-05, 3.87320800e-05, 3.61922787e-05, 1.88705567e-05, + 1.46863804e-05, 1.48600693e-05, 2.07094525e-05, 2.97055653e-05, 3.03522830e-05, 3.31781139e-05, + 3.73953988e-05, 2.03649929e-05, 1.59149452e-05, 1.56126572e-05, 1.73146245e-05, 2.10120652e-05, + 2.88211315e-05, 3.34080309e-05, 3.25975590e-05, 1.64855846e-05, 1.12902212e-05, 1.41175112e-05, + 2.39184725e-05, 3.45411959e-05, 3.49140582e-05, 3.36064179e-05, 2.22635043e-05, 1.64852457e-05, + 1.39231618e-05, 1.57171610e-05, 2.21541520e-05, 2.80140891e-05, 3.19794773e-05, 3.60703564e-05, + 2.44518688e-05, 2.09809014e-05, 2.01405678e-05, 2.19363098e-05, 2.46354470e-05, 2.69307754e-05, + 2.79625071e-05, 2.80038569e-05, 2.78945058e-05, 2.48597746e-05, 2.27743419e-05, 2.34079757e-05, + 2.46650329e-05, 2.48660744e-05, 2.52339056e-05, 2.68096358e-05, 2.79336039e-05, 2.77602792e-05, + 2.75493040e-05, 2.79956290e-05, 2.36533314e-05, 2.14174826e-05, 2.16826070e-05, 2.40838889e-05, + 2.53374292e-05, 2.56114645e-05, 2.71771446e-05, 2.84269928e-05, 2.87593924e-05, 2.16559873e-05, + 1.73991626e-05, 1.91387757e-05, 2.49097221e-05, 2.79052181e-05, 2.81422706e-05, 2.81030035e-05, + 2.83281399e-05, 2.83758981e-05, 2.52686180e-05, 2.12870768e-05, 1.99776217e-05, 2.35302587e-05, + 2.62125970e-05, 2.61598748e-05, 2.59287927e-05, 2.70668702e-05, 2.81934121e-05, 2.77431787e-05, + 2.52601053e-05, 2.00848906e-05, 1.74110112e-05, 2.00271150e-05, 2.47063875e-05, 2.80854134e-05, + 2.88851125e-05, 2.85972933e-05, 2.20433772e-05, 1.86583075e-05, 1.95584937e-05, 2.32959585e-05, + 2.69280729e-05, 2.87724191e-05, 2.90948920e-05, 2.85562562e-05, 2.07735363e-05, 1.78278814e-05, + 1.94657889e-05, 2.37386893e-05, 2.79296656e-05, 2.91393458e-05, 2.87149642e-05, 2.82476385e-05, + 2.01028448e-05, 1.64559266e-05, 2.05050146e-05, 2.49988419e-05, 2.66172312e-05, 2.72279097e-05, + 2.78407178e-05, 2.32253251e-05, 2.11111440e-05, 2.07064285e-05, 2.18133267e-05, 2.52651805e-05, + 2.79166051e-05, 2.83616265e-05, 2.81467556e-05, 2.37942474e-05, 2.17700772e-05, 2.18978153e-05, + 2.34278145e-05, 2.46587852e-05, 2.56588771e-05, 2.73917679e-05, 2.80820549e-05, 2.43158489e-05, + 2.16988161e-05, 2.17898788e-05, 2.27794174e-05, 2.36029477e-05, 2.55067407e-05, 2.73551203e-05, + 2.82065945e-05, 2.81706642e-05, 2.56183908e-05, 2.13189652e-05, 1.69913473e-05, 1.80220716e-05, + 2.27930852e-05, 2.74093082e-05, 2.84311752e-05, 2.73055887e-05, 2.24185836e-05, 2.01840923e-05, + 2.20636789e-05, 2.50563899e-05, 2.57645475e-05, 2.64175835e-05, 2.77315729e-05, 2.80754902e-05, + 2.57147879e-05, 2.22538972e-05, 1.98081186e-05, 2.21534685e-05, 2.48558586e-05, 2.69683608e-05, + 2.80118525e-05, 2.80454338e-05, 2.44951582e-05, 2.17141004e-05, 2.12678186e-05, 2.32719982e-05, + 2.53713425e-05, 2.67984968e-05, 2.80924463e-05, 2.77583102e-05, 2.71516668e-05, 2.46090751e-05, + 2.02237899e-05, 1.81126836e-05, 2.16553265e-05, 2.60205542e-05, 2.79087040e-05, 2.87641674e-05, + 2.88308139e-05, 2.83440789e-05, 2.33775404e-05, 2.12515682e-05, 2.10782420e-05, 2.39278390e-05, + 2.68715847e-05, 2.65765900e-05, 2.73173765e-05, 2.84632818e-05, 2.35926785e-05, 2.16686106e-05, + 2.15690992e-05, 2.23136080e-05, 2.38968176e-05, 2.67484722e-05, 2.78688555e-05, 2.74879921e-05, + 2.21573140e-05, 1.87352165e-05, 2.03398666e-05, 2.49365425e-05, 2.80326762e-05, 2.80963030e-05, + 2.77369696e-05, 2.47638601e-05, 2.20757978e-05, 2.03413131e-05, 2.12567669e-05, 2.41944918e-05, + 2.61655856e-05, 2.73342169e-05, 2.83574982e-05, 2.51691872e-05, 2.57131048e-05, 2.56743086e-05, + 2.63591322e-05, 2.62022348e-05, 2.44720774e-05, 2.32898088e-05, 2.29879651e-05, 2.27254542e-05, + 2.48347307e-05, 2.53776466e-05, 2.51809493e-05, 2.51679385e-05, 2.51553431e-05, 2.49475042e-05, + 2.44811363e-05, 2.35913335e-05, 2.32882156e-05, 2.31567486e-05, 2.26908188e-05, 2.57080446e-05, + 2.59653253e-05, 2.55338168e-05, 2.56234205e-05, 2.53898458e-05, 2.46444987e-05, 2.34234593e-05, + 2.24181960e-05, 2.20462662e-05, 2.58760868e-05, 2.53045744e-05, 2.56235097e-05, 2.61086146e-05, + 2.46217106e-05, 2.32904052e-05, 2.25404244e-05, 2.23241555e-05, 2.23214395e-05, 2.62678845e-05, + 2.70741361e-05, 2.61443475e-05, 2.61483989e-05, 2.50175107e-05, 2.40904542e-05, 2.35677310e-05, + 2.29874165e-05, 2.22358911e-05, 2.42481589e-05, 2.60750749e-05, 2.59537793e-05, 2.47770352e-05, + 2.56449889e-05, 2.53281323e-05, 2.30656249e-05, 2.17025253e-05, 2.19160063e-05, 2.54085965e-05, + 2.58515773e-05, 2.62843602e-05, 2.64637266e-05, 2.48215133e-05, 2.27406464e-05, 2.19012594e-05, + 2.21855499e-05, 2.50750410e-05, 2.56712889e-05, 2.65235436e-05, 2.62725181e-05, 2.39151027e-05, + 2.19458864e-05, 2.18875257e-05, 2.23957946e-05, 2.60391901e-05, 2.54050695e-05, 2.69265729e-05, + 2.65763904e-05, 2.45818305e-05, 2.27849055e-05, 2.22370808e-05, 2.60743495e-05, 2.69743238e-05, + 2.66375761e-05, 2.56832899e-05, 2.43705433e-05, 2.28348741e-05, 2.23300788e-05, 2.25039483e-05, + 2.59319824e-05, 2.67109315e-05, 2.65878344e-05, 2.61431010e-05, 2.50221194e-05, 2.38419635e-05, + 2.29396112e-05, 2.25688328e-05, 2.57418538e-05, 2.62584874e-05, 2.61777000e-05, 2.64331934e-05, + 2.58491538e-05, 2.44302497e-05, 2.30411716e-05, 2.24040585e-05, 2.24790048e-05, 2.70083940e-05, + 2.82528262e-05, 2.56515178e-05, 2.48068761e-05, 2.43802220e-05, 2.25842100e-05, 2.20186365e-05, + 2.24824428e-05, 2.62017366e-05, 2.70411927e-05, 2.68814759e-05, 2.59202161e-05, 2.49913805e-05, + 2.38929917e-05, 2.29208967e-05, 2.26617547e-05, 2.68181561e-05, 2.71421329e-05, 2.59147192e-05, + 2.58135830e-05, 2.50980848e-05, 2.34865151e-05, 2.24684915e-05, 2.26616719e-05, 2.55143943e-05, + 2.63736209e-05, 2.63998647e-05, 2.64950314e-05, 2.56522335e-05, 2.41596917e-05, 2.27571804e-05, + 2.26872873e-05, 2.27826283e-05, 2.61822100e-05, 2.65061496e-05, 2.51925741e-05, 2.56196383e-05, + 2.50210114e-05, 2.35378169e-05, 2.20640127e-05, 2.17985394e-05, 2.22920114e-05, 2.71102336e-05, + 2.81158584e-05, 2.71197280e-05, 2.59274380e-05, 2.37517145e-05, 2.24740245e-05, 2.20207835e-05, + 2.17836100e-05, 2.54344048e-05, 2.69389746e-05, 2.72158595e-05, 2.64089265e-05, 2.54047013e-05, + 2.42539590e-05, 2.31571820e-05, 2.28581243e-05, 2.74511581e-05, 2.74805885e-05, 2.61987383e-05, + 2.46117003e-05, 2.27074342e-05, 2.25914718e-05, 2.26874757e-05, 2.62212243e-05, 2.71778939e-05, + 2.66348880e-05, 2.59677159e-05, 2.47269136e-05, 2.35244579e-05, 2.29730942e-05, 2.24061965e-05, + 2.49568795e-05, 2.38186132e-05, 2.34179942e-05, 2.47477871e-05, 2.58870950e-05, 2.55832538e-05, + 2.51089237e-05, 2.48687684e-05, 2.45823774e-05, 2.48741042e-05, 2.43569291e-05, 2.44865432e-05, + 2.50557043e-05, 2.51402173e-05, 2.51438500e-05, 2.55287653e-05, 2.53553677e-05, 2.49990921e-05, + 2.47747778e-05, 2.46059743e-05, 2.50215143e-05, 2.42074434e-05, 2.39915392e-05, 2.51537692e-05, + 2.55595243e-05, 2.50733868e-05, 2.48130785e-05, 2.46026213e-05, 2.44634107e-05, 2.42453319e-05, + 2.19462616e-05, 2.29400571e-05, 2.59438603e-05, 2.62360682e-05, 2.52077546e-05, 2.45325610e-05, + 2.44658134e-05, 2.44896409e-05, 2.62521204e-05, 2.50032423e-05, 2.37007422e-05, 2.53174007e-05, + 2.56804314e-05, 2.48748709e-05, 2.43259021e-05, 2.43847471e-05, 2.43157023e-05, 2.58215892e-05, + 2.60884683e-05, 2.36046477e-05, 2.15700459e-05, 2.33459350e-05, 2.52062598e-05, 2.49805617e-05, + 2.42327753e-05, 2.42569421e-05, 2.40543546e-05, 2.28976971e-05, 2.36188068e-05, 2.54595762e-05, + 2.58799480e-05, 2.50835550e-05, 2.45326618e-05, 2.44706753e-05, 2.32387005e-05, 2.23998822e-05, + 2.37560262e-05, 2.55150627e-05, 2.56347619e-05, 2.45992179e-05, 2.42982209e-05, 2.44845300e-05, + 2.36771455e-05, 2.16046333e-05, 2.45308064e-05, 2.63723425e-05, 2.55163566e-05, 2.42916294e-05, + 2.41308243e-05, 2.51161391e-05, 2.48453282e-05, 2.44026094e-05, 2.41659846e-05, 2.46817523e-05, + 2.46890526e-05, 2.44893545e-05, 2.45243108e-05, 2.52672292e-05, 2.49452276e-05, 2.49082670e-05, + 2.52652569e-05, 2.49335244e-05, 2.44278555e-05, 2.45069496e-05, 2.45460601e-05, 2.53589142e-05, + 2.45613887e-05, 2.45399513e-05, 2.51940518e-05, 2.51113970e-05, 2.48452664e-05, 2.45755911e-05, + 2.44694992e-05, 2.45154590e-05, 2.70444366e-05, 2.59256602e-05, 2.20168034e-05, 2.18540019e-05, + 2.35753723e-05, 2.42103012e-05, 2.42549197e-05, 2.40709831e-05, 2.48452138e-05, 2.44708042e-05, + 2.52138024e-05, 2.58605394e-05, 2.54366274e-05, 2.48341395e-05, 2.46660312e-05, 2.46234368e-05, + 2.69357318e-05, 2.55064267e-05, 2.34525773e-05, 2.44203551e-05, 2.50883956e-05, 2.47617243e-05, + 2.44213277e-05, 2.46072415e-05, 2.52585393e-05, 2.46576972e-05, 2.44751681e-05, 2.54732801e-05, + 2.57933627e-05, 2.52496371e-05, 2.47156682e-05, 2.44778606e-05, 2.42517253e-05, 2.58579568e-05, + 2.40843435e-05, 2.21751127e-05, 2.40460339e-05, 2.55875687e-05, 2.52953015e-05, 2.44817962e-05, + 2.42861031e-05, 2.44464262e-05, 2.60143877e-05, 2.57881061e-05, 2.49417421e-05, 2.53262540e-05, + 2.49392436e-05, 2.37106080e-05, 2.36806340e-05, 2.40666779e-05, 2.47738727e-05, 2.50753314e-05, + 2.52435398e-05, 2.49596597e-05, 2.48900543e-05, 2.53044834e-05, 2.49433422e-05, 2.44858889e-05, + 2.57026351e-05, 2.41327512e-05, 2.39036358e-05, 2.47268072e-05, 2.46402233e-05, 2.45734203e-05, + 2.44669197e-05, 2.59650605e-05, 2.54508187e-05, 2.42349516e-05, 2.41372673e-05, 2.44784857e-05, + 2.44019114e-05, 2.45065146e-05, 2.45536903e-05, 2.54588387e-05, 3.12414073e-05, 3.25384795e-05, + 2.98403992e-05, 2.53399859e-05, 2.09295296e-05, 1.86846850e-05, 1.85180949e-05, 1.86486539e-05, + 2.46869813e-05, 2.82997827e-05, 2.72138084e-05, 2.50950717e-05, 2.47476225e-05, 2.40667603e-05, + 2.11544956e-05, 1.88215863e-05, 1.90733076e-05, 1.94356768e-05, 1.84432533e-05, 2.69146360e-05, + 3.05999429e-05, 3.00958176e-05, 2.61755924e-05, 2.39791647e-05, 2.33387862e-05, 2.02073056e-05, + 1.75109422e-05, 1.67158757e-05, 3.02046807e-05, 3.65098372e-05, 3.40458532e-05, 2.48520548e-05, + 1.91115172e-05, 1.83342511e-05, 1.81874229e-05, 1.76759603e-05, 1.75806620e-05, 2.42522674e-05, + 3.09747473e-05, 3.28697933e-05, 2.71998332e-05, 2.23545416e-05, 2.22329668e-05, 2.24974103e-05, + 2.02802772e-05, 1.79104050e-05, 1.93481446e-05, 2.42370262e-05, 3.26740632e-05, 3.63971112e-05, + 3.27069342e-05, 2.50580282e-05, 1.83822965e-05, 1.63354686e-05, 1.69994888e-05, 2.94919115e-05, + 3.47950238e-05, 3.35264207e-05, 2.76406243e-05, 2.10099248e-05, 1.69103549e-05, 1.59659767e-05, + 1.71753679e-05, 3.14343450e-05, 3.59646819e-05, 3.37001651e-05, 2.68722368e-05, 1.89098727e-05, + 1.58864413e-05, 1.67512202e-05, 1.78580082e-05, 3.26611311e-05, 3.78158924e-05, 3.21747873e-05, + 2.47679538e-05, 2.15289117e-05, 1.99198695e-05, 1.85895830e-05, 2.76932174e-05, 3.12385014e-05, + 3.18239809e-05, 2.99167392e-05, 2.38752645e-05, 1.86402729e-05, 1.76117775e-05, 1.80905267e-05, + 2.67206268e-05, 3.01600576e-05, 2.99377392e-05, 2.73694222e-05, 2.50738042e-05, 2.30492633e-05, + 1.96651458e-05, 1.82372303e-05, 2.58055704e-05, 3.02035851e-05, 3.00446532e-05, 2.84866040e-05, + 2.70253953e-05, 2.34702613e-05, 1.97646027e-05, 1.79410939e-05, 1.80358163e-05, 2.37304614e-05, + 3.10397681e-05, 3.71283194e-05, 3.55294131e-05, 2.80309298e-05, 1.95182833e-05, 1.73676490e-05, + 1.96761777e-05, 2.90365279e-05, 3.26813621e-05, 2.97136783e-05, 2.45662752e-05, 2.31471596e-05, + 2.17202150e-05, 1.90202075e-05, 1.82795508e-05, 2.35368222e-05, 2.94410338e-05, 3.30893932e-05, + 2.93955221e-05, 2.47528308e-05, 2.06095722e-05, 1.83403302e-05, 1.83377838e-05, 2.54566696e-05, + 3.01980148e-05, 3.09098215e-05, 2.76851741e-05, 2.39696360e-05, 2.10987736e-05, 1.82763961e-05, + 1.88963915e-05, 2.00594715e-05, 2.53820140e-05, 3.25493388e-05, 3.54740458e-05, 3.01565472e-05, + 2.26990205e-05, 1.88558650e-05, 1.67121637e-05, 1.64822948e-05, 1.76337795e-05, 2.75951648e-05, + 3.11355283e-05, 3.13083170e-05, 2.64954566e-05, 2.08599952e-05, 2.09965837e-05, 1.94903021e-05, + 1.72195198e-05, 2.69611099e-05, 3.03533085e-05, 3.05463044e-05, 2.92407214e-05, 2.64463909e-05, + 2.12131797e-05, 1.88279305e-05, 1.94600554e-05, 2.96328254e-05, 3.48832010e-05, 3.23236228e-05, + 2.45021659e-05, 1.83768783e-05, 1.82168325e-05, 1.89369523e-05, 2.51221005e-05, 2.97324537e-05, + 3.23875020e-05, 3.08544867e-05, 2.57932102e-05, 2.20664868e-05, 1.97825752e-05, 1.76449972e-05, + 2.55565513e-05, 2.63912133e-05, 2.64363849e-05, 2.57626593e-05, 2.47158846e-05, 2.38061291e-05, + 2.31357118e-05, 2.32406273e-05, 2.35519903e-05, 2.55096878e-05, 2.62481253e-05, 2.61288671e-05, + 2.54157937e-05, 2.52834923e-05, 2.51478744e-05, 2.39405386e-05, 2.30082431e-05, 2.34355853e-05, + 2.38100734e-05, 2.34157976e-05, 2.56296950e-05, 2.61505532e-05, 2.64326511e-05, 2.54599367e-05, + 2.47644060e-05, 2.50375622e-05, 2.41483020e-05, 2.28537631e-05, 2.24364666e-05, 2.61792270e-05, + 2.60482662e-05, 2.63567257e-05, 2.45942715e-05, 2.24480665e-05, 2.28583043e-05, 2.33275861e-05, + 2.30704848e-05, 2.29906726e-05, 2.42208134e-05, 2.53377601e-05, 2.60630780e-05, 2.53732038e-05, + 2.42310264e-05, 2.48870684e-05, 2.54554100e-05, 2.45486147e-05, 2.33405257e-05, 2.29005009e-05, + 2.43587830e-05, 2.62170505e-05, 2.64830932e-05, 2.64531937e-05, 2.52760089e-05, 2.30713969e-05, + 2.23515031e-05, 2.27993665e-05, 2.64481210e-05, 2.60661134e-05, 2.59108491e-05, 2.52514882e-05, + 2.35897331e-05, 2.20736415e-05, 2.18391539e-05, 2.27430342e-05, 2.68982620e-05, 2.59355595e-05, + 2.57133957e-05, 2.51834560e-05, 2.28278244e-05, 2.17269169e-05, 2.25948000e-05, 2.31683363e-05, + 2.61521369e-05, 2.54698814e-05, 2.54889240e-05, 2.42093046e-05, 2.40916245e-05, 2.44602104e-05, + 2.38986007e-05, 2.55622213e-05, 2.54288902e-05, 2.57038865e-05, 2.62938093e-05, 2.55150266e-05, + 2.34583204e-05, 2.30106320e-05, 2.32766893e-05, 2.53979899e-05, 2.55353790e-05, 2.56013603e-05, + 2.54241970e-05, 2.55216366e-05, 2.55298973e-05, 2.41516095e-05, 2.33458012e-05, 2.52394616e-05, + 2.58847523e-05, 2.59278832e-05, 2.54722971e-05, 2.55532052e-05, 2.52721228e-05, 2.41419303e-05, + 2.32317076e-05, 2.32511299e-05, 2.34411908e-05, 2.44723759e-05, 2.55712763e-05, 2.67052716e-05, + 2.69818412e-05, 2.43317278e-05, 2.30465522e-05, 2.45312423e-05, 2.57565885e-05, 2.53938041e-05, + 2.53490398e-05, 2.46181671e-05, 2.46702966e-05, 2.47462618e-05, 2.36853806e-05, 2.33064461e-05, + 2.34891578e-05, 2.51128575e-05, 2.62261287e-05, 2.61170476e-05, 2.53304309e-05, 2.43702319e-05, + 2.35101518e-05, 2.33538287e-05, 2.52866951e-05, 2.57960887e-05, 2.58426329e-05, 2.52391178e-05, + 2.45590391e-05, 2.41552246e-05, 2.32282815e-05, 2.37766773e-05, 2.45611000e-05, 2.47470060e-05, + 2.58003172e-05, 2.64240923e-05, 2.63728343e-05, 2.44146671e-05, 2.30757826e-05, 2.24190564e-05, + 2.24145469e-05, 2.30598599e-05, 2.47540754e-05, 2.45781295e-05, 2.53235475e-05, 2.53307442e-05, + 2.43237127e-05, 2.54523580e-05, 2.47759677e-05, 2.31041632e-05, 2.58565725e-05, 2.53848314e-05, + 2.51966842e-05, 2.56337207e-05, 2.57199716e-05, 2.41531897e-05, 2.33506204e-05, 2.40667588e-05, + 2.49119174e-05, 2.48336876e-05, 2.60385299e-05, 2.56070091e-05, 2.33491097e-05, 2.33110751e-05, + 2.38079706e-05, 2.46172601e-05, 2.51294416e-05, 2.57064899e-05, 2.61698017e-05, 2.60303937e-05, + 2.52460664e-05, 2.42095699e-05, 2.29787676e-05, 2.53696320e-05, 3.21391051e-05, 3.37166482e-05, + 3.04859247e-05, 2.52687023e-05, 2.03371411e-05, 1.79023541e-05, 1.77185979e-05, 1.78503197e-05, + 2.44893872e-05, 2.86388852e-05, 2.73737575e-05, 2.49587367e-05, 2.45673152e-05, 2.37986298e-05, + 2.05811695e-05, 1.80550508e-05, 1.83146728e-05, 1.86972256e-05, 1.76322785e-05, 2.70468874e-05, + 3.13770376e-05, 3.07596737e-05, 2.61982765e-05, 2.37144574e-05, 2.29802528e-05, 1.95301250e-05, + 1.66453058e-05, 1.58075909e-05, 3.09015121e-05, 3.87300727e-05, 3.55856401e-05, 2.47151974e-05, + 1.83899990e-05, 1.75318294e-05, 1.73587478e-05, 1.68160127e-05, 1.67160676e-05, 2.40474859e-05, + 3.18700874e-05, 3.41425331e-05, 2.73900861e-05, 2.19059328e-05, 2.17460967e-05, 2.20218960e-05, + 1.95974182e-05, 1.70600596e-05, 1.86320929e-05, 2.40241529e-05, 3.38939081e-05, 3.85622750e-05, + 3.39226361e-05, 2.49220029e-05, 1.75770113e-05, 1.54055016e-05, 1.60996770e-05, 3.00391627e-05, + 3.65406519e-05, 3.49623508e-05, 2.79105223e-05, 2.04339987e-05, 1.60258078e-05, 1.50281678e-05, + 1.62891694e-05, 3.23496912e-05, 3.80344273e-05, 3.51890639e-05, 2.70174240e-05, 1.81570411e-05, + 1.49471599e-05, 1.58407447e-05, 1.70087482e-05, 3.38813031e-05, 4.04698784e-05, 3.33204396e-05, + 2.46361780e-05, 2.09908836e-05, 1.92055397e-05, 1.77761472e-05, 2.79576984e-05, 3.21842090e-05, + 3.28805970e-05, 3.05520143e-05, 2.35680944e-05, 1.78441073e-05, 1.67488707e-05, 1.72558205e-05, + 2.68317379e-05, 3.08795606e-05, 3.06101869e-05, 2.75855561e-05, 2.49302373e-05, 2.26371722e-05, + 1.89368012e-05, 1.74119241e-05, 2.57810970e-05, 3.09142576e-05, 3.07219550e-05, 2.88938544e-05, + 2.71789668e-05, 2.31197488e-05, 1.90457003e-05, 1.70962528e-05, 1.71976456e-05, 2.34896624e-05, + 3.19985977e-05, 3.95603377e-05, 3.74390069e-05, 2.82940359e-05, 1.87711850e-05, 1.64861760e-05, + 1.89373454e-05, 2.95302735e-05, 3.39470893e-05, 3.03554253e-05, 2.43879504e-05, 2.27783984e-05, + 2.11801966e-05, 1.82490974e-05, 1.74587756e-05, 2.32678891e-05, 3.00427175e-05, 3.44049299e-05, + 2.99394059e-05, 2.45713959e-05, 1.99648573e-05, 1.75182851e-05, 1.75202131e-05, 2.53781417e-05, + 3.09119348e-05, 3.17652862e-05, 2.79632605e-05, 2.37120266e-05, 2.05118637e-05, 1.74577429e-05, + 1.81119327e-05, 1.93551508e-05, 2.53155683e-05, 3.37623830e-05, 3.73821598e-05, 3.08349969e-05, + 2.22847393e-05, 1.80900552e-05, 1.58041353e-05, 1.55596816e-05, 1.67710437e-05, 2.78814791e-05, + 3.21081782e-05, 3.22745596e-05, 2.65736806e-05, 2.02423203e-05, 2.03573225e-05, 1.87278397e-05, + 1.63261237e-05, 2.70912219e-05, 3.11191321e-05, 3.13611670e-05, 2.97783017e-05, 2.65002810e-05, + 2.06385432e-05, 1.80508625e-05, 1.87157815e-05, 3.02820489e-05, 3.67253406e-05, 3.34732179e-05, + 2.42754085e-05, 1.75625804e-05, 1.73909608e-05, 1.81549800e-05, 2.50232155e-05, 3.03893006e-05, + 3.35689415e-05, 3.16824793e-05, 2.57348760e-05, 2.15484021e-05, 1.90632237e-05, 1.67854657e-05, + 2.54682908e-05, 3.09367826e-05, 3.21461012e-05, 2.96530631e-05, 2.53956376e-05, 2.11265803e-05, + 1.89320285e-05, 1.87620372e-05, 1.88791344e-05, 2.47229362e-05, 2.81608685e-05, 2.71286591e-05, + 2.51232770e-05, 2.47930032e-05, 2.41380517e-05, 2.13423750e-05, 1.90733861e-05, 1.93057952e-05, + 1.96495922e-05, 1.86804377e-05, 2.68681089e-05, 3.03480097e-05, 2.98555145e-05, 2.61654820e-05, + 2.40713469e-05, 2.34339180e-05, 2.03987876e-05, 1.77736775e-05, 1.69947050e-05, 2.99733309e-05, + 3.58083585e-05, 3.35460068e-05, 2.49284667e-05, 1.93847187e-05, 1.85945849e-05, 1.84293717e-05, + 1.79298239e-05, 1.78378766e-05, 2.43635577e-05, 3.07495443e-05, 3.24781044e-05, 2.71557046e-05, + 2.25087421e-05, 2.23594066e-05, 2.25920583e-05, 2.04535583e-05, 1.81528631e-05, 1.96009112e-05, + 2.43420443e-05, 3.22862902e-05, 3.56744928e-05, 3.23016490e-05, 2.50943877e-05, 1.86337804e-05, + 1.66166169e-05, 1.72646013e-05, 2.92831280e-05, 3.42529636e-05, 3.30966276e-05, 2.75850973e-05, + 2.12153726e-05, 1.72035053e-05, 1.62649605e-05, 1.74426971e-05, 3.10862398e-05, 3.53256716e-05, + 3.32701631e-05, 2.68508918e-05, 1.91685868e-05, 1.61892162e-05, 1.70240146e-05, 1.81075148e-05, + 3.22784180e-05, 3.70153618e-05, 3.18665660e-05, 2.48657136e-05, 2.17042125e-05, 2.01012897e-05, + 1.88062116e-05, 2.76187305e-05, 3.09923610e-05, 3.15251184e-05, 2.96943996e-05, 2.39338566e-05, + 1.88746433e-05, 1.78681451e-05, 1.83349128e-05, 2.66937602e-05, 2.99688452e-05, 2.97545862e-05, + 2.73157616e-05, 2.50973606e-05, 2.31279303e-05, 1.98624535e-05, 1.84782307e-05, 2.58196262e-05, + 2.99896164e-05, 2.98368120e-05, 2.83821921e-05, 2.69785942e-05, 2.35509916e-05, 1.99613013e-05, + 1.81878108e-05, 1.82814317e-05, 2.38920248e-05, 3.08616462e-05, 3.63974683e-05, 3.48758353e-05, + 2.78633690e-05, 1.97094271e-05, 1.76229659e-05, 1.98572452e-05, 2.88902929e-05, 3.23452336e-05, + 2.95567063e-05, 2.46496851e-05, 2.32641698e-05, 2.18627576e-05, 1.92427097e-05, 1.85219587e-05, + 2.37005939e-05, 2.93112341e-05, 3.26713700e-05, 2.92108407e-05, 2.47957272e-05, 2.07862946e-05, + 1.85741921e-05, 1.85780047e-05, 2.54798743e-05, 2.99895431e-05, 3.06583310e-05, 2.76284597e-05, + 2.40719666e-05, 2.12779782e-05, 1.85219837e-05, 1.91160036e-05, 2.02349333e-05, 2.54347908e-05, + 3.21966824e-05, 3.48461146e-05, 2.99164218e-05, 2.28377932e-05, 1.91046796e-05, 1.69916557e-05, + 1.67614595e-05, 1.78881528e-05, 2.75681147e-05, 3.09457587e-05, 3.10643121e-05, 2.64804933e-05, + 2.10352618e-05, 2.11197818e-05, 1.96629336e-05, 1.74727144e-05, 2.69007097e-05, 3.01603514e-05, + 3.03536848e-05, 2.90914076e-05, 2.64129036e-05, 2.13907407e-05, 1.90655913e-05, 1.96629414e-05, + 2.95047860e-05, 3.44171563e-05, 3.19712567e-05, 2.45387434e-05, 1.86171052e-05, 1.84593250e-05, + 1.91549788e-05, 2.51893622e-05, 2.95870363e-05, 3.20516879e-05, 3.05866000e-05, 2.57670824e-05, + 2.21797241e-05, 1.99762054e-05, 1.79025646e-05, 2.50269610e-05, 2.33411774e-05, 2.28389974e-05, + 2.37163826e-05, 2.48453644e-05, 2.56060860e-05, 2.57743368e-05, 2.58248238e-05, 2.58925007e-05, + 2.52185536e-05, 2.43425802e-05, 2.46557316e-05, 2.50902748e-05, 2.51485041e-05, 2.52858379e-05, + 2.56013417e-05, 2.57196127e-05, 2.58052765e-05, 2.58544897e-05, 2.58814052e-05, 2.46315097e-05, + 2.35306745e-05, 2.37714529e-05, 2.48052429e-05, 2.52092857e-05, 2.54311657e-05, 2.58238473e-05, + 2.58292844e-05, 2.57802026e-05, 2.36798908e-05, 2.09418868e-05, 2.21812689e-05, 2.49422290e-05, + 2.55079032e-05, 2.57398372e-05, 2.58875312e-05, 2.58724699e-05, 2.58601313e-05, 2.49919085e-05, + 2.32063152e-05, 2.26292499e-05, 2.44835983e-05, 2.54389717e-05, 2.56354551e-05, 2.57148574e-05, + 2.59122436e-05, 2.59207419e-05, 2.56113318e-05, 2.50349248e-05, 2.27408668e-05, 2.10667064e-05, + 2.27730149e-05, 2.50658534e-05, 2.57945684e-05, 2.57816434e-05, 2.58589526e-05, 2.39865845e-05, + 2.17876069e-05, 2.23218501e-05, 2.43178958e-05, 2.55294815e-05, 2.56590270e-05, 2.56558803e-05, + 2.58291696e-05, 2.33627375e-05, 2.12012863e-05, 2.22059148e-05, 2.45338727e-05, 2.56543521e-05, + 2.56268957e-05, 2.58217095e-05, 2.58804386e-05, 2.27331666e-05, 2.01347387e-05, 2.27840193e-05, + 2.48557397e-05, 2.55705876e-05, 2.59470337e-05, 2.59884580e-05, 2.43785735e-05, 2.31301678e-05, + 2.29708601e-05, 2.38064574e-05, 2.54202140e-05, 2.58686546e-05, 2.58625435e-05, 2.58846946e-05, + 2.46326321e-05, 2.35499886e-05, 2.36443761e-05, 2.44446880e-05, 2.51212282e-05, 2.56133076e-05, + 2.59088786e-05, 2.58867614e-05, 2.48545452e-05, 2.36157741e-05, 2.36820275e-05, 2.41041958e-05, + 2.45801728e-05, 2.54580598e-05, 2.58916083e-05, 2.58887443e-05, 2.58838196e-05, 2.48872114e-05, + 2.29534546e-05, 2.05333770e-05, 2.15414717e-05, 2.45741755e-05, 2.59746219e-05, 2.58947887e-05, + 2.59999645e-05, 2.39905427e-05, 2.25592823e-05, 2.36612148e-05, 2.50229216e-05, 2.53813735e-05, + 2.57037568e-05, 2.58796505e-05, 2.58713648e-05, 2.49498331e-05, 2.36950742e-05, 2.25703118e-05, + 2.39500462e-05, 2.51586528e-05, 2.58133793e-05, 2.59183755e-05, 2.58773106e-05, 2.49620181e-05, + 2.35976236e-05, 2.33491812e-05, 2.43009011e-05, 2.51567437e-05, 2.56700773e-05, 2.58505776e-05, + 2.59197239e-05, 2.59500076e-05, 2.48423943e-05, 2.27048031e-05, 2.15260182e-05, 2.37375626e-05, + 2.54140038e-05, 2.57343604e-05, 2.57755684e-05, 2.57901182e-05, 2.58737308e-05, 2.42004268e-05, + 2.29477408e-05, 2.30782962e-05, 2.46816614e-05, 2.57577300e-05, 2.59996184e-05, 2.60822497e-05, + 2.59225104e-05, 2.46706370e-05, 2.34443723e-05, 2.33278634e-05, 2.38927570e-05, 2.47897992e-05, + 2.56481091e-05, 2.58152595e-05, 2.59172180e-05, 2.35762845e-05, 2.14831247e-05, 2.28465670e-05, + 2.52880907e-05, 2.58714473e-05, 2.58797957e-05, 2.59225262e-05, 2.48770563e-05, 2.35990080e-05, + 2.27492191e-05, 2.34409640e-05, 2.50440568e-05, 2.57550309e-05, 2.59059578e-05, 2.58506032e-05, + 2.41845161e-05, 2.01565204e-05, 1.92181524e-05, 2.14414131e-05, 2.47769053e-05, 2.74774872e-05, + 2.87251573e-05, 2.86817684e-05, 2.83949077e-05, 2.46141935e-05, 2.21412213e-05, 2.28550990e-05, + 2.44662380e-05, 2.47314540e-05, 2.51616594e-05, 2.72919587e-05, 2.87909546e-05, 2.83790815e-05, + 2.79782269e-05, 2.85553879e-05, 2.33312658e-05, 2.07237015e-05, 2.09020384e-05, 2.38548284e-05, + 2.54588654e-05, 2.55824090e-05, 2.74762944e-05, 2.92179657e-05, 2.96992618e-05, 2.09718439e-05, + 1.62814931e-05, 1.81350957e-05, 2.51173410e-05, 2.91451096e-05, 2.90399532e-05, 2.86854143e-05, + 2.90033087e-05, 2.90884949e-05, 2.56707404e-05, 2.08958694e-05, 1.91693093e-05, 2.33174277e-05, + 2.65842060e-05, 2.61729271e-05, 2.56553067e-05, 2.71431003e-05, 2.87302913e-05, 2.87185593e-05, + 2.55909006e-05, 1.92340016e-05, 1.61661338e-05, 1.90871489e-05, 2.45755102e-05, 2.88534766e-05, + 2.98139316e-05, 2.93435404e-05, 2.12832549e-05, 1.76930581e-05, 1.87546702e-05, 2.31234082e-05, + 2.76043735e-05, 2.99909701e-05, 3.03076092e-05, 2.93681996e-05, 1.97452830e-05, 1.67992969e-05, + 1.87189160e-05, 2.36228459e-05, 2.89096032e-05, 3.04156166e-05, 2.95546924e-05, 2.88861820e-05, + 1.92768850e-05, 1.53813920e-05, 1.99658669e-05, 2.54024895e-05, 2.70332573e-05, 2.73226658e-05, + 2.81226600e-05, 2.29113803e-05, 2.06648337e-05, 2.01103267e-05, 2.10971252e-05, 2.50060851e-05, + 2.84736933e-05, 2.90659227e-05, 2.87483945e-05, 2.35831026e-05, 2.13509669e-05, 2.14643681e-05, + 2.31865319e-05, 2.44088690e-05, 2.53694106e-05, 2.76411586e-05, 2.86595101e-05, 2.41965766e-05, + 2.11339917e-05, 2.12161044e-05, 2.24742814e-05, 2.33129965e-05, 2.53608244e-05, 2.76195332e-05, + 2.88164373e-05, 2.87811040e-05, 2.64364356e-05, 2.12765517e-05, 1.59612919e-05, 1.67813272e-05, + 2.18569555e-05, 2.75391868e-05, 2.90754779e-05, 2.73361537e-05, 2.19662850e-05, 1.96408791e-05, + 2.17486107e-05, 2.52536814e-05, 2.59221577e-05, 2.64818739e-05, 2.81926703e-05, 2.86829912e-05, + 2.65077698e-05, 2.20551578e-05, 1.89238292e-05, 2.15336559e-05, 2.46982257e-05, 2.71716052e-05, + 2.85002056e-05, 2.86306631e-05, 2.43570526e-05, 2.11857449e-05, 2.06784023e-05, 2.31033508e-05, + 2.55982706e-05, 2.71558025e-05, 2.87485929e-05, 2.81504352e-05, 2.72015801e-05, 2.47345880e-05, + 1.95374153e-05, 1.69684624e-05, 2.08958132e-05, 2.63028833e-05, 2.87273646e-05, 2.97151351e-05, + 2.97439692e-05, 2.90199352e-05, 2.34336973e-05, 2.11576897e-05, 2.06689853e-05, 2.37531018e-05, + 2.71187093e-05, 2.62134130e-05, 2.71887152e-05, 2.90468725e-05, 2.31667440e-05, 2.12996510e-05, + 2.12649353e-05, 2.19037025e-05, 2.35426671e-05, 2.71134898e-05, 2.85137368e-05, 2.77670915e-05, + 2.20329427e-05, 1.81907209e-05, 1.95803854e-05, 2.46418652e-05, 2.86257333e-05, 2.86928772e-05, + 2.81147730e-05, 2.49571432e-05, 2.18524550e-05, 1.97026692e-05, 2.05410165e-05, 2.37033256e-05, + 2.59805306e-05, 2.75609018e-05, 2.90871512e-05, 2.47114630e-05, 2.23987932e-05, 2.17656309e-05, + 2.35141739e-05, 2.55674697e-05, 2.63698812e-05, 2.64902641e-05, 2.63039324e-05, 2.59972777e-05, + 2.48169754e-05, 2.35283578e-05, 2.38889797e-05, 2.48850016e-05, 2.50425221e-05, 2.52065642e-05, + 2.62635095e-05, 2.66889873e-05, 2.62873748e-05, 2.59838735e-05, 2.60715611e-05, 2.44302149e-05, + 2.28768188e-05, 2.28053426e-05, 2.47194790e-05, 2.56027791e-05, 2.53152176e-05, 2.58293182e-05, + 2.63059321e-05, 2.63771370e-05, 2.29993777e-05, 1.96337972e-05, 2.10226014e-05, 2.57358470e-05, + 2.74418280e-05, 2.66741627e-05, 2.60657575e-05, 2.61314708e-05, 2.61788698e-05, 2.61564659e-05, + 2.34648230e-05, 2.19282157e-05, 2.46232978e-05, 2.61069806e-05, 2.53964784e-05, 2.48257605e-05, + 2.54074336e-05, 2.59269067e-05, 2.69926144e-05, 2.60143924e-05, 2.18923675e-05, 1.93504524e-05, + 2.16667031e-05, 2.50286554e-05, 2.64452462e-05, 2.62513956e-05, 2.61024478e-05, 2.29954837e-05, + 2.08154380e-05, 2.17078662e-05, 2.46432498e-05, 2.66240083e-05, 2.69272273e-05, 2.66428421e-05, + 2.62647875e-05, 2.18586726e-05, 2.01330307e-05, 2.17810705e-05, 2.48736261e-05, 2.69301573e-05, + 2.67292978e-05, 2.62069239e-05, 2.61031202e-05, 2.19563228e-05, 1.90440290e-05, 2.27846369e-05, + 2.61360871e-05, 2.61594689e-05, 2.54064997e-05, 2.55787477e-05, 2.43318456e-05, 2.32695344e-05, + 2.27598285e-05, 2.29963888e-05, 2.48317131e-05, 2.61013821e-05, 2.61706253e-05, 2.60823689e-05, + 2.46919008e-05, 2.36080835e-05, 2.36286872e-05, 2.45378571e-05, 2.47802662e-05, 2.47913401e-05, + 2.56730891e-05, 2.60661263e-05, 2.49883750e-05, 2.32705880e-05, 2.32888823e-05, 2.42138658e-05, + 2.44835207e-05, 2.50758713e-05, 2.57137669e-05, 2.60675083e-05, 2.60877290e-05, 2.69899819e-05, + 2.42183453e-05, 1.95440109e-05, 1.97819058e-05, 2.28984581e-05, 2.54267571e-05, 2.60059937e-05, + 2.52555249e-05, 2.37843517e-05, 2.26144284e-05, 2.39418277e-05, 2.57309269e-05, 2.56919340e-05, + 2.54816051e-05, 2.59840946e-05, 2.61296868e-05, 2.69427885e-05, 2.42556621e-05, 2.16697072e-05, + 2.33346457e-05, 2.49946876e-05, 2.56826356e-05, 2.59202941e-05, 2.60994153e-05, 2.49814284e-05, + 2.33541823e-05, 2.30338132e-05, 2.46446049e-05, 2.58153985e-05, 2.60185025e-05, 2.62189152e-05, + 2.58354031e-05, 2.53348185e-05, 2.55315513e-05, 2.23236767e-05, 2.00612435e-05, 2.28387012e-05, + 2.59380149e-05, 2.66233415e-05, 2.63960111e-05, 2.62651636e-05, 2.61235127e-05, 2.51342577e-05, + 2.40808357e-05, 2.33338838e-05, 2.47968202e-05, 2.57878109e-05, 2.45992247e-05, 2.49267225e-05, + 2.58607229e-05, 2.42009282e-05, 2.36729501e-05, 2.37691221e-05, 2.38354659e-05, 2.44226207e-05, + 2.60412778e-05, 2.62964278e-05, 2.57035071e-05, 2.43759527e-05, 2.18028837e-05, 2.22243561e-05, + 2.47267738e-05, 2.61211457e-05, 2.60975658e-05, 2.58148560e-05, 2.56891880e-05, 2.41387691e-05, + 2.24874496e-05, 2.27587729e-05, 2.42054753e-05, 2.49974618e-05, 2.56438775e-05, 2.62242487e-05, + 2.48932424e-05, 2.32564789e-05, 2.27564771e-05, 2.41616966e-05, 2.56163408e-05, 2.58622583e-05, + 2.56898576e-05, 2.55139840e-05, 2.52768872e-05, 2.49190412e-05, 2.40774337e-05, 2.43168838e-05, + 2.50120464e-05, 2.51173690e-05, 2.51973866e-05, 2.57984774e-05, 2.58719152e-05, 2.55717248e-05, + 2.53645341e-05, 2.53118291e-05, 2.47642314e-05, 2.36448794e-05, 2.35534319e-05, 2.49574966e-05, + 2.55266460e-05, 2.52225889e-05, 2.53275266e-05, 2.53792684e-05, 2.53233615e-05, 2.37306969e-05, + 2.09761863e-05, 2.21540886e-05, 2.57179331e-05, 2.65302830e-05, 2.57953286e-05, 2.52733121e-05, + 2.52584335e-05, 2.52843424e-05, 2.60212646e-05, 2.41827809e-05, 2.29166429e-05, 2.49520629e-05, + 2.57952606e-05, 2.51831828e-05, 2.47253030e-05, 2.49823292e-05, 2.51214030e-05, 2.61904018e-05, + 2.58995369e-05, 2.28758356e-05, 2.07136496e-05, 2.26757372e-05, 2.51320101e-05, 2.56128754e-05, + 2.51635713e-05, 2.51393621e-05, 2.36854637e-05, 2.19952934e-05, 2.27481542e-05, 2.50010657e-05, + 2.60835463e-05, 2.58020220e-05, 2.54259849e-05, 2.52979883e-05, 2.27861090e-05, 2.14155348e-05, + 2.28207552e-05, 2.51436609e-05, 2.60824961e-05, 2.54837567e-05, 2.51890722e-05, 2.52599336e-05, + 2.29322956e-05, 2.04672552e-05, 2.36449809e-05, 2.60504690e-05, 2.57523216e-05, 2.49399633e-05, + 2.49215850e-05, 2.47352827e-05, 2.40253137e-05, 2.36058632e-05, 2.37114388e-05, 2.48600970e-05, + 2.53621438e-05, 2.52818586e-05, 2.52741346e-05, 2.49756471e-05, 2.42627033e-05, 2.42677364e-05, + 2.48905516e-05, 2.49204258e-05, 2.47491878e-05, 2.51330174e-05, 2.52802238e-05, 2.51592345e-05, + 2.39691966e-05, 2.39760798e-05, 2.46871124e-05, 2.48184958e-05, 2.50312710e-05, 2.51788701e-05, + 2.52417710e-05, 2.52712342e-05, 2.66748395e-05, 2.48451801e-05, 2.09101293e-05, 2.10820625e-05, + 2.35078402e-05, 2.49094797e-05, 2.51121994e-05, 2.47848224e-05, 2.43487083e-05, 2.35181360e-05, + 2.45280154e-05, 2.56885825e-05, 2.55238551e-05, 2.52022721e-05, 2.53131895e-05, 2.53384193e-05, + 2.66164093e-05, 2.47847142e-05, 2.26954078e-05, 2.39775465e-05, 2.50768894e-05, 2.52506722e-05, + 2.51730194e-05, 2.53210559e-05, 2.51248257e-05, 2.40422860e-05, 2.38002431e-05, 2.50053964e-05, + 2.57062652e-05, 2.55870322e-05, 2.54117988e-05, 2.51739768e-05, 2.48960348e-05, 2.55892299e-05, + 2.32541293e-05, 2.13348583e-05, 2.35863333e-05, 2.56877792e-05, 2.58221159e-05, 2.53382679e-05, + 2.51969270e-05, 2.52460576e-05, 2.54212125e-05, 2.47304678e-05, 2.40855628e-05, 2.50488918e-05, + 2.53670039e-05, 2.43795668e-05, 2.44870278e-05, 2.49716798e-05, 2.45692307e-05, 2.43306218e-05, + 2.44257288e-05, 2.44061569e-05, 2.47224464e-05, 2.56187459e-05, 2.55479642e-05, 2.51337426e-05, + 2.49010952e-05, 2.28850179e-05, 2.31553019e-05, 2.48257790e-05, 2.53441885e-05, 2.53035330e-05, + 2.51619899e-05, 2.57015731e-05, 2.47008278e-05, 2.33919478e-05, 2.35545824e-05, 2.44841462e-05, + 2.48282599e-05, 2.51225741e-05, 2.53306487e-05, 2.46595160e-05, 2.15003119e-05, 2.07212922e-05, + 2.19566447e-05, 2.40751836e-05, 2.64241620e-05, 2.75463727e-05, 2.77830008e-05, 2.79752194e-05, + 2.51550541e-05, 2.32787122e-05, 2.39079233e-05, 2.47988003e-05, 2.49336013e-05, 2.52990566e-05, + 2.63765634e-05, 2.73126043e-05, 2.75214253e-05, 2.75845826e-05, 2.80128783e-05, 2.37379835e-05, + 2.17444279e-05, 2.22496727e-05, 2.41005222e-05, 2.50461476e-05, 2.57248803e-05, 2.72883054e-05, + 2.82376101e-05, 2.84942595e-05, 2.20117164e-05, 1.80492547e-05, 1.97428200e-05, 2.43055595e-05, + 2.65340480e-05, 2.75600920e-05, 2.81383988e-05, 2.83134496e-05, 2.83147816e-05, 2.44040926e-05, + 2.09655916e-05, 2.02868648e-05, 2.33584634e-05, 2.57488421e-05, 2.64024994e-05, 2.66829393e-05, + 2.75912192e-05, 2.83810960e-05, 2.67905553e-05, 2.45302573e-05, 2.05022687e-05, 1.83482113e-05, + 2.06271711e-05, 2.47139422e-05, 2.77295536e-05, 2.87378457e-05, 2.86180268e-05, 2.26457282e-05, + 1.91148076e-05, 1.97936313e-05, 2.29818332e-05, 2.61663335e-05, 2.79538965e-05, 2.85273073e-05, + 2.84110368e-05, 2.16991747e-05, 1.83253819e-05, 1.95676962e-05, 2.34282970e-05, 2.70663881e-05, + 2.84784595e-05, 2.86252000e-05, 2.82570892e-05, 2.04699208e-05, 1.69308532e-05, 2.03418931e-05, + 2.40445920e-05, 2.62322140e-05, 2.77955398e-05, 2.83513098e-05, 2.31787409e-05, 2.08674994e-05, + 2.06948711e-05, 2.22706869e-05, 2.57308747e-05, 2.78926917e-05, 2.83083401e-05, 2.81692701e-05, + 2.36912583e-05, 2.16005568e-05, 2.17841278e-05, 2.32863482e-05, 2.48964774e-05, 2.63383141e-05, + 2.77174496e-05, 2.81148787e-05, 2.41779851e-05, 2.18134780e-05, 2.19422607e-05, 2.26039468e-05, + 2.36077426e-05, 2.58235763e-05, 2.76298220e-05, 2.82496773e-05, 2.81898185e-05, 2.40909683e-05, + 2.03233290e-05, 1.74117728e-05, 1.90137862e-05, 2.39643741e-05, 2.79987738e-05, 2.85501333e-05, + 2.80530675e-05, 2.24585592e-05, 1.99762735e-05, 2.17461200e-05, 2.45198058e-05, 2.55550655e-05, + 2.66630439e-05, 2.78004136e-05, 2.80419721e-05, 2.42654447e-05, 2.17460372e-05, 2.02527387e-05, + 2.24818094e-05, 2.49673428e-05, 2.71764096e-05, 2.81879527e-05, 2.80398183e-05, 2.44504830e-05, + 2.17564742e-05, 2.13466986e-05, 2.29439498e-05, 2.48822248e-05, 2.66111098e-05, 2.79688728e-05, + 2.79863702e-05, 2.77757462e-05, 2.40720423e-05, 2.03167204e-05, 1.88968965e-05, 2.21713864e-05, + 2.56588136e-05, 2.73505714e-05, 2.84796406e-05, 2.86744482e-05, 2.83384152e-05, 2.26342617e-05, + 2.03416687e-05, 2.07539480e-05, 2.37886880e-05, 2.69427705e-05, 2.78181665e-05, 2.84215844e-05, + 2.87333553e-05, 2.38760705e-05, 2.13771446e-05, 2.11284289e-05, 2.22427140e-05, 2.41169883e-05, + 2.65230853e-05, 2.76375797e-05, 2.78028126e-05, 2.14830965e-05, 1.83260883e-05, 2.06054849e-05, + 2.53610183e-05, 2.80031593e-05, 2.80981406e-05, 2.79828848e-05, 2.41418177e-05, 2.15783901e-05, + 2.03547268e-05, 2.15980597e-05, 2.47930494e-05, 2.68293601e-05, 2.76773066e-05, 2.82489496e-05, + 2.53006859e-05, 2.42555422e-05, 2.38919358e-05, 2.39418170e-05, 2.42326118e-05, 2.49023522e-05, + 2.50787830e-05, 2.53224911e-05, 2.57080501e-05, 2.55589677e-05, 2.51027882e-05, 2.53587941e-05, + 2.52621009e-05, 2.52289824e-05, 2.53343290e-05, 2.49839810e-05, 2.48202859e-05, 2.53083197e-05, + 2.56602450e-05, 2.56211685e-05, 2.48223128e-05, 2.41703759e-05, 2.46946744e-05, 2.48858890e-05, + 2.48523940e-05, 2.55021184e-05, 2.57468844e-05, 2.53145461e-05, 2.51542543e-05, 2.43395271e-05, + 2.22663398e-05, 2.33328429e-05, 2.42649593e-05, 2.38627446e-05, 2.48619124e-05, 2.56337476e-05, + 2.55427423e-05, 2.54786086e-05, 2.40085776e-05, 2.30447760e-05, 2.33371167e-05, 2.43815885e-05, + 2.48327747e-05, 2.57993711e-05, 2.64681495e-05, 2.62848240e-05, 2.58102343e-05, 2.43927533e-05, + 2.41993717e-05, 2.35834459e-05, 2.27986432e-05, 2.38592608e-05, 2.50904015e-05, 2.51482958e-05, + 2.52555026e-05, 2.55324462e-05, 2.49260179e-05, 2.27692739e-05, 2.29565387e-05, 2.40629426e-05, + 2.45598045e-05, 2.44952207e-05, 2.47019161e-05, 2.53437638e-05, 2.48189664e-05, 2.22869258e-05, + 2.26703878e-05, 2.42577677e-05, 2.45124600e-05, 2.45796351e-05, 2.53722481e-05, 2.55841148e-05, + 2.35089232e-05, 2.12612419e-05, 2.28565679e-05, 2.37873034e-05, 2.50187429e-05, 2.63464583e-05, + 2.62516858e-05, 2.44433759e-05, 2.30732279e-05, 2.32253626e-05, 2.45821376e-05, 2.59177843e-05, + 2.55751029e-05, 2.54904496e-05, 2.56129713e-05, 2.45941045e-05, 2.35516473e-05, 2.37075674e-05, + 2.43846431e-05, 2.54126652e-05, 2.63124398e-05, 2.60341626e-05, 2.56327294e-05, 2.47408274e-05, + 2.39720778e-05, 2.40794452e-05, 2.40428541e-05, 2.46805895e-05, 2.57652602e-05, 2.59675608e-05, + 2.56309301e-05, 2.56060071e-05, 2.31771114e-05, 2.19699136e-05, 2.15554400e-05, 2.33061765e-05, + 2.61546063e-05, 2.63748055e-05, 2.56861960e-05, 2.65802217e-05, 2.42104820e-05, 2.25896064e-05, + 2.34674397e-05, 2.44121771e-05, 2.50836567e-05, 2.58458910e-05, 2.57008177e-05, 2.55509519e-05, + 2.33190225e-05, 2.32632266e-05, 2.34661854e-05, 2.45408580e-05, 2.52898854e-05, 2.58601640e-05, + 2.58177978e-05, 2.55884195e-05, 2.49425055e-05, 2.38634331e-05, 2.36866119e-05, 2.40309579e-05, + 2.45790921e-05, 2.53131419e-05, 2.54374074e-05, 2.59017781e-05, 2.64186435e-05, 2.42572179e-05, + 2.31183081e-05, 2.29932199e-05, 2.45985886e-05, 2.49314747e-05, 2.49003569e-05, 2.51301920e-05, + 2.52617286e-05, 2.55511882e-05, 2.34421979e-05, 2.20692393e-05, 2.29227078e-05, 2.45923311e-05, + 2.56686451e-05, 2.72119261e-05, 2.70399286e-05, 2.58604860e-05, 2.51006404e-05, 2.33017618e-05, + 2.30074804e-05, 2.39844589e-05, 2.51217638e-05, 2.52551166e-05, 2.53156105e-05, 2.60202000e-05, + 2.29498065e-05, 2.13076703e-05, 2.34762075e-05, 2.57693965e-05, 2.55597344e-05, 2.55928368e-05, + 2.59254418e-05, 2.41880237e-05, 2.31876470e-05, 2.30544958e-05, 2.41094988e-05, 2.57952019e-05, + 2.63815107e-05, 2.60560198e-05, 2.54238727e-05, 2.52550659e-05, 2.42568555e-05, 2.38996132e-05, + 2.41583694e-05, 2.45516209e-05, 2.49927159e-05, 2.50196561e-05, 2.51694786e-05, 2.54270098e-05, + 2.54392717e-05, 2.50134832e-05, 2.52329247e-05, 2.52381110e-05, 2.52229815e-05, 2.53010321e-05, + 2.50520758e-05, 2.48571265e-05, 2.51900334e-05, 2.54361432e-05, 2.53589508e-05, 2.48953362e-05, + 2.42537607e-05, 2.46333079e-05, 2.49631692e-05, 2.49848024e-05, 2.54148856e-05, 2.55234036e-05, + 2.50988084e-05, 2.49321114e-05, 2.43942518e-05, 2.23408499e-05, 2.33707550e-05, 2.45826806e-05, + 2.42333063e-05, 2.48573704e-05, 2.53514189e-05, 2.52583964e-05, 2.52101352e-05, 2.44185013e-05, + 2.34777687e-05, 2.35040279e-05, 2.45929027e-05, 2.49712728e-05, 2.56034488e-05, 2.60359117e-05, + 2.58724120e-05, 2.54470369e-05, 2.45992363e-05, 2.45470836e-05, 2.36852110e-05, 2.26991610e-05, + 2.38611979e-05, 2.51263652e-05, 2.50479175e-05, 2.49639547e-05, 2.52002633e-05, 2.48258616e-05, + 2.29114632e-05, 2.31843406e-05, 2.43619505e-05, 2.47674538e-05, 2.45173338e-05, 2.45697321e-05, + 2.50924419e-05, 2.46023264e-05, 2.24370265e-05, 2.29760617e-05, 2.45233416e-05, 2.46580557e-05, + 2.44821543e-05, 2.50762145e-05, 2.52977543e-05, 2.36377881e-05, 2.14696924e-05, 2.32517573e-05, + 2.42621941e-05, 2.50827812e-05, 2.58983815e-05, 2.57726994e-05, 2.46123596e-05, 2.34763329e-05, + 2.35291425e-05, 2.45732922e-05, 2.56818292e-05, 2.53405267e-05, 2.52200278e-05, 2.53318088e-05, + 2.47522180e-05, 2.38770279e-05, 2.39962443e-05, 2.45878475e-05, 2.53368226e-05, 2.59386083e-05, + 2.56876666e-05, 2.53538873e-05, 2.48783791e-05, 2.41530421e-05, 2.42351556e-05, 2.43071902e-05, + 2.47976964e-05, 2.55855852e-05, 2.56489895e-05, 2.53335890e-05, 2.53237553e-05, 2.38559154e-05, + 2.27387319e-05, 2.17795736e-05, 2.31552932e-05, 2.57014517e-05, 2.58994022e-05, 2.53282584e-05, + 2.60372026e-05, 2.43872703e-05, 2.30258174e-05, 2.38505038e-05, 2.46855691e-05, 2.51407981e-05, + 2.56266291e-05, 2.54423446e-05, 2.53036146e-05, 2.39541861e-05, 2.37299926e-05, 2.35656192e-05, + 2.45819450e-05, 2.52627477e-05, 2.56099100e-05, 2.54796341e-05, 2.53314292e-05, 2.50203497e-05, + 2.40816336e-05, 2.39111880e-05, 2.43385926e-05, 2.48034888e-05, 2.52671529e-05, 2.52298148e-05, + 2.55655490e-05, 2.59499013e-05, 2.45671755e-05, 2.33914401e-05, 2.29641377e-05, 2.45665099e-05, + 2.50390945e-05, 2.49116448e-05, 2.49161822e-05, 2.49813085e-05, 2.52608542e-05, 2.39461264e-05, + 2.28004719e-05, 2.33695366e-05, 2.47589874e-05, 2.54929593e-05, 2.64819797e-05, 2.63194163e-05, + 2.54286446e-05, 2.50757364e-05, 2.36961888e-05, 2.34842584e-05, 2.42252406e-05, 2.51088474e-05, + 2.52317699e-05, 2.51821567e-05, 2.56696172e-05, 2.35057362e-05, 2.19246037e-05, 2.36493762e-05, + 2.55786427e-05, 2.53152260e-05, 2.53268234e-05, 2.55829317e-05, 2.45262119e-05, 2.36608553e-05, + 2.33644287e-05, 2.41938320e-05, 2.55667083e-05, 2.59763136e-05, 2.57066599e-05, 2.51793079e-05, + 2.56447366e-05, 2.82874889e-05, 2.87618915e-05, 2.73385016e-05, 2.50079681e-05, 2.27458437e-05, + 2.14196432e-05, 2.14202649e-05, 2.16746365e-05, 2.53280895e-05, 2.71600892e-05, 2.66868870e-05, + 2.54127376e-05, 2.51925619e-05, 2.48465268e-05, 2.29225976e-05, 2.13916546e-05, 2.17709570e-05, + 2.21607936e-05, 2.15028667e-05, 2.62216542e-05, 2.78875971e-05, 2.79244642e-05, 2.58359375e-05, + 2.45479984e-05, 2.44982237e-05, 2.26907764e-05, 2.07589480e-05, 2.01627112e-05, 2.77735297e-05, + 2.97737347e-05, 2.92052860e-05, 2.47468986e-05, 2.11390736e-05, 2.10985422e-05, 2.13412361e-05, + 2.09655338e-05, 2.08751152e-05, 2.42682210e-05, 2.74019232e-05, 2.85863285e-05, 2.61379938e-05, + 2.35758702e-05, 2.39750761e-05, 2.44613762e-05, 2.29835512e-05, 2.12351537e-05, 2.15295819e-05, + 2.43593568e-05, 2.86393712e-05, 3.00859480e-05, 2.88315665e-05, 2.53010716e-05, 2.12557722e-05, + 1.99486357e-05, 2.05109650e-05, 2.77257117e-05, 2.92252801e-05, 2.86860989e-05, 2.62041481e-05, + 2.26315755e-05, 2.00140414e-05, 1.94712216e-05, 2.05490061e-05, 2.87354996e-05, 2.95048307e-05, + 2.85894492e-05, 2.58858142e-05, 2.13090321e-05, 1.93673557e-05, 2.02773834e-05, 2.11033983e-05, + 2.85852052e-05, 2.97288122e-05, 2.79146332e-05, 2.44452107e-05, 2.31679082e-05, 2.27807440e-05, + 2.18738408e-05, 2.64481989e-05, 2.75587669e-05, 2.79628538e-05, 2.77593896e-05, 2.50286400e-05, + 2.16106805e-05, 2.09007466e-05, 2.12687109e-05, 2.59863835e-05, 2.72774832e-05, 2.72514624e-05, + 2.62344994e-05, 2.54791519e-05, 2.47247954e-05, 2.24762465e-05, 2.13734004e-05, 2.55462264e-05, + 2.75534880e-05, 2.75313684e-05, 2.66588854e-05, 2.62060678e-05, 2.47088292e-05, 2.25099065e-05, + 2.11782705e-05, 2.12297888e-05, 2.35343044e-05, 2.67652476e-05, 2.95890823e-05, 2.99738506e-05, + 2.75948379e-05, 2.25343204e-05, 2.08218881e-05, 2.27284299e-05, 2.70578955e-05, 2.80078197e-05, + 2.69873070e-05, 2.46604463e-05, 2.41740604e-05, 2.36821679e-05, 2.19120442e-05, 2.13654491e-05, + 2.34985414e-05, 2.67191917e-05, 2.87852322e-05, 2.74479834e-05, 2.52272857e-05, 2.29967013e-05, + 2.15214021e-05, 2.14197937e-05, 2.54536657e-05, 2.74853520e-05, 2.77615522e-05, 2.62106595e-05, + 2.44016906e-05, 2.30449377e-05, 2.13138459e-05, 2.19209498e-05, 2.29030868e-05, 2.50450586e-05, + 2.82776533e-05, 2.97325432e-05, 2.79010390e-05, 2.38308239e-05, 2.14493681e-05, 2.01501721e-05, + 2.00504197e-05, 2.09412601e-05, 2.58261237e-05, 2.68771212e-05, 2.75019050e-05, 2.58581314e-05, + 2.30643142e-05, 2.38665640e-05, 2.28113640e-05, 2.07961913e-05, 2.64009890e-05, 2.72296939e-05, + 2.71526240e-05, 2.70375123e-05, 2.61185511e-05, 2.30878559e-05, 2.16169257e-05, 2.23381229e-05, + 2.66337163e-05, 2.82772594e-05, 2.83852608e-05, 2.53271583e-05, 2.14327510e-05, 2.13427084e-05, + 2.19577384e-05, 2.48601409e-05, 2.68297286e-05, 2.81519401e-05, 2.79889234e-05, 2.61010182e-05, + 2.41527362e-05, 2.25614095e-05, 2.08941858e-05, 2.55432385e-05, 2.69878996e-05, 2.71709131e-05, + 2.64576103e-05, 2.50802518e-05, 2.35264404e-05, 2.25189927e-05, 2.25183259e-05, 2.27148723e-05, + 2.53478162e-05, 2.64572025e-05, 2.61953274e-05, 2.53914689e-05, 2.52459293e-05, 2.50193888e-05, + 2.36575680e-05, 2.24978195e-05, 2.27914580e-05, 2.30906317e-05, 2.25811118e-05, 2.58800690e-05, + 2.67738791e-05, 2.68467272e-05, 2.56443054e-05, 2.48013827e-05, 2.47875805e-05, 2.34919614e-05, + 2.19933085e-05, 2.15114380e-05, 2.67314097e-05, 2.72716524e-05, 2.72796878e-05, 2.49105533e-05, + 2.22995904e-05, 2.22677070e-05, 2.24538061e-05, 2.21562153e-05, 2.20845795e-05, 2.45793780e-05, + 2.63928312e-05, 2.70110575e-05, 2.58007450e-05, 2.41264644e-05, 2.44289191e-05, 2.47823194e-05, + 2.37120287e-05, 2.23679566e-05, 2.26043064e-05, 2.46488818e-05, 2.70711308e-05, 2.74937776e-05, + 2.71984024e-05, 2.53113706e-05, 2.23901008e-05, 2.13333135e-05, 2.17897281e-05, 2.67608917e-05, + 2.71864045e-05, 2.69966035e-05, 2.58183048e-05, 2.34374942e-05, 2.13990928e-05, 2.09466685e-05, + 2.18234720e-05, 2.72745840e-05, 2.71888053e-05, 2.69071528e-05, 2.56381675e-05, 2.24335929e-05, + 2.08620110e-05, 2.16017795e-05, 2.22657521e-05, 2.70355010e-05, 2.69920099e-05, 2.66257068e-05, + 2.46878979e-05, 2.38370981e-05, 2.35600790e-05, 2.28658525e-05, 2.59918256e-05, 2.64771485e-05, + 2.66994505e-05, 2.67476459e-05, 2.51600859e-05, 2.26658065e-05, 2.21049809e-05, 2.23966749e-05, + 2.57213655e-05, 2.63845188e-05, 2.63866797e-05, 2.58594542e-05, 2.54409714e-05, 2.49625666e-05, + 2.33304054e-05, 2.24791924e-05, 2.54531064e-05, 2.65766381e-05, 2.65757413e-05, 2.60847815e-05, + 2.58617074e-05, 2.49388699e-05, 2.33559979e-05, 2.23247822e-05, 2.23659175e-05, 2.40429547e-05, + 2.59247833e-05, 2.70367946e-05, 2.75672392e-05, 2.67801213e-05, 2.33735591e-05, 2.20390198e-05, + 2.35199797e-05, 2.63271345e-05, 2.66312978e-05, 2.62176661e-05, 2.48597130e-05, 2.45525135e-05, + 2.42205779e-05, 2.28992611e-05, 2.24736282e-05, 2.40242400e-05, 2.60482304e-05, 2.71202246e-05, + 2.65741202e-05, 2.52711912e-05, 2.37203987e-05, 2.25940310e-05, 2.25161075e-05, 2.54036972e-05, + 2.65289192e-05, 2.66547726e-05, 2.58198409e-05, 2.46923715e-05, 2.37513830e-05, 2.24338706e-05, + 2.29051268e-05, 2.36518978e-05, 2.51056203e-05, 2.68361365e-05, 2.74189363e-05, 2.68249096e-05, + 2.43089595e-05, 2.25426695e-05, 2.15015446e-05, 2.14172574e-05, 2.21366878e-05, 2.55438510e-05, + 2.59964038e-05, 2.64291835e-05, 2.56416475e-05, 2.37690688e-05, 2.43639145e-05, 2.35802694e-05, + 2.20156324e-05, 2.60065233e-05, 2.63317845e-05, 2.62574050e-05, 2.62954092e-05, 2.58338678e-05, + 2.37821211e-05, 2.26719626e-05, 2.32253287e-05, 2.59685756e-05, 2.65221395e-05, 2.69373282e-05, + 2.53547237e-05, 2.25265232e-05, 2.24553380e-05, 2.29334673e-05, 2.49814577e-05, 2.61020344e-05, + 2.67675768e-05, 2.68197186e-05, 2.58565258e-05, 2.45635610e-05, 2.33949068e-05, 2.21005201e-05, + 2.50628097e-05, 2.42466789e-05, 2.39153623e-05, 2.49419426e-05, 2.57156431e-05, 2.52855419e-05, + 2.47644559e-05, 2.45802850e-05, 2.43919731e-05, 2.49808485e-05, 2.46710474e-05, 2.47581481e-05, + 2.51229612e-05, 2.51720950e-05, 2.51500878e-05, 2.52634859e-05, 2.49492459e-05, 2.47247154e-05, + 2.45998055e-05, 2.43884888e-05, 2.51374187e-05, 2.45421219e-05, 2.43946839e-05, 2.52192677e-05, + 2.54398116e-05, 2.50690161e-05, 2.46907707e-05, 2.42878975e-05, 2.40974523e-05, 2.45764630e-05, + 2.26096675e-05, 2.34999071e-05, 2.57406123e-05, 2.55837628e-05, 2.47980799e-05, 2.43110917e-05, + 2.42102013e-05, 2.42164823e-05, 2.59335671e-05, 2.51013218e-05, 2.41078474e-05, 2.53505515e-05, + 2.54453676e-05, 2.48712043e-05, 2.44937654e-05, 2.43926647e-05, 2.41296400e-05, 2.53214857e-05, + 2.58194845e-05, 2.40460380e-05, 2.23383921e-05, 2.38564842e-05, 2.52286745e-05, 2.46448035e-05, + 2.38887077e-05, 2.39869546e-05, 2.44473955e-05, 2.34272991e-05, 2.40194195e-05, 2.54544764e-05, + 2.54975578e-05, 2.45519035e-05, 2.40491463e-05, 2.41573498e-05, 2.38181879e-05, 2.29851614e-05, + 2.41097141e-05, 2.54860830e-05, 2.51512724e-05, 2.40844773e-05, 2.39862439e-05, 2.42429503e-05, + 2.40990910e-05, 2.22422611e-05, 2.47297607e-05, 2.60352157e-05, 2.52801122e-05, 2.42980914e-05, + 2.40668832e-05, 2.52120423e-05, 2.49827346e-05, 2.46504905e-05, 2.45234186e-05, 2.48134873e-05, + 2.44662177e-05, 2.42197064e-05, 2.42953219e-05, 2.53090641e-05, 2.50774328e-05, 2.50547330e-05, + 2.53153050e-05, 2.50353921e-05, 2.45949325e-05, 2.44302194e-05, 2.43256638e-05, 2.53565488e-05, + 2.48033833e-05, 2.47905563e-05, 2.52690265e-05, 2.52026856e-05, 2.49129179e-05, 2.44871371e-05, + 2.42411806e-05, 2.42834172e-05, 2.64558077e-05, 2.57432445e-05, 2.26099198e-05, 2.26107978e-05, + 2.41017649e-05, 2.42070453e-05, 2.40278378e-05, 2.41207920e-05, 2.50192550e-05, 2.46673503e-05, + 2.52740596e-05, 2.56728354e-05, 2.53163531e-05, 2.48118023e-05, 2.44859261e-05, 2.43843465e-05, + 2.63730053e-05, 2.54831109e-05, 2.39187554e-05, 2.47124864e-05, 2.51354963e-05, 2.46850887e-05, + 2.42481892e-05, 2.43788466e-05, 2.52769380e-05, 2.48722839e-05, 2.47276668e-05, 2.54643882e-05, + 2.56032469e-05, 2.50641542e-05, 2.44487525e-05, 2.43417019e-05, 2.42807192e-05, 2.56964452e-05, + 2.43969239e-05, 2.28532968e-05, 2.44332625e-05, 2.53994337e-05, 2.49108268e-05, 2.41098294e-05, + 2.39445726e-05, 2.41919826e-05, 2.58424369e-05, 2.56454552e-05, 2.50489419e-05, 2.53472561e-05, + 2.48287727e-05, 2.39598727e-05, 2.38253565e-05, 2.38784293e-05, 2.49613659e-05, 2.51660037e-05, + 2.52806019e-05, 2.50992106e-05, 2.50366503e-05, 2.51105495e-05, 2.46626282e-05, 2.43978633e-05, + 2.56179469e-05, 2.43081698e-05, 2.42753863e-05, 2.48693648e-05, 2.44059469e-05, 2.43428239e-05, + 2.43377295e-05, 2.57637788e-05, 2.54404985e-05, 2.45109874e-05, 2.44862525e-05, 2.47285089e-05, + 2.45243978e-05, 2.44396744e-05, 2.42684704e-05, 2.52366182e-05, 2.64796292e-05, 2.66014162e-05, + 2.69421104e-05, 2.62172983e-05, 2.39945832e-05, 2.25887911e-05, 2.22851666e-05, 2.20574551e-05, + 2.48187036e-05, 2.57892238e-05, 2.54646914e-05, 2.51899949e-05, 2.51343150e-05, 2.48492639e-05, + 2.40325870e-05, 2.28885293e-05, 2.26386911e-05, 2.25629765e-05, 2.19983280e-05, 2.59394565e-05, + 2.66493300e-05, 2.61620419e-05, 2.57648720e-05, 2.52618039e-05, 2.44677827e-05, 2.29129008e-05, + 2.16217771e-05, 2.11710966e-05, 2.65123392e-05, 2.67313995e-05, 2.67385600e-05, 2.60640178e-05, + 2.38908735e-05, 2.25425333e-05, 2.18247327e-05, 2.15564067e-05, 2.15412844e-05, 2.61387180e-05, + 2.77918111e-05, 2.71108240e-05, 2.64029880e-05, 2.46971448e-05, 2.38008648e-05, 2.33370871e-05, + 2.25120621e-05, 2.15052199e-05, 2.35735752e-05, 2.59518071e-05, 2.68964010e-05, 2.61828260e-05, + 2.65931160e-05, 2.53395120e-05, 2.23395517e-05, 2.08027732e-05, 2.10886487e-05, 2.59651907e-05, + 2.70623074e-05, 2.73339673e-05, 2.67657878e-05, 2.43350642e-05, 2.18390852e-05, 2.09354370e-05, + 2.13614760e-05, 2.58719567e-05, 2.70314806e-05, 2.75954876e-05, 2.64818939e-05, 2.32028232e-05, + 2.09655035e-05, 2.10292397e-05, 2.16469450e-05, 2.69798024e-05, 2.70073811e-05, 2.78005267e-05, + 2.65028334e-05, 2.41766102e-05, 2.22761981e-05, 2.15942185e-05, 2.63932433e-05, 2.77271042e-05, + 2.74684795e-05, 2.62870812e-05, 2.42729440e-05, 2.21584484e-05, 2.15534196e-05, 2.17780752e-05, + 2.61323124e-05, 2.73288360e-05, 2.71793702e-05, 2.64193005e-05, 2.50470078e-05, 2.36661131e-05, + 2.23890014e-05, 2.18577081e-05, 2.58326880e-05, 2.68887535e-05, 2.67892960e-05, 2.68436138e-05, + 2.60903081e-05, 2.42796815e-05, 2.24970045e-05, 2.16655545e-05, 2.17476867e-05, 2.67785548e-05, + 2.89665296e-05, 2.71652234e-05, 2.61037155e-05, 2.47838728e-05, 2.20371048e-05, 2.12323662e-05, + 2.19616154e-05, 2.66865116e-05, 2.79802890e-05, 2.74395518e-05, 2.58459688e-05, 2.47744628e-05, + 2.35488377e-05, 2.22883348e-05, 2.19497832e-05, 2.65703326e-05, 2.76605160e-05, 2.69095616e-05, + 2.63507183e-05, 2.50799474e-05, 2.30237602e-05, 2.17777315e-05, 2.19573501e-05, 2.55691429e-05, + 2.70014398e-05, 2.71171056e-05, 2.68019646e-05, 2.55118557e-05, 2.37216758e-05, 2.20382291e-05, + 2.20539768e-05, 2.22916704e-05, 2.62034243e-05, 2.74304535e-05, 2.64854395e-05, 2.62539461e-05, + 2.47450896e-05, 2.28431325e-05, 2.11869837e-05, 2.09110454e-05, 2.15210017e-05, 2.73895832e-05, + 2.88437610e-05, 2.78800799e-05, 2.60994580e-05, 2.33058180e-05, 2.21170610e-05, 2.15055685e-05, + 2.09951618e-05, 2.56796792e-05, 2.75782885e-05, 2.78763354e-05, 2.69153312e-05, 2.55870304e-05, + 2.38255405e-05, 2.24839410e-05, 2.22863568e-05, 2.79891198e-05, 2.87129856e-05, 2.70960420e-05, + 2.45816336e-05, 2.20051113e-05, 2.18761087e-05, 2.20593930e-05, 2.62073880e-05, 2.77334124e-05, + 2.75378580e-05, 2.66833324e-05, 2.48512323e-05, 2.32427603e-05, 2.24354203e-05, 2.16284587e-05, + 2.45051428e-05, 2.13473033e-05, 2.05595410e-05, 2.24684360e-05, 2.50902054e-05, 2.68643786e-05, + 2.75560612e-05, 2.74729533e-05, 2.72268202e-05, 2.47910779e-05, 2.29269686e-05, 2.34707167e-05, + 2.47214448e-05, 2.49226126e-05, 2.52217253e-05, 2.67315996e-05, 2.76539656e-05, 2.73138841e-05, + 2.70094059e-05, 2.73322922e-05, 2.39076967e-05, 2.18408437e-05, 2.19425701e-05, 2.43065308e-05, + 2.55054540e-05, 2.54965681e-05, 2.66973209e-05, 2.77387208e-05, 2.79938799e-05, 2.20352591e-05, + 1.79918918e-05, 1.96341810e-05, 2.53393167e-05, 2.80739536e-05, 2.77747671e-05, 2.73952675e-05, + 2.75742706e-05, 2.76320901e-05, 2.57802822e-05, 2.20921238e-05, 2.05619065e-05, 2.39481766e-05, + 2.62935274e-05, 2.58552728e-05, 2.53951970e-05, 2.63872732e-05, 2.73703093e-05, 2.77133595e-05, + 2.56950641e-05, 2.05990096e-05, 1.78478289e-05, 2.04463412e-05, 2.48257603e-05, 2.76058737e-05, + 2.80026307e-05, 2.77283048e-05, 2.22396317e-05, 1.92727222e-05, 2.02224008e-05, 2.38307391e-05, + 2.70093147e-05, 2.83242358e-05, 2.83714536e-05, 2.77969988e-05, 2.09421945e-05, 1.84778980e-05, + 2.02128266e-05, 2.42025899e-05, 2.77918522e-05, 2.84520568e-05, 2.78653812e-05, 2.75071838e-05, + 2.06430942e-05, 1.71954122e-05, 2.13042723e-05, 2.56153999e-05, 2.65588651e-05, 2.64816657e-05, + 2.69496175e-05, 2.36188542e-05, 2.18914042e-05, 2.13982814e-05, 2.21175088e-05, 2.50254972e-05, + 2.73011024e-05, 2.76182622e-05, 2.74321352e-05, 2.41315640e-05, 2.24304528e-05, 2.25105899e-05, + 2.38443493e-05, 2.46586480e-05, 2.52231385e-05, 2.67341250e-05, 2.73825029e-05, 2.45860460e-05, + 2.22071590e-05, 2.22660032e-05, 2.33103984e-05, 2.39099419e-05, 2.53005918e-05, 2.67359387e-05, + 2.74607212e-05, 2.74501423e-05, 2.64522604e-05, 2.25176090e-05, 1.77338526e-05, 1.83912333e-05, + 2.25848057e-05, 2.66011310e-05, 2.75659239e-05, 2.64397226e-05, 2.28772585e-05, 2.10412985e-05, + 2.27719705e-05, 2.54192853e-05, 2.57988072e-05, 2.60523975e-05, 2.71197642e-05, 2.74155561e-05, + 2.64814140e-05, 2.30473942e-05, 2.03330797e-05, 2.24860912e-05, 2.48897844e-05, 2.64890931e-05, + 2.72539629e-05, 2.73792875e-05, 2.46816231e-05, 2.22612170e-05, 2.18469370e-05, 2.38183496e-05, + 2.56454450e-05, 2.65836981e-05, 2.74781600e-05, 2.70493145e-05, 2.63949572e-05, 2.50552060e-05, + 2.09056704e-05, 1.85870916e-05, 2.19464549e-05, 2.60860585e-05, 2.76004049e-05, 2.80080365e-05, + 2.79750029e-05, 2.75796514e-05, 2.41481531e-05, 2.24066448e-05, 2.19086569e-05, 2.42639157e-05, + 2.64932133e-05, 2.56329976e-05, 2.62549145e-05, 2.75012654e-05, 2.37460698e-05, 2.24112025e-05, + 2.24098982e-05, 2.28487435e-05, 2.40368047e-05, 2.65675277e-05, 2.73855299e-05, 2.68093677e-05, + 2.30606214e-05, 1.98375386e-05, 2.09133866e-05, 2.47824625e-05, 2.73840917e-05, 2.74096926e-05, + 2.70243742e-05, 2.52308694e-05, 2.28864499e-05, 2.10565314e-05, 2.16906335e-05, 2.40773897e-05, + 2.56286449e-05, 2.66828366e-05, 2.76470128e-05, 2.56180028e-05, 2.80991932e-05, 2.85326207e-05, + 2.72605090e-05, 2.50819218e-05, 2.28674490e-05, 2.15569191e-05, 2.15410870e-05, 2.17654864e-05, + 2.53035260e-05, 2.70378555e-05, 2.65874412e-05, 2.54017733e-05, 2.51957464e-05, 2.48609238e-05, + 2.30338887e-05, 2.15467569e-05, 2.18871175e-05, 2.22458212e-05, 2.16022911e-05, 2.61862171e-05, + 2.77454533e-05, 2.77539154e-05, 2.58223141e-05, 2.46069516e-05, 2.45183183e-05, 2.27577273e-05, + 2.08880496e-05, 2.03066277e-05, 2.76349002e-05, 2.94274329e-05, 2.89344675e-05, 2.48325752e-05, + 2.13620053e-05, 2.12547281e-05, 2.14421285e-05, 2.10771423e-05, 2.09919967e-05, 2.43926845e-05, + 2.73591888e-05, 2.83987691e-05, 2.61334827e-05, 2.36760324e-05, 2.39976789e-05, 2.44207628e-05, + 2.30067519e-05, 2.13254915e-05, 2.17112899e-05, 2.44678160e-05, 2.84365423e-05, 2.96796008e-05, + 2.85947126e-05, 2.53068582e-05, 2.13906352e-05, 2.00864031e-05, 2.06272459e-05, 2.75628909e-05, + 2.89648620e-05, 2.84978725e-05, 2.62127670e-05, 2.27788379e-05, 2.02032644e-05, 1.96469835e-05, + 2.06778292e-05, 2.84723810e-05, 2.92063279e-05, 2.84224933e-05, 2.59054904e-05, 2.14860306e-05, + 1.95512804e-05, 2.04059529e-05, 2.12106669e-05, 2.83917718e-05, 2.93854187e-05, 2.78247889e-05, + 2.45749973e-05, 2.32695752e-05, 2.28052605e-05, 2.19245330e-05, 2.64179282e-05, 2.74988404e-05, + 2.78533074e-05, 2.76104448e-05, 2.49972168e-05, 2.17115447e-05, 2.10165697e-05, 2.13719786e-05, + 2.59800439e-05, 2.72238489e-05, 2.71928315e-05, 2.62230258e-05, 2.54552043e-05, 2.46826663e-05, + 2.25292067e-05, 2.14739180e-05, 2.55590364e-05, 2.74537328e-05, 2.74286210e-05, 2.66341324e-05, + 2.61798299e-05, 2.47025287e-05, 2.25665442e-05, 2.12814688e-05, 2.13340301e-05, 2.37413707e-05, + 2.68307877e-05, 2.92768468e-05, 2.95826478e-05, 2.73783786e-05, 2.25630261e-05, 2.09251969e-05, + 2.27385854e-05, 2.69914332e-05, 2.79168072e-05, 2.69642140e-05, 2.47413998e-05, 2.42349042e-05, + 2.37124981e-05, 2.19992293e-05, 2.14716094e-05, 2.36981035e-05, 2.67294317e-05, 2.85678741e-05, + 2.73302563e-05, 2.52248404e-05, 2.30478521e-05, 2.16072511e-05, 2.15226525e-05, 2.54598044e-05, + 2.73972857e-05, 2.76541413e-05, 2.62205738e-05, 2.44845286e-05, 2.31309549e-05, 2.14283929e-05, + 2.19944211e-05, 2.29195349e-05, 2.51155126e-05, 2.81357507e-05, 2.93868732e-05, 2.77374346e-05, + 2.39151804e-05, 2.15982257e-05, 2.02957760e-05, 2.01874613e-05, 2.10525502e-05, 2.58956091e-05, + 2.69277267e-05, 2.74541962e-05, 2.58603052e-05, 2.31262382e-05, 2.38000340e-05, 2.27884649e-05, + 2.08879039e-05, 2.63370177e-05, 2.71922223e-05, 2.71359141e-05, 2.69843422e-05, 2.60727164e-05, + 2.31764251e-05, 2.17351947e-05, 2.23951583e-05, 2.66665956e-05, 2.81856965e-05, 2.82173441e-05, + 2.52895587e-05, 2.15373626e-05, 2.14463491e-05, 2.20289279e-05, 2.49446665e-05, 2.68341136e-05, + 2.80272973e-05, 2.78390834e-05, 2.60162809e-05, 2.41304049e-05, 2.26108834e-05, 2.10145891e-05, + 2.56445488e-05, 2.79569477e-05, 2.83506876e-05, 2.70480688e-05, 2.49426618e-05, 2.29330703e-05, + 2.17260267e-05, 2.17500490e-05, 2.20225218e-05, 2.53807872e-05, 2.70171864e-05, 2.66102663e-05, + 2.54268233e-05, 2.52205932e-05, 2.49132628e-05, 2.31042996e-05, 2.16751245e-05, 2.20731482e-05, + 2.24679784e-05, 2.18551022e-05, 2.61226110e-05, 2.75791588e-05, 2.76740161e-05, 2.57750712e-05, + 2.45871809e-05, 2.46100794e-05, 2.29666733e-05, 2.11367401e-05, 2.05688865e-05, 2.74940063e-05, + 2.90874781e-05, 2.86922344e-05, 2.47065735e-05, 2.13482080e-05, 2.14081976e-05, 2.17065380e-05, + 2.13496763e-05, 2.12598202e-05, 2.42393993e-05, 2.70005853e-05, 2.81227624e-05, 2.59964429e-05, + 2.36905957e-05, 2.41583698e-05, 2.46760308e-05, 2.32905628e-05, 2.16248534e-05, 2.17605882e-05, + 2.43436926e-05, 2.82010904e-05, 2.94416713e-05, 2.84109725e-05, 2.53055013e-05, 2.15811183e-05, + 2.03794517e-05, 2.09269911e-05, 2.75176952e-05, 2.86423125e-05, 2.81686014e-05, 2.60211603e-05, + 2.27930018e-05, 2.03699241e-05, 1.98857781e-05, 2.09447983e-05, 2.84356178e-05, 2.88413137e-05, + 2.80449839e-05, 2.57510641e-05, 2.15688301e-05, 1.97782629e-05, 2.06953909e-05, 2.14813907e-05, + 2.81423351e-05, 2.89224547e-05, 2.74480347e-05, 2.43776121e-05, 2.33339697e-05, 2.31087872e-05, + 2.22590114e-05, 2.62882435e-05, 2.71477246e-05, 2.75365442e-05, 2.75091192e-05, 2.51428016e-05, + 2.19505541e-05, 2.12846967e-05, 2.16373539e-05, 2.58809958e-05, 2.69464565e-05, 2.69408590e-05, + 2.60853894e-05, 2.55042142e-05, 2.49034640e-05, 2.27963597e-05, 2.17362484e-05, 2.54928137e-05, + 2.72489946e-05, 2.72412011e-05, 2.64360468e-05, 2.60924768e-05, 2.48318169e-05, 2.28210244e-05, + 2.15552166e-05, 2.16006196e-05, 2.34764506e-05, 2.62891420e-05, 2.88292310e-05, 2.93992307e-05, + 2.75356607e-05, 2.28832149e-05, 2.12298289e-05, 2.30830204e-05, 2.68215458e-05, 2.75012146e-05, + 2.66705438e-05, 2.46431906e-05, 2.42675512e-05, 2.38926793e-05, 2.22416832e-05, 2.17211092e-05, + 2.34590858e-05, 2.64010000e-05, 2.83212878e-05, 2.72179783e-05, 2.52591032e-05, 2.32607459e-05, + 2.18909915e-05, 2.17750217e-05, 2.54297939e-05, 2.71737324e-05, 2.74065407e-05, 2.60235011e-05, + 2.44234357e-05, 2.32504762e-05, 2.16625007e-05, 2.22692717e-05, 2.32291632e-05, 2.49794064e-05, + 2.78127400e-05, 2.91379761e-05, 2.76413430e-05, 2.39355977e-05, 2.17362328e-05, 2.05550338e-05, + 2.04745369e-05, 2.13279596e-05, 2.56039862e-05, 2.64033393e-05, 2.70776281e-05, 2.57629863e-05, + 2.33041211e-05, 2.41999860e-05, 2.32042572e-05, 2.12221431e-05, 2.63184794e-05, 2.68732229e-05, + 2.67677744e-05, 2.67767539e-05, 2.60609840e-05, 2.32842043e-05, 2.19313728e-05, 2.26671057e-05, + 2.62859485e-05, 2.75904530e-05, 2.79545452e-05, 2.54023813e-05, 2.17842925e-05, 2.17040202e-05, + 2.23056269e-05, 2.48021041e-05, 2.64933605e-05, 2.76896204e-05, 2.76651855e-05, 2.61184689e-05, + 2.43818703e-05, 2.28773365e-05, 2.12723655e-05, 2.55041035e-05, 2.58760298e-05, 2.58165490e-05, + 2.53512373e-05, 2.46468148e-05, 2.40876677e-05, 2.35955396e-05, 2.37225287e-05, 2.40381539e-05, + 2.55229484e-05, 2.59728345e-05, 2.59424125e-05, 2.53903099e-05, 2.52837787e-05, 2.52030126e-05, + 2.42076317e-05, 2.34478701e-05, 2.38738471e-05, 2.42328984e-05, 2.39148092e-05, 2.54554188e-05, + 2.56841140e-05, 2.60117823e-05, 2.53432324e-05, 2.48132997e-05, 2.51531993e-05, 2.45139675e-05, + 2.34139296e-05, 2.30524317e-05, 2.57453346e-05, 2.51075860e-05, 2.56148493e-05, 2.45623139e-05, + 2.28301479e-05, 2.33369495e-05, 2.38471469e-05, 2.36267036e-05, 2.35518568e-05, 2.42266506e-05, + 2.48296818e-05, 2.54137292e-05, 2.51683759e-05, 2.44022258e-05, 2.50968620e-05, 2.56644342e-05, + 2.49269031e-05, 2.38886896e-05, 2.32842617e-05, 2.43708385e-05, 2.55845179e-05, 2.55491391e-05, + 2.58198680e-05, 2.52491465e-05, 2.35572472e-05, 2.30015705e-05, 2.34084594e-05, 2.60774486e-05, + 2.52635765e-05, 2.52084880e-05, 2.50073526e-05, 2.38538275e-05, 2.26474094e-05, 2.24947963e-05, + 2.33306673e-05, 2.63733582e-05, 2.50395414e-05, 2.49963438e-05, 2.50006633e-05, 2.32492376e-05, + 2.23835236e-05, 2.32169434e-05, 2.37118622e-05, 2.55201150e-05, 2.44271413e-05, 2.48891492e-05, + 2.41713801e-05, 2.43313086e-05, 2.48691263e-05, 2.44096905e-05, 2.53214027e-05, 2.49014514e-05, + 2.51338885e-05, 2.58853547e-05, 2.56005323e-05, 2.39401755e-05, 2.35698390e-05, 2.38030633e-05, + 2.52336644e-05, 2.50945126e-05, 2.51793217e-05, 2.52066670e-05, 2.55014636e-05, 2.56909214e-05, + 2.45697328e-05, 2.38614126e-05, 2.51475196e-05, 2.54461699e-05, 2.55028320e-05, 2.51644749e-05, + 2.53676100e-05, 2.53849398e-05, 2.45498929e-05, 2.37705170e-05, 2.37815329e-05, 2.34623659e-05, + 2.39469337e-05, 2.45835540e-05, 2.58423635e-05, 2.67458427e-05, 2.47734903e-05, 2.36327344e-05, + 2.49676674e-05, 2.54100762e-05, 2.47538157e-05, 2.49403502e-05, 2.46112912e-05, 2.47887394e-05, + 2.49973462e-05, 2.41421550e-05, 2.38156233e-05, 2.35283334e-05, 2.47213197e-05, 2.55604076e-05, + 2.57482100e-05, 2.53318524e-05, 2.47083464e-05, 2.40246852e-05, 2.38598676e-05, 2.52259217e-05, + 2.53565031e-05, 2.53468237e-05, 2.49910428e-05, 2.46012618e-05, 2.44373436e-05, 2.37333796e-05, + 2.42505454e-05, 2.49614361e-05, 2.46754044e-05, 2.51741844e-05, 2.55664632e-05, 2.59460017e-05, + 2.45627271e-05, 2.35157611e-05, 2.30343218e-05, 2.30533079e-05, 2.36197266e-05, 2.45012495e-05, + 2.40469636e-05, 2.47892692e-05, 2.51833790e-05, 2.46359619e-05, 2.58040894e-05, 2.52434349e-05, + 2.37090274e-05, 2.56844416e-05, 2.49262089e-05, 2.47199443e-05, 2.52682304e-05, 2.55877589e-05, + 2.44246305e-05, 2.38081871e-05, 2.45005331e-05, 2.45015466e-05, 2.40226907e-05, 2.54324279e-05, + 2.56399070e-05, 2.38509984e-05, 2.38267652e-05, 2.42795138e-05, 2.45632951e-05, 2.47152750e-05, + 2.50922256e-05, 2.56830401e-05, 2.59635364e-05, 2.54865157e-05, 2.46192183e-05, 2.35327489e-05, + 2.50719954e-05, 2.34933346e-05, 2.30137810e-05, 2.37643073e-05, 2.47564739e-05, 2.54918524e-05, + 2.56550377e-05, 2.57345327e-05, 2.58506952e-05, 2.52715602e-05, 2.44659894e-05, 2.47682911e-05, + 2.51192519e-05, 2.51629831e-05, 2.52938118e-05, 2.55009428e-05, 2.55693957e-05, 2.57174069e-05, + 2.58134794e-05, 2.58275782e-05, 2.46677135e-05, 2.36414147e-05, 2.39225347e-05, 2.48232520e-05, + 2.51559860e-05, 2.54406200e-05, 2.58026590e-05, 2.57341497e-05, 2.56657433e-05, 2.37927282e-05, + 2.11624736e-05, 2.23730439e-05, 2.48422603e-05, 2.52419824e-05, 2.55915123e-05, 2.58339292e-05, + 2.58058889e-05, 2.57854283e-05, 2.48432695e-05, 2.31986079e-05, 2.27544827e-05, 2.44766346e-05, + 2.53435040e-05, 2.56558544e-05, 2.58229408e-05, 2.59582378e-05, 2.58878891e-05, 2.54131075e-05, + 2.49090920e-05, 2.28853898e-05, 2.13448578e-05, 2.29529293e-05, 2.50727400e-05, 2.56819326e-05, + 2.56812513e-05, 2.57908427e-05, 2.41387346e-05, 2.19561586e-05, 2.24375894e-05, 2.42888728e-05, + 2.53745186e-05, 2.54622592e-05, 2.54887916e-05, 2.57374976e-05, 2.35932984e-05, 2.13867833e-05, + 2.22969320e-05, 2.44998741e-05, 2.54668264e-05, 2.54451374e-05, 2.57342266e-05, 2.58194448e-05, + 2.28679234e-05, 2.03288696e-05, 2.28138937e-05, 2.46951568e-05, 2.54812086e-05, 2.59959751e-05, + 2.60133892e-05, 2.43977754e-05, 2.31387546e-05, 2.30271928e-05, 2.39356662e-05, 2.54943787e-05, + 2.58103707e-05, 2.57893608e-05, 2.58281007e-05, 2.46340871e-05, 2.35651532e-05, 2.36682918e-05, + 2.44444266e-05, 2.51679397e-05, 2.57149330e-05, 2.59164036e-05, 2.58332679e-05, 2.48425121e-05, + 2.36839029e-05, 2.37559073e-05, 2.41062750e-05, 2.46031526e-05, 2.55030283e-05, 2.58920569e-05, + 2.58338096e-05, 2.58261455e-05, 2.46231559e-05, 2.28198651e-05, 2.07114906e-05, 2.18229429e-05, + 2.48152768e-05, 2.60225269e-05, 2.58455737e-05, 2.60748575e-05, 2.40359095e-05, 2.25838080e-05, + 2.36460136e-05, 2.49324359e-05, 2.53348941e-05, 2.57195244e-05, 2.58397672e-05, 2.58079692e-05, + 2.46978987e-05, 2.36431752e-05, 2.27233696e-05, 2.40510506e-05, 2.51807235e-05, 2.58118530e-05, + 2.58882787e-05, 2.58188491e-05, 2.49632855e-05, 2.36523119e-05, 2.34159826e-05, 2.42697113e-05, + 2.50698199e-05, 2.56091526e-05, 2.57731258e-05, 2.59036371e-05, 2.60095634e-05, 2.47578244e-05, + 2.27861304e-05, 2.17653393e-05, 2.38797249e-05, 2.53383068e-05, 2.55943035e-05, 2.56581303e-05, + 2.56898279e-05, 2.58081113e-05, 2.40944806e-05, 2.28306639e-05, 2.30721616e-05, 2.46749511e-05, + 2.57365446e-05, 2.61702287e-05, 2.62117423e-05, 2.58948757e-05, 2.47424371e-05, 2.34382412e-05, + 2.32952340e-05, 2.39194394e-05, 2.48458691e-05, 2.55820320e-05, 2.57262740e-05, 2.59208302e-05, + 2.34950325e-05, 2.14806585e-05, 2.29592923e-05, 2.53614588e-05, 2.58096515e-05, 2.58212720e-05, + 2.59096797e-05, 2.47759451e-05, 2.35508486e-05, 2.28141999e-05, 2.35564580e-05, 2.51602621e-05, + 2.58433774e-05, 2.59175101e-05, 2.57692371e-05, 2.51727756e-05, 2.46602225e-05, 2.43961586e-05, + 2.50815555e-05, 2.54852547e-05, 2.49867497e-05, 2.44525511e-05, 2.43386082e-05, 2.42660646e-05, + 2.51063294e-05, 2.49912321e-05, 2.50441663e-05, 2.51915226e-05, 2.52032278e-05, 2.51623151e-05, + 2.49994564e-05, 2.45611923e-05, 2.44894749e-05, 2.44777803e-05, 2.42336978e-05, 2.52326131e-05, + 2.48468503e-05, 2.47964985e-05, 2.52653246e-05, 2.52986574e-05, 2.50819071e-05, 2.46182231e-05, + 2.40337264e-05, 2.37969978e-05, 2.48837660e-05, 2.32429789e-05, 2.40366584e-05, 2.54807823e-05, + 2.48997795e-05, 2.44151162e-05, 2.41562884e-05, 2.40238366e-05, 2.40108167e-05, 2.55455615e-05, + 2.50992350e-05, 2.44655659e-05, 2.53371302e-05, 2.51948252e-05, 2.49058961e-05, 2.47368189e-05, + 2.44784373e-05, 2.40227819e-05, 2.48118070e-05, 2.54916601e-05, 2.44516093e-05, 2.31146674e-05, + 2.43515682e-05, 2.52422069e-05, 2.43490545e-05, 2.36213617e-05, 2.37958988e-05, 2.48470732e-05, + 2.39115994e-05, 2.43572934e-05, 2.53852898e-05, 2.50956434e-05, 2.40518934e-05, 2.36235138e-05, + 2.39111203e-05, 2.44258329e-05, 2.35233997e-05, 2.43839800e-05, 2.54017452e-05, 2.46697231e-05, + 2.36236147e-05, 2.37495051e-05, 2.40700696e-05, 2.44796737e-05, 2.28203643e-05, 2.48332363e-05, + 2.56148681e-05, 2.50439868e-05, 2.43888167e-05, 2.40959543e-05, 2.52676886e-05, 2.50253005e-05, + 2.48223942e-05, 2.48696458e-05, 2.49854572e-05, 2.43012658e-05, 2.40176747e-05, 2.41332632e-05, + 2.53154281e-05, 2.51330835e-05, 2.51323963e-05, 2.53197446e-05, 2.51475130e-05, 2.48266616e-05, + 2.44235582e-05, 2.41712226e-05, 2.53252583e-05, 2.49970107e-05, 2.49980107e-05, 2.52837584e-05, + 2.52650147e-05, 2.50125930e-05, 2.44642702e-05, 2.40827238e-05, 2.41187020e-05, 2.57556482e-05, + 2.53921038e-05, 2.31396422e-05, 2.33853368e-05, 2.47005770e-05, 2.42933003e-05, 2.38815427e-05, + 2.42695859e-05, 2.51481962e-05, 2.47587295e-05, 2.52477107e-05, 2.54374082e-05, 2.51903816e-05, + 2.48331685e-05, 2.43655086e-05, 2.42065696e-05, 2.57072764e-05, 2.53577649e-05, 2.43493160e-05, + 2.49846127e-05, 2.51854349e-05, 2.46607560e-05, 2.41489624e-05, 2.42128704e-05, 2.52779667e-05, + 2.50312407e-05, 2.49218697e-05, 2.53896645e-05, 2.53763052e-05, 2.48977916e-05, 2.42375447e-05, + 2.42769644e-05, 2.43966364e-05, 2.54773977e-05, 2.46385598e-05, 2.35231648e-05, 2.48134754e-05, + 2.51992456e-05, 2.45478990e-05, 2.38022968e-05, 2.36775384e-05, 2.40078100e-05, 2.55685762e-05, + 2.53413759e-05, 2.50522442e-05, 2.53319527e-05, 2.47583153e-05, 2.43332442e-05, 2.40954912e-05, + 2.37817218e-05, 2.51456369e-05, 2.51659708e-05, 2.52099869e-05, 2.51809613e-05, 2.51790654e-05, + 2.49317429e-05, 2.44244208e-05, 2.43812395e-05, 2.54131039e-05, 2.43339720e-05, 2.45970480e-05, + 2.50431124e-05, 2.42321446e-05, 2.41764613e-05, 2.42807104e-05, 2.55011755e-05, 2.53258844e-05, + 2.47087406e-05, 2.48047641e-05, 2.50134838e-05, 2.47187814e-05, 2.44429142e-05, 2.40471303e-05, + 2.54362410e-05, 2.93550368e-05, 3.01440138e-05, 2.87564686e-05, 2.57665494e-05, 2.21460638e-05, + 2.01808469e-05, 1.99611599e-05, 1.99607101e-05, 2.47981562e-05, 2.73534045e-05, 2.65765568e-05, + 2.51976990e-05, 2.49644584e-05, 2.44339786e-05, 2.23031457e-05, 2.03797930e-05, 2.04499843e-05, + 2.06534955e-05, 1.98067340e-05, 2.66018540e-05, 2.90654076e-05, 2.85570654e-05, 2.60867448e-05, + 2.45465285e-05, 2.38345281e-05, 2.12759371e-05, 1.90644951e-05, 1.83810234e-05, 2.87767096e-05, + 3.23948492e-05, 3.10493295e-05, 2.54054122e-05, 2.09341694e-05, 1.99363226e-05, 1.95776078e-05, + 1.91479997e-05, 1.90805727e-05, 2.50644957e-05, 2.97912625e-05, 3.05676326e-05, 2.69675365e-05, + 2.33150212e-05, 2.28873552e-05, 2.28643490e-05, 2.11674928e-05, 1.92808503e-05, 2.09731523e-05, + 2.49809617e-05, 3.03576792e-05, 3.20589998e-05, 3.02346172e-05, 2.52368005e-05, 1.98932900e-05, + 1.79987712e-05, 1.85373013e-05, 2.81218692e-05, 3.16191267e-05, 3.10412397e-05, 2.73837499e-05, + 2.23264170e-05, 1.87473145e-05, 1.78005496e-05, 1.87509913e-05, 2.91842241e-05, 3.22468708e-05, + 3.12612125e-05, 2.68043371e-05, 2.05522877e-05, 1.77579302e-05, 1.83533589e-05, 1.92992068e-05, + 3.03891360e-05, 3.32386611e-05, 3.04884407e-05, 2.55288967e-05, 2.25948220e-05, 2.08503517e-05, + 1.97493080e-05, 2.72571651e-05, 2.99156648e-05, 3.01370469e-05, 2.85102210e-05, 2.40828788e-05, + 1.99929380e-05, 1.91052284e-05, 1.94978392e-05, 2.65671714e-05, 2.91127405e-05, 2.89174356e-05, + 2.70756317e-05, 2.51258303e-05, 2.33338885e-05, 2.07331337e-05, 1.96219218e-05, 2.58921498e-05, + 2.89437570e-05, 2.88075979e-05, 2.79195234e-05, 2.67315776e-05, 2.38391906e-05, 2.08372349e-05, + 1.93598070e-05, 1.94512903e-05, 2.49870922e-05, 3.03430064e-05, 3.29465912e-05, 3.15516130e-05, + 2.67545819e-05, 2.05058528e-05, 1.88293359e-05, 2.05760705e-05, 2.81752506e-05, 3.08602717e-05, + 2.88998331e-05, 2.51420439e-05, 2.38388301e-05, 2.24701268e-05, 2.02850127e-05, 1.96832646e-05, + 2.47843950e-05, 2.88346499e-05, 3.05972200e-05, 2.82372824e-05, 2.49453437e-05, 2.15718942e-05, + 1.96586007e-05, 1.97236173e-05, 2.55725456e-05, 2.89904643e-05, 2.94535004e-05, 2.74256181e-05, + 2.46405411e-05, 2.21486493e-05, 1.97138759e-05, 2.01179243e-05, 2.09438708e-05, 2.57866239e-05, + 3.05337946e-05, 3.17105711e-05, 2.86332100e-05, 2.35489642e-05, 2.03853359e-05, 1.83842625e-05, + 1.81342021e-05, 1.91076656e-05, 2.76178000e-05, 3.03463277e-05, 3.00241447e-05, 2.64183959e-05, + 2.18381052e-05, 2.14560213e-05, 2.02832008e-05, 1.86464589e-05, 2.65192785e-05, 2.93350323e-05, + 2.95784689e-05, 2.83944515e-05, 2.61741032e-05, 2.22607028e-05, 2.02345866e-05, 2.05642209e-05, + 2.90893042e-05, 3.24502904e-05, 3.02520045e-05, 2.45888782e-05, 1.97664974e-05, 1.96155695e-05, + 2.01458379e-05, 2.56290315e-05, 2.90381654e-05, 3.04907988e-05, 2.92267161e-05, 2.54747606e-05, + 2.25626006e-05, 2.08250605e-05, 1.91542237e-05, 2.43054945e-05, 2.04997615e-05, 1.96005063e-05, + 2.16066711e-05, 2.46470622e-05, 2.72229307e-05, 2.84135328e-05, 2.84289352e-05, 2.82474498e-05, + 2.47414425e-05, 2.24227148e-05, 2.31107083e-05, 2.45540130e-05, 2.47884856e-05, 2.51981993e-05, + 2.70702359e-05, 2.84153279e-05, 2.81429187e-05, 2.78471486e-05, 2.83786193e-05, 2.34511317e-05, + 2.09977625e-05, 2.12387964e-05, 2.39345079e-05, 2.53776113e-05, 2.56123634e-05, 2.73993273e-05, + 2.89327306e-05, 2.93527688e-05, 2.12471869e-05, 1.67321060e-05, 1.85454279e-05, 2.49589169e-05, + 2.85193892e-05, 2.86571189e-05, 2.85040246e-05, 2.87836222e-05, 2.88492326e-05, 2.54069487e-05, + 2.09758573e-05, 1.94763272e-05, 2.33630557e-05, 2.63940740e-05, 2.62089695e-05, 2.58602412e-05, + 2.72014706e-05, 2.85874161e-05, 2.82502063e-05, 2.53721098e-05, 1.95702504e-05, 1.66958266e-05, + 1.94776951e-05, 2.46221775e-05, 2.85495916e-05, 2.94896883e-05, 2.91059581e-05, 2.16188941e-05, + 1.80698985e-05, 1.90492172e-05, 2.31341032e-05, 2.72663400e-05, 2.94629865e-05, 2.98220394e-05, + 2.90829671e-05, 2.02104018e-05, 1.72011017e-05, 1.89758064e-05, 2.36157621e-05, 2.84541996e-05, + 2.98937590e-05, 2.92689725e-05, 2.86823086e-05, 1.95979744e-05, 1.57930139e-05, 2.01173106e-05, + 2.51237896e-05, 2.68409035e-05, 2.73815969e-05, 2.81123731e-05, 2.30086849e-05, 2.07744077e-05, + 2.03028216e-05, 2.13976113e-05, 2.51633133e-05, 2.82914051e-05, 2.88306195e-05, 2.85586864e-05, + 2.36387383e-05, 2.14631890e-05, 2.15896910e-05, 2.32459803e-05, 2.45288053e-05, 2.55683018e-05, + 2.76132747e-05, 2.84793487e-05, 2.42172074e-05, 2.13356658e-05, 2.14262874e-05, 2.25490593e-05, + 2.34104316e-05, 2.54593570e-05, 2.75789740e-05, 2.86272291e-05, 2.85879810e-05, 2.59261928e-05, + 2.11377186e-05, 1.63518626e-05, 1.73181369e-05, 2.23300316e-05, 2.75900778e-05, 2.88867220e-05, + 2.74428287e-05, 2.21209666e-05, 1.97867937e-05, 2.18047499e-05, 2.51092848e-05, 2.58418092e-05, + 2.65017777e-05, 2.80562509e-05, 2.84826390e-05, 2.60188841e-05, 2.20442674e-05, 1.92743629e-05, + 2.17847355e-05, 2.47693694e-05, 2.71407309e-05, 2.83714328e-05, 2.84419746e-05, 2.43980625e-05, + 2.13649592e-05, 2.08824507e-05, 2.31106308e-05, 2.54516249e-05, 2.70136155e-05, 2.85181754e-05, + 2.80611142e-05, 2.72834817e-05, 2.46136103e-05, 1.97740736e-05, 1.74468690e-05, 2.12184867e-05, + 2.61580508e-05, 2.83746201e-05, 2.93618925e-05, 2.94234849e-05, 2.88014289e-05, 2.33028802e-05, + 2.10493667e-05, 2.07543250e-05, 2.37914523e-05, 2.70525470e-05, 2.65187487e-05, 2.73994870e-05, + 2.89014021e-05, 2.33497673e-05, 2.13771207e-05, 2.12985387e-05, 2.20280251e-05, 2.36932966e-05, + 2.69628552e-05, 2.82701645e-05, 2.77278913e-05, 2.19718832e-05, 1.83061415e-05, 1.98657599e-05, + 2.48042669e-05, 2.84307534e-05, 2.85016192e-05, 2.80328679e-05, 2.48005972e-05, 2.18511538e-05, + 1.99123500e-05, 2.08240794e-05, 2.39541381e-05, 2.61437817e-05, 2.75430492e-05, 2.88348468e-05, + 2.28834926e-05, 1.65331572e-05, 1.52600903e-05, 1.81117334e-05, 2.33087544e-05, 2.90758701e-05, + 3.24056221e-05, 3.25762180e-05, 3.22240916e-05, 2.37791313e-05, 1.95588494e-05, 2.07490985e-05, + 2.33481124e-05, 2.37960105e-05, 2.46401269e-05, 2.87248195e-05, 3.22844661e-05, 3.17169235e-05, + 3.10336108e-05, 3.25787847e-05, 2.12421429e-05, 1.72370250e-05, 1.76597979e-05, 2.21140839e-05, + 2.48898890e-05, 2.55462276e-05, 2.98488446e-05, 3.41902142e-05, 3.55692563e-05, 1.76253814e-05, + 1.16327435e-05, 1.38489374e-05, 2.39171842e-05, 3.21511157e-05, 3.30395743e-05, 3.29768512e-05, + 3.38301841e-05, 3.40102883e-05, 2.47524133e-05, 1.70696086e-05, 1.50387386e-05, 2.10122883e-05, + 2.70781339e-05, 2.69472927e-05, 2.63644172e-05, 2.95464467e-05, 3.33452893e-05, 3.16108762e-05, + 2.47251205e-05, 1.51877359e-05, 1.16312791e-05, 1.50939541e-05, 2.34418615e-05, 3.28563799e-05, + 3.61659892e-05, 3.49370570e-05, 1.82653740e-05, 1.32180878e-05, 1.44485252e-05, 2.05689912e-05, + 2.90652699e-05, 3.55130753e-05, 3.70404058e-05, 3.47270805e-05, 1.61944730e-05, 1.21619565e-05, + 1.43285520e-05, 2.14300678e-05, 3.22536520e-05, 3.72315134e-05, 3.54171127e-05, 3.35209676e-05, + 1.52167839e-05, 1.05532167e-05, 1.58469219e-05, 2.41389797e-05, 2.81786612e-05, 3.00526539e-05, + 3.21000032e-05, 2.04198398e-05, 1.67846687e-05, 1.61406577e-05, 1.78821774e-05, 2.47147342e-05, + 3.22884810e-05, 3.39551213e-05, 3.31386861e-05, 2.15303590e-05, 1.78454736e-05, 1.80553234e-05, + 2.08119729e-05, 2.33326887e-05, 2.56757523e-05, 3.05490061e-05, 3.28985261e-05, 2.26039275e-05, + 1.77091680e-05, 1.78583208e-05, 1.95998352e-05, 2.11461249e-05, 2.52920425e-05, 3.04252588e-05, + 3.33692891e-05, 3.32284161e-05, 2.56324434e-05, 1.71823180e-05, 1.11668143e-05, 1.23758719e-05, + 1.95801050e-05, 3.06387585e-05, 3.42695467e-05, 3.03235369e-05, 1.89420090e-05, 1.53748165e-05, + 1.83502389e-05, 2.42457566e-05, 2.59258989e-05, 2.76427917e-05, 3.16524272e-05, 3.28639209e-05, + 2.58600672e-05, 1.86914449e-05, 1.47877510e-05, 1.84656467e-05, 2.37723393e-05, 2.92202699e-05, + 3.26626739e-05, 3.27573849e-05, 2.29829963e-05, 1.77387907e-05, 1.70107353e-05, 2.05242812e-05, + 2.49761531e-05, 2.86992715e-05, 3.29132625e-05, 3.17656840e-05, 2.98197331e-05, 2.32501585e-05, + 1.54110199e-05, 1.24998463e-05, 1.76168346e-05, 2.65763594e-05, 3.22022306e-05, 3.55856753e-05, + 3.59154006e-05, 3.38947570e-05, 2.07552278e-05, 1.70660040e-05, 1.67391950e-05, 2.18011650e-05, + 2.89242433e-05, 2.81697237e-05, 3.04161790e-05, 3.44361310e-05, 2.11155650e-05, 1.76862407e-05, + 1.75345769e-05, 1.87645243e-05, 2.17249085e-05, 2.85540172e-05, 3.20943057e-05, 3.08621690e-05, + 1.85389068e-05, 1.33840345e-05, 1.55712569e-05, 2.39524904e-05, 3.27070516e-05, 3.29465425e-05, + 3.16941669e-05, 2.35936176e-05, 1.83846797e-05, 1.55899189e-05, 1.69779282e-05, 2.23319879e-05, + 2.69816556e-05, 3.03655352e-05, 3.39284934e-05, 2.45419904e-05, 2.15972575e-05, 2.08464945e-05, + 2.27982087e-05, 2.53391089e-05, 2.67909919e-05, 2.72806170e-05, 2.71325631e-05, 2.68197107e-05, + 2.47568950e-05, 2.30408095e-05, 2.35281753e-05, 2.47564970e-05, 2.49543790e-05, 2.52108339e-05, + 2.66548386e-05, 2.74447460e-05, 2.70232802e-05, 2.66762990e-05, 2.69246596e-05, 2.40639592e-05, + 2.21171340e-05, 2.21272388e-05, 2.44393303e-05, 2.55881397e-05, 2.54248712e-05, 2.64039752e-05, + 2.73061188e-05, 2.75118142e-05, 2.22848464e-05, 1.83964843e-05, 1.99719570e-05, 2.55698967e-05, + 2.81002709e-05, 2.75144164e-05, 2.69621563e-05, 2.71113798e-05, 2.71728802e-05, 2.60488615e-05, + 2.25807771e-05, 2.09414460e-05, 2.41944715e-05, 2.63131586e-05, 2.56742202e-05, 2.51008533e-05, + 2.59946325e-05, 2.68763776e-05, 2.76393661e-05, 2.59222808e-05, 2.09387578e-05, 1.81655652e-05, + 2.07344862e-05, 2.48935277e-05, 2.72895284e-05, 2.74574447e-05, 2.71992393e-05, 2.23858566e-05, + 1.96804352e-05, 2.06500966e-05, 2.41440267e-05, 2.70136559e-05, 2.80034034e-05, 2.78992897e-05, + 2.73245253e-05, 2.10873113e-05, 1.89117323e-05, 2.06879007e-05, 2.44707527e-05, 2.76564311e-05, + 2.79966405e-05, 2.73423454e-05, 2.70534131e-05, 2.09970884e-05, 1.76886179e-05, 2.17983923e-05, + 2.59459667e-05, 2.64966349e-05, 2.60515279e-05, 2.64312022e-05, 2.38562893e-05, 2.23682273e-05, + 2.18302484e-05, 2.23245700e-05, 2.48949438e-05, 2.69199234e-05, 2.71596984e-05, 2.69943110e-05, + 2.43303731e-05, 2.28328887e-05, 2.28851843e-05, 2.40913796e-05, 2.46639070e-05, 2.49840745e-05, + 2.63449338e-05, 2.69541216e-05, 2.47406949e-05, 2.25267145e-05, 2.25668504e-05, 2.36287859e-05, + 2.40952368e-05, 2.51831612e-05, 2.63671857e-05, 2.70053863e-05, 2.70086550e-05, 2.68903209e-05, + 2.32287461e-05, 1.82255072e-05, 1.86677850e-05, 2.25076785e-05, 2.61353840e-05, 2.70438291e-05, + 2.59474794e-05, 2.31608773e-05, 2.15713684e-05, 2.31973170e-05, 2.56113090e-05, 2.58026422e-05, + 2.58347719e-05, 2.67453438e-05, 2.70074552e-05, 2.68805620e-05, 2.35176339e-05, 2.06813781e-05, + 2.27045171e-05, 2.49097611e-05, 2.62008455e-05, 2.67979982e-05, 2.69688631e-05, 2.47885863e-05, + 2.26018722e-05, 2.22103312e-05, 2.41383044e-05, 2.57841292e-05, 2.64358059e-05, 2.70927961e-05, + 2.66248544e-05, 2.59613258e-05, 2.52998813e-05, 2.13370533e-05, 1.89210447e-05, 2.21482623e-05, + 2.61014061e-05, 2.73770268e-05, 2.75305590e-05, 2.74450477e-05, 2.71109570e-05, 2.45899607e-05, + 2.30936952e-05, 2.24139331e-05, 2.44600380e-05, 2.62590079e-05, 2.51183256e-05, 2.56642087e-05, + 2.69296742e-05, 2.38491665e-05, 2.28604795e-05, 2.29151975e-05, 2.31754915e-05, 2.41282969e-05, + 2.64383604e-05, 2.70731268e-05, 2.64071660e-05, 2.35934909e-05, 2.05216530e-05, 2.12834643e-05, + 2.47022261e-05, 2.69829375e-05, 2.69874758e-05, 2.65986461e-05, 2.54842234e-05, 2.33685617e-05, + 2.15053238e-05, 2.19744310e-05, 2.40284581e-05, 2.53279442e-05, 2.62982198e-05, 2.72052139e-05, + 2.46270557e-05, 2.20912341e-05, 2.14145749e-05, 2.33398712e-05, 2.56415340e-05, 2.65778048e-05, + 2.67611498e-05, 2.65423532e-05, 2.61724605e-05, 2.47401792e-05, 2.33027969e-05, 2.36957353e-05, + 2.48262932e-05, 2.50077195e-05, 2.51941216e-05, 2.64485649e-05, 2.69962542e-05, 2.65085768e-05, + 2.61383026e-05, 2.62666466e-05, 2.43254610e-05, 2.26223347e-05, 2.25186424e-05, 2.46502948e-05, + 2.56640671e-05, 2.53173400e-05, 2.59408974e-05, 2.65765949e-05, 2.66934863e-05, 2.27497231e-05, + 1.91834972e-05, 2.06322795e-05, 2.58342292e-05, 2.78981779e-05, 2.69916424e-05, 2.62671084e-05, + 2.63620366e-05, 2.64220251e-05, 2.63292991e-05, 2.33313168e-05, 2.16208709e-05, 2.45613738e-05, + 2.62570913e-05, 2.54112761e-05, 2.47368322e-05, 2.54389956e-05, 2.61100317e-05, 2.73497606e-05, + 2.61587240e-05, 2.15688661e-05, 1.88507948e-05, 2.13080227e-05, 2.49957978e-05, 2.67154393e-05, + 2.65598642e-05, 2.63525715e-05, 2.27184801e-05, 2.04364210e-05, 2.13997351e-05, 2.45977727e-05, + 2.68820253e-05, 2.73471139e-05, 2.70484978e-05, 2.65398823e-05, 2.14720574e-05, 1.97219325e-05, + 2.14954105e-05, 2.48496358e-05, 2.72843664e-05, 2.71568512e-05, 2.64879203e-05, 2.63220525e-05, + 2.16427613e-05, 1.86021804e-05, 2.25885480e-05, 2.63125134e-05, 2.63217521e-05, 2.54433901e-05, + 2.56759944e-05, 2.42303901e-05, 2.31131088e-05, 2.25412227e-05, 2.27350498e-05, 2.47491844e-05, + 2.62969202e-05, 2.64110734e-05, 2.62898846e-05, 2.46301858e-05, 2.34638514e-05, 2.34788696e-05, + 2.44648546e-05, 2.47021701e-05, 2.46970725e-05, 2.57640346e-05, 2.62660679e-05, 2.49612524e-05, + 2.30679056e-05, 2.30829511e-05, 2.41160171e-05, 2.43912654e-05, 2.50347026e-05, 2.58105794e-05, + 2.62768258e-05, 2.62979815e-05, 2.73281695e-05, 2.42321243e-05, 1.91250240e-05, 1.92900041e-05, + 2.25607293e-05, 2.54745830e-05, 2.62231073e-05, 2.52689726e-05, 2.36278585e-05, 2.24156143e-05, + 2.38400254e-05, 2.58240378e-05, 2.57639782e-05, 2.55136620e-05, 2.61475646e-05, 2.63407373e-05, + 2.72688564e-05, 2.42013622e-05, 2.13312142e-05, 2.31119548e-05, 2.49511509e-05, 2.57612117e-05, + 2.60891089e-05, 2.63028898e-05, 2.49464440e-05, 2.31660193e-05, 2.28199299e-05, 2.46007406e-05, + 2.59175773e-05, 2.61562428e-05, 2.64474886e-05, 2.59733513e-05, 2.53562969e-05, 2.55994398e-05, + 2.20665162e-05, 1.96072505e-05, 2.25599232e-05, 2.60557188e-05, 2.69165197e-05, 2.67162969e-05, + 2.65695810e-05, 2.63539797e-05, 2.51813041e-05, 2.40725684e-05, 2.31926442e-05, 2.47490910e-05, + 2.58835502e-05, 2.44778522e-05, 2.48844445e-05, 2.60553184e-05, 2.40562012e-05, 2.35489761e-05, + 2.36717314e-05, 2.36956333e-05, 2.43054821e-05, 2.61825339e-05, 2.65252754e-05, 2.58040928e-05, + 2.43526550e-05, 2.15983125e-05, 2.19385265e-05, 2.46315089e-05, 2.63277282e-05, 2.63042154e-05, + 2.59479230e-05, 2.57829999e-05, 2.40745448e-05, 2.22501373e-05, 2.24949450e-05, 2.40369590e-05, + 2.49398046e-05, 2.57272340e-05, 2.64740647e-05, 2.57218316e-05, 2.92028778e-05, 2.98917014e-05, + 2.78392765e-05, 2.48051452e-05, 2.21775355e-05, 2.07047285e-05, 2.07392837e-05, 2.10754576e-05, + 2.53530099e-05, 2.76833567e-05, 2.70750531e-05, 2.54249097e-05, 2.51456959e-05, 2.47296991e-05, + 2.23921877e-05, 2.06381645e-05, 2.11270582e-05, 2.16132794e-05, 2.08725856e-05, 2.64124731e-05, + 2.86239880e-05, 2.87077479e-05, 2.59207803e-05, 2.43068374e-05, 2.43246095e-05, 2.22274124e-05, + 2.00133569e-05, 1.93478322e-05, 2.84723961e-05, 3.15668665e-05, 3.05724293e-05, 2.44843971e-05, + 2.02299728e-05, 2.03207778e-05, 2.06957761e-05, 2.02707195e-05, 2.01630078e-05, 2.38689157e-05, + 2.78796588e-05, 2.96175227e-05, 2.62612848e-05, 2.31367049e-05, 2.37335250e-05, 2.44034490e-05, + 2.26377414e-05, 2.06041079e-05, 2.07333374e-05, 2.40014012e-05, 2.97011302e-05, 3.20554787e-05, + 2.99962905e-05, 2.52655057e-05, 2.05334363e-05, 1.91339763e-05, 1.97760212e-05, 2.84450870e-05, + 3.06191275e-05, 2.97679036e-05, 2.63189406e-05, 2.20015334e-05, 1.90958041e-05, 1.85498274e-05, + 1.97901004e-05, 2.98843274e-05, 3.11068411e-05, 2.96214120e-05, 2.59222777e-05, 2.05048008e-05, + 1.84233080e-05, 1.95018325e-05, 2.04273626e-05, 2.96183496e-05, 3.16229643e-05, 2.86108440e-05, + 2.40608974e-05, 2.26815586e-05, 2.24133675e-05, 2.13745526e-05, 2.66739650e-05, 2.81035981e-05, + 2.86911010e-05, 2.84680545e-05, 2.50245298e-05, 2.09856860e-05, 2.01926171e-05, 2.06129563e-05, + 2.60848402e-05, 2.77307672e-05, 2.77039083e-05, 2.63876596e-05, 2.55254484e-05, 2.47021326e-05, + 2.20223835e-05, 2.07311069e-05, 2.55363093e-05, 2.81409049e-05, 2.81164736e-05, 2.69202900e-05, + 2.63783955e-05, 2.46135007e-05, 2.20513928e-05, 2.05161130e-05, 2.05691642e-05, 2.28914335e-05, + 2.69425451e-05, 3.13286700e-05, 3.18247629e-05, 2.83691294e-05, 2.21361747e-05, 2.01347320e-05, + 2.23864235e-05, 2.74722895e-05, 2.87434970e-05, 2.73245407e-05, 2.43941223e-05, 2.38812821e-05, + 2.33925412e-05, 2.13393939e-05, 2.07107862e-05, 2.28646489e-05, 2.69451547e-05, 2.99206444e-05, + 2.80317373e-05, 2.51959888e-05, 2.25946022e-05, 2.09209078e-05, 2.07760770e-05, 2.54409207e-05, + 2.80390424e-05, 2.84195653e-05, 2.63246889e-05, 2.40965046e-05, 2.25770930e-05, 2.06378879e-05, + 2.13775676e-05, 2.25637938e-05, 2.48540879e-05, 2.91517004e-05, 3.14390820e-05, 2.86684948e-05, + 2.34515212e-05, 2.07130714e-05, 1.93309881e-05, 1.92432702e-05, 2.02454331e-05, 2.57712373e-05, + 2.71025311e-05, 2.80167081e-05, 2.59193123e-05, 2.26469056e-05, 2.37959325e-05, 2.25467670e-05, + 2.01318762e-05, 2.66739222e-05, 2.76502787e-05, 2.75275813e-05, 2.74279801e-05, 2.63088453e-05, + 2.26192449e-05, 2.09564128e-05, 2.18637680e-05, 2.68091851e-05, 2.91757583e-05, 2.93189410e-05, + 2.53766464e-05, 2.07863554e-05, 2.06916145e-05, 2.14220963e-05, 2.46163223e-05, 2.70911833e-05, + 2.89640823e-05, 2.87653179e-05, 2.63584364e-05, 2.40218247e-05, 2.21223267e-05, 2.01760104e-05, + 2.56911777e-05, 3.14231493e-05, 3.27157520e-05, 2.93574511e-05, 2.46596863e-05, 2.08219690e-05, + 1.88516472e-05, 1.88520676e-05, 1.92151510e-05, 2.50841149e-05, 2.86983387e-05, 2.76857477e-05, + 2.52693948e-05, 2.48744268e-05, 2.42500502e-05, 2.10931021e-05, 1.88133417e-05, 1.93548867e-05, + 1.99217791e-05, 1.89699308e-05, 2.68565945e-05, 3.05204578e-05, 3.04515041e-05, 2.61046074e-05, + 2.37741156e-05, 2.36340491e-05, 2.07137671e-05, 1.79311353e-05, 1.71265303e-05, 3.02117459e-05, + 3.64728745e-05, 3.41343478e-05, 2.41863952e-05, 1.84669866e-05, 1.83985878e-05, 1.87415745e-05, + 1.82175203e-05, 1.80923272e-05, 2.33751475e-05, 2.97752649e-05, 3.25075576e-05, 2.67688975e-05, + 2.21419770e-05, 2.27400696e-05, 2.35132611e-05, 2.11516455e-05, 1.85946709e-05, 1.90174536e-05, + 2.35125005e-05, 3.25355230e-05, 3.70494842e-05, 3.29056019e-05, 2.50858042e-05, 1.86194149e-05, + 1.68472868e-05, 1.75986796e-05, 2.99486515e-05, 3.45022357e-05, 3.29404603e-05, 2.69597589e-05, + 2.06593944e-05, 1.69188394e-05, 1.62158926e-05, 1.76464365e-05, 3.23057889e-05, 3.56295068e-05, + 3.28296680e-05, 2.62994485e-05, 1.86986152e-05, 1.60801373e-05, 1.72831969e-05, 1.84087383e-05, + 3.24306692e-05, 3.72035249e-05, 3.10481325e-05, 2.37103644e-05, 2.14769356e-05, 2.08418942e-05, + 1.95036773e-05, 2.73731949e-05, 3.01254456e-05, 3.10192069e-05, 3.01125281e-05, 2.45196128e-05, + 1.91234328e-05, 1.81276842e-05, 1.86395985e-05, 2.64373066e-05, 2.93348129e-05, 2.92322296e-05, + 2.69585094e-05, 2.53736362e-05, 2.39667326e-05, 2.03867044e-05, 1.87868520e-05, 2.55807201e-05, + 2.98247343e-05, 2.97446039e-05, 2.78859451e-05, 2.68499609e-05, 2.39756810e-05, 2.04376865e-05, + 1.85133801e-05, 1.85850608e-05, 2.22139445e-05, 2.87125466e-05, 3.64684304e-05, 3.63462559e-05, + 2.94046378e-05, 2.04713989e-05, 1.80226298e-05, 2.07614799e-05, 2.86822477e-05, 3.13883438e-05, + 2.87244208e-05, 2.40160963e-05, 2.31155241e-05, 2.22616307e-05, 1.95575602e-05, 1.87751620e-05, + 2.21390079e-05, 2.82054863e-05, 3.29583472e-05, 2.94383657e-05, 2.49304206e-05, 2.11799989e-05, + 1.89972808e-05, 1.88520845e-05, 2.53827218e-05, 2.97044774e-05, 3.03845551e-05, 2.69790751e-05, + 2.35470161e-05, 2.12713505e-05, 1.87019031e-05, 1.95702522e-05, 2.10269911e-05, 2.47237899e-05, + 3.18280481e-05, 3.58294358e-05, 3.04254792e-05, 2.25537645e-05, 1.88951326e-05, 1.71094474e-05, + 1.69807940e-05, 1.81841922e-05, 2.63364422e-05, 2.89282717e-05, 3.00474899e-05, 2.61911852e-05, + 2.12898624e-05, 2.25182486e-05, 2.08860741e-05, 1.79909074e-05, 2.71621814e-05, 2.93043507e-05, + 2.92253450e-05, 2.86948251e-05, 2.66096242e-05, 2.13407280e-05, 1.91327482e-05, 2.01812880e-05, + 2.81102734e-05, 3.27592270e-05, 3.19462213e-05, 2.50618751e-05, 1.88702849e-05, 1.87433693e-05, + 1.96236163e-05, 2.43985078e-05, 2.84631116e-05, 3.15447533e-05, 3.07724432e-05, 2.64844092e-05, + 2.30052204e-05, 2.05140180e-05, 1.81178439e-05, 2.54681748e-05, 2.52143202e-05, 2.50202027e-05, + 2.46233225e-05, 2.42672084e-05, 2.43703805e-05, 2.42463246e-05, 2.44833330e-05, 2.49144588e-05, + 2.56373920e-05, 2.56927836e-05, 2.58074185e-05, 2.53698908e-05, 2.52807220e-05, 2.52951819e-05, + 2.44902465e-05, 2.39895086e-05, 2.45461069e-05, 2.49754614e-05, 2.47921890e-05, 2.51575550e-05, + 2.50079570e-05, 2.55243185e-05, 2.51154021e-05, 2.47516470e-05, 2.53715771e-05, 2.51799450e-05, + 2.43342111e-05, 2.40542208e-05, 2.51358722e-05, 2.38617186e-05, 2.46418162e-05, 2.42324350e-05, + 2.30107824e-05, 2.39668399e-05, 2.47694022e-05, 2.46001182e-05, 2.45184417e-05, 2.38661768e-05, + 2.37845368e-05, 2.44345470e-05, 2.47080624e-05, 2.44963915e-05, 2.55335921e-05, 2.63084399e-05, + 2.57739134e-05, 2.49187433e-05, 2.36057633e-05, 2.40726870e-05, 2.46859204e-05, 2.44752030e-05, + 2.50123101e-05, 2.51738354e-05, 2.42784582e-05, 2.41087405e-05, 2.44942685e-05, 2.56878333e-05, + 2.41201909e-05, 2.41081280e-05, 2.44185124e-05, 2.40123375e-05, 2.33853563e-05, 2.34754843e-05, + 2.43185423e-05, 2.59002199e-05, 2.37761372e-05, 2.38063331e-05, 2.45205059e-05, 2.36737295e-05, + 2.33365037e-05, 2.42897747e-05, 2.46698578e-05, 2.45972248e-05, 2.29343344e-05, 2.37629357e-05, + 2.36965824e-05, 2.45809230e-05, 2.57875250e-05, 2.54899956e-05, 2.48527529e-05, 2.38588509e-05, + 2.41279528e-05, 2.53654853e-05, 2.59112387e-05, 2.47707867e-05, 2.45354097e-05, 2.47334905e-05, + 2.48727246e-05, 2.42312749e-05, 2.43729549e-05, 2.47372778e-05, 2.55339123e-05, 2.62212528e-05, + 2.54119292e-05, 2.47753663e-05, 2.48981291e-05, 2.47162540e-05, 2.48127811e-05, 2.45250183e-05, + 2.50159123e-05, 2.56811396e-05, 2.53544036e-05, 2.47315483e-05, 2.47183199e-05, 2.28903904e-05, + 2.25789814e-05, 2.31412556e-05, 2.49008702e-05, 2.68457109e-05, 2.57589557e-05, 2.47094941e-05, + 2.60050722e-05, 2.48000216e-05, 2.35400819e-05, 2.40660688e-05, 2.43530986e-05, 2.48841607e-05, + 2.55085766e-05, 2.49596988e-05, 2.46939216e-05, 2.30179415e-05, 2.37940213e-05, 2.46232362e-05, + 2.52325726e-05, 2.53489680e-05, 2.53611172e-05, 2.49881172e-05, 2.47422129e-05, 2.50696894e-05, + 2.45916256e-05, 2.45056060e-05, 2.43894664e-05, 2.44503803e-05, 2.48386193e-05, 2.45721628e-05, + 2.51579484e-05, 2.58865928e-05, 2.43004331e-05, 2.41263422e-05, 2.45167459e-05, 2.54244011e-05, + 2.46531096e-05, 2.40796262e-05, 2.40282745e-05, 2.41355937e-05, 2.46031854e-05, 2.37196304e-05, + 2.27051485e-05, 2.36985747e-05, 2.48366696e-05, 2.51897128e-05, 2.68958023e-05, 2.64768213e-05, + 2.48741837e-05, 2.54769233e-05, 2.39783489e-05, 2.36751134e-05, 2.45765624e-05, 2.54204360e-05, + 2.47921103e-05, 2.45194361e-05, 2.53670196e-05, 2.34706340e-05, 2.24315990e-05, 2.45008568e-05, + 2.58427429e-05, 2.47170617e-05, 2.47298307e-05, 2.51892382e-05, 2.41866486e-05, 2.37533086e-05, + 2.40255263e-05, 2.49807033e-05, 2.60724717e-05, 2.61472795e-05, 2.54526810e-05, 2.44691916e-05, + 2.53675599e-05, 2.50078080e-05, 2.47857561e-05, 2.47709187e-05, 2.46834660e-05, 2.45957498e-05, + 2.43377928e-05, 2.44542242e-05, 2.47092970e-05, 2.54566068e-05, 2.54422803e-05, 2.55381338e-05, + 2.53109537e-05, 2.52577016e-05, 2.52548474e-05, 2.46785561e-05, 2.42054207e-05, 2.45459584e-05, + 2.48209381e-05, 2.46191256e-05, 2.51813687e-05, 2.49402834e-05, 2.52597528e-05, 2.51670012e-05, + 2.49451335e-05, 2.52787881e-05, 2.50008603e-05, 2.42537855e-05, 2.39910031e-05, 2.50375971e-05, + 2.36191377e-05, 2.44101547e-05, 2.46601167e-05, 2.36653172e-05, 2.41420656e-05, 2.45778951e-05, + 2.44229315e-05, 2.43655572e-05, 2.44385521e-05, 2.42183206e-05, 2.44276098e-05, 2.49208091e-05, + 2.47457306e-05, 2.53257326e-05, 2.57646050e-05, 2.53351374e-05, 2.46284025e-05, 2.40339497e-05, + 2.45588594e-05, 2.45874588e-05, 2.39691835e-05, 2.47645200e-05, 2.52003679e-05, 2.43241153e-05, + 2.39663241e-05, 2.42760697e-05, 2.53850395e-05, 2.40253627e-05, 2.41747164e-05, 2.47443534e-05, + 2.43950490e-05, 2.36385635e-05, 2.35543197e-05, 2.42017747e-05, 2.53665345e-05, 2.36630738e-05, + 2.39848412e-05, 2.48195382e-05, 2.40327432e-05, 2.34632432e-05, 2.41277263e-05, 2.44839305e-05, + 2.45393694e-05, 2.28651305e-05, 2.41118599e-05, 2.43461653e-05, 2.47524808e-05, 2.53128548e-05, + 2.50206525e-05, 2.49911970e-05, 2.42424077e-05, 2.43508739e-05, 2.51828768e-05, 2.55937843e-05, + 2.46283108e-05, 2.43789026e-05, 2.45467701e-05, 2.50232492e-05, 2.45286344e-05, 2.46227553e-05, + 2.49337249e-05, 2.54026343e-05, 2.57393435e-05, 2.50840528e-05, 2.45868684e-05, 2.50457892e-05, + 2.48021457e-05, 2.48662612e-05, 2.47783660e-05, 2.50993218e-05, 2.54554931e-05, 2.50610030e-05, + 2.45281849e-05, 2.45319637e-05, 2.38486077e-05, 2.35015226e-05, 2.31126219e-05, 2.43413978e-05, + 2.60788386e-05, 2.52614167e-05, 2.44446519e-05, 2.54100591e-05, 2.49120740e-05, 2.39374356e-05, + 2.44586433e-05, 2.47266221e-05, 2.49976733e-05, 2.52853891e-05, 2.47725290e-05, 2.45462074e-05, + 2.39204742e-05, 2.43145493e-05, 2.45099273e-05, 2.51378704e-05, 2.52961159e-05, 2.51322530e-05, + 2.47166565e-05, 2.45796476e-05, 2.51433021e-05, 2.47319333e-05, 2.46360944e-05, 2.47264406e-05, + 2.47722428e-05, 2.48728584e-05, 2.44777548e-05, 2.48701856e-05, 2.53788486e-05, 2.47028351e-05, + 2.42854297e-05, 2.41441691e-05, 2.52007941e-05, 2.48497791e-05, 2.42602536e-05, 2.39759199e-05, + 2.40030301e-05, 2.44194205e-05, 2.43390565e-05, 2.35708621e-05, 2.41444930e-05, 2.50057434e-05, + 2.50543970e-05, 2.59958408e-05, 2.56474532e-05, 2.45160994e-05, 2.53597186e-05, 2.43712707e-05, + 2.41832092e-05, 2.47755432e-05, 2.53359294e-05, 2.48537433e-05, 2.45066875e-05, 2.50406294e-05, + 2.41154144e-05, 2.30496428e-05, 2.45178035e-05, 2.55680945e-05, 2.45699305e-05, 2.45591855e-05, + 2.48916301e-05, 2.46357001e-05, 2.42760039e-05, 2.42432100e-05, 2.49072163e-05, 2.57025029e-05, + 2.56559800e-05, 2.51168985e-05, 2.43460311e-05, 2.52831953e-05, 3.01987222e-05, 3.12481757e-05, + 2.96743097e-05, 2.60638147e-05, 2.15895041e-05, 1.92647373e-05, 1.89494111e-05, 1.88510573e-05, + 2.44562202e-05, 2.75623514e-05, 2.65734322e-05, 2.50210837e-05, 2.47625660e-05, 2.41116327e-05, + 2.17477850e-05, 1.95629010e-05, 1.95136580e-05, 1.96539839e-05, 1.86974992e-05, 2.68113700e-05, + 2.99166802e-05, 2.91009368e-05, 2.61897012e-05, 2.44072132e-05, 2.33625770e-05, 2.03431752e-05, + 1.79275505e-05, 1.71884340e-05, 2.95115108e-05, 3.45072039e-05, 3.25183777e-05, 2.56261307e-05, + 2.04776410e-05, 1.90398953e-05, 1.84336119e-05, 1.79675673e-05, 1.79063801e-05, 2.53184114e-05, + 3.13017666e-05, 3.20101830e-05, 2.74125799e-05, 2.29746180e-05, 2.21778878e-05, 2.19528416e-05, + 2.00746128e-05, 1.80540510e-05, 2.03706869e-05, 2.51495398e-05, 3.16463499e-05, 3.38104911e-05, + 3.13630593e-05, 2.51275183e-05, 1.89162758e-05, 1.67323593e-05, 1.72780590e-05, 2.85083755e-05, + 3.34471660e-05, 3.27378804e-05, 2.80307464e-05, 2.19038847e-05, 1.77640014e-05, 1.66327875e-05, + 1.75641477e-05, 2.97367547e-05, 3.43730946e-05, 3.31445913e-05, 2.72724980e-05, 1.98467660e-05, + 1.66121352e-05, 1.71068295e-05, 1.81293118e-05, 3.17214529e-05, 3.59827322e-05, 3.21922208e-05, + 2.59528599e-05, 2.20765266e-05, 1.96986443e-05, 1.84771910e-05, 2.77237448e-05, 3.14288596e-05, + 3.15979800e-05, 2.90993137e-05, 2.35143521e-05, 1.89213751e-05, 1.79315468e-05, 1.83480135e-05, + 2.68610617e-05, 3.02689899e-05, 2.99696217e-05, 2.75371665e-05, 2.48849208e-05, 2.25340216e-05, + 1.96467693e-05, 1.84842630e-05, 2.60182452e-05, 2.98737007e-05, 2.96681018e-05, 2.86633521e-05, + 2.70177389e-05, 2.32833637e-05, 1.97827615e-05, 1.81867923e-05, 1.82968002e-05, 2.55381438e-05, + 3.25180613e-05, 3.55320797e-05, 3.30134675e-05, 2.64697583e-05, 1.93013674e-05, 1.75725569e-05, + 1.93287300e-05, 2.88846098e-05, 3.27576979e-05, 3.00641813e-05, 2.52617393e-05, 2.35039271e-05, + 2.16847568e-05, 1.92225138e-05, 1.85743616e-05, 2.52409379e-05, 3.00863812e-05, 3.19687893e-05, + 2.88086129e-05, 2.47191583e-05, 2.06509015e-05, 1.84803776e-05, 1.86110027e-05, 2.55711885e-05, + 2.99787060e-05, 3.05907579e-05, 2.80932557e-05, 2.46126803e-05, 2.14706973e-05, 1.86376154e-05, + 1.89811050e-05, 1.97858353e-05, 2.60780617e-05, 3.20963475e-05, 3.33776181e-05, 2.92302694e-05, + 2.32158517e-05, 1.95478039e-05, 1.71976954e-05, 1.68840795e-05, 1.79197557e-05, 2.85739606e-05, + 3.24667557e-05, 3.16319125e-05, 2.66885382e-05, 2.10099628e-05, 2.01565214e-05, 1.88858601e-05, + 1.73259151e-05, 2.66074513e-05, 3.06474443e-05, 3.10763915e-05, 2.92388110e-05, 2.62014173e-05, + 2.16175114e-05, 1.92645328e-05, 1.94582547e-05, 3.05364328e-05, 3.52919546e-05, 3.15900529e-05, + 2.41441524e-05, 1.86670158e-05, 1.84868902e-05, 1.90068567e-05, 2.59186979e-05, 3.03600694e-05, + 3.20846399e-05, 3.01271656e-05, 2.51512678e-05, 2.16346845e-05, 1.97456574e-05, 1.80032662e-05, + 2.50793549e-05, 2.46667511e-05, 2.44188081e-05, 2.54345004e-05, 2.59869808e-05, 2.50838304e-05, + 2.43081319e-05, 2.40546436e-05, 2.37996865e-05, 2.48969529e-05, 2.48434007e-05, 2.48361810e-05, + 2.51298150e-05, 2.51678052e-05, 2.50814785e-05, 2.50624627e-05, 2.45637949e-05, 2.42586378e-05, + 2.40946592e-05, 2.37930799e-05, 2.53326818e-05, 2.49822734e-05, 2.46995212e-05, 2.53684742e-05, + 2.54792809e-05, 2.49155803e-05, 2.42387869e-05, 2.36557498e-05, 2.34072428e-05, 2.49707948e-05, + 2.33929912e-05, 2.41149699e-05, 2.59772006e-05, 2.54513689e-05, 2.43517673e-05, 2.36866328e-05, + 2.35497651e-05, 2.35586242e-05, 2.62001970e-05, 2.58426883e-05, 2.47513735e-05, 2.56660345e-05, + 2.53765749e-05, 2.45739037e-05, 2.40737611e-05, 2.38359892e-05, 2.34407305e-05, 2.50877703e-05, + 2.60363302e-05, 2.46276417e-05, 2.29849354e-05, 2.43658300e-05, 2.52740254e-05, 2.41418428e-05, + 2.31333105e-05, 2.32537556e-05, 2.46877616e-05, 2.41660220e-05, 2.47508889e-05, 2.58667209e-05, + 2.53829554e-05, 2.40227228e-05, 2.33601261e-05, 2.34816997e-05, 2.40990909e-05, 2.37974235e-05, + 2.49153412e-05, 2.58208193e-05, 2.48443796e-05, 2.34106091e-05, 2.32564369e-05, 2.35937531e-05, + 2.47005607e-05, 2.32053608e-05, 2.55158600e-05, 2.63905168e-05, 2.51024884e-05, 2.36973957e-05, + 2.33603202e-05, 2.55285945e-05, 2.57157900e-05, 2.53384271e-05, 2.48539810e-05, 2.46017030e-05, + 2.39004076e-05, 2.35628528e-05, 2.36649309e-05, 2.55529896e-05, 2.56766588e-05, 2.56101159e-05, + 2.56359880e-05, 2.50060971e-05, 2.42452461e-05, 2.38693998e-05, 2.37066016e-05, 2.55240799e-05, + 2.52918343e-05, 2.52496895e-05, 2.57104480e-05, 2.54369629e-05, 2.47092079e-05, 2.39490759e-05, + 2.35913774e-05, 2.36486752e-05, 2.69100036e-05, 2.67968149e-05, 2.35480654e-05, 2.31730323e-05, + 2.40257550e-05, 2.35644987e-05, 2.33052125e-05, 2.34523429e-05, 2.54295412e-05, 2.55206883e-05, + 2.58912895e-05, 2.58558906e-05, 2.52461430e-05, 2.44654072e-05, 2.39321001e-05, 2.37863954e-05, + 2.67749897e-05, 2.61524433e-05, 2.45236049e-05, 2.50457935e-05, 2.51172699e-05, 2.42445209e-05, + 2.36023684e-05, 2.37792666e-05, 2.53783558e-05, 2.53890509e-05, 2.52946824e-05, 2.58863770e-05, + 2.57084922e-05, 2.47839633e-05, 2.38738793e-05, 2.37346620e-05, 2.36779808e-05, 2.59637025e-05, + 2.51052145e-05, 2.35003451e-05, 2.47624022e-05, 2.53330693e-05, 2.45112304e-05, 2.34240589e-05, + 2.32053338e-05, 2.35252697e-05, 2.64186337e-05, 2.66687182e-05, 2.58237438e-05, 2.55823915e-05, + 2.44504448e-05, 2.32809487e-05, 2.30529875e-05, 2.31055856e-05, 2.50911624e-05, 2.58344846e-05, + 2.60315928e-05, 2.55717363e-05, 2.51408686e-05, 2.48529731e-05, 2.41702724e-05, 2.38208417e-05, + 2.63775137e-05, 2.54652730e-05, 2.48904383e-05, 2.47275647e-05, 2.38162996e-05, 2.37297626e-05, + 2.37298760e-05, 2.60349004e-05, 2.61347040e-05, 2.52392525e-05, 2.49430132e-05, 2.46478115e-05, + 2.40912616e-05, 2.38851622e-05, 2.36287550e-05, 2.45830112e-05, 2.18957611e-05, 2.11907065e-05, + 2.31794552e-05, 2.56098702e-05, 2.66885346e-05, 2.69503566e-05, 2.67335036e-05, 2.63524725e-05, + 2.47177631e-05, 2.31783463e-05, 2.35998071e-05, 2.47937441e-05, 2.49862978e-05, 2.51933621e-05, + 2.65502041e-05, 2.71847933e-05, 2.66798749e-05, 2.62910802e-05, 2.64554504e-05, 2.42413866e-05, + 2.24422545e-05, 2.23494978e-05, 2.45876747e-05, 2.56708220e-05, 2.53384773e-05, 2.60652216e-05, + 2.68044830e-05, 2.69534163e-05, 2.25789032e-05, 1.88853956e-05, 2.03779621e-05, 2.58180003e-05, + 2.80920783e-05, 2.71974640e-05, 2.64648718e-05, 2.65797955e-05, 2.66443836e-05, 2.63352620e-05, + 2.31445110e-05, 2.13901073e-05, 2.44717107e-05, 2.63187407e-05, 2.54656503e-05, 2.47749399e-05, + 2.55532032e-05, 2.63146462e-05, 2.75258652e-05, 2.61633402e-05, 2.13422180e-05, 1.85562602e-05, + 2.10806149e-05, 2.49658426e-05, 2.69145108e-05, 2.68316044e-05, 2.65948994e-05, 2.25636522e-05, + 2.01674710e-05, 2.11552492e-05, 2.44971383e-05, 2.69946178e-05, 2.76129418e-05, 2.73452358e-05, + 2.67794230e-05, 2.12713015e-05, 1.94320966e-05, 2.12471938e-05, 2.47704349e-05, 2.74748313e-05, + 2.74591500e-05, 2.67422909e-05, 2.65325170e-05, 2.14164084e-05, 1.82824002e-05, 2.23733035e-05, + 2.63033608e-05, 2.64097722e-05, 2.55690687e-05, 2.58492117e-05, 2.41261215e-05, 2.29197557e-05, + 2.23337256e-05, 2.25706785e-05, 2.47489325e-05, 2.64794304e-05, 2.66320927e-05, 2.64914848e-05, + 2.45532951e-05, 2.32963986e-05, 2.33166807e-05, 2.43702317e-05, 2.46690222e-05, 2.47191215e-05, + 2.59030825e-05, 2.64620623e-05, 2.49109521e-05, 2.28981464e-05, 2.29168908e-05, 2.39914700e-05, + 2.43048534e-05, 2.50488741e-05, 2.59471479e-05, 2.64834790e-05, 2.65016681e-05, 2.73605642e-05, + 2.40457689e-05, 1.88153820e-05, 1.90099796e-05, 2.24383399e-05, 2.56136543e-05, 2.64493429e-05, + 2.53996125e-05, 2.34875852e-05, 2.21890399e-05, 2.36844833e-05, 2.58157804e-05, 2.57958774e-05, + 2.55846802e-05, 2.63144595e-05, 2.65366113e-05, 2.73065482e-05, 2.40538544e-05, 2.10958717e-05, + 2.29609678e-05, 2.49290320e-05, 2.58699733e-05, 2.62782780e-05, 2.64960316e-05, 2.49053174e-05, + 2.29967079e-05, 2.26334036e-05, 2.44989945e-05, 2.59273469e-05, 2.62554242e-05, 2.66454250e-05, + 2.61414218e-05, 2.54761709e-05, 2.55662321e-05, 2.18427117e-05, 1.93272729e-05, 2.23895610e-05, + 2.61044143e-05, 2.71024510e-05, 2.69768376e-05, 2.68358751e-05, 2.65731067e-05, 2.50855431e-05, + 2.38835632e-05, 2.29978429e-05, 2.46789289e-05, 2.59862591e-05, 2.45559137e-05, 2.50147103e-05, + 2.62836428e-05, 2.39690306e-05, 2.33772597e-05, 2.34958262e-05, 2.35507995e-05, 2.42331553e-05, + 2.62784927e-05, 2.67053209e-05, 2.59505077e-05, 2.42010541e-05, 2.13247150e-05, 2.17195135e-05, + 2.46129831e-05, 2.65199528e-05, 2.65016260e-05, 2.61141836e-05, 2.57587040e-05, 2.39194436e-05, + 2.20299491e-05, 2.23088618e-05, 2.39790984e-05, 2.49929118e-05, 2.58618724e-05, 2.66950892e-05, + 2.49628727e-05, 2.43081689e-05, 2.40050127e-05, 2.53869454e-05, 2.62992516e-05, 2.53629733e-05, + 2.45433302e-05, 2.41982830e-05, 2.38049588e-05, 2.47428248e-05, 2.45346283e-05, 2.45446422e-05, + 2.50557651e-05, 2.51316989e-05, 2.50519459e-05, 2.53036436e-05, 2.48984264e-05, 2.44086722e-05, + 2.41147004e-05, 2.38283633e-05, 2.52699974e-05, 2.47443816e-05, 2.43305521e-05, 2.53492053e-05, + 2.56401375e-05, 2.48671561e-05, 2.42176243e-05, 2.37889947e-05, 2.35770432e-05, 2.47207680e-05, + 2.28706086e-05, 2.36633053e-05, 2.63143030e-05, 2.61776007e-05, 2.46666853e-05, 2.37155974e-05, + 2.36044047e-05, 2.36343659e-05, 2.66883339e-05, 2.60066126e-05, 2.44977439e-05, 2.57479394e-05, + 2.56331113e-05, 2.44716383e-05, 2.37275714e-05, 2.36259314e-05, 2.34050370e-05, 2.55928355e-05, + 2.64449319e-05, 2.43098310e-05, 2.22866933e-05, 2.39379854e-05, 2.52676243e-05, 2.43489223e-05, + 2.32531174e-05, 2.32974386e-05, 2.43082962e-05, 2.37946937e-05, 2.45368182e-05, 2.60316912e-05, + 2.57963169e-05, 2.44465028e-05, 2.36651115e-05, 2.35967544e-05, 2.35092345e-05, 2.33824041e-05, + 2.47863362e-05, 2.59852109e-05, 2.53006461e-05, 2.37573898e-05, 2.33493557e-05, 2.36365235e-05, + 2.44136746e-05, 2.27764788e-05, 2.55717591e-05, 2.69365636e-05, 2.53184494e-05, 2.34731677e-05, + 2.31785478e-05, 2.55350178e-05, 2.58279223e-05, 2.52972231e-05, 2.45493260e-05, 2.43718366e-05, + 2.39529821e-05, 2.36349464e-05, 2.37003102e-05, 2.55975099e-05, 2.57447148e-05, 2.56442380e-05, + 2.56994133e-05, 2.48776672e-05, 2.39248229e-05, 2.37553666e-05, 2.37363572e-05, 2.55930496e-05, + 2.51843923e-05, 2.51210215e-05, 2.57890643e-05, 2.54183276e-05, 2.45575385e-05, 2.38569141e-05, + 2.36187013e-05, 2.36859275e-05, 2.78027821e-05, 2.74332162e-05, 2.31667743e-05, 2.24614261e-05, + 2.33788189e-05, 2.33363836e-05, 2.33038625e-05, 2.31542367e-05, 2.53760604e-05, 2.56048611e-05, + 2.60545255e-05, 2.61534334e-05, 2.53659594e-05, 2.43669311e-05, 2.39398696e-05, 2.38455976e-05, + 2.76144377e-05, 2.64385379e-05, 2.41835675e-05, 2.48210797e-05, 2.50579188e-05, 2.41745766e-05, + 2.35678608e-05, 2.38255421e-05, 2.53976606e-05, 2.53254883e-05, 2.52032244e-05, 2.60596763e-05, + 2.59787630e-05, 2.49010274e-05, 2.39738710e-05, 2.36720400e-05, 2.34271395e-05, 2.62623833e-05, + 2.49916139e-05, 2.29137068e-05, 2.44212270e-05, 2.55348485e-05, 2.48150626e-05, 2.36024514e-05, + 2.33284133e-05, 2.35762044e-05, 2.68510057e-05, 2.72429721e-05, 2.59891225e-05, 2.56487037e-05, + 2.44429234e-05, 2.27514320e-05, 2.26103865e-05, 2.30412992e-05, 2.49186943e-05, 2.59798072e-05, + 2.62746941e-05, 2.55833453e-05, 2.50079781e-05, 2.49885457e-05, 2.43176233e-05, 2.37138835e-05, + 2.67746316e-05, 2.56915752e-05, 2.46700922e-05, 2.45101715e-05, 2.38730868e-05, 2.37735018e-05, + 2.36589417e-05, 2.63831180e-05, 2.64144122e-05, 2.51781640e-05, 2.46936674e-05, 2.43254493e-05, + 2.37930291e-05, 2.37620377e-05, 2.37252160e-05, 2.55518519e-05, 2.72713868e-05, 2.75189287e-05, + 2.67114565e-05, 2.51460227e-05, 2.33691304e-05, 2.22527963e-05, 2.22313325e-05, 2.24126611e-05, + 2.53107091e-05, 2.65862474e-05, 2.62686920e-05, 2.53878188e-05, 2.52302304e-05, 2.49700004e-05, + 2.35054352e-05, 2.22519608e-05, 2.25299989e-05, 2.28258664e-05, 2.22744858e-05, 2.59733865e-05, + 2.70406395e-05, 2.70645615e-05, 2.57052309e-05, 2.47760177e-05, 2.46986748e-05, 2.32562077e-05, + 2.16614223e-05, 2.11520279e-05, 2.69742970e-05, 2.78339626e-05, 2.77083077e-05, 2.49547365e-05, + 2.21197812e-05, 2.19976477e-05, 2.21350663e-05, 2.18194449e-05, 2.17469780e-05, 2.46138478e-05, + 2.67402932e-05, 2.74034276e-05, 2.59308535e-05, 2.40343006e-05, 2.42770184e-05, 2.46039218e-05, + 2.34497410e-05, 2.20272588e-05, 2.24056715e-05, 2.46717061e-05, 2.74422640e-05, 2.80197793e-05, + 2.75537561e-05, 2.53161425e-05, 2.21065378e-05, 2.09510861e-05, 2.14229386e-05, 2.69436284e-05, + 2.76715838e-05, 2.74327190e-05, 2.59839939e-05, 2.33029127e-05, 2.10841213e-05, 2.05769936e-05, + 2.14748013e-05, 2.75305212e-05, 2.77359519e-05, 2.73661543e-05, 2.57629256e-05, 2.22086721e-05, + 2.04951852e-05, 2.12322944e-05, 2.19349336e-05, 2.74107676e-05, 2.76482626e-05, 2.70249644e-05, + 2.47563512e-05, 2.36991581e-05, 2.32787940e-05, 2.25314702e-05, 2.61370809e-05, 2.68319295e-05, + 2.70647225e-05, 2.69659221e-05, 2.50695759e-05, 2.23704737e-05, 2.17681434e-05, 2.20747246e-05, + 2.58205482e-05, 2.66730634e-05, 2.66580052e-05, 2.59958691e-05, 2.54277922e-05, 2.48157993e-05, + 2.30551692e-05, 2.21627356e-05, 2.55079063e-05, 2.68415022e-05, 2.68285835e-05, 2.62834208e-05, + 2.59675801e-05, 2.48404364e-05, 2.30887673e-05, 2.19951594e-05, 2.20418931e-05, 2.41037965e-05, + 2.63394285e-05, 2.76588654e-05, 2.80391812e-05, 2.68374365e-05, 2.30732490e-05, 2.16806206e-05, + 2.32153136e-05, 2.65360303e-05, 2.70632918e-05, 2.64953679e-05, 2.48837474e-05, 2.44794547e-05, + 2.40443804e-05, 2.26139269e-05, 2.21635090e-05, 2.40687348e-05, 2.63283110e-05, 2.75115960e-05, + 2.67763331e-05, 2.52521983e-05, 2.34958181e-05, 2.22721266e-05, 2.22065543e-05, 2.54329495e-05, + 2.68001011e-05, 2.69612976e-05, 2.59891089e-05, 2.46823070e-05, 2.35784003e-05, 2.21297884e-05, + 2.26033353e-05, 2.33726993e-05, 2.51716491e-05, 2.72316391e-05, 2.79089500e-05, 2.70506106e-05, + 2.42257638e-05, 2.22939404e-05, 2.11432562e-05, 2.10414146e-05, 2.17975609e-05, 2.57444677e-05, + 2.64083597e-05, 2.67954437e-05, 2.57321868e-05, 2.35659436e-05, 2.40811921e-05, 2.32424977e-05, + 2.16411987e-05, 2.60853466e-05, 2.66421420e-05, 2.65922352e-05, 2.65251770e-05, 2.58916135e-05, + 2.36173205e-05, 2.23991825e-05, 2.29418803e-05, 2.62743588e-05, 2.71003266e-05, 2.73037499e-05, + 2.52981085e-05, 2.22202778e-05, 2.21401359e-05, 2.26321774e-05, 2.50410397e-05, 2.63971627e-05, + 2.71617364e-05, 2.70988841e-05, 2.58497410e-05, 2.43720065e-05, 2.31235983e-05, 2.17687802e-05, + 2.56832797e-05, 2.76271616e-05, 2.79346533e-05, 2.66073909e-05, 2.46787997e-05, 2.30846440e-05, + 2.20900443e-05, 2.21911972e-05, 2.25546455e-05, 2.55209424e-05, 2.69404195e-05, 2.66246927e-05, + 2.54662714e-05, 2.52629488e-05, 2.50129030e-05, 2.32629882e-05, 2.19609610e-05, 2.24663401e-05, + 2.29270983e-05, 2.23807338e-05, 2.59814233e-05, 2.72131731e-05, 2.74698588e-05, 2.56710849e-05, + 2.45542404e-05, 2.47897741e-05, 2.33943178e-05, 2.16615489e-05, 2.11256011e-05, 2.71781500e-05, + 2.83421258e-05, 2.81505507e-05, 2.44712796e-05, 2.13658078e-05, 2.17451501e-05, 2.22564337e-05, + 2.19191304e-05, 2.18209203e-05, 2.39599454e-05, 2.62878783e-05, 2.75349746e-05, 2.57187974e-05, + 2.37353316e-05, 2.44772679e-05, 2.51716055e-05, 2.38605409e-05, 2.22442559e-05, 2.18939429e-05, + 2.41173551e-05, 2.76877489e-05, 2.88779764e-05, 2.79897291e-05, 2.52965463e-05, 2.19880632e-05, + 2.09984180e-05, 2.15540874e-05, 2.73833431e-05, 2.79492088e-05, 2.74788601e-05, 2.56405735e-05, + 2.28480936e-05, 2.07420065e-05, 2.04024336e-05, 2.15072670e-05, 2.82948791e-05, 2.80589666e-05, + 2.72683071e-05, 2.54451537e-05, 2.17681859e-05, 2.02726963e-05, 2.13043645e-05, 2.20459714e-05, + 2.76042172e-05, 2.79453833e-05, 2.66901692e-05, 2.40138031e-05, 2.34783289e-05, 2.37197248e-05, + 2.29408642e-05, 2.60190042e-05, 2.64453533e-05, 2.68884040e-05, 2.72680158e-05, 2.54182715e-05, + 2.24481946e-05, 2.18461471e-05, 2.21898560e-05, 2.56770772e-05, 2.63863430e-05, 2.64284211e-05, + 2.58049805e-05, 2.55882212e-05, 2.53284572e-05, 2.33396288e-05, 2.22817618e-05, 2.53576492e-05, + 2.68182361e-05, 2.68432524e-05, 2.60352705e-05, 2.59068550e-05, 2.50805034e-05, 2.33391999e-05, + 2.21249821e-05, 2.21558788e-05, 2.30003965e-05, 2.52564958e-05, 2.78878332e-05, 2.89439216e-05, + 2.77908585e-05, 2.35296726e-05, 2.18636105e-05, 2.37749250e-05, 2.64658492e-05, 2.66695454e-05, + 2.60862001e-05, 2.44611218e-05, 2.43389453e-05, 2.42528822e-05, 2.27429154e-05, 2.22416584e-05, + 2.30311155e-05, 2.57578351e-05, 2.77832561e-05, 2.69626330e-05, 2.53188350e-05, 2.36925228e-05, + 2.24768858e-05, 2.23006260e-05, 2.53643315e-05, 2.67093170e-05, 2.68914176e-05, 2.56326322e-05, + 2.43146278e-05, 2.35016580e-05, 2.21535697e-05, 2.28336213e-05, 2.38506306e-05, 2.47208797e-05, + 2.71453656e-05, 2.85667386e-05, 2.74071139e-05, 2.39882300e-05, 2.20400312e-05, 2.11059867e-05, + 2.10808819e-05, 2.19032748e-05, 2.50447774e-05, 2.53994716e-05, 2.63296667e-05, 2.55644151e-05, + 2.36673737e-05, 2.49873666e-05, 2.40362737e-05, 2.19144777e-05, 2.62593746e-05, 2.62371728e-05, + 2.60428682e-05, 2.63511095e-05, 2.60195138e-05, 2.35123818e-05, 2.23457718e-05, 2.32212709e-05, + 2.55486293e-05, 2.64224547e-05, 2.73965215e-05, 2.56105827e-05, 2.22991595e-05, 2.22407401e-05, + 2.28731999e-05, 2.45342576e-05, 2.58253671e-05, 2.69981829e-05, 2.72827105e-05, 2.62942578e-05, + 2.48741843e-05, 2.34182832e-05, 2.18136444e-05, 2.57338594e-05, 3.00786754e-05, 3.09935521e-05, + 2.84302268e-05, 2.47452636e-05, 2.16475691e-05, 1.99765003e-05, 2.00021276e-05, 2.03573110e-05, + 2.52759411e-05, 2.81068953e-05, 2.73446327e-05, 2.53860016e-05, 2.50596061e-05, 2.45625454e-05, + 2.18868320e-05, 1.99161675e-05, 2.04365633e-05, 2.09631218e-05, 2.01352895e-05, 2.66018212e-05, + 2.93700841e-05, 2.94084402e-05, 2.60080956e-05, 2.41069522e-05, 2.40765982e-05, 2.16516411e-05, + 1.91962388e-05, 1.84704854e-05, 2.91613936e-05, 3.34265116e-05, 3.19452421e-05, 2.43645057e-05, + 1.95138481e-05, 1.95599782e-05, 1.99376249e-05, 1.94701078e-05, 1.93539243e-05, 2.36649908e-05, + 2.85941538e-05, 3.07286952e-05, 2.64646060e-05, 2.27507926e-05, 2.33701379e-05, 2.40976094e-05, + 2.20850803e-05, 1.98269364e-05, 2.00468709e-05, 2.38038177e-05, 3.07978684e-05, 3.39666387e-05, + 3.11305144e-05, 2.52127041e-05, 1.97817664e-05, 1.82317249e-05, 1.89242031e-05, 2.90573660e-05, + 3.20992534e-05, 3.09778126e-05, 2.65669168e-05, 2.14696275e-05, 1.82238884e-05, 1.76175928e-05, + 1.89483615e-05, 3.08556814e-05, 3.28192065e-05, 3.08366650e-05, 2.60707242e-05, 1.97841435e-05, + 1.74849974e-05, 1.86298561e-05, 1.96417782e-05, 3.07042646e-05, 3.37087807e-05, 2.95315608e-05, + 2.39089175e-05, 2.22151412e-05, 2.18271748e-05, 2.06635601e-05, 2.69548468e-05, 2.88682309e-05, + 2.95796776e-05, 2.91264197e-05, 2.48612816e-05, 2.02639655e-05, 1.93861312e-05, 1.98465251e-05, + 2.62319401e-05, 2.83448589e-05, 2.82924853e-05, 2.66161381e-05, 2.54917375e-05, 2.44553138e-05, + 2.14030826e-05, 1.99770108e-05, 2.55644345e-05, 2.87978522e-05, 2.87544667e-05, 2.72961439e-05, + 2.65750295e-05, 2.43929957e-05, 2.14396208e-05, 1.97380052e-05, 1.97981847e-05, 2.25956930e-05, + 2.75791138e-05, 3.32550459e-05, 3.35695974e-05, 2.88295425e-05, 2.15124054e-05, 1.93128342e-05, + 2.17835094e-05, 2.79490274e-05, 2.97374249e-05, 2.78561944e-05, 2.42457713e-05, 2.35932219e-05, + 2.29745279e-05, 2.06531982e-05, 1.99585371e-05, 2.25528688e-05, 2.74166000e-05, 3.10932575e-05, + 2.85950724e-05, 2.51136680e-05, 2.20616509e-05, 2.01791105e-05, 2.00293650e-05, 2.54330684e-05, + 2.86857664e-05, 2.91790033e-05, 2.65772169e-05, 2.38835123e-05, 2.20762588e-05, 1.98831544e-05, + 2.06852024e-05, 2.19933872e-05, 2.48008323e-05, 3.01731271e-05, 3.31229273e-05, 2.93717020e-05, + 2.31068669e-05, 1.99955081e-05, 1.84530739e-05, 1.83510999e-05, 1.94416927e-05, 2.59736878e-05, + 2.77634210e-05, 2.87806709e-05, 2.60343211e-05, 2.21331155e-05, 2.33496956e-05, 2.19394148e-05, + 1.93016333e-05, 2.68879994e-05, 2.82772169e-05, 2.81636739e-05, 2.79211045e-05, 2.64487541e-05, + 2.21281582e-05, 2.02450641e-05, 2.12250290e-05, 2.72884087e-05, 3.04956842e-05, 3.03316188e-05, + 2.52863190e-05, 2.00422936e-05, 1.99350599e-05, 2.07338521e-05, 2.45265643e-05, 2.76044337e-05, + 2.99463559e-05, 2.95531961e-05, 2.64456589e-05, 2.36626054e-05, 2.15146879e-05, 1.93709542e-05, + 2.41621529e-05, 1.97638885e-05, 1.87736543e-05, 2.04436688e-05, 2.35167342e-05, 2.72115058e-05, + 2.91954689e-05, 2.95390352e-05, 2.97376023e-05, 2.48798780e-05, 2.21215097e-05, 2.29995457e-05, + 2.43904874e-05, 2.46126146e-05, 2.51714127e-05, 2.70982679e-05, 2.88660341e-05, 2.90497212e-05, + 2.90224458e-05, 2.98475915e-05, 2.28590653e-05, 2.01107288e-05, 2.07266094e-05, 2.33956451e-05, + 2.48956838e-05, 2.58210676e-05, 2.84450576e-05, 3.04274940e-05, 3.10240580e-05, 2.04533013e-05, + 1.55982605e-05, 1.75774573e-05, 2.38706364e-05, 2.78257769e-05, 2.93185287e-05, 3.00840505e-05, + 3.04682578e-05, 3.05014062e-05, 2.40986173e-05, 1.92249263e-05, 1.82770518e-05, 2.23861750e-05, + 2.60668000e-05, 2.68692360e-05, 2.71399434e-05, 2.87937485e-05, 3.04763646e-05, 2.80738937e-05, + 2.42471830e-05, 1.85264967e-05, 1.59103496e-05, 1.86543064e-05, 2.43001664e-05, 2.95142864e-05, + 3.14712951e-05, 3.10815931e-05, 2.12444917e-05, 1.68497610e-05, 1.76869668e-05, 2.18953038e-05, + 2.68818302e-05, 3.02716824e-05, 3.13383156e-05, 3.07590202e-05, 1.99519795e-05, 1.59285021e-05, + 1.74328576e-05, 2.25183492e-05, 2.85368297e-05, 3.13053537e-05, 3.11779442e-05, 3.03380426e-05, + 1.84939174e-05, 1.43662788e-05, 1.84157009e-05, 2.35871808e-05, 2.68340141e-05, 2.91432075e-05, + 3.02228905e-05, 2.21061192e-05, 1.90870691e-05, 1.88314754e-05, 2.07745422e-05, 2.57136107e-05, + 2.96378157e-05, 3.04830141e-05, 3.01533703e-05, 2.28392766e-05, 2.00140901e-05, 2.02429897e-05, + 2.22780042e-05, 2.45067158e-05, 2.66055589e-05, 2.91198054e-05, 3.00389842e-05, 2.35495146e-05, + 2.02386729e-05, 2.03999307e-05, 2.13469202e-05, 2.26942537e-05, 2.59082669e-05, 2.89842724e-05, + 3.03018556e-05, 3.01965271e-05, 2.38385902e-05, 1.85307462e-05, 1.49032658e-05, 1.66715174e-05, + 2.29268839e-05, 2.95073964e-05, 3.08691769e-05, 2.95283035e-05, 2.11057790e-05, 1.79721494e-05, + 2.02323286e-05, 2.41712432e-05, 2.56634564e-05, 2.73022499e-05, 2.94094001e-05, 2.99348257e-05, + 2.40788559e-05, 2.02697126e-05, 1.82160436e-05, 2.10791391e-05, 2.46504713e-05, 2.82015551e-05, + 3.00975984e-05, 2.99139229e-05, 2.39236886e-05, 2.01777112e-05, 1.96419001e-05, 2.18461717e-05, + 2.47074622e-05, 2.73937250e-05, 2.98447707e-05, 2.96762256e-05, 2.90798270e-05, 2.35054978e-05, + 1.83454808e-05, 1.65577564e-05, 2.06331427e-05, 2.58834197e-05, 2.89028046e-05, 3.10067947e-05, + 3.13369216e-05, 3.05135300e-05, 2.15160674e-05, 1.85387621e-05, 1.89572385e-05, 2.29874221e-05, + 2.78537961e-05, 2.88756403e-05, 3.00359362e-05, 3.11512885e-05, 2.30064356e-05, 1.97471229e-05, + 1.94541573e-05, 2.08398641e-05, 2.33666841e-05, 2.72594724e-05, 2.92654616e-05, 2.92834595e-05, + 1.99576985e-05, 1.60325231e-05, 1.86768345e-05, 2.51547993e-05, 2.98561152e-05, 3.00245479e-05, + 2.96597067e-05, 2.36327955e-05, 2.00476459e-05, 1.84043895e-05, 1.99193072e-05, 2.42523311e-05, + 2.74166969e-05, 2.90373123e-05, 3.03974588e-05, 2.50830104e-05, 2.35291844e-05, 2.30549382e-05, + 2.37732583e-05, 2.47321196e-05, 2.54640159e-05, 2.56276350e-05, 2.57149282e-05, 2.58438158e-05, + 2.52852323e-05, 2.44959619e-05, 2.47960777e-05, 2.51262569e-05, 2.51663851e-05, 2.52959721e-05, + 2.54765856e-05, 2.55337267e-05, 2.56979934e-05, 2.58061750e-05, 2.58176822e-05, 2.46754005e-05, + 2.36666053e-05, 2.39587714e-05, 2.48266063e-05, 2.51419839e-05, 2.54436998e-05, 2.57999938e-05, + 2.57140920e-05, 2.56412424e-05, 2.38187109e-05, 2.12138771e-05, 2.24179376e-05, 2.48153194e-05, + 2.51756686e-05, 2.55567359e-05, 2.58243025e-05, 2.57932478e-05, 2.57707167e-05, 2.48039235e-05, + 2.31921558e-05, 2.27822514e-05, 2.44726923e-05, 2.53195439e-05, 2.56626591e-05, 2.58528678e-05, + 2.59733509e-05, 2.58839885e-05, 2.53643794e-05, 2.48757622e-05, 2.29184025e-05, 2.14117373e-05, + 2.29953641e-05, 2.50739116e-05, 2.56565346e-05, 2.56607888e-05, 2.57783610e-05, 2.41756227e-05, + 2.19944749e-05, 2.24624827e-05, 2.42788081e-05, 2.53358831e-05, 2.54158936e-05, 2.54510351e-05, + 2.57186346e-05, 2.36499836e-05, 2.14290591e-05, 2.23151617e-05, 2.44889924e-05, 2.54212610e-05, + 2.54035830e-05, 2.57168270e-05, 2.58081322e-05, 2.28983412e-05, 2.03726323e-05, 2.28167165e-05, + 2.46523101e-05, 2.54594763e-05, 2.60121584e-05, 2.60242661e-05, 2.44004454e-05, 2.31364633e-05, + 2.30372245e-05, 2.39661809e-05, 2.55142567e-05, 2.57991342e-05, 2.57750257e-05, 2.58177613e-05, + 2.46326894e-05, 2.35652292e-05, 2.36708184e-05, 2.44421488e-05, 2.51796677e-05, 2.57427267e-05, + 2.59217859e-05, 2.58236291e-05, 2.48381563e-05, 2.36979999e-05, 2.37716266e-05, 2.41039047e-05, + 2.46072587e-05, 2.55154395e-05, 2.58954816e-05, 2.58240328e-05, 2.58155652e-05, 2.45538841e-05, + 2.27801920e-05, 2.07512696e-05, 2.18911174e-05, 2.48768616e-05, 2.60387565e-05, 2.58377879e-05, + 2.60981420e-05, 2.40446714e-05, 2.25849387e-05, 2.36383185e-05, 2.49081959e-05, 2.53232970e-05, + 2.57254884e-05, 2.58330957e-05, 2.57956739e-05, 2.46319365e-05, 2.36259465e-05, 2.27584332e-05, + 2.40743739e-05, 2.51861357e-05, 2.58140860e-05, 2.58847545e-05, 2.58078124e-05, 2.49626917e-05, + 2.36628441e-05, 2.34293128e-05, 2.42590452e-05, 2.50469410e-05, 2.55952707e-05, 2.57571137e-05, + 2.59033739e-05, 2.60284588e-05, 2.47345817e-05, 2.28023974e-05, 2.18222398e-05, 2.39135472e-05, + 2.53193136e-05, 2.55612857e-05, 2.56328456e-05, 2.56692681e-05, 2.57957597e-05, 2.40641410e-05, + 2.27952772e-05, 2.30659356e-05, 2.46715403e-05, 2.57333696e-05, 2.62180000e-05, 2.62497330e-05, + 2.58929341e-05, 2.47595467e-05, 2.34325662e-05, 2.32824411e-05, 2.39231206e-05, 2.48591422e-05, + 2.55666994e-05, 2.57067634e-05, 2.59253384e-05, 2.34699456e-05, 2.14735217e-05, 2.29840298e-05, + 2.53806746e-05, 2.57977001e-05, 2.58103180e-05, 2.59102431e-05, 2.47485166e-05, 2.35344327e-05, + 2.28262151e-05, 2.35827647e-05, 2.51899767e-05, 2.58683731e-05, 2.59238678e-05, 2.57527094e-05, + 2.53422436e-05, 2.61698185e-05, 2.62021896e-05, 2.62842146e-05, 2.56409820e-05, 2.41073376e-05, + 2.30633527e-05, 2.29140662e-05, 2.28736510e-05, 2.50945193e-05, 2.58181826e-05, 2.56182283e-05, + 2.52770006e-05, 2.52083332e-05, 2.50083516e-05, 2.41718063e-05, 2.32012033e-05, 2.31886229e-05, + 2.32603187e-05, 2.27951461e-05, 2.57456602e-05, 2.62151919e-05, 2.60390420e-05, 2.56061883e-05, + 2.51283584e-05, 2.47580167e-05, 2.35751211e-05, 2.23881214e-05, 2.19786871e-05, 2.61589861e-05, + 2.59473517e-05, 2.61865897e-05, 2.55216749e-05, 2.36032380e-05, 2.29463975e-05, 2.26616021e-05, + 2.24165983e-05, 2.23821811e-05, 2.54492047e-05, 2.65843375e-05, 2.63613759e-05, 2.59237990e-05, + 2.46458580e-05, 2.43257214e-05, 2.42173367e-05, 2.34546160e-05, 2.24695277e-05, 2.35696495e-05, + 2.53891086e-05, 2.62967067e-05, 2.57741978e-05, 2.61953825e-05, 2.53208656e-05, 2.28930513e-05, + 2.17242132e-05, 2.20430485e-05, 2.59484460e-05, 2.62410506e-05, 2.64088966e-05, 2.60804034e-05, + 2.42355229e-05, 2.22674854e-05, 2.16408948e-05, 2.21934336e-05, 2.59644327e-05, 2.61158070e-05, + 2.64837038e-05, 2.59146921e-05, 2.33283627e-05, 2.16226289e-05, 2.19416772e-05, 2.25028691e-05, + 2.63243013e-05, 2.58309909e-05, 2.65926551e-05, 2.56433558e-05, 2.43027398e-05, 2.32845165e-05, + 2.26959269e-05, 2.59672850e-05, 2.65687403e-05, 2.64915610e-05, 2.60742939e-05, 2.47836954e-05, + 2.29058520e-05, 2.23959187e-05, 2.26171378e-05, 2.57872418e-05, 2.64187508e-05, 2.63633098e-05, + 2.59456286e-05, 2.52265997e-05, 2.44336379e-05, 2.32599909e-05, 2.26874536e-05, 2.55821700e-05, + 2.62811497e-05, 2.62434715e-05, 2.61745704e-05, 2.58059983e-05, 2.47179273e-05, 2.33225542e-05, + 2.25341407e-05, 2.25905365e-05, 2.55489745e-05, 2.69302516e-05, 2.60004973e-05, 2.58480982e-05, + 2.54512531e-05, 2.30996112e-05, 2.22094929e-05, 2.31128156e-05, 2.61612596e-05, 2.66395881e-05, + 2.64342329e-05, 2.54093159e-05, 2.48243703e-05, 2.41352068e-05, 2.30554813e-05, 2.27313100e-05, + 2.54522818e-05, 2.64877552e-05, 2.62887064e-05, 2.60721200e-05, 2.51911832e-05, 2.37093110e-05, + 2.26896800e-05, 2.27507781e-05, 2.54510434e-05, 2.63169706e-05, 2.63728397e-05, 2.60957744e-05, + 2.52065284e-05, 2.40570735e-05, 2.27605406e-05, 2.29410910e-05, 2.33241265e-05, 2.56425847e-05, + 2.64715386e-05, 2.59860066e-05, 2.60718300e-05, 2.47298891e-05, 2.31960085e-05, 2.19828766e-05, + 2.18113178e-05, 2.23915219e-05, 2.62672611e-05, 2.68973262e-05, 2.66163158e-05, 2.57515245e-05, + 2.38633249e-05, 2.34767297e-05, 2.29021406e-05, 2.20803194e-05, 2.56651801e-05, 2.65027069e-05, + 2.65995481e-05, 2.62460035e-05, 2.55794126e-05, 2.41173343e-05, 2.30687521e-05, 2.31717106e-05, + 2.65963732e-05, 2.67451830e-05, 2.63686469e-05, 2.49870239e-05, 2.27783970e-05, 2.26878217e-05, + 2.29540320e-05, 2.56065284e-05, 2.65247533e-05, 2.65082850e-05, 2.62317657e-05, 2.52553801e-05, + 2.41006807e-05, 2.33058107e-05, 2.24318335e-05, 2.36348300e-05, 1.84735110e-05, 1.73571624e-05, + 2.00036057e-05, 2.43265834e-05, 2.83322876e-05, 3.04064558e-05, 3.03991198e-05, 3.00113528e-05, + 2.42493271e-05, 2.09527892e-05, 2.18844106e-05, 2.40132020e-05, 2.43731078e-05, 2.49837460e-05, + 2.80598038e-05, 3.04496553e-05, 2.98782299e-05, 2.92962952e-05, 3.02645542e-05, 2.24563596e-05, + 1.91461429e-05, 1.93928418e-05, 2.31516355e-05, 2.53418666e-05, 2.56021424e-05, 2.84997455e-05, + 3.13530000e-05, 3.22033589e-05, 1.94558347e-05, 1.40347288e-05, 1.61005044e-05, 2.47965980e-05, + 3.08044690e-05, 3.08915488e-05, 3.04961034e-05, 3.10370564e-05, 3.11711297e-05, 2.55370639e-05, + 1.92899215e-05, 1.72755577e-05, 2.24004063e-05, 2.69645563e-05, 2.65061157e-05, 2.58473821e-05, + 2.80823168e-05, 3.06305344e-05, 3.02197431e-05, 2.54477884e-05, 1.73612111e-05, 1.39270278e-05, + 1.72045885e-05, 2.41436567e-05, 3.06482047e-05, 3.24729970e-05, 3.16668734e-05, 1.98728387e-05, + 1.55868110e-05, 1.67850630e-05, 2.21233766e-05, 2.84654692e-05, 3.25069567e-05, 3.32246619e-05, + 3.16428751e-05, 1.80179372e-05, 1.45923949e-05, 1.67328432e-05, 2.27881326e-05, 3.05709670e-05, + 3.33899575e-05, 3.20103251e-05, 3.08385230e-05, 1.74072991e-05, 1.30571670e-05, 1.81779712e-05, + 2.51376267e-05, 2.76693345e-05, 2.83837065e-05, 2.96938654e-05, 2.18812840e-05, 1.90149563e-05, + 1.83655047e-05, 1.96230544e-05, 2.48384888e-05, 3.01101947e-05, 3.11338171e-05, 3.06012778e-05, + 2.27657712e-05, 1.98692096e-05, 2.00171659e-05, 2.22309999e-05, 2.39514017e-05, 2.54089877e-05, + 2.88302880e-05, 3.04501393e-05, 2.35939041e-05, 1.96304586e-05, 1.97368816e-05, 2.12945087e-05, + 2.24201943e-05, 2.53210393e-05, 2.87796053e-05, 3.07281784e-05, 3.06572900e-05, 2.65198289e-05, + 1.96904445e-05, 1.36743723e-05, 1.46055106e-05, 2.06749457e-05, 2.87433591e-05, 3.12189632e-05, + 2.84590453e-05, 2.06694400e-05, 1.77869704e-05, 2.03511129e-05, 2.50019713e-05, 2.60331635e-05, + 2.69757070e-05, 2.96647895e-05, 3.04671580e-05, 2.66399715e-05, 2.07168719e-05, 1.69995835e-05, + 2.01555470e-05, 2.43342773e-05, 2.80400422e-05, 3.02252608e-05, 3.03864319e-05, 2.38307513e-05, + 1.96868215e-05, 1.90643708e-05, 2.20950224e-05, 2.55044880e-05, 2.79100799e-05, 3.05488436e-05, + 2.96459228e-05, 2.82046094e-05, 2.42715639e-05, 1.76908980e-05, 1.47986676e-05, 1.93794069e-05, + 2.65650007e-05, 3.03623907e-05, 3.22245163e-05, 3.23359937e-05, 3.10701834e-05, 2.24741036e-05, + 1.95525953e-05, 1.90120071e-05, 2.29893956e-05, 2.79196491e-05, 2.68121899e-05, 2.83264545e-05, + 3.12283372e-05, 2.22663068e-05, 1.97919809e-05, 1.97329130e-05, 2.05763298e-05, 2.27606901e-05, + 2.78341636e-05, 3.01083629e-05, 2.90339877e-05, 2.06694630e-05, 1.60889600e-05, 1.77575031e-05, + 2.43120385e-05, 3.03694605e-05, 3.04969956e-05, 2.95916779e-05, 2.45680112e-05, 2.04615220e-05, + 1.78799849e-05, 1.89234749e-05, 2.30391078e-05, 2.63138461e-05, 2.87043764e-05, 3.11502926e-05, + 2.30265263e-05, 1.68864903e-05, 1.56379840e-05, 1.85226039e-05, 2.36313395e-05, 2.90109981e-05, + 3.20408621e-05, 3.21325974e-05, 3.17147575e-05, 2.38467451e-05, 1.97982760e-05, 2.09329084e-05, + 2.34837420e-05, 2.39228533e-05, 2.47161786e-05, 2.86638302e-05, 3.19973492e-05, 3.13547681e-05, + 3.06435587e-05, 3.20576484e-05, 2.15035415e-05, 1.76091134e-05, 1.79634582e-05, 2.23482482e-05, + 2.50481370e-05, 2.55507301e-05, 2.95348329e-05, 3.35866536e-05, 3.48566508e-05, 1.79774361e-05, + 1.20622081e-05, 1.42551099e-05, 2.42185175e-05, 3.21245775e-05, 3.26736517e-05, 3.24131838e-05, + 3.32026167e-05, 3.33809467e-05, 2.50792457e-05, 1.75931332e-05, 1.54785214e-05, 2.13490116e-05, + 2.71437675e-05, 2.68185743e-05, 2.61353112e-05, 2.91331834e-05, 3.26972886e-05, 3.14888957e-05, + 2.50155278e-05, 1.56013549e-05, 1.20091064e-05, 1.54722473e-05, 2.36053036e-05, 3.24318578e-05, + 3.53516686e-05, 3.41894595e-05, 1.85375826e-05, 1.36644597e-05, 1.49167518e-05, 2.09616268e-05, + 2.90796221e-05, 3.49997129e-05, 3.62854133e-05, 3.40566318e-05, 1.64727622e-05, 1.26144549e-05, + 1.48265721e-05, 2.17821481e-05, 3.20490545e-05, 3.64906174e-05, 3.46591539e-05, 3.29148108e-05, + 1.56401488e-05, 1.10194552e-05, 1.63680090e-05, 2.45252757e-05, 2.81434137e-05, 2.95835538e-05, + 3.14655285e-05, 2.07527318e-05, 1.72987230e-05, 1.66209283e-05, 1.82019632e-05, 2.46782029e-05, + 3.18069242e-05, 3.33284521e-05, 3.25641608e-05, 2.18247486e-05, 1.83095585e-05, 1.84992513e-05, + 2.11504341e-05, 2.34420247e-05, 2.55165132e-05, 3.01107003e-05, 3.23429550e-05, 2.28520676e-05, + 1.81126787e-05, 1.82479784e-05, 1.99996656e-05, 2.14321855e-05, 2.52576082e-05, 3.00131584e-05, + 3.27663888e-05, 3.26466034e-05, 2.61017231e-05, 1.78603218e-05, 1.16410093e-05, 1.27342720e-05, + 1.96644257e-05, 3.01120972e-05, 3.35549194e-05, 2.97768322e-05, 1.93168561e-05, 1.59167230e-05, + 1.88316777e-05, 2.45099475e-05, 2.59955637e-05, 2.74620974e-05, 3.11979505e-05, 3.23331400e-05, + 2.62931367e-05, 1.92063904e-05, 1.52055163e-05, 1.87922056e-05, 2.38889174e-05, 2.89281019e-05, + 3.20825536e-05, 3.22273134e-05, 2.31861290e-05, 1.81577531e-05, 1.74455041e-05, 2.09223743e-05, + 2.51842115e-05, 2.85661775e-05, 3.24073540e-05, 3.12508099e-05, 2.93536505e-05, 2.35696081e-05, + 1.58874206e-05, 1.28946818e-05, 1.79334216e-05, 2.66463127e-05, 3.19015744e-05, 3.48781646e-05, + 3.51299673e-05, 3.32580084e-05, 2.12486476e-05, 1.77266054e-05, 1.72727950e-05, 2.20912689e-05, + 2.86964508e-05, 2.76636337e-05, 2.97544474e-05, 3.36545876e-05, 2.13339346e-05, 1.81838678e-05, + 1.80717057e-05, 1.91724675e-05, 2.19278301e-05, 2.84432783e-05, 3.16968286e-05, 3.04001040e-05, + 1.90993453e-05, 1.40018412e-05, 1.60068891e-05, 2.39754734e-05, 3.21893512e-05, 3.23966203e-05, + 3.11800789e-05, 2.39176211e-05, 1.89077347e-05, 1.60789863e-05, 1.73555441e-05, 2.24067950e-05, + 2.67317752e-05, 2.99376358e-05, 3.33228111e-05, 2.54073919e-05, 2.60203922e-05, 2.60083215e-05, + 2.58907770e-05, 2.52511430e-05, 2.41291075e-05, 2.33119896e-05, 2.32696125e-05, 2.33639284e-05, + 2.52677193e-05, 2.58627105e-05, 2.57353763e-05, 2.53255178e-05, 2.52442509e-05, 2.50948189e-05, + 2.42139205e-05, 2.33387240e-05, 2.34938971e-05, 2.36733541e-05, 2.32695589e-05, 2.56250593e-05, + 2.59764209e-05, 2.60012903e-05, 2.55009148e-05, 2.50161286e-05, 2.49266131e-05, 2.39709243e-05, + 2.28319430e-05, 2.24448647e-05, 2.59690488e-05, 2.55480953e-05, 2.59096050e-05, 2.51487190e-05, + 2.33381433e-05, 2.31423408e-05, 2.31623545e-05, 2.29293786e-05, 2.28801763e-05, 2.49743661e-05, + 2.58528642e-05, 2.59427588e-05, 2.56176281e-05, 2.45714914e-05, 2.46456036e-05, 2.47923000e-05, + 2.40519187e-05, 2.30598733e-05, 2.34963445e-05, 2.49963200e-05, 2.59729763e-05, 2.56183293e-05, + 2.60044129e-05, 2.52974427e-05, 2.31941005e-05, 2.22693113e-05, 2.26179352e-05, 2.59754243e-05, + 2.57981080e-05, 2.58849653e-05, 2.56448171e-05, 2.41147582e-05, 2.24670178e-05, 2.20272943e-05, + 2.26812828e-05, 2.60874328e-05, 2.56257955e-05, 2.58431533e-05, 2.55474221e-05, 2.33384503e-05, + 2.19739143e-05, 2.24838802e-05, 2.30142596e-05, 2.59641337e-05, 2.51972792e-05, 2.58743503e-05, + 2.50648061e-05, 2.43398199e-05, 2.39260093e-05, 2.33930046e-05, 2.57014910e-05, 2.58710833e-05, + 2.59153332e-05, 2.59744642e-05, 2.51111612e-05, 2.33467974e-05, 2.28953550e-05, 2.31185570e-05, + 2.55640585e-05, 2.58665412e-05, 2.58688603e-05, 2.56449384e-05, 2.53379961e-05, 2.49336673e-05, + 2.37995349e-05, 2.31835523e-05, 2.54116291e-05, 2.59244417e-05, 2.59252619e-05, 2.57588779e-05, + 2.56263956e-05, 2.49904398e-05, 2.38304058e-05, 2.30554359e-05, 2.30941684e-05, 2.47258659e-05, + 2.56913688e-05, 2.53660479e-05, 2.57836211e-05, 2.59345905e-05, 2.37767478e-05, 2.28042217e-05, + 2.38565825e-05, 2.58452474e-05, 2.58438879e-05, 2.58164122e-05, 2.51024297e-05, 2.48267201e-05, + 2.44929334e-05, 2.35142055e-05, 2.31932087e-05, 2.46970269e-05, 2.57611215e-05, 2.59559134e-05, + 2.59226422e-05, 2.52524555e-05, 2.41257221e-05, 2.32460467e-05, 2.32217571e-05, 2.53650794e-05, + 2.59103015e-05, 2.59354757e-05, 2.56472240e-05, 2.49798005e-05, 2.42332765e-05, 2.31801009e-05, + 2.34847945e-05, 2.39845767e-05, 2.52632747e-05, 2.59149479e-05, 2.57597794e-05, 2.59951766e-05, + 2.46834660e-05, 2.33616643e-05, 2.24406148e-05, 2.23423354e-05, 2.29113658e-05, 2.55522267e-05, + 2.57134371e-05, 2.58532760e-05, 2.55239806e-05, 2.41918727e-05, 2.43880488e-05, 2.38267848e-05, + 2.27528008e-05, 2.56654378e-05, 2.58474414e-05, 2.58198939e-05, 2.58384802e-05, 2.55786353e-05, + 2.42646246e-05, 2.33961727e-05, 2.37196003e-05, 2.57344167e-05, 2.55906588e-05, 2.59580925e-05, + 2.52478072e-05, 2.32353214e-05, 2.31707719e-05, 2.35035579e-05, 2.51983883e-05, 2.57787794e-05, + 2.59049313e-05, 2.59843986e-05, 2.55293927e-05, 2.46551076e-05, 2.38460786e-05, 2.29034437e-05, + 2.55216143e-05, 2.68724336e-05, 2.70326621e-05, 2.64137864e-05, 2.51320503e-05, 2.36033517e-05, + 2.26034868e-05, 2.25896875e-05, 2.27632307e-05, 2.53253740e-05, 2.63766762e-05, 2.61271173e-05, + 2.53802246e-05, 2.52440037e-05, 2.50237239e-05, 2.37270962e-05, 2.25964666e-05, 2.28602991e-05, + 2.31362138e-05, 2.26356885e-05, 2.58567614e-05, 2.66879015e-05, 2.67390508e-05, 2.56344408e-05, + 2.48384635e-05, 2.47940545e-05, 2.35254840e-05, 2.20692747e-05, 2.15977628e-05, 2.66463948e-05, + 2.70731496e-05, 2.71198222e-05, 2.49697423e-05, 2.24518584e-05, 2.23663567e-05, 2.25090021e-05, + 2.22187695e-05, 2.21510837e-05, 2.46659545e-05, 2.63776636e-05, 2.69026193e-05, 2.58006389e-05, + 2.41903075e-05, 2.44341756e-05, 2.47413037e-05, 2.37124679e-05, 2.24143731e-05, 2.27246243e-05, + 2.47234701e-05, 2.69514737e-05, 2.72554301e-05, 2.70556998e-05, 2.53122734e-05, 2.24721536e-05, + 2.14141636e-05, 2.18547008e-05, 2.66562754e-05, 2.70368262e-05, 2.68903621e-05, 2.58290190e-05, + 2.35342239e-05, 2.15217085e-05, 2.10573215e-05, 2.18986310e-05, 2.71085399e-05, 2.70191824e-05, + 2.68160780e-05, 2.56545734e-05, 2.25495062e-05, 2.09791205e-05, 2.16760150e-05, 2.23252642e-05, + 2.69222081e-05, 2.68018860e-05, 2.65818419e-05, 2.47796595e-05, 2.39001514e-05, 2.35605732e-05, + 2.28830714e-05, 2.59747352e-05, 2.64508298e-05, 2.66406616e-05, 2.66543447e-05, 2.51301027e-05, + 2.27219067e-05, 2.21707138e-05, 2.24535253e-05, 2.57184618e-05, 2.63589476e-05, 2.63568338e-05, + 2.58548530e-05, 2.54201779e-05, 2.49221381e-05, 2.33519365e-05, 2.25341976e-05, 2.54613587e-05, + 2.65188076e-05, 2.65152432e-05, 2.60741890e-05, 2.58453834e-05, 2.49261755e-05, 2.33805805e-05, + 2.23812813e-05, 2.24234177e-05, 2.41906157e-05, 2.59862437e-05, 2.68636268e-05, 2.73343809e-05, + 2.66322035e-05, 2.33762079e-05, 2.20944878e-05, 2.35089209e-05, 2.62886878e-05, 2.65884431e-05, + 2.62122063e-05, 2.49146641e-05, 2.45888069e-05, 2.42302302e-05, 2.29455877e-05, 2.25331086e-05, + 2.41658406e-05, 2.60656078e-05, 2.69923832e-05, 2.65007572e-05, 2.52651511e-05, 2.37428847e-05, + 2.26378587e-05, 2.25731372e-05, 2.54060420e-05, 2.64792667e-05, 2.65941364e-05, 2.58316240e-05, + 2.47471935e-05, 2.38015435e-05, 2.24998753e-05, 2.29406018e-05, 2.36466338e-05, 2.51549509e-05, + 2.67577246e-05, 2.72158074e-05, 2.67223022e-05, 2.43617307e-05, 2.26365058e-05, 2.15892011e-05, + 2.14977622e-05, 2.21989126e-05, 2.55984754e-05, 2.60475507e-05, 2.64116504e-05, 2.56442261e-05, + 2.38003547e-05, 2.42989853e-05, 2.35436299e-05, 2.20617317e-05, 2.59628450e-05, 2.63182509e-05, + 2.62591463e-05, 2.62670720e-05, 2.58015486e-05, 2.38344904e-05, 2.27419472e-05, 2.32494835e-05, + 2.60026824e-05, 2.64868934e-05, 2.68401685e-05, 2.53221686e-05, 2.25849946e-05, 2.25127318e-05, + 2.29672755e-05, 2.50404918e-05, 2.61161440e-05, 2.67004368e-05, 2.67293565e-05, 2.57939616e-05, + 2.45348154e-05, 2.34140620e-05, 2.21699034e-05, 2.49212048e-05, 3.52771820e-05, 3.79589082e-05, + 3.24436255e-05, 2.46160734e-05, 1.82061718e-05, 1.53170665e-05, 1.51276773e-05, 1.53152364e-05, + 2.37249810e-05, 2.97437509e-05, 2.78577281e-05, 2.43354717e-05, 2.37844456e-05, 2.27438202e-05, + 1.85172509e-05, 1.54697566e-05, 1.58177030e-05, 1.63021526e-05, 1.50557634e-05, 2.72753757e-05, + 3.39644199e-05, 3.30570693e-05, 2.60430003e-05, 2.25630560e-05, 2.16658250e-05, 1.73093256e-05, + 1.39111008e-05, 1.29750662e-05, 3.32116406e-05, 4.72636504e-05, 4.12680093e-05, 2.38493573e-05, + 1.57698943e-05, 1.48720982e-05, 1.47437204e-05, 1.41216039e-05, 1.40040994e-05, 2.28990211e-05, + 3.45351044e-05, 3.85776016e-05, 2.77093568e-05, 2.01750269e-05, 2.00870023e-05, 2.05287816e-05, + 1.74483051e-05, 1.44200278e-05, 1.61023362e-05, 2.28933213e-05, 3.81945092e-05, 4.71143159e-05, + 3.83226063e-05, 2.42581380e-05, 1.49494133e-05, 1.25480064e-05, 1.33249286e-05, 3.19296723e-05, + 4.29433584e-05, 3.99784610e-05, 2.84341548e-05, 1.82885449e-05, 1.31605445e-05, 1.21031642e-05, + 1.35182452e-05, 3.57831173e-05, 4.58010250e-05, 4.03190439e-05, 2.71357832e-05, 1.55594567e-05, + 1.20083701e-05, 1.30285080e-05, 1.43421583e-05, 3.81514415e-05, 5.07070732e-05, 3.69828217e-05, + 2.36726870e-05, 1.90331405e-05, 1.69795692e-05, 1.52802587e-05, 2.85736698e-05, 3.50722929e-05, + 3.63053171e-05, 3.26902484e-05, 2.25125170e-05, 1.52956806e-05, 1.40418323e-05, 1.46246442e-05, + 2.69189529e-05, 3.30026774e-05, 3.25959936e-05, 2.80021428e-05, 2.43183028e-05, 2.13178738e-05, + 1.66246969e-05, 1.48043259e-05, 2.54196586e-05, 3.31510979e-05, 3.28585778e-05, 2.99353699e-05, + 2.74468994e-05, 2.18873144e-05, 1.67482247e-05, 1.44451916e-05, 1.45579299e-05, 2.20411772e-05, + 3.45142452e-05, 4.87862764e-05, 4.49424549e-05, 2.94153715e-05, 1.64615917e-05, 1.37651974e-05, + 1.66812540e-05, 3.09658670e-05, 3.80260133e-05, 3.21331644e-05, 2.34193403e-05, 2.13434401e-05, + 1.93684652e-05, 1.57785432e-05, 1.48504896e-05, 2.17651143e-05, 3.15906485e-05, 3.90930851e-05, + 3.16866661e-05, 2.37990745e-05, 1.78520679e-05, 1.49428557e-05, 1.49241897e-05, 2.48777716e-05, + 3.31234339e-05, 3.45052404e-05, 2.85081132e-05, 2.25225847e-05, 1.84676815e-05, 1.48390739e-05, + 1.56375010e-05, 1.71680691e-05, 2.46855928e-05, 3.78333864e-05, 4.47109041e-05, 3.31599009e-05, + 2.06772575e-05, 1.55177354e-05, 1.29694017e-05, 1.27147188e-05, 1.40718851e-05, 2.82819798e-05, + 3.47190237e-05, 3.51910378e-05, 2.65406180e-05, 1.81729953e-05, 1.84909366e-05, 1.64777216e-05, + 1.36020615e-05, 2.73895079e-05, 3.33424180e-05, 3.36782714e-05, 3.13141581e-05, 2.65214751e-05, + 1.86188668e-05, 1.55109948e-05, 1.63599685e-05, 3.19105079e-05, 4.28463374e-05, 3.74114653e-05, + 2.34596676e-05, 1.49701406e-05, 1.47767978e-05, 1.56900310e-05, 2.42660205e-05, 3.21305026e-05, + 3.74720004e-05, 3.44641038e-05, 2.55221336e-05, 1.99040961e-05, 1.67782951e-05, 1.40771299e-05, + 2.54978260e-05, 3.17987227e-05, 3.32450950e-05, 3.00308020e-05, 2.50751595e-05, 2.05764949e-05, + 1.83177072e-05, 1.81967623e-05, 1.84045287e-05, 2.47221887e-05, 2.86291947e-05, 2.74704638e-05, + 2.50885402e-05, 2.47008530e-05, 2.39909239e-05, 2.08276119e-05, 1.84050281e-05, 1.87577766e-05, + 1.91992214e-05, 1.81788263e-05, 2.69752461e-05, 3.10017370e-05, 3.05868329e-05, 2.61721786e-05, + 2.37730902e-05, 2.32509082e-05, 2.00122278e-05, 1.71801781e-05, 1.63572994e-05, 3.05932612e-05, + 3.76974740e-05, 3.49152406e-05, 2.45567964e-05, 1.85043998e-05, 1.79217674e-05, 1.79218437e-05, + 1.73882324e-05, 1.72804709e-05, 2.38465940e-05, 3.10455642e-05, 3.34383871e-05, 2.71631106e-05, + 2.20451349e-05, 2.21448033e-05, 2.25839538e-05, 2.02019526e-05, 1.76747986e-05, 1.88510657e-05, + 2.38801008e-05, 3.32928765e-05, 3.77975336e-05, 3.34411380e-05, 2.50018050e-05, 1.80256273e-05, + 1.59972193e-05, 1.67073766e-05, 2.99543546e-05, 3.56401081e-05, 3.41030357e-05, 2.75598025e-05, + 2.05834983e-05, 1.64327561e-05, 1.55374982e-05, 1.68493888e-05, 3.22382322e-05, 3.69668713e-05, + 3.42038495e-05, 2.67618620e-05, 1.84327497e-05, 1.54386221e-05, 1.64309820e-05, 1.75794520e-05, + 3.32479176e-05, 3.90278589e-05, 3.24047703e-05, 2.43385735e-05, 2.12247322e-05, 1.98400879e-05, + 1.84500585e-05, 2.77350838e-05, 3.13669493e-05, 3.21210343e-05, 3.03372799e-05, 2.39328429e-05, + 1.83700182e-05, 1.73139495e-05, 1.78198148e-05, 2.66921721e-05, 3.02698185e-05, 3.00644995e-05, + 2.73536368e-05, 2.51058547e-05, 2.31390394e-05, 1.95118448e-05, 1.79721039e-05, 2.57236610e-05, + 3.04653716e-05, 3.03160071e-05, 2.85077618e-05, 2.70571833e-05, 2.34573524e-05, 1.96007835e-05, + 1.76721366e-05, 1.77631665e-05, 2.30801327e-05, 3.07365910e-05, 3.82062665e-05, 3.68503675e-05, + 2.86474830e-05, 1.94297935e-05, 1.71044015e-05, 1.96353421e-05, 2.91902040e-05, 3.29155567e-05, + 2.97238749e-05, 2.42885445e-05, 2.29431509e-05, 2.16137766e-05, 1.87820642e-05, 1.79993126e-05, + 2.29134397e-05, 2.93424036e-05, 3.37620258e-05, 2.97139105e-05, 2.47226808e-05, 2.04539498e-05, + 1.81121829e-05, 1.80655161e-05, 2.53970989e-05, 3.04214227e-05, 3.11979733e-05, 2.75999348e-05, + 2.36927868e-05, 2.08430877e-05, 1.79743311e-05, 1.86953816e-05, 2.00002484e-05, 2.51274832e-05, + 3.29593404e-05, 3.66335272e-05, 3.06256240e-05, 2.24313836e-05, 1.84556085e-05, 1.63493596e-05, + 1.61440320e-05, 1.73473326e-05, 2.73196050e-05, 3.08835590e-05, 3.13949668e-05, 2.64419373e-05, + 2.06729972e-05, 2.11541766e-05, 1.95357285e-05, 1.69870468e-05, 2.71092871e-05, 3.04086342e-05, + 3.05308908e-05, 2.93511115e-05, 2.65400895e-05, 2.09492089e-05, 1.85096769e-05, 1.92975522e-05, + 2.94570264e-05, 3.51200773e-05, 3.28210927e-05, 2.45759539e-05, 1.80996263e-05, 1.79438160e-05, + 1.87415559e-05, 2.48272686e-05, 2.96512332e-05, 3.27376001e-05, 3.12827754e-05, 2.60040886e-05, + 2.21036746e-05, 1.96376415e-05, 1.73350182e-05, 2.39874077e-05, 1.92184207e-05, 1.81704550e-05, + 1.99180863e-05, 2.32412417e-05, 2.74096629e-05, 2.97205765e-05, 3.01269181e-05, 3.03631719e-05, + 2.47906894e-05, 2.17580100e-05, 2.27175119e-05, 2.42382132e-05, 2.44831504e-05, 2.51083792e-05, + 2.72809200e-05, 2.93319998e-05, 2.95500573e-05, 2.95207105e-05, 3.04930925e-05, 2.25434811e-05, + 1.95778761e-05, 2.02522002e-05, 2.31308195e-05, 2.47865718e-05, 2.58414393e-05, 2.88476874e-05, + 3.11840605e-05, 3.19027632e-05, 1.99466529e-05, 1.48614629e-05, 1.69132847e-05, 2.36320086e-05, + 2.81117703e-05, 2.98655589e-05, 3.07738593e-05, 3.12320965e-05, 3.12719375e-05, 2.38768473e-05, + 1.85973666e-05, 1.76296647e-05, 2.20137163e-05, 2.61023694e-05, 2.70355357e-05, 2.73607417e-05, + 2.92613180e-05, 3.12414923e-05, 2.84028839e-05, 2.40468403e-05, 1.78992968e-05, 1.52029997e-05, + 1.80455052e-05, 2.41326026e-05, 3.00973106e-05, 3.24435344e-05, 3.19688653e-05, 2.08123088e-05, + 1.61441867e-05, 1.70049315e-05, 2.14715526e-05, 2.70262055e-05, 3.10034668e-05, 3.22904486e-05, + 3.15816633e-05, 1.94437336e-05, 1.51917533e-05, 1.67306789e-05, 2.21522081e-05, 2.89446452e-05, + 3.22525813e-05, 3.20865855e-05, 3.10764438e-05, 1.78618573e-05, 1.35875025e-05, 1.77484367e-05, + 2.33053315e-05, 2.69789553e-05, 2.96700373e-05, 3.09410739e-05, 2.17137266e-05, 1.84549930e-05, + 1.81966683e-05, 2.02975656e-05, 2.57329158e-05, 3.02445743e-05, 3.12498878e-05, 3.08563110e-05, + 2.25132664e-05, 1.94474539e-05, 1.96956513e-05, 2.18968780e-05, 2.43719092e-05, 2.67496436e-05, + 2.96386581e-05, 3.07202848e-05, 2.32941681e-05, 1.97031705e-05, 1.98781873e-05, 2.08824517e-05, + 2.23590529e-05, 2.59469807e-05, 2.94792620e-05, 3.10332401e-05, 3.09076973e-05, 2.35676673e-05, + 1.78265347e-05, 1.41323721e-05, 1.59946943e-05, 2.26733949e-05, 3.00972817e-05, 3.17122648e-05, + 3.01244184e-05, 2.06323390e-05, 1.72784655e-05, 1.96737563e-05, 2.39687337e-05, 2.56529523e-05, + 2.75309977e-05, 2.99757030e-05, 3.05964164e-05, 2.38377920e-05, 1.97044589e-05, 1.75736692e-05, + 2.06187315e-05, 2.45271247e-05, 2.85668148e-05, 3.07903656e-05, 3.05716794e-05, 2.37122754e-05, + 1.96339329e-05, 1.90631264e-05, 2.14174188e-05, 2.45690998e-05, 2.76256615e-05, 3.04893419e-05, + 3.02917280e-05, 2.95970069e-05, 2.32296816e-05, 1.76889649e-05, 1.58623625e-05, 2.01488246e-05, + 2.58971849e-05, 2.93754802e-05, 3.18821584e-05, 3.22803167e-05, 3.12862393e-05, 2.10399777e-05, + 1.78392228e-05, 1.83128345e-05, 2.26744433e-05, 2.81615855e-05, 2.93741003e-05, 3.07277461e-05, + 3.20509599e-05, 2.27145673e-05, 1.91555909e-05, 1.88352467e-05, 2.03396949e-05, 2.31079547e-05, + 2.74704585e-05, 2.98039455e-05, 2.98303762e-05, 1.93617568e-05, 1.52430368e-05, 1.80490238e-05, + 2.51035559e-05, 3.05030322e-05, 3.07030643e-05, 3.02723903e-05, 2.33674908e-05, 1.94667421e-05, + 1.77465113e-05, 1.93739973e-05, 2.41047754e-05, 2.76743234e-05, 2.95423695e-05, 3.11477365e-05, + 2.40642459e-05, 1.95182992e-05, 1.85025653e-05, 2.03748835e-05, 2.36898259e-05, 2.74301791e-05, + 2.94213294e-05, 2.96943176e-05, 2.97756384e-05, 2.47580757e-05, 2.18964809e-05, 2.27833246e-05, + 2.43224927e-05, 2.45718750e-05, 2.51390185e-05, 2.72863702e-05, 2.91658739e-05, 2.92015972e-05, + 2.90645911e-05, 2.99134984e-05, 2.27911566e-05, 1.99335389e-05, 2.04698797e-05, 2.33583814e-05, + 2.49917340e-05, 2.57796486e-05, 2.84464383e-05, 3.05902408e-05, 3.12325589e-05, 2.02684483e-05, + 1.52973193e-05, 1.72946143e-05, 2.40652453e-05, 2.83945582e-05, 2.96137938e-05, 3.01475617e-05, + 3.05604882e-05, 3.06133742e-05, 2.43919108e-05, 1.92619072e-05, 1.80953860e-05, 2.24045819e-05, + 2.62471290e-05, 2.67938650e-05, 2.68712910e-05, 2.86376593e-05, 3.04860394e-05, 2.84853496e-05, + 2.44939527e-05, 1.83096370e-05, 1.55158098e-05, 1.83762034e-05, 2.42774639e-05, 2.97233033e-05, + 3.16421275e-05, 3.11731440e-05, 2.09785531e-05, 1.66138730e-05, 1.75272183e-05, 2.19582311e-05, + 2.71916865e-05, 3.06878806e-05, 3.16811889e-05, 3.09114904e-05, 1.95666659e-05, 1.56773241e-05, + 1.73159208e-05, 2.25877095e-05, 2.89246857e-05, 3.16862870e-05, 3.13175627e-05, 3.04175517e-05, + 1.82938588e-05, 1.41211500e-05, 1.83928000e-05, 2.39037754e-05, 2.69986054e-05, 2.89753823e-05, + 3.00961263e-05, 2.20768909e-05, 1.90965893e-05, 1.87608633e-05, 2.05564529e-05, 2.55379914e-05, + 2.97159676e-05, 3.05913625e-05, 3.02235831e-05, 2.28384951e-05, 2.00067510e-05, 2.02186059e-05, + 2.22843664e-05, 2.44017982e-05, 2.63593050e-05, 2.90480572e-05, 3.01025896e-05, 2.35701557e-05, + 2.01356385e-05, 2.02851413e-05, 2.13549195e-05, 2.26531738e-05, 2.57912676e-05, 2.89304559e-05, + 3.03668708e-05, 3.02690284e-05, 2.43674465e-05, 1.87850890e-05, 1.46756598e-05, 1.62586397e-05, + 2.24666268e-05, 2.93366471e-05, 3.09153980e-05, 2.92944639e-05, 2.10360817e-05, 1.79607907e-05, + 2.02778283e-05, 2.43460812e-05, 2.57411236e-05, 2.72323005e-05, 2.94456759e-05, 3.00231063e-05, + 2.45846771e-05, 2.03808048e-05, 1.79886826e-05, 2.09083494e-05, 2.45939702e-05, 2.81606221e-05, + 3.01042852e-05, 2.99904660e-05, 2.39152517e-05, 2.00990848e-05, 1.95465556e-05, 2.19134079e-05, + 2.48736369e-05, 2.74926475e-05, 2.99675409e-05, 2.96536931e-05, 2.88885182e-05, 2.36700207e-05, + 1.82366154e-05, 1.62134949e-05, 2.03936607e-05, 2.60220097e-05, 2.91785109e-05, 3.12228881e-05, + 3.15081535e-05, 3.06030724e-05, 2.17244652e-05, 1.87648848e-05, 1.89927201e-05, 2.30014191e-05, + 2.78604741e-05, 2.84359353e-05, 2.96655151e-05, 3.11412167e-05, 2.28684995e-05, 1.97788734e-05, + 1.95335883e-05, 2.08062820e-05, 2.32553272e-05, 2.73706129e-05, 2.94189463e-05, 2.92189194e-05, + 2.01218577e-05, 1.60731184e-05, 1.85118984e-05, 2.49880863e-05, 2.99411035e-05, 3.01004137e-05, + 2.96296745e-05, 2.38300606e-05, 2.01526606e-05, 1.83224800e-05, 1.97359324e-05, 2.40115005e-05, + 2.71864395e-05, 2.89572056e-05, 3.05264640e-05, 2.51586155e-05, 2.51640608e-05, 2.50078424e-05, + 2.57683225e-05, 2.59438985e-05, 2.47708905e-05, 2.38703552e-05, 2.36343126e-05, 2.34289843e-05, + 2.49388826e-05, 2.51489313e-05, 2.50707158e-05, 2.51749644e-05, 2.51809993e-05, 2.50505725e-05, + 2.47743529e-05, 2.41048364e-05, 2.38696549e-05, 2.37662660e-05, 2.34011281e-05, 2.54879775e-05, + 2.54104844e-05, 2.51300056e-05, 2.54661383e-05, 2.53905135e-05, 2.48448934e-05, 2.39689893e-05, + 2.31791028e-05, 2.28731684e-05, 2.53778323e-05, 2.42418969e-05, 2.48029973e-05, 2.58963358e-05, + 2.48969273e-05, 2.38691020e-05, 2.32815651e-05, 2.31069231e-05, 2.31037309e-05, 2.60406642e-05, + 2.61958633e-05, 2.53218837e-05, 2.58013643e-05, 2.51591631e-05, 2.44506647e-05, 2.40373280e-05, + 2.36269926e-05, 2.30394077e-05, 2.46115396e-05, 2.58970058e-05, 2.52016526e-05, 2.38668921e-05, + 2.49683634e-05, 2.52984496e-05, 2.36943194e-05, 2.25930914e-05, 2.27752446e-05, 2.50842856e-05, + 2.48798693e-05, 2.53519289e-05, 2.60085053e-05, 2.50369388e-05, 2.34221706e-05, 2.27409890e-05, + 2.29911328e-05, 2.46658243e-05, 2.45904443e-05, 2.55071455e-05, 2.59140263e-05, 2.43551600e-05, + 2.27739351e-05, 2.27483325e-05, 2.31651762e-05, 2.52663645e-05, 2.41096160e-05, 2.59701291e-05, + 2.62490786e-05, 2.48448531e-05, 2.34713943e-05, 2.30435854e-05, 2.57144973e-05, 2.60980218e-05, + 2.57939945e-05, 2.52572212e-05, 2.46150697e-05, 2.35148496e-05, 2.31108952e-05, 2.32522187e-05, + 2.56679262e-05, 2.60018408e-05, 2.59297228e-05, 2.57867927e-05, 2.50648072e-05, 2.42344433e-05, + 2.35949889e-05, 2.33042147e-05, 2.55750390e-05, 2.56631384e-05, 2.56164474e-05, 2.59277135e-05, + 2.55875831e-05, 2.46757139e-05, 2.36739814e-05, 2.31723999e-05, 2.32321851e-05, 2.66098556e-05, + 2.70423862e-05, 2.44019750e-05, 2.40084246e-05, 2.44052355e-05, 2.33161047e-05, 2.28618819e-05, + 2.32346221e-05, 2.57147604e-05, 2.59999334e-05, 2.61649000e-05, 2.57673311e-05, 2.51165082e-05, + 2.43098531e-05, 2.35826354e-05, 2.33775082e-05, 2.64760046e-05, 2.63784962e-05, 2.51279908e-05, + 2.53967659e-05, 2.51371578e-05, 2.40133937e-05, 2.32257126e-05, 2.33777499e-05, 2.54207350e-05, + 2.57491087e-05, 2.57057845e-05, 2.60288570e-05, 2.55893359e-05, 2.45280154e-05, 2.34523967e-05, + 2.33992327e-05, 2.34682763e-05, 2.59268935e-05, 2.56228456e-05, 2.43036726e-05, 2.51895169e-05, + 2.51525563e-05, 2.40634495e-05, 2.28871044e-05, 2.26724398e-05, 2.30811166e-05, 2.64896618e-05, + 2.69350176e-05, 2.61976237e-05, 2.56774413e-05, 2.42161027e-05, 2.32109858e-05, 2.28692978e-05, + 2.26734712e-05, 2.52784190e-05, 2.61529234e-05, 2.63385584e-05, 2.58532889e-05, 2.52857221e-05, + 2.45987429e-05, 2.37673513e-05, 2.35321464e-05, 2.65887566e-05, 2.60499109e-05, 2.54197441e-05, + 2.47757313e-05, 2.34138867e-05, 2.33219033e-05, 2.33993675e-05, 2.59683789e-05, 2.63809341e-05, + 2.57344432e-05, 2.53896534e-05, 2.48039278e-05, 2.40149616e-05, 2.36204591e-05, 2.31712374e-05, + 2.52496960e-05, 2.76416970e-05, 2.80365038e-05, 2.79572395e-05, 2.63916081e-05, 2.32701051e-05, + 2.14613773e-05, 2.11078073e-05, 2.08665979e-05, 2.46596124e-05, 2.63139069e-05, 2.57645576e-05, + 2.51465581e-05, 2.50358705e-05, 2.46166022e-05, 2.33374656e-05, 2.18094915e-05, 2.15530321e-05, + 2.15024998e-05, 2.07826304e-05, 2.62844787e-05, 2.77332384e-05, 2.70537902e-05, 2.59711590e-05, + 2.50866928e-05, 2.40852381e-05, 2.19700215e-05, 2.02861024e-05, 1.97267841e-05, 2.74970987e-05, + 2.90852465e-05, 2.85163120e-05, 2.61436998e-05, 2.29686893e-05, 2.13780821e-05, 2.05679290e-05, + 2.02280114e-05, 2.02033437e-05, 2.61528644e-05, 2.92065564e-05, 2.87325582e-05, 2.68802957e-05, + 2.42346297e-05, 2.31908373e-05, 2.26920020e-05, 2.15275712e-05, 2.01916256e-05, 2.26313939e-05, + 2.59300600e-05, 2.84273464e-05, 2.83651551e-05, 2.80595206e-05, 2.53170229e-05, 2.11561566e-05, + 1.92953980e-05, 1.96592428e-05, 2.67152015e-05, 2.90875171e-05, 2.91474937e-05, 2.73836187e-05, + 2.36683650e-05, 2.04762906e-05, 1.94118975e-05, 1.99722347e-05, 2.69374883e-05, 2.93276233e-05, + 2.95126578e-05, 2.69259545e-05, 2.21709939e-05, 1.94387426e-05, 1.95745607e-05, 2.03432049e-05, + 2.85279545e-05, 2.97933029e-05, 2.94505343e-05, 2.66532500e-05, 2.35428311e-05, 2.12287868e-05, + 2.03489847e-05, 2.69435212e-05, 2.91762154e-05, 2.89681241e-05, 2.71745548e-05, 2.39251298e-05, + 2.09779529e-05, 2.02193122e-05, 2.05079305e-05, 2.64858717e-05, 2.84864580e-05, 2.82640512e-05, + 2.69254214e-05, 2.49763558e-05, 2.31298995e-05, 2.13300654e-05, 2.06087490e-05, 2.59997539e-05, + 2.79553809e-05, 2.78063225e-05, 2.76114420e-05, 2.64804898e-05, 2.38838893e-05, 2.14602650e-05, + 2.03708456e-05, 2.04696302e-05, 2.68443657e-05, 3.06868606e-05, 2.98017355e-05, 2.80577460e-05, + 2.50807986e-05, 2.09243099e-05, 1.98464734e-05, 2.08554594e-05, 2.75108781e-05, 2.97789215e-05, + 2.85437202e-05, 2.58481549e-05, 2.44172163e-05, 2.28469126e-05, 2.11571207e-05, 2.07143531e-05, + 2.65719746e-05, 2.87675815e-05, 2.85277064e-05, 2.71640137e-05, 2.49729701e-05, 2.21353840e-05, + 2.05294231e-05, 2.07278742e-05, 2.56405534e-05, 2.80920802e-05, 2.83617512e-05, 2.74341648e-05, + 2.53782588e-05, 2.29768506e-05, 2.08120589e-05, 2.08852366e-05, 2.12596163e-05, 2.63809037e-05, + 2.90648160e-05, 2.85215939e-05, 2.71753779e-05, 2.43301085e-05, 2.17617542e-05, 1.97438696e-05, + 1.94246001e-05, 2.01854972e-05, 2.81315796e-05, 3.05511634e-05, 2.93795445e-05, 2.64140814e-05, + 2.24797366e-05, 2.11582730e-05, 2.03333897e-05, 1.95749244e-05, 2.59825657e-05, 2.88279591e-05, + 2.92314758e-05, 2.78225567e-05, 2.57989056e-05, 2.31073650e-05, 2.13574261e-05, 2.11960710e-05, + 2.92059388e-05, 3.12059011e-05, 2.86046892e-05, 2.43603716e-05, 2.07842468e-05, 2.06273085e-05, + 2.08949604e-05, 2.63500677e-05, 2.89081970e-05, 2.91658599e-05, 2.78202787e-05, 2.48431681e-05, + 2.25371206e-05, 2.13931885e-05, 2.03047322e-05, 2.33229984e-05, 3.97001900e-05, 4.45443106e-05, + 3.52143899e-05, 2.32755299e-05, 1.47675949e-05, 1.14276362e-05, 1.11805801e-05, 1.13204989e-05, + 2.16050661e-05, 3.04026769e-05, 2.74819727e-05, 2.25299115e-05, 2.17907669e-05, 2.03657243e-05, + 1.51216438e-05, 1.16401141e-05, 1.19390428e-05, 1.24153814e-05, 1.10543020e-05, 2.68487144e-05, + 3.75666531e-05, 3.57923516e-05, 2.50476346e-05, 2.02725603e-05, 1.89108393e-05, 1.35409514e-05, + 9.88906586e-06, 8.95149208e-06, 3.62379531e-05, 6.35816232e-05, 5.09370909e-05, 2.22008606e-05, + 1.21508785e-05, 1.09797182e-05, 1.07180983e-05, 1.00752878e-05, 9.96204383e-06, 2.09904568e-05, + 3.92085241e-05, 4.60390671e-05, 2.76696705e-05, 1.71949071e-05, 1.68422249e-05, 1.72256908e-05, + 1.35958877e-05, 1.03485509e-05, 1.24257887e-05, 2.09203252e-05, 4.51781607e-05, 6.27209884e-05, + 4.52075927e-05, 2.24814864e-05, 1.10162731e-05, 8.51102797e-06, 9.25537484e-06, 3.38720649e-05, + 5.45726006e-05, 4.88663167e-05, 2.88921446e-05, 1.49433449e-05, 9.23036882e-06, 8.14036359e-06, + 9.47873543e-06, 4.02065046e-05, 6.06154317e-05, 4.97257799e-05, 2.68764635e-05, 1.17942320e-05, + 8.06222430e-06, 8.97660714e-06, 1.03004510e-05, 4.51555690e-05, 7.19571756e-05, 4.35621953e-05, + 2.21232943e-05, 1.57373212e-05, 1.30513471e-05, 1.11951143e-05, 2.89316276e-05, 4.01028114e-05, + 4.21207031e-05, 3.52627445e-05, 1.98908248e-05, 1.13211556e-05, 9.99965507e-06, 1.05946609e-05, + 2.64218909e-05, 3.63454592e-05, 3.55921852e-05, 2.81029048e-05, 2.24564456e-05, 1.82504720e-05, + 1.27089966e-05, 1.07829000e-05, 2.42185267e-05, 3.63464752e-05, 3.58097731e-05, 3.11945948e-05, + 2.71575565e-05, 1.91232168e-05, 1.28601611e-05, 1.04019759e-05, 1.05249712e-05, 2.01058632e-05, + 3.98877243e-05, 6.75207906e-05, 5.79323225e-05, 2.94513321e-05, 1.24659346e-05, 9.68484484e-06, + 1.26743382e-05, 3.27178615e-05, 4.56135390e-05, 3.49765423e-05, 2.15629511e-05, 1.86122093e-05, + 1.59519645e-05, 1.18276150e-05, 1.08451270e-05, 1.96899932e-05, 3.42143618e-05, 4.68659433e-05, + 3.36850282e-05, 2.17909017e-05, 1.41463184e-05, 1.09018953e-05, 1.09181583e-05, 2.33874388e-05, + 3.63633229e-05, 3.87549524e-05, 2.90182006e-05, 2.03029839e-05, 1.49885576e-05, 1.08509045e-05, + 1.16390196e-05, 1.32512395e-05, 2.33638686e-05, 4.48753858e-05, 5.77745971e-05, 3.60108092e-05, + 1.78027792e-05, 1.16790351e-05, 8.94896419e-06, 8.67614268e-06, 1.00221341e-05, 2.89467681e-05, + 4.01722190e-05, 4.04051579e-05, 2.58744202e-05, 1.45620956e-05, 1.46174535e-05, 1.23690377e-05, + 9.49335118e-06, 2.69027877e-05, 3.70526481e-05, 3.77907210e-05, 3.33839017e-05, 2.56412503e-05, + 1.51824166e-05, 1.15997028e-05, 1.24154737e-05, 3.49092234e-05, 5.57664913e-05, 4.38749720e-05, + 2.11841178e-05, 1.09720621e-05, 1.07597624e-05, 1.16924467e-05, 2.28036780e-05, 3.51307837e-05, + 4.42820407e-05, 3.84298836e-05, 2.39856767e-05, 1.64792569e-05, 1.28777663e-05, 1.00462788e-05, + 2.46941732e-05, 3.70815656e-05, 4.04497045e-05, 3.31676823e-05, 2.38500011e-05, 1.70277203e-05, + 1.40727360e-05, 1.39442421e-05, 1.42395171e-05, 2.34105076e-05, 3.04570188e-05, 2.82553325e-05, + 2.39901309e-05, 2.33353089e-05, 2.21840737e-05, 1.73854417e-05, 1.41587426e-05, 1.46490457e-05, + 1.52516690e-05, 1.39494432e-05, 2.72656482e-05, 3.52844345e-05, 3.44499073e-05, 2.58231675e-05, + 2.17799511e-05, 2.10281965e-05, 1.63398266e-05, 1.27106502e-05, 1.17424498e-05, 3.44161109e-05, + 5.24661406e-05, 4.46313313e-05, 2.29882942e-05, 1.42007263e-05, 1.35639579e-05, 1.36332452e-05, + 1.29783229e-05, 1.28440562e-05, 2.18082464e-05, 3.52507501e-05, 4.08560207e-05, 2.75591549e-05, + 1.91224346e-05, 1.93742263e-05, 2.01129377e-05, 1.66537616e-05, 1.33478599e-05, 1.46850359e-05, + 2.18813491e-05, 4.05276888e-05, 5.28211614e-05, 4.09267870e-05, 2.38231124e-05, 1.37168341e-05, + 1.13450428e-05, 1.21760287e-05, 3.31347555e-05, 4.65280038e-05, 4.24792824e-05, 2.82630028e-05, + 1.70043322e-05, 1.17745585e-05, 1.07936107e-05, 1.23247337e-05, 3.81758375e-05, 5.02665183e-05, + 4.27081794e-05, 2.68085983e-05, 1.41663318e-05, 1.06767037e-05, 1.18446090e-05, 1.32118679e-05, + 4.04087585e-05, 5.66761456e-05, 3.83197140e-05, 2.25808283e-05, 1.79501413e-05, 1.61695466e-05, + 1.43489899e-05, 2.86390515e-05, 3.59662958e-05, 3.76970676e-05, 3.38985773e-05, 2.21598501e-05, + 1.41837411e-05, 1.28849744e-05, 1.35064085e-05, 2.67211625e-05, 3.36276303e-05, 3.32110596e-05, + 2.79137476e-05, 2.40377373e-05, 2.09492424e-05, 1.56993799e-05, 1.36949194e-05, 2.50181326e-05, + 3.40944402e-05, 3.37882686e-05, 3.00838476e-05, 2.73991493e-05, 2.13829898e-05, 1.58105787e-05, + 1.33282761e-05, 1.34366711e-05, 2.05253000e-05, 3.44802431e-05, 5.40150796e-05, 5.00254636e-05, + 3.06451462e-05, 1.56257216e-05, 1.26536992e-05, 1.59198855e-05, 3.14651391e-05, 3.95066840e-05, + 3.24725339e-05, 2.25638994e-05, 2.05040730e-05, 1.85977532e-05, 1.47172068e-05, 1.37209037e-05, + 2.02818407e-05, 3.16669549e-05, 4.16752577e-05, 3.25807525e-05, 2.33788868e-05, 1.69552433e-05, + 1.38850804e-05, 1.38060197e-05, 2.44778518e-05, 3.39871282e-05, 3.56581883e-05, 2.83350064e-05, + 2.16223987e-05, 1.74403157e-05, 1.36797925e-05, 1.46259442e-05, 1.63934119e-05, 2.39410903e-05, + 3.96645839e-05, 4.93568980e-05, 3.45206073e-05, 1.97088096e-05, 1.42293304e-05, 1.17314331e-05, + 1.15101538e-05, 1.29301888e-05, 2.77460771e-05, 3.48077475e-05, 3.60136290e-05, 2.62694953e-05, + 1.72391406e-05, 1.80901172e-05, 1.58362054e-05, 1.25309389e-05, 2.75477658e-05, 3.38960741e-05, + 3.41275669e-05, 3.17650035e-05, 2.65104531e-05, 1.75836058e-05, 1.43351750e-05, 1.54157394e-05, + 3.18693522e-05, 4.50140562e-05, 3.93729095e-05, 2.31932073e-05, 1.38455566e-05, 1.36564754e-05, + 1.46871292e-05, 2.34290565e-05, 3.22925401e-05, 3.91266480e-05, 3.58987851e-05, 2.56404017e-05, + 1.93795138e-05, 1.58685900e-05, 1.29042152e-05, 2.54422626e-05, 2.51209402e-05, 2.49112868e-05, + 2.46058436e-05, 2.43341428e-05, 2.44410020e-05, 2.43131011e-05, 2.45306524e-05, 2.49299133e-05, + 2.56037579e-05, 2.56156045e-05, 2.57360304e-05, 2.53545635e-05, 2.52747892e-05, 2.52920181e-05, + 2.45524840e-05, 2.40765921e-05, 2.45935936e-05, 2.49927836e-05, 2.48150858e-05, 2.51416597e-05, + 2.49452279e-05, 2.54296000e-05, 2.51106835e-05, 2.47906753e-05, 2.53653916e-05, 2.51860912e-05, + 2.43814683e-05, 2.41114144e-05, 2.50707397e-05, 2.37208448e-05, 2.45216150e-05, 2.43053859e-05, + 2.31703282e-05, 2.40511051e-05, 2.47913521e-05, 2.46291081e-05, 2.45525045e-05, 2.39693256e-05, + 2.38098492e-05, 2.43650718e-05, 2.47236587e-05, 2.45590195e-05, 2.55166592e-05, 2.62290243e-05, + 2.57334495e-05, 2.49258852e-05, 2.37248217e-05, 2.41609367e-05, 2.46010893e-05, 2.42853375e-05, + 2.48995853e-05, 2.51740908e-05, 2.43399347e-05, 2.41555817e-05, 2.45221205e-05, 2.55910999e-05, + 2.40197692e-05, 2.40471736e-05, 2.44507041e-05, 2.41095533e-05, 2.34951447e-05, 2.35635480e-05, + 2.43624498e-05, 2.57446554e-05, 2.36636072e-05, 2.37646541e-05, 2.45541628e-05, 2.37846447e-05, + 2.34334211e-05, 2.43295673e-05, 2.46957093e-05, 2.45199849e-05, 2.28167211e-05, 2.37638089e-05, + 2.38089723e-05, 2.46370178e-05, 2.57439602e-05, 2.54595066e-05, 2.48509971e-05, 2.38730992e-05, + 2.41086093e-05, 2.52872717e-05, 2.58601854e-05, 2.47972775e-05, 2.45685672e-05, 2.47571377e-05, + 2.48811511e-05, 2.42383200e-05, 2.43731715e-05, 2.47485705e-05, 2.55058098e-05, 2.61479947e-05, + 2.53966873e-05, 2.47973987e-05, 2.49136624e-05, 2.46846905e-05, 2.47765997e-05, 2.45374334e-05, + 2.50097935e-05, 2.56501120e-05, 2.53443543e-05, 2.47536199e-05, 2.47425169e-05, 2.30642118e-05, + 2.26909056e-05, 2.30361281e-05, 2.47075443e-05, 2.66759476e-05, 2.57149934e-05, 2.47259469e-05, + 2.59423136e-05, 2.47825710e-05, 2.35459418e-05, 2.40937204e-05, 2.44189024e-05, 2.49161687e-05, + 2.54934692e-05, 2.49749938e-05, 2.47226962e-05, 2.31837880e-05, 2.38466640e-05, 2.45324261e-05, + 2.51746890e-05, 2.53376649e-05, 2.53548974e-05, 2.49947133e-05, 2.47678797e-05, 2.50749603e-05, + 2.45699812e-05, 2.44765549e-05, 2.44232828e-05, 2.45120823e-05, 2.48744008e-05, 2.46102526e-05, + 2.51566936e-05, 2.58358691e-05, 2.43645843e-05, 2.40897979e-05, 2.43591612e-05, 2.53367045e-05, + 2.47035778e-05, 2.41603308e-05, 2.40873746e-05, 2.41828518e-05, 2.46314038e-05, 2.38042064e-05, + 2.28063352e-05, 2.37235326e-05, 2.48502749e-05, 2.51977793e-05, 2.67659566e-05, 2.63738474e-05, + 2.48756696e-05, 2.54352335e-05, 2.40010900e-05, 2.37170352e-05, 2.45731540e-05, 2.53890000e-05, + 2.48316981e-05, 2.45668816e-05, 2.53538885e-05, 2.35438970e-05, 2.24616297e-05, 2.44400037e-05, + 2.57938638e-05, 2.47450752e-05, 2.47551612e-05, 2.51858874e-05, 2.42611321e-05, 2.38040848e-05, + 2.40009178e-05, 2.49148666e-05, 2.59950801e-05, 2.60812157e-05, 2.54349832e-05, 2.45078526e-05, + 2.46393896e-05, 2.15207052e-05, 2.07468389e-05, 2.21244220e-05, 2.43269954e-05, 2.65031345e-05, + 2.75000219e-05, 2.76585985e-05, 2.77467944e-05, 2.50785677e-05, 2.32329999e-05, 2.38339557e-05, + 2.47939717e-05, 2.49415952e-05, 2.52855100e-05, 2.64378279e-05, 2.73460967e-05, 2.74277279e-05, + 2.74067282e-05, 2.77985228e-05, 2.38057969e-05, 2.18199009e-05, 2.22265051e-05, 2.41712253e-05, + 2.51581026e-05, 2.56689831e-05, 2.71149052e-05, 2.80562102e-05, 2.83028907e-05, 2.20676151e-05, + 1.81175259e-05, 1.97885249e-05, 2.45577316e-05, 2.68477572e-05, 2.75582750e-05, 2.79059798e-05, + 2.80760158e-05, 2.80898851e-05, 2.47294034e-05, 2.12810485e-05, 2.04168573e-05, 2.35264271e-05, + 2.58660605e-05, 2.62599617e-05, 2.63629055e-05, 2.72696430e-05, 2.80804324e-05, 2.69653475e-05, + 2.48073190e-05, 2.05895193e-05, 1.83106215e-05, 2.06490848e-05, 2.47535244e-05, 2.76480903e-05, + 2.84850653e-05, 2.83359610e-05, 2.25950600e-05, 1.92266394e-05, 1.99626447e-05, 2.32127831e-05, + 2.63398406e-05, 2.79720445e-05, 2.84091274e-05, 2.81978750e-05, 2.15759719e-05, 1.84408358e-05, + 1.97874671e-05, 2.36365296e-05, 2.71906596e-05, 2.83901026e-05, 2.83716206e-05, 2.80191996e-05, + 2.05750252e-05, 1.70789616e-05, 2.06265992e-05, 2.44181331e-05, 2.62905163e-05, 2.74431725e-05, + 2.79626839e-05, 2.33155002e-05, 2.11611446e-05, 2.09184920e-05, 2.22829940e-05, 2.55653074e-05, + 2.77020540e-05, 2.80820264e-05, 2.79371818e-05, 2.38209454e-05, 2.18436443e-05, 2.20020992e-05, + 2.34481876e-05, 2.48533388e-05, 2.60657094e-05, 2.74432161e-05, 2.78856373e-05, 2.42930998e-05, + 2.19560700e-05, 2.20675719e-05, 2.28079370e-05, 2.37074523e-05, 2.56983477e-05, 2.73784192e-05, + 2.80032987e-05, 2.79564801e-05, 2.46321701e-05, 2.08763255e-05, 1.75709886e-05, 1.89433442e-05, + 2.36671976e-05, 2.76214692e-05, 2.82495197e-05, 2.76241961e-05, 2.25995430e-05, 2.02868618e-05, + 2.20312585e-05, 2.47387824e-05, 2.56091508e-05, 2.65002723e-05, 2.75925392e-05, 2.78388242e-05, + 2.47729658e-05, 2.20919652e-05, 2.03382831e-05, 2.25280201e-05, 2.49596129e-05, 2.69839606e-05, + 2.79109747e-05, 2.78291022e-05, 2.45213905e-05, 2.19248313e-05, 2.15182716e-05, 2.31810687e-05, + 2.50647106e-05, 2.65816078e-05, 2.77983780e-05, 2.77149470e-05, 2.74084062e-05, 2.43168842e-05, + 2.05178511e-05, 1.89012210e-05, 2.21681620e-05, 2.57518182e-05, 2.73629046e-05, 2.82951483e-05, + 2.84321583e-05, 2.80957404e-05, 2.30160302e-05, 2.08669375e-05, 2.10776398e-05, 2.39248081e-05, + 2.68101405e-05, 2.72603297e-05, 2.78526294e-05, 2.83703644e-05, 2.38734567e-05, 2.16680164e-05, + 2.14764632e-05, 2.24284957e-05, 2.41222748e-05, 2.65117513e-05, 2.75305309e-05, 2.75238875e-05, + 2.18922158e-05, 1.87464106e-05, 2.07402753e-05, 2.52314798e-05, 2.78029001e-05, 2.78792888e-05, + 2.77066938e-05, 2.44088350e-05, 2.19276148e-05, 2.05809841e-05, 2.16741544e-05, 2.46411340e-05, + 2.65265631e-05, 2.74016233e-05, 2.80443146e-05, 2.50778002e-05, 2.42273238e-05, 2.38898312e-05, + 2.48577635e-05, 2.56126889e-05, 2.52748021e-05, 2.48086823e-05, 2.46531777e-05, 2.45013133e-05, + 2.50210085e-05, 2.46893607e-05, 2.47911987e-05, 2.51326192e-05, 2.51774533e-05, 2.51663345e-05, + 2.52589633e-05, 2.49634126e-05, 2.47852387e-05, 2.46899538e-05, 2.44932545e-05, 2.51102213e-05, + 2.44989578e-05, 2.43984416e-05, 2.51933426e-05, 2.54041716e-05, 2.51043309e-05, 2.47778617e-05, + 2.43828399e-05, 2.41972104e-05, 2.45437482e-05, 2.25508178e-05, 2.34601347e-05, 2.56399023e-05, + 2.54865062e-05, 2.48269530e-05, 2.44225123e-05, 2.43240938e-05, 2.43262392e-05, 2.58028448e-05, + 2.49379686e-05, 2.40300985e-05, 2.52773419e-05, 2.54137996e-05, 2.49428012e-05, 2.46308804e-05, + 2.45324611e-05, 2.42646580e-05, 2.52791011e-05, 2.57106830e-05, 2.39901851e-05, 2.23340549e-05, + 2.38322102e-05, 2.52198269e-05, 2.47025958e-05, 2.40095959e-05, 2.41167465e-05, 2.44649375e-05, + 2.33516219e-05, 2.39192289e-05, 2.53500557e-05, 2.54484329e-05, 2.45779632e-05, 2.41255158e-05, + 2.42637416e-05, 2.38638001e-05, 2.29033239e-05, 2.39822927e-05, 2.53958171e-05, 2.51304954e-05, + 2.41508440e-05, 2.41068561e-05, 2.43567346e-05, 2.40344918e-05, 2.21354687e-05, 2.45758654e-05, + 2.58792112e-05, 2.52754610e-05, 2.44488750e-05, 2.42308064e-05, 2.51510843e-05, 2.48292184e-05, + 2.45299268e-05, 2.45116083e-05, 2.48906947e-05, 2.45623507e-05, 2.43298998e-05, 2.44067735e-05, + 2.52551155e-05, 2.49550518e-05, 2.49457904e-05, 2.52441894e-05, 2.50609654e-05, 2.47140459e-05, + 2.45541401e-05, 2.44359132e-05, 2.53125804e-05, 2.47298034e-05, 2.47258287e-05, 2.51734416e-05, + 2.51609736e-05, 2.49752362e-05, 2.46029011e-05, 2.43577491e-05, 2.43953802e-05, 2.62268596e-05, + 2.54502318e-05, 2.24998300e-05, 2.26243887e-05, 2.42250219e-05, 2.43666306e-05, 2.41634037e-05, + 2.42977052e-05, 2.49510450e-05, 2.44969374e-05, 2.51329928e-05, 2.55883306e-05, 2.53078373e-05, + 2.48920646e-05, 2.45874744e-05, 2.44854811e-05, 2.61617311e-05, 2.53129108e-05, 2.38623290e-05, + 2.46868095e-05, 2.51473587e-05, 2.47783774e-05, 2.43746910e-05, 2.44825176e-05, 2.52534150e-05, + 2.47863328e-05, 2.46371686e-05, 2.53568438e-05, 2.55374282e-05, 2.50952705e-05, 2.45384748e-05, + 2.44656089e-05, 2.44365492e-05, 2.55964511e-05, 2.42844956e-05, 2.28301479e-05, 2.44278364e-05, + 2.53765267e-05, 2.49328174e-05, 2.42072621e-05, 2.40617859e-05, 2.43077202e-05, 2.56653020e-05, + 2.53674112e-05, 2.48794073e-05, 2.52913153e-05, 2.48995416e-05, 2.41798285e-05, 2.40483047e-05, + 2.40346946e-05, 2.49646665e-05, 2.50186600e-05, 2.51028017e-05, 2.50089610e-05, 2.50380641e-05, + 2.51343066e-05, 2.47285798e-05, 2.45236754e-05, 2.54139747e-05, 2.40618378e-05, 2.41973386e-05, + 2.49311910e-05, 2.45059095e-05, 2.44495126e-05, 2.44632331e-05, 2.56549973e-05, 2.52669018e-05, + 2.43864083e-05, 2.44419389e-05, 2.47967025e-05, 2.46557027e-05, 2.45639569e-05, 2.43711827e-05, + 2.49979802e-05, 2.40842569e-05, 2.37302201e-05, 2.49634294e-05, 2.59202434e-05, 2.54277573e-05, + 2.48573732e-05, 2.46131124e-05, 2.43370565e-05, 2.48841519e-05, 2.45114225e-05, 2.45986662e-05, + 2.50816125e-05, 2.51514980e-05, 2.51269336e-05, 2.53838586e-05, 2.51065860e-05, 2.47670249e-05, + 2.45622493e-05, 2.43509125e-05, 2.51212310e-05, 2.44504583e-05, 2.42143152e-05, 2.52234106e-05, + 2.55365983e-05, 2.50265338e-05, 2.46343807e-05, 2.43043089e-05, 2.41297513e-05, 2.44732454e-05, + 2.23928010e-05, 2.33050328e-05, 2.59561554e-05, 2.59887505e-05, 2.49383511e-05, 2.42669066e-05, + 2.41775649e-05, 2.41965355e-05, 2.62373917e-05, 2.52652955e-05, 2.40278313e-05, 2.54284451e-05, + 2.55869097e-05, 2.47830107e-05, 2.42499665e-05, 2.42145553e-05, 2.40408296e-05, 2.55909668e-05, + 2.60738388e-05, 2.39234533e-05, 2.20072461e-05, 2.36639754e-05, 2.52300423e-05, 2.47168982e-05, + 2.38851748e-05, 2.39406125e-05, 2.42542544e-05, 2.32906943e-05, 2.39705045e-05, 2.55885839e-05, + 2.57249515e-05, 2.47479771e-05, 2.41610783e-05, 2.41588158e-05, 2.35084877e-05, 2.28316533e-05, + 2.41158316e-05, 2.56126314e-05, 2.53861334e-05, 2.42223524e-05, 2.39693367e-05, 2.42044351e-05, + 2.39960294e-05, 2.20967843e-05, 2.48374666e-05, 2.63794545e-05, 2.53881243e-05, 2.41069830e-05, + 2.38897574e-05, 2.52471128e-05, 2.51169537e-05, 2.46944426e-05, 2.43825082e-05, 2.46597144e-05, + 2.44417353e-05, 2.41977095e-05, 2.42543234e-05, 2.53588343e-05, 2.51743760e-05, 2.51284016e-05, + 2.53831902e-05, 2.49590669e-05, 2.43737748e-05, 2.43082726e-05, 2.42824821e-05, 2.54129399e-05, + 2.47905635e-05, 2.47628144e-05, 2.53570104e-05, 2.52154918e-05, 2.48054704e-05, 2.43803915e-05, + 2.41935017e-05, 2.42430888e-05, 2.70029626e-05, 2.61965565e-05, 2.24883624e-05, 2.22625968e-05, + 2.37194009e-05, 2.40092133e-05, 2.39559232e-05, 2.38787005e-05, 2.50293792e-05, 2.47971246e-05, + 2.54262092e-05, 2.58610257e-05, 2.53791372e-05, 2.47208480e-05, 2.44363215e-05, 2.43605815e-05, + 2.68860972e-05, 2.57089221e-05, 2.37859841e-05, 2.46175065e-05, 2.51001280e-05, 2.46012859e-05, + 2.41644476e-05, 2.43473202e-05, 2.52985244e-05, 2.48870684e-05, 2.47315880e-05, 2.56041140e-05, + 2.57687542e-05, 2.51051830e-05, 2.44512144e-05, 2.42453178e-05, 2.40736599e-05, 2.58929636e-05, + 2.44021744e-05, 2.25854340e-05, 2.42713295e-05, 2.55097368e-05, 2.50489805e-05, 2.41476154e-05, + 2.39445545e-05, 2.41565393e-05, 2.61419563e-05, 2.60620060e-05, 2.52167975e-05, 2.54086071e-05, + 2.47877030e-05, 2.35789076e-05, 2.34857609e-05, 2.37641155e-05, 2.48757165e-05, 2.53128360e-05, + 2.54897190e-05, 2.51522422e-05, 2.49711663e-05, 2.51644846e-05, 2.47008386e-05, 2.42784204e-05, + 2.59137934e-05, 2.45442769e-05, 2.42112889e-05, 2.47300741e-05, 2.43815831e-05, 2.43084685e-05, + 2.42363629e-05, 2.59887463e-05, 2.56649695e-05, 2.45476609e-05, 2.43897623e-05, 2.45346303e-05, + 2.43074036e-05, 2.43130226e-05, 2.42625075e-05, 2.52524577e-05, 2.83227237e-05, 2.88860250e-05, + 2.84912152e-05, 2.64022259e-05, 2.28280725e-05, 2.08313391e-05, 2.04681024e-05, 2.02416550e-05, + 2.45785297e-05, 2.66285689e-05, 2.59533011e-05, 2.51118718e-05, 2.49655553e-05, 2.44752122e-05, + 2.29160560e-05, 2.11871986e-05, 2.09559249e-05, 2.09376679e-05, 2.01413258e-05, 2.64543917e-05, + 2.83447023e-05, 2.75842675e-05, 2.60587328e-05, 2.49419512e-05, 2.38697737e-05, 2.14688052e-05, + 1.95739349e-05, 1.89595008e-05, 2.80553232e-05, 3.05056947e-05, 2.95743892e-05, 2.61003972e-05, + 2.23610760e-05, 2.07184810e-05, 1.99082060e-05, 1.95309504e-05, 1.94986974e-05, 2.60491627e-05, + 2.99211562e-05, 2.96546481e-05, 2.70942967e-05, 2.39269224e-05, 2.28685495e-05, 2.23930594e-05, + 2.10361640e-05, 1.95150483e-05, 2.20481182e-05, 2.58215972e-05, 2.93110952e-05, 2.97257477e-05, + 2.89302766e-05, 2.52812335e-05, 2.05039634e-05, 1.85069440e-05, 1.89172340e-05, 2.71685567e-05, + 3.02732024e-05, 3.01722215e-05, 2.76578293e-05, 2.32332416e-05, 1.97089691e-05, 1.85896358e-05, + 1.92380929e-05, 2.76128853e-05, 3.06861662e-05, 3.05786730e-05, 2.71066580e-05, 2.15525229e-05, + 1.86091063e-05, 1.88138057e-05, 1.96594077e-05, 2.94148272e-05, 3.14552163e-05, 3.03214234e-05, + 2.66100628e-05, 2.31559809e-05, 2.07088233e-05, 1.97269539e-05, 2.72112750e-05, 2.99209664e-05, + 2.97739061e-05, 2.76894615e-05, 2.37590367e-05, 2.03506760e-05, 1.95169884e-05, 1.98409696e-05, + 2.66403548e-05, 2.90765034e-05, 2.88202809e-05, 2.71584497e-05, 2.49371083e-05, 2.28822634e-05, + 2.07870283e-05, 1.99525964e-05, 2.60503657e-05, 2.85302826e-05, 2.83578040e-05, 2.79838687e-05, + 2.66664461e-05, 2.36793979e-05, 2.09245530e-05, 1.96935945e-05, 1.97986763e-05, 2.66978800e-05, + 3.14760265e-05, 3.13589652e-05, 2.92831136e-05, 2.53366583e-05, 2.03731433e-05, 1.91311343e-05, + 2.03185922e-05, 2.79402652e-05, 3.07289599e-05, 2.90848369e-05, 2.57714581e-05, 2.41859467e-05, + 2.24776874e-05, 2.05602240e-05, 2.00600980e-05, 2.64017898e-05, 2.92858609e-05, 2.94669525e-05, + 2.76213877e-05, 2.49023191e-05, 2.16687449e-05, 1.98833570e-05, 2.00783898e-05, 2.56495818e-05, + 2.86714644e-05, 2.90334371e-05, 2.77145744e-05, 2.52360007e-05, 2.25509290e-05, 2.01559718e-05, + 2.02812894e-05, 2.07514100e-05, 2.63956137e-05, 2.99634097e-05, 2.97656670e-05, 2.77167991e-05, + 2.40555916e-05, 2.11430569e-05, 1.89758765e-05, 1.86450818e-05, 1.94856884e-05, 2.84223719e-05, + 3.13458106e-05, 3.01416495e-05, 2.65436875e-05, 2.20337736e-05, 2.07315770e-05, 1.97873182e-05, + 1.88531069e-05, 2.61504098e-05, 2.94537374e-05, 2.98963424e-05, 2.82848123e-05, 2.59104530e-05, + 2.26916525e-05, 2.07412571e-05, 2.06367383e-05, 2.97628749e-05, 3.25286506e-05, 2.94542138e-05, + 2.42579955e-05, 2.01372248e-05, 1.99691082e-05, 2.02943588e-05, 2.63377097e-05, 2.94652125e-05, + 3.00493727e-05, 2.84640612e-05, 2.48722703e-05, 2.21993184e-05, 2.08597021e-05, 1.96035838e-05, + 2.52413918e-05, 2.81989573e-05, 2.87334565e-05, 2.84255923e-05, 2.64393577e-05, 2.29098979e-05, + 2.09283752e-05, 2.05572337e-05, 2.03157552e-05, 2.45731400e-05, 2.65569566e-05, 2.58993343e-05, + 2.51100468e-05, 2.49721697e-05, 2.44907846e-05, 2.29917706e-05, 2.12931929e-05, 2.10411411e-05, + 2.10065319e-05, 2.02201383e-05, 2.64298823e-05, 2.82453388e-05, 2.74781464e-05, 2.60489478e-05, + 2.49789977e-05, 2.38918291e-05, 2.15264155e-05, 1.96697446e-05, 1.90644775e-05, 2.79609574e-05, + 3.02630454e-05, 2.93896887e-05, 2.61461575e-05, 2.25045124e-05, 2.08263038e-05, 1.99884346e-05, + 1.96177029e-05, 1.95882668e-05, 2.61182837e-05, 2.98617169e-05, 2.95147371e-05, 2.70818709e-05, + 2.39921243e-05, 2.28972225e-05, 2.23930875e-05, 2.10736202e-05, 1.95909739e-05, 2.21671698e-05, + 2.58823147e-05, 2.91672285e-05, 2.94645831e-05, 2.87730717e-05, 2.52872120e-05, 2.06005634e-05, + 1.86094968e-05, 1.90078243e-05, 2.70708281e-05, 3.00834917e-05, 3.00250189e-05, 2.76485374e-05, + 2.33282524e-05, 1.98377033e-05, 1.87125479e-05, 1.93345082e-05, 2.74593629e-05, 3.04677536e-05, + 3.04382335e-05, 2.71078169e-05, 2.16701334e-05, 1.87365480e-05, 1.89109718e-05, 1.97435908e-05, + 2.92747764e-05, 3.11949914e-05, 3.02296026e-05, 2.66794898e-05, 2.32253745e-05, 2.07482672e-05, + 1.97826519e-05, 2.71835901e-05, 2.98512887e-05, 2.96768083e-05, 2.75934889e-05, 2.37554120e-05, + 2.04296240e-05, 1.96059626e-05, 1.99226069e-05, 2.66303154e-05, 2.90190358e-05, 2.87624203e-05, + 2.71416334e-05, 2.49296531e-05, 2.28787180e-05, 2.08401335e-05, 2.00325086e-05, 2.60550697e-05, + 2.84521461e-05, 2.82797698e-05, 2.79528733e-05, 2.66452846e-05, 2.36889241e-05, 2.09789859e-05, + 1.97755907e-05, 1.98809300e-05, 2.68163499e-05, 3.14700387e-05, 3.11198205e-05, 2.90385504e-05, + 2.52313707e-05, 2.04159293e-05, 1.92146073e-05, 2.03527541e-05, 2.78862771e-05, 3.06316909e-05, + 2.90451009e-05, 2.58163393e-05, 2.42280844e-05, 2.25122212e-05, 2.06314483e-05, 2.01426334e-05, + 2.65165780e-05, 2.92641938e-05, 2.93130386e-05, 2.75426183e-05, 2.49063558e-05, 2.17174746e-05, + 1.99559759e-05, 2.01591596e-05, 2.56533302e-05, 2.85984097e-05, 2.89457555e-05, 2.77055897e-05, + 2.52849081e-05, 2.26142726e-05, 2.02426334e-05, 2.03464324e-05, 2.07867919e-05, 2.64307454e-05, + 2.98454394e-05, 2.95369908e-05, 2.76128554e-05, 2.41113431e-05, 2.12456582e-05, 1.90817239e-05, + 1.87470046e-05, 1.95723883e-05, 2.84435258e-05, 3.13311254e-05, 3.00769643e-05, 2.65390657e-05, + 2.20865220e-05, 2.07287243e-05, 1.98084388e-05, 1.89314186e-05, 2.61131373e-05, 2.94020545e-05, + 2.98528124e-05, 2.82350863e-05, 2.58845786e-05, 2.27557952e-05, 2.08282438e-05, 2.06924265e-05, + 2.97509562e-05, 3.24080286e-05, 2.93278165e-05, 2.42480706e-05, 2.02187390e-05, 2.00505877e-05, + 2.03583115e-05, 2.63814204e-05, 2.94384324e-05, 2.99403189e-05, 2.83592267e-05, 2.48343938e-05, + 2.22091826e-05, 2.09107975e-05, 1.96947399e-05}; diff --git a/accelerators/stratus_hls/sinkhorn_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/sinkhorn_stratus/hw/tb/sc_main.cpp index b562f24802..3e547360d7 100644 --- a/accelerators/stratus_hls/sinkhorn_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/sinkhorn_stratus/hw/tb/sc_main.cpp @@ -5,54 +5,55 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; - -uint32_t p_rows = 229; -uint32_t q_cols = 177; -uint32_t m_rows = 3; -float gamma_sink = 1.6; -uint32_t maxiter = 10; -uint32_t p2p_in = 0; -uint32_t p2p_out = 0; -uint32_t p2p_iter = 0; +system_t *testbench = NULL; + +uint32_t p_rows = 229; +uint32_t q_cols = 177; +uint32_t m_rows = 3; +float gamma_sink = 1.6; +uint32_t maxiter = 10; +uint32_t p2p_in = 0; +uint32_t p2p_out = 0; +uint32_t p2p_iter = 0; uint32_t store_state = 0; extern void esc_elaborate() { // Creating the whole system - testbench = new system_t("testbench", p_rows, q_cols, m_rows, gamma_sink, maxiter, p2p_in, p2p_out, p2p_iter, store_state); + testbench = new system_t("testbench", p_rows, q_cols, m_rows, gamma_sink, maxiter, p2p_in, + p2p_out, p2p_iter, store_state); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); - esc_cleanup(); + esc_log_pass(); + esc_cleanup(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/sinkhorn_stratus/sw/baremetal/sinkhorn.c b/accelerators/stratus_hls/sinkhorn_stratus/sw/baremetal/sinkhorn.c index db18736240..7c69f6ba82 100644 --- a/accelerators/stratus_hls/sinkhorn_stratus/sw/baremetal/sinkhorn.c +++ b/accelerators/stratus_hls/sinkhorn_stratus/sw/baremetal/sinkhorn.c @@ -3,7 +3,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -12,24 +12,20 @@ typedef int32_t token_t; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} - +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } #define SLD_SINKHORN 0x144 -#define DEV_NAME "sld,sinkhorn_stratus" +#define DEV_NAME "sld,sinkhorn_stratus" /* <<--params-->> */ -const int32_t maxiter = 150; -const float gamma_float = 1.6; -const int32_t q_cols = 177; -const int32_t m_rows = 3; -const int32_t p_rows = 229; -const int32_t p2p_in = 0; -const int32_t p2p_out = 0; -const int32_t p2p_iter = 1; +const int32_t maxiter = 150; +const float gamma_float = 1.6; +const int32_t q_cols = 177; +const int32_t m_rows = 3; +const int32_t p_rows = 229; +const int32_t p2p_in = 0; +const int32_t p2p_out = 0; +const int32_t p2p_iter = 1; const int32_t store_state = 0; static unsigned inX_words_adj; @@ -50,272 +46,257 @@ static int32_t gamma_fixed; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ #define SINKHORN_STORE_STATE_REG 0x60 -#define SINKHORN_P2P_ITER_REG 0x5C -#define SINKHORN_P2P_OUT_REG 0x58 -#define SINKHORN_P2P_IN_REG 0x54 -#define SINKHORN_MAXITER_REG 0x50 -#define SINKHORN_GAMMA_REG 0x4c -#define SINKHORN_Q_COLS_REG 0x44 -#define SINKHORN_M_ROWS_REG 0x48 -#define SINKHORN_P_ROWS_REG 0x40 - +#define SINKHORN_P2P_ITER_REG 0x5C +#define SINKHORN_P2P_OUT_REG 0x58 +#define SINKHORN_P2P_IN_REG 0x54 +#define SINKHORN_MAXITER_REG 0x50 +#define SINKHORN_GAMMA_REG 0x4c +#define SINKHORN_Q_COLS_REG 0x44 +#define SINKHORN_M_ROWS_REG 0x48 +#define SINKHORN_P_ROWS_REG 0x40 static int validate_buf(token_t *out, token_t *gold) { - int i; - int j; - float sum = 0; - unsigned errors = 0; - - for (i = 0; i < 1; i++) - { - for (j = 0; j < p_rows * q_cols + 1; j++) - { - float val = fixed32_to_float(out[i * out_words_adj + j], 11); - if (j < p_rows * q_cols) // P sum - { - //print_uart_int(out[i * out_words_adj + j]);print_uart("\n"); - sum += val; - } - else - { - float CP_val = fixed32_to_float(gold[i * out_words_adj + j],11); - if (CP_val != val) // CP_sum - { - float CP_error = 100*(CP_val-val)/CP_val; - printf("CP_sum is: %d\n", out[i * out_words_adj + j]); - printf("Expected CP_sum is: %d\n", gold[i * out_words_adj + j]); - if (CP_error > 3 || CP_error < -3) - { - printf("CP error is bigger than 3 percent\n"); - errors++; - } - else - printf("CP error is smaller than 3 percent - Passed.\n"); - } - } - } - - if (sum != 1.0) - { - float P_error = 100*(1.0-sum)/1.0; - int32_t sum_fixed = float_to_fixed32(sum, 11); - int32_t sum_expected = float_to_fixed32(1.0, 11); - printf("P sum is: %d\n", sum_fixed); - printf("Expected P sum is: %d\n", sum_expected); - if (P_error > 3) - { - printf("P error is bigger than 3 percent"); - errors++; - } - } - } - - return errors; + int i; + int j; + float sum = 0; + unsigned errors = 0; + + for (i = 0; i < 1; i++) { + for (j = 0; j < p_rows * q_cols + 1; j++) { + float val = fixed32_to_float(out[i * out_words_adj + j], 11); + if (j < p_rows * q_cols) // P sum + { + // print_uart_int(out[i * out_words_adj + j]);print_uart("\n"); + sum += val; + } + else { + float CP_val = fixed32_to_float(gold[i * out_words_adj + j], 11); + if (CP_val != val) // CP_sum + { + float CP_error = 100 * (CP_val - val) / CP_val; + printf("CP_sum is: %d\n", out[i * out_words_adj + j]); + printf("Expected CP_sum is: %d\n", gold[i * out_words_adj + j]); + if (CP_error > 3 || CP_error < -3) { + printf("CP error is bigger than 3 percent\n"); + errors++; + } + else + printf("CP error is smaller than 3 percent - Passed.\n"); + } + } + } + + if (sum != 1.0) { + float P_error = 100 * (1.0 - sum) / 1.0; + int32_t sum_fixed = float_to_fixed32(sum, 11); + int32_t sum_expected = float_to_fixed32(1.0, 11); + printf("P sum is: %d\n", sum_fixed); + printf("Expected P sum is: %d\n", sum_expected); + if (P_error > 3) { + printf("P error is bigger than 3 percent"); + errors++; + } + } + } + + return errors; } - -static void init_buf (token_t *in, token_t * gold) +static void init_buf(token_t *in, token_t *gold) { #include "input.h" - int i; - int j; - int k; + int i; + int j; + int k; - printf("Initializing buffer\n"); + printf("Initializing buffer\n"); - //inX_len = round_up(p_rows * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - //inY_len = round_up(q_cols * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + // inX_len = round_up(p_rows * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + // inY_len = round_up(q_cols * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - for (i = 0; i < 1; i++) - { - for (j = 0; j < p_rows * m_rows; j++) - { - //print_uart_int(j); print_uart("\n"); - in[i * inX_words_adj + j] = (token_t) float_to_fixed32(inputX[j], 11); - } + for (i = 0; i < 1; i++) { + for (j = 0; j < p_rows * m_rows; j++) { + // print_uart_int(j); print_uart("\n"); + in[i * inX_words_adj + j] = (token_t)float_to_fixed32(inputX[j], 11); + } - //j = inX_len; + // j = inX_len; - printf("Finished loading X\n"); + printf("Finished loading X\n"); - for (k = 0; k < q_cols * m_rows; k++) - { - //print_uart_int(k); print_uart("\n"); - in[i * inY_words_adj + j + k] = float_to_fixed32(inputY[k], 11); - } + for (k = 0; k < q_cols * m_rows; k++) { + // print_uart_int(k); print_uart("\n"); + in[i * inY_words_adj + j + k] = float_to_fixed32(inputY[k], 11); + } - printf("Finished loading Y\n"); - } + printf("Finished loading Y\n"); + } - gold[p_rows * q_cols] = (token_t) float_to_fixed32(0.868033, 11); + gold[p_rows * q_cols] = (token_t)float_to_fixed32(0.868033, 11); - /* for (i = 0; i < 1; i++) */ - /* for (j = 0; j < /\*p_rows * q_cols + 1*\/5; j++) */ - /* { */ - /* print_uart_int(j); print_uart("\n"); */ - /* gold[i * out_words_adj + j] = 0; */ - /* if (j == p_rows * q_cols) //CP_sum */ - /* gold[i * out_words_adj + j] = (token_t) float_to_fixed32(0.868033, 11); */ - /* } */ + /* for (i = 0; i < 1; i++) */ + /* for (j = 0; j < /\*p_rows * q_cols + 1*\/5; j++) */ + /* { */ + /* print_uart_int(j); print_uart("\n"); */ + /* gold[i * out_words_adj + j] = 0; */ + /* if (j == p_rows * q_cols) //CP_sum */ + /* gold[i * out_words_adj + j] = (token_t) float_to_fixed32(0.868033, 11); */ + /* } */ - printf("Finished initialization\n"); + printf("Finished initialization\n"); } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable; - token_t *mem; - token_t *gold; - unsigned errors = 0; - unsigned coherence; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - inX_words_adj = p_rows * m_rows; - inY_words_adj = q_cols * m_rows; - in_words_adj = inX_words_adj + inY_words_adj; - out_words_adj = p_rows * q_cols + 1; - } else { - inX_words_adj = round_up(p_rows * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - inY_words_adj = round_up(q_cols * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - in_words_adj = round_up((p_rows+q_cols) * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(p_rows * q_cols + 1, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - inX_len = inX_words_adj * (1); - inY_len = inY_words_adj * (1); - in_len = in_words_adj * (1); - out_len = out_words_adj * (1); - inX_size = inX_len * sizeof(token_t); - inY_size = inY_len * sizeof(token_t); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - gamma_fixed = float_to_fixed32(gamma_float, 11); - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_SINKHORN, DEV_NAME); - if (ndev == 0) { - printf("sinkhorn not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - printf("**************** %s.%d ****************\n", DEV_NAME, n); - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_size); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - - // Alocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable; + token_t *mem; + token_t *gold; + unsigned errors = 0; + unsigned coherence; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + inX_words_adj = p_rows * m_rows; + inY_words_adj = q_cols * m_rows; + in_words_adj = inX_words_adj + inY_words_adj; + out_words_adj = p_rows * q_cols + 1; + } + else { + inX_words_adj = round_up(p_rows * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + inY_words_adj = round_up(q_cols * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + in_words_adj = round_up((p_rows + q_cols) * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(p_rows * q_cols + 1, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + inX_len = inX_words_adj * (1); + inY_len = inY_words_adj * (1); + in_len = in_words_adj * (1); + out_len = out_words_adj * (1); + inX_size = inX_len * sizeof(token_t); + inY_size = inY_len * sizeof(token_t); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + gamma_fixed = float_to_fixed32(gamma_float, 11); + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_SINKHORN, DEV_NAME); + if (ndev == 0) { + printf("sinkhorn not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + printf("**************** %s.%d ****************\n", DEV_NAME, n); + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_size); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); + + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - printf(" --------------------\n"); - printf(" Generate input...\n"); - init_buf(mem, gold); - - // Pass common configuration parameters - - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); - - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - iowrite32(dev, SINKHORN_MAXITER_REG, maxiter); - iowrite32(dev, SINKHORN_GAMMA_REG, gamma_fixed); - iowrite32(dev, SINKHORN_Q_COLS_REG, q_cols); - iowrite32(dev, SINKHORN_M_ROWS_REG, m_rows); - iowrite32(dev, SINKHORN_P_ROWS_REG, p_rows); - iowrite32(dev, SINKHORN_P2P_OUT_REG, p2p_out); - iowrite32(dev, SINKHORN_P2P_IN_REG, p2p_in); - iowrite32(dev, SINKHORN_P2P_ITER_REG, p2p_iter); - iowrite32(dev, SINKHORN_STORE_STATE_REG, store_state); - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + printf(" --------------------\n"); + printf(" Generate input...\n"); + init_buf(mem, gold); + + // Pass common configuration parameters + + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); + + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + iowrite32(dev, SINKHORN_MAXITER_REG, maxiter); + iowrite32(dev, SINKHORN_GAMMA_REG, gamma_fixed); + iowrite32(dev, SINKHORN_Q_COLS_REG, q_cols); + iowrite32(dev, SINKHORN_M_ROWS_REG, m_rows); + iowrite32(dev, SINKHORN_P_ROWS_REG, p_rows); + iowrite32(dev, SINKHORN_P2P_OUT_REG, p2p_out); + iowrite32(dev, SINKHORN_P2P_IN_REG, p2p_in); + iowrite32(dev, SINKHORN_P2P_ITER_REG, p2p_iter); + iowrite32(dev, SINKHORN_STORE_STATE_REG, store_state); + + // Flush (customize coherence model here) + esp_flush(coherence); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/app/c_run.cpp b/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/app/c_run.cpp index 08748f46da..4a33bce5c5 100644 --- a/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/app/c_run.cpp +++ b/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/app/c_run.cpp @@ -1,458 +1,422 @@ #include "c_run.h" #include "eigen/Eigen/Dense" #include "eigen/Eigen/SVD" -#include +#include "total.h" #include -#include #include -#include "total.h" +#include +#include using namespace Eigen; using namespace std; extern "C" { - MatrixXf P, K3, K3_t, b2, a2, C3; - ArrayXXf C2, K2, CP; - VectorXf a3, b3; - Matrix3f R; - - float c_run_hiwa(unsigned p, unsigned q, float* X, float* Y, - float gamma, unsigned maxiter, float outputX[], - float outputY[], float C[], float K[], float a[], float b[]) - { +MatrixXf P, K3, K3_t, b2, a2, C3; +ArrayXXf C2, K2, CP; +VectorXf a3, b3; +Matrix3f R; - unsigned m = 3; - - for(unsigned i = 0; i < m; i++) - for(unsigned j = 0 ; j < p; j++) - { - outputX[j] += pow(X[i * p + j], 2); - } +float c_run_hiwa(unsigned p, unsigned q, float *X, float *Y, float gamma, unsigned maxiter, + float outputX[], float outputY[], float C[], float K[], float a[], float b[]) +{ + unsigned m = 3; - for(unsigned i = 0; i < m; i++) - for(unsigned j = 0 ; j < q; j++) - { - outputY[j] += pow(Y[i * q + j], 2); - } + for (unsigned i = 0; i < m; i++) + for (unsigned j = 0; j < p; j++) { + outputX[j] += pow(X[i * p + j], 2); + } + for (unsigned i = 0; i < m; i++) + for (unsigned j = 0; j < q; j++) { + outputY[j] += pow(Y[i * q + j], 2); + } - reshape_to_C_mat_with_R2(outputY, outputX, Y, X, q, p, C); + reshape_to_C_mat_with_R2(outputY, outputX, Y, X, q, p, C); - C2 = Map >(C); - K2 = C2 / (-1 * gamma); - K2 = K2.exp(); - K3 = K2.matrix(); - K3_t = K3.transpose(); + C2 = Map>(C); + K2 = C2 / (-1 * gamma); + K2 = K2.exp(); + K3 = K2.matrix(); + K3_t = K3.transpose(); - //Initializing b - for(unsigned i = 0; i < q; i++) - { - b[i] = 1.0 / (float)q; - } + // Initializing b + for (unsigned i = 0; i < q; i++) { + b[i] = 1.0 / (float)q; + } - b2 = Map >(b); - MatrixXf b2_prev; - float norm = 0.0; - //MatrixXf a2; + b2 = Map>(b); + MatrixXf b2_prev; + float norm = 0.0; + // MatrixXf a2; - for(unsigned i = 0; i < maxiter; i++) - { - b2_prev = b2; + for (unsigned i = 0; i < maxiter; i++) { + b2_prev = b2; - a2 = (1.0 / (p * b2 * K3).array()).matrix(); + a2 = (1.0 / (p * b2 * K3).array()).matrix(); - b2 = (1.0 / (q * a2 * K3_t).array()).matrix(); + b2 = (1.0 / (q * a2 * K3_t).array()).matrix(); - norm = (b2 - b2_prev).norm(); - if(norm < 0.00001) - break; - } + norm = (b2 - b2_prev).norm(); + if (norm < 0.00001) break; + } - a3 = Map(a2.data(), a2.cols()*a2.rows()); - b3 = Map(b2.data(), b2.cols()*b2.rows()); - DiagonalMatrix P2 = a3.asDiagonal(); - DiagonalMatrix P3 = b3.asDiagonal(); + a3 = Map(a2.data(), a2.cols() * a2.rows()); + b3 = Map(b2.data(), b2.cols() * b2.rows()); + DiagonalMatrix P2 = a3.asDiagonal(); + DiagonalMatrix P3 = b3.asDiagonal(); - P = P3 * K3 * P2; + P = P3 * K3 * P2; - C3 = (C2.matrix()).transpose(); - //ArrayXXf CP; - CP = P.array() * C2.array(); - float sum_CP = CP.sum(); + C3 = (C2.matrix()).transpose(); + // ArrayXXf CP; + CP = P.array() * C2.array(); + float sum_CP = CP.sum(); - return sum_CP; - } + return sum_CP; +} -void reshape_to_C_mat_with_R2(float* y, float* x, float* Y, float* X, unsigned q, unsigned p, float* C) +void reshape_to_C_mat_with_R2(float *y, float *x, float *Y, float *X, unsigned q, unsigned p, + float *C) { - //Takes two arrays with different dimensions - //Array x has n elements, array y has m elements - //Arrange x times m rows in X and y times n columns in Y - //Add X+Y - - for(unsigned i = 0; i < p; i++) - for(unsigned j = 0 ; j < q; j++) - { - //C[i * q + j] = 0; - for(unsigned k = 0; k < 3; k++) - { - C[i * q + j] += X[k * p + i] * Y[k * q + j]; - } - - C[i * q + j] = y[j] + x[i] - 2 * C[i * q + j]; - } + // Takes two arrays with different dimensions + // Array x has n elements, array y has m elements + // Arrange x times m rows in X and y times n columns in Y + // Add X+Y + + for (unsigned i = 0; i < p; i++) + for (unsigned j = 0; j < q; j++) { + // C[i * q + j] = 0; + for (unsigned k = 0; k < 3; k++) { + C[i * q + j] += X[k * p + i] * Y[k * q + j]; + } + C[i * q + j] = y[j] + x[i] - 2 * C[i * q + j]; + } } - void c_run_svd(float inputP, float* inputX, float* inputY, float* inputT) - { - //Variables - float inputQ[229*177]; - int p = 229, q = 177; - for(int j = 0; j < p*q; j++) //Q - inputQ[j] = (float) 1/(p * q); - - Matrix3f A; - //float Q[229*177]; - MatrixXf Q = Map >(inputQ); - MatrixXf C; - MatrixXf X = Map >(inputX); - MatrixXf Y = Map >(inputY); - Matrix3f T = Map >(inputT); - - //Measure time - //struct timespec startn, endn; - //unsigned long long sw_ns; - - //gettime(&startn); - - //Run svd software - get R, X*R and Y.T - A = Y*Q*X.transpose()*2*inputP+T; - JacobiSVD svd(A, ComputeFullU | ComputeFullV); - Matrix3f U = svd.matrixU(); - Matrix3f Vh = svd.matrixV().transpose(); - R = U * Vh; - MatrixXf X_res = X.transpose()*R; - MatrixXf Y_res = Y; - - //gettime(&endn); - - //sw_ns = ts_subtract(&startn, &endn); - //printf(" > Software test time: %llu ns\n", sw_ns); - //printf(" + CP_sum: %f\n", sum); - - } +void c_run_svd(float inputP, float *inputX, float *inputY, float *inputT) +{ + // Variables + float inputQ[229 * 177]; + int p = 229, q = 177; + for (int j = 0; j < p * q; j++) // Q + inputQ[j] = (float)1 / (p * q); + + Matrix3f A; + // float Q[229*177]; + MatrixXf Q = Map>(inputQ); + MatrixXf C; + MatrixXf X = Map>(inputX); + MatrixXf Y = Map>(inputY); + Matrix3f T = Map>(inputT); + + // Measure time + // struct timespec startn, endn; + // unsigned long long sw_ns; + + // gettime(&startn); + + // Run svd software - get R, X*R and Y.T + A = Y * Q * X.transpose() * 2 * inputP + T; + JacobiSVD svd(A, ComputeFullU | ComputeFullV); + Matrix3f U = svd.matrixU(); + Matrix3f Vh = svd.matrixV().transpose(); + R = U * Vh; + MatrixXf X_res = X.transpose() * R; + MatrixXf Y_res = Y; + + // gettime(&endn); + + // sw_ns = ts_subtract(&startn, &endn); + // printf(" > Software test time: %llu ns\n", sw_ns); + // printf(" + CP_sum: %f\n", sum); +} - void reshape_to_C_mat_with_RK(float* y, float* x, float* Y, float* X, - unsigned q, unsigned p, float* C, float* K, float gamma) - { - //Takes two arrays with different dimensions - //Array x has n elements, array y has m elements - //Arrange x times m rows in X and y times n columns in Y - //Add X+Y - - for(unsigned i = 0; i < p; i++) - for(unsigned j = 0 ; j < q; j++) - { - C[i * q + j] = 0; - for(unsigned k = 0; k < 3; k++) - { - C[i * q + j] += X[k * p + i] * Y[k * q + j]; - } - - C[i * q + j] = y[j] + x[i] - 2 * C[i * q + j]; - K[i * q + j] = exp(-C[i * q + j] / gamma); +void reshape_to_C_mat_with_RK(float *y, float *x, float *Y, float *X, unsigned q, unsigned p, + float *C, float *K, float gamma) +{ + // Takes two arrays with different dimensions + // Array x has n elements, array y has m elements + // Arrange x times m rows in X and y times n columns in Y + // Add X+Y + + for (unsigned i = 0; i < p; i++) + for (unsigned j = 0; j < q; j++) { + C[i * q + j] = 0; + for (unsigned k = 0; k < 3; k++) { + C[i * q + j] += X[k * p + i] * Y[k * q + j]; } - } - - float sinkhorn_kernel_clean(unsigned iter, unsigned p, unsigned q, - float* a, float* b, float* b_prev, - float* K, float* C, float* P) - { - //Implementation of the inner loop in sinkhorn algorithm - - float norm = 0.0; - //Initializing b - for(unsigned i = 0; i < q; i++) - { - b[i] = 1.0 / (float)q; + C[i * q + j] = y[j] + x[i] - 2 * C[i * q + j]; + K[i * q + j] = exp(-C[i * q + j] / gamma); } +} - //Main loop - for(unsigned i = 0; i < iter; i++) - { - - for(unsigned j = 0; j < q; j++) - b_prev[j] = b[j]; +float sinkhorn_kernel_clean(unsigned iter, unsigned p, unsigned q, float *a, float *b, + float *b_prev, float *K, float *C, float *P) +{ + // Implementation of the inner loop in sinkhorn algorithm - //printf("%u ", i); - sink_kernel_operation(a, p, q, K, b, false); + float norm = 0.0; - sink_kernel_operation(b, p, q, K, a, true); + // Initializing b + for (unsigned i = 0; i < q; i++) { + b[i] = 1.0 / (float)q; + } - norm = 0; - for(unsigned j = 0; j < q; j++) - norm += pow(b[j]-b_prev[j],2); + // Main loop + for (unsigned i = 0; i < iter; i++) { - norm = sqrt(norm); - if(norm < 0.00001) - break; + for (unsigned j = 0; j < q; j++) + b_prev[j] = b[j]; - } + // printf("%u ", i); + sink_kernel_operation(a, p, q, K, b, false); - mult_diag_mat_diag(a, K, b, P, p, q); + sink_kernel_operation(b, p, q, K, a, true); - float sum = 0; - sum = mult_sum_mats_elementwise(C, P, p, q); - return sum; + norm = 0; + for (unsigned j = 0; j < q; j++) + norm += pow(b[j] - b_prev[j], 2); + norm = sqrt(norm); + if (norm < 0.00001) break; } - void sink_kernel_operation(float* a, unsigned p, unsigned q, float* K, float* b, bool transpose) + mult_diag_mat_diag(a, K, b, P, p, q); + + float sum = 0; + sum = mult_sum_mats_elementwise(C, P, p, q); + return sum; +} + +void sink_kernel_operation(float *a, unsigned p, unsigned q, float *K, float *b, bool transpose) +{ + if (!transpose) // Regular multiplication { - if(!transpose)//Regular multiplication - { - for(unsigned i = 0; i < p; i++) - { - a[i] = 0; - for(unsigned k = 0; k < q; k++) - { - a[i] += K[i * q + k] * b[k]; - } - a[i] = 1.0/((float)p * a[i]); + for (unsigned i = 0; i < p; i++) { + a[i] = 0; + for (unsigned k = 0; k < q; k++) { + a[i] += K[i * q + k] * b[k]; } + a[i] = 1.0 / ((float)p * a[i]); } - else//Transpose multiplication - { - float* a_alt = (float*)malloc(q * sizeof(float)); - if (a_alt == NULL) { - printf("Memory not allocated.\n"); - exit(0); - }; - - for(unsigned i = 0; i < p; i++) - { - //a_alt[i] = 0; - for(unsigned k = 0; k < q; k++) - { - if(i == 0) - a_alt[k] = 0; - //a[i] += K[k * q + i] * b[k]; - a_alt[k] += K[i * q + k] * b[i]; - if(i == p-1) - { - a[k] = 1.0/((float)q * a_alt[k]); - } - } - //a[i] = 1.0/((float)q * a[i]); + } + else // Transpose multiplication + { + float *a_alt = (float *)malloc(q * sizeof(float)); + if (a_alt == NULL) { + printf("Memory not allocated.\n"); + exit(0); + }; + + for (unsigned i = 0; i < p; i++) { + // a_alt[i] = 0; + for (unsigned k = 0; k < q; k++) { + if (i == 0) a_alt[k] = 0; + // a[i] += K[k * q + i] * b[k]; + a_alt[k] += K[i * q + k] * b[i]; + if (i == p - 1) { a[k] = 1.0 / ((float)q * a_alt[k]); } } + // a[i] = 1.0/((float)q * a[i]); } } +} - void mult_diag_mat_diag(float* diag_vec_1, float* K, float* diag_vec_2, float* R, unsigned m, unsigned n) - { - //Multiply 2 diagonal matrices with another matrix K in the middle - //Save result in R - //m is rows in K and n is columns - - for(unsigned i = 0; i < m; i++) - for(unsigned j = 0; j < n; j++) - { - R[i*n + j] = diag_vec_1[i] * K[i*n + j] * diag_vec_2[j]; - } +void mult_diag_mat_diag(float *diag_vec_1, float *K, float *diag_vec_2, float *R, unsigned m, + unsigned n) +{ + // Multiply 2 diagonal matrices with another matrix K in the middle + // Save result in R + // m is rows in K and n is columns + for (unsigned i = 0; i < m; i++) + for (unsigned j = 0; j < n; j++) { + R[i * n + j] = diag_vec_1[i] * K[i * n + j] * diag_vec_2[j]; + } +} + +float mult_sum_mats_elementwise(float *C, float *P, unsigned rows, unsigned cols) +{ + // Calculate the sum of element-wise multiplication of 2 matrices + float sum = 0; + for (unsigned j = 0; j < cols * rows; j++) { + sum += C[j] * P[j]; } + return sum; +} - float mult_sum_mats_elementwise(float* C, float* P, unsigned rows, unsigned cols) - { - //Calculate the sum of element-wise multiplication of 2 matrices - float sum = 0; - for(unsigned j = 0; j < cols*rows; j++) - { - sum += C[j] * P[j]; +float total_sinkhorn_clean(unsigned p, unsigned q, float *X, float *Y, float *P, float gamma, + unsigned maxiter, float outputX[], float outputY[], float C[], float K[], + float a[], float b[], float b_prev[]) +{ + float sum = 0; + + unsigned m = 3; + + for (unsigned i = 0; i < m; i++) + for (unsigned j = 0; j < p; j++) { + if (i == 0) outputX[j] = 0; + outputX[j] += pow(X[i * p + j], 2); } - return sum; - } - float total_sinkhorn_clean(unsigned p, unsigned q, float* X, float* Y, float* P, - float gamma, unsigned maxiter, float outputX[], - float outputY[], float C[],float K[], float a[], float b[], float b_prev[]) - { - float sum = 0; + for (unsigned i = 0; i < m; i++) + for (unsigned j = 0; j < q; j++) { + if (i == 0) outputY[j] = 0; + outputY[j] += pow(Y[i * q + j], 2); + } - unsigned m = 3; + // float C[229*177] = {0}; + reshape_to_C_mat_with_RK(outputY, outputX, Y, X, q, p, C, K, gamma); + // exp_gamma_mat(C, gamma, p, q, K); - for(unsigned i = 0; i < m; i++) - for(unsigned j = 0 ; j < p; j++) - { - if(i == 0) - outputX[j] = 0; - outputX[j] += pow(X[i * p + j], 2); - } + sum = sinkhorn_kernel_clean(maxiter, p, q, a, b, b_prev, K, C, P); + return sum; +} - for(unsigned i = 0; i < m; i++) - for(unsigned j = 0 ; j < q; j++) - { - if(i == 0) - outputY[j] = 0; - outputY[j] += pow(Y[i * q + j], 2); - } +void *c_hiwa_tot(void *pq) +{ - //float C[229*177] = {0}; - reshape_to_C_mat_with_RK(outputY, outputX, Y, X, q, p, C, K, gamma); + int i = *((int *)pq) / 4; + int j = *((int *)pq) % 4; - //exp_gamma_mat(C, gamma, p, q, K); + int p = p_tot[i]; + int q = q_tot[j]; + float *X_i = X_tot[i]; + float *Y_j = Y_tot[j]; - sum = sinkhorn_kernel_clean(maxiter, p, q, a, b, b_prev, K, C, P); + float *outputX3; + outputX3 = (float *)malloc(p * sizeof(float)); + if (outputX3 == NULL) { + printf("Memory not allocated.\n"); + exit(0); + } + for (int i = 0; i < p; i++) + outputX3[i] = 0; + + float *outputY3; + outputY3 = (float *)malloc(q * sizeof(float)); + if (outputY3 == NULL) { + printf("Memory not allocated.\n"); + exit(0); + } + for (int i = 0; i < q; i++) + outputY3[i] = 0; - return sum; + float *X_sink = (float *)malloc(p * 3 * sizeof(float)); + if (X_sink == NULL) { + printf("Memory not allocated.\n"); + exit(0); } + float *Y_sink = (float *)malloc(q * 3 * sizeof(float)); + if (Y_sink == NULL) { + printf("Memory not allocated.\n"); + exit(0); + } - void* c_hiwa_tot(void* pq) - { + float *P_sink = (float *)malloc(q * p * sizeof(float)); + if (P_sink == NULL) { + printf("Memory not allocated.\n"); + exit(0); + } - int i = *((int*)pq)/4; - int j = *((int*)pq)%4; + float *C_sink = (float *)malloc(q * p * sizeof(float)); + if (C_sink == NULL) { + printf("Memory not allocated.\n"); + exit(0); + } - int p = p_tot[i]; - int q = q_tot[j]; - float* X_i = X_tot[i]; - float* Y_j = Y_tot[j]; + float *K_sink = (float *)malloc(q * p * sizeof(float)); + if (K_sink == NULL) { + printf("Memory not allocated.\n"); + exit(0); + } - float* outputX3; - outputX3 = (float*)malloc(p * sizeof(float)); - if (outputX3 == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } - for(int i = 0; i < p; i++) outputX3[i] = 0; + float *a = (float *)malloc(p * sizeof(float)); + if (a == NULL) { + printf("Memory not allocated.\n"); + exit(0); + } - float* outputY3; - outputY3 = (float*)malloc(q * sizeof(float)); - if (outputY3 == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } - for(int i = 0; i < q; i++) outputY3[i] = 0; + float *b = (float *)malloc(q * sizeof(float)); + if (b == NULL) { + printf("Memory not allocated.\n"); + exit(0); + } - float* X_sink = (float*)malloc(p*3 * sizeof(float)); - if (X_sink == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } + float *b_prev = (float *)malloc(q * sizeof(float)); + if (b_prev == NULL) { + printf("Memory not allocated.\n"); + exit(0); + } - float* Y_sink = (float*)malloc(q*3 * sizeof(float)); - if (Y_sink == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } + ArrayXXf C3(p, q); + unsigned iter = 150; + float sum = 0; + float gamma = 1.6; - float* P_sink = (float*)malloc(q*p * sizeof(float)); - if (P_sink == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } + Matrix3f A, A2; + MatrixXf Q = MatrixXf::Ones(q, p); + Q = Q * ((float)1 / (p * q)); - float* C_sink = (float*)malloc(q*p * sizeof(float)); - if (C_sink == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } + MatrixXf C; + MatrixXf X = Map(X_i, 3, p); + MatrixXf Y = Map(Y_j, 3, q); + Matrix3f T = Map>(T_total); + Matrix3f U, Vh, res, prev_res; + MatrixXf X_res, Y_res; - float* K_sink = (float*)malloc(q*p * sizeof(float)); - if (K_sink == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } + res = Matrix3f::Identity(); + float norm = 0; - float* a = (float*)malloc(p * sizeof(float)); - if (a == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } + for (int i = 0; i < 100; i++) { + prev_res = res; - float* b = (float*)malloc(q * sizeof(float)); - if (b == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } + // SVD + A = Y * Q * X.transpose() * 2 * P_total + T; - float* b_prev = (float*)malloc(q * sizeof(float)); - if (b_prev == NULL) { - printf("Memory not allocated.\n"); - exit(0); - } + JacobiSVD svd(A, ComputeFullU | ComputeFullV); - ArrayXXf C3(p, q); - unsigned iter = 150; - float sum = 0; - float gamma = 1.6; - - Matrix3f A, A2; - MatrixXf Q = MatrixXf::Ones(q,p); - Q = Q *((float) 1/(p*q)); - - MatrixXf C; - MatrixXf X = Map(X_i, 3, p); - MatrixXf Y = Map(Y_j, 3, q); - Matrix3f T = Map >(T_total); - Matrix3f U, Vh, res, prev_res; - MatrixXf X_res, Y_res; - - res = Matrix3f::Identity(); - float norm = 0; - - for(int i = 0; i < 100; i++) - { - prev_res = res; - - //SVD - A = Y*Q*X.transpose()*2*P_total+T; - - JacobiSVD svd(A, ComputeFullU | ComputeFullV); - - U = svd.matrixU(); - Vh = svd.matrixV().transpose(); - res = U * Vh; - X_res = res*X; - Y_res = Y; - - for(int k = 0; k < 3; k++) - for(int j = 0; j < p; j++) - X_sink[k*p+j] = X_res(k, j); - - for(int k = 0; k < 3; k++) - for(int j = 0; j < q; j++) - Y_sink[k*q+j] = Y_res(k, j); - - //Sinkhorn - sum = total_sinkhorn_clean(p, q, X_sink, Y_sink, P_sink, - gamma, iter, outputX3, outputY3, C_sink, - K_sink, a, b, b_prev); - - for(int k = 0; k < q; k++) - for(int j = 0; j < p; j++) - Q(k, j) = P_sink[j*q+k]; - - norm = (res-prev_res).norm(); - if(norm < 0.0141){ - //printf("norm is: %f. CP_sum: %f\n", norm, sum); - break; - } - } + U = svd.matrixU(); + Vh = svd.matrixV().transpose(); + res = U * Vh; + X_res = res * X; + Y_res = Y; - free(outputX3); - free(outputY3); + for (int k = 0; k < 3; k++) + for (int j = 0; j < p; j++) + X_sink[k * p + j] = X_res(k, j); - CP_res[*((int*)pq)] = sum; + for (int k = 0; k < 3; k++) + for (int j = 0; j < q; j++) + Y_sink[k * q + j] = Y_res(k, j); - return pq; + // Sinkhorn + sum = total_sinkhorn_clean(p, q, X_sink, Y_sink, P_sink, gamma, iter, outputX3, outputY3, + C_sink, K_sink, a, b, b_prev); + + for (int k = 0; k < q; k++) + for (int j = 0; j < p; j++) + Q(k, j) = P_sink[j * q + k]; + + norm = (res - prev_res).norm(); + if (norm < 0.0141) { + // printf("norm is: %f. CP_sum: %f\n", norm, sum); + break; + } } + free(outputX3); + free(outputY3); + + CP_res[*((int *)pq)] = sum; + + return pq; +} + } /* extern "C" */ diff --git a/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/app/hiwa.c b/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/app/hiwa.c index 1b6c13c119..60761733d6 100644 --- a/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/app/hiwa.c +++ b/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/app/hiwa.c @@ -1,6 +1,6 @@ -#include "libesp.h" -#include "cfg.h" #include "c_run.h" +#include "cfg.h" +#include "libesp.h" static unsigned inX_words_adj; static unsigned inY_words_adj; @@ -20,390 +20,363 @@ static unsigned size; /* User-defined code */ static int validate_buffer(token_t *out, token_t *gold) { - int i; - int j; - float sum = 0; - unsigned errors = 0; - - for (i = 0; i < 1; i++) - { - for (j = 0; j < p_rows * q_cols + 1; j++) - { - float val = fixed32_to_float(out[i * out_words_adj + j], 11); - if (j != p_rows * q_cols) // P sum - sum += val; - else - { - float CP_val = fixed32_to_float(gold[i * out_words_adj + j],11); - if (CP_val != val) // CP_sum - { - float CP_error = 100*(CP_val-val)/CP_val; - printf("CP_sum is: %f\n", val); - printf("Expected CP_sum is: %f\n", CP_val); - if (CP_error > 3 || CP_error < -3) - { - printf("CP error is bigger than 3 percent - %f.\n", CP_error); - errors++; - } - else - printf("CP error is smaller than 3 percent - Passed.\n"); - } - } - } - - if (sum != 1.0) - { - float P_error = 100*(1.0-sum)/1.0; - - printf("P sum is: %f\n", sum); - if (P_error > 3) - { - printf("P error is bigger than 3 percent\n"); - errors++; - } - - } - } - - return errors; + int i; + int j; + float sum = 0; + unsigned errors = 0; + + for (i = 0; i < 1; i++) { + for (j = 0; j < p_rows * q_cols + 1; j++) { + float val = fixed32_to_float(out[i * out_words_adj + j], 11); + if (j != p_rows * q_cols) // P sum + sum += val; + else { + float CP_val = fixed32_to_float(gold[i * out_words_adj + j], 11); + if (CP_val != val) // CP_sum + { + float CP_error = 100 * (CP_val - val) / CP_val; + printf("CP_sum is: %f\n", val); + printf("Expected CP_sum is: %f\n", CP_val); + if (CP_error > 3 || CP_error < -3) { + printf("CP error is bigger than 3 percent - %f.\n", CP_error); + errors++; + } + else + printf("CP error is smaller than 3 percent - Passed.\n"); + } + } + } + + if (sum != 1.0) { + float P_error = 100 * (1.0 - sum) / 1.0; + + printf("P sum is: %f\n", sum); + if (P_error > 3) { + printf("P error is bigger than 3 percent\n"); + errors++; + } + } + } + + return errors; } - /* User-defined code */ -static void init_buffer(token_t *in, token_t * gold) +static void init_buffer(token_t *in, token_t *gold) { - int i; - int j; - int k; + int i; + int j; + int k; - printf("Initializing buffer\n"); + printf("Initializing buffer\n"); - for (i = 0; i < 1; i++) - { - for (j = 0; j < p_rows * m_rows; j++) - { - in[i * in_words_adj + j] = (token_t) float_to_fixed32(inputX[j], 11); - } + for (i = 0; i < 1; i++) { + for (j = 0; j < p_rows * m_rows; j++) { + in[i * in_words_adj + j] = (token_t)float_to_fixed32(inputX[j], 11); + } - //j = inX_len; + // j = inX_len; - printf("Finished loading X\n"); + printf("Finished loading X\n"); - for (k = 0; k < q_cols * m_rows; k++) - { - in[i * in_words_adj + j + k] = (token_t) float_to_fixed32(inputYT[k], 11); - } + for (k = 0; k < q_cols * m_rows; k++) { + in[i * in_words_adj + j + k] = (token_t)float_to_fixed32(inputYT[k], 11); + } - printf("Finished loading Y\n"); - } + printf("Finished loading Y\n"); + } - gold[p_rows * q_cols] = (token_t) float_to_fixed32(0.868033, 11); + gold[p_rows * q_cols] = (token_t)float_to_fixed32(0.868033, 11); - printf("Finished initialization"); + printf("Finished initialization"); } - /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - inX_words_adj = p_rows * m_rows; - inY_words_adj = q_cols * m_rows; - in_words_adj = inX_words_adj + inY_words_adj; - out_words_adj = p_rows * q_cols + 1; - } else { - inX_words_adj = round_up(p_rows * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - inY_words_adj = round_up(q_cols * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - in_words_adj = round_up((p_rows+q_cols) * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(p_rows * q_cols + 1, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - - inX_len = inX_words_adj * (1); - inY_len = inY_words_adj * (1); - in_len = in_words_adj * (1); - out_len = out_words_adj * (1); - inX_size = inX_len * sizeof(token_t); - inY_size = inY_len * sizeof(token_t); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + inX_words_adj = p_rows * m_rows; + inY_words_adj = q_cols * m_rows; + in_words_adj = inX_words_adj + inY_words_adj; + out_words_adj = p_rows * q_cols + 1; + } + else { + inX_words_adj = round_up(p_rows * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + inY_words_adj = round_up(q_cols * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + in_words_adj = round_up((p_rows + q_cols) * m_rows, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(p_rows * q_cols + 1, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + + inX_len = inX_words_adj * (1); + inY_len = inY_words_adj * (1); + in_len = in_words_adj * (1); + out_len = out_words_adj * (1); + inX_size = inX_len * sizeof(token_t); + inY_size = inY_len * sizeof(token_t); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + size = (out_offset * sizeof(token_t)) + out_size; } -void inline reshape_to_C_mat_with_R(float* y, float* x, float* Y, float* X, unsigned q, unsigned p, float* C) +void inline reshape_to_C_mat_with_R(float *y, float *x, float *Y, float *X, unsigned q, unsigned p, + float *C) { - //Takes two arrays with different dimensions - //Array x has n elements, array y has m elements - //Arrange x times m rows in X and y times n columns in Y - //Add X+Y - - for(unsigned i = 0; i < p; i++) - for(unsigned j = 0 ; j < q; j++) - { - //C[i * q + j] = 0; - for(unsigned k = 0; k < 3; k++) - { - C[i * q + j] += X[k * p + i] * Y[k * q + j]; - } - - C[i * q + j] = y[j] + x[i] - 2 * C[i * q + j]; - } - + // Takes two arrays with different dimensions + // Array x has n elements, array y has m elements + // Arrange x times m rows in X and y times n columns in Y + // Add X+Y + + for (unsigned i = 0; i < p; i++) + for (unsigned j = 0; j < q; j++) { + // C[i * q + j] = 0; + for (unsigned k = 0; k < 3; k++) { + C[i * q + j] += X[k * p + i] * Y[k * q + j]; + } + + C[i * q + j] = y[j] + x[i] - 2 * C[i * q + j]; + } } -void inline exp_gamma_mat(float* C, float gamma, unsigned rows, unsigned cols, float* K) +void inline exp_gamma_mat(float *C, float gamma, unsigned rows, unsigned cols, float *K) { - //Element-wise operation on C matrix. Divide each element by gamma and exp(-result) - //Save the final result in K + // Element-wise operation on C matrix. Divide each element by gamma and exp(-result) + // Save the final result in K - for(unsigned i = 0; i < rows*cols; i++) - { - K[i] = exp(-C[i] / gamma); - } + for (unsigned i = 0; i < rows * cols; i++) { + K[i] = exp(-C[i] / gamma); + } } -void inline sink_kernel_operation(float* a, unsigned p, unsigned q, float* K, float* b, bool transpose) +void inline sink_kernel_operation(float *a, unsigned p, unsigned q, float *K, float *b, + bool transpose) { - if(!transpose)//Regular multiplication - { - for(unsigned i = 0; i < p; i++) - { - a[i] = 0; - for(unsigned k = 0; k < q; k++) - { - a[i] += K[i * q + k] * b[k]; - } - a[i] = 1.0/((float)p * a[i]); - } - } - else//Transpose multiplication - { - for(unsigned i = 0; i < q; i++) - { - a[i] = 0; - for(unsigned k = 0; k < p; k++) - { - a[i] += K[k * q + i] * b[k]; - } - a[i] = 1.0/((float)q * a[i]); - } - } + if (!transpose) // Regular multiplication + { + for (unsigned i = 0; i < p; i++) { + a[i] = 0; + for (unsigned k = 0; k < q; k++) { + a[i] += K[i * q + k] * b[k]; + } + a[i] = 1.0 / ((float)p * a[i]); + } + } + else // Transpose multiplication + { + for (unsigned i = 0; i < q; i++) { + a[i] = 0; + for (unsigned k = 0; k < p; k++) { + a[i] += K[k * q + i] * b[k]; + } + a[i] = 1.0 / ((float)q * a[i]); + } + } } -void inline mult_diag_mat_diag(float* diag_vec_1, float* K, float* diag_vec_2, float* R, unsigned m, unsigned n) +void inline mult_diag_mat_diag(float *diag_vec_1, float *K, float *diag_vec_2, float *R, unsigned m, + unsigned n) { - //Multiply 2 diagonal matrices with another matrix K in the middle - //Save result in R - //m is rows in K and n is columns - - for(unsigned i = 0; i < m; i++) - for(unsigned j = 0; j < n; j++) - { - R[i*n + j] = diag_vec_1[i] * K[i*n + j] * diag_vec_2[j]; - } - + // Multiply 2 diagonal matrices with another matrix K in the middle + // Save result in R + // m is rows in K and n is columns + + for (unsigned i = 0; i < m; i++) + for (unsigned j = 0; j < n; j++) { + R[i * n + j] = diag_vec_1[i] * K[i * n + j] * diag_vec_2[j]; + } } -float inline mult_sum_mats_elementwise(float* C, float* P, unsigned rows, unsigned cols) +float inline mult_sum_mats_elementwise(float *C, float *P, unsigned rows, unsigned cols) { - //Calculate the sum of element-wise multiplication of 2 matrices - float sum = 0; - for(unsigned j = 0; j < cols*rows; j++) - { - sum += C[j] * P[j]; - } - return sum; + // Calculate the sum of element-wise multiplication of 2 matrices + float sum = 0; + for (unsigned j = 0; j < cols * rows; j++) { + sum += C[j] * P[j]; + } + return sum; } -float inline sinkhorn_kernel(unsigned iter, unsigned p, unsigned q, float* a, float* b, - float* K, float* C, float* tmp, float* P) +float inline sinkhorn_kernel(unsigned iter, unsigned p, unsigned q, float *a, float *b, float *K, + float *C, float *tmp, float *P) { - //Implementation of the inner loop in sinkhorn algorithm - - float b_prev[177]; - float norm = 0.0; + // Implementation of the inner loop in sinkhorn algorithm - //Initializing b - for(unsigned i = 0; i < q; i++) - b[i] = 1.0 / (float)q; + float b_prev[177]; + float norm = 0.0; - //Main loop - for(unsigned i = 0; i < iter; i++) - { - for(unsigned j = 0; j < 177; j++) - b_prev[j] = b[j]; + // Initializing b + for (unsigned i = 0; i < q; i++) + b[i] = 1.0 / (float)q; - //printf("%u ", i); - sink_kernel_operation(a, p, q, K, b, false); + // Main loop + for (unsigned i = 0; i < iter; i++) { + for (unsigned j = 0; j < 177; j++) + b_prev[j] = b[j]; - sink_kernel_operation(b, p, q, K, a, true); + // printf("%u ", i); + sink_kernel_operation(a, p, q, K, b, false); - //b norm check - norm = 0; - for(unsigned j = 0; j < 177; j++) - norm += pow(b[j]-b_prev[j],2); - norm = sqrt(norm); - if(norm < 0.00001) - break; + sink_kernel_operation(b, p, q, K, a, true); - } + // b norm check + norm = 0; + for (unsigned j = 0; j < 177; j++) + norm += pow(b[j] - b_prev[j], 2); + norm = sqrt(norm); + if (norm < 0.00001) break; + } - mult_diag_mat_diag(a, K, b, P, p, q); + mult_diag_mat_diag(a, K, b, P, p, q); - float sum = 0; - sum = mult_sum_mats_elementwise(C, P, p, q); - return sum; + float sum = 0; + sum = mult_sum_mats_elementwise(C, P, p, q); + return sum; } -float inline sinkhorn(float p, float q, float* X, float* Y, float* P, float gamma, unsigned maxiter, float outputX[], float outputY[], float C[], float K[], float a[], float b[], float tmp[]) +float inline sinkhorn(float p, float q, float *X, float *Y, float *P, float gamma, unsigned maxiter, + float outputX[], float outputY[], float C[], float K[], float a[], float b[], + float tmp[]) { - float sum = 0; - unsigned m = 3; - unsigned nX = p; - unsigned nY = q; - int power = 2; + float sum = 0; + unsigned m = 3; + unsigned nX = p; + unsigned nY = q; + int power = 2; - for(unsigned i = 0; i < m; i++) - for(unsigned j = 0 ; j < nX; j++) - { - outputX[j] += pow(X[i * nX + j], power); - } + for (unsigned i = 0; i < m; i++) + for (unsigned j = 0; j < nX; j++) { + outputX[j] += pow(X[i * nX + j], power); + } - for(unsigned i = 0; i < m; i++) - for(unsigned j = 0 ; j < nY; j++) - { - outputY[j] += pow(Y[i * nY + j], power); - } + for (unsigned i = 0; i < m; i++) + for (unsigned j = 0; j < nY; j++) { + outputY[j] += pow(Y[i * nY + j], power); + } - reshape_to_C_mat_with_R(outputY, outputX, Y, X, 177, 229, C); + reshape_to_C_mat_with_R(outputY, outputX, Y, X, 177, 229, C); - exp_gamma_mat(C, gamma, nX, nY, K); + exp_gamma_mat(C, gamma, nX, nY, K); - sum = sinkhorn_kernel(maxiter, p, q, a, b, K, C, tmp, P); + sum = sinkhorn_kernel(maxiter, p, q, a, b, K, C, tmp, P); - return sum; + return sum; } void c_run() { - float outputX[229] = {0}; - float outputY[177] = {0}; - float C[229*177] = {0}; - float K[229*177] = {0}; - float a[229] = {0}; - float b[177] = {0}; - float tmp[229*177] = {0}; - float P[229*177] = {0}; - float gamma = 1.6; - unsigned iter = 150; - unsigned p = 229; - unsigned q = 177; - float sum = 0; - - struct timespec startn, endn; - unsigned long long sw_ns; - - - gettime(&startn); - sum = sinkhorn(p, q, inputX, inputYT, P, gamma, iter, outputX, outputY, C, - K, a, b, tmp); - gettime(&endn); - - sw_ns = ts_subtract(&startn, &endn); - printf(" > Software test time: %llu ns\n", sw_ns); - printf(" + CP_sum: %f\n", sum); - - float outputX1[229] = {0}; - float outputY1[177] = {0}; - float C1[229*177] = {0}; - float K1[229*177] = {0}; - float a1[229] = {0}; - float b1[177] = {0}; - - //Use eigen library - gettime(&startn); - sum = c_run_hiwa(p, q, inputX, inputYT, gamma, iter, - outputX1, outputY1, C1, K1, a1, b1); - - gettime(&endn); - - sw_ns = ts_subtract(&startn, &endn); - printf(" > Eigen software test time: %llu ns\n", sw_ns); - printf(" + CP_sum: %f\n", sum); + float outputX[229] = {0}; + float outputY[177] = {0}; + float C[229 * 177] = {0}; + float K[229 * 177] = {0}; + float a[229] = {0}; + float b[177] = {0}; + float tmp[229 * 177] = {0}; + float P[229 * 177] = {0}; + float gamma = 1.6; + unsigned iter = 150; + unsigned p = 229; + unsigned q = 177; + float sum = 0; + + struct timespec startn, endn; + unsigned long long sw_ns; + + gettime(&startn); + sum = sinkhorn(p, q, inputX, inputYT, P, gamma, iter, outputX, outputY, C, K, a, b, tmp); + gettime(&endn); + + sw_ns = ts_subtract(&startn, &endn); + printf(" > Software test time: %llu ns\n", sw_ns); + printf(" + CP_sum: %f\n", sum); + + float outputX1[229] = {0}; + float outputY1[177] = {0}; + float C1[229 * 177] = {0}; + float K1[229 * 177] = {0}; + float a1[229] = {0}; + float b1[177] = {0}; + + // Use eigen library + gettime(&startn); + sum = c_run_hiwa(p, q, inputX, inputYT, gamma, iter, outputX1, outputY1, C1, K1, a1, b1); + + gettime(&endn); + + sw_ns = ts_subtract(&startn, &endn); + printf(" > Eigen software test time: %llu ns\n", sw_ns); + printf(" + CP_sum: %f\n", sum); } - int main(int argc, char **argv) - { - int errors; - - token_t *gold; - token_t *buf; +int main(int argc, char **argv) +{ + int errors; - init_parameters(); + token_t *gold; + token_t *buf; - buf = (token_t *) esp_alloc(size); - gold = malloc(out_size); + init_parameters(); - init_buffer(buf, gold); + buf = (token_t *)esp_alloc(size); + gold = malloc(out_size); - printf("\n====== %s ======\n\n", cfg_000[1].devname); - /* <<--print-params-->> */ - printf(" .maxiter = %d\n", maxiter); - printf(" .gamma = %f\n", gamma_float); - printf(" .q_cols = %d\n", q_cols); - printf(" .m_rows = %d\n", m_rows); - printf(" .p_rows = %d\n", p_rows); - printf("\n ** START **\n"); + init_buffer(buf, gold); - ((struct sinkhorn_access*) cfg_000[1].esp_desc)->gamma = float_to_fixed32(gamma_float, 11); - cfg_000[1].hw_buf = buf; + printf("\n====== %s ======\n\n", cfg_000[1].devname); + /* <<--print-params-->> */ + printf(" .maxiter = %d\n", maxiter); + printf(" .gamma = %f\n", gamma_float); + printf(" .q_cols = %d\n", q_cols); + printf(" .m_rows = %d\n", m_rows); + printf(" .p_rows = %d\n", p_rows); + printf("\n ** START **\n"); - //Run software execution for comparison - c_run(); + ((struct sinkhorn_access *)cfg_000[1].esp_desc)->gamma = float_to_fixed32(gamma_float, 11); + cfg_000[1].hw_buf = buf; - //Run Sinkhorn accelerator - esp_run(&cfg_000[1], 1); + // Run software execution for comparison + c_run(); - printf("\n ** DONE **\n"); + // Run Sinkhorn accelerator + esp_run(&cfg_000[1], 1); - //Validate the output - errors = validate_buffer(&buf[out_offset], gold); + printf("\n ** DONE **\n"); - if (!errors) - printf("+ Test PASSED\n"); - else - printf("+ Test FAILED\n"); + // Validate the output + errors = validate_buffer(&buf[out_offset], gold); - printf("\n====== %s ======\n\n", cfg_000[1].devname); + if (!errors) printf("+ Test PASSED\n"); + else + printf("+ Test FAILED\n"); + printf("\n====== %s ======\n\n", cfg_000[1].devname); - //In case we have more than one sinkhorn - check maximum 4 - for(int8_t i = 1; i < 4; i++){ - char acc[3][16]; - sprintf(acc[i-1], "/dev/sinkhorn.%d", i); + // In case we have more than one sinkhorn - check maximum 4 + for (int8_t i = 1; i < 4; i++) { + char acc[3][16]; + sprintf(acc[i - 1], "/dev/sinkhorn.%d", i); - if(access(acc[i-1], F_OK) == 0){ + if (access(acc[i - 1], F_OK) == 0) { - printf("\nAdditional accelerator: %s\n\n", acc[i-1]); + printf("\nAdditional accelerator: %s\n\n", acc[i - 1]); - ((struct sinkhorn_access*) cfg_000[i+1].esp_desc)->gamma = float_to_fixed32(gamma_float, 11); - cfg_000[i+1].hw_buf = buf; - esp_run(&cfg_000[i+1], 1); + ((struct sinkhorn_access *)cfg_000[i + 1].esp_desc)->gamma = + float_to_fixed32(gamma_float, 11); + cfg_000[i + 1].hw_buf = buf; + esp_run(&cfg_000[i + 1], 1); - errors = validate_buffer(&buf[out_offset], gold); + errors = validate_buffer(&buf[out_offset], gold); - if (!errors) - printf("+ Test PASSED for %s\n", acc[i-1]); - else - printf("+ Test FAILED for %s\n", acc[i-1]); - } - } + if (!errors) printf("+ Test PASSED for %s\n", acc[i - 1]); + else + printf("+ Test FAILED for %s\n", acc[i - 1]); + } + } - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - esp_free(buf); - free(gold); + esp_free(buf); + free(gold); - return errors; - return 0; - } + return errors; + return 0; +} diff --git a/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/driver/sinkhorn_stratus.c b/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/driver/sinkhorn_stratus.c index fae03f693f..5267e28b20 100644 --- a/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/driver/sinkhorn_stratus.c +++ b/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/driver/sinkhorn_stratus.c @@ -1,143 +1,135 @@ -#include #include +#include #include -#include #include +#include #include "sinkhorn_stratus.h" -#define DRV_NAME "sinkhorn" +#define DRV_NAME "sinkhorn" /* <<--regs-->> */ #define SINKHORN_STORE_STATE_REG 0x60 -#define SINKHORN_P2P_ITER_REG 0x5C -#define SINKHORN_P2P_OUT_REG 0x58 -#define SINKHORN_P2P_IN_REG 0x54 -#define SINKHORN_MAXITER_REG 0x50 -#define SINKHORN_GAMMA_REG 0x4c -#define SINKHORN_Q_COLS_REG 0x44 -#define SINKHORN_M_ROWS_REG 0x48 -#define SINKHORN_P_ROWS_REG 0x40 +#define SINKHORN_P2P_ITER_REG 0x5C +#define SINKHORN_P2P_OUT_REG 0x58 +#define SINKHORN_P2P_IN_REG 0x54 +#define SINKHORN_MAXITER_REG 0x50 +#define SINKHORN_GAMMA_REG 0x4c +#define SINKHORN_Q_COLS_REG 0x44 +#define SINKHORN_M_ROWS_REG 0x48 +#define SINKHORN_P_ROWS_REG 0x40 struct sinkhorn_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver sinkhorn_driver; static struct of_device_id sinkhorn_device_ids[] = { - { - .name = "SLD_SINKHORN_STRATUS", - }, - { - .name = "eb_144", - }, - { - .compatible = "sld,sinkhorn_stratus", - }, - { }, + { + .name = "SLD_SINKHORN_STRATUS", + }, + { + .name = "eb_144", + }, + { + .compatible = "sld,sinkhorn_stratus", + }, + {}, }; static int sinkhorn_devs; static inline struct sinkhorn_device *to_sinkhorn(struct esp_device *esp) { - return container_of(esp, struct sinkhorn_device, esp); + return container_of(esp, struct sinkhorn_device, esp); } static void sinkhorn_prep_xfer(struct esp_device *esp, void *arg) { - struct sinkhorn_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->store_state, esp->iomem + SINKHORN_STORE_STATE_REG); - iowrite32be(a->p2p_iter, esp->iomem + SINKHORN_P2P_ITER_REG); - iowrite32be(a->p2p_in, esp->iomem + SINKHORN_P2P_IN_REG); - iowrite32be(a->p2p_out, esp->iomem + SINKHORN_P2P_OUT_REG); - iowrite32be(a->maxiter, esp->iomem + SINKHORN_MAXITER_REG); - iowrite32be(a->gamma, esp->iomem + SINKHORN_GAMMA_REG); - iowrite32be(a->q_cols, esp->iomem + SINKHORN_Q_COLS_REG); - iowrite32be(a->m_rows, esp->iomem + SINKHORN_M_ROWS_REG); - iowrite32be(a->p_rows, esp->iomem + SINKHORN_P_ROWS_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); - + struct sinkhorn_access *a = arg; + + /* <<--regs-config-->> */ + iowrite32be(a->store_state, esp->iomem + SINKHORN_STORE_STATE_REG); + iowrite32be(a->p2p_iter, esp->iomem + SINKHORN_P2P_ITER_REG); + iowrite32be(a->p2p_in, esp->iomem + SINKHORN_P2P_IN_REG); + iowrite32be(a->p2p_out, esp->iomem + SINKHORN_P2P_OUT_REG); + iowrite32be(a->maxiter, esp->iomem + SINKHORN_MAXITER_REG); + iowrite32be(a->gamma, esp->iomem + SINKHORN_GAMMA_REG); + iowrite32be(a->q_cols, esp->iomem + SINKHORN_Q_COLS_REG); + iowrite32be(a->m_rows, esp->iomem + SINKHORN_M_ROWS_REG); + iowrite32be(a->p_rows, esp->iomem + SINKHORN_P_ROWS_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool sinkhorn_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct sinkhorn_device *sinkhorn = to_sinkhorn(esp); */ - /* struct sinkhorn_access *a = arg; */ + /* struct sinkhorn_device *sinkhorn = to_sinkhorn(esp); */ + /* struct sinkhorn_access *a = arg; */ - return true; + return true; } static int sinkhorn_probe(struct platform_device *pdev) { - struct sinkhorn_device *sinkhorn; - struct esp_device *esp; - int rc; - - sinkhorn = kzalloc(sizeof(*sinkhorn), GFP_KERNEL); - if (sinkhorn == NULL) - return -ENOMEM; - esp = &sinkhorn->esp; - esp->module = THIS_MODULE; - esp->number = sinkhorn_devs; - esp->driver = &sinkhorn_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - sinkhorn_devs++; - return 0; - err: - kfree(sinkhorn); - return rc; + struct sinkhorn_device *sinkhorn; + struct esp_device *esp; + int rc; + + sinkhorn = kzalloc(sizeof(*sinkhorn), GFP_KERNEL); + if (sinkhorn == NULL) return -ENOMEM; + esp = &sinkhorn->esp; + esp->module = THIS_MODULE; + esp->number = sinkhorn_devs; + esp->driver = &sinkhorn_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + sinkhorn_devs++; + return 0; +err: + kfree(sinkhorn); + return rc; } static int __exit sinkhorn_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct sinkhorn_device *sinkhorn = to_sinkhorn(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct sinkhorn_device *sinkhorn = to_sinkhorn(esp); - esp_device_unregister(esp); - kfree(sinkhorn); - return 0; + esp_device_unregister(esp); + kfree(sinkhorn); + return 0; } static struct esp_driver sinkhorn_driver = { - .plat = { - .probe = sinkhorn_probe, - .remove = sinkhorn_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = sinkhorn_device_ids, - }, - }, - .xfer_input_ok = sinkhorn_xfer_input_ok, - .prep_xfer = sinkhorn_prep_xfer, - .ioctl_cm = SINKHORN_IOC_ACCESS, - .arg_size = sizeof(struct sinkhorn_access), + .plat = + { + .probe = sinkhorn_probe, + .remove = sinkhorn_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = sinkhorn_device_ids, + }, + }, + .xfer_input_ok = sinkhorn_xfer_input_ok, + .prep_xfer = sinkhorn_prep_xfer, + .ioctl_cm = SINKHORN_IOC_ACCESS, + .arg_size = sizeof(struct sinkhorn_access), }; -static int __init sinkhorn_init(void) -{ - return esp_driver_register(&sinkhorn_driver); -} +static int __init sinkhorn_init(void) { return esp_driver_register(&sinkhorn_driver); } -static void __exit sinkhorn_exit(void) -{ - esp_driver_unregister(&sinkhorn_driver); -} +static void __exit sinkhorn_exit(void) { esp_driver_unregister(&sinkhorn_driver); } -module_init(sinkhorn_init) -module_exit(sinkhorn_exit) +module_init(sinkhorn_init) module_exit(sinkhorn_exit) -MODULE_DEVICE_TABLE(of, sinkhorn_device_ids); + MODULE_DEVICE_TABLE(of, sinkhorn_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/include/sinkhorn_stratus.h b/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/include/sinkhorn_stratus.h index ff3c5bdaf4..c54ff3c87e 100644 --- a/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/include/sinkhorn_stratus.h +++ b/accelerators/stratus_hls/sinkhorn_stratus/sw/linux/include/sinkhorn_stratus.h @@ -2,35 +2,35 @@ #define _SINKHORN_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct sinkhorn_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned maxiter; - unsigned gamma; - unsigned q_cols; - unsigned m_rows; - unsigned p_rows; - unsigned p2p_out; - unsigned p2p_in; - unsigned p2p_iter; - unsigned store_state; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned maxiter; + unsigned gamma; + unsigned q_cols; + unsigned m_rows; + unsigned p_rows; + unsigned p2p_out; + unsigned p2p_in; + unsigned p2p_iter; + unsigned store_state; + unsigned src_offset; + unsigned dst_offset; }; -#define SINKHORN_IOC_ACCESS _IOW ('S', 0, struct sinkhorn_access) +#define SINKHORN_IOC_ACCESS _IOW('S', 0, struct sinkhorn_access) #endif /* _SINKHORN_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/sort_stratus/hw/src/sort.cpp b/accelerators/stratus_hls/sort_stratus/hw/src/sort.cpp index 65fec911f2..f1f105a7a3 100644 --- a/accelerators/stratus_hls/sort_stratus/hw/src/sort.cpp +++ b/accelerators/stratus_hls/sort_stratus/hw/src/sort.cpp @@ -12,606 +12,547 @@ void sort::load_input() { - bool ping; - unsigned len; // from conf_info.len - unsigned bursts; // from conf_info.batch - unsigned index; - - // Reset - { - HLS_LOAD_RESET; - - this->reset_load_input(); - - index = 0; - len = 0; - bursts = 0; - - ping = true; - wait(); - } - - // Config - { - HLS_LOAD_CONFIG; - - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); - len = config.len; - bursts = config.batch; - } - - // Load - { - for (uint16_t b = 0; b < bursts; b++) - { - HLS_LOAD_INPUT_BATCH_LOOP; - - { - HLS_LOAD_DMA; - - dma_info_t dma_info(index / (DMA_WIDTH / 32), len / (DMA_WIDTH / 32), SIZE_WORD); - index += len; - this->dma_read_ctrl.put(dma_info); - } + bool ping; + unsigned len; // from conf_info.len + unsigned bursts; // from conf_info.batch + unsigned index; + + // Reset + { + HLS_LOAD_RESET; + + this->reset_load_input(); + + index = 0; + len = 0; + bursts = 0; + + ping = true; + wait(); + } + + // Config + { + HLS_LOAD_CONFIG; + + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); + len = config.len; + bursts = config.batch; + } + + // Load + { + for (uint16_t b = 0; b < bursts; b++) { + HLS_LOAD_INPUT_BATCH_LOOP; + + { + HLS_LOAD_DMA; + + dma_info_t dma_info(index / (DMA_WIDTH / 32), len / (DMA_WIDTH / 32), SIZE_WORD); + index += len; + this->dma_read_ctrl.put(dma_info); + } #if (DMA_WIDTH == 32) - for (uint16_t i = 0; i < len; i++) - { - HLS_LOAD_INPUT_LOOP; - - uint32_t data = this->dma_read_chnl.get().to_uint(); - { - HLS_LOAD_INPUT_PLM_WRITE; - if (ping) - A0[i] = data; - else - A1[i] = data; - wait(); - } + for (uint16_t i = 0; i < len; i++) { + HLS_LOAD_INPUT_LOOP; + + uint32_t data = this->dma_read_chnl.get().to_uint(); + { + HLS_LOAD_INPUT_PLM_WRITE; + if (ping) A0[i] = data; + else + A1[i] = data; + wait(); + } #elif (DMA_WIDTH == 64) - for (uint16_t i = 0; i < len; i += 2) - { - HLS_LOAD_INPUT_LOOP; - - sc_dt::sc_bv<64> data_bv = this->dma_read_chnl.get(); - { - HLS_LOAD_INPUT_PLM_WRITE; - uint32_t data_1 = data_bv.range(31, 0).to_uint(); - uint32_t data_2 = data_bv.range(63, 32).to_uint(); - if (ping) { - A0[i] = data_1; - A0[i + 1] = data_2; - } else { - A1[i] = data_1; - A1[i + 1] = data_2; - } - wait(); - } + for (uint16_t i = 0; i < len; i += 2) { + HLS_LOAD_INPUT_LOOP; + + sc_dt::sc_bv<64> data_bv = this->dma_read_chnl.get(); + { + HLS_LOAD_INPUT_PLM_WRITE; + uint32_t data_1 = data_bv.range(31, 0).to_uint(); + uint32_t data_2 = data_bv.range(63, 32).to_uint(); + if (ping) { + A0[i] = data_1; + A0[i + 1] = data_2; + } + else { + A1[i] = data_1; + A1[i + 1] = data_2; + } + wait(); + } #endif - } - ping = !ping; - this->load_compute_handshake(); - } - } - - // Conclude - { - this->process_done(); - } + } + ping = !ping; + this->load_compute_handshake(); + } + } + + // Conclude + { + this->process_done(); + } } - - void sort::store_output() { - bool ping; - unsigned len; // from conf_info.len - unsigned bursts; // from conf_info.batch - unsigned index; - - // Reset - { - HLS_STORE_RESET; - - this->reset_store_output(); - - index = 0; - len = 0; - bursts = 0; - - ping = true; - wait(); - } - - // Config - { - HLS_STORE_CONFIG; - - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); - len = config.len; - bursts = config.batch; - } - - // Store - { - for (uint16_t b = 0; b < bursts; b++) - { - HLS_STORE_OUTPUT_BATCH_LOOP; - - this->store_compute_handshake(); - - { - HLS_STORE_DMA; - - dma_info_t dma_info(index / (DMA_WIDTH / 32), len / (DMA_WIDTH / 32), SIZE_WORD); - index += len; - this->dma_write_ctrl.put(dma_info); - } + bool ping; + unsigned len; // from conf_info.len + unsigned bursts; // from conf_info.batch + unsigned index; + + // Reset + { + HLS_STORE_RESET; + + this->reset_store_output(); + + index = 0; + len = 0; + bursts = 0; + + ping = true; + wait(); + } + + // Config + { + HLS_STORE_CONFIG; + + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); + len = config.len; + bursts = config.batch; + } + + // Store + { + for (uint16_t b = 0; b < bursts; b++) { + HLS_STORE_OUTPUT_BATCH_LOOP; + + this->store_compute_handshake(); + + { + HLS_STORE_DMA; + + dma_info_t dma_info(index / (DMA_WIDTH / 32), len / (DMA_WIDTH / 32), SIZE_WORD); + index += len; + this->dma_write_ctrl.put(dma_info); + } #if (DMA_WIDTH == 32) - for (uint16_t i = 0; i < len; i++) - { - HLS_STORE_OUTPUT_LOOP; - - uint32_t data; - { - HLS_STORE_OUTPUT_PLM_READ; - if (ping) - data = B0[i]; - else - data = B1[i]; - wait(); - } - this->dma_write_chnl.put(data); + for (uint16_t i = 0; i < len; i++) { + HLS_STORE_OUTPUT_LOOP; + + uint32_t data; + { + HLS_STORE_OUTPUT_PLM_READ; + if (ping) data = B0[i]; + else + data = B1[i]; + wait(); + } + this->dma_write_chnl.put(data); #elif (DMA_WIDTH == 64) - for (uint16_t i = 0; i < len; i += 2) - { - HLS_STORE_OUTPUT_LOOP; - - sc_dt::sc_bv<64> data_bv; - { - HLS_STORE_OUTPUT_PLM_READ; - if (ping) { - data_bv.range(31, 0) = B0[i]; - data_bv.range(63, 32) = B0[i + 1]; - } else { - data_bv.range(31, 0) = B1[i]; - data_bv.range(63, 32) = B1[i + 1]; - } - wait(); - } - this->dma_write_chnl.put(data_bv); + for (uint16_t i = 0; i < len; i += 2) { + HLS_STORE_OUTPUT_LOOP; + + sc_dt::sc_bv<64> data_bv; + { + HLS_STORE_OUTPUT_PLM_READ; + if (ping) { + data_bv.range(31, 0) = B0[i]; + data_bv.range(63, 32) = B0[i + 1]; + } + else { + data_bv.range(31, 0) = B1[i]; + data_bv.range(63, 32) = B1[i + 1]; + } + wait(); + } + this->dma_write_chnl.put(data_bv); #endif - } - ping = !ping; - } - } - - // Conclude - { - this->accelerator_done(); - this->process_done(); - } + } + ping = !ping; + } + } + + // Conclude + { + this->accelerator_done(); + this->process_done(); + } } - void sort::compute_kernel() { - // Bi-tonic sort - bool ping; - unsigned len; // from conf_info.len - unsigned bursts; // from conf_info.batch - - // Reset - { - HLS_RB_RESET; - - this->reset_compute_1_kernel(); - - len = 0; - bursts = 0; - - ping = true; - wait(); - } - - // Config - { - HLS_RB_CONFIG; - - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); - len = config.len; - bursts = config.batch; - } - - - // Compute - { - for (uint16_t b = 0; b < bursts; b++) - { - HLS_RB_SORT_LOOP; - - this->compute_load_handshake(); - - // Flatten array - unsigned regs[NUM]; - HLS_RB_MAP_REGS; - - uint8_t wchunk = 0; - - // Break the following - for (uint16_t chunk = 0; chunk < LEN / NUM; chunk++) - { - HLS_RB_MAIN; - - if (chunk * NUM == len) - break; - - //Break the following - for (uint8_t i = 0; i < NUM; i++) - { - HLS_RB_RW_CHUNK; - - unsigned elem; - if (ping) - { - elem = A0[chunk * NUM + i]; - C0[wchunk][i] = regs[i]; - } - else - { - elem = A1[chunk * NUM + i]; - C1[wchunk][i] = regs[i]; - } - regs[i] = elem; - } - if (chunk != 0) - wchunk++; - - //Break the following - for (uint8_t k = 0; k < NUM; k++) - { - HLS_RB_INSERTION_OUTER; - //Unroll the following - for (uint8_t i = 0; i < NUM; i += 2) - { - HLS_RB_INSERTION_EVEN; - if (!lt_float(regs[i], regs[i + 1])) - { - unsigned tmp = regs[i]; - regs[i] = regs[i + 1]; - regs[i + 1] = tmp; - } - } - - //Unroll the following - for (uint8_t i = 1; i < NUM - 1; i += 2) - { - HLS_RB_INSERTION_ODD; - if (!lt_float(regs[i], regs[i + 1])) - { - unsigned tmp = regs[i]; - regs[i] = regs[i + 1]; - regs[i + 1] = tmp; - } - } - } - } - - { - HLS_RB_BREAK_FALSE_DEP; - } - - for (uint8_t i = 0; i < NUM; i++) - { - HLS_RB_W_LAST_CHUNKS_INNER; - uint32_t elem = regs[i]; - if (ping) - C0[wchunk][i] = elem; - else - C1[wchunk][i] = elem; - } - - ping = !ping; - - this->compute_compute_2_handshake(); - } - - // Conclude - { - this->process_done(); - } - } + // Bi-tonic sort + bool ping; + unsigned len; // from conf_info.len + unsigned bursts; // from conf_info.batch + + // Reset + { + HLS_RB_RESET; + + this->reset_compute_1_kernel(); + + len = 0; + bursts = 0; + + ping = true; + wait(); + } + + // Config + { + HLS_RB_CONFIG; + + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); + len = config.len; + bursts = config.batch; + } + + // Compute + { + for (uint16_t b = 0; b < bursts; b++) { + HLS_RB_SORT_LOOP; + + this->compute_load_handshake(); + + // Flatten array + unsigned regs[NUM]; + HLS_RB_MAP_REGS; + + uint8_t wchunk = 0; + + // Break the following + for (uint16_t chunk = 0; chunk < LEN / NUM; chunk++) { + HLS_RB_MAIN; + + if (chunk * NUM == len) break; + + // Break the following + for (uint8_t i = 0; i < NUM; i++) { + HLS_RB_RW_CHUNK; + + unsigned elem; + if (ping) { + elem = A0[chunk * NUM + i]; + C0[wchunk][i] = regs[i]; + } + else { + elem = A1[chunk * NUM + i]; + C1[wchunk][i] = regs[i]; + } + regs[i] = elem; + } + if (chunk != 0) wchunk++; + + // Break the following + for (uint8_t k = 0; k < NUM; k++) { + HLS_RB_INSERTION_OUTER; + // Unroll the following + for (uint8_t i = 0; i < NUM; i += 2) { + HLS_RB_INSERTION_EVEN; + if (!lt_float(regs[i], regs[i + 1])) { + unsigned tmp = regs[i]; + regs[i] = regs[i + 1]; + regs[i + 1] = tmp; + } + } + + // Unroll the following + for (uint8_t i = 1; i < NUM - 1; i += 2) { + HLS_RB_INSERTION_ODD; + if (!lt_float(regs[i], regs[i + 1])) { + unsigned tmp = regs[i]; + regs[i] = regs[i + 1]; + regs[i + 1] = tmp; + } + } + } + } + + { + HLS_RB_BREAK_FALSE_DEP; + } + + for (uint8_t i = 0; i < NUM; i++) { + HLS_RB_W_LAST_CHUNKS_INNER; + uint32_t elem = regs[i]; + if (ping) C0[wchunk][i] = elem; + else + C1[wchunk][i] = elem; + } + + ping = !ping; + + this->compute_compute_2_handshake(); + } + + // Conclude + { + this->process_done(); + } + } } - void sort::compute_2_kernel() { - // Bi-tonic sort - bool ping; - unsigned len; // from conf_info.len - unsigned bursts; // from conf_info.batch - - // Reset - { - HLS_MERGE_RESET; - - this->reset_compute_2_kernel(); - - len = 0; - bursts = 0; - - ping = true; - wait(); - } - - // Config - { - HLS_MERGE_CONFIG; - - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); - len = config.len; - bursts = config.batch; - } - - - // Compute - const uint8_t chunk_max = (uint8_t) (len >> lgNUM); - { - for (uint16_t b = 0; b < bursts; b++) - { - HLS_MERGE_SORT_LOOP; - unsigned head[LEN / NUM]; // Fifo output - unsigned fidx[LEN / NUM]; // Fifo index - bool pop_array[32]; - sc_dt::sc_bv<32> pop_bv(0); - unsigned pop; // pop from ith fifo - bool shift_array[32]; - sc_dt::sc_bv<32> shift_bv(0); - unsigned shift; // shift from ith fifo - unsigned regs[LEN / NUM]; // State - unsigned regs_in[LEN / NUM]; // Next state - HLS_MERGE_SORT_MAP_REGS; - - //Should not be a combinational loop. BTW unroll. - for (uint8_t i = 0; i < LEN / NUM; i++) - { - HLS_MERGE_INIT_ZERO_FIDX; - - fidx[i] = 0; - shift_array[i] = false; - pop_array[i] = false; - } - - this->compute_2_compute_handshake(); - - if (chunk_max > 1) //MERGE is needed - { - - //Break the following - for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) - { - HLS_MERGE_RD_FIRST_ELEMENTS; - - unsigned elem; - if (ping) - elem = C0[chunk][0]; - else - elem = C1[chunk][0]; - - if (chunk < chunk_max) { - head[chunk] = elem; - fidx[chunk]++; - } - } - - regs[0] = head[0]; - { - HLS_MERGE_RD_NEXT_ELEMENT; - if (ping) - head[0] = C0[0][1]; - else - head[0] = C1[0][1]; - } - fidx[0]++; - - uint8_t cur = 2; - uint16_t cnt = 0; - //Break the following - while(true) - { - HLS_MERGE_MAIN; - //Unroll the following - for (uint8_t chunk = 1; chunk < LEN / NUM; chunk++) - { - HLS_MERGE_COMPARE; - - if ((chunk < cur) && !lt_float(regs[chunk - 1], head[chunk])) - shift_array[chunk] = 1; - } - for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) - { - HLS_MERGE_SHIFT_ARRAY; - - shift_bv[chunk] = shift_array[chunk]; - } - shift = shift_bv.to_uint(); - - const int DeBruijn32[32] = - { - 0, 1, 28, 2, 29, 14, 24, 3, - 30, 22, 20, 15, 25, 17, 4, 8, - 31, 27, 13, 23, 21, 19, 16, 7, - 26, 12, 18, 6, 11, 5, 10, 9 - }; - HLS_MERGE_DEBRUIJN32; - - sc_dt::sc_bv<32> shift_rev_bv; - //Unroll the following - for (uint8_t i = 0; i < 32; i++) { - HLS_MERGE_SHIFT_REV; - - const uint8_t index_rev = 31 - i; - shift_rev_bv[index_rev] = shift_bv[i]; - } - unsigned shift_rev = shift_rev_bv.to_uint(); - unsigned shift_msb; - { - int v = shift_rev; - shift_msb = 31 - DeBruijn32[((unsigned)((v & -v) * 0x077CB531U)) >> 27]; - shift_msb = shift != 0 ? shift_msb : 0; - } - - regs_in[0] = regs[0]; - //Unroll the following - for (uint8_t chunk = LEN / NUM - 1; chunk > 1; chunk--) - { - HLS_MERGE_SHIFT; - - const uint32_t mask = 1 << chunk; - if (chunk < cur && chunk >= shift_msb) { - if (shift & mask) - { - regs_in[chunk] = head[chunk]; - pop_array[chunk] = 1; - } - else - { - regs_in[chunk] = regs[chunk - 1]; - } - } - } - - if (shift_msb <= 1) { - if (shift & 2) - { - regs_in[1] = head[1]; - pop_array[1] = 1; - } - else - { - regs_in[1] = regs[0]; - regs_in[0] = head[0]; - pop_array[0] = 1; - } - } - - for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) - { - HLS_MERGE_POP_ARRAY; - - pop_bv[chunk] = pop_array[chunk]; - } - pop = pop_bv.to_uint(); - - //Unroll the following - for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) - { - HLS_MERGE_SEQ; - - if (chunk < cur) - regs[chunk] = regs_in[chunk]; - } - - if (cur == chunk_max) - { - HLS_MERGE_WR_LAST_ELEMENTS; - // write output - if (ping) - B0[cnt] = regs[chunk_max - 1]; - else - B1[cnt] = regs[chunk_max - 1]; - cnt++; - } - - //Notice that only one pop[i] will be true at any time - int pop_idx = -1; - { - unsigned pop_msb; - int v = pop; - pop_msb = DeBruijn32[((unsigned)((v & -v) * 0x077CB531U)) >> 27]; - pop_idx = pop != 0 ? pop_msb : -1; - } - - - if (pop_idx != -1) - if (fidx[pop_idx] >= NUM) { - head[pop_idx] = 0x7f800000; // +INF - pop_idx = -1; - } - - if (pop_idx != -1) - { - HLS_MERGE_DO_POP; - if (ping) - head[pop_idx] = C0[pop_idx][fidx[pop_idx]]; - else - head[pop_idx] = C1[pop_idx][fidx[pop_idx]]; - fidx[pop_idx]++; - } - - for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) - { - HLS_MERGE_ZERO; - shift_array[chunk] = false; - pop_array[chunk] = false; - } - - // DEBUG - // cout << "heads after pop: "; - // for (int chunk = 0; chunk < LEN/NUM; chunk++) { - // if (chunk == chunk_max) - // break; - // cout << chunk << ": " << std::hex << head[chunk] << "; "; - // } - // cout << std::dec << endl << endl; - - if (cur < chunk_max) - cur++; - - if (cnt == len) - break; - } - } - else // MERGE is not required - { - for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) - { - HLS_MERGE_NO_MERGE_OUTER; - if (chunk == chunk_max) - break; - - for (uint8_t i = 0; i < NUM; i++) - { - HLS_MERGE_NO_MERGE_INNER; - - unsigned elem; - { - if (ping) - elem = C0[chunk][i]; - else - elem = C1[chunk][i]; - } - { - if (ping) - B0[i] = elem; - else - B1[i] = elem; - } - } - } - } - - ping = !ping; - - this->compute_store_handshake(); - } - - // Conclude - { - this->process_done(); - } - } + // Bi-tonic sort + bool ping; + unsigned len; // from conf_info.len + unsigned bursts; // from conf_info.batch + + // Reset + { + HLS_MERGE_RESET; + + this->reset_compute_2_kernel(); + + len = 0; + bursts = 0; + + ping = true; + wait(); + } + + // Config + { + HLS_MERGE_CONFIG; + + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); + len = config.len; + bursts = config.batch; + } + + // Compute + const uint8_t chunk_max = (uint8_t)(len >> lgNUM); + { + for (uint16_t b = 0; b < bursts; b++) { + HLS_MERGE_SORT_LOOP; + unsigned head[LEN / NUM]; // Fifo output + unsigned fidx[LEN / NUM]; // Fifo index + bool pop_array[32]; + sc_dt::sc_bv<32> pop_bv(0); + unsigned pop; // pop from ith fifo + bool shift_array[32]; + sc_dt::sc_bv<32> shift_bv(0); + unsigned shift; // shift from ith fifo + unsigned regs[LEN / NUM]; // State + unsigned regs_in[LEN / NUM]; // Next state + HLS_MERGE_SORT_MAP_REGS; + + // Should not be a combinational loop. BTW unroll. + for (uint8_t i = 0; i < LEN / NUM; i++) { + HLS_MERGE_INIT_ZERO_FIDX; + + fidx[i] = 0; + shift_array[i] = false; + pop_array[i] = false; + } + + this->compute_2_compute_handshake(); + + if (chunk_max > 1) // MERGE is needed + { + + // Break the following + for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) { + HLS_MERGE_RD_FIRST_ELEMENTS; + + unsigned elem; + if (ping) elem = C0[chunk][0]; + else + elem = C1[chunk][0]; + + if (chunk < chunk_max) { + head[chunk] = elem; + fidx[chunk]++; + } + } + + regs[0] = head[0]; + { + HLS_MERGE_RD_NEXT_ELEMENT; + if (ping) head[0] = C0[0][1]; + else + head[0] = C1[0][1]; + } + fidx[0]++; + + uint8_t cur = 2; + uint16_t cnt = 0; + // Break the following + while (true) { + HLS_MERGE_MAIN; + // Unroll the following + for (uint8_t chunk = 1; chunk < LEN / NUM; chunk++) { + HLS_MERGE_COMPARE; + + if ((chunk < cur) && !lt_float(regs[chunk - 1], head[chunk])) + shift_array[chunk] = 1; + } + for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) { + HLS_MERGE_SHIFT_ARRAY; + + shift_bv[chunk] = shift_array[chunk]; + } + shift = shift_bv.to_uint(); + + const int DeBruijn32[32] = {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, + 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, + 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; + HLS_MERGE_DEBRUIJN32; + + sc_dt::sc_bv<32> shift_rev_bv; + // Unroll the following + for (uint8_t i = 0; i < 32; i++) { + HLS_MERGE_SHIFT_REV; + + const uint8_t index_rev = 31 - i; + shift_rev_bv[index_rev] = shift_bv[i]; + } + unsigned shift_rev = shift_rev_bv.to_uint(); + unsigned shift_msb; + { + int v = shift_rev; + shift_msb = 31 - DeBruijn32[((unsigned)((v & -v) * 0x077CB531U)) >> 27]; + shift_msb = shift != 0 ? shift_msb : 0; + } + + regs_in[0] = regs[0]; + // Unroll the following + for (uint8_t chunk = LEN / NUM - 1; chunk > 1; chunk--) { + HLS_MERGE_SHIFT; + + const uint32_t mask = 1 << chunk; + if (chunk < cur && chunk >= shift_msb) { + if (shift & mask) { + regs_in[chunk] = head[chunk]; + pop_array[chunk] = 1; + } + else { + regs_in[chunk] = regs[chunk - 1]; + } + } + } + + if (shift_msb <= 1) { + if (shift & 2) { + regs_in[1] = head[1]; + pop_array[1] = 1; + } + else { + regs_in[1] = regs[0]; + regs_in[0] = head[0]; + pop_array[0] = 1; + } + } + + for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) { + HLS_MERGE_POP_ARRAY; + + pop_bv[chunk] = pop_array[chunk]; + } + pop = pop_bv.to_uint(); + + // Unroll the following + for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) { + HLS_MERGE_SEQ; + + if (chunk < cur) regs[chunk] = regs_in[chunk]; + } + + if (cur == chunk_max) { + HLS_MERGE_WR_LAST_ELEMENTS; + // write output + if (ping) B0[cnt] = regs[chunk_max - 1]; + else + B1[cnt] = regs[chunk_max - 1]; + cnt++; + } + + // Notice that only one pop[i] will be true at any time + int pop_idx = -1; + { + unsigned pop_msb; + int v = pop; + pop_msb = DeBruijn32[((unsigned)((v & -v) * 0x077CB531U)) >> 27]; + pop_idx = pop != 0 ? pop_msb : -1; + } + + if (pop_idx != -1) + if (fidx[pop_idx] >= NUM) { + head[pop_idx] = 0x7f800000; // +INF + pop_idx = -1; + } + + if (pop_idx != -1) { + HLS_MERGE_DO_POP; + if (ping) head[pop_idx] = C0[pop_idx][fidx[pop_idx]]; + else + head[pop_idx] = C1[pop_idx][fidx[pop_idx]]; + fidx[pop_idx]++; + } + + for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) { + HLS_MERGE_ZERO; + shift_array[chunk] = false; + pop_array[chunk] = false; + } + + // DEBUG + // cout << "heads after pop: "; + // for (int chunk = 0; chunk < LEN/NUM; chunk++) { + // if (chunk == chunk_max) + // break; + // cout << chunk << ": " << std::hex << head[chunk] << "; "; + // } + // cout << std::dec << endl << endl; + + if (cur < chunk_max) cur++; + + if (cnt == len) break; + } + } + else // MERGE is not required + { + for (uint8_t chunk = 0; chunk < LEN / NUM; chunk++) { + HLS_MERGE_NO_MERGE_OUTER; + if (chunk == chunk_max) break; + + for (uint8_t i = 0; i < NUM; i++) { + HLS_MERGE_NO_MERGE_INNER; + + unsigned elem; + { + if (ping) elem = C0[chunk][i]; + else + elem = C1[chunk][i]; + } + { + if (ping) B0[i] = elem; + else + B1[i] = elem; + } + } + } + } + + ping = !ping; + + this->compute_store_handshake(); + } + + // Conclude + { + this->process_done(); + } + } } diff --git a/accelerators/stratus_hls/sort_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/sort_stratus/hw/tb/sc_main.cpp index 75896b080a..0ca146195e 100644 --- a/accelerators/stratus_hls/sort_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/sort_stratus/hw/tb/sc_main.cpp @@ -5,43 +5,43 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; extern void esc_elaborate() { - // Creating the whole system - testbench = new system_t("testbench"); + // Creating the whole system + testbench = new system_t("testbench"); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); + esc_log_pass(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/sort_stratus/sw/baremetal/sort.c b/accelerators/stratus_hls/sort_stratus/sw/baremetal/sort.c index 5288f47759..4fdf4558c8 100644 --- a/accelerators/stratus_hls/sort_stratus/sw/baremetal/sort.c +++ b/accelerators/stratus_hls/sort_stratus/sw/baremetal/sort.c @@ -6,204 +6,197 @@ * Select Scatter-Gather in ESP configuration */ -#include -#include #include #include +#include +#include -#define SLD_SORT 0x0B +#define SLD_SORT 0x0B #define DEV_NAME "sld,sort_stratus" -#define SORT_LEN 64 +#define SORT_LEN 64 #define SORT_BATCH 2 #define SORT_BUF_SIZE (SORT_LEN * SORT_BATCH * sizeof(unsigned)) /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 7 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK ((SORT_BUF_SIZE % CHUNK_SIZE == 0) ? \ - (SORT_BUF_SIZE / CHUNK_SIZE) : \ - (SORT_BUF_SIZE / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK \ + ((SORT_BUF_SIZE % CHUNK_SIZE == 0) ? (SORT_BUF_SIZE / CHUNK_SIZE) : \ + (SORT_BUF_SIZE / CHUNK_SIZE) + 1) // User defined registers -#define SORT_LEN_REG 0x40 -#define SORT_BATCH_REG 0x44 -#define SORT_LEN_MIN_REG 0x48 -#define SORT_LEN_MAX_REG 0x4c -#define SORT_BATCH_MAX_REG 0x50 - +#define SORT_LEN_REG 0x40 +#define SORT_BATCH_REG 0x44 +#define SORT_LEN_MIN_REG 0x48 +#define SORT_LEN_MAX_REG 0x4c +#define SORT_BATCH_MAX_REG 0x50 static int validate_sorted(float *array, int len) { - int i; - int rtn = 0; - for (i = 1; i < len; i++) - if (array[i] < array[i-1]) - rtn++; - return rtn; + int i; + int rtn = 0; + for (i = 1; i < len; i++) + if (array[i] < array[i - 1]) rtn++; + return rtn; } -static void init_buf (float *buf, unsigned sort_size, unsigned sort_batch) +static void init_buf(float *buf, unsigned sort_size, unsigned sort_batch) { - int i, j; - printf(" Generate random input...\n"); + int i, j; + printf(" Generate random input...\n"); - /* srand(time(NULL)); */ - for (j = 0; j < sort_batch; j++) - for (i = 0; i < sort_size; i++) { - /* TAV rand between 0 and 1 */ + /* srand(time(NULL)); */ + for (j = 0; j < sort_batch; j++) + for (i = 0; i < sort_size; i++) { + /* TAV rand between 0 and 1 */ #ifndef __riscv - buf[sort_size * j + i] = ((float) rand () / (float) RAND_MAX); + buf[sort_size * j + i] = ((float)rand() / (float)RAND_MAX); #else - buf[sort_size * j + i] = 1.0 / ((float) i + 1); + buf[sort_size * j + i] = 1.0 / ((float)i + 1); #endif - /* /\* More general testbench *\/ */ - /* float M = 100000.0; */ - /* buf[sort_size * j + i] = M * ((float) rand() / (float) RAND_MAX) - M/2; */ - /* /\* Easyto debug...! *\/ */ - /* buf[sort_size * j + i] = (float) (sort_size - i);; */ - } + /* /\* More general testbench *\/ */ + /* float M = 100000.0; */ + /* buf[sort_size * j + i] = M * ((float) rand() / (float) RAND_MAX) - M/2; */ + /* /\* Easyto debug...! *\/ */ + /* buf[sort_size * j + i] = (float) (sort_size - i);; */ + } } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int n; - int ndev; - struct esp_device *espdevs = NULL; - unsigned coherence; - - ndev = probe(&espdevs, VENDOR_SLD, SLD_SORT, DEV_NAME); - if (!ndev) { - printf("Error: %s device not found!\n", DEV_NAME); - exit(EXIT_FAILURE); - } - - printf("Test parameters: [LEN, BATCH] = [%d, %d]\n\n", SORT_LEN, SORT_BATCH); - for (n = 0; n < ndev; n++) { + int n; + int ndev; + struct esp_device *espdevs = NULL; + unsigned coherence; + + ndev = probe(&espdevs, VENDOR_SLD, SLD_SORT, DEV_NAME); + if (!ndev) { + printf("Error: %s device not found!\n", DEV_NAME); + exit(EXIT_FAILURE); + } + + printf("Test parameters: [LEN, BATCH] = [%d, %d]\n\n", SORT_LEN, SORT_BATCH); + for (n = 0; n < ndev; n++) { #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - struct esp_device *dev = &espdevs[n]; - unsigned sort_batch_max; - unsigned sort_len_max; - unsigned sort_len_min; - unsigned done; - int i, j; - unsigned **ptable = NULL; - unsigned *mem; - unsigned errors = 0; - int scatter_gather = 1; - - sort_batch_max = ioread32(dev, SORT_BATCH_MAX_REG); - sort_len_min = ioread32(dev, SORT_LEN_MIN_REG); - sort_len_max = ioread32(dev, SORT_LEN_MAX_REG); - - printf("******************** %s.%d ********************\n", DEV_NAME, n); - // Check access ok - if (SORT_LEN < sort_len_min || - SORT_LEN > sort_len_max || - SORT_BATCH < 1 || - SORT_BATCH > sort_batch_max) { - printf(" Error: unsopported configuration parameters for %s.%d\n", DEV_NAME, n); - printf(" device can sort up to %d fp-vectors of size [%d, %d]\n", - sort_batch_max, sort_len_min, sort_len_max); - break; - } - - // Check if scatter-gather DMA is disabled - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - scatter_gather = 0; - } - - if (scatter_gather) - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { - printf(" -> Not enough TLB entries available. Abort.\n"); - break; - } - - // Allocate memory (will be contigous anyway in baremetal) - mem = aligned_malloc(SORT_BUF_SIZE); - - printf(" memory buffer base-address = %p\n", mem); - - if (scatter_gather) { - //Alocate and populate page table - ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); - for (i = 0; i < NCHUNK; i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(unsigned))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK); - } - - // Initialize input: write floating point hex values (simpler to debug) - init_buf((float *) mem, SORT_LEN, SORT_BATCH); - - // Configure device - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); - - if (scatter_gather) { - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - iowrite32(dev, SRC_OFFSET_REG, 0); - iowrite32(dev, DST_OFFSET_REG, 0); // Sort runs in place - } else { - iowrite32(dev, SRC_OFFSET_REG, (unsigned long) mem); - iowrite32(dev, DST_OFFSET_REG, (unsigned long) mem); // Sort runs in place - } - iowrite32(dev, SORT_LEN_REG, SORT_LEN); - iowrite32(dev, SORT_BATCH_REG, SORT_BATCH); - - // Flush for non-coherent DMA - esp_flush(coherence); - - // Start accelerator - printf(" Start..\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - printf(" Done\n"); - - /* /\* Print output *\/ */ - /* printf(" output:\n"); */ - /* for (j = 0; j < SORT_BATCH; j++) */ - /* for (i = 0; i < SORT_LEN; i++) */ - /* printf(" mem[%d][%d] = %08x\n", j, i, mem[j*SORT_LEN + i]); */ - - /* Validation */ - printf(" validating...\n"); - - for (j = 0; j < SORT_BATCH; j++) { - int err = validate_sorted((float *) &mem[j * SORT_LEN], SORT_LEN); - /* if (err != 0) */ - /* printf(" Error: %s.%d mismatch on batch %d\n", DEV_NAME, n, j); */ - errors += err; - } - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - printf("**************************************************\n\n"); - - if (scatter_gather) - aligned_free(ptable); - aligned_free(mem); - - } - } - return 0; + struct esp_device *dev = &espdevs[n]; + unsigned sort_batch_max; + unsigned sort_len_max; + unsigned sort_len_min; + unsigned done; + int i, j; + unsigned **ptable = NULL; + unsigned *mem; + unsigned errors = 0; + int scatter_gather = 1; + + sort_batch_max = ioread32(dev, SORT_BATCH_MAX_REG); + sort_len_min = ioread32(dev, SORT_LEN_MIN_REG); + sort_len_max = ioread32(dev, SORT_LEN_MAX_REG); + + printf("******************** %s.%d ********************\n", DEV_NAME, n); + // Check access ok + if (SORT_LEN < sort_len_min || SORT_LEN > sort_len_max || SORT_BATCH < 1 || + SORT_BATCH > sort_batch_max) { + printf(" Error: unsopported configuration parameters for %s.%d\n", DEV_NAME, n); + printf(" device can sort up to %d fp-vectors of size [%d, %d]\n", + sort_batch_max, sort_len_min, sort_len_max); + break; + } + + // Check if scatter-gather DMA is disabled + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + scatter_gather = 0; + } + + if (scatter_gather) + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { + printf(" -> Not enough TLB entries available. Abort.\n"); + break; + } + + // Allocate memory (will be contigous anyway in baremetal) + mem = aligned_malloc(SORT_BUF_SIZE); + + printf(" memory buffer base-address = %p\n", mem); + + if (scatter_gather) { + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); + for (i = 0; i < NCHUNK; i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(unsigned))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK); + } + + // Initialize input: write floating point hex values (simpler to debug) + init_buf((float *)mem, SORT_LEN, SORT_BATCH); + + // Configure device + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); + + if (scatter_gather) { + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + iowrite32(dev, SRC_OFFSET_REG, 0); + iowrite32(dev, DST_OFFSET_REG, 0); // Sort runs in place + } + else { + iowrite32(dev, SRC_OFFSET_REG, (unsigned long)mem); + iowrite32(dev, DST_OFFSET_REG, (unsigned long)mem); // Sort runs in place + } + iowrite32(dev, SORT_LEN_REG, SORT_LEN); + iowrite32(dev, SORT_BATCH_REG, SORT_BATCH); + + // Flush for non-coherent DMA + esp_flush(coherence); + + // Start accelerator + printf(" Start..\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + printf(" Done\n"); + + /* /\* Print output *\/ */ + /* printf(" output:\n"); */ + /* for (j = 0; j < SORT_BATCH; j++) */ + /* for (i = 0; i < SORT_LEN; i++) */ + /* printf(" mem[%d][%d] = %08x\n", j, i, mem[j*SORT_LEN + i]); */ + + /* Validation */ + printf(" validating...\n"); + + for (j = 0; j < SORT_BATCH; j++) { + int err = validate_sorted((float *)&mem[j * SORT_LEN], SORT_LEN); + /* if (err != 0) */ + /* printf(" Error: %s.%d mismatch on batch %d\n", DEV_NAME, n, j); */ + errors += err; + } + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + printf("**************************************************\n\n"); + + if (scatter_gather) aligned_free(ptable); + aligned_free(mem); + } + } + return 0; } diff --git a/accelerators/stratus_hls/sort_stratus/sw/linux/app/sort.c b/accelerators/stratus_hls/sort_stratus/sw/linux/app/sort.c index fe0da3167e..2fc5933382 100644 --- a/accelerators/stratus_hls/sort_stratus/sw/linux/app/sort.c +++ b/accelerators/stratus_hls/sort_stratus/sw/linux/app/sort.c @@ -1,302 +1,286 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 +#include #include +#include #include #include #include -#include -#include #include +#include #include #include -#include #define DEVNAME "/dev/sort_stratus.0" -#define NAME "sort_stratus" - -static const char usage_str[] = "usage: sort coherence cmd [n_elems] [n_batches] [-v]\n" - " coherence: none|llc-coh-dma|coh-dma|coh\n" - " cmd: config|test|run|hw|flush\n" - "\n" - "Optional arguments: n_elems and batch apply to 'config', 'hw' and 'test':\n" - " n_elems: number of elements per batch to be sorted\n" - " n_batches: number of batches\n" - "\n" - "The remaining option is only optional for 'test':\n" - " -v: enable verbose output for output-to-gold comparison\n"; +#define NAME "sort_stratus" + +static const char usage_str[] = + "usage: sort coherence cmd [n_elems] [n_batches] [-v]\n" + " coherence: none|llc-coh-dma|coh-dma|coh\n" + " cmd: config|test|run|hw|flush\n" + "\n" + "Optional arguments: n_elems and batch apply to 'config', 'hw' and 'test':\n" + " n_elems: number of elements per batch to be sorted\n" + " n_batches: number of batches\n" + "\n" + "The remaining option is only optional for 'test':\n" + " -v: enable verbose output for output-to-gold comparison\n"; struct sort_test { - struct test_info info; - struct sort_stratus_access desc; - float *hbuf; - float *sbuf; - unsigned int n_elems; - unsigned int n_batches; - bool verbose; + struct test_info info; + struct sort_stratus_access desc; + float *hbuf; + float *sbuf; + unsigned int n_elems; + unsigned int n_batches; + bool verbose; }; static inline struct sort_test *to_sort(struct test_info *info) { - return container_of(info, struct sort_test, info); + return container_of(info, struct sort_test, info); } static void insertion_sort(float *value, int len) { - int i; + int i; - for (i = 1; i < len; i++) { - double current; - int empty; + for (i = 1; i < len; i++) { + double current; + int empty; - current = value[i]; - empty = i; + current = value[i]; + empty = i; - while (empty > 0 && current < value[empty-1]) { - value[empty] = value[empty-1]; - empty--; - } + while (empty > 0 && current < value[empty - 1]) { + value[empty] = value[empty - 1]; + empty--; + } - value[empty] = current; - } + value[empty] = current; + } } -static int partition(float * array, int low, int high) +static int partition(float *array, int low, int high) { - int left, right, mid; - int pivot; - float cur; - - mid = (low + high) / 2; - left = low; - right = high; - - /* choose pivot as median of 3: low, high, and mid */ - if ((array[low] - array[mid]) * (array[high] - array[low]) >= 0) - pivot = low; - else if ((array[mid] - array[low]) * (array[high] - array[mid]) >= 0) - pivot = mid; - else - pivot = high; - - /* store value,index at the pivot */ - cur = array[pivot]; - - /* swap pivot with the first entry in the list */ - array[pivot] = array[low]; - array[low] = cur; - - /* the quicksort itself */ - while (left < right) - { - while (array[left] <= cur && left < high) - left++; - while (array[right] > cur) - right--; - if (left < right) - { - float tmp_val; - - tmp_val = array[right]; - array[right] = array[left]; - array[left] = tmp_val; - - } - } - - /* pivot was in low, but now moves into position at right */ - array[low] = array[right]; - array[right] = cur; - - return right; + int left, right, mid; + int pivot; + float cur; + + mid = (low + high) / 2; + left = low; + right = high; + + /* choose pivot as median of 3: low, high, and mid */ + if ((array[low] - array[mid]) * (array[high] - array[low]) >= 0) pivot = low; + else if ((array[mid] - array[low]) * (array[high] - array[mid]) >= 0) + pivot = mid; + else + pivot = high; + + /* store value,index at the pivot */ + cur = array[pivot]; + + /* swap pivot with the first entry in the list */ + array[pivot] = array[low]; + array[low] = cur; + + /* the quicksort itself */ + while (left < right) { + while (array[left] <= cur && left < high) + left++; + while (array[right] > cur) + right--; + if (left < right) { + float tmp_val; + + tmp_val = array[right]; + array[right] = array[left]; + array[left] = tmp_val; + } + } + + /* pivot was in low, but now moves into position at right */ + array[low] = array[right]; + array[right] = cur; + + return right; } - /* This defines the length at which we switch to insertion sort */ #define MAX_THRESH 10 int quicksort_inner(float *array, int low, int high) { - int pivot; - int length = high - low + 1; - - if (high > low) { - if (length > MAX_THRESH) { - pivot = partition (array, low, high); - quicksort_inner (array, low, pivot-1); - quicksort_inner (array, pivot+1, high); - } - } - - return 0; + int pivot; + int length = high - low + 1; + + if (high > low) { + if (length > MAX_THRESH) { + pivot = partition(array, low, high); + quicksort_inner(array, low, pivot - 1); + quicksort_inner(array, pivot + 1, high); + } + } + + return 0; } int quicksort(float *array, int len) { - quicksort_inner(array, 0, len-1); - insertion_sort(array, len); - return 0; + quicksort_inner(array, 0, len - 1); + insertion_sort(array, len); + return 0; } -static int check_gold (float *gold, float *array, int len, bool verbose) +static int check_gold(float *gold, float *array, int len, bool verbose) { - int i; - int rtn = 0; - for (i = 0; i < len; i++) { - if (array[i] != gold[i]) { - if (verbose) - printf("A[%d]: array=%.15g; gold=%.15g\n", i, array[i], gold[i]); - rtn++; - } - } - return rtn; + int i; + int rtn = 0; + for (i = 0; i < len; i++) { + if (array[i] != gold[i]) { + if (verbose) printf("A[%d]: array=%.15g; gold=%.15g\n", i, array[i], gold[i]); + rtn++; + } + } + return rtn; } -static void init_buf (float *buf, unsigned sort_size, unsigned sort_batch) +static void init_buf(float *buf, unsigned sort_size, unsigned sort_batch) { - int i, j; - printf("Generate random input...\n"); - srand(time(NULL)); - for (j = 0; j < sort_batch; j++) - for (i = 0; i < sort_size; i++) { - /* TAV rand between 0 and 1 */ - buf[sort_size * j + i] = ((float) rand () / (float) RAND_MAX); - /* /\* More general testbench *\/ */ - /* float M = 100000.0; */ - /* buf[sort_size * j + i] = M * ((float) rand() / (float) RAND_MAX) - M/2; */ - /* /\* Easyto debug...! *\/ */ - /* buf[sort_size * j + i] = (float) (sort_size - i);; */ - } + int i, j; + printf("Generate random input...\n"); + srand(time(NULL)); + for (j = 0; j < sort_batch; j++) + for (i = 0; i < sort_size; i++) { + /* TAV rand between 0 and 1 */ + buf[sort_size * j + i] = ((float)rand() / (float)RAND_MAX); + /* /\* More general testbench *\/ */ + /* float M = 100000.0; */ + /* buf[sort_size * j + i] = M * ((float) rand() / (float) RAND_MAX) - M/2; */ + /* /\* Easyto debug...! *\/ */ + /* buf[sort_size * j + i] = (float) (sort_size - i);; */ + } } static inline size_t sort_size(struct sort_test *t) { - return t->n_elems * t->n_batches * sizeof(float); + return t->n_elems * t->n_batches * sizeof(float); } static void sort_alloc_buf(struct test_info *info) { - struct sort_test *t = to_sort(info); + struct sort_test *t = to_sort(info); - t->hbuf = malloc0_check(sort_size(t)); - if (!strcmp(info->cmd, "test")) - t->sbuf = malloc0_check(sort_size(t)); + t->hbuf = malloc0_check(sort_size(t)); + if (!strcmp(info->cmd, "test")) t->sbuf = malloc0_check(sort_size(t)); } static void sort_alloc_contig(struct test_info *info) { - struct sort_test *t = to_sort(info); + struct sort_test *t = to_sort(info); - printf("HW buf size: %zu\n", sort_size(t)); - if (contig_alloc(sort_size(t), &info->contig) == NULL) - die_errno(__func__); + printf("HW buf size: %zu\n", sort_size(t)); + if (contig_alloc(sort_size(t), &info->contig) == NULL) die_errno(__func__); } static void sort_init_bufs(struct test_info *info) { - struct sort_test *t = to_sort(info); + struct sort_test *t = to_sort(info); - init_buf(t->hbuf, t->n_elems, t->n_batches); - contig_copy_to(info->contig, 0, t->hbuf, sort_size(t)); - if (!strcmp(info->cmd, "test")) - memcpy(t->sbuf, t->hbuf, sort_size(t)); + init_buf(t->hbuf, t->n_elems, t->n_batches); + contig_copy_to(info->contig, 0, t->hbuf, sort_size(t)); + if (!strcmp(info->cmd, "test")) memcpy(t->sbuf, t->hbuf, sort_size(t)); } static void sort_set_access(struct test_info *info) { - struct sort_test *t = to_sort(info); + struct sort_test *t = to_sort(info); - t->desc.size = t->n_elems; - t->desc.batch = t->n_batches; + t->desc.size = t->n_elems; + t->desc.batch = t->n_batches; } static void sort_comp(struct test_info *info) { - struct sort_test *t = to_sort(info); - int i; + struct sort_test *t = to_sort(info); + int i; - for (i = 0; i < t->n_batches; i++) - quicksort(&t->sbuf[i * t->n_elems], t->n_elems); + for (i = 0; i < t->n_batches; i++) + quicksort(&t->sbuf[i * t->n_elems], t->n_elems); } static bool sort_diff_ok(struct test_info *info) { - struct sort_test *t = to_sort(info); - int total_err = 0; - int i; - - contig_copy_from(t->hbuf, info->contig, 0, sort_size(t)); - for (i = 0; i < t->n_batches; i++) { - int err; - - err = check_gold(t->sbuf, t->hbuf, t->n_elems, t->verbose); - if (err) - printf("Batch %d: %d mismatches\n", i, err); - total_err += err; - } - if (t->verbose) { - for (i = 0; i < t->n_batches; i++) { - int j; - - printf("BATCH %d\n", i); - for (j = 0; j < t->n_elems; j++) { - printf(" \t%d : %.15g\n", - i, t->hbuf[t->n_elems * i + j]); - } - printf("\n"); - } - } - if (total_err) - printf("%d mismatches in total\n", total_err); - return !total_err; + struct sort_test *t = to_sort(info); + int total_err = 0; + int i; + + contig_copy_from(t->hbuf, info->contig, 0, sort_size(t)); + for (i = 0; i < t->n_batches; i++) { + int err; + + err = check_gold(t->sbuf, t->hbuf, t->n_elems, t->verbose); + if (err) printf("Batch %d: %d mismatches\n", i, err); + total_err += err; + } + if (t->verbose) { + for (i = 0; i < t->n_batches; i++) { + int j; + + printf("BATCH %d\n", i); + for (j = 0; j < t->n_elems; j++) { + printf(" \t%d : %.15g\n", i, t->hbuf[t->n_elems * i + j]); + } + printf("\n"); + } + } + if (total_err) printf("%d mismatches in total\n", total_err); + return !total_err; } static struct sort_test sort_test = { - .info = { - .name = NAME, - .devname = DEVNAME, - .alloc_buf = sort_alloc_buf, - .alloc_contig = sort_alloc_contig, - .init_bufs = sort_init_bufs, - .set_access = sort_set_access, - .comp = sort_comp, - .diff_ok = sort_diff_ok, - .esp = &sort_test.desc.esp, - .cm = SORT_STRATUS_IOC_ACCESS, - }, + .info = + { + .name = NAME, + .devname = DEVNAME, + .alloc_buf = sort_alloc_buf, + .alloc_contig = sort_alloc_contig, + .init_bufs = sort_init_bufs, + .set_access = sort_set_access, + .comp = sort_comp, + .diff_ok = sort_diff_ok, + .esp = &sort_test.desc.esp, + .cm = SORT_STRATUS_IOC_ACCESS, + }, }; static void NORETURN usage(void) { - fprintf(stderr, "%s", usage_str); - exit(1); + fprintf(stderr, "%s", usage_str); + exit(1); } int main(int argc, char *argv[]) { - int n_argc; - - if (argc < 3) - usage(); - - if (!strcmp(argv[2], "run") || !strcmp(argv[2], "flush")) - n_argc = 3; - else - n_argc = 5; - - if (argc < n_argc) - usage(); - - if (n_argc > 3) { - sort_test.n_elems = strtoul(argv[3], NULL, 0); - sort_test.n_batches = strtoul(argv[4], NULL, 0); - if (argc == 6) { - if (strcmp(argv[5], "-v")) - usage(); - sort_test.verbose = true; - } - } - return test_main(&sort_test.info, argv[1], argv[2]); -} + int n_argc; + + if (argc < 3) usage(); + if (!strcmp(argv[2], "run") || !strcmp(argv[2], "flush")) n_argc = 3; + else + n_argc = 5; + if (argc < n_argc) usage(); + + if (n_argc > 3) { + sort_test.n_elems = strtoul(argv[3], NULL, 0); + sort_test.n_batches = strtoul(argv[4], NULL, 0); + if (argc == 6) { + if (strcmp(argv[5], "-v")) usage(); + sort_test.verbose = true; + } + } + return test_main(&sort_test.info, argv[1], argv[2]); +} diff --git a/accelerators/stratus_hls/sort_stratus/sw/linux/driver/sort_stratus.c b/accelerators/stratus_hls/sort_stratus/sw/linux/driver/sort_stratus.c index e37f6de4a8..ee2f2d9691 100644 --- a/accelerators/stratus_hls/sort_stratus/sw/linux/driver/sort_stratus.c +++ b/accelerators/stratus_hls/sort_stratus/sw/linux/driver/sort_stratus.c @@ -1,146 +1,136 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "sort_stratus.h" -#define DRV_NAME "sort_stratus" +#define DRV_NAME "sort_stratus" -#define SORT_LEN_REG 0x40 -#define SORT_BATCH_REG 0x44 -#define SORT_LEN_MIN_REG 0x48 -#define SORT_LEN_MAX_REG 0x4c -#define SORT_BATCH_MAX_REG 0x50 +#define SORT_LEN_REG 0x40 +#define SORT_BATCH_REG 0x44 +#define SORT_LEN_MIN_REG 0x48 +#define SORT_LEN_MAX_REG 0x4c +#define SORT_BATCH_MAX_REG 0x50 struct sort_stratus_device { - struct esp_device esp; - size_t max_size; /* Maximum buffer size to be DMA'd to/from in bytes */ - unsigned min_len; - unsigned max_len; - unsigned max_batch; + struct esp_device esp; + size_t max_size; /* Maximum buffer size to be DMA'd to/from in bytes */ + unsigned min_len; + unsigned max_len; + unsigned max_batch; }; static struct esp_driver sort_driver; static struct of_device_id sort_device_ids[] = { - { - .name = "SLD_SORT_STRATUS", - }, - { - .name = "eb_00b", - }, - { - .compatible = "sld,sort_stratus", - }, - { }, + { + .name = "SLD_SORT_STRATUS", + }, + { + .name = "eb_00b", + }, + { + .compatible = "sld,sort_stratus", + }, + {}, }; static int sort_devs; static inline struct sort_stratus_device *to_sort(struct esp_device *esp) { - return container_of(esp, struct sort_stratus_device, esp); + return container_of(esp, struct sort_stratus_device, esp); } static void sort_prep_xfer(struct esp_device *esp, void *arg) { - struct sort_stratus_access *a = arg; + struct sort_stratus_access *a = arg; - iowrite32be(a->size, esp->iomem + SORT_LEN_REG); - iowrite32be(a->batch, esp->iomem + SORT_BATCH_REG); + iowrite32be(a->size, esp->iomem + SORT_LEN_REG); + iowrite32be(a->batch, esp->iomem + SORT_BATCH_REG); } static bool sort_xfer_input_ok(struct esp_device *esp, void *arg) { - struct sort_stratus_device *sort = to_sort(esp); - struct sort_stratus_access *a = arg; - unsigned size_mask = 0x0000001f; - - if (a->size & size_mask || - a->size > sort->max_len || - a->size < sort->min_len || - a->batch > sort->max_batch || - a->batch < 1) - return false; - return true; + struct sort_stratus_device *sort = to_sort(esp); + struct sort_stratus_access *a = arg; + unsigned size_mask = 0x0000001f; + + if (a->size & size_mask || a->size > sort->max_len || a->size < sort->min_len || + a->batch > sort->max_batch || a->batch < 1) + return false; + return true; } static int sort_probe(struct platform_device *pdev) { - struct sort_stratus_device *sort; - struct esp_device *esp; - size_t max_size; - int rc; - - sort = kzalloc(sizeof(*sort), GFP_KERNEL); - if (sort == NULL) - return -ENOMEM; - esp = &sort->esp; - esp->module = THIS_MODULE; - esp->number = sort_devs; - esp->driver = &sort_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - sort->max_len = ioread32be(esp->iomem + SORT_LEN_MAX_REG); - sort->min_len = ioread32be(esp->iomem + SORT_LEN_MIN_REG); - sort->max_batch = ioread32be(esp->iomem + SORT_BATCH_MAX_REG); - max_size = sort->max_len * sort->max_batch * sizeof(u32); - sort->max_size = round_up(max_size, PAGE_SIZE); - - sort_devs++; - return 0; - err: - kfree(sort); - return rc; + struct sort_stratus_device *sort; + struct esp_device *esp; + size_t max_size; + int rc; + + sort = kzalloc(sizeof(*sort), GFP_KERNEL); + if (sort == NULL) return -ENOMEM; + esp = &sort->esp; + esp->module = THIS_MODULE; + esp->number = sort_devs; + esp->driver = &sort_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + sort->max_len = ioread32be(esp->iomem + SORT_LEN_MAX_REG); + sort->min_len = ioread32be(esp->iomem + SORT_LEN_MIN_REG); + sort->max_batch = ioread32be(esp->iomem + SORT_BATCH_MAX_REG); + max_size = sort->max_len * sort->max_batch * sizeof(u32); + sort->max_size = round_up(max_size, PAGE_SIZE); + + sort_devs++; + return 0; +err: + kfree(sort); + return rc; } static int __exit sort_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct sort_stratus_device *sort = to_sort(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct sort_stratus_device *sort = to_sort(esp); - esp_device_unregister(esp); - kfree(sort); - return 0; + esp_device_unregister(esp); + kfree(sort); + return 0; } static struct esp_driver sort_driver = { - .plat = { - .probe = sort_probe, - .remove = sort_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = sort_device_ids, - }, - }, - .xfer_input_ok = sort_xfer_input_ok, - .prep_xfer = sort_prep_xfer, - .ioctl_cm = SORT_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct sort_stratus_access), + .plat = + { + .probe = sort_probe, + .remove = sort_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = sort_device_ids, + }, + }, + .xfer_input_ok = sort_xfer_input_ok, + .prep_xfer = sort_prep_xfer, + .ioctl_cm = SORT_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct sort_stratus_access), }; -static int __init sort_init(void) -{ - return esp_driver_register(&sort_driver); -} +static int __init sort_init(void) { return esp_driver_register(&sort_driver); } -static void __exit sort_exit(void) -{ - esp_driver_unregister(&sort_driver); -} +static void __exit sort_exit(void) { esp_driver_unregister(&sort_driver); } -module_init(sort_init) -module_exit(sort_exit) +module_init(sort_init) module_exit(sort_exit) -MODULE_DEVICE_TABLE(of, sort_device_ids); + MODULE_DEVICE_TABLE(of, sort_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/sort_stratus/sw/linux/include/sort_stratus.h b/accelerators/stratus_hls/sort_stratus/sw/linux/include/sort_stratus.h index 649ccc595d..8dc255ae03 100644 --- a/accelerators/stratus_hls/sort_stratus/sw/linux/include/sort_stratus.h +++ b/accelerators/stratus_hls/sort_stratus/sw/linux/include/sort_stratus.h @@ -4,25 +4,25 @@ #define _SORT_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct sort_stratus_access { - struct esp_access esp; - unsigned int size; - unsigned int batch; + struct esp_access esp; + unsigned int size; + unsigned int batch; }; -#define SORT_STRATUS_IOC_ACCESS _IOW ('S', 0, struct sort_stratus_access) +#define SORT_STRATUS_IOC_ACCESS _IOW('S', 0, struct sort_stratus_access) #endif /* _SORT_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/spmv_stratus/hw/src/spmv.cpp b/accelerators/stratus_hls/spmv_stratus/hw/src/spmv.cpp index 50a3e4fccd..c7ae5fba33 100644 --- a/accelerators/stratus_hls/spmv_stratus/hw/src/spmv.cpp +++ b/accelerators/stratus_hls/spmv_stratus/hw/src/spmv.cpp @@ -23,7 +23,7 @@ void spmv::load_input() uint32_t max_nonzero; uint32_t mtx_len; uint32_t vals_plm_size; - bool vect_fits_plm; + bool vect_fits_plm; // for derived configuration uint32_t index_rows; @@ -43,224 +43,215 @@ void spmv::load_input() // Reset { - HLS_LOAD_RESET; + HLS_LOAD_RESET; - this->reset_load_input(); + this->reset_load_input(); - ping = true; + ping = true; - nrows = 0; - ncols = 0; - max_nonzero = 0; - mtx_len = 0; - vals_plm_size = 0; - vect_fits_plm = 0; + nrows = 0; + ncols = 0; + max_nonzero = 0; + mtx_len = 0; + vals_plm_size = 0; + vect_fits_plm = 0; - index_rows = 0; - index_cols = 0; - index_vals = 0; - index_vect = 0; - len_rows = 0; - len_cols = 0; - len_vals = 0; - len_vect = 0; + index_rows = 0; + index_cols = 0; + index_vals = 0; + index_vect = 0; + len_rows = 0; + len_cols = 0; + len_vals = 0; + len_vect = 0; - bursts = 0; + bursts = 0; - rows_last = 0; - rows_last_diff = 0; + rows_last = 0; + rows_last_diff = 0; - wait(); + wait(); } // Config { - HLS_LOAD_CONFIG; - - // Acquire config parameters - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); - - nrows = config.nrows; - ncols = config.ncols; - max_nonzero = config.max_nonzero; - mtx_len = config.mtx_len; - vals_plm_size = config.vals_plm_size; - vect_fits_plm = config.vect_fits_plm; - - // DMA index evaluation - index_rows = 2 * mtx_len; - index_cols = mtx_len; - index_vals = 0; - index_vect = nrows + 2 * mtx_len; - - // DMA length evaluation - len_rows = (uint32_t) (vals_plm_size / max_nonzero); - - // # of bursts evaluation - bursts = (uint32_t) ((nrows - 1) / len_rows) + 1; + HLS_LOAD_CONFIG; + + // Acquire config parameters + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); + + nrows = config.nrows; + ncols = config.ncols; + max_nonzero = config.max_nonzero; + mtx_len = config.mtx_len; + vals_plm_size = config.vals_plm_size; + vect_fits_plm = config.vect_fits_plm; + + // DMA index evaluation + index_rows = 2 * mtx_len; + index_cols = mtx_len; + index_vals = 0; + index_vect = nrows + 2 * mtx_len; + + // DMA length evaluation + len_rows = (uint32_t)(vals_plm_size / max_nonzero); + + // # of bursts evaluation + bursts = (uint32_t)((nrows - 1) / len_rows) + 1; } // Load the whole vector if it fits the PLM if (vect_fits_plm) { - { - HLS_LOAD_DMA; + { + HLS_LOAD_DMA; - dma_info_t dma_info(index_vect, ncols, SIZE_WORD); - this->dma_read_ctrl.put(dma_info); - } + dma_info_t dma_info(index_vect, ncols, SIZE_WORD); + this->dma_read_ctrl.put(dma_info); + } - for (int i = 0; i < ncols; i++) { + for (int i = 0; i < ncols; i++) { - HLS_LOAD_VECT_PLM_READ; + HLS_LOAD_VECT_PLM_READ; - sc_bv data = this->dma_read_chnl.get(); + sc_bv data = this->dma_read_chnl.get(); - { - HLS_LOAD_VECT_PLM_WRITE; + { + HLS_LOAD_VECT_PLM_WRITE; - VECT0[i] = data.to_int(); + VECT0[i] = data.to_int(); - wait(); - } - } + wait(); + } + } } // Load bursts - for (uint32_t b = 0; b < bursts; b++) - { - HLS_LOAD_INPUT_BATCH_LOOP; + for (uint32_t b = 0; b < bursts; b++) { + HLS_LOAD_INPUT_BATCH_LOOP; - // Load row delimiters - { - HLS_LOAD_DMA; + // Load row delimiters + { + HLS_LOAD_DMA; - dma_info_t dma_info(index_rows, len_rows, SIZE_WORD); - index_rows += len_rows; - this->dma_read_ctrl.put(dma_info); - } + dma_info_t dma_info(index_rows, len_rows, SIZE_WORD); + index_rows += len_rows; + this->dma_read_ctrl.put(dma_info); + } - for (uint16_t i = 0; i < len_rows; i++) - { - HLS_LOAD_INPUT_LOOP; + for (uint16_t i = 0; i < len_rows; i++) { + HLS_LOAD_INPUT_LOOP; - sc_bv data = this->dma_read_chnl.get(); + sc_bv data = this->dma_read_chnl.get(); - { - HLS_LOAD_ROWS_PLM_WRITE; + { + HLS_LOAD_ROWS_PLM_WRITE; - if (ping) - ROWS0[i] = data.to_int() - rows_last; - else - ROWS1[i] = data.to_int() - rows_last; + if (ping) ROWS0[i] = data.to_int() - rows_last; + else + ROWS1[i] = data.to_int() - rows_last; - if (i == len_rows - 1) { - rows_last_diff = data.to_int() - rows_last; - rows_last = data.to_int(); - } + if (i == len_rows - 1) { + rows_last_diff = data.to_int() - rows_last; + rows_last = data.to_int(); + } - wait(); - } - } + wait(); + } + } - // Load matrix values - len_vals = rows_last_diff; + // Load matrix values + len_vals = rows_last_diff; - { - HLS_LOAD_DMA; + { + HLS_LOAD_DMA; - dma_info_t dma_info(index_vals, len_vals, SIZE_WORD); - index_vals += len_vals; - this->dma_read_ctrl.put(dma_info); - } + dma_info_t dma_info(index_vals, len_vals, SIZE_WORD); + index_vals += len_vals; + this->dma_read_ctrl.put(dma_info); + } - for (uint16_t i = 0; i < len_vals; i++) - { - HLS_LOAD_INPUT_LOOP; + for (uint16_t i = 0; i < len_vals; i++) { + HLS_LOAD_INPUT_LOOP; - sc_bv data = this->dma_read_chnl.get(); + sc_bv data = this->dma_read_chnl.get(); - { - HLS_LOAD_VALS_PLM_WRITE; - if (ping) - VALS0[i] = data.to_int(); - else - VALS1[i] = data.to_int(); - wait(); - } - } + { + HLS_LOAD_VALS_PLM_WRITE; + if (ping) VALS0[i] = data.to_int(); + else + VALS1[i] = data.to_int(); + wait(); + } + } - // Load column values - len_cols = rows_last_diff; + // Load column values + len_cols = rows_last_diff; - { - HLS_LOAD_DMA; + { + HLS_LOAD_DMA; - dma_info_t dma_info(index_cols, len_cols, SIZE_WORD); - index_cols += len_cols; - this->dma_read_ctrl.put(dma_info); - } + dma_info_t dma_info(index_cols, len_cols, SIZE_WORD); + index_cols += len_cols; + this->dma_read_ctrl.put(dma_info); + } - for (uint16_t i = 0; i < len_cols; i++) - { - HLS_LOAD_INPUT_LOOP; + for (uint16_t i = 0; i < len_cols; i++) { + HLS_LOAD_INPUT_LOOP; - sc_bv data = this->dma_read_chnl.get(); + sc_bv data = this->dma_read_chnl.get(); - { - HLS_LOAD_COLS_PLM_WRITE; + { + HLS_LOAD_COLS_PLM_WRITE; - if (ping | !vect_fits_plm) - COLS0[i] = data.to_int(); - else - COLS1[i] = data.to_int(); + if (ping | !vect_fits_plm) COLS0[i] = data.to_int(); + else + COLS1[i] = data.to_int(); - wait(); - } - } + wait(); + } + } - if (!vect_fits_plm) { - // Load vector values based on column values - len_vect = rows_last_diff; + if (!vect_fits_plm) { + // Load vector values based on column values + len_vect = rows_last_diff; - for (int i = 0; i < len_vect; i++) { + for (int i = 0; i < len_vect; i++) { - HLS_LOAD_VECT_PLM_READ; + HLS_LOAD_VECT_PLM_READ; - uint32_t local_index_vect; + uint32_t local_index_vect; - local_index_vect = index_vect + COLS0[i]; + local_index_vect = index_vect + COLS0[i]; - { - HLS_LOAD_DMA; + { + HLS_LOAD_DMA; - dma_info_t dma_info(local_index_vect, 1, SIZE_WORD); - this->dma_read_ctrl.put(dma_info); - } + dma_info_t dma_info(local_index_vect, 1, SIZE_WORD); + this->dma_read_ctrl.put(dma_info); + } - sc_bv data = this->dma_read_chnl.get(); + sc_bv data = this->dma_read_chnl.get(); - { - HLS_LOAD_VECT_PLM_WRITE; - if (ping) - VECT0[i] = data.to_int(); - else - VECT1[i] = data.to_int(); - wait(); - } - } - } + { + HLS_LOAD_VECT_PLM_WRITE; + if (ping) VECT0[i] = data.to_int(); + else + VECT1[i] = data.to_int(); + wait(); + } + } + } - ping = !ping; - this->load_compute_handshake(); + ping = !ping; + this->load_compute_handshake(); } // Conclude this->process_done(); } - void spmv::store_output() { /* Local variables */ @@ -274,7 +265,7 @@ void spmv::store_output() uint32_t max_nonzero; uint32_t mtx_len; uint32_t vals_plm_size; - bool vect_fits_plm; + bool vect_fits_plm; // for derived configuration uint32_t index_out; @@ -285,97 +276,93 @@ void spmv::store_output() // Reset { - HLS_STORE_RESET; + HLS_STORE_RESET; - this->reset_store_output(); + this->reset_store_output(); - ping = true; + ping = true; - nrows = 0; - ncols = 0; - max_nonzero = 0; - mtx_len = 0; - vals_plm_size = 0; - vect_fits_plm = 0; + nrows = 0; + ncols = 0; + max_nonzero = 0; + mtx_len = 0; + vals_plm_size = 0; + vect_fits_plm = 0; - index_out = 0; - len_out = 0; + index_out = 0; + len_out = 0; - bursts = 0; + bursts = 0; - wait(); + wait(); } // Config { - HLS_STORE_CONFIG; + HLS_STORE_CONFIG; - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); - nrows = config.nrows; - ncols = config.ncols; - max_nonzero = config.max_nonzero; - mtx_len = config.mtx_len; - vals_plm_size = config.vals_plm_size; - vect_fits_plm = config.vect_fits_plm; + nrows = config.nrows; + ncols = config.ncols; + max_nonzero = config.max_nonzero; + mtx_len = config.mtx_len; + vals_plm_size = config.vals_plm_size; + vect_fits_plm = config.vect_fits_plm; - // DMA index evaluation - index_out = nrows + ncols + 2 * mtx_len; + // DMA index evaluation + index_out = nrows + ncols + 2 * mtx_len; - // DMA length evaluation - len_out = (uint32_t) (vals_plm_size / max_nonzero); + // DMA length evaluation + len_out = (uint32_t)(vals_plm_size / max_nonzero); - // # of bursts evaluation - bursts = (uint32_t) ((nrows - 1) / len_out) + 1; + // # of bursts evaluation + bursts = (uint32_t)((nrows - 1) / len_out) + 1; } // Store bursts - for (uint16_t b = 0; b < bursts; b++) - { - HLS_STORE_OUTPUT_BATCH_LOOP; + for (uint16_t b = 0; b < bursts; b++) { + HLS_STORE_OUTPUT_BATCH_LOOP; - this->store_compute_handshake(); + this->store_compute_handshake(); - { - HLS_STORE_DMA; + { + HLS_STORE_DMA; - dma_info_t dma_info(index_out, len_out, SIZE_WORD); - index_out += len_out; - this->dma_write_ctrl.put(dma_info); - } + dma_info_t dma_info(index_out, len_out, SIZE_WORD); + index_out += len_out; + this->dma_write_ctrl.put(dma_info); + } - for (uint16_t i = 0; i < len_out; i++) - { - HLS_STORE_OUTPUT_LOOP; + for (uint16_t i = 0; i < len_out; i++) { + HLS_STORE_OUTPUT_LOOP; - sc_bv data; + sc_bv data; - float tmp; - - { - HLS_STORE_OUTPUT_PLM_READ; - if (ping) - data = sc_bv(OUT0[i]); - else - data = sc_bv(OUT1[i]); + float tmp; - wait(); - } - this->dma_write_chnl.put(data); - } + { + HLS_STORE_OUTPUT_PLM_READ; + if (ping) data = sc_bv(OUT0[i]); + else + data = sc_bv(OUT1[i]); - ping = !ping; + wait(); + } + this->dma_write_chnl.put(data); + } + + ping = !ping; } // Conclude { - this->accelerator_done(); - this->process_done(); + this->accelerator_done(); + this->process_done(); } } - void spmv::compute_kernel() { /* Local variables */ @@ -389,7 +376,7 @@ void spmv::compute_kernel() uint32_t max_nonzero; uint32_t mtx_len; uint32_t vals_plm_size; - bool vect_fits_plm; + bool vect_fits_plm; // for derived configuration uint32_t index_rows; @@ -412,134 +399,134 @@ void spmv::compute_kernel() // Reset { - HLS_COMPUTE_RESET; + HLS_COMPUTE_RESET; - this->reset_compute_kernel(); + this->reset_compute_kernel(); - ping = true; + ping = true; - nrows = 0; - ncols = 0; - max_nonzero = 0; - mtx_len = 0; - vals_plm_size = 0; - vect_fits_plm = 0; + nrows = 0; + ncols = 0; + max_nonzero = 0; + mtx_len = 0; + vals_plm_size = 0; + vect_fits_plm = 0; - index_rows = 0; - index_cols = 0; - index_vals = 0; - index_vect = 0; - index_out = 0; - len_rows = 0; - len_cols = 0; - len_vals = 0; - len_vect = 0; - len_out = 0; + index_rows = 0; + index_cols = 0; + index_vals = 0; + index_vect = 0; + index_out = 0; + len_rows = 0; + len_cols = 0; + len_vals = 0; + len_vect = 0; + len_out = 0; - bursts = 0; + bursts = 0; - rows_l = 0; - rows_r = 0; + rows_l = 0; + rows_r = 0; - wait(); + wait(); } // Config { - HLS_COMPUTE_CONFIG; - - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); - - nrows = config.nrows; - ncols = config.ncols; - max_nonzero = config.max_nonzero; - mtx_len = config.mtx_len; - vals_plm_size = config.vals_plm_size; - vect_fits_plm = config.vect_fits_plm; - - // DMA index evaluation - index_rows = 2 * mtx_len; - index_cols = mtx_len; - index_vals = 0; - index_vect = nrows + 2 * mtx_len; - index_out = nrows + ncols + 2 * mtx_len; - - // DMA length evaluation - len_rows = (uint32_t) (vals_plm_size / max_nonzero); - len_out = len_rows; - - // # of bursts evaluation - bursts = (uint32_t) ((nrows - 1) / len_rows) + 1; + HLS_COMPUTE_CONFIG; + + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); + + nrows = config.nrows; + ncols = config.ncols; + max_nonzero = config.max_nonzero; + mtx_len = config.mtx_len; + vals_plm_size = config.vals_plm_size; + vect_fits_plm = config.vect_fits_plm; + + // DMA index evaluation + index_rows = 2 * mtx_len; + index_cols = mtx_len; + index_vals = 0; + index_vect = nrows + 2 * mtx_len; + index_out = nrows + ncols + 2 * mtx_len; + + // DMA length evaluation + len_rows = (uint32_t)(vals_plm_size / max_nonzero); + len_out = len_rows; + + // # of bursts evaluation + bursts = (uint32_t)((nrows - 1) / len_rows) + 1; } // Compute for (unsigned b = 0; b < bursts; b++) { - HLS_COMPUTE_SPMV_LOOP; + HLS_COMPUTE_SPMV_LOOP; - this->compute_load_handshake(); + this->compute_load_handshake(); - rows_l = 0; - rows_r = 0; + rows_l = 0; + rows_r = 0; - for (unsigned r = 0; r < len_rows; r++) { + for (unsigned r = 0; r < len_rows; r++) { - HLS_COMPUTE_MAIN; + HLS_COMPUTE_MAIN; - FPDATA sum = FPDATA(0.0); + FPDATA sum = FPDATA(0.0); - if (ping) - rows_r = ROWS0[r]; - else - rows_r = ROWS1[r]; + if (ping) rows_r = ROWS0[r]; + else + rows_r = ROWS1[r]; - for (unsigned c = rows_l; c < rows_r; c++) { + for (unsigned c = rows_l; c < rows_r; c++) { - HLS_COMPUTE_RW_CHUNK; + HLS_COMPUTE_RW_CHUNK; - FPDATA val = FPDATA(0.0); - FPDATA vect = FPDATA(0.0); - FPDATA dot = FPDATA(0.0); - uint32_t col; + FPDATA val = FPDATA(0.0); + FPDATA vect = FPDATA(0.0); + FPDATA dot = FPDATA(0.0); + uint32_t col; - if (ping) { - val = int2fp(VALS0[c]); + if (ping) { + val = int2fp(VALS0[c]); - if (vect_fits_plm) { - col = COLS0[c]; - vect = int2fp(VECT0[col]); - } else { - vect = int2fp(VECT0[c]); - } + if (vect_fits_plm) { + col = COLS0[c]; + vect = int2fp(VECT0[col]); + } + else { + vect = int2fp(VECT0[c]); + } + } + else { + val = int2fp(VALS1[c]); - } else { - val = int2fp(VALS1[c]); + if (vect_fits_plm) { + col = COLS1[c]; + vect = int2fp(VECT0[col]); + } + else { + vect = int2fp(VECT1[c]); + } + } - if (vect_fits_plm) { - col = COLS1[c]; - vect = int2fp(VECT0[col]); - } else { - vect = int2fp(VECT1[c]); - } - } - - dot = val * vect; + dot = val * vect; - sum += dot; - } + sum += dot; + } - if (ping) - OUT0[r] = fp2int(sum); - else - OUT1[r] = fp2int(sum); + if (ping) OUT0[r] = fp2int(sum); + else + OUT1[r] = fp2int(sum); - rows_l = rows_r; - } + rows_l = rows_r; + } - ping = !ping; + ping = !ping; - this->compute_store_handshake(); + this->compute_store_handshake(); } // Conclude diff --git a/accelerators/stratus_hls/spmv_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/spmv_stratus/hw/tb/sc_main.cpp index 75896b080a..0ca146195e 100644 --- a/accelerators/stratus_hls/spmv_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/spmv_stratus/hw/tb/sc_main.cpp @@ -5,43 +5,43 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; extern void esc_elaborate() { - // Creating the whole system - testbench = new system_t("testbench"); + // Creating the whole system + testbench = new system_t("testbench"); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); + esc_log_pass(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/spmv_stratus/sw/baremetal/spmv.c b/accelerators/stratus_hls/spmv_stratus/sw/baremetal/spmv.c index 52166fb847..b5297c8363 100644 --- a/accelerators/stratus_hls/spmv_stratus/sw/baremetal/spmv.c +++ b/accelerators/stratus_hls/spmv_stratus/sw/baremetal/spmv.c @@ -6,328 +6,318 @@ * Select Scatter-Gather in ESP configuration */ -#include -#include -#include #include #include -#include #include +#include +#include +#include +#include -#define SLD_SPMV 0x0C +#define SLD_SPMV 0x0C #define DEV_NAME "sld,spmv_stratus" /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 14 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) // User defined registers -#define SPMV_NROWS_REG 0x40 -#define SPMV_NCOLS_REG 0x44 -#define SPMV_MAX_NONZERO_REG 0x48 -#define SPMV_MTX_LEN_REG 0x4C -#define SPMV_VALS_PLM_SIZE_REG 0x50 -#define SPMV_VECT_FITS_PLM_REG 0x54 - +#define SPMV_NROWS_REG 0x40 +#define SPMV_NCOLS_REG 0x44 +#define SPMV_MAX_NONZERO_REG 0x48 +#define SPMV_MTX_LEN_REG 0x4C +#define SPMV_VALS_PLM_SIZE_REG 0x50 +#define SPMV_VECT_FITS_PLM_REG 0x54 #define MAX_REL_ERROR 0.003 #define MAX_ABS_ERROR 0.05 int check_error_threshold(float out, float gold) { - float error; - - if (gold != 0) - error = fabs((gold - out) / gold); - else if (out != 0) - error = fabs((out - gold) / out); - else - error = 0; - - if (fabs(gold) >= 1) { - return (error > MAX_REL_ERROR); - } else { - return (fabs(gold - out) > MAX_ABS_ERROR); - } + float error; + + if (gold != 0) error = fabs((gold - out) / gold); + else if (out != 0) + error = fabs((out - gold) / out); + else + error = 0; + + if (fabs(gold) >= 1) { return (error > MAX_REL_ERROR); } + else { + return (fabs(gold - out) > MAX_ABS_ERROR); + } } static int validate(float *gold, float *out, int nrows, int verbose) { - int i; - int rtn = 0; + int i; + int rtn = 0; - for (i = 0; i < nrows; i++) - if (check_error_threshold(out[i], gold[i])) { - if (verbose) { + for (i = 0; i < nrows; i++) + if (check_error_threshold(out[i], gold[i])) { + if (verbose) { #ifndef __riscv - printf("out[%d]: result=%.15g; gold=%.15g\n", i, out[i], gold[i]); + printf("out[%d]: result=%.15g; gold=%.15g\n", i, out[i], gold[i]); #else - printf("out[%d]: result=%08x; gold=%08x\n", i, *((unsigned *) &out[i]), *((unsigned *) &gold[i])); + printf("out[%d]: result=%08x; gold=%08x\n", i, *((unsigned *)&out[i]), + *((unsigned *)&gold[i])); #endif - } - rtn++; - } + } + rtn++; + } - return rtn; + return rtn; } -void spmv_comp(unsigned nrows, unsigned ncols, - float *in_vals_buf, unsigned *in_cols_buf, - unsigned *in_rows_buf, float *in_vect_buf, - float *gold_buf) +void spmv_comp(unsigned nrows, unsigned ncols, float *in_vals_buf, unsigned *in_cols_buf, + unsigned *in_rows_buf, float *in_vect_buf, float *gold_buf) { - long i, j; - double sum, Si; + long i, j; + double sum, Si; - for(i = 0; i < nrows; i++) { - int tmp_begin; - int tmp_end; - sum = 0; Si = 0; + for (i = 0; i < nrows; i++) { + int tmp_begin; + int tmp_end; + sum = 0; + Si = 0; - if (i == 0) - tmp_begin = 0; - else - tmp_begin= in_rows_buf[i - 1]; + if (i == 0) tmp_begin = 0; + else + tmp_begin = in_rows_buf[i - 1]; - tmp_end = in_rows_buf[i]; - - for (j = tmp_begin; j < tmp_end; j++) { - Si = in_vals_buf[j] * in_vect_buf[in_cols_buf[j]]; - sum = sum + Si; - } - - gold_buf[i] = sum; - } + tmp_end = in_rows_buf[i]; + for (j = tmp_begin; j < tmp_end; j++) { + Si = in_vals_buf[j] * in_vect_buf[in_cols_buf[j]]; + sum = sum + Si; + } + gold_buf[i] = sum; + } } -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - unsigned int nrows; - unsigned int ncols; - unsigned int max_nonzero; - unsigned int mtx_len; - const unsigned int vals_plm_size = 256; - const unsigned int vect_fits_plm = 0; - - float *in_vals_buf; - unsigned *in_cols_buf; - unsigned *in_rows_buf; - float *in_vect_buf; - float *out_buf; - float *gold_buf; - - unsigned vals_addr; - unsigned cols_addr; - unsigned rows_addr; - unsigned vect_addr; - unsigned out_addr; - - unsigned vals_size; - unsigned cols_size; - unsigned rows_size; - unsigned vect_size; - unsigned out_size; - - int *in_vals_fx_buf; - int *in_vect_fx_buf; - int *out_fx_buf; - - int i; - int n; - int ndev; - struct esp_device *espdevs = NULL; - unsigned coherence; - - // Configure and initialize buffers - nrows = 512; - ncols = 512; - max_nonzero = 8; - mtx_len = 2385; - - vals_addr = 0; - vals_size = mtx_len; - - cols_addr = mtx_len; - cols_size = mtx_len; - - rows_addr = 2 * mtx_len; - rows_size = nrows; - - vect_addr = nrows + 2 * mtx_len; - vect_size = ncols; - - out_addr = nrows + 2 * mtx_len + ncols; - out_size = nrows; - - printf("Memory allocation\n"); - - in_vals_buf = aligned_malloc(sizeof(float) * vals_size); - in_cols_buf = aligned_malloc(sizeof(unsigned) * cols_size); - in_rows_buf = aligned_malloc(sizeof(unsigned) * rows_size); - in_vect_buf = aligned_malloc(sizeof(float) * vect_size); - out_buf = aligned_malloc(sizeof(float) * out_size); - gold_buf = aligned_malloc(sizeof(float) * out_size); - - in_vals_fx_buf = aligned_malloc(sizeof(int) * vals_size); - in_vect_fx_buf = aligned_malloc(sizeof(int) * vect_size); - out_fx_buf = aligned_malloc(sizeof(int) * out_size); - - if (!(in_vals_buf && in_cols_buf && in_rows_buf && in_vect_buf && out_buf && in_vals_fx_buf && in_vect_fx_buf && out_fx_buf)) { - printf("Error: not enough memory\n"); - exit(EXIT_FAILURE); - } - - printf("Data initialization\n"); + unsigned int nrows; + unsigned int ncols; + unsigned int max_nonzero; + unsigned int mtx_len; + const unsigned int vals_plm_size = 256; + const unsigned int vect_fits_plm = 0; + + float *in_vals_buf; + unsigned *in_cols_buf; + unsigned *in_rows_buf; + float *in_vect_buf; + float *out_buf; + float *gold_buf; + + unsigned vals_addr; + unsigned cols_addr; + unsigned rows_addr; + unsigned vect_addr; + unsigned out_addr; + + unsigned vals_size; + unsigned cols_size; + unsigned rows_size; + unsigned vect_size; + unsigned out_size; + + int *in_vals_fx_buf; + int *in_vect_fx_buf; + int *out_fx_buf; + + int i; + int n; + int ndev; + struct esp_device *espdevs = NULL; + unsigned coherence; + + // Configure and initialize buffers + nrows = 512; + ncols = 512; + max_nonzero = 8; + mtx_len = 2385; + + vals_addr = 0; + vals_size = mtx_len; + + cols_addr = mtx_len; + cols_size = mtx_len; + + rows_addr = 2 * mtx_len; + rows_size = nrows; + + vect_addr = nrows + 2 * mtx_len; + vect_size = ncols; + + out_addr = nrows + 2 * mtx_len + ncols; + out_size = nrows; + + printf("Memory allocation\n"); + + in_vals_buf = aligned_malloc(sizeof(float) * vals_size); + in_cols_buf = aligned_malloc(sizeof(unsigned) * cols_size); + in_rows_buf = aligned_malloc(sizeof(unsigned) * rows_size); + in_vect_buf = aligned_malloc(sizeof(float) * vect_size); + out_buf = aligned_malloc(sizeof(float) * out_size); + gold_buf = aligned_malloc(sizeof(float) * out_size); + + in_vals_fx_buf = aligned_malloc(sizeof(int) * vals_size); + in_vect_fx_buf = aligned_malloc(sizeof(int) * vect_size); + out_fx_buf = aligned_malloc(sizeof(int) * out_size); + + if (!(in_vals_buf && in_cols_buf && in_rows_buf && in_vect_buf && out_buf && in_vals_fx_buf && + in_vect_fx_buf && out_fx_buf)) { + printf("Error: not enough memory\n"); + exit(EXIT_FAILURE); + } + + printf("Data initialization\n"); #include "data.h" - for (i = 0; i < vals_size; i++) - in_vals_fx_buf[i] = float_to_fixed32(in_vals_buf[i], 16); + for (i = 0; i < vals_size; i++) + in_vals_fx_buf[i] = float_to_fixed32(in_vals_buf[i], 16); - for (i = 0; i < vect_size; i++) - in_vect_fx_buf[i] = float_to_fixed32(in_vect_buf[i], 16); + for (i = 0; i < vect_size; i++) + in_vect_fx_buf[i] = float_to_fixed32(in_vect_buf[i], 16); - // Search for the device - ndev = probe(&espdevs, VENDOR_SLD, SLD_SPMV, DEV_NAME); - if (!ndev) { - printf("Error: %s device not found!\n", DEV_NAME); - exit(EXIT_FAILURE); - } + // Search for the device + ndev = probe(&espdevs, VENDOR_SLD, SLD_SPMV, DEV_NAME); + if (!ndev) { + printf("Error: %s device not found!\n", DEV_NAME); + exit(EXIT_FAILURE); + } - // Run software - printf("Software execution\n"); - spmv_comp(nrows, ncols, in_vals_buf, in_cols_buf, in_rows_buf, in_vect_buf, gold_buf); + // Run software + printf("Software execution\n"); + spmv_comp(nrows, ncols, in_vals_buf, in_cols_buf, in_rows_buf, in_vect_buf, gold_buf); - // Test all devices matching SPMV ID. - for (n = 0; n < ndev; n++) { + // Test all devices matching SPMV ID. + for (n = 0; n < ndev; n++) { #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - struct esp_device *dev = &espdevs[n]; - - unsigned done; - unsigned **ptable = NULL; - unsigned *mem; - unsigned errors = 0; - int scatter_gather = 1; - size_t size; - - printf("Testing %s.%d \n", DEV_NAME, n); - - // Check access ok (TODO) - - // Check if scatter-gather DMA is disabled - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled; revert to contiguous buffer.\n"); - scatter_gather = 0; - } else { - printf(" -> scatter-gather DMA is enabled.\n"); - } - - size = sizeof(int) * (vals_size + cols_size + rows_size + vect_size + out_size); - - if (scatter_gather) - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(size)) { - printf(" Trying to allocate %lu chunks on %d TLB available entries\n", - NCHUNK(size), ioread32(dev, PT_NCHUNK_MAX_REG)); - break; - } - - // Allocate memory (will be contigous anyway in baremetal) - mem = aligned_malloc(size); - if (!mem) { - printf("Error: not enough memory\n"); - exit(EXIT_FAILURE); - } - printf(" memory buffer base-address = %p\n", mem); - - if (scatter_gather) { - //Alocate and populate page table - ptable = aligned_malloc(NCHUNK(size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(unsigned))]; - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(size)); - } - - // Initialize input: write floating point hex values (simpler to debug) - printf(" Prepare input... "); - - memcpy(&mem[vals_addr], in_vals_fx_buf, sizeof(int) * vals_size); - memcpy(&mem[cols_addr], in_cols_buf, sizeof(int) * cols_size); - memcpy(&mem[rows_addr], in_rows_buf, sizeof(int) * rows_size); - memcpy(&mem[vect_addr], in_vect_fx_buf, sizeof(int) * vect_size); - - printf("Input ready\n"); - - // Configure device - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); - - if (scatter_gather) { - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - iowrite32(dev, SRC_OFFSET_REG, 0); - iowrite32(dev, DST_OFFSET_REG, 0); // Sort runs in place - } else { - iowrite32(dev, SRC_OFFSET_REG, (unsigned long) mem); - iowrite32(dev, DST_OFFSET_REG, (unsigned long) mem); // Sort runs in place - } - - iowrite32(dev, SPMV_NROWS_REG, nrows); - iowrite32(dev, SPMV_NCOLS_REG, ncols); - iowrite32(dev, SPMV_MAX_NONZERO_REG, max_nonzero); - iowrite32(dev, SPMV_MTX_LEN_REG, mtx_len); - iowrite32(dev, SPMV_VALS_PLM_SIZE_REG, vals_plm_size); - iowrite32(dev, SPMV_VECT_FITS_PLM_REG, vect_fits_plm); - - // Flush for non-coherent DMA - esp_flush(coherence); - - // Start accelerator - printf(" Start..\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - printf(" Done\n"); - - - /* Validation */ - printf(" validating...\n"); - - - memcpy(out_fx_buf, &mem[out_addr], out_size * sizeof(int)); - for (i = 0; i < out_size; i++) - out_buf[i] = fixed32_to_float(out_fx_buf[i], 16); - - errors = validate(gold_buf, out_buf, nrows, 0); - - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - printf("\n"); - - if (scatter_gather) - aligned_free(ptable); - aligned_free(mem); - } - } - return 0; + struct esp_device *dev = &espdevs[n]; + + unsigned done; + unsigned **ptable = NULL; + unsigned *mem; + unsigned errors = 0; + int scatter_gather = 1; + size_t size; + + printf("Testing %s.%d \n", DEV_NAME, n); + + // Check access ok (TODO) + + // Check if scatter-gather DMA is disabled + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled; revert to contiguous buffer.\n"); + scatter_gather = 0; + } + else { + printf(" -> scatter-gather DMA is enabled.\n"); + } + + size = sizeof(int) * (vals_size + cols_size + rows_size + vect_size + out_size); + + if (scatter_gather) + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(size)) { + printf(" Trying to allocate %lu chunks on %d TLB available entries\n", + NCHUNK(size), ioread32(dev, PT_NCHUNK_MAX_REG)); + break; + } + + // Allocate memory (will be contigous anyway in baremetal) + mem = aligned_malloc(size); + if (!mem) { + printf("Error: not enough memory\n"); + exit(EXIT_FAILURE); + } + printf(" memory buffer base-address = %p\n", mem); + + if (scatter_gather) { + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(unsigned))]; + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(size)); + } + + // Initialize input: write floating point hex values (simpler to debug) + printf(" Prepare input... "); + + memcpy(&mem[vals_addr], in_vals_fx_buf, sizeof(int) * vals_size); + memcpy(&mem[cols_addr], in_cols_buf, sizeof(int) * cols_size); + memcpy(&mem[rows_addr], in_rows_buf, sizeof(int) * rows_size); + memcpy(&mem[vect_addr], in_vect_fx_buf, sizeof(int) * vect_size); + + printf("Input ready\n"); + + // Configure device + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); + + if (scatter_gather) { + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + iowrite32(dev, SRC_OFFSET_REG, 0); + iowrite32(dev, DST_OFFSET_REG, 0); // Sort runs in place + } + else { + iowrite32(dev, SRC_OFFSET_REG, (unsigned long)mem); + iowrite32(dev, DST_OFFSET_REG, (unsigned long)mem); // Sort runs in place + } + + iowrite32(dev, SPMV_NROWS_REG, nrows); + iowrite32(dev, SPMV_NCOLS_REG, ncols); + iowrite32(dev, SPMV_MAX_NONZERO_REG, max_nonzero); + iowrite32(dev, SPMV_MTX_LEN_REG, mtx_len); + iowrite32(dev, SPMV_VALS_PLM_SIZE_REG, vals_plm_size); + iowrite32(dev, SPMV_VECT_FITS_PLM_REG, vect_fits_plm); + + // Flush for non-coherent DMA + esp_flush(coherence); + + // Start accelerator + printf(" Start..\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + printf(" Done\n"); + + /* Validation */ + printf(" validating...\n"); + + memcpy(out_fx_buf, &mem[out_addr], out_size * sizeof(int)); + for (i = 0; i < out_size; i++) + out_buf[i] = fixed32_to_float(out_fx_buf[i], 16); + + errors = validate(gold_buf, out_buf, nrows, 0); + + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + printf("\n"); + + if (scatter_gather) aligned_free(ptable); + aligned_free(mem); + } + } + return 0; } - diff --git a/accelerators/stratus_hls/spmv_stratus/sw/linux/app/host/generate.py b/accelerators/stratus_hls/spmv_stratus/sw/linux/app/host/generate.py index 03a545d6aa..23de4eaea4 100755 --- a/accelerators/stratus_hls/spmv_stratus/sw/linux/app/host/generate.py +++ b/accelerators/stratus_hls/spmv_stratus/sw/linux/app/host/generate.py @@ -22,25 +22,25 @@ # Matrix parameters for generation n_mtx = 4 -mtx_m_file = [['inputs/in1.mtx' , 'inputs/in2.mtx', \ - 'inputs/in3.mtx' , 'inputs/in4.mtx'], \ - ['inputs/in_d1.mtx', 'inputs/in_d2.mtx', \ - 'inputs/in_d3.mtx', 'inputs/in_d4.mtx'],\ - ['inputs/in_t1.mtx', 'inputs/in_t2.mtx', \ +mtx_m_file = [['inputs/in1.mtx', 'inputs/in2.mtx', + 'inputs/in3.mtx', 'inputs/in4.mtx'], + ['inputs/in_d1.mtx', 'inputs/in_d2.mtx', + 'inputs/in_d3.mtx', 'inputs/in_d4.mtx'], + ['inputs/in_t1.mtx', 'inputs/in_t2.mtx', 'inputs/in_t3.mtx', 'inputs/in_t4.mtx']] -mtx_data_file = [['inputs/in1.data' , 'inputs/in2.data', \ - 'inputs/in3.data' , 'inputs/in4.data'], \ - ['inputs/in_d1.data', 'inputs/in_d2.data', \ - 'inputs/in_d3.data', 'inputs/in_d4.data'],\ - ['inputs/in_t1.data', 'inputs/in_t2.data', \ +mtx_data_file = [['inputs/in1.data', 'inputs/in2.data', + 'inputs/in3.data', 'inputs/in4.data'], + ['inputs/in_d1.data', 'inputs/in_d2.data', + 'inputs/in_d3.data', 'inputs/in_d4.data'], + ['inputs/in_t1.data', 'inputs/in_t2.data', 'inputs/in_t3.data', 'inputs/in_t4.data']] -mtx_chk_file = [['outputs/chk1.data' , 'outputs/chk2.data', \ - 'outputs/chk3.data' , 'outputs/chk4.data'], \ - ['outputs/chk_d1.data', 'outputs/chk_d2.data', \ - 'outputs/chk_d3.data', 'outputs/chk_d4.data'],\ - ['outputs/chk_t1.data', 'outputs/chk_t2.data', \ +mtx_chk_file = [['outputs/chk1.data', 'outputs/chk2.data', + 'outputs/chk3.data', 'outputs/chk4.data'], + ['outputs/chk_d1.data', 'outputs/chk_d2.data', + 'outputs/chk_d3.data', 'outputs/chk_d4.data'], + ['outputs/chk_t1.data', 'outputs/chk_t2.data', 'outputs/chk_t3.data', 'outputs/chk_t4.data']] mtx_n_rows = [512, 2048, 8192, 65536] @@ -53,156 +53,165 @@ # Write list of matrices to create for t in range(0, mtx_n_types): - for m in range(0, n_mtx): + for m in range(0, n_mtx): - # Acquire parameters defined locally + # Acquire parameters defined locally - m_file = mtx_m_file[t][m] - data_file = mtx_data_file[t][m] - chk_file = mtx_chk_file[t][m] - n_rows = int(mtx_n_rows[m]) - n_cols = int(mtx_n_cols[m]) - max_val = int(mtx_max_val) - max_non_null = int(mtx_max_non_null[m]) - diag_thickness = int(mtx_diag_thickness[m]) + m_file = mtx_m_file[t][m] + data_file = mtx_data_file[t][m] + chk_file = mtx_chk_file[t][m] + n_rows = int(mtx_n_rows[m]) + n_cols = int(mtx_n_cols[m]) + max_val = int(mtx_max_val) + max_non_null = int(mtx_max_non_null[m]) + diag_thickness = int(mtx_diag_thickness[m]) - # Generate matrix + # Generate matrix - random.seed(23, version = 2) + random.seed(23, version=2) - all_rows = [] - all_cols = [] - all_idxs = [] - all_vals = [] - all_vect = [] - all_chks = [] - idx = 0 + all_rows = [] + all_cols = [] + all_idxs = [] + all_vals = [] + all_vect = [] + all_chks = [] + idx = 0 - for r in range(0, n_rows): + for r in range(0, n_rows): - # index of all_vals where this row starts - all_idxs.append(idx) + # index of all_vals where this row starts + all_idxs.append(idx) - # random number of non-null elements for the current row - n_vals = random.randint(1, max_non_null) + # random number of non-null elements for the current row + n_vals = random.randint(1, max_non_null) - # columns to be associated to the random values - if t == 0: - cols = random.sample(range(0, n_cols - 1), n_vals) + # columns to be associated to the random values + if t == 0: + cols = random.sample(range(0, n_cols - 1), n_vals) - elif t == 1: - left_c = max(0, r - diag_thickness) - right_c = min(n_cols - 1, r + diag_thickness) + elif t == 1: + left_c = max(0, r - diag_thickness) + right_c = min(n_cols - 1, r + diag_thickness) - cols = random.sample(range(left_c, right_c), n_vals) + cols = random.sample(range(left_c, right_c), n_vals) - else: - if r == 0: - n_vals = 1 - elif r < max_non_null: - n_vals = random.randint(1, r) + else: + if r == 0: + n_vals = 1 + elif r < max_non_null: + n_vals = random.randint(1, r) - cols = random.sample(range(0, r + 1), n_vals) + cols = random.sample(range(0, r + 1), n_vals) - cols.sort() + cols.sort() - # random float values of matrix elements - vals = [] - for i in range(0, n_vals): - vals.append(random.uniform(-max_val, max_val)) - idx += 1 + # random float values of matrix elements + vals = [] + for i in range(0, n_vals): + vals.append(random.uniform(-max_val, max_val)) + idx += 1 - # append the info of the current row - all_rows.extend(r * np.ones((n_vals,), dtype=np.int)) - all_cols.extend(cols) - all_vals.extend(vals) + # append the info of the current row + all_rows.extend(r * np.ones((n_vals,), dtype=np.int)) + all_cols.extend(cols) + all_vals.extend(vals) - # print(all_rows) - # print(all_cols) - # print(all_vals) + # print(all_rows) + # print(all_cols) + # print(all_vals) - all_idxs.append(idx) + all_idxs.append(idx) - for c in range(0, n_cols): + for c in range(0, n_cols): - all_vect.append(random.uniform(-max_val, max_val)) + all_vect.append(random.uniform(-max_val, max_val)) - # Write matrix to file - fp = open(m_file, "w+") + # Write matrix to file + fp = open(m_file, "w+") - input_size = 4 * (n_rows + len(all_cols)) + 8 * (n_cols + len(all_vals)) + input_size = 4 * (n_rows + len(all_cols)) + \ + 8 * (n_cols + len(all_vals)) - fp.write("%% Rectangular sparse real valued matrix: row col value.\n") - fp.write("%d %d %d %d\n" % (n_rows, n_cols, max_non_null, len(all_vals))) + fp.write("%% Rectangular sparse real valued matrix: row col value.\n") + fp.write( + "%d %d %d %d\n" % + (n_rows, n_cols, max_non_null, len(all_vals))) - for i in range(0, len(all_rows)): + for i in range(0, len(all_rows)): - fp.write("{0:d} {1:d} {2:2.13e}\n".format(all_rows[i], all_cols[i], all_vals[i])) + fp.write( + "{0:d} {1:d} {2:2.13e}\n".format( + all_rows[i], + all_cols[i], + all_vals[i])) - fp.close() + fp.close() - # Write input data for spmv + # Write input data for spmv - fp = open(data_file, "w+") + fp = open(data_file, "w+") - fp.write("%d %d %d %d\n" % (n_rows, n_cols, max_non_null, len(all_vals))) + fp.write( + "%d %d %d %d\n" % + (n_rows, n_cols, max_non_null, len(all_vals))) - # Write array of sparse matrix values + # Write array of sparse matrix values - fp.write("%%\n") + fp.write("%%\n") - for i in range(0, len(all_vals)): + for i in range(0, len(all_vals)): - fp.write("{0:.12g}\n".format(all_vals[i])) + fp.write("{0:.12g}\n".format(all_vals[i])) - # Write columns corresponding to values + # Write columns corresponding to values - fp.write("%%\n") + fp.write("%%\n") - for i in range(0, len(all_cols)): + for i in range(0, len(all_cols)): - fp.write("{0:d}\n".format(all_cols[i])) + fp.write("{0:d}\n".format(all_cols[i])) - # Write indexes of list of values where each row starts + # Write indexes of list of values where each row starts - fp.write("%%\n") + fp.write("%%\n") - for i in range(0, len(all_idxs)): + for i in range(0, len(all_idxs)): - fp.write("{0:d}\n".format(all_idxs[i])) + fp.write("{0:d}\n".format(all_idxs[i])) - # Write vector values + # Write vector values - fp.write("%%\n") + fp.write("%%\n") - for i in range(0, len(all_vect)): + for i in range(0, len(all_vect)): - fp.write("{0:.12g}\n".format(all_vect[i])) + fp.write("{0:.12g}\n".format(all_vect[i])) - fp.close() + fp.close() - # Write check file + # Write check file - fp = open(chk_file, "w+") + fp = open(chk_file, "w+") - fp.write("%%\n") + fp.write("%%\n") - for i in range(0, n_rows): + for i in range(0, n_rows): - accum = 0 - si = 0 + accum = 0 + si = 0 - begin = all_idxs[i] - end = all_idxs[i + 1] + begin = all_idxs[i] + end = all_idxs[i + 1] - for j in range(begin, end): + for j in range(begin, end): - si = all_vals[j] * all_vect[all_cols[j]] + si = all_vals[j] * all_vect[all_cols[j]] - accum += si + accum += si - all_chks.append(accum) + all_chks.append(accum) - fp.write("{0:.12g}\n".format(accum)) + fp.write("{0:.12g}\n".format(accum)) - fp.close() + fp.close() diff --git a/accelerators/stratus_hls/spmv_stratus/sw/linux/app/host/harness.c b/accelerators/stratus_hls/spmv_stratus/sw/linux/app/host/harness.c index 345f547f99..67e7e8d8cd 100644 --- a/accelerators/stratus_hls/spmv_stratus/sw/linux/app/host/harness.c +++ b/accelerators/stratus_hls/spmv_stratus/sw/linux/app/host/harness.c @@ -1,12 +1,12 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include +#include +#include #include +#include #include -#include -#include #include -#include +#include #define WRITE_OUTPUT #define CHECK_OUTPUT @@ -24,7 +24,7 @@ int main(int argc, char **argv) /* Parse command line. */ - assert((argc == 5) && "Wrong command line arguments" ); + assert((argc == 5) && "Wrong command line arguments"); ret = sprintf(in_file, "inputs/in%s.data", argv[1]); assert((ret >= 0) && "Error sprintf"); @@ -48,27 +48,27 @@ int main(int argc, char **argv) data.val = malloc(sizeof(TYPE) * data.mtx_len); assert(data.val != NULL && "Out of memory"); - memset((void *) data.val, 0, sizeof(TYPE) * data.mtx_len); + memset((void *)data.val, 0, sizeof(TYPE) * data.mtx_len); data.cols = malloc(sizeof(int) * data.mtx_len); assert(data.cols != NULL && "Out of memory"); - memset((void *) data.cols, 0, sizeof(int) * data.mtx_len); + memset((void *)data.cols, 0, sizeof(int) * data.mtx_len); data.rowDelimiters = malloc(sizeof(int) * (data.nrows + 1)); assert(data.rowDelimiters != NULL && "Out of memory"); - memset((void *) data.rowDelimiters, 0, sizeof(int) * data.nrows); + memset((void *)data.rowDelimiters, 0, sizeof(int) * data.nrows); data.vec = malloc(sizeof(TYPE) * data.ncols); assert(data.vec != NULL && "Out of memory"); - memset((void *) data.vec, 0, sizeof(TYPE) * data.ncols); + memset((void *)data.vec, 0, sizeof(TYPE) * data.ncols); data.out = malloc(sizeof(TYPE) * data.nrows); assert(data.out != NULL && "Out of memory"); - memset((void *) data.out, 0, sizeof(TYPE) * data.nrows); + memset((void *)data.out, 0, sizeof(TYPE) * data.nrows); data.chk = malloc(sizeof(TYPE) * data.nrows); assert(data.chk != NULL && "Out of memory"); - memset((void *) data.chk, 0, sizeof(TYPE) * data.nrows); + memset((void *)data.chk, 0, sizeof(TYPE) * data.nrows); /* Load input data */ @@ -87,8 +87,9 @@ int main(int argc, char **argv) #ifdef WRITE_OUTPUT int out_fd; - out_fd = open(out_file, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); - assert(out_fd > 0 && "Couldn't open output data file" ); + out_fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + assert(out_fd > 0 && "Couldn't open output data file"); data_to_output(out_fd, &data); close(out_fd); #endif @@ -97,29 +98,29 @@ int main(int argc, char **argv) #ifdef CHECK_OUTPUT int check_fd; - + check_fd = open(chk_file, O_RDONLY); assert(check_fd > 0 && "Couldn't open check data file"); output_to_data(check_fd, &data); close(check_fd); #endif - + /* Validate results */ #ifdef CHECK_OUTPUT - if(!check_data(&data) ) { - fprintf(stderr, "Benchmark results are incorrect\n"); - return -1; + if (!check_data(&data)) { + fprintf(stderr, "Benchmark results are incorrect\n"); + return -1; } #endif - + free(data.val); free(data.cols); free(data.rowDelimiters); free(data.vec); free(data.out); free(data.chk); - + printf("Success.\n"); return 0; diff --git a/accelerators/stratus_hls/spmv_stratus/sw/linux/app/spmv.c b/accelerators/stratus_hls/spmv_stratus/sw/linux/app/spmv.c index 7b6700773e..a7879db9b7 100644 --- a/accelerators/stratus_hls/spmv_stratus/sw/linux/app/spmv.c +++ b/accelerators/stratus_hls/spmv_stratus/sw/linux/app/spmv.c @@ -1,72 +1,73 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 +#include +#include #include +#include #include #include #include -#include -#include -#include +#include #include +#include #include #include -#include -#include #define DEVNAME "/dev/spmv_stratus.0" -#define NAME "spmv_stratus" - -static const char usage_str[] = "usage: spmv_stratus coherence cmd [plm_size] [fit_plm] [in_file] [-v]\n" - " coherence : none|llc-coh-dma|coh-dma|coh\n" - " cmd : config|test|run|hw\n" - "\n" - "Optional arguments: these are required for 'config', 'test' and 'hw'\n" - " plm_size : must be at most 1024 and a power of 2\n" - " fit_plm : when not zero the dense vector is kept in the PLM if cols < 8K\n" - " in_file : input matrix, input vector and configuration parameters\n" - "\n" - "Other optional arguments:\n" - " -v : 'test' prints mismatched values in case of errors above threshold\n"; +#define NAME "spmv_stratus" + +static const char usage_str[] = + "usage: spmv_stratus coherence cmd [plm_size] [fit_plm] [in_file] [-v]\n" + " coherence : none|llc-coh-dma|coh-dma|coh\n" + " cmd : config|test|run|hw\n" + "\n" + "Optional arguments: these are required for 'config', 'test' and 'hw'\n" + " plm_size : must be at most 1024 and a power of 2\n" + " fit_plm : when not zero the dense vector is kept in the PLM if cols < 8K\n" + " in_file : input matrix, input vector and configuration parameters\n" + "\n" + "Other optional arguments:\n" + " -v : 'test' prints mismatched values in case of errors above threshold\n"; struct spmv_test { - struct test_info info; - struct spmv_stratus_access desc; - - unsigned int nrows; - unsigned int ncols; - unsigned int max_nonzero; - unsigned int mtx_len; - unsigned int vals_plm_size; - unsigned int vect_fits_plm; - - const char *in_file; - - bool verbose; - - unsigned vals_addr; - unsigned cols_addr; - unsigned rows_addr; - unsigned vect_addr; - unsigned out_addr; - - unsigned vals_size; - unsigned cols_size; - unsigned rows_size; - unsigned vect_size; - unsigned out_size; - - float *in_vals_buf; - unsigned *in_cols_buf; - unsigned *in_rows_buf; - float *in_vect_buf; - float *out_buf; - - int *in_vals_fx_buf; - int *in_vect_fx_buf; - int *out_fx_buf; - - float *gold_buf; + struct test_info info; + struct spmv_stratus_access desc; + + unsigned int nrows; + unsigned int ncols; + unsigned int max_nonzero; + unsigned int mtx_len; + unsigned int vals_plm_size; + unsigned int vect_fits_plm; + + const char *in_file; + + bool verbose; + + unsigned vals_addr; + unsigned cols_addr; + unsigned rows_addr; + unsigned vect_addr; + unsigned out_addr; + + unsigned vals_size; + unsigned cols_size; + unsigned rows_size; + unsigned vect_size; + unsigned out_size; + + float *in_vals_buf; + unsigned *in_cols_buf; + unsigned *in_rows_buf; + float *in_vect_buf; + float *out_buf; + + int *in_vals_fx_buf; + int *in_vect_fx_buf; + int *out_fx_buf; + + float *gold_buf; }; /* @@ -74,119 +75,108 @@ struct spmv_test { */ static inline struct spmv_test *to_spmv(struct test_info *info) { - return container_of(info, struct spmv_test, info); + return container_of(info, struct spmv_test, info); } static inline size_t spmv_in_size(struct spmv_test *test) { - return sizeof(int) * (test->vals_size + test->cols_size + test->rows_size + test->vect_size); + return sizeof(int) * (test->vals_size + test->cols_size + test->rows_size + test->vect_size); } -static inline size_t spmv_out_size(struct spmv_test *test) -{ - return sizeof(int) * test->out_size; -} +static inline size_t spmv_out_size(struct spmv_test *test) { return sizeof(int) * test->out_size; } -static inline size_t spmv_out_addr(struct spmv_test *test) -{ - return sizeof(int) * test->out_addr; -} +static inline size_t spmv_out_addr(struct spmv_test *test) { return sizeof(int) * test->out_addr; } static inline size_t spmv_size(struct spmv_test *test) { - return spmv_in_size(test) + spmv_out_size(test); + return spmv_in_size(test) + spmv_out_size(test); } - - /* * spmv_alloc_buf */ static void spmv_alloc_buf(struct test_info *info) { - struct spmv_test *test = to_spmv(info); - - FILE *fp; - char str_tmp[4]; - int i; - - fp = fopen(test->in_file, "r"); - if (!fp) - die_errno("%s: cannot open file %s", __func__, test->in_file); - - // Read configuration - fscanf(fp, "%u %u %u %u\n", &test->nrows, &test->ncols, &test->max_nonzero, &test->mtx_len); - - printf("config: %u %u %u %u\n", test->nrows, test->ncols, test->max_nonzero, test->mtx_len); - - // Set data structure offsets (4B words) - test->vals_addr = 0; - test->vals_size = test->mtx_len; - - test->cols_addr = test->mtx_len; - test->cols_size = test->mtx_len; - - test->rows_addr = 2 * test->mtx_len; - test->rows_size = test->nrows; - - test->vect_addr = test->nrows + 2 * test->mtx_len; - test->vect_size = test->ncols; - - test->out_addr = test->nrows + 2 * test->mtx_len + test->ncols; - test->out_size = test->nrows; - - // Allocate input buffers - test->in_vals_buf = malloc0_check(sizeof(float) * test->vals_size); - test->in_cols_buf = malloc0_check(sizeof(unsigned) * test->cols_size); - test->in_rows_buf = malloc0_check(sizeof(unsigned) * test->rows_size); - test->in_vect_buf = malloc0_check(sizeof(float) * test->vect_size); - test->out_buf = malloc0_check(sizeof(float) * test->out_size); - - test->in_vals_fx_buf = malloc0_check(sizeof(int) * test->vals_size); - test->in_vect_fx_buf = malloc0_check(sizeof(int) * test->vect_size); - test->out_fx_buf = malloc0_check(sizeof(int) * test->out_size); - - // Read input data - // Vals - fscanf(fp, "%s\n", str_tmp); // Read separator line: %% - for (i = 0; i < test->vals_size; i++) { - float val; - fscanf(fp, "%f\n", &val); - test->in_vals_buf[i] = val; - } - // Cols - fscanf(fp, "%s\n", str_tmp); // Read separator line: %% - for (i = 0; i < test->cols_size; i++) { - uint32_t col; - fscanf(fp, "%u\n", &col); - test->in_cols_buf[i] = col; - } - // Rows - fscanf(fp, "%s\n", str_tmp); // Read separator line: %% - fscanf(fp, "%s\n", str_tmp); // Read 0 - for (i = 0; i < test->rows_size; i++) { - uint32_t row; - fscanf(fp, "%u\n", &row); - test->in_rows_buf[i] = row; - } - // Vect - fscanf(fp, "%s\n", str_tmp); // Read separator line: %% - for (i = 0; i < test->vect_size; i++) { - float vect; - fscanf(fp, "%f\n", &vect); - test->in_vect_buf[i] = vect; // FPDATA -> sc_bv and store it - } - - fclose(fp); - - // Gold - if (!strcmp(info->cmd, "test")) { - test->gold_buf = malloc0_check(sizeof(float) * test->out_size); - } -} + struct spmv_test *test = to_spmv(info); + + FILE *fp; + char str_tmp[4]; + int i; + + fp = fopen(test->in_file, "r"); + if (!fp) die_errno("%s: cannot open file %s", __func__, test->in_file); + + // Read configuration + fscanf(fp, "%u %u %u %u\n", &test->nrows, &test->ncols, &test->max_nonzero, &test->mtx_len); + + printf("config: %u %u %u %u\n", test->nrows, test->ncols, test->max_nonzero, test->mtx_len); + + // Set data structure offsets (4B words) + test->vals_addr = 0; + test->vals_size = test->mtx_len; + + test->cols_addr = test->mtx_len; + test->cols_size = test->mtx_len; + + test->rows_addr = 2 * test->mtx_len; + test->rows_size = test->nrows; + test->vect_addr = test->nrows + 2 * test->mtx_len; + test->vect_size = test->ncols; + test->out_addr = test->nrows + 2 * test->mtx_len + test->ncols; + test->out_size = test->nrows; + + // Allocate input buffers + test->in_vals_buf = malloc0_check(sizeof(float) * test->vals_size); + test->in_cols_buf = malloc0_check(sizeof(unsigned) * test->cols_size); + test->in_rows_buf = malloc0_check(sizeof(unsigned) * test->rows_size); + test->in_vect_buf = malloc0_check(sizeof(float) * test->vect_size); + test->out_buf = malloc0_check(sizeof(float) * test->out_size); + + test->in_vals_fx_buf = malloc0_check(sizeof(int) * test->vals_size); + test->in_vect_fx_buf = malloc0_check(sizeof(int) * test->vect_size); + test->out_fx_buf = malloc0_check(sizeof(int) * test->out_size); + + // Read input data + // Vals + fscanf(fp, "%s\n", str_tmp); // Read separator line: %% + for (i = 0; i < test->vals_size; i++) { + float val; + fscanf(fp, "%f\n", &val); + test->in_vals_buf[i] = val; + } + // Cols + fscanf(fp, "%s\n", str_tmp); // Read separator line: %% + for (i = 0; i < test->cols_size; i++) { + uint32_t col; + fscanf(fp, "%u\n", &col); + test->in_cols_buf[i] = col; + } + // Rows + fscanf(fp, "%s\n", str_tmp); // Read separator line: %% + fscanf(fp, "%s\n", str_tmp); // Read 0 + for (i = 0; i < test->rows_size; i++) { + uint32_t row; + fscanf(fp, "%u\n", &row); + test->in_rows_buf[i] = row; + } + // Vect + fscanf(fp, "%s\n", str_tmp); // Read separator line: %% + for (i = 0; i < test->vect_size; i++) { + float vect; + fscanf(fp, "%f\n", &vect); + test->in_vect_buf[i] = vect; // FPDATA -> sc_bv and store it + } + + fclose(fp); + + // Gold + if (!strcmp(info->cmd, "test")) { + test->gold_buf = malloc0_check(sizeof(float) * test->out_size); + } +} /* * spmv_alloc_contig @@ -194,50 +184,52 @@ static void spmv_alloc_buf(struct test_info *info) static void spmv_alloc_contig(struct test_info *info) { - struct spmv_test *test = to_spmv(info); - size_t size = spmv_size(test); + struct spmv_test *test = to_spmv(info); + size_t size = spmv_size(test); - printf("HW buf size: %zu\n", size); - if (contig_alloc(size, &info->contig) == NULL) - die_errno(__func__); + printf("HW buf size: %zu\n", size); + if (contig_alloc(size, &info->contig) == NULL) die_errno(__func__); } - /* * spmv_init_bufs */ static void spmv_init_bufs(struct test_info *info) { - struct spmv_test *test = to_spmv(info); - int i; - - // Convert to fixed point - printf("Converting input data to fixed point...\n"); - for (i = 0; i < test->vals_size; i++) - test->in_vals_fx_buf[i] = float_to_fixed32(test->in_vals_buf[i], 16); - - for (i = 0; i < test->vect_size; i++) - test->in_vect_fx_buf[i] = float_to_fixed32(test->in_vect_buf[i], 16); - - // Memory layout - - // =========================== ^ - // | vals (input) (float) | | mtx_len - // =========================== - - // | cols (input) (uint) | | mtx_len - // =========================== - - // | rows (input) (uint) | | nrows - // =========================== - - // | vect (input) (float) | | ncols - // =========================== - - // | cols (output) (float) | | nrows - // =========================== v - - contig_copy_to(info->contig, sizeof(int) * test->vals_addr, test->in_vals_fx_buf, sizeof(int) * test->vals_size); - contig_copy_to(info->contig, sizeof(int) * test->cols_addr, test->in_cols_buf, sizeof(int) * test->cols_size); - contig_copy_to(info->contig, sizeof(int) * test->rows_addr, test->in_rows_buf, sizeof(int) * test->rows_size); - contig_copy_to(info->contig, sizeof(int) * test->vect_addr, test->in_vect_fx_buf, sizeof(int) * test->vect_size); + struct spmv_test *test = to_spmv(info); + int i; + + // Convert to fixed point + printf("Converting input data to fixed point...\n"); + for (i = 0; i < test->vals_size; i++) + test->in_vals_fx_buf[i] = float_to_fixed32(test->in_vals_buf[i], 16); + + for (i = 0; i < test->vect_size; i++) + test->in_vect_fx_buf[i] = float_to_fixed32(test->in_vect_buf[i], 16); + + // Memory layout + + // =========================== ^ + // | vals (input) (float) | | mtx_len + // =========================== - + // | cols (input) (uint) | | mtx_len + // =========================== - + // | rows (input) (uint) | | nrows + // =========================== - + // | vect (input) (float) | | ncols + // =========================== - + // | cols (output) (float) | | nrows + // =========================== v + + contig_copy_to(info->contig, sizeof(int) * test->vals_addr, test->in_vals_fx_buf, + sizeof(int) * test->vals_size); + contig_copy_to(info->contig, sizeof(int) * test->cols_addr, test->in_cols_buf, + sizeof(int) * test->cols_size); + contig_copy_to(info->contig, sizeof(int) * test->rows_addr, test->in_rows_buf, + sizeof(int) * test->rows_size); + contig_copy_to(info->contig, sizeof(int) * test->vect_addr, test->in_vect_fx_buf, + sizeof(int) * test->vect_size); } /* @@ -246,17 +238,16 @@ static void spmv_init_bufs(struct test_info *info) static void spmv_set_access(struct test_info *info) { - struct spmv_test *test = to_spmv(info); - - test->desc.nrows = test->nrows; - test->desc.ncols = test->ncols; - test->desc.max_nonzero = test->max_nonzero; - test->desc.mtx_len = test->mtx_len; - test->desc.vals_plm_size = test->vals_plm_size; - test->desc.vect_fits_plm = test->vect_fits_plm; + struct spmv_test *test = to_spmv(info); + + test->desc.nrows = test->nrows; + test->desc.ncols = test->ncols; + test->desc.max_nonzero = test->max_nonzero; + test->desc.mtx_len = test->mtx_len; + test->desc.vals_plm_size = test->vals_plm_size; + test->desc.vect_fits_plm = test->vect_fits_plm; } - /* * smpv_diff_ok */ @@ -268,99 +259,93 @@ int check_error_threshold(float out, float gold) { float error; - if (gold != 0) - error = fabs((gold - out) / gold); + if (gold != 0) error = fabs((gold - out) / gold); else if (out != 0) error = fabs((out - gold) / out); else - error = 0; + error = 0; - if (fabs(gold) >= 1) { - return (error > MAX_REL_ERROR); - } else { - return (fabs(gold - out) > MAX_ABS_ERROR); + if (fabs(gold) >= 1) { return (error > MAX_REL_ERROR); } + else { + return (fabs(gold - out) > MAX_ABS_ERROR); } } static int check_gold(float *gold, float *out, int nrows, bool verbose) { - int i; - int rtn = 0; + int i; + int rtn = 0; - for (i = 0; i < nrows; i++) - if (check_error_threshold(out[i], gold[i])) { - if (verbose) - printf("out[%d]: result=%.15g; gold=%.15g\n", i, out[i], gold[i]); - rtn++; - } + for (i = 0; i < nrows; i++) + if (check_error_threshold(out[i], gold[i])) { + if (verbose) printf("out[%d]: result=%.15g; gold=%.15g\n", i, out[i], gold[i]); + rtn++; + } - return rtn; + return rtn; } static bool spmv_diff_ok(struct test_info *info) { - struct spmv_test *t = to_spmv(info); - int total_err = 0; - int i; + struct spmv_test *t = to_spmv(info); + int total_err = 0; + int i; - contig_copy_from(t->out_fx_buf, info->contig, spmv_out_addr(t), spmv_out_size(t)); + contig_copy_from(t->out_fx_buf, info->contig, spmv_out_addr(t), spmv_out_size(t)); - for (i = 0; i < t->out_size; i++) { - t->out_buf[i] = fixed32_to_float(t->out_fx_buf[i], 16); - } + for (i = 0; i < t->out_size; i++) { + t->out_buf[i] = fixed32_to_float(t->out_fx_buf[i], 16); + } - total_err = check_gold(t->gold_buf, t->out_buf, t->nrows, t->verbose); - if (total_err) - printf("%d mismatches in total\n", total_err); - return !total_err; + total_err = check_gold(t->gold_buf, t->out_buf, t->nrows, t->verbose); + if (total_err) printf("%d mismatches in total\n", total_err); + return !total_err; } void spmv_comp(struct test_info *info) { - struct spmv_test *t = to_spmv(info); - long i, j; - double sum, Si; - - for(i = 0; i < t->nrows; i++) { - int tmp_begin; - int tmp_end; - sum = 0; Si = 0; + struct spmv_test *t = to_spmv(info); + long i, j; + double sum, Si; - if (i == 0) - tmp_begin = 0; - else - tmp_begin= t->in_rows_buf[i - 1]; + for (i = 0; i < t->nrows; i++) { + int tmp_begin; + int tmp_end; + sum = 0; + Si = 0; - tmp_end = t->in_rows_buf[i]; + if (i == 0) tmp_begin = 0; + else + tmp_begin = t->in_rows_buf[i - 1]; - for (j = tmp_begin; j < tmp_end; j++) { - Si = t->in_vals_buf[j] * t->in_vect_buf[t->in_cols_buf[j]]; - sum = sum + Si; - } - - t->gold_buf[i] = sum; - } + tmp_end = t->in_rows_buf[i]; + for (j = tmp_begin; j < tmp_end; j++) { + Si = t->in_vals_buf[j] * t->in_vect_buf[t->in_cols_buf[j]]; + sum = sum + Si; + } + t->gold_buf[i] = sum; + } } - /* * Test operations assignment */ static struct spmv_test spmv_test = { - .info = { - .name = NAME, - .devname = DEVNAME, - .alloc_buf = spmv_alloc_buf, - .alloc_contig = spmv_alloc_contig, - .init_bufs = spmv_init_bufs, - .set_access = spmv_set_access, - .diff_ok = spmv_diff_ok, - .comp = spmv_comp, - .esp = &spmv_test.desc.esp, - .cm = SPMV_STRATUS_IOC_ACCESS, - }, + .info = + { + .name = NAME, + .devname = DEVNAME, + .alloc_buf = spmv_alloc_buf, + .alloc_contig = spmv_alloc_contig, + .init_bufs = spmv_init_bufs, + .set_access = spmv_set_access, + .diff_ok = spmv_diff_ok, + .comp = spmv_comp, + .esp = &spmv_test.desc.esp, + .cm = SPMV_STRATUS_IOC_ACCESS, + }, }; /* @@ -368,38 +353,34 @@ static struct spmv_test spmv_test = { */ static void NORETURN usage(void) { - fprintf(stderr, "%s", usage_str); - exit(1); + fprintf(stderr, "%s", usage_str); + exit(1); } int main(int argc, char *argv[]) { - int n_argc; - - if (argc < 3) - usage(); - - if (!strcmp(argv[2], "run")) - n_argc = 3; - else if (!strcmp(argv[2], "test")) - n_argc = 6; - else - n_argc = 5; - - if (argc < n_argc) - usage(); - - spmv_test.verbose = false; - if (n_argc > 3) { - spmv_test.vals_plm_size = strtoul(argv[3], NULL, 0); - spmv_test.vect_fits_plm = strtoul(argv[4], NULL, 0); - spmv_test.in_file = argv[5]; - if (argc == 7) { - if (strcmp(argv[6], "-v")) - usage(); - spmv_test.verbose = true; - } - } - - return test_main(&spmv_test.info, argv[1], argv[2]); + int n_argc; + + if (argc < 3) usage(); + + if (!strcmp(argv[2], "run")) n_argc = 3; + else if (!strcmp(argv[2], "test")) + n_argc = 6; + else + n_argc = 5; + + if (argc < n_argc) usage(); + + spmv_test.verbose = false; + if (n_argc > 3) { + spmv_test.vals_plm_size = strtoul(argv[3], NULL, 0); + spmv_test.vect_fits_plm = strtoul(argv[4], NULL, 0); + spmv_test.in_file = argv[5]; + if (argc == 7) { + if (strcmp(argv[6], "-v")) usage(); + spmv_test.verbose = true; + } + } + + return test_main(&spmv_test.info, argv[1], argv[2]); } diff --git a/accelerators/stratus_hls/spmv_stratus/sw/linux/driver/spmv_stratus.c b/accelerators/stratus_hls/spmv_stratus/sw/linux/driver/spmv_stratus.c index 62fcd1200f..c3d7273e24 100644 --- a/accelerators/stratus_hls/spmv_stratus/sw/linux/driver/spmv_stratus.c +++ b/accelerators/stratus_hls/spmv_stratus/sw/linux/driver/spmv_stratus.c @@ -1,159 +1,144 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include -#include #include +#include +#include #include -#include #include +#include #include "spmv_stratus.h" -#define DRV_NAME "spmv_stratus" +#define DRV_NAME "spmv_stratus" -#define SPMV_NROWS_REG 0x40 -#define SPMV_NCOLS_REG 0x44 -#define SPMV_MAX_NONZERO_REG 0x48 -#define SPMV_MTX_LEN_REG 0x4C -#define SPMV_VALS_PLM_SIZE_REG 0x50 -#define SPMV_VECT_FITS_PLM_REG 0x54 +#define SPMV_NROWS_REG 0x40 +#define SPMV_NCOLS_REG 0x44 +#define SPMV_MAX_NONZERO_REG 0x48 +#define SPMV_MTX_LEN_REG 0x4C +#define SPMV_VALS_PLM_SIZE_REG 0x50 +#define SPMV_VECT_FITS_PLM_REG 0x54 struct spmv_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver spmv_driver; static struct of_device_id spmv_device_ids[] = { - { - .name = "SLD_SPMV_STRATUS", - }, - { - .name = "eb_00c", - }, - { - .compatible = "sld,spmv_stratus", - }, - { }, + { + .name = "SLD_SPMV_STRATUS", + }, + { + .name = "eb_00c", + }, + { + .compatible = "sld,spmv_stratus", + }, + {}, }; static int spmv_devs; static inline struct spmv_stratus_device *to_spmv(struct esp_device *esp) { - return container_of(esp, struct spmv_stratus_device, esp); + return container_of(esp, struct spmv_stratus_device, esp); } static void spmv_prep_xfer(struct esp_device *esp, void *arg) { - struct spmv_stratus_access *a = arg; - - iowrite32be(a->nrows, esp->iomem + SPMV_NROWS_REG); - iowrite32be(a->ncols, esp->iomem + SPMV_NCOLS_REG); - iowrite32be(a->max_nonzero, esp->iomem + SPMV_MAX_NONZERO_REG); - iowrite32be(a->mtx_len, esp->iomem + SPMV_MTX_LEN_REG); - iowrite32be(a->vals_plm_size, esp->iomem + SPMV_VALS_PLM_SIZE_REG); - iowrite32be(a->vect_fits_plm, esp->iomem + SPMV_VECT_FITS_PLM_REG); + struct spmv_stratus_access *a = arg; + + iowrite32be(a->nrows, esp->iomem + SPMV_NROWS_REG); + iowrite32be(a->ncols, esp->iomem + SPMV_NCOLS_REG); + iowrite32be(a->max_nonzero, esp->iomem + SPMV_MAX_NONZERO_REG); + iowrite32be(a->mtx_len, esp->iomem + SPMV_MTX_LEN_REG); + iowrite32be(a->vals_plm_size, esp->iomem + SPMV_VALS_PLM_SIZE_REG); + iowrite32be(a->vect_fits_plm, esp->iomem + SPMV_VECT_FITS_PLM_REG); } static bool spmv_xfer_input_ok(struct esp_device *esp, void *arg) { - struct spmv_stratus_access *a = arg; - long long unsigned mtx_max = ((long long unsigned) a->nrows) * ((long long unsigned) a->ncols); + struct spmv_stratus_access *a = arg; + long long unsigned mtx_max = ((long long unsigned)a->nrows) * ((long long unsigned)a->ncols); - if (!is_power_of_2(a->nrows)) - return false; + if (!is_power_of_2(a->nrows)) return false; - if (!is_power_of_2(a->ncols)) - return false; + if (!is_power_of_2(a->ncols)) return false; - if (!is_power_of_2(a->max_nonzero)) - return false; + if (!is_power_of_2(a->max_nonzero)) return false; - if (a->max_nonzero > 32 || a->max_nonzero < 4) - return false; + if (a->max_nonzero > 32 || a->max_nonzero < 4) return false; - if (a->mtx_len == 0 || ((long long unsigned) a->mtx_len) > mtx_max) - return false; + if (a->mtx_len == 0 || ((long long unsigned)a->mtx_len) > mtx_max) return false; - if (!is_power_of_2(a->vals_plm_size)) - return false; + if (!is_power_of_2(a->vals_plm_size)) return false; - if (a->vals_plm_size < 16 || a->vals_plm_size > 1024) - return false; + if (a->vals_plm_size < 16 || a->vals_plm_size > 1024) return false; - if (a->vect_fits_plm && a->ncols > 8192) - return false; + if (a->vect_fits_plm && a->ncols > 8192) return false; - return true; + return true; } static int spmv_probe(struct platform_device *pdev) { - struct spmv_stratus_device *spmv; - struct esp_device *esp; - int rc; - - spmv = kzalloc(sizeof(*spmv), GFP_KERNEL); - if (spmv == NULL) - return -ENOMEM; - esp = &spmv->esp; - esp->module = THIS_MODULE; - esp->number = spmv_devs; - esp->driver = &spmv_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - spmv_devs++; - return 0; - err: - kfree(spmv); - return rc; + struct spmv_stratus_device *spmv; + struct esp_device *esp; + int rc; + + spmv = kzalloc(sizeof(*spmv), GFP_KERNEL); + if (spmv == NULL) return -ENOMEM; + esp = &spmv->esp; + esp->module = THIS_MODULE; + esp->number = spmv_devs; + esp->driver = &spmv_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + spmv_devs++; + return 0; +err: + kfree(spmv); + return rc; } static int __exit spmv_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct spmv_stratus_device *spmv = to_spmv(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct spmv_stratus_device *spmv = to_spmv(esp); - esp_device_unregister(esp); - kfree(spmv); - return 0; + esp_device_unregister(esp); + kfree(spmv); + return 0; } static struct esp_driver spmv_driver = { - .plat = { - .probe = spmv_probe, - .remove = spmv_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = spmv_device_ids, - }, - }, - .xfer_input_ok = spmv_xfer_input_ok, - .prep_xfer = spmv_prep_xfer, - .ioctl_cm = SPMV_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct spmv_stratus_access), + .plat = + { + .probe = spmv_probe, + .remove = spmv_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = spmv_device_ids, + }, + }, + .xfer_input_ok = spmv_xfer_input_ok, + .prep_xfer = spmv_prep_xfer, + .ioctl_cm = SPMV_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct spmv_stratus_access), }; -static int __init spmv_init(void) -{ - return esp_driver_register(&spmv_driver); -} +static int __init spmv_init(void) { return esp_driver_register(&spmv_driver); } -static void __exit spmv_exit(void) -{ - esp_driver_unregister(&spmv_driver); -} +static void __exit spmv_exit(void) { esp_driver_unregister(&spmv_driver); } -module_init(spmv_init) -module_exit(spmv_exit) +module_init(spmv_init) module_exit(spmv_exit) -MODULE_DEVICE_TABLE(of, spmv_device_ids); + MODULE_DEVICE_TABLE(of, spmv_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/spmv_stratus/sw/linux/include/spmv_stratus.h b/accelerators/stratus_hls/spmv_stratus/sw/linux/include/spmv_stratus.h index eafd28514b..e2a6ce5b6a 100644 --- a/accelerators/stratus_hls/spmv_stratus/sw/linux/include/spmv_stratus.h +++ b/accelerators/stratus_hls/spmv_stratus/sw/linux/include/spmv_stratus.h @@ -4,41 +4,41 @@ #define _SPMV_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct spmv_stratus_access { - struct esp_access esp; - // Rows of input matrix. Rows of output vector. - // Powers of 2 - unsigned int nrows; - // Cols of input matrix. Cols of input vector. - // Powers of 2 - unsigned int ncols; - // Max of non-zero entries in a matrix row. - // 4, 8, 16 or 32 - unsigned int max_nonzero; - // Number of total nonzero matrix elements - // Stored in .data input file - unsigned int mtx_len; - // PLM size to be used for values. All other sizes are derived - // Max is 1024 - unsigned int vals_plm_size; - // 'True' is the vector size fits the vector PLM and if it should be stored there - // Set to false if ncols > 8192 - unsigned int vect_fits_plm; + struct esp_access esp; + // Rows of input matrix. Rows of output vector. + // Powers of 2 + unsigned int nrows; + // Cols of input matrix. Cols of input vector. + // Powers of 2 + unsigned int ncols; + // Max of non-zero entries in a matrix row. + // 4, 8, 16 or 32 + unsigned int max_nonzero; + // Number of total nonzero matrix elements + // Stored in .data input file + unsigned int mtx_len; + // PLM size to be used for values. All other sizes are derived + // Max is 1024 + unsigned int vals_plm_size; + // 'True' is the vector size fits the vector PLM and if it should be stored there + // Set to false if ncols > 8192 + unsigned int vect_fits_plm; }; -#define SPMV_STRATUS_IOC_ACCESS _IOW ('S', 0, struct spmv_stratus_access) +#define SPMV_STRATUS_IOC_ACCESS _IOW('S', 0, struct spmv_stratus_access) #endif /* _SPMV_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/synth_stratus/hw/src/log2.h b/accelerators/stratus_hls/synth_stratus/hw/src/log2.h index 03c819390e..260a2284cd 100644 --- a/accelerators/stratus_hls/synth_stratus/hw/src/log2.h +++ b/accelerators/stratus_hls/synth_stratus/hw/src/log2.h @@ -12,71 +12,126 @@ * the massive ternary operator construction * */ -#define ilog2(n) \ - ( \ - (n) < 2 ? 0 : \ - (n) & (1ULL << 63) ? 63 : \ - (n) & (1ULL << 62) ? 62 : \ - (n) & (1ULL << 61) ? 61 : \ - (n) & (1ULL << 60) ? 60 : \ - (n) & (1ULL << 59) ? 59 : \ - (n) & (1ULL << 58) ? 58 : \ - (n) & (1ULL << 57) ? 57 : \ - (n) & (1ULL << 56) ? 56 : \ - (n) & (1ULL << 55) ? 55 : \ - (n) & (1ULL << 54) ? 54 : \ - (n) & (1ULL << 53) ? 53 : \ - (n) & (1ULL << 52) ? 52 : \ - (n) & (1ULL << 51) ? 51 : \ - (n) & (1ULL << 50) ? 50 : \ - (n) & (1ULL << 49) ? 49 : \ - (n) & (1ULL << 48) ? 48 : \ - (n) & (1ULL << 47) ? 47 : \ - (n) & (1ULL << 46) ? 46 : \ - (n) & (1ULL << 45) ? 45 : \ - (n) & (1ULL << 44) ? 44 : \ - (n) & (1ULL << 43) ? 43 : \ - (n) & (1ULL << 42) ? 42 : \ - (n) & (1ULL << 41) ? 41 : \ - (n) & (1ULL << 40) ? 40 : \ - (n) & (1ULL << 39) ? 39 : \ - (n) & (1ULL << 38) ? 38 : \ - (n) & (1ULL << 37) ? 37 : \ - (n) & (1ULL << 36) ? 36 : \ - (n) & (1ULL << 35) ? 35 : \ - (n) & (1ULL << 34) ? 34 : \ - (n) & (1ULL << 33) ? 33 : \ - (n) & (1ULL << 32) ? 32 : \ - (n) & (1ULL << 31) ? 31 : \ - (n) & (1ULL << 30) ? 30 : \ - (n) & (1ULL << 29) ? 29 : \ - (n) & (1ULL << 28) ? 28 : \ - (n) & (1ULL << 27) ? 27 : \ - (n) & (1ULL << 26) ? 26 : \ - (n) & (1ULL << 25) ? 25 : \ - (n) & (1ULL << 24) ? 24 : \ - (n) & (1ULL << 23) ? 23 : \ - (n) & (1ULL << 22) ? 22 : \ - (n) & (1ULL << 21) ? 21 : \ - (n) & (1ULL << 20) ? 20 : \ - (n) & (1ULL << 19) ? 19 : \ - (n) & (1ULL << 18) ? 18 : \ - (n) & (1ULL << 17) ? 17 : \ - (n) & (1ULL << 16) ? 16 : \ - (n) & (1ULL << 15) ? 15 : \ - (n) & (1ULL << 14) ? 14 : \ - (n) & (1ULL << 13) ? 13 : \ - (n) & (1ULL << 12) ? 12 : \ - (n) & (1ULL << 11) ? 11 : \ - (n) & (1ULL << 10) ? 10 : \ - (n) & (1ULL << 9) ? 9 : \ - (n) & (1ULL << 8) ? 8 : \ - (n) & (1ULL << 7) ? 7 : \ - (n) & (1ULL << 6) ? 6 : \ - (n) & (1ULL << 5) ? 5 : \ - (n) & (1ULL << 4) ? 4 : \ - (n) & (1ULL << 3) ? 3 : \ - (n) & (1ULL << 2) ? 2 : \ - 1 ) +#define ilog2(n) \ + ((n) < 2 ? 0 : \ + (n) & (1ULL << 63) ? \ + 63 : \ + (n) & (1ULL << 62) ? \ + 62 : \ + (n) & (1ULL << 61) ? \ + 61 : \ + (n) & (1ULL << 60) ? \ + 60 : \ + (n) & (1ULL << 59) ? \ + 59 : \ + (n) & (1ULL << 58) ? \ + 58 : \ + (n) & (1ULL << 57) ? \ + 57 : \ + (n) & (1ULL << 56) ? \ + 56 : \ + (n) & (1ULL << 55) ? \ + 55 : \ + (n) & (1ULL << 54) ? \ + 54 : \ + (n) & (1ULL << 53) ? \ + 53 : \ + (n) & (1ULL << 52) ? \ + 52 : \ + (n) & (1ULL << 51) ? \ + 51 : \ + (n) & (1ULL << 50) ? \ + 50 : \ + (n) & (1ULL << 49) ? \ + 49 : \ + (n) & (1ULL << 48) ? \ + 48 : \ + (n) & (1ULL << 47) ? \ + 47 : \ + (n) & (1ULL << 46) ? \ + 46 : \ + (n) & (1ULL << 45) ? \ + 45 : \ + (n) & (1ULL << 44) ? \ + 44 : \ + (n) & (1ULL << 43) ? \ + 43 : \ + (n) & (1ULL << 42) ? \ + 42 : \ + (n) & (1ULL << 41) ? \ + 41 : \ + (n) & (1ULL << 40) ? \ + 40 : \ + (n) & (1ULL << 39) ? \ + 39 : \ + (n) & (1ULL << 38) ? \ + 38 : \ + (n) & (1ULL << 37) ? \ + 37 : \ + (n) & (1ULL << 36) ? \ + 36 : \ + (n) & (1ULL << 35) ? \ + 35 : \ + (n) & (1ULL << 34) ? \ + 34 : \ + (n) & (1ULL << 33) ? \ + 33 : \ + (n) & (1ULL << 32) ? \ + 32 : \ + (n) & (1ULL << 31) ? \ + 31 : \ + (n) & (1ULL << 30) ? \ + 30 : \ + (n) & (1ULL << 29) ? \ + 29 : \ + (n) & (1ULL << 28) ? \ + 28 : \ + (n) & (1ULL << 27) ? \ + 27 : \ + (n) & (1ULL << 26) ? \ + 26 : \ + (n) & (1ULL << 25) ? \ + 25 : \ + (n) & (1ULL << 24) ? \ + 24 : \ + (n) & (1ULL << 23) ? \ + 23 : \ + (n) & (1ULL << 22) ? \ + 22 : \ + (n) & (1ULL << 21) ? \ + 21 : \ + (n) & (1ULL << 20) ? \ + 20 : \ + (n) & (1ULL << 19) ? \ + 19 : \ + (n) & (1ULL << 18) ? \ + 18 : \ + (n) & (1ULL << 17) ? \ + 17 : \ + (n) & (1ULL << 16) ? \ + 16 : \ + (n) & (1ULL << 15) ? \ + 15 : \ + (n) & (1ULL << 14) ? \ + 14 : \ + (n) & (1ULL << 13) ? \ + 13 : \ + (n) & (1ULL << 12) ? \ + 12 : \ + (n) & (1ULL << 11) ? \ + 11 : \ + (n) & (1ULL << 10) ? \ + 10 : \ + (n) & (1ULL << 9) ? \ + 9 : \ + (n) & (1ULL << 8) ? \ + 8 : \ + (n) & (1ULL << 7) ? \ + 7 : \ + (n) & (1ULL << 6) ? \ + 6 : \ + (n) & (1ULL << 5) ? \ + 5 : \ + (n) & (1ULL << 4) ? 4 : (n) & (1ULL << 3) ? 3 : (n) & (1ULL << 2) ? 2 : 1) #endif /* _LOG2_H_ */ diff --git a/accelerators/stratus_hls/synth_stratus/hw/src/synth.cpp b/accelerators/stratus_hls/synth_stratus/hw/src/synth.cpp index b646911aa7..93595787b0 100644 --- a/accelerators/stratus_hls/synth_stratus/hw/src/synth.cpp +++ b/accelerators/stratus_hls/synth_stratus/hw/src/synth.cpp @@ -2,15 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 #include "synth.hpp" -#include "synth_directives.hpp" #include "log2.h" +#include "synth_directives.hpp" // Functions #include "synth_functions.hpp" // Processes -#ifdef COLLECT_LATENCY +#ifdef COLLECT_LATENCY void synth::latency_collector() { bool load_exec; @@ -18,35 +18,38 @@ void synth::latency_collector() bool store_exec; { - HLS_DEFINE_PROTOCOL("latency-collector-reset"); - load_exec = false; - compute_exec = false; - store_exec = false; - load.reset(); - compute.reset(); - store.reset(); - - wait(); + HLS_DEFINE_PROTOCOL("latency-collector-reset"); + load_exec = false; + compute_exec = false; + store_exec = false; + load.reset(); + compute.reset(); + store.reset(); + + wait(); } - while(true){ + while (true) { HLS_DEFINE_PROTOCOL("latency-collector"); - load_exec = this->sig_load.read(); + load_exec = this->sig_load.read(); compute_exec = this->sig_compute.read(); - store_exec = this->sig_store.read(); + store_exec = this->sig_store.read(); - while (!load.nb_can_put()) wait(); + while (!load.nb_can_put()) + wait(); load.nb_put(load_exec); - - while (!compute.nb_can_put()) wait(); + + while (!compute.nb_can_put()) + wait(); compute.nb_put(compute_exec); - - while (!store.nb_can_put()) wait(); + + while (!store.nb_can_put()) + wait(); store.nb_put(store_exec); wait(); } } -#endif +#endif void synth::load_input() { @@ -58,7 +61,7 @@ void synth::load_input() uint32_t reuse_factor; uint32_t ld_st_ratio; uint32_t stride_len; - uint32_t in_place; + uint32_t in_place; uint32_t offset; uint32_t rd_data; uint32_t wr_data; @@ -72,188 +75,175 @@ void synth::load_input() uint32_t rd_err; // Reset { - HLS_DEFINE_PROTOCOL("load-reset"); - - this->reset_load_input(); - - // PLM memories reset - // No PLMs - - // User-defined reset code - pattern = 0; - in_size = 0; - access_factor = 0; - burst_len = 0; - irregular_seed = 0; - reuse_factor = 0; - stride_len = 0; - in_place = 0; - ld_st_ratio = 0; - offset = 0; - rd_data = 0; - - nwords = 0; - ntrans = 0; - masked_seed = 0; - index = 0; - stride = 0; - burst_len_log = 0; - rd_err = 0; + HLS_DEFINE_PROTOCOL("load-reset"); + + this->reset_load_input(); + + // PLM memories reset + // No PLMs + + // User-defined reset code + pattern = 0; + in_size = 0; + access_factor = 0; + burst_len = 0; + irregular_seed = 0; + reuse_factor = 0; + stride_len = 0; + in_place = 0; + ld_st_ratio = 0; + offset = 0; + rd_data = 0; + + nwords = 0; + ntrans = 0; + masked_seed = 0; + index = 0; + stride = 0; + burst_len_log = 0; + rd_err = 0; #ifdef COLLECT_LATENCY - this->sig_load.write(false); + this->sig_load.write(false); #endif - wait(); + wait(); } // Config { - HLS_DEFINE_PROTOCOL("load-config"); - - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); - - // User-defined config code - pattern = config.pattern; - in_size = config.in_size; - access_factor = config.access_factor; - burst_len = config.burst_len; - irregular_seed = config.irregular_seed; - reuse_factor = config.reuse_factor; - stride_len = config.stride_len; - ld_st_ratio = config.ld_st_ratio; - in_place = config.in_place; - offset = config.offset; - rd_data = config.rd_data; - wr_data = config.wr_data; - - // Logarithms - burst_len_log = ilog2(burst_len); - - // Number of words to be read - if (config.pattern == IRREGULAR) - nwords = in_size >> access_factor; - else - nwords = in_size; - - // Number of DMA read transactions - ntrans = nwords >> burst_len_log; - - // Seed for semi-random DMA load index - masked_seed = (irregular_seed & (ntrans - 1)) << burst_len_log; - - if (pattern == IRREGULAR){ - in_place = 0; - } - - if (ld_st_ratio > 1 && in_place == 1) - reuse_factor = 1; + HLS_DEFINE_PROTOCOL("load-config"); + + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); + + // User-defined config code + pattern = config.pattern; + in_size = config.in_size; + access_factor = config.access_factor; + burst_len = config.burst_len; + irregular_seed = config.irregular_seed; + reuse_factor = config.reuse_factor; + stride_len = config.stride_len; + ld_st_ratio = config.ld_st_ratio; + in_place = config.in_place; + offset = config.offset; + rd_data = config.rd_data; + wr_data = config.wr_data; + + // Logarithms + burst_len_log = ilog2(burst_len); + + // Number of words to be read + if (config.pattern == IRREGULAR) nwords = in_size >> access_factor; + else + nwords = in_size; + + // Number of DMA read transactions + ntrans = nwords >> burst_len_log; + + // Seed for semi-random DMA load index + masked_seed = (irregular_seed & (ntrans - 1)) << burst_len_log; + + if (pattern == IRREGULAR) { in_place = 0; } + + if (ld_st_ratio > 1 && in_place == 1) reuse_factor = 1; } - + // Load { - // Reuse loop - for (uint32_t r = 0; r < reuse_factor; r++) - { - HLS_LOAD_INPUT_REUSE_LOOP; - // Init index and stride counter - index = 0; - stride = 0; - - if (pattern == IRREGULAR) { - index += masked_seed; - index &= (nwords - 1); - } - - { - HLS_DEFINE_PROTOCOL("load-start"); + // Reuse loop + for (uint32_t r = 0; r < reuse_factor; r++) { + HLS_LOAD_INPUT_REUSE_LOOP; + // Init index and stride counter + index = 0; + stride = 0; + + if (pattern == IRREGULAR) { + index += masked_seed; + index &= (nwords - 1); + } + + { + HLS_DEFINE_PROTOCOL("load-start"); #ifdef COLLECT_LATENCY - this->sig_load.write(true); + this->sig_load.write(true); #endif - } - - // Bursts loop - for (uint32_t b = 0; b < ntrans; b++) - { - HLS_LOAD_INPUT_BATCH_LOOP; - - { - HLS_DEFINE_PROTOCOL("load-dma-conf"); - - // Configure DMA transaction - dma_info_t dma_info(index + offset, burst_len, SIZE_WORD); - this->dma_read_ctrl.put(dma_info); - } - - // Words loop - for (uint32_t i = 0; i < burst_len; i++) - { - HLS_LOAD_INPUT_LOOP; - { - HLS_LOAD_DMA; - uint32_t data = this->dma_read_chnl.get().to_uint(); - wait(); - - //validate read data - if ((!in_place || r == 0) && data != rd_data){ - rd_err = data; - } else if (in_place && r > 0 && data != wr_data){ - rd_err = data; } - rd_errs.write(rd_err); - } - } - - { - HLS_DEFINE_PROTOCOL("load-stop"); + + // Bursts loop + for (uint32_t b = 0; b < ntrans; b++) { + HLS_LOAD_INPUT_BATCH_LOOP; + + { + HLS_DEFINE_PROTOCOL("load-dma-conf"); + + // Configure DMA transaction + dma_info_t dma_info(index + offset, burst_len, SIZE_WORD); + this->dma_read_ctrl.put(dma_info); + } + + // Words loop + for (uint32_t i = 0; i < burst_len; i++) { + HLS_LOAD_INPUT_LOOP; + { + HLS_LOAD_DMA; + uint32_t data = this->dma_read_chnl.get().to_uint(); + wait(); + + // validate read data + if ((!in_place || r == 0) && data != rd_data) { rd_err = data; } + else if (in_place && r > 0 && data != wr_data) { + rd_err = data; + } + rd_errs.write(rd_err); + } + } + + { + HLS_DEFINE_PROTOCOL("load-stop"); #ifdef COLLECT_LATENCY - this->sig_load.write(false); + this->sig_load.write(false); #endif - } + } - this->load_compute_handshake(); - { - HLS_DEFINE_PROTOCOL("load-resume"); + this->load_compute_handshake(); + { + HLS_DEFINE_PROTOCOL("load-resume"); #ifdef COLLECT_LATENCY - this->sig_load.write(true); + this->sig_load.write(true); #endif - } - // Index calculation - if (pattern == STREAMING) { - - index += burst_len; - - } else if (pattern == STRIDED) { - - index += stride_len; - if (index >= in_size) { - stride += burst_len; - index = stride; - } - - } else { // pattern == IRREGULAR - - index += masked_seed; - index &= (nwords - 1); - } - } - } + } + // Index calculation + if (pattern == STREAMING) { index += burst_len; } + else if (pattern == STRIDED) { + + index += stride_len; + if (index >= in_size) { + stride += burst_len; + index = stride; + } + } + else { // pattern == IRREGULAR + + index += masked_seed; + index &= (nwords - 1); + } + } + } } - + { - HLS_DEFINE_PROTOCOL("load-done"); + HLS_DEFINE_PROTOCOL("load-done"); #ifdef COLLECT_LATENCY - this->sig_load.write(false); + this->sig_load.write(false); #endif } // Conclude { - this->process_done(); + this->process_done(); } } - - void synth::store_output() { @@ -276,154 +266,144 @@ void synth::store_output() uint32_t stride; // Reset { - HLS_DEFINE_PROTOCOL("store-reset"); - - this->reset_store_output(); - - // PLM memories reset - - // User-defined reset code - pattern = 0; - burst_len = 0; - in_size = 0; - out_size = 0; - reuse_factor = 0; - in_place = 0; - ld_st_ratio = 0; - offset = 0; - rd_err = 0; - stride_len = 0; - - nwords = 0; - ntrans = 0; - index = 0; - burst_len_log = 0; - wr_data = 0; - stride = 0; + HLS_DEFINE_PROTOCOL("store-reset"); + + this->reset_store_output(); + + // PLM memories reset + + // User-defined reset code + pattern = 0; + burst_len = 0; + in_size = 0; + out_size = 0; + reuse_factor = 0; + in_place = 0; + ld_st_ratio = 0; + offset = 0; + rd_err = 0; + stride_len = 0; + + nwords = 0; + ntrans = 0; + index = 0; + burst_len_log = 0; + wr_data = 0; + stride = 0; #ifdef COLLECT_LATENCY - this->sig_store.write(false); + this->sig_store.write(false); #endif - wait(); + wait(); } // Config { - HLS_DEFINE_PROTOCOL("store-config"); - - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); - - pattern = config.pattern; - burst_len = config.burst_len; - in_size = config.in_size; - out_size = config.out_size; - reuse_factor = config.reuse_factor; - in_place = config.in_place; - ld_st_ratio = config.ld_st_ratio; - offset = config.offset; - wr_data = config.wr_data; - stride_len = config.stride_len; - - if (ld_st_ratio > 1 && in_place == 1) - reuse_factor = 1; - - if (pattern == IRREGULAR){ - in_place = 0; - } + HLS_DEFINE_PROTOCOL("store-config"); + + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); - // Logarithms - burst_len_log = ilog2(burst_len); + pattern = config.pattern; + burst_len = config.burst_len; + in_size = config.in_size; + out_size = config.out_size; + reuse_factor = config.reuse_factor; + in_place = config.in_place; + ld_st_ratio = config.ld_st_ratio; + offset = config.offset; + wr_data = config.wr_data; + stride_len = config.stride_len; - nwords = out_size; - ntrans = nwords >> burst_len_log; + if (ld_st_ratio > 1 && in_place == 1) reuse_factor = 1; + if (pattern == IRREGULAR) { in_place = 0; } + + // Logarithms + burst_len_log = ilog2(burst_len); + + nwords = out_size; + ntrans = nwords >> burst_len_log; } // Store { - // Reuse loop - for (uint32_t r = 0; r < reuse_factor; r++) - { - - stride = 0; - if (!in_place) - index = in_size; - else - index = 0; - - for (uint32_t b = 0; b < ntrans; b++) - { - HLS_STORE_OUTPUT_BATCH_LOOP; - - this->store_compute_handshake(); - - { - HLS_DEFINE_PROTOCOL("store-start"); + // Reuse loop + for (uint32_t r = 0; r < reuse_factor; r++) { + + stride = 0; + if (!in_place) index = in_size; + else + index = 0; + + for (uint32_t b = 0; b < ntrans; b++) { + HLS_STORE_OUTPUT_BATCH_LOOP; + + this->store_compute_handshake(); + + { + HLS_DEFINE_PROTOCOL("store-start"); #ifdef COLLECT_LATENCY - this->sig_store.write(true); + this->sig_store.write(true); #endif - } - - { - HLS_DEFINE_PROTOCOL("store-dma-conf"); - rd_err = rd_errs.read(); - // Configure DMA transaction - dma_info_t dma_info(index + offset, burst_len, SIZE_WORD); - this->dma_write_ctrl.put(dma_info); - } - - for (uint32_t i = 0; i < burst_len; i++) - { - HLS_STORE_OUTPUT_LOOP; - - { - HLS_STORE_DMA; - if (r == reuse_factor - 1 && b == ntrans - 1 && i == burst_len - 1 && rd_err > 0){ - this->dma_write_chnl.put(rd_err); - }else{ - this->dma_write_chnl.put(wr_data); - } - wait(); - } - } - - // Index calculation - if (in_place) { - if (pattern == STREAMING) { - - index += burst_len; - - } else if (pattern == STRIDED) { - - index += stride_len; - if (index >= out_size) { - stride += burst_len; - index = stride; } - } - } else { - index += burst_len; - } + { + HLS_DEFINE_PROTOCOL("store-dma-conf"); + rd_err = rd_errs.read(); + // Configure DMA transaction + dma_info_t dma_info(index + offset, burst_len, SIZE_WORD); + this->dma_write_ctrl.put(dma_info); + } - { - HLS_DEFINE_PROTOCOL("store-stop"); + for (uint32_t i = 0; i < burst_len; i++) { + HLS_STORE_OUTPUT_LOOP; + + { + HLS_STORE_DMA; + if (r == reuse_factor - 1 && b == ntrans - 1 && i == burst_len - 1 && + rd_err > 0) { + this->dma_write_chnl.put(rd_err); + } + else { + this->dma_write_chnl.put(wr_data); + } + wait(); + } + } + + // Index calculation + if (in_place) { + if (pattern == STREAMING) { index += burst_len; } + else if (pattern == STRIDED) { + + index += stride_len; + if (index >= out_size) { + stride += burst_len; + index = stride; + } + } + } + else { + index += burst_len; + } + + { + HLS_DEFINE_PROTOCOL("store-stop"); #ifdef COLLECT_LATENCY - this->sig_store.write(false); + this->sig_store.write(false); #endif + } + } } - } - } } - + // Conclude { - this->accelerator_done(); - this->process_done(); + this->accelerator_done(); + this->process_done(); } } - void synth::compute_kernel() { uint32_t burst_len; @@ -441,108 +421,103 @@ void synth::compute_kernel() // Reset { - HLS_DEFINE_PROTOCOL("compute-reset"); + HLS_DEFINE_PROTOCOL("compute-reset"); - this->reset_compute_kernel(); + this->reset_compute_kernel(); - // PLM memories reset + // PLM memories reset - // User-defined reset code - burst_len = 0; - in_size = 0; - reuse_factor = 0; - in_place = 0; - ld_st_ratio = 0; - compute_bound_factor = 0; + // User-defined reset code + burst_len = 0; + in_size = 0; + reuse_factor = 0; + in_place = 0; + ld_st_ratio = 0; + compute_bound_factor = 0; - nwords = 0; - ntrans = 0; - burst_len_log = 0; - ld_st_ratio_cnt = 0; - compute_bound_delay = 0; + nwords = 0; + ntrans = 0; + burst_len_log = 0; + ld_st_ratio_cnt = 0; + compute_bound_delay = 0; #ifdef COLLECT_LATENCY - this->sig_compute.write(false); + this->sig_compute.write(false); #endif - wait(); + wait(); } // Config { - HLS_DEFINE_PROTOCOL("compute-config"); + HLS_DEFINE_PROTOCOL("compute-config"); - cfg.wait_for_config(); // config process - conf_info_t config = this->conf_info.read(); + cfg.wait_for_config(); // config process + conf_info_t config = this->conf_info.read(); - // User-defined config code - burst_len = config.burst_len; - in_size = config.in_size; - reuse_factor = config.reuse_factor; - in_place = config.in_place; - ld_st_ratio = config.ld_st_ratio; - compute_bound_factor = config.compute_bound_factor; + // User-defined config code + burst_len = config.burst_len; + in_size = config.in_size; + reuse_factor = config.reuse_factor; + in_place = config.in_place; + ld_st_ratio = config.ld_st_ratio; + compute_bound_factor = config.compute_bound_factor; - if (ld_st_ratio > 1 && in_place == 1) - reuse_factor = 1; + if (ld_st_ratio > 1 && in_place == 1) reuse_factor = 1; - // Logarithms - burst_len_log = ilog2(burst_len); + // Logarithms + burst_len_log = ilog2(burst_len); - // Delay between the end of a DMA read transaction and the issue of the - // next. When this delay is > 0 it emulates a compute-bound accelerator. - compute_bound_delay = burst_len * (compute_bound_factor - 1); + // Delay between the end of a DMA read transaction and the issue of the + // next. When this delay is > 0 it emulates a compute-bound accelerator. + compute_bound_delay = burst_len * (compute_bound_factor - 1); - nwords = in_size; - ntrans = nwords >> burst_len_log; + nwords = in_size; + ntrans = nwords >> burst_len_log; } // Compute { - // Reuse loop - for (uint32_t r = 0; r < reuse_factor; r++) - { - ld_st_ratio_cnt = 0; + // Reuse loop + for (uint32_t r = 0; r < reuse_factor; r++) { + ld_st_ratio_cnt = 0; - for (uint32_t b = 0; b < ntrans; b++) - { + for (uint32_t b = 0; b < ntrans; b++) { - this->compute_load_handshake(); - { - HLS_DEFINE_PROTOCOL("compute_start"); + this->compute_load_handshake(); + { + HLS_DEFINE_PROTOCOL("compute_start"); #ifdef COLLECT_LATENCY - this->sig_compute.write(true); + this->sig_compute.write(true); #endif - } - // Computing phase implementation - // Compute-bound emulation - for (uint32_t i = 0; i < compute_bound_delay; i++) - { - HLS_LOAD_INPUT_LOOP; + } + // Computing phase implementation + // Compute-bound emulation + for (uint32_t i = 0; i < compute_bound_delay; i++) { + HLS_LOAD_INPUT_LOOP; + { + HLS_DEFINE_PROTOCOL("compute-bound-delay"); + wait(); + } + } + // Handshake to compute process + ld_st_ratio_cnt++; + { - HLS_DEFINE_PROTOCOL("compute-bound-delay"); - wait(); - } - } - // Handshake to compute process - ld_st_ratio_cnt++; - - { - HLS_DEFINE_PROTOCOL("compute_stop"); + HLS_DEFINE_PROTOCOL("compute_stop"); #ifdef COLLECT_LATENCY - this->sig_compute.write(false); + this->sig_compute.write(false); #endif - } + } - if (ld_st_ratio_cnt == ld_st_ratio) { - this->compute_store_handshake(); - ld_st_ratio_cnt = 0; + if (ld_st_ratio_cnt == ld_st_ratio) { + this->compute_store_handshake(); + ld_st_ratio_cnt = 0; + } } + } - } - } - - // Conclude - { - this->process_done(); - } + // Conclude + { + this->process_done(); + } } } diff --git a/accelerators/stratus_hls/synth_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/synth_stratus/hw/tb/sc_main.cpp index 9f313f9a31..0ca146195e 100644 --- a/accelerators/stratus_hls/synth_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/synth_stratus/hw/tb/sc_main.cpp @@ -5,7 +5,7 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; extern void esc_elaborate() { @@ -22,13 +22,13 @@ extern void esc_cleanup() int sc_main(int argc, char *argv[]) { // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); esc_initialize(argc, argv); esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); sc_signal rst("rst"); testbench->clk(clk); diff --git a/accelerators/stratus_hls/synth_stratus/sw/baremetal/synth.c b/accelerators/stratus_hls/synth_stratus/sw/baremetal/synth.c index 9ddb4c7824..eeb37be744 100644 --- a/accelerators/stratus_hls/synth_stratus/sw/baremetal/synth.c +++ b/accelerators/stratus_hls/synth_stratus/sw/baremetal/synth.c @@ -9,192 +9,189 @@ * Select Scatter-Gather in ESP configuration */ -#include -#include #include #include +#include +#include -#define SLD_SYNTH 0x014 -#define DEV_NAME "sld,synth_stratus" -#define TRIALS 10 +#define SLD_SYNTH 0x014 +#define DEV_NAME "sld,synth_stratus" +#define TRIALS 10 #define PATTERN_STREAMING 0 -#define PATTERN_STRIDED 1 +#define PATTERN_STRIDED 1 #define PATTERN_IRREGULAR 2 -#define SYNTH_OFFSET_REG 0x40 -#define SYNTH_PATTERN_REG 0x44 -#define SYNTH_IN_SIZE_REG 0x48 -#define SYNTH_ACCESS_FACTOR_REG 0x4c -#define SYNTH_BURST_LEN_REG 0x50 +#define SYNTH_OFFSET_REG 0x40 +#define SYNTH_PATTERN_REG 0x44 +#define SYNTH_IN_SIZE_REG 0x48 +#define SYNTH_ACCESS_FACTOR_REG 0x4c +#define SYNTH_BURST_LEN_REG 0x50 #define SYNTH_COMPUTE_BOUND_FACTOR_REG 0x54 -#define SYNTH_IRREGULAR_SEED_REG 0x58 -#define SYNTH_REUSE_FACTOR_REG 0x5c -#define SYNTH_LD_ST_RATIO_REG 0x60 -#define SYNTH_STRIDE_LEN_REG 0x64 -#define SYNTH_OUT_SIZE_REG 0x68 -#define SYNTH_IN_PLACE_REG 0x6c -#define SYNTH_WR_DATA_REG 0x70 -#define SYNTH_RD_DATA_REG 0x78 +#define SYNTH_IRREGULAR_SEED_REG 0x58 +#define SYNTH_REUSE_FACTOR_REG 0x5c +#define SYNTH_LD_ST_RATIO_REG 0x60 +#define SYNTH_STRIDE_LEN_REG 0x64 +#define SYNTH_OUT_SIZE_REG 0x68 +#define SYNTH_IN_PLACE_REG 0x6c +#define SYNTH_WR_DATA_REG 0x70 +#define SYNTH_RD_DATA_REG 0x78 // Accelerator-specific buffe size -#define IN_SIZE 1024 -#define LD_ST_RATIO 2 -#define ACCESS_FACTOR 0 -#define OUT_SIZE ((IN_SIZE / LD_ST_RATIO) >> ACCESS_FACTOR) +#define IN_SIZE 1024 +#define LD_ST_RATIO 2 +#define ACCESS_FACTOR 0 +#define OUT_SIZE ((IN_SIZE / LD_ST_RATIO) >> ACCESS_FACTOR) #define SYNTH_BUF_SIZE ((IN_SIZE + OUT_SIZE) * sizeof(unsigned)) -#define OUT_DATA 0x12345678 -#define IN_DATA 0x89abcdef -#define IN_PLACE 0 +#define OUT_DATA 0x12345678 +#define IN_DATA 0x89abcdef +#define IN_PLACE 0 /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK ((SYNTH_BUF_SIZE % CHUNK_SIZE == 0) ? \ - (SYNTH_BUF_SIZE / CHUNK_SIZE) : \ - (SYNTH_BUF_SIZE / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK \ + ((SYNTH_BUF_SIZE % CHUNK_SIZE == 0) ? (SYNTH_BUF_SIZE / CHUNK_SIZE) : \ + (SYNTH_BUF_SIZE / CHUNK_SIZE) + 1) // User defined registers - - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int n, trial; - int ndev; - struct esp_device *espdevs = NULL; - unsigned coherence; - - ndev = probe(&espdevs, VENDOR_SLD, SLD_SYNTH, DEV_NAME); - if (!ndev) { - printf("Error: %s device not found!\n", DEV_NAME); - exit(EXIT_FAILURE); - } - - for (trial = 0; trial < TRIALS; trial++) { -/* #ifndef __riscv */ -/* for (coherence = ACC_COH_NONE; coherence <= ACC_COH_RECALL; coherence++) */ -/* { */ -/* #else */ - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; -/* #endif */ - struct esp_device *dev; - unsigned **ptable = NULL; - unsigned *mem; - int scatter_gather = 1; - for (n = 0; n < ndev; n++){ - dev = &espdevs[n]; - int i; - printf("******************** %s.%d ********************\n", DEV_NAME, n); - - // Check if scatter-gather DMA is disabled - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled; revert to contiguous buffer.\n"); - scatter_gather = 0; - } else { - printf(" -> scatter-gather DMA is enabled.\n"); - } - - if (scatter_gather) - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { - printf(" Trying to allocate %lu chunks on %d TLB available entries\n", - NCHUNK, ioread32(dev, PT_NCHUNK_MAX_REG)); - break; - } - - // Allocate memory (will be contigous anyway in baremetal) - mem = aligned_malloc(SYNTH_BUF_SIZE); - for (i = 0; i < IN_SIZE; i++){ - mem[i] = IN_DATA; - } - printf(" memory buffer base-address = %p\n", mem); - - if (scatter_gather) { - //Alocate and populate page table - ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); - for (i = 0; i < NCHUNK; i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(unsigned))]; - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK); - } - - // Initialize input: write floating point hex values (simpler to debug) - - // Configure device - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); - - if (scatter_gather) { - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - iowrite32(dev, SRC_OFFSET_REG, 0); - iowrite32(dev, DST_OFFSET_REG, 0); // Sort runs in place - } else { - iowrite32(dev, SRC_OFFSET_REG, (unsigned long) mem); - iowrite32(dev, DST_OFFSET_REG, (unsigned long) mem); // Sort runs in place - } - - // Accelerator-specific registers - iowrite32(dev, SYNTH_OFFSET_REG, 0); - iowrite32(dev, SYNTH_PATTERN_REG, PATTERN_STRIDED); - iowrite32(dev, SYNTH_IN_SIZE_REG, IN_SIZE); - iowrite32(dev, SYNTH_ACCESS_FACTOR_REG, ACCESS_FACTOR); - iowrite32(dev, SYNTH_BURST_LEN_REG, 4); - iowrite32(dev, SYNTH_COMPUTE_BOUND_FACTOR_REG, 2); - iowrite32(dev, SYNTH_IRREGULAR_SEED_REG, 0); - iowrite32(dev, SYNTH_REUSE_FACTOR_REG, 8); - iowrite32(dev, SYNTH_LD_ST_RATIO_REG, LD_ST_RATIO); - iowrite32(dev, SYNTH_STRIDE_LEN_REG, 256); - iowrite32(dev, SYNTH_OUT_SIZE_REG, OUT_SIZE); - iowrite32(dev, SYNTH_IN_PLACE_REG, IN_PLACE); - iowrite32(dev, SYNTH_WR_DATA_REG, OUT_DATA); - iowrite32(dev, SYNTH_RD_DATA_REG, IN_DATA); - // Flush for non-coherent DMA - esp_flush(coherence); - - // Start accelerator - printf(" Start..\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - unsigned done = 0; - - while (!done) { - dev = &espdevs[n]; - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - - iowrite32(dev, CMD_REG, 0x0); - printf(" Validating...\n"); - - - uint32_t start = IN_PLACE ? 0 : IN_SIZE; - uint32_t errors = 0; - - for (i = start; i < start + OUT_SIZE; i++){ - if (i == start + OUT_SIZE - 1 && mem[i] != 0){ - errors += mem[i]; - printf("%d read errors \n", mem[i]); - } - else if (i != start + OUT_SIZE - 1 && mem[i] != OUT_DATA) - errors++; - } - - printf(" %d errors \n", errors); - - printf(" Done\n"); - - - // Validation - - if (scatter_gather) - aligned_free(ptable); - aligned_free(mem); - } - printf("**************************************************\n\n"); - } - } - return 0; + int n, trial; + int ndev; + struct esp_device *espdevs = NULL; + unsigned coherence; + + ndev = probe(&espdevs, VENDOR_SLD, SLD_SYNTH, DEV_NAME); + if (!ndev) { + printf("Error: %s device not found!\n", DEV_NAME); + exit(EXIT_FAILURE); + } + + for (trial = 0; trial < TRIALS; trial++) { + /* #ifndef __riscv */ + /* for (coherence = ACC_COH_NONE; coherence <= ACC_COH_RECALL; coherence++) */ + /* { */ + /* #else */ + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; + /* #endif */ + struct esp_device *dev; + unsigned **ptable = NULL; + unsigned *mem; + int scatter_gather = 1; + for (n = 0; n < ndev; n++) { + dev = &espdevs[n]; + int i; + printf("******************** %s.%d ********************\n", DEV_NAME, n); + + // Check if scatter-gather DMA is disabled + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled; revert to contiguous buffer.\n"); + scatter_gather = 0; + } + else { + printf(" -> scatter-gather DMA is enabled.\n"); + } + + if (scatter_gather) + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { + printf(" Trying to allocate %lu chunks on %d TLB available entries\n", + NCHUNK, ioread32(dev, PT_NCHUNK_MAX_REG)); + break; + } + + // Allocate memory (will be contigous anyway in baremetal) + mem = aligned_malloc(SYNTH_BUF_SIZE); + for (i = 0; i < IN_SIZE; i++) { + mem[i] = IN_DATA; + } + printf(" memory buffer base-address = %p\n", mem); + + if (scatter_gather) { + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); + for (i = 0; i < NCHUNK; i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(unsigned))]; + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK); + } + + // Initialize input: write floating point hex values (simpler to debug) + + // Configure device + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); + + if (scatter_gather) { + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + iowrite32(dev, SRC_OFFSET_REG, 0); + iowrite32(dev, DST_OFFSET_REG, 0); // Sort runs in place + } + else { + iowrite32(dev, SRC_OFFSET_REG, (unsigned long)mem); + iowrite32(dev, DST_OFFSET_REG, (unsigned long)mem); // Sort runs in place + } + + // Accelerator-specific registers + iowrite32(dev, SYNTH_OFFSET_REG, 0); + iowrite32(dev, SYNTH_PATTERN_REG, PATTERN_STRIDED); + iowrite32(dev, SYNTH_IN_SIZE_REG, IN_SIZE); + iowrite32(dev, SYNTH_ACCESS_FACTOR_REG, ACCESS_FACTOR); + iowrite32(dev, SYNTH_BURST_LEN_REG, 4); + iowrite32(dev, SYNTH_COMPUTE_BOUND_FACTOR_REG, 2); + iowrite32(dev, SYNTH_IRREGULAR_SEED_REG, 0); + iowrite32(dev, SYNTH_REUSE_FACTOR_REG, 8); + iowrite32(dev, SYNTH_LD_ST_RATIO_REG, LD_ST_RATIO); + iowrite32(dev, SYNTH_STRIDE_LEN_REG, 256); + iowrite32(dev, SYNTH_OUT_SIZE_REG, OUT_SIZE); + iowrite32(dev, SYNTH_IN_PLACE_REG, IN_PLACE); + iowrite32(dev, SYNTH_WR_DATA_REG, OUT_DATA); + iowrite32(dev, SYNTH_RD_DATA_REG, IN_DATA); + // Flush for non-coherent DMA + esp_flush(coherence); + + // Start accelerator + printf(" Start..\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + unsigned done = 0; + + while (!done) { + dev = &espdevs[n]; + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + + iowrite32(dev, CMD_REG, 0x0); + printf(" Validating...\n"); + + uint32_t start = IN_PLACE ? 0 : IN_SIZE; + uint32_t errors = 0; + + for (i = start; i < start + OUT_SIZE; i++) { + if (i == start + OUT_SIZE - 1 && mem[i] != 0) { + errors += mem[i]; + printf("%d read errors \n", mem[i]); + } + else if (i != start + OUT_SIZE - 1 && mem[i] != OUT_DATA) + errors++; + } + + printf(" %d errors \n", errors); + + printf(" Done\n"); + + // Validation + + if (scatter_gather) aligned_free(ptable); + aligned_free(mem); + } + printf("**************************************************\n\n"); + } + } + return 0; } diff --git a/accelerators/stratus_hls/synth_stratus/sw/linux/app/cfg_synth.py b/accelerators/stratus_hls/synth_stratus/sw/linux/app/cfg_synth.py index 3bbc66e32a..9bab26fc39 100644 --- a/accelerators/stratus_hls/synth_stratus/sw/linux/app/cfg_synth.py +++ b/accelerators/stratus_hls/synth_stratus/sw/linux/app/cfg_synth.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 import os.path import random as rand -import math +import math i = 0 while True: @@ -24,7 +24,21 @@ x.close() max_words = pt_size / 4 -sizes = ["K1", "K2", "K4", "K8", "K16", "K32", "K64", "K128", "K256", "K512", "M1", "M2", "M4", "M8"] +sizes = [ + "K1", + "K2", + "K4", + "K8", + "K16", + "K32", + "K64", + "K128", + "K256", + "K512", + "M1", + "M2", + "M4", + "M8"] patterns = ["STREAMING", "STRIDED", "IRREGULAR"] burst_lens = [4, 8, 16, 32, 64, 128, 256] cb_factors = [1, 2, 4, 8, 16, 32] @@ -49,16 +63,16 @@ nthreads = rand.choices(range(1, 13), choices) threads = nthreads[0] f.write(str(threads) + "\n") - #512 MB / 4 bytes per word + # 512 MB / 4 bytes per word total_size_avail = math.pow(2, 29) / 4 for t in range(threads): # NDEVICES avail = len(devices) - (threads - (t + 1)) - devs = rand.choices(range(1, avail+1), choices[0:avail]) + devs = rand.choices(range(1, avail + 1), choices[0:avail]) ndev = devs[0] f.write(str(ndev) + "\n") - - #DATA FLOW + + # DATA FLOW if ndev == 1: flow_choice = "serial" else: @@ -67,41 +81,41 @@ if flow_choice == "p2p": p2p_burst_len = rand.choice(burst_lens) - p2p_reuse_factor = rand.choice(reuse_factors) + p2p_reuse_factor = rand.choice(reuse_factors) - #INPUT SIZE + # INPUT SIZE size = rand.choice(sizes) log_size = 10 + sizes.index(size) - thread_size_start = math.pow(2, log_size) + thread_size_start = math.pow(2, log_size) while True: if thread_size_start <= total_size_avail: break size = rand.choice(sizes) log_size = 10 + sizes.index(size) - thread_size_start = math.pow(2, log_size) + thread_size_start = math.pow(2, log_size) thread_size_avail = pt_size * math.pow(2, 20) / 4 f.write(str(size) + "\n") - thread_size_avail -= thread_size_start + thread_size_avail -= thread_size_start total_size_avail -= thread_size_start - #ALLOCATION + # ALLOCATION alloc = rand.choice(alloc_choices) f.write(alloc + "\n") first = True for d in range(ndev): - #DEVICE + # DEVICE d = rand.choice(devices) devices.remove(d) - - #PATTERN + + # PATTERN pattern = rand.choice(patterns) - - #ACCESS FACTOR + + # ACCESS FACTOR if flow_choice == "p2p": access_factor = 0 elif pattern == "IRREGULAR": - upper = log_size - 10 + upper = log_size - 10 if upper > 4: upper = 4 if upper < 0: @@ -110,23 +124,23 @@ else: access_factor = 0 log_size -= access_factor - - #BURST LEN + + # BURST LEN if flow_choice == "p2p": burst_len = p2p_burst_len - else: + else: burst_len = rand.choice(burst_lens) - - #COMPUTE BOUND FACTOR + + # COMPUTE BOUND FACTOR cb_factor = rand.choice(cb_factors) - - #REUSE FACTOR + + # REUSE FACTOR if flow_choice == "p2p": reuse_factor = p2p_reuse_factor else: reuse_factor = rand.choice(reuse_factors) - - #LD ST RATIO + + # LD ST RATIO upper = log_size - 10 if upper > 2: upper = 2 @@ -135,60 +149,60 @@ else: ld_st_ratio = rand.choice(ld_st_ratios[0:upper]) log_size -= ld_st_ratios.index(ld_st_ratio) - - #STRIDE LEN + + # STRIDE LEN if pattern == "STRIDED": if burst_len == 256: stride_len = 512 elif burst_len >= 32: index = stride_lens.index(burst_len) - stride_len = rand.choice(stride_lens[index+1:-1]) + stride_len = rand.choice(stride_lens[index + 1:-1]) else: stride_len = rand.choice(stride_lens) else: stride_len = 0 - - #IN PLACE + + # IN PLACE out_size = math.pow(2, log_size) in_place = 0 - + if flow_choice == "p2p": in_place = 0 elif thread_size_avail < out_size or total_size_avail < out_size: - in_place = 1 + in_place = 1 elif pattern == "IRREGULAR" or (ld_st_ratio > 1 and reuse_factor > 1): in_place = 0 else: in_place = rand.randint(0, 1) - - if in_place == 1: + + if in_place == 1: if pattern == "IRREGULAR": pattern = "STREAMING" if ld_st_ratio > 1 and reuse_factor > 1: ld_st_ratio = 1 - + if in_place == 0 and (not flow_choice == "p2p" or d == ndev - 1): - thread_size_avail -= out_size + thread_size_avail -= out_size total_size_avail -= out_size - - #WRITE DATA + + # WRITE DATA wr_data = rand.randint(0, 4294967295) - #READ DATA + # READ DATA if first: rd_data = rand.randint(0, 4294967295) - else: + else: rd_data = last_wr_data - + last_wr_data = wr_data first = False - #COHERENCE + # COHERENCE if flow_choice == "p2p": coherence = "none" else: - coherence = rand.choice(coherence_choices) - + coherence = rand.choice(coherence_choices) + f.write(str(d) + " ") f.write(pattern + " ") f.write(str(access_factor) + " ") @@ -201,5 +215,5 @@ f.write(str(wr_data) + " ") f.write(str(rd_data) + " ") f.write(coherence + "\n") - + f.close() diff --git a/accelerators/stratus_hls/synth_stratus/sw/linux/app/synth.c b/accelerators/stratus_hls/synth_stratus/sw/linux/app/synth.c index bb9feaeb17..d45cbae0cc 100644 --- a/accelerators/stratus_hls/synth_stratus/sw/linux/app/synth.c +++ b/accelerators/stratus_hls/synth_stratus/sw/linux/app/synth.c @@ -1,408 +1,421 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 #include "libesp.h" -#include "synth_stratus.h" #include "string.h" +#include "synth_stratus.h" #define DEBUG 1 -#define dprintf if(DEBUG) printf +#define dprintf \ + if (DEBUG) printf -#define NPHASES_MAX 100 -#define NTHREADS_MAX 16 -#define NDEV_MAX 16 +#define NPHASES_MAX 100 +#define NTHREADS_MAX 16 +#define NDEV_MAX 16 #define IRREGULAR_SEED_MAX 2048 -#define CFG 0 +#define CFG 0 #define FIXED 1 -#define AUTO 2 +#define AUTO 2 unsigned long long total_alloc = 0; typedef struct accelerator_thread_info { - int tid; - int ndev; + int tid; + int ndev; int chain[NDEV_MAX]; int p2p; size_t memsz; - enum contig_alloc_policy alloc_choice; + enum contig_alloc_policy alloc_choice; struct timespec th_start; - struct timespec th_end; + struct timespec th_end; } accelerator_thread_info_t; typedef struct soc_config { - int rows; - int cols; + int rows; + int cols; int nmem; - int* mem_y; - int* mem_x; - int nsynth; - int* synth_y; - int* synth_x; - int* ddr_hops; -} soc_config_t; - -size_t size_to_bytes (char* size){ - if (!strncmp(size, "M8", 2)){ - return 8388608; - } else if (!strncmp(size, "M4", 2)){ + int *mem_y; + int *mem_x; + int nsynth; + int *synth_y; + int *synth_x; + int *ddr_hops; +} soc_config_t; + +size_t size_to_bytes(char *size) +{ + if (!strncmp(size, "M8", 2)) { return 8388608; } + else if (!strncmp(size, "M4", 2)) { return 4194304; - } else if (!strncmp(size, "M2", 2)){ + } + else if (!strncmp(size, "M2", 2)) { return 2097152; - } else if (!strncmp(size, "M1", 2)){ + } + else if (!strncmp(size, "M1", 2)) { return 1048576; - } else if (!strncmp(size, "K512", 4)){ + } + else if (!strncmp(size, "K512", 4)) { return 524288; - } else if (!strncmp(size, "K256", 4)){ + } + else if (!strncmp(size, "K256", 4)) { return 262144; - } else if (!strncmp(size, "K128", 4)){ + } + else if (!strncmp(size, "K128", 4)) { return 131072; - } else if (!strncmp(size, "K64", 3)){ + } + else if (!strncmp(size, "K64", 3)) { return 65536; - } else if (!strncmp(size, "K32", 3)){ + } + else if (!strncmp(size, "K32", 3)) { return 32768; - } else if (!strncmp(size, "K16", 3)){ + } + else if (!strncmp(size, "K16", 3)) { return 16384; - } else if (!strncmp(size, "K8", 2)){ + } + else if (!strncmp(size, "K8", 2)) { return 8192; - } else if (!strncmp(size, "K4", 2)){ + } + else if (!strncmp(size, "K4", 2)) { return 4096; - } else if (!strncmp(size, "K2", 2)){ + } + else if (!strncmp(size, "K2", 2)) { return 2048; - } else if (!strncmp(size, "K1", 2)){ + } + else if (!strncmp(size, "K1", 2)) { return 1024; - } else { + } + else { return -1; } } char *devnames[] = { -"synth_stratus.0", -"synth_stratus.1", -"synth_stratus.2", -"synth_stratus.3", -"synth_stratus.4", -"synth_stratus.5", -"synth_stratus.6", -"synth_stratus.7", -"synth_stratus.8", -"synth_stratus.9", -"synth_stratus.10", -"synth_stratus.11", -"synth_stratus.12", -"synth_stratus.13", -"synth_stratus.14", -"synth_stratus.15", + "synth_stratus.0", "synth_stratus.1", "synth_stratus.2", "synth_stratus.3", + "synth_stratus.4", "synth_stratus.5", "synth_stratus.6", "synth_stratus.7", + "synth_stratus.8", "synth_stratus.9", "synth_stratus.10", "synth_stratus.11", + "synth_stratus.12", "synth_stratus.13", "synth_stratus.14", "synth_stratus.15", }; -static void read_soc_config(FILE* f, soc_config_t* soc_config){ - fscanf(f, "%d", &soc_config->rows); - fscanf(f, "%d", &soc_config->cols); - - //get locations of memory controllers +static void read_soc_config(FILE *f, soc_config_t *soc_config) +{ + fscanf(f, "%d", &soc_config->rows); + fscanf(f, "%d", &soc_config->cols); + + // get locations of memory controllers fscanf(f, "%d", &soc_config->nmem); - + int mem_loc; soc_config->mem_y = malloc(sizeof(int) * soc_config->nmem); soc_config->mem_x = malloc(sizeof(int) * soc_config->nmem); - for (int i = 0; i < soc_config->nmem; i++){ - fscanf(f, "%d", &mem_loc); - soc_config->mem_y[i] = mem_loc / soc_config->cols; - soc_config->mem_x[i] = mem_loc % soc_config->cols; + for (int i = 0; i < soc_config->nmem; i++) { + fscanf(f, "%d", &mem_loc); + soc_config->mem_y[i] = mem_loc / soc_config->cols; + soc_config->mem_x[i] = mem_loc % soc_config->cols; } - - //get locations of synthetic accelerators + + // get locations of synthetic accelerators fscanf(f, "%d", &soc_config->nsynth); - + int synth_loc; - soc_config->synth_y = malloc(sizeof(int)*soc_config->nsynth); - soc_config->synth_x = malloc(sizeof(int)*soc_config->nsynth); - for (int i = 0; i < soc_config->nsynth; i++){ - fscanf(f, "%d", &synth_loc); - soc_config->synth_y[i] = synth_loc / soc_config->cols; - soc_config->synth_x[i] = synth_loc % soc_config->cols; - } - - //calculate hops to each ddr controller - soc_config->ddr_hops = malloc(sizeof(int)*soc_config->nmem*soc_config->nsynth); - for (int s = 0; s < soc_config->nsynth; s++){ - for (int m = 0; m < soc_config->nmem; m++){ - soc_config->ddr_hops[s*soc_config->nmem + m] = abs(soc_config->synth_y[s] - soc_config->mem_y[m]) + abs(soc_config->synth_x[s] - soc_config->mem_x[m]); + soc_config->synth_y = malloc(sizeof(int) * soc_config->nsynth); + soc_config->synth_x = malloc(sizeof(int) * soc_config->nsynth); + for (int i = 0; i < soc_config->nsynth; i++) { + fscanf(f, "%d", &synth_loc); + soc_config->synth_y[i] = synth_loc / soc_config->cols; + soc_config->synth_x[i] = synth_loc % soc_config->cols; + } + + // calculate hops to each ddr controller + soc_config->ddr_hops = malloc(sizeof(int) * soc_config->nmem * soc_config->nsynth); + for (int s = 0; s < soc_config->nsynth; s++) { + for (int m = 0; m < soc_config->nmem; m++) { + soc_config->ddr_hops[s * soc_config->nmem + m] = + abs(soc_config->synth_y[s] - soc_config->mem_y[m]) + + abs(soc_config->synth_x[s] - soc_config->mem_x[m]); } - } + } } -static void config_threads(FILE* f, accelerator_thread_info_t **thread_info, esp_thread_info_t ***cfg, struct synth_stratus_access ***synth_cfg, int phase, int* nthreads, int coherence_mode, enum accelerator_coherence coherence, unsigned **nacc){ - fscanf(f, "%d", nthreads); - dprintf("%d threads in phase %d\n", *nthreads, phase); - *cfg = malloc(sizeof(esp_thread_info_t*) * *nthreads); - *nacc = malloc(sizeof(esp_thread_info_t*) * *nthreads); - *synth_cfg = malloc(sizeof(struct synth_stratus_access*) * *nthreads); - - for (int t = 0; t < *nthreads; t++){ - thread_info[t] = malloc(sizeof(accelerator_thread_info_t)); +static void config_threads(FILE *f, accelerator_thread_info_t **thread_info, + esp_thread_info_t ***cfg, struct synth_stratus_access ***synth_cfg, + int phase, int *nthreads, int coherence_mode, + enum accelerator_coherence coherence, unsigned **nacc) +{ + fscanf(f, "%d", nthreads); + dprintf("%d threads in phase %d\n", *nthreads, phase); + *cfg = malloc(sizeof(esp_thread_info_t *) * *nthreads); + *nacc = malloc(sizeof(esp_thread_info_t *) * *nthreads); + *synth_cfg = malloc(sizeof(struct synth_stratus_access *) * *nthreads); + + for (int t = 0; t < *nthreads; t++) { + thread_info[t] = malloc(sizeof(accelerator_thread_info_t)); thread_info[t]->tid = t; - - //get number of devices and size + + // get number of devices and size fscanf(f, "%d\n", &(thread_info[t]->ndev)); dprintf("%d devices in thread %d.%d\n", thread_info[t]->ndev, phase, t); - - (*cfg)[t] = malloc(sizeof(esp_thread_info_t) * thread_info[t]->ndev); + + (*cfg)[t] = malloc(sizeof(esp_thread_info_t) * thread_info[t]->ndev); (*synth_cfg)[t] = malloc(sizeof(struct synth_stratus_access) * thread_info[t]->ndev); - (*nacc)[t] = thread_info[t]->ndev; + (*nacc)[t] = thread_info[t]->ndev; char flow_choice[7]; fscanf(f, "%s\n", flow_choice); - if(!strcmp(flow_choice, "p2p")){ - thread_info[t]->p2p = 1; - } else { - thread_info[t]->p2p = 0; + if (!strcmp(flow_choice, "p2p")) { thread_info[t]->p2p = 1; } + else { + thread_info[t]->p2p = 0; } - + char size[5]; - fscanf(f, "%s\n", size); - + fscanf(f, "%s\n", size); + char alloc_choice[13]; fscanf(f, "%s\n", alloc_choice); - if (!strcmp(alloc_choice, "preferred")){ + if (!strcmp(alloc_choice, "preferred")) { thread_info[t]->alloc_choice = CONTIG_ALLOC_PREFERRED; - } else if (!strcmp(alloc_choice, "lloaded")){ + } + else if (!strcmp(alloc_choice, "lloaded")) { thread_info[t]->alloc_choice = CONTIG_ALLOC_LEAST_LOADED; - } else if (!strcmp(alloc_choice, "balanced")){ + } + else if (!strcmp(alloc_choice, "balanced")) { thread_info[t]->alloc_choice = CONTIG_ALLOC_BALANCED; } - size_t in_size; - in_size = size_to_bytes(size); + size_t in_size; + in_size = size_to_bytes(size); - size_t memsz = in_size; - unsigned int offset = 0; + size_t memsz = in_size; + unsigned int offset = 0; char pattern[10]; char coh_choice[7]; int prev_devid = 0; - for (int d = 0; d < thread_info[t]->ndev; d++){ - fscanf(f, "%d", &(thread_info[t]->chain[d])); - - //esp accelerator parameters - int devid = thread_info[t]->chain[d]; - (*cfg)[t][d].run = true; - (*cfg)[t][d].devname = devnames[devid]; + for (int d = 0; d < thread_info[t]->ndev; d++) { + fscanf(f, "%d", &(thread_info[t]->chain[d])); + + // esp accelerator parameters + int devid = thread_info[t]->chain[d]; + (*cfg)[t][d].run = true; + (*cfg)[t][d].devname = devnames[devid]; (*cfg)[t][d].ioctl_req = SYNTH_STRATUS_IOC_ACCESS; - (*cfg)[t][d].esp_desc = &((*synth_cfg)[t][d].esp); - + (*cfg)[t][d].esp_desc = &((*synth_cfg)[t][d].esp); + (*synth_cfg)[t][d].src_offset = 0; (*synth_cfg)[t][d].dst_offset = 0; - - if (thread_info[t]->p2p && d != thread_info[t]->ndev - 1){ + + if (thread_info[t]->p2p && d != thread_info[t]->ndev - 1) { (*synth_cfg)[t][d].esp.p2p_store = 1; - } else { + } + else { (*synth_cfg)[t][d].esp.p2p_store = 0; } - if (thread_info[t]->p2p && d != 0){ + if (thread_info[t]->p2p && d != 0) { (*synth_cfg)[t][d].esp.p2p_nsrcs = 1; strcpy((*synth_cfg)[t][d].esp.p2p_srcs[0], devnames[prev_devid]); - } else { + } + else { (*synth_cfg)[t][d].esp.p2p_nsrcs = 0; } - - //read parameters into esp_thread_info_t - fscanf(f, "%s", pattern); - if (!strncmp(pattern, "STREAMING", 9)){ + + // read parameters into esp_thread_info_t + fscanf(f, "%s", pattern); + if (!strncmp(pattern, "STREAMING", 9)) { (*synth_cfg)[t][d].pattern = PATTERN_STREAMING; - } else if (!strncmp(pattern, "STRIDED", 7)){ + } + else if (!strncmp(pattern, "STRIDED", 7)) { (*synth_cfg)[t][d].pattern = PATTERN_STRIDED; - } else if (!strncmp(pattern, "IRREGULAR", 9)){ + } + else if (!strncmp(pattern, "IRREGULAR", 9)) { (*synth_cfg)[t][d].pattern = PATTERN_IRREGULAR; } - fscanf(f, "%d %d %d %d %d %d %d %d %d %s", - &(*synth_cfg)[t][d].access_factor, - &(*synth_cfg)[t][d].burst_len, - &(*synth_cfg)[t][d].compute_bound_factor, - &(*synth_cfg)[t][d].reuse_factor, - &(*synth_cfg)[t][d].ld_st_ratio, - &(*synth_cfg)[t][d].stride_len, - &(*synth_cfg)[t][d].in_place, - &(*synth_cfg)[t][d].wr_data, - &(*synth_cfg)[t][d].rd_data, - coh_choice); - + fscanf(f, "%d %d %d %d %d %d %d %d %d %s", &(*synth_cfg)[t][d].access_factor, + &(*synth_cfg)[t][d].burst_len, &(*synth_cfg)[t][d].compute_bound_factor, + &(*synth_cfg)[t][d].reuse_factor, &(*synth_cfg)[t][d].ld_st_ratio, + &(*synth_cfg)[t][d].stride_len, &(*synth_cfg)[t][d].in_place, + &(*synth_cfg)[t][d].wr_data, &(*synth_cfg)[t][d].rd_data, coh_choice); + if ((*synth_cfg)[t][d].pattern == PATTERN_IRREGULAR) (*synth_cfg)[t][d].irregular_seed = rand() % IRREGULAR_SEED_MAX; - - //calculate output size, offset, and memsize - (*synth_cfg)[t][d].in_size = in_size; - unsigned int out_size = (in_size >> (*synth_cfg)[t][d].access_factor) - / (*synth_cfg)[t][d].ld_st_ratio; - (*synth_cfg)[t][d].out_size = out_size; - (*synth_cfg)[t][d].offset = offset; - - if((*synth_cfg)[t][d].in_place == 0 && !thread_info[t]->p2p){ + + // calculate output size, offset, and memsize + (*synth_cfg)[t][d].in_size = in_size; + unsigned int out_size = + (in_size >> (*synth_cfg)[t][d].access_factor) / (*synth_cfg)[t][d].ld_st_ratio; + (*synth_cfg)[t][d].out_size = out_size; + (*synth_cfg)[t][d].offset = offset; + + if ((*synth_cfg)[t][d].in_place == 0 && !thread_info[t]->p2p) { memsz += out_size; offset += in_size; } - if (thread_info[t]->p2p && d == thread_info[t]->ndev - 1){ + if (thread_info[t]->p2p && d == thread_info[t]->ndev - 1) { memsz += out_size; (*synth_cfg)[t][d].offset = (*synth_cfg)[t][0].in_size - in_size; } - + unsigned int footprint = in_size >> (*synth_cfg)[t][d].access_factor; - if (!(*synth_cfg)[t][d].in_place && (!thread_info[t]->p2p || d == thread_info[t]->ndev - 1)) + if (!(*synth_cfg)[t][d].in_place && + (!thread_info[t]->p2p || d == thread_info[t]->ndev - 1)) footprint += out_size; - - if (thread_info[t]->p2p){ - (*synth_cfg)[t][d].esp.coherence = ACC_COH_NONE; - } - else if (coherence_mode == FIXED){ + + if (thread_info[t]->p2p) { (*synth_cfg)[t][d].esp.coherence = ACC_COH_NONE; } + else if (coherence_mode == FIXED) { (*synth_cfg)[t][d].esp.coherence = coherence; } - else if (!strcmp(coh_choice, "none")){ + else if (!strcmp(coh_choice, "none")) { (*synth_cfg)[t][d].esp.coherence = ACC_COH_NONE; } - else if (!strcmp(coh_choice, "llc")){ + else if (!strcmp(coh_choice, "llc")) { (*synth_cfg)[t][d].esp.coherence = ACC_COH_LLC; } - else if (!strcmp(coh_choice, "recall")){ + else if (!strcmp(coh_choice, "recall")) { (*synth_cfg)[t][d].esp.coherence = ACC_COH_RECALL; } - else if (!strcmp(coh_choice, "full")){ + else if (!strcmp(coh_choice, "full")) { (*synth_cfg)[t][d].esp.coherence = ACC_COH_FULL; } - (*synth_cfg)[t][d].esp.footprint = footprint * 4; - (*synth_cfg)[t][d].esp.in_place = (*synth_cfg)[t][d].in_place; + (*synth_cfg)[t][d].esp.footprint = footprint * 4; + (*synth_cfg)[t][d].esp.in_place = (*synth_cfg)[t][d].in_place; (*synth_cfg)[t][d].esp.reuse_factor = (*synth_cfg)[t][d].reuse_factor; - in_size = out_size; + in_size = out_size; prev_devid = devid; } thread_info[t]->memsz = memsz * 4; } } -static void alloc_phase(accelerator_thread_info_t **thread_info, esp_thread_info_t ***cfg, struct synth_stratus_access ***synth_cfg, int nthreads, soc_config_t soc_config, int alloc_mode, enum alloc_effort alloc, uint32_t **buffers, int phase){ +static void alloc_phase(accelerator_thread_info_t **thread_info, esp_thread_info_t ***cfg, + struct synth_stratus_access ***synth_cfg, int nthreads, + soc_config_t soc_config, int alloc_mode, enum alloc_effort alloc, + uint32_t **buffers, int phase) +{ int largest_thread = 0; - size_t largest_sz = 0; - int* ddr_node_cost = malloc(sizeof(int)*soc_config.nmem); + size_t largest_sz = 0; + int *ddr_node_cost = malloc(sizeof(int) * soc_config.nmem); int preferred_node_cost; int preferred_node[NTHREADS_MAX]; - //determine preferred controller for each thread - for (int t = 0; t < nthreads; t++){ - if (thread_info[t]->memsz > largest_sz){ - largest_sz = thread_info[t]->memsz; + // determine preferred controller for each thread + for (int t = 0; t < nthreads; t++) { + if (thread_info[t]->memsz > largest_sz) { + largest_sz = thread_info[t]->memsz; largest_thread = t; } - - for (int m = 0; m < soc_config.nmem; m++){ + + for (int m = 0; m < soc_config.nmem; m++) { ddr_node_cost[m] = 0; } - for (int d = 0; d < thread_info[t]->ndev; d++){ - for (int m = 0; m < soc_config.nmem; m++){ - ddr_node_cost[m] += soc_config.ddr_hops[thread_info[t]->chain[d]*soc_config.nmem + m]; + for (int d = 0; d < thread_info[t]->ndev; d++) { + for (int m = 0; m < soc_config.nmem; m++) { + ddr_node_cost[m] += + soc_config.ddr_hops[thread_info[t]->chain[d] * soc_config.nmem + m]; } } preferred_node_cost = ddr_node_cost[0]; - preferred_node[t] = 0; - for (int m = 1; m < soc_config.nmem; m++){ - if (ddr_node_cost[m] < preferred_node_cost){ + preferred_node[t] = 0; + for (int m = 1; m < soc_config.nmem; m++) { + if (ddr_node_cost[m] < preferred_node_cost) { preferred_node_cost = ddr_node_cost[m]; - preferred_node[t] = m; + preferred_node[t] = m; } } } - - //set policy - for (int i = 0; i < nthreads; i++){ - struct contig_alloc_params params; - if (alloc_mode == CFG){ - params.policy = thread_info[i]->alloc_choice; - } - else if (alloc_mode == FIXED){ - params.policy = alloc; + // set policy + for (int i = 0; i < nthreads; i++) { + struct contig_alloc_params params; + + if (alloc_mode == CFG) { params.policy = thread_info[i]->alloc_choice; } + else if (alloc_mode == FIXED) { + params.policy = alloc; thread_info[i]->alloc_choice = alloc; } // AUTO - else if (nthreads < 3){ - params.policy = CONTIG_ALLOC_BALANCED; - thread_info[i]->alloc_choice = CONTIG_ALLOC_BALANCED; - params.pol.balanced.threshold = 4; + else if (nthreads < 3) { + params.policy = CONTIG_ALLOC_BALANCED; + thread_info[i]->alloc_choice = CONTIG_ALLOC_BALANCED; + params.pol.balanced.threshold = 4; params.pol.balanced.cluster_size = 1; - } else if (i == largest_thread){ + } + else if (i == largest_thread) { thread_info[i]->alloc_choice = CONTIG_ALLOC_PREFERRED; - params.policy = CONTIG_ALLOC_PREFERRED; - params.pol.first.ddr_node = preferred_node[largest_thread]; - } else { + params.policy = CONTIG_ALLOC_PREFERRED; + params.pol.first.ddr_node = preferred_node[largest_thread]; + } + else { thread_info[i]->alloc_choice = CONTIG_ALLOC_LEAST_LOADED; - params.policy = CONTIG_ALLOC_LEAST_LOADED; + params.policy = CONTIG_ALLOC_LEAST_LOADED; params.pol.lloaded.threshold = 4; } - if (alloc_mode == CFG || alloc_mode == FIXED){ - if (params.policy == CONTIG_ALLOC_PREFERRED){ - params.pol.first.ddr_node = preferred_node[i]; - } else if (params.policy == CONTIG_ALLOC_BALANCED){ - params.pol.balanced.threshold = 4; + if (alloc_mode == CFG || alloc_mode == FIXED) { + if (params.policy == CONTIG_ALLOC_PREFERRED) { + params.pol.first.ddr_node = preferred_node[i]; + } + else if (params.policy == CONTIG_ALLOC_BALANCED) { + params.pol.balanced.threshold = 4; params.pol.balanced.cluster_size = 1; - } else if (params.policy == CONTIG_ALLOC_LEAST_LOADED){ - params.pol.lloaded.threshold = 4; + } + else if (params.policy == CONTIG_ALLOC_LEAST_LOADED) { + params.pol.lloaded.threshold = 4; } } total_alloc += thread_info[i]->memsz; - buffers[i] = (uint32_t *) esp_alloc_policy(params, thread_info[i]->memsz); - if (buffers[i] == NULL){ - die_errno("error: cannot allocate %zu contig bytes", thread_info[i]->memsz); + buffers[i] = (uint32_t *)esp_alloc_policy(params, thread_info[i]->memsz); + if (buffers[i] == NULL) { + die_errno("error: cannot allocate %zu contig bytes", thread_info[i]->memsz); } - for (int j = 0; j < (*synth_cfg)[i][0].in_size; j++){ + for (int j = 0; j < (*synth_cfg)[i][0].in_size; j++) { buffers[i][j] = (*synth_cfg)[i][0].rd_data; } - for (int acc = 0; acc < thread_info[i]->ndev; acc++){ - (*cfg)[i][acc].hw_buf = (void*) buffers[i]; + for (int acc = 0; acc < thread_info[i]->ndev; acc++) { + (*cfg)[i][acc].hw_buf = (void *)buffers[i]; } } free(ddr_node_cost); } -static int validate_buffer(accelerator_thread_info_t *thread_info, struct synth_stratus_access **synth_cfg, uint32_t *buf){ - int errors = 0; - for (int i = 0; i < thread_info->ndev; i++){ - if (thread_info->p2p && i != thread_info->ndev - 1) - continue; +static int validate_buffer(accelerator_thread_info_t *thread_info, + struct synth_stratus_access **synth_cfg, uint32_t *buf) +{ + int errors = 0; + for (int i = 0; i < thread_info->ndev; i++) { + if (thread_info->p2p && i != thread_info->ndev - 1) continue; - int t = thread_info->tid; - int offset = synth_cfg[t][i].offset; - int in_size = synth_cfg[t][i].in_size; + int t = thread_info->tid; + int offset = synth_cfg[t][i].offset; + int in_size = synth_cfg[t][i].in_size; int out_size = synth_cfg[t][i].out_size; int in_place = synth_cfg[t][i].in_place; - int wr_data = synth_cfg[t][i].wr_data; + int wr_data = synth_cfg[t][i].wr_data; int next_in_place; - - if (i != thread_info->ndev - 1){ - next_in_place = synth_cfg[t][i+1].in_place; - if (next_in_place) - continue; + + if (i != thread_info->ndev - 1) { + next_in_place = synth_cfg[t][i + 1].in_place; + if (next_in_place) continue; } - if (!in_place && !thread_info->p2p) - offset += in_size; + if (!in_place && !thread_info->p2p) offset += in_size; else if (thread_info->p2p) offset = synth_cfg[t][0].in_size; - for (int j = offset; j < offset + out_size; j++){ - if (j == offset + out_size - 1 && buf[j] != wr_data){ + for (int j = offset; j < offset + out_size; j++) { + if (j == offset + out_size - 1 && buf[j] != wr_data) { errors += buf[j]; printf("%u read errors in thread %d device %d\n", buf[j], t, i); } - else if (j != offset + out_size - 1 && buf[j] != wr_data){ + else if (j != offset + out_size - 1 && buf[j] != wr_data) { errors++; } } @@ -410,9 +423,11 @@ static int validate_buffer(accelerator_thread_info_t *thread_info, struct synth_ return errors; } -static void free_phase(accelerator_thread_info_t **thread_info, esp_thread_info_t **cfg, struct synth_stratus_access **synth_cfg, int nthreads){ - for (int i = 0; i < nthreads; i++){ - esp_free(cfg[i]->hw_buf); +static void free_phase(accelerator_thread_info_t **thread_info, esp_thread_info_t **cfg, + struct synth_stratus_access **synth_cfg, int nthreads) +{ + for (int i = 0; i < nthreads; i++) { + esp_free(cfg[i]->hw_buf); free(thread_info[i]); free(cfg[i]); free(synth_cfg[i]); @@ -421,56 +436,58 @@ static void free_phase(accelerator_thread_info_t **thread_info, esp_thread_info_ free(cfg); } -static void dump_results(FILE* out_file, accelerator_thread_info_t **thread_info, esp_thread_info_t **cfg, struct synth_stratus_access **synth_cfg, soc_config_t *soc_config, int phase, int nthreads, char** argv, int test_no){ +static void dump_results(FILE *out_file, accelerator_thread_info_t **thread_info, + esp_thread_info_t **cfg, struct synth_stratus_access **synth_cfg, + soc_config_t *soc_config, int phase, int nthreads, char **argv, + int test_no) +{ int t, d; unsigned long long thread_ns; unsigned long long phase_size = 0; - unsigned long long phase_ns = 0; - int phase_adj = test_no * 40 + phase; - for (t = 0; t < nthreads; t++){ + unsigned long long phase_ns = 0; + int phase_adj = test_no * 40 + phase; + for (t = 0; t < nthreads; t++) { thread_ns = 0; - for (d = 0; d < thread_info[t]->ndev; d++){ + for (d = 0; d < thread_info[t]->ndev; d++) { thread_ns += cfg[t][d].hw_ns; phase_ns += cfg[t][d].hw_ns; - fprintf(out_file,"%d-%d-%d,", phase_adj, t, d); - fprintf(out_file,"%d,", thread_info[t]->chain[d]); - if (synth_cfg[t][d].esp.coherence == ACC_COH_FULL) - fprintf(out_file,"full,"); + fprintf(out_file, "%d-%d-%d,", phase_adj, t, d); + fprintf(out_file, "%d,", thread_info[t]->chain[d]); + if (synth_cfg[t][d].esp.coherence == ACC_COH_FULL) fprintf(out_file, "full,"); else if (synth_cfg[t][d].esp.coherence == ACC_COH_LLC) - fprintf(out_file,"llc,"); + fprintf(out_file, "llc,"); else if (synth_cfg[t][d].esp.coherence == ACC_COH_RECALL) - fprintf(out_file,"recall,"); + fprintf(out_file, "recall,"); else if (synth_cfg[t][d].esp.coherence == ACC_COH_NONE) - fprintf(out_file,"none,"); + fprintf(out_file, "none,"); else if (synth_cfg[t][d].esp.coherence == ACC_COH_AUTO) - fprintf(out_file,"auto,"); + fprintf(out_file, "auto,"); if (thread_info[t]->alloc_choice == CONTIG_ALLOC_BALANCED) - fprintf(out_file,"balanced,"); + fprintf(out_file, "balanced,"); else if (thread_info[t]->alloc_choice == CONTIG_ALLOC_PREFERRED) - fprintf(out_file,"preferred,"); + fprintf(out_file, "preferred,"); else if (thread_info[t]->alloc_choice == CONTIG_ALLOC_LEAST_LOADED) - fprintf(out_file,"lloaded,"); + fprintf(out_file, "lloaded,"); - fprintf(out_file, "%d,", synth_cfg[t][d].esp.footprint); + fprintf(out_file, "%d,", synth_cfg[t][d].esp.footprint); - fprintf(out_file,"%d,", synth_cfg[t][d].esp.ddr_node); - fprintf(out_file,"%llu\n", cfg[t][d].hw_ns); + fprintf(out_file, "%d,", synth_cfg[t][d].esp.ddr_node); + fprintf(out_file, "%llu\n", cfg[t][d].hw_ns); } fprintf(out_file, "%d-%d,", phase_adj, t); fprintf(out_file, "%d,", thread_info[t]->ndev); fprintf(out_file, "%s,", argv[2]); - if (thread_info[t]->alloc_choice == CONTIG_ALLOC_BALANCED) - fprintf(out_file,"balanced,"); + if (thread_info[t]->alloc_choice == CONTIG_ALLOC_BALANCED) fprintf(out_file, "balanced,"); else if (thread_info[t]->alloc_choice == CONTIG_ALLOC_PREFERRED) - fprintf(out_file,"preferred,"); + fprintf(out_file, "preferred,"); else if (thread_info[t]->alloc_choice == CONTIG_ALLOC_LEAST_LOADED) - fprintf(out_file,"lloaded,"); - + fprintf(out_file, "lloaded,"); + fprintf(out_file, "%zu,", thread_info[t]->memsz); - phase_size += thread_info[t]->memsz; - - fprintf(out_file,"%d,", synth_cfg[t][0].esp.ddr_node); + phase_size += thread_info[t]->memsz; + + fprintf(out_file, "%d,", synth_cfg[t][0].esp.ddr_node); fprintf(out_file, "%llu\n", thread_ns); } fprintf(out_file, "%d,", phase_adj); @@ -482,102 +499,101 @@ static void dump_results(FILE* out_file, accelerator_thread_info_t **thread_info fprintf(out_file, "%llu\n", phase_ns); } -int main (int argc, char** argv) +int main(int argc, char **argv) { srand(time(NULL)); - if (argc != 4){ - printf("Usage: ./synth.exe file coherence alloc\n"); - } - //command line args - FILE* f; + if (argc != 4) { printf("Usage: ./synth.exe file coherence alloc\n"); } + // command line args + FILE *f; f = fopen(argv[1], "r"); int test_no = argv[1][9] - 48; char out_name[20]; - int len = strlen(strcpy(out_name, argv[1])); - out_name[len-3] = 'c'; - out_name[len-2] = 's'; - out_name[len-1] = 'v'; - - FILE* out_file; - if (access(out_name, F_OK) != -1){ - out_file = fopen(out_name, "a"); - } else { + int len = strlen(strcpy(out_name, argv[1])); + out_name[len - 3] = 'c'; + out_name[len - 2] = 's'; + out_name[len - 1] = 'v'; + + FILE *out_file; + if (access(out_name, F_OK) != -1) { out_file = fopen(out_name, "a"); } + else { out_file = fopen(out_name, "w"); - fprintf(out_file, "Device/Thread/Phase name, devID/nacc/nthreads, coherence, allocation, footprint, DDR#, time\n"); + fprintf(out_file, + "Device/Thread/Phase name, devID/nacc/nthreads, coherence, allocation, footprint, " + "DDR#, time\n"); } - - enum accelerator_coherence coherence = ACC_COH_NONE; - enum alloc_effort alloc; + + enum accelerator_coherence coherence = ACC_COH_NONE; + enum alloc_effort alloc; int coherence_mode, alloc_mode; - - if (!strcmp(argv[2], "none")){ + + if (!strcmp(argv[2], "none")) { coherence_mode = FIXED; - coherence = ACC_COH_NONE; + coherence = ACC_COH_NONE; } - else if (!strcmp(argv[2], "llc")){ + else if (!strcmp(argv[2], "llc")) { coherence_mode = FIXED; - coherence = ACC_COH_LLC; + coherence = ACC_COH_LLC; } - else if (!strcmp(argv[2], "recall")){ + else if (!strcmp(argv[2], "recall")) { coherence_mode = FIXED; - coherence = ACC_COH_RECALL; + coherence = ACC_COH_RECALL; } - else if (!strcmp(argv[2], "full")){ + else if (!strcmp(argv[2], "full")) { coherence_mode = FIXED; - coherence = ACC_COH_FULL; + coherence = ACC_COH_FULL; } - else if (!strcmp(argv[2], "auto")){ + else if (!strcmp(argv[2], "auto")) { coherence_mode = FIXED; - coherence = ACC_COH_AUTO; + coherence = ACC_COH_AUTO; } - else if (!strcmp(argv[2], "cfg")){ + else if (!strcmp(argv[2], "cfg")) { coherence_mode = CFG; } - else{ + else { printf("Valid coherence choices include none, llc, recall, full, auto, or cfg\n"); return 1; } - if (!strcmp(argv[3], "preferred")){ + if (!strcmp(argv[3], "preferred")) { alloc_mode = FIXED; - alloc = CONTIG_ALLOC_PREFERRED; + alloc = CONTIG_ALLOC_PREFERRED; } - else if (!strcmp(argv[3], "lloaded")){ + else if (!strcmp(argv[3], "lloaded")) { alloc_mode = FIXED; - alloc = CONTIG_ALLOC_LEAST_LOADED; + alloc = CONTIG_ALLOC_LEAST_LOADED; } - else if (!strcmp(argv[3], "balanced")){ + else if (!strcmp(argv[3], "balanced")) { alloc_mode = FIXED; - alloc = CONTIG_ALLOC_BALANCED; + alloc = CONTIG_ALLOC_BALANCED; } - else if (!strcmp(argv[3], "auto")){ + else if (!strcmp(argv[3], "auto")) { alloc_mode = AUTO; - alloc = ACC_COH_AUTO; + alloc = ACC_COH_AUTO; } - else if (!strcmp(argv[3], "cfg")){ + else if (!strcmp(argv[3], "cfg")) { alloc_mode = CFG; } - else{ + else { printf("Valid alloc choices include preferred, lloaded, balanced, auto, and cfg\n"); return 1; } - soc_config_t* soc_config = malloc(sizeof(soc_config_t)); + soc_config_t *soc_config = malloc(sizeof(soc_config_t)); read_soc_config(f, soc_config); - - //get phases - int nphases; - fscanf(f, "%d\n", &nphases); + + // get phases + int nphases; + fscanf(f, "%d\n", &nphases); dprintf("%d phases\n", nphases); - + struct timespec th_start; struct timespec th_end; - unsigned long long hw_ns = 0, hw_ns_total = 0; - float hw_s = 0, hw_s_total = 0; - + unsigned long long hw_ns = 0, hw_ns_total = 0; + float hw_s = 0, hw_s_total = 0; + int nthreads; accelerator_thread_info_t *thread_info[NPHASES_MAX][NTHREADS_MAX]; uint32_t *buffers[NTHREADS_MAX]; @@ -585,38 +601,40 @@ int main (int argc, char** argv) struct synth_stratus_access **synth_cfg; unsigned *nacc = NULL; - //loop over phases - config, alloc, spawn thread, validate, and free - for (int p = 0; p < nphases; p++){ - config_threads(f, thread_info[p], &cfg, &synth_cfg, p, &nthreads, coherence_mode, coherence, &nacc); - alloc_phase(thread_info[p], &cfg, &synth_cfg, nthreads, *soc_config, alloc_mode, alloc, buffers, p); - + // loop over phases - config, alloc, spawn thread, validate, and free + for (int p = 0; p < nphases; p++) { + config_threads(f, thread_info[p], &cfg, &synth_cfg, p, &nthreads, coherence_mode, coherence, + &nacc); + alloc_phase(thread_info[p], &cfg, &synth_cfg, nthreads, *soc_config, alloc_mode, alloc, + buffers, p); + gettime(&th_start); - + esp_run_parallel(cfg, nthreads, nacc); - gettime(&th_end); - for (int t = 0; t < nthreads; t++){ + gettime(&th_end); + for (int t = 0; t < nthreads; t++) { int errors = validate_buffer(thread_info[p][t], synth_cfg, buffers[t]); - if (errors) - printf("[FAIL] Thread %d.%d : %u errors\n", p, t, errors); - else - printf("[PASS] Thread %d.%d\n", p, t); + if (errors) printf("[FAIL] Thread %d.%d : %u errors\n", p, t, errors); + else + printf("[PASS] Thread %d.%d\n", p, t); } - + hw_ns = ts_subtract(&th_start, &th_end); - hw_ns_total += hw_ns; - hw_s = (float) hw_ns / 1000000000; + hw_ns_total += hw_ns; + hw_s = (float)hw_ns / 1000000000; printf("PHASE.%d %.4f s\n", p, hw_s); - - dump_results(out_file, thread_info[p], cfg, synth_cfg, soc_config, p, nthreads, argv, test_no); + + dump_results(out_file, thread_info[p], cfg, synth_cfg, soc_config, p, nthreads, argv, + test_no); free_phase(thread_info[p], cfg, synth_cfg, nthreads); - free(nacc); + free(nacc); } - hw_s_total = (float) hw_ns_total / 1000000000; - printf("TOTAL %.4f s\n", hw_s_total); - + hw_s_total = (float)hw_ns_total / 1000000000; + printf("TOTAL %.4f s\n", hw_s_total); + free(soc_config->mem_y); free(soc_config->mem_x); free(soc_config->synth_y); @@ -624,6 +642,6 @@ int main (int argc, char** argv) free(soc_config->ddr_hops); free(soc_config); fclose(f); - fclose(out_file); - return 0; + fclose(out_file); + return 0; } diff --git a/accelerators/stratus_hls/synth_stratus/sw/linux/driver/synth_stratus.c b/accelerators/stratus_hls/synth_stratus/sw/linux/driver/synth_stratus.c index 1299ac39d0..da15f2299f 100644 --- a/accelerators/stratus_hls/synth_stratus/sw/linux/driver/synth_stratus.c +++ b/accelerators/stratus_hls/synth_stratus/sw/linux/driver/synth_stratus.c @@ -1,146 +1,136 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "synth_stratus.h" -#define DRV_NAME "synth_stratus" - -#define SYNTH_OFFSET_REG 0x40 -#define SYNTH_PATTERN_REG 0x44 -#define SYNTH_IN_SIZE_REG 0x48 -#define SYNTH_ACCESS_FACTOR_REG 0x4c -#define SYNTH_BURST_LEN_REG 0x50 -#define SYNTH_COMPUTE_BOUND_factor_REG 0x54 -#define SYNTH_IRREGULAR_SEED_REG 0x58 -#define SYNTH_REUSE_FACTOR_REG 0x5c -#define SYNTH_LD_ST_ratio_REG 0x60 -#define SYNTH_STRIDE_LEN_REG 0x64 -#define SYNTH_OUT_SIZE_REG 0x68 -#define SYNTH_IN_PLACE_REG 0x6c -#define SYNTH_WR_DATA_REG 0x70 -#define SYNTH_RD_DATA_REG 0x74 +#define DRV_NAME "synth_stratus" + +#define SYNTH_OFFSET_REG 0x40 +#define SYNTH_PATTERN_REG 0x44 +#define SYNTH_IN_SIZE_REG 0x48 +#define SYNTH_ACCESS_FACTOR_REG 0x4c +#define SYNTH_BURST_LEN_REG 0x50 +#define SYNTH_COMPUTE_BOUND_factor_REG 0x54 +#define SYNTH_IRREGULAR_SEED_REG 0x58 +#define SYNTH_REUSE_FACTOR_REG 0x5c +#define SYNTH_LD_ST_ratio_REG 0x60 +#define SYNTH_STRIDE_LEN_REG 0x64 +#define SYNTH_OUT_SIZE_REG 0x68 +#define SYNTH_IN_PLACE_REG 0x6c +#define SYNTH_WR_DATA_REG 0x70 +#define SYNTH_RD_DATA_REG 0x74 struct synth_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver synth_driver; static struct of_device_id synth_device_ids[] = { - { - .name = "SLD_SYNTH_STRATUS", - }, - { - .name = "eb_014", - }, - { - .compatible = "sld,synth_stratus", - }, - { }, + { + .name = "SLD_SYNTH_STRATUS", + }, + { + .name = "eb_014", + }, + { + .compatible = "sld,synth_stratus", + }, + {}, }; static int synth_devs; // TODO this is never initialized static inline struct synth_stratus_device *to_synth(struct esp_device *esp) { - return container_of(esp, struct synth_stratus_device, esp); + return container_of(esp, struct synth_stratus_device, esp); } static void synth_prep_xfer(struct esp_device *esp, void *arg) { - struct synth_stratus_access *a = arg; - - iowrite32be(a->offset, esp->iomem + SYNTH_OFFSET_REG); - iowrite32be(a->pattern, esp->iomem + SYNTH_PATTERN_REG); - iowrite32be(a->in_size, esp->iomem + SYNTH_IN_SIZE_REG); - iowrite32be(a->access_factor, esp->iomem + SYNTH_ACCESS_FACTOR_REG); - iowrite32be(a->burst_len, esp->iomem + SYNTH_BURST_LEN_REG); - iowrite32be(a->compute_bound_factor, esp->iomem + SYNTH_COMPUTE_BOUND_factor_REG); - iowrite32be(a->irregular_seed, esp->iomem + SYNTH_IRREGULAR_SEED_REG); - iowrite32be(a->reuse_factor, esp->iomem + SYNTH_REUSE_FACTOR_REG); - iowrite32be(a->ld_st_ratio, esp->iomem + SYNTH_LD_ST_ratio_REG); - iowrite32be(a->stride_len, esp->iomem + SYNTH_STRIDE_LEN_REG); - iowrite32be(a->out_size, esp->iomem + SYNTH_OUT_SIZE_REG); - iowrite32be(a->in_place, esp->iomem + SYNTH_IN_PLACE_REG); + struct synth_stratus_access *a = arg; + + iowrite32be(a->offset, esp->iomem + SYNTH_OFFSET_REG); + iowrite32be(a->pattern, esp->iomem + SYNTH_PATTERN_REG); + iowrite32be(a->in_size, esp->iomem + SYNTH_IN_SIZE_REG); + iowrite32be(a->access_factor, esp->iomem + SYNTH_ACCESS_FACTOR_REG); + iowrite32be(a->burst_len, esp->iomem + SYNTH_BURST_LEN_REG); + iowrite32be(a->compute_bound_factor, esp->iomem + SYNTH_COMPUTE_BOUND_factor_REG); + iowrite32be(a->irregular_seed, esp->iomem + SYNTH_IRREGULAR_SEED_REG); + iowrite32be(a->reuse_factor, esp->iomem + SYNTH_REUSE_FACTOR_REG); + iowrite32be(a->ld_st_ratio, esp->iomem + SYNTH_LD_ST_ratio_REG); + iowrite32be(a->stride_len, esp->iomem + SYNTH_STRIDE_LEN_REG); + iowrite32be(a->out_size, esp->iomem + SYNTH_OUT_SIZE_REG); + iowrite32be(a->in_place, esp->iomem + SYNTH_IN_PLACE_REG); iowrite32be(a->wr_data, esp->iomem + SYNTH_WR_DATA_REG); iowrite32be(a->rd_data, esp->iomem + SYNTH_RD_DATA_REG); } -static bool synth_xfer_input_ok(struct esp_device *esp, void *arg) -{ - return true; -} +static bool synth_xfer_input_ok(struct esp_device *esp, void *arg) { return true; } static int synth_probe(struct platform_device *pdev) { - struct synth_stratus_device *synth; - struct esp_device *esp; - int rc; - - synth = kzalloc(sizeof(*synth), GFP_KERNEL); - if (synth == NULL) - return -ENOMEM; - esp = &synth->esp; - esp->module = THIS_MODULE; - esp->number = synth_devs; - esp->driver = &synth_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - synth_devs++; - return 0; - err: - kfree(synth); - return rc; + struct synth_stratus_device *synth; + struct esp_device *esp; + int rc; + + synth = kzalloc(sizeof(*synth), GFP_KERNEL); + if (synth == NULL) return -ENOMEM; + esp = &synth->esp; + esp->module = THIS_MODULE; + esp->number = synth_devs; + esp->driver = &synth_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + synth_devs++; + return 0; +err: + kfree(synth); + return rc; } static int __exit synth_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct synth_stratus_device *synth = to_synth(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct synth_stratus_device *synth = to_synth(esp); - esp_device_unregister(esp); - kfree(synth); - return 0; + esp_device_unregister(esp); + kfree(synth); + return 0; } static struct esp_driver synth_driver = { - .plat = { - .probe = synth_probe, - .remove = synth_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = synth_device_ids, - }, - }, - .xfer_input_ok = synth_xfer_input_ok, - .prep_xfer = synth_prep_xfer, - .ioctl_cm = SYNTH_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct synth_stratus_access), + .plat = + { + .probe = synth_probe, + .remove = synth_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = synth_device_ids, + }, + }, + .xfer_input_ok = synth_xfer_input_ok, + .prep_xfer = synth_prep_xfer, + .ioctl_cm = SYNTH_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct synth_stratus_access), }; -static int __init synth_init(void) -{ - return esp_driver_register(&synth_driver); -} +static int __init synth_init(void) { return esp_driver_register(&synth_driver); } -static void __exit synth_exit(void) -{ - esp_driver_unregister(&synth_driver); -} +static void __exit synth_exit(void) { esp_driver_unregister(&synth_driver); } -module_init(synth_init) -module_exit(synth_exit) +module_init(synth_init) module_exit(synth_exit) -MODULE_DEVICE_TABLE(of, synth_device_ids); + MODULE_DEVICE_TABLE(of, synth_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/synth_stratus/sw/linux/include/synth_stratus.h b/accelerators/stratus_hls/synth_stratus/sw/linux/include/synth_stratus.h index ad4a93cded..067dfe2ac9 100644 --- a/accelerators/stratus_hls/synth_stratus/sw/linux/include/synth_stratus.h +++ b/accelerators/stratus_hls/synth_stratus/sw/linux/include/synth_stratus.h @@ -4,43 +4,43 @@ #define _SYNTH_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include -enum synth_pattern {PATTERN_STREAMING = 0, PATTERN_STRIDED, PATTERN_IRREGULAR}; +enum synth_pattern { PATTERN_STREAMING = 0, PATTERN_STRIDED, PATTERN_IRREGULAR }; struct synth_stratus_access { - struct esp_access esp; - unsigned int offset; /* Memory offset when chaining dependent accelerators */ - enum synth_pattern pattern; /* load pattern: streaming, strided, irregular */ - unsigned int in_size; /* size of input dataset */ - unsigned int access_factor; /* accessed portion of dataset */ - unsigned int burst_len; /* dma burst length */ - unsigned int compute_bound_factor; /* cycles for word transferred */ - unsigned int irregular_seed; /* random integer used for irregular DMA */ - unsigned int reuse_factor; /* # of times the dataset is accessed */ - unsigned int ld_st_ratio; /* size of data to be loaded w.r.t data to be stored */ - unsigned int stride_len; /* stride length for strided pattern */ - unsigned int out_size; /* size of output dataset */ - unsigned int in_place; /* output stored in place of input */ - unsigned int wr_data; /* output word to be written */ - unsigned int rd_data; /* input word to be validate reads */ + struct esp_access esp; + unsigned int offset; /* Memory offset when chaining dependent accelerators */ + enum synth_pattern pattern; /* load pattern: streaming, strided, irregular */ + unsigned int in_size; /* size of input dataset */ + unsigned int access_factor; /* accessed portion of dataset */ + unsigned int burst_len; /* dma burst length */ + unsigned int compute_bound_factor; /* cycles for word transferred */ + unsigned int irregular_seed; /* random integer used for irregular DMA */ + unsigned int reuse_factor; /* # of times the dataset is accessed */ + unsigned int ld_st_ratio; /* size of data to be loaded w.r.t data to be stored */ + unsigned int stride_len; /* stride length for strided pattern */ + unsigned int out_size; /* size of output dataset */ + unsigned int in_place; /* output stored in place of input */ + unsigned int wr_data; /* output word to be written */ + unsigned int rd_data; /* input word to be validate reads */ unsigned src_offset; unsigned dst_offset; }; -enum alloc_effort {ALLOC_NONE, ALLOC_AUTO}; +enum alloc_effort { ALLOC_NONE, ALLOC_AUTO }; -#define SYNTH_STRATUS_IOC_ACCESS _IOW ('S', 0, struct synth_stratus_access) +#define SYNTH_STRATUS_IOC_ACCESS _IOW('S', 0, struct synth_stratus_access) #endif /* _SYNTH_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/vitbfly2_stratus/hw/src/vitbfly2.cpp b/accelerators/stratus_hls/vitbfly2_stratus/hw/src/vitbfly2.cpp index 3ca88e6061..24ca6208a2 100644 --- a/accelerators/stratus_hls/vitbfly2_stratus/hw/src/vitbfly2.cpp +++ b/accelerators/stratus_hls/vitbfly2_stratus/hw/src/vitbfly2.cpp @@ -34,7 +34,6 @@ void vitbfly2::load_input() // d_brtab27[i] = 0; // } - // Config { HLS_DEFINE_PROTOCOL("load-config"); @@ -50,67 +49,66 @@ void vitbfly2::load_input() HLS_DEFINE_PROTOCOL("load-dma"); uint32_t dma_addr = 0; - //for (uint16_t b = 0; b < /* number of transfers */; b++) + // for (uint16_t b = 0; b < /* number of transfers */; b++) { dma_info_t dma_info(dma_addr, 6 * 64 / WORDS_PER_DMA, SIZE_BYTE); // Configure DMA transaction this->dma_read_ctrl.put(dma_info); for (uint16_t j = 0; j < 6; j++) - for (uint16_t i = 0; i < 64; i += WORDS_PER_DMA) - { + for (uint16_t i = 0; i < 64; i += WORDS_PER_DMA) { wait(); sc_dt::sc_bv data = this->dma_read_chnl.get(); - switch(j) { - case 0: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - mm0[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); - } - break; - - case 1: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - mm1[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); - } - break; - - case 2: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - pp0[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); - } - break; - - case 3: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - pp1[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); - } - break; - - case 4: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - unsigned index = i % 32; - if (i < 32) - d_brtab27[0][index + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); - else - d_brtab27[1][index + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); - } - break; - - case 5: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - symbols[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); - } - break; - - default: - break; - + switch (j) { + case 0: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + mm0[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); + } + break; + + case 1: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + mm1[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); + } + break; + + case 2: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + pp0[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); + } + break; + + case 3: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + pp1[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); + } + break; + + case 4: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + unsigned index = i % 32; + if (i < 32) + d_brtab27[0][index + k] = + data.range(((k + 1) << 3) - 1, k << 3).to_uint(); + else + d_brtab27[1][index + k] = + data.range(((k + 1) << 3) - 1, k << 3).to_uint(); + } + break; + + case 5: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + symbols[i + k] = data.range(((k + 1) << 3) - 1, k << 3).to_uint(); + } + break; + + default: break; } } this->load_compute_handshake(); @@ -123,8 +121,6 @@ void vitbfly2::load_input() } } - - void vitbfly2::store_output() { // Reset @@ -163,44 +159,41 @@ void vitbfly2::store_output() this->dma_write_ctrl.put(dma_info); for (uint16_t j = 0; j < 4; j++) - for (uint16_t i = 0; i < 64; i += WORDS_PER_DMA) - { + for (uint16_t i = 0; i < 64; i += WORDS_PER_DMA) { wait(); sc_dt::sc_bv data; - switch(j) { - case 0: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - data.range(((k + 1) << 3) - 1, k << 3) = sc_bv<8>(mm0[i + k]); - } - break; - - case 1: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - data.range(((k + 1) << 3) - 1, k << 3) = sc_bv<8>(mm1[i + k]); - } - break; + switch (j) { + case 0: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + data.range(((k + 1) << 3) - 1, k << 3) = sc_bv<8>(mm0[i + k]); + } + break; - case 2: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - data.range(((k + 1) << 3) - 1, k << 3) = sc_bv<8>(pp0[i + k]); - } - break; + case 1: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + data.range(((k + 1) << 3) - 1, k << 3) = sc_bv<8>(mm1[i + k]); + } + break; - case 3: - for (int k = 0; k < WORDS_PER_DMA; k++) { - HLS_UNROLL_LOOP_SIMPLE; - data.range(((k + 1) << 3) - 1, k << 3) = sc_bv<8>(pp1[i + k]); - } - break; + case 2: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + data.range(((k + 1) << 3) - 1, k << 3) = sc_bv<8>(pp0[i + k]); + } + break; + case 3: + for (int k = 0; k < WORDS_PER_DMA; k++) { + HLS_UNROLL_LOOP_SIMPLE; + data.range(((k + 1) << 3) - 1, k << 3) = sc_bv<8>(pp1[i + k]); + } + break; } this->dma_write_chnl.put(data); - } } @@ -211,7 +204,6 @@ void vitbfly2::store_output() } } - void vitbfly2::compute_kernel() { // Reset @@ -237,7 +229,6 @@ void vitbfly2::compute_kernel() // User-defined config code } - // Compute { this->compute_load_handshake(); diff --git a/accelerators/stratus_hls/vitbfly2_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/vitbfly2_stratus/hw/tb/sc_main.cpp index 9d0fcd90e5..365a845fdc 100644 --- a/accelerators/stratus_hls/vitbfly2_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/vitbfly2_stratus/hw/tb/sc_main.cpp @@ -5,49 +5,49 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; // Default settings if argv[] is not set -std::string in_path = "in.txt"; +std::string in_path = "in.txt"; std::string gold_path = "gold.txt"; extern void esc_elaborate() { - // Creating the whole system - testbench = new system_t("testbench", in_path, gold_path); + // Creating the whole system + testbench = new system_t("testbench", in_path, gold_path); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - // Kills Warning from FlexChannels library: no unique name assignment - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + // Kills Warning from FlexChannels library: no unique name assignment + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); - esc_cleanup(); + esc_log_pass(); + esc_cleanup(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/vitbfly2_stratus/sw/baremetal/vitbfly2.c b/accelerators/stratus_hls/vitbfly2_stratus/sw/baremetal/vitbfly2.c index 50a61b64af..dcaddcf1f0 100644 --- a/accelerators/stratus_hls/vitbfly2_stratus/sw/baremetal/vitbfly2.c +++ b/accelerators/stratus_hls/vitbfly2_stratus/sw/baremetal/vitbfly2.c @@ -6,15 +6,14 @@ * Select Scatter-Gather in ESP configuration */ - #include #include #include #include -#define SLD_VITBFLY2 0x16 -#define DEV_NAME "sld,vitbfly2_stratus" +#define SLD_VITBFLY2 0x16 +#define DEV_NAME "sld,vitbfly2_stratus" #define COLS 40 #define ROWS 30 @@ -23,149 +22,146 @@ /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK ((VITBFLY2_BUF_SIZE % CHUNK_SIZE == 0) ? \ - (VITBFLY2_BUF_SIZE / CHUNK_SIZE) : \ - (VITBFLY2_BUF_SIZE / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK \ + ((VITBFLY2_BUF_SIZE % CHUNK_SIZE == 0) ? (VITBFLY2_BUF_SIZE / CHUNK_SIZE) : \ + (VITBFLY2_BUF_SIZE / CHUNK_SIZE) + 1) // User defined registers -#define VITBFLY2_NIMAGES_REG 0x40 -#define VITBFLY2_NROWS_REG 0x44 -#define VITBFLY2_NCOLS_REG 0x48 - +#define VITBFLY2_NIMAGES_REG 0x40 +#define VITBFLY2_NROWS_REG 0x44 +#define VITBFLY2_NCOLS_REG 0x48 -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int n; - int ndev; - struct esp_device *espdevs = NULL; - unsigned coherence; - - // TODO This app is just a placeholder. Exit! - printf("There is no bare-metal app for the 'vitbfly2' accelerator.\n"); - printf("This bare-metal app is a placeholder.\n"); - printf("Exiting...\n"); - return 0; - - ndev = probe(&espdevs, VENDOR_SLD, SLD_VITBFLY2, DEV_NAME); - if (ndev <= 0) { - printf("Error: %s device not found!\n", DEV_NAME); - exit(EXIT_FAILURE); - } - - for (n = 0; n < ndev; n++) { + int n; + int ndev; + struct esp_device *espdevs = NULL; + unsigned coherence; + + // TODO This app is just a placeholder. Exit! + printf("There is no bare-metal app for the 'vitbfly2' accelerator.\n"); + printf("This bare-metal app is a placeholder.\n"); + printf("Exiting...\n"); + return 0; + + ndev = probe(&espdevs, VENDOR_SLD, SLD_VITBFLY2, DEV_NAME); + if (ndev <= 0) { + printf("Error: %s device not found!\n", DEV_NAME); + exit(EXIT_FAILURE); + } + + for (n = 0; n < ndev; n++) { #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - struct esp_device *dev = &espdevs[n]; - int done; - int i, j; - unsigned **ptable = NULL; - short *mem; - short gold[COLS * ROWS]; - unsigned errors = 0; - int scatter_gather = 1; - - printf("******************** %s.%d ********************\n", DEV_NAME, n); - - // Check access ok (TODO) - - // Check if scatter-gather DMA is disabled - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled; revert to contiguous buffer.\n"); - scatter_gather = 0; - } else { - printf(" -> scatter-gather DMA is enabled.\n"); - } - - if (scatter_gather) - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { - printf(" Trying to allocate %lu chunks on %d TLB available entries\n", - NCHUNK, ioread32(dev, PT_NCHUNK_MAX_REG)); - break; - } - - // Allocate memory (will be contigous anyway in baremetal) - mem = aligned_malloc(VITBFLY2_BUF_SIZE); - printf(" memory buffer base-address = %p\n", mem); - - if (scatter_gather) { - //Alocate and populate page table - ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); - for (i = 0; i < NCHUNK; i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(unsigned short))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK); - } - - // Initialize input (TODO) - #include "data.h" - - // Configure device - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); - - if (scatter_gather) { - iowrite32(dev, PT_ADDRESS_REG, (uintptr_t) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - iowrite32(dev, SRC_OFFSET_REG, 0); - iowrite32(dev, DST_OFFSET_REG, 0); - } else { - iowrite32(dev, SRC_OFFSET_REG, (uintptr_t) mem); - iowrite32(dev, DST_OFFSET_REG, (uintptr_t) mem); - } - - // Accelerator-specific registers - iowrite32(dev, VITBFLY2_NIMAGES_REG, 1); - iowrite32(dev, VITBFLY2_NROWS_REG, ROWS); - iowrite32(dev, VITBFLY2_NCOLS_REG, COLS); - - // Flush for non-coherent DMA - esp_flush(coherence); - - // Start accelerator - printf(" Start..\n"); - - iowrite32(dev, CMD_REG, CMD_MASK_START); - - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - printf(" Done\n"); - - /* Validation */ - printf(" validating...\n"); - - for (i = 0; i < ROWS; i++) - for (j = 0; j < COLS; j++) - if (mem[i * COLS + j] != gold[i * COLS + j]) { - printf(" %d,%d: %d != %d\n", i, j, mem[i * COLS + j], gold[i * COLS + j]); - errors++; - } - - - if (errors) { - printf(" ... FAIL\n"); - } else { - printf(" ... PASS\n"); - } - - if (scatter_gather) - aligned_free(ptable); - aligned_free(mem); - - printf("**************************************************\n\n"); - } - } - return 0; + struct esp_device *dev = &espdevs[n]; + int done; + int i, j; + unsigned **ptable = NULL; + short *mem; + short gold[COLS * ROWS]; + unsigned errors = 0; + int scatter_gather = 1; + + printf("******************** %s.%d ********************\n", DEV_NAME, n); + + // Check access ok (TODO) + + // Check if scatter-gather DMA is disabled + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled; revert to contiguous buffer.\n"); + scatter_gather = 0; + } + else { + printf(" -> scatter-gather DMA is enabled.\n"); + } + + if (scatter_gather) + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { + printf(" Trying to allocate %lu chunks on %d TLB available entries\n", NCHUNK, + ioread32(dev, PT_NCHUNK_MAX_REG)); + break; + } + + // Allocate memory (will be contigous anyway in baremetal) + mem = aligned_malloc(VITBFLY2_BUF_SIZE); + printf(" memory buffer base-address = %p\n", mem); + + if (scatter_gather) { + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); + for (i = 0; i < NCHUNK; i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(unsigned short))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK); + } + +// Initialize input (TODO) +#include "data.h" + + // Configure device + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); + + if (scatter_gather) { + iowrite32(dev, PT_ADDRESS_REG, (uintptr_t)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + iowrite32(dev, SRC_OFFSET_REG, 0); + iowrite32(dev, DST_OFFSET_REG, 0); + } + else { + iowrite32(dev, SRC_OFFSET_REG, (uintptr_t)mem); + iowrite32(dev, DST_OFFSET_REG, (uintptr_t)mem); + } + + // Accelerator-specific registers + iowrite32(dev, VITBFLY2_NIMAGES_REG, 1); + iowrite32(dev, VITBFLY2_NROWS_REG, ROWS); + iowrite32(dev, VITBFLY2_NCOLS_REG, COLS); + + // Flush for non-coherent DMA + esp_flush(coherence); + + // Start accelerator + printf(" Start..\n"); + + iowrite32(dev, CMD_REG, CMD_MASK_START); + + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + printf(" Done\n"); + + /* Validation */ + printf(" validating...\n"); + + for (i = 0; i < ROWS; i++) + for (j = 0; j < COLS; j++) + if (mem[i * COLS + j] != gold[i * COLS + j]) { + printf(" %d,%d: %d != %d\n", i, j, mem[i * COLS + j], gold[i * COLS + j]); + errors++; + } + + if (errors) { printf(" ... FAIL\n"); } + else { + printf(" ... PASS\n"); + } + + if (scatter_gather) aligned_free(ptable); + aligned_free(mem); + + printf("**************************************************\n\n"); + } + } + return 0; } - diff --git a/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/app/vitbfly2.c b/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/app/vitbfly2.c index fd844dfaab..117cbb6660 100644 --- a/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/app/vitbfly2.c +++ b/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/app/vitbfly2.c @@ -4,7 +4,7 @@ int main(int argc, char **argv) { - decode_wrapper(); + decode_wrapper(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/driver/vitbfly2_stratus.c b/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/driver/vitbfly2_stratus.c index 5a2a19fd46..b98f8426cf 100644 --- a/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/driver/vitbfly2_stratus.c +++ b/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/driver/vitbfly2_stratus.c @@ -1,117 +1,105 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include -#include #include +#include +#include #include -#include #include +#include #include "vitbfly2_stratus.h" -#define DRV_NAME "vitbfly2_stratus" +#define DRV_NAME "vitbfly2_stratus" struct vitbfly2_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver vitbfly2_driver; static struct of_device_id vitbfly2_device_ids[] = { - { - .name = "SLD_VITBFLY2_STRATUS", - }, - { - .name = "eb_016", - }, - { - .compatible = "sld,vitbfly2_stratus", - }, - { }, + { + .name = "SLD_VITBFLY2_STRATUS", + }, + { + .name = "eb_016", + }, + { + .compatible = "sld,vitbfly2_stratus", + }, + {}, }; static int vitbfly2_devs; static inline struct vitbfly2_stratus_device *to_vitbfly2(struct esp_device *esp) { - return container_of(esp, struct vitbfly2_stratus_device, esp); + return container_of(esp, struct vitbfly2_stratus_device, esp); } -static void vitbfly2_prep_xfer(struct esp_device *esp, void *arg) -{ -} +static void vitbfly2_prep_xfer(struct esp_device *esp, void *arg) {} -static bool vitbfly2_xfer_input_ok(struct esp_device *esp, void *arg) -{ - return true; -} +static bool vitbfly2_xfer_input_ok(struct esp_device *esp, void *arg) { return true; } static int vitbfly2_probe(struct platform_device *pdev) { - struct vitbfly2_stratus_device *vitbfly2; - struct esp_device *esp; - int rc; - - vitbfly2 = kzalloc(sizeof(*vitbfly2), GFP_KERNEL); - if (vitbfly2 == NULL) - return -ENOMEM; - esp = &vitbfly2->esp; - esp->module = THIS_MODULE; - esp->number = vitbfly2_devs; - esp->driver = &vitbfly2_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - vitbfly2_devs++; - return 0; - err: - kfree(vitbfly2); - return rc; + struct vitbfly2_stratus_device *vitbfly2; + struct esp_device *esp; + int rc; + + vitbfly2 = kzalloc(sizeof(*vitbfly2), GFP_KERNEL); + if (vitbfly2 == NULL) return -ENOMEM; + esp = &vitbfly2->esp; + esp->module = THIS_MODULE; + esp->number = vitbfly2_devs; + esp->driver = &vitbfly2_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + vitbfly2_devs++; + return 0; +err: + kfree(vitbfly2); + return rc; } static int __exit vitbfly2_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct vitbfly2_stratus_device *vitbfly2 = to_vitbfly2(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct vitbfly2_stratus_device *vitbfly2 = to_vitbfly2(esp); - esp_device_unregister(esp); - kfree(vitbfly2); - return 0; + esp_device_unregister(esp); + kfree(vitbfly2); + return 0; } static struct esp_driver vitbfly2_driver = { - .plat = { - .probe = vitbfly2_probe, - .remove = vitbfly2_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = vitbfly2_device_ids, - }, - }, - .xfer_input_ok = vitbfly2_xfer_input_ok, - .prep_xfer = vitbfly2_prep_xfer, - .ioctl_cm = VITBFLY2_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct vitbfly2_stratus_access), + .plat = + { + .probe = vitbfly2_probe, + .remove = vitbfly2_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = vitbfly2_device_ids, + }, + }, + .xfer_input_ok = vitbfly2_xfer_input_ok, + .prep_xfer = vitbfly2_prep_xfer, + .ioctl_cm = VITBFLY2_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct vitbfly2_stratus_access), }; -static int __init vitbfly2_init(void) -{ - return esp_driver_register(&vitbfly2_driver); -} +static int __init vitbfly2_init(void) { return esp_driver_register(&vitbfly2_driver); } -static void __exit vitbfly2_exit(void) -{ - esp_driver_unregister(&vitbfly2_driver); -} +static void __exit vitbfly2_exit(void) { esp_driver_unregister(&vitbfly2_driver); } -module_init(vitbfly2_init) -module_exit(vitbfly2_exit) +module_init(vitbfly2_init) module_exit(vitbfly2_exit) -MODULE_DEVICE_TABLE(of, vitbfly2_device_ids); + MODULE_DEVICE_TABLE(of, vitbfly2_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/include/vitbfly2_stratus.h b/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/include/vitbfly2_stratus.h index 58621d018e..88e7e0341d 100644 --- a/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/include/vitbfly2_stratus.h +++ b/accelerators/stratus_hls/vitbfly2_stratus/sw/linux/include/vitbfly2_stratus.h @@ -4,23 +4,23 @@ #define _VITBFLY2_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct vitbfly2_stratus_access { - struct esp_access esp; + struct esp_access esp; }; -#define VITBFLY2_STRATUS_IOC_ACCESS _IOW ('S', 0, struct vitbfly2_stratus_access) +#define VITBFLY2_STRATUS_IOC_ACCESS _IOW('S', 0, struct vitbfly2_stratus_access) #endif /* _VITBFLY2_STRATUS_H_ */ diff --git a/accelerators/stratus_hls/vitdodec_stratus/hw/src/vitdodec.cpp b/accelerators/stratus_hls/vitdodec_stratus/hw/src/vitdodec.cpp index 712ac86f19..6be7bdd8ec 100644 --- a/accelerators/stratus_hls/vitdodec_stratus/hw/src/vitdodec.cpp +++ b/accelerators/stratus_hls/vitdodec_stratus/hw/src/vitdodec.cpp @@ -39,21 +39,20 @@ void vitdodec::load_input() // User-defined config code /* <<--local-params-->> */ - cbps = config.cbps; + cbps = config.cbps; ntraceback = config.ntraceback; - data_bits = config.data_bits; + data_bits = config.data_bits; } // Load { HLS_PROTO("load-dma"); - bool ping = true; + bool ping = true; uint32_t offset = 0; wait(); // Batching - for (uint16_t b = 0; b < 1; b++) - { + for (uint16_t b = 0; b < 1; b++) { wait(); #if (DMA_WORD_PER_BEAT == 0) uint32_t length = 24852; @@ -61,8 +60,7 @@ void vitdodec::load_input() uint32_t length = round_up(24852, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_IN_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_IN_WORD) { wait(); // Configure DMA transaction uint32_t len = rem > PLM_IN_WORD ? PLM_IN_WORD : rem; @@ -78,27 +76,25 @@ void vitdodec::load_input() #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - for (uint16_t i = 0; i < len; i++) - { + for (uint16_t i = 0; i < len; i++) { sc_dt::sc_bv dataBv; - for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) - { - dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH) = this->dma_read_chnl.get(); + for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) { + dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH) = + this->dma_read_chnl.get(); wait(); } // Write to PLM - //if (ping) - plm_in_ping[i] = dataBv.to_int64(); - //else + // if (ping) + plm_in_ping[i] = dataBv.to_int64(); + // else // plm_in_pong[i] = dataBv.to_int64(); } #else - for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { HLS_BREAK_DEP(plm_in_ping); - //HLS_BREAK_DEP(plm_in_pong); + // HLS_BREAK_DEP(plm_in_pong); sc_dt::sc_bv dataBv; @@ -106,16 +102,17 @@ void vitdodec::load_input() wait(); // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; - //if (ping) - plm_in_ping[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); - //else - // plm_in_pong[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + // if (ping) + plm_in_ping[i + k] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + // else + // plm_in_pong[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * + // DATA_WIDTH).to_int64(); } } - #if(0) + #if (0) { printf(" memory in = "); int limi = 0; @@ -147,16 +144,16 @@ void vitdodec::load_input() } printf("\n\n"); - //sc_stop(); - //wait(); + // sc_stop(); + // wait(); } - #endif + #endif #endif this->load_compute_handshake(); - //ping = !ping; - } // for (rem = - } // for (b = 0 ... - } // Load + // ping = !ping; + } // for (rem = + } // for (b = 0 ... + } // Load // Conclude { @@ -164,8 +161,6 @@ void vitdodec::load_input() } } - - void vitdodec::store_output() { // Reset @@ -194,9 +189,9 @@ void vitdodec::store_output() // User-defined config code /* <<--local-params-->> */ - cbps = config.cbps; + cbps = config.cbps; ntraceback = config.ntraceback; - data_bits = config.data_bits; + data_bits = config.data_bits; } // Store @@ -212,8 +207,7 @@ void vitdodec::store_output() wait(); // Batching - for (uint16_t b = 0; b < 1; b++) - { + for (uint16_t b = 0; b < 1; b++) { wait(); #if (DMA_WORD_PER_BEAT == 0) uint32_t length = 18585; @@ -221,8 +215,7 @@ void vitdodec::store_output() uint32_t length = round_up(18585, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) { this->store_compute_handshake(); @@ -240,46 +233,45 @@ void vitdodec::store_output() #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - for (uint16_t i = 0; i < len; i++) - { + for (uint16_t i = 0; i < len; i++) { // Read from PLM sc_dt::sc_int data; wait(); - //if (ping) - data = plm_out_ping[i]; - //else + // if (ping) + data = plm_out_ping[i]; + // else // data = plm_out_pong[i]; sc_dt::sc_bv dataBv(data); uint16_t k = 0; - for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) - { - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) { + this->dma_write_chnl.put( + dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); wait(); } // Last beat on the bus does not require wait(), which is // placed before accessing the PLM - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + this->dma_write_chnl.put(dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); } #else - for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { sc_dt::sc_bv dataBv; // Read from PLM wait(); - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; - //if (ping) - dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_ping[i + k]; - //else - // dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_pong[i + k]; + // if (ping) + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = + plm_out_ping[i + k]; + // else + // dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_pong[i + // + k]; } this->dma_write_chnl.put(dataBv); } #endif - //ping = !ping; + // ping = !ping; } } } @@ -291,7 +283,6 @@ void vitdodec::store_output() } } - void vitdodec::compute_kernel() { // Reset @@ -320,18 +311,16 @@ void vitdodec::compute_kernel() // User-defined config code /* <<--local-params-->> */ - cbps = config.cbps; + cbps = config.cbps; ntraceback = config.ntraceback; - data_bits = config.data_bits; + data_bits = config.data_bits; } - // Compute bool ping = true; { - for (uint16_t b = 0; b < 1; b++) - { - uint32_t in_length = 24852; + for (uint16_t b = 0; b < 1; b++) { + uint32_t in_length = 24852; uint32_t out_length = 18585; // int out_rem = out_length; @@ -349,9 +338,11 @@ void vitdodec::compute_kernel() // ntraceback : INPUT : X : int = 4 bytes (REGISTER) // data_bits : INPUT : X : int = 4 bytes (REGISTER) // d_branchtab27_generic : INPUT : 0 : uint8_t[2][32] = 64 bytes - // in_depuncture_pattern : INPUT : 64 : uint8_t[8] (max is 6 bytes + 2 padding bytes) - // depd_data : INPUT : 72 : uint8_t[MAX_ENCODED_BITS == 24780] (depunctured data) - // : OUTPUT : 0 : uint8_t[MAX_ENCODED_BITS * 3 / 4 == 18585 ] : The decoded data stream + // in_depuncture_pattern : INPUT : 64 : uint8_t[8] (max is 6 bytes + 2 + // padding bytes) depd_data : INPUT : 72 : + // uint8_t[MAX_ENCODED_BITS == 24780] (depunctured data) : + // OUTPUT : 0 : uint8_t[MAX_ENCODED_BITS * 3 / 4 == 18585 ] : The + // decoded data stream /* THESE ARE JUST USED LOCALLY IN THIS FUNCTION NOW */ /* BUT they must reset to zero on each invocation */ @@ -360,26 +351,26 @@ void vitdodec::compute_kernel() // l_metric1_generic : INPUT : uint8_t[64] // l_path0_generic : INPUT : uint8_t[64] // l_path1_generic : INPUT : uint8_t[64] - // l_store_pos : INPUT : int (position in circular traceback buffer?) - // l_mmresult : OUTPUT : uint8_t[64] - // l_ppresult : OUTPUT : uint8_t[ntraceback_MAX][ 64 bytes ] + // l_store_pos : INPUT : int (position in circular traceback + // buffer?) l_mmresult : OUTPUT : uint8_t[64] l_ppresult : OUTPUT + // : uint8_t[ntraceback_MAX][ 64 bytes ] - int in_count = 0; + int in_count = 0; int out_count = 0; int n_decoded = 0; - int idx_brtab27_0 = 0; + int idx_brtab27_0 = 0; int idx_brtab27_1 = 32; int idx_depunc_ptn = 64; int idx_depd_data = 72; - uint8_t l_metric0_generic[64]; - uint8_t l_metric1_generic[64]; - uint8_t l_path0_generic[64]; - uint8_t l_path1_generic[64]; - uint8_t l_mmresult[64]; - uint8_t l_ppresult[TRACEBACK_MAX][64]; - int l_store_pos = 0; + uint8_t l_metric0_generic[64]; + uint8_t l_metric1_generic[64]; + uint8_t l_path0_generic[64]; + uint8_t l_path1_generic[64]; + uint8_t l_mmresult[64]; + uint8_t l_ppresult[TRACEBACK_MAX][64]; + int l_store_pos = 0; HLS_FLAT(l_metric0_generic); HLS_FLAT(l_metric1_generic); @@ -388,26 +379,25 @@ void vitdodec::compute_kernel() HLS_FLAT(l_mmresult); HLS_FLAT(l_ppresult); - -#if(0) +#if (0) { printf(" d_brtab27_0 = "); for (int li = 0; li < 32; li++) { - printf("%u", (unsigned char)plm_in_ping[idx_brtab27_0+li]); + printf("%u", (unsigned char)plm_in_ping[idx_brtab27_0 + li]); if ((li % 8) == 7) { printf(" "); } } printf("\n d_brtab27_1 = "); for (int li = 0; li < 32; li++) { - printf("%u", (unsigned char)plm_in_ping[idx_brtab27_1+li]); + printf("%u", (unsigned char)plm_in_ping[idx_brtab27_1 + li]); if ((li % 8) == 7) { printf(" "); } } printf("\n depunct_ptn = "); for (int li = 0; li < 8; li++) { - printf("%u", (unsigned char)plm_in_ping[idx_depunc_ptn+li]); + printf("%u", (unsigned char)plm_in_ping[idx_depunc_ptn + li]); } printf("\n dep_data = "); for (int li = 0; li < 32; li++) { - printf("%u", (unsigned char)plm_in_ping[idx_depd_data+li]); + printf("%u", (unsigned char)plm_in_ping[idx_depd_data + li]); if ((li % 8) == 7) { printf(" "); } } printf("\n"); @@ -425,7 +415,7 @@ void vitdodec::compute_kernel() for (int li = 0; li < 32; li++) { printf("%u", (unsigned char)plm_in_ping[limi++]); if ((li % 8) == 7) { printf(" "); } - } + } printf("\n depnc "); for (int li = 0; li < 8; li++) { printf("%u", (unsigned char)plm_in_ping[limi++]); @@ -444,29 +434,29 @@ void vitdodec::compute_kernel() for (int i = 0; i < 64; i++) { l_metric0_generic[i] = 0; - l_path0_generic[i] = 0; + l_path0_generic[i] = 0; l_metric1_generic[i] = 0; - l_path1_generic[i] = 0; - l_mmresult[i] = 0; + l_path1_generic[i] = 0; + l_mmresult[i] = 0; for (int j = 0; j < TRACEBACK_MAX; j++) { l_ppresult[j][i] = 0; } } int viterbi_butterfly_calls = 0; - while(n_decoded < data_bits) { - //printf("n_decoded = %u vs %u = data_bits\n", n_decoded, data_bits); - if ((in_count % 4) == 0) { //0 or 3 + while (n_decoded < data_bits) { + // printf("n_decoded = %u vs %u = data_bits\n", n_decoded, data_bits); + if ((in_count % 4) == 0) { // 0 or 3 /* The basic Viterbi decoder operation, called a "butterfly" * operation because of the way it looks on a trellis diagram. Each - * butterfly involves an Add-Compare-Select (ACS) operation on the two nodes - * where the 0 and 1 paths from the current node merge at the next step of - * the trellis. + * butterfly involves an Add-Compare-Select (ACS) operation on the two + *nodes where the 0 and 1 paths from the current node merge at the next + *step of the trellis. * * The code polynomials are assumed to have 1's on both ends. Given a * function encode_state() that returns the two symbols for a given - * encoder state in the low two bits, such a code will have the following - * identities for even 'n' < 64: + * encoder state in the low two bits, such a code will have the + *following identities for even 'n' < 64: * * encode_state(n) = encode_state(n+65) * encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n)) @@ -483,10 +473,10 @@ void vitdodec::compute_kernel() */ // INPUTS/OUTPUTS: All are 64-entry (bytes) arrays randomly accessed. - // symbols : INPUT : Array [ 4 bytes ] + // symbols : INPUT : Array [ 4 bytes ] // mm0 : INPUT/OUTPUT : Array [ 64 bytes ] // mm1 : INPUT/OUTPUT : Array [ 64 bytes ] - // pp0 : INPUT/OUTPUT : Array [ 64 bytes ] + // pp0 : INPUT/OUTPUT : Array [ 64 bytes ] // pp1 : INPUT/OUTPUT : Array [ 64 bytes ] // d_branchtab27_generic[1].c[] : INPUT : Array [2].c[32] {GLOBAL} // @@ -495,33 +485,42 @@ void vitdodec::compute_kernel() /* unsigned char *mm0, unsigned char *mm1, */ /* unsigned char *pp0, unsigned char *pp1) */ { - unsigned char *mm0 = l_metric0_generic; - unsigned char *mm1 = l_metric1_generic; - unsigned char *pp0 = l_path0_generic; - unsigned char *pp1 = l_path1_generic; - unsigned char symbols[4];// = (unsigned char)plm_in_ping[(idx_depd_data + in_count) & 0xfffffffc]; + unsigned char *mm0 = l_metric0_generic; + unsigned char *mm1 = l_metric1_generic; + unsigned char *pp0 = l_path0_generic; + unsigned char *pp1 = l_path1_generic; + unsigned char + symbols[4]; // = (unsigned char)plm_in_ping[(idx_depd_data + + // in_count) & 0xfffffffc]; HLS_FLAT(symbols); - symbols[0] = (unsigned char)plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + 0]; - symbols[1] = (unsigned char)plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + 1]; - symbols[2] = (unsigned char)plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + 2]; - symbols[3] = (unsigned char)plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + 3]; - - // These are used to "virtually" rename the uses below (for symmetry; reduces code size) - // Really these are functionally "offset pointers" into the above arrays.... + symbols[0] = (unsigned char) + plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + 0]; + symbols[1] = (unsigned char) + plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + 1]; + symbols[2] = (unsigned char) + plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + 2]; + symbols[3] = (unsigned char) + plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + 3]; + + // These are used to "virtually" rename the uses below (for + // symmetry; reduces code size) + // Really these are functionally "offset pointers" into the above + // arrays.... unsigned char *metric0, *metric1; unsigned char *path0, *path1; // Operate on 4 symbols (2 bits) at a time - unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], survivor0[16], survivor1[16]; + unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], + decision1[16], survivor0[16], survivor1[16]; unsigned char metsv[16], metsvm[16]; unsigned char shift0[16], shift1[16]; unsigned char tmp0[16], tmp1[16]; unsigned char sym0v[16], sym1v[16]; unsigned short simd_epi16; - unsigned int first_symbol; - unsigned int second_symbol; + unsigned int first_symbol; + unsigned int second_symbol; HLS_FLAT(m0); HLS_FLAT(m1); @@ -540,238 +539,274 @@ void vitdodec::compute_kernel() HLS_FLAT(sym0v); HLS_FLAT(sym1v); - - //printf("Setting up for next two symbols\n"); + // printf("Setting up for next two symbols\n"); // Set up for the first two symbols (0 and 1) - metric0 = mm0; - path0 = pp0; - metric1 = mm1; - path1 = pp1; - first_symbol = 0; - second_symbol = first_symbol+1; + metric0 = mm0; + path0 = pp0; + metric1 = mm1; + path1 = pp1; + first_symbol = 0; + second_symbol = first_symbol + 1; for (int j = 0; j < 16; j++) { sym0v[j] = symbols[first_symbol]; sym1v[j] = symbols[second_symbol]; - //sym0v[j] = (unsigned char)plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + first_symbol]; - //sym1v[j] = (unsigned char)plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + second_symbol]; + // sym0v[j] = (unsigned char)plm_in_ping[((idx_depd_data + + // in_count) & 0xfffffffc) + first_symbol]; sym1v[j] = (unsigned + // char)plm_in_ping[((idx_depd_data + in_count) & 0xfffffffc) + + // second_symbol]; } for (int s = 0; s < 2; s++) { // iterate across the 2 symbol groups - // This is the basic viterbi butterfly for 2 symbols (we need therefore 2 passes for 4 total symbols) - //printf("for s = %u :\n", s); + // This is the basic viterbi butterfly for 2 symbols (we need + // therefore 2 passes for 4 total symbols) + // printf("for s = %u :\n", s); for (int i = 0; i < 2; i++) { - //printf(" for i = %u :\n", i); + // printf(" for i = %u :\n", i); if (symbols[first_symbol] == 2) { for (int j = 0; j < 16; j++) { - //metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; - //metsvm[j] = d_brtab27[1][(i*16) + j] ^ sym1v[j]; - metsvm[j] = (unsigned char)plm_in_ping[idx_brtab27_1 + (i*16) + j] ^ sym1v[j]; + // metsvm[j] = d_branchtab27_generic[1].c[(i*16) + + // j] ^ sym1v[j]; metsvm[j] = d_brtab27[1][(i*16) + + // j] ^ sym1v[j]; + metsvm[j] = + (unsigned char) + plm_in_ping[idx_brtab27_1 + (i * 16) + j] ^ + sym1v[j]; metsv[j] = 1 - metsvm[j]; } } else if (symbols[second_symbol] == 2) { for (int j = 0; j < 16; j++) { - //metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; - //metsvm[j] = d_brtab27[0][(i*16) + j] ^ sym0v[j]; - //metsvm[j] = d_brtab27_0[(i*16) + j] ^ sym0v[j]; - metsvm[j] = (unsigned char)plm_in_ping[idx_brtab27_0 + (i*16) + j] ^ sym0v[j]; + // metsvm[j] = d_branchtab27_generic[0].c[(i*16) + + // j] ^ sym0v[j]; metsvm[j] = d_brtab27[0][(i*16) + + // j] ^ sym0v[j]; metsvm[j] = d_brtab27_0[(i*16) + j] + // ^ sym0v[j]; + metsvm[j] = + (unsigned char) + plm_in_ping[idx_brtab27_0 + (i * 16) + j] ^ + sym0v[j]; metsv[j] = 1 - metsvm[j]; } } else { for (int j = 0; j < 16; j++) { - //metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); - //metsvm[j] = (d_brtab27[0][(i*16) + j] ^ sym0v[j]) + (d_brtab27[1][(i*16) + j] ^ sym1v[j]); - metsvm[j] = ((unsigned char)plm_in_ping[idx_brtab27_0 + (i*16) + j] ^ sym0v[j]) - + ((unsigned char)plm_in_ping[idx_brtab27_1 + (i*16) + j] ^ sym1v[j]); + // metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + + // j] ^ sym0v[j]) + + // (d_branchtab27_generic[1].c[(i*16) + j] ^ + // sym1v[j]); metsvm[j] = (d_brtab27[0][(i*16) + j] ^ + // sym0v[j]) + (d_brtab27[1][(i*16) + j] ^ sym1v[j]); + metsvm[j] = + ((unsigned char) + plm_in_ping[idx_brtab27_0 + (i * 16) + j] ^ + sym0v[j]) + + ((unsigned char) + plm_in_ping[idx_brtab27_1 + (i * 16) + j] ^ + sym1v[j]); metsv[j] = 2 - metsvm[j]; } } for (int j = 0; j < 16; j++) { - m0[j] = metric0[(i*16) + j] + metsv[j]; - m1[j] = metric0[((i+2)*16) + j] + metsvm[j]; - m2[j] = metric0[(i*16) + j] + metsvm[j]; - m3[j] = metric0[((i+2)*16) + j] + metsv[j]; + m0[j] = metric0[(i * 16) + j] + metsv[j]; + m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j]; + m2[j] = metric0[(i * 16) + j] + metsvm[j]; + m3[j] = metric0[((i + 2) * 16) + j] + metsv[j]; } for (int j = 0; j < 16; j++) { decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; - survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); - survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); + survivor0[j] = + (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); + survivor1[j] = + (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); } for (int j = 0; j < 16; j += 2) { - simd_epi16 = path0[(i*16) + j]; - simd_epi16 |= path0[(i*16) + (j+1)] << 8; + simd_epi16 = path0[(i * 16) + j]; + simd_epi16 |= path0[(i * 16) + (j + 1)] << 8; simd_epi16 <<= 1; - shift0[j] = simd_epi16; - shift0[j+1] = simd_epi16 >> 8; + shift0[j] = simd_epi16; + shift0[j + 1] = simd_epi16 >> 8; - simd_epi16 = path0[((i+2)*16) + j]; - simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8; + simd_epi16 = path0[((i + 2) * 16) + j]; + simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8; simd_epi16 <<= 1; - shift1[j] = simd_epi16; - shift1[j+1] = simd_epi16 >> 8; + shift1[j] = simd_epi16; + shift1[j + 1] = simd_epi16 >> 8; } for (int j = 0; j < 16; j++) { shift1[j] = shift1[j] + 1; } for (int j = 0, k = 0; j < 16; j += 2, k++) { - metric1[(2*i*16) + j] = survivor0[k]; - metric1[(2*i*16) + (j+1)] = survivor1[k]; + metric1[(2 * i * 16) + j] = survivor0[k]; + metric1[(2 * i * 16) + (j + 1)] = survivor1[k]; } for (int j = 0; j < 16; j++) { - tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); + tmp0[j] = (decision0[j] & shift0[j]) | + ((~decision0[j]) & shift1[j]); } for (int j = 0, k = 8; j < 16; j += 2, k++) { - metric1[((2*i+1)*16) + j] = survivor0[k]; - metric1[((2*i+1)*16) + (j+1)] = survivor1[k]; + metric1[((2 * i + 1) * 16) + j] = survivor0[k]; + metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k]; } for (int j = 0; j < 16; j++) { - tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); + tmp1[j] = (decision1[j] & shift0[j]) | + ((~decision1[j]) & shift1[j]); } for (int j = 0, k = 0; j < 16; j += 2, k++) { - path1[(2*i*16) + j] = tmp0[k]; - path1[(2*i*16) + (j+1)] = tmp1[k]; + path1[(2 * i * 16) + j] = tmp0[k]; + path1[(2 * i * 16) + (j + 1)] = tmp1[k]; } for (int j = 0, k = 8; j < 16; j += 2, k++) { - path1[((2*i+1)*16) + j] = tmp0[k]; - path1[((2*i+1)*16) + (j+1)] = tmp1[k]; + path1[((2 * i + 1) * 16) + j] = tmp0[k]; + path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k]; } } // for (i = 0 to 2) // Set up for the second two symbols (2 and 3) - metric0 = mm1; - path0 = pp1; - metric1 = mm0; - path1 = pp0; - first_symbol = 2; - second_symbol = first_symbol+1; + metric0 = mm1; + path0 = pp1; + metric1 = mm0; + path1 = pp0; + first_symbol = 2; + second_symbol = first_symbol + 1; for (int j = 0; j < 16; j++) { sym0v[j] = symbols[first_symbol]; sym1v[j] = symbols[second_symbol]; } - } // for (s = 0 to 2) - } // END of call to viterbi_butterfly2_generic - viterbi_butterfly_calls++; // Do not increment until after the comparison code. + } // for (s = 0 to 2) + } // END of call to viterbi_butterfly2_generic + viterbi_butterfly_calls++; // Do not increment until after the + // comparison code. - //printf("in_count = %u && (in_count % 16) == %u\n", in_count, (in_count%16)); + // printf("in_count = %u && (in_count % 16) == %u\n", in_count, + // (in_count%16)); if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 unsigned char c; // Find current best path - // - // INPUTS/OUTPUTS: + // + // INPUTS/OUTPUTS: // RET_VAL : (ignored) // mm0 : INPUT/OUTPUT : Array [ 64 ] // mm1 : INPUT/OUTPUT : Array [ 64 ] - // pp0 : INPUT/OUTPUT : Array [ 64 ] + // pp0 : INPUT/OUTPUT : Array [ 64 ] // pp1 : INPUT/OUTPUT : Array [ 64 ] - // ntraceback : INPUT : int (I think effectively const for given run type; here 5 I think) - // outbuf : OUTPUT : 1 byte - // l_store_pos : GLOBAL IN/OUT : int (position in circular traceback buffer?) - + // ntraceback : INPUT : int (I think effectively const + // for given run type; here 5 I think) outbuf : OUTPUT : 1 + // byte l_store_pos : GLOBAL IN/OUT : int (position in circular + // traceback buffer?) - // l_mmresult : GLOBAL OUTPUT : Array [ 64 bytes ] + // l_mmresult : GLOBAL OUTPUT : Array [ 64 bytes ] // l_ppresult : GLOBAL OUTPUT : Array [ntraceback][ 64 bytes ] - // CALL : viterbi_get_output_generic(l_metric0_generic, l_path0_generic, ntraceback, &c); - // unsigned char viterbi_get_output_generic(unsigned char *mm0, unsigned char *pp0, int ntraceback, unsigned char *outbuf) + // CALL : viterbi_get_output_generic(l_metric0_generic, + // l_path0_generic, ntraceback, &c); unsigned char + // viterbi_get_output_generic(unsigned char *mm0, unsigned char + // *pp0, int ntraceback, unsigned char *outbuf) { - unsigned char *mm0 = l_metric0_generic; - unsigned char *pp0 = l_path0_generic; - //int ntraceback = ntraceback; + unsigned char *mm0 = l_metric0_generic; + unsigned char *pp0 = l_path0_generic; + // int ntraceback = ntraceback; unsigned char *outbuf = &c; int i; int bestmetric, minmetric; int beststate = 0; - int pos = 0; + int pos = 0; int j; - //printf("Finding current best-path\n"); - //printf(" Setting l_store_pos = (%u + 1) MOD %u\n", l_store_pos, ntraceback); + // printf("Finding current best-path\n"); + // printf(" Setting l_store_pos = (%u + 1) MOD %u\n", + // l_store_pos, ntraceback); // circular buffer with the last ntraceback paths l_store_pos = (l_store_pos + 1) % ntraceback; - //printf("Setting up l_mmresult and l_ppresult\n"); + // printf("Setting up l_mmresult and l_ppresult\n"); for (i = 0; i < 4; i++) { for (j = 0; j < 16; j++) { - l_mmresult[(i*16) + j] = mm0[(i*16) + j]; - l_ppresult[l_store_pos][(i*16) + j] = pp0[(i*16) + j]; + l_mmresult[(i * 16) + j] = mm0[(i * 16) + j]; + l_ppresult[l_store_pos][(i * 16) + j] = + pp0[(i * 16) + j]; } } - //printf("Setting up best and min metric\n"); + // printf("Setting up best and min metric\n"); // Find out the best final state bestmetric = l_mmresult[beststate]; - minmetric = l_mmresult[beststate]; - //printf(" bestmetric = %u minmetric = %u\n", bestmetric, minmetric); + minmetric = l_mmresult[beststate]; + // printf(" bestmetric = %u minmetric = %u\n", bestmetric, + // minmetric); for (i = 1; i < 64; i++) { if (l_mmresult[i] > bestmetric) { bestmetric = l_mmresult[i]; - beststate = i; + beststate = i; } if (l_mmresult[i] < minmetric) { minmetric = l_mmresult[i]; } } - //printf(" final bestmetric = %u minmetric = %u\n", bestmetric, minmetric); + // printf(" final bestmetric = %u minmetric = %u\n", + // bestmetric, minmetric); // Trace back for (i = 0, pos = l_store_pos; i < (ntraceback - 1); i++) { // Obtain the state from the output bits // by clocking in the output bits in reverse order. // The state has only 6 bits beststate = l_ppresult[pos][beststate] >> 2; - pos = (pos - 1 + ntraceback) % ntraceback; + pos = (pos - 1 + ntraceback) % ntraceback; } - //printf(" did traceback stuff... set outbuf at %p\n", outbuf); + // printf(" did traceback stuff... set outbuf at %p\n", + // outbuf); // Store output byte *outbuf = l_ppresult[pos][beststate]; - //printf(" set outbuf %p to %u\n", outbuf, *outbuf); + // printf(" set outbuf %p to %u\n", outbuf, *outbuf); for (i = 0; i < 4; i++) { for (j = 0; j < 16; j++) { - pp0[(i*16) + j] = 0; - mm0[(i*16) + j] = mm0[(i*16) + j] - minmetric; + pp0[(i * 16) + j] = 0; + mm0[(i * 16) + j] = mm0[(i * 16) + j] - minmetric; } } - //return bestmetric; + // return bestmetric; } - //printf(" out_count = %u vs %u = ntraceback\n", out_count, ntraceback); + // printf(" out_count = %u vs %u = ntraceback\n", out_count, + // ntraceback); if (out_count >= ntraceback) { - for (int i= 0; i < 8; i++) { - //l_decoded[(out_count - ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; - plm_out_ping[(out_count - ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; + for (int i = 0; i < 8; i++) { + // l_decoded[(out_count - ntraceback) * 8 + i] = (c >> (7 - + // i)) & 0x1; + plm_out_ping[(out_count - ntraceback) * 8 + i] = + (c >> (7 - i)) & 0x1; // if (n_decoded < 16) { - // printf("plm_out_ping[%2u] written as %u = %u\n", (out_count - ntraceback) * 8 + i, (c >> (7 - i)) & 0x1, (unsigned char)plm_out_ping[(out_count - ntraceback) * 8 + i]); + // printf("plm_out_ping[%2u] written as %u = %u\n", + // (out_count - ntraceback) * 8 + i, (c >> (7 - i)) & + // 0x1, (unsigned char)plm_out_ping[(out_count - + // ntraceback) * 8 + i]); // } n_decoded++; } } out_count++; } // if (in_count >0) && (in_count % 16 == 8) - } // if (in_count % 4 == 0) + } // if (in_count % 4 == 0) in_count++; } - } -#if(0) +#if (0) { printf("\n memory out = "); int limi = 0; - //for (int li = 0; li < 32; li++) { + // for (int li = 0; li < 32; li++) { for (int li = 0; li < out_length; li++) { std::cout << plm_out_ping[limi++]; if ((li % 8) == 7) { std::cout << " "; } @@ -789,9 +824,9 @@ void vitdodec::compute_kernel() // // plm_out_pong[i] = plm_in_pong[i]; // } - //out_rem -= PLM_OUT_WORD; + // out_rem -= PLM_OUT_WORD; this->compute_store_handshake(); - //ping = !ping; + // ping = !ping; } } diff --git a/accelerators/stratus_hls/vitdodec_stratus/hw/tb/do_decoding.c b/accelerators/stratus_hls/vitdodec_stratus/hw/tb/do_decoding.c index 95c8019726..0df7c54d3c 100644 --- a/accelerators/stratus_hls/vitdodec_stratus/hw/tb/do_decoding.c +++ b/accelerators/stratus_hls/vitdodec_stratus/hw/tb/do_decoding.c @@ -30,12 +30,11 @@ */ #include - // GLOBAL VARIABLES -#define MAX_PAYLOAD_SIZE 1500 -#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC -#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) -#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288) +#define MAX_PAYLOAD_SIZE 1500 +#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC +#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) +#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288) /* This is the main "do_decoding" function; takes the necessary inputs * from the decode call (above) and does the decoding, outputing the decoded result. @@ -46,8 +45,9 @@ // in_n_data_bits : INPUT : X : int = 4 bytes (REGISTER) // d_branchtab27_generic : INPUT : 0 : uint8_t[2][32] = 64 bytes // in_depuncture_pattern : INPUT : 64 : uint8_t[8] (max is 6 bytes + 2 padding bytes) -// depd_data : INPUT : 72 : uint8_t[MAX_ENCODED_BITS == 24780] (depunctured data) -// : OUTPUT : 24852 : uint8_t[MAX_ENCODED_BITS * 3 / 4 == 18585 ] : The decoded data stream +// depd_data : INPUT : 72 : uint8_t[MAX_ENCODED_BITS == 24780] (depunctured +// data) : OUTPUT : 24852 : uint8_t[MAX_ENCODED_BITS * 3 / 4 == 18585 ] : +// The decoded data stream /* THESE ARE JUST USED LOCALLY IN THIS FUNCTION NOW */ /* BUT they must reset to zero on each invocation */ @@ -57,373 +57,372 @@ // d_path0_generic : INPUT : uint8_t[64] // d_path1_generic : INPUT : uint8_t[64] // d_store_pos : INPUT : int (position in circular traceback buffer?) -// d_mmresult : OUTPUT : uint8_t[64] +// d_mmresult : OUTPUT : uint8_t[64] // d_ppresult : OUTPUT : uint8_t[ntraceback_MAX][ 64 bytes ] - -void do_decoding(int in_n_data_bits, int in_cbps, int in_ntraceback, unsigned char *inMemory, unsigned char *l_decoded) +void do_decoding(int in_n_data_bits, int in_cbps, int in_ntraceback, unsigned char *inMemory, + unsigned char *l_decoded) { - int in_count = 0; - int out_count = 0; - int n_decoded = 0; - - unsigned char* d_brtab27[2] = { &(inMemory[ 0]), - &(inMemory[ 32]) }; - unsigned char* in_depuncture_pattern = &(inMemory[ 64]); - uint8_t* depd_data = &(inMemory[ 72]); - - VERBOSE({ - printf("\nVBS: in_cbps = %u\n", in_cbps); - printf("VBS: in_ntraceback = %u\n", in_ntraceback); - printf("VBS: in_n_data_bits = %u\n", in_n_data_bits); - for (int ti = 0; ti < 2; ti ++) { - printf("d_brtab[%u] = [ ", ti); - for (int tj = 0; tj < 32; tj++) { - if (tj > 0) { printf(", "); } - printf("%u", d_brtab27[ti][tj]); - } - printf(" ]\n"); - } - printf("VBS: in_depuncture_pattern = [ "); - for (int ti = 0; ti < 6; ti ++) { - if (ti > 0) { printf(", "); } - printf("%02x", in_depuncture_pattern[ti]); - } - printf("]\n"); - printf("\nVBS: depd_data : %p\n", depd_data); - { - int per_row = 0; - printf("%p : ", &depd_data[0]); - for (int ti = 0; ti < MAX_ENCODED_BITS; ti++) { - per_row++; - if ((per_row % 8) == 0) { - printf(" "); - } - printf("%u", depd_data[ti]); - if (per_row == 39) { - printf("\n"); - printf("%p : ", &depd_data[ti]); - per_row = 0; - } - } - printf("\n"); - } - printf("\n\n"); + int in_count = 0; + int out_count = 0; + int n_decoded = 0; + + unsigned char *d_brtab27[2] = {&(inMemory[0]), &(inMemory[32])}; + unsigned char *in_depuncture_pattern = &(inMemory[64]); + uint8_t *depd_data = &(inMemory[72]); + + VERBOSE({ + printf("\nVBS: in_cbps = %u\n", in_cbps); + printf("VBS: in_ntraceback = %u\n", in_ntraceback); + printf("VBS: in_n_data_bits = %u\n", in_n_data_bits); + for (int ti = 0; ti < 2; ti++) { + printf("d_brtab[%u] = [ ", ti); + for (int tj = 0; tj < 32; tj++) { + if (tj > 0) { printf(", "); } + printf("%u", d_brtab27[ti][tj]); + } + printf(" ]\n"); + } + printf("VBS: in_depuncture_pattern = [ "); + for (int ti = 0; ti < 6; ti++) { + if (ti > 0) { printf(", "); } + printf("%02x", in_depuncture_pattern[ti]); + } + printf("]\n"); + printf("\nVBS: depd_data : %p\n", depd_data); + { + int per_row = 0; + printf("%p : ", &depd_data[0]); + for (int ti = 0; ti < MAX_ENCODED_BITS; ti++) { + per_row++; + if ((per_row % 8) == 0) { printf(" "); } + printf("%u", depd_data[ti]); + if (per_row == 39) { + printf("\n"); + printf("%p : ", &depd_data[ti]); + per_row = 0; + } + } + printf("\n"); + } + printf("\n\n"); }); - - uint8_t l_metric0_generic[64]; - uint8_t l_metric1_generic[64]; - uint8_t l_path0_generic[64]; - uint8_t l_path1_generic[64]; - uint8_t l_mmresult[64]; - uint8_t l_ppresult[TRACEBACK_MAX][64]; - int l_store_pos = 0; - - // This is the "reset" portion: - // Do this before the real operation so local memories are "cleared to zero" - // d_store_pos = 0; - for (int i = 0; i < 64; i++) { - l_metric0_generic[i] = 0; - l_path0_generic[i] = 0; - l_metric1_generic[i] = 0; - l_path1_generic[i] = 0; - l_mmresult[i] = 0; - for (int j = 0; j < TRACEBACK_MAX; j++) { - l_ppresult[j][i] = 0; - } - } - - int viterbi_butterfly_calls = 0; - //while(n_decoded < d_frame->n_data_bits) { - while(n_decoded < in_n_data_bits) { - //printf("n_decoded = %d vs %d = in_n_data_bits\n", n_decoded, in_n_data_bits); - if ((in_count % 4) == 0) { //0 or 3 - //printf(" Viterbi_Butterfly Call,%d,n_decoded,%d,n_data_bits,%d,in_count,%d,%d\n", viterbi_butterfly_calls, n_decoded, in_n_data_bits, in_count, (in_count & 0xfffffffc)); - - //CALL viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc], l_metric0_generic, l_metric1_generic, l_path0_generic, l_path1_generic); - /* The basic Viterbi decoder operation, called a "butterfly" - * operation because of the way it looks on a trellis diagram. Each - * butterfly involves an Add-Compare-Select (ACS) operation on the two nodes - * where the 0 and 1 paths from the current node merge at the next step of - * the trellis. - * - * The code polynomials are assumed to have 1's on both ends. Given a - * function encode_state() that returns the two symbols for a given - * encoder state in the low two bits, such a code will have the following - * identities for even 'n' < 64: - * - * encode_state(n) = encode_state(n+65) - * encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n)) - * - * Any convolutional code you would actually want to use will have - * these properties, so these assumptions aren't too limiting. - * - * Doing this as a macro lets the compiler evaluate at compile time the - * many expressions that depend on the loop index and encoder state and - * emit them as immediate arguments. - * This makes an enormous difference on register-starved machines such - * as the Intel x86 family where evaluating these expressions at runtime - * would spill over into memory. - */ - - // INPUTS/OUTPUTS: All are 64-entry (bytes) arrays randomly accessed. - // symbols : INPUT : Array [ 4 bytes ] - // mm0 : INPUT/OUTPUT : Array [ 64 bytes ] - // mm1 : INPUT/OUTPUT : Array [ 64 bytes ] - // pp0 : INPUT/OUTPUT : Array [ 64 bytes ] - // pp1 : INPUT/OUTPUT : Array [ 64 bytes ] - // d_branchtab27_generic[1].c[] : INPUT : Array [2].c[32] {GLOBAL} - // - - /* void viterbi_butterfly2_generic(unsigned char *symbols, */ - /* unsigned char *mm0, unsigned char *mm1, */ - /* unsigned char *pp0, unsigned char *pp1) */ - { - unsigned char *mm0 = l_metric0_generic; - unsigned char *mm1 = l_metric1_generic; - unsigned char *pp0 = l_path0_generic; - unsigned char *pp1 = l_path1_generic; - unsigned char *symbols = &depd_data[in_count & 0xfffffffc]; - - // These are used to "virtually" rename the uses below (for symmetry; reduces code size) - // Really these are functionally "offset pointers" into the above arrays.... - unsigned char *metric0, *metric1; - unsigned char *path0, *path1; - - // Operate on 4 symbols (2 bits) at a time - - unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], survivor0[16], survivor1[16]; - unsigned char metsv[16], metsvm[16]; - unsigned char shift0[16], shift1[16]; - unsigned char tmp0[16], tmp1[16]; - unsigned char sym0v[16], sym1v[16]; - unsigned short simd_epi16; - unsigned int first_symbol; - unsigned int second_symbol; - - // Set up for the first two symbols (0 and 1) - metric0 = mm0; - path0 = pp0; - metric1 = mm1; - path1 = pp1; - first_symbol = 0; - second_symbol = first_symbol+1; - for (int j = 0; j < 16; j++) { - sym0v[j] = symbols[first_symbol]; - sym1v[j] = symbols[second_symbol]; - } - - for (int s = 0; s < 2; s++) { // iterate across the 2 symbol groups - // This is the basic viterbi butterfly for 2 symbols (we need therefore 2 passes for 4 total symbols) - for (int i = 0; i < 2; i++) { - if (symbols[first_symbol] == 2) { - for (int j = 0; j < 16; j++) { - //metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; - metsvm[j] = d_brtab27[1][(i*16) + j] ^ sym1v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else if (symbols[second_symbol] == 2) { - for (int j = 0; j < 16; j++) { - //metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; - metsvm[j] = d_brtab27[0][(i*16) + j] ^ sym0v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else { - for (int j = 0; j < 16; j++) { - //metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); - metsvm[j] = (d_brtab27[0][(i*16) + j] ^ sym0v[j]) + (d_brtab27[1][(i*16) + j] ^ sym1v[j]); - metsv[j] = 2 - metsvm[j]; - } - } - - for (int j = 0; j < 16; j++) { - m0[j] = metric0[(i*16) + j] + metsv[j]; - m1[j] = metric0[((i+2)*16) + j] + metsvm[j]; - m2[j] = metric0[(i*16) + j] + metsvm[j]; - m3[j] = metric0[((i+2)*16) + j] + metsv[j]; - } - - for (int j = 0; j < 16; j++) { - decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; - decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; - survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); - survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); - } - - for (int j = 0; j < 16; j += 2) { - simd_epi16 = path0[(i*16) + j]; - simd_epi16 |= path0[(i*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift0[j] = simd_epi16; - shift0[j+1] = simd_epi16 >> 8; - - simd_epi16 = path0[((i+2)*16) + j]; - simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift1[j] = simd_epi16; - shift1[j+1] = simd_epi16 >> 8; - } - for (int j = 0; j < 16; j++) { - shift1[j] = shift1[j] + 1; - } - - for (int j = 0, k = 0; j < 16; j += 2, k++) { - metric1[(2*i*16) + j] = survivor0[k]; - metric1[(2*i*16) + (j+1)] = survivor1[k]; - } - for (int j = 0; j < 16; j++) { - tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); - } - - for (int j = 0, k = 8; j < 16; j += 2, k++) { - metric1[((2*i+1)*16) + j] = survivor0[k]; - metric1[((2*i+1)*16) + (j+1)] = survivor1[k]; - } - for (int j = 0; j < 16; j++) { - tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); - } - - for (int j = 0, k = 0; j < 16; j += 2, k++) { - path1[(2*i*16) + j] = tmp0[k]; - path1[(2*i*16) + (j+1)] = tmp1[k]; - } - for (int j = 0, k = 8; j < 16; j += 2, k++) { - path1[((2*i+1)*16) + j] = tmp0[k]; - path1[((2*i+1)*16) + (j+1)] = tmp1[k]; - } - } - - // Set up for the second two symbols (2 and 3) - metric0 = mm1; - path0 = pp1; - metric1 = mm0; - path1 = pp0; - first_symbol = 2; - second_symbol = first_symbol+1; - for (int j = 0; j < 16; j++) { - sym0v[j] = symbols[first_symbol]; - sym1v[j] = symbols[second_symbol]; - } - } - } // END of call to viterbi_butterfly2_generic - viterbi_butterfly_calls++; // Do not increment until after the comparison code. - - if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 - unsigned char c; - // Find current best path - // - // INPUTS/OUTPUTS: - // RET_VAL : (ignored) - // mm0 : INPUT/OUTPUT : Array [ 64 ] - // mm1 : INPUT/OUTPUT : Array [ 64 ] - // pp0 : INPUT/OUTPUT : Array [ 64 ] - // pp1 : INPUT/OUTPUT : Array [ 64 ] - // ntraceback : INPUT : int (I think effectively const for given run type; here 5 I think) - // outbuf : OUTPUT : 1 byte - // l_store_pos : GLOBAL IN/OUT : int (position in circular traceback buffer?) - - - // l_mmresult : GLOBAL OUTPUT : Array [ 64 bytes ] - // l_ppresult : GLOBAL OUTPUT : Array [ntraceback][ 64 bytes ] - - // CALL : viterbi_get_output_generic(l_metric0_generic, l_path0_generic, in_ntraceback, &c); - // unsigned char viterbi_get_output_generic(unsigned char *mm0, unsigned char *pp0, int ntraceback, unsigned char *outbuf) - { - unsigned char *mm0 = l_metric0_generic; - unsigned char *pp0 = l_path0_generic; - int ntraceback = in_ntraceback; - unsigned char *outbuf = &c; - - int i; - int bestmetric, minmetric; - int beststate = 0; - int pos = 0; - int j; - - // circular buffer with the last ntraceback paths - l_store_pos = (l_store_pos + 1) % ntraceback; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 16; j++) { - l_mmresult[(i*16) + j] = mm0[(i*16) + j]; - l_ppresult[l_store_pos][(i*16) + j] = pp0[(i*16) + j]; - } - } - - // Find out the best final state - bestmetric = l_mmresult[beststate]; - minmetric = l_mmresult[beststate]; - - for (i = 1; i < 64; i++) { - if (l_mmresult[i] > bestmetric) { - bestmetric = l_mmresult[i]; - beststate = i; - } - if (l_mmresult[i] < minmetric) { - minmetric = l_mmresult[i]; - } - } - - // Trace back - for (i = 0, pos = l_store_pos; i < (ntraceback - 1); i++) { - // Obtain the state from the output bits - // by clocking in the output bits in reverse order. - // The state has only 6 bits - beststate = l_ppresult[pos][beststate] >> 2; - pos = (pos - 1 + ntraceback) % ntraceback; - } - - // Store output byte - *outbuf = l_ppresult[pos][beststate]; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 16; j++) { - pp0[(i*16) + j] = 0; - mm0[(i*16) + j] = mm0[(i*16) + j] - minmetric; - } - } - - //return bestmetric; - } - - //std::cout << "OUTPUT: " << (unsigned int)c << std::endl; - if (out_count >= in_ntraceback) { - for (int i= 0; i < 8; i++) { - l_decoded[(out_count - in_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; - /* if (n_decoded < 16) { */ - /* printf("l_decoded[ %u ] written as %u\n", (out_count - in_ntraceback) * 8 + i, l_decoded[(out_count - in_ntraceback) * 8 + i]); */ - /* } */ - n_decoded++; - } - } - out_count++; - } + uint8_t l_metric0_generic[64]; + uint8_t l_metric1_generic[64]; + uint8_t l_path0_generic[64]; + uint8_t l_path1_generic[64]; + uint8_t l_mmresult[64]; + uint8_t l_ppresult[TRACEBACK_MAX][64]; + int l_store_pos = 0; + + // This is the "reset" portion: + // Do this before the real operation so local memories are "cleared to zero" + // d_store_pos = 0; + for (int i = 0; i < 64; i++) { + l_metric0_generic[i] = 0; + l_path0_generic[i] = 0; + l_metric1_generic[i] = 0; + l_path1_generic[i] = 0; + l_mmresult[i] = 0; + for (int j = 0; j < TRACEBACK_MAX; j++) { + l_ppresult[j][i] = 0; + } } - in_count++; - } - - VERBOSE({ - printf("\nVBS: Final l_decoded : %p\n", l_decoded); - int per_row = 0; - printf("%p : ", &l_decoded[0]); - for (int ti = 0; ti < (MAX_ENCODED_BITS * 3 / 4); ti ++) { - per_row++; - if ((per_row % 8) == 0) { - printf(" "); - } - printf("%u", l_decoded[ti]); - if (per_row == 39) { - printf("\n"); - printf("%p : ", &l_decoded[ti]); - per_row = 0; - } + + int viterbi_butterfly_calls = 0; + // while(n_decoded < d_frame->n_data_bits) { + while (n_decoded < in_n_data_bits) { + // printf("n_decoded = %d vs %d = in_n_data_bits\n", n_decoded, in_n_data_bits); + if ((in_count % 4) == 0) { // 0 or 3 + // printf(" Viterbi_Butterfly Call,%d,n_decoded,%d,n_data_bits,%d,in_count,%d,%d\n", + // viterbi_butterfly_calls, n_decoded, in_n_data_bits, in_count, (in_count & + // 0xfffffffc)); + + // CALL viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc], + // l_metric0_generic, l_metric1_generic, l_path0_generic, l_path1_generic); + /* The basic Viterbi decoder operation, called a "butterfly" + * operation because of the way it looks on a trellis diagram. Each + * butterfly involves an Add-Compare-Select (ACS) operation on the two nodes + * where the 0 and 1 paths from the current node merge at the next step of + * the trellis. + * + * The code polynomials are assumed to have 1's on both ends. Given a + * function encode_state() that returns the two symbols for a given + * encoder state in the low two bits, such a code will have the following + * identities for even 'n' < 64: + * + * encode_state(n) = encode_state(n+65) + * encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n)) + * + * Any convolutional code you would actually want to use will have + * these properties, so these assumptions aren't too limiting. + * + * Doing this as a macro lets the compiler evaluate at compile time the + * many expressions that depend on the loop index and encoder state and + * emit them as immediate arguments. + * This makes an enormous difference on register-starved machines such + * as the Intel x86 family where evaluating these expressions at runtime + * would spill over into memory. + */ + + // INPUTS/OUTPUTS: All are 64-entry (bytes) arrays randomly accessed. + // symbols : INPUT : Array [ 4 bytes ] + // mm0 : INPUT/OUTPUT : Array [ 64 bytes ] + // mm1 : INPUT/OUTPUT : Array [ 64 bytes ] + // pp0 : INPUT/OUTPUT : Array [ 64 bytes ] + // pp1 : INPUT/OUTPUT : Array [ 64 bytes ] + // d_branchtab27_generic[1].c[] : INPUT : Array [2].c[32] {GLOBAL} + // + + /* void viterbi_butterfly2_generic(unsigned char *symbols, */ + /* unsigned char *mm0, unsigned char *mm1, */ + /* unsigned char *pp0, unsigned char *pp1) */ + { + unsigned char *mm0 = l_metric0_generic; + unsigned char *mm1 = l_metric1_generic; + unsigned char *pp0 = l_path0_generic; + unsigned char *pp1 = l_path1_generic; + unsigned char *symbols = &depd_data[in_count & 0xfffffffc]; + + // These are used to "virtually" rename the uses below (for symmetry; reduces code + // size) + // Really these are functionally "offset pointers" into the above arrays.... + unsigned char *metric0, *metric1; + unsigned char *path0, *path1; + + // Operate on 4 symbols (2 bits) at a time + + unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], + survivor0[16], survivor1[16]; + unsigned char metsv[16], metsvm[16]; + unsigned char shift0[16], shift1[16]; + unsigned char tmp0[16], tmp1[16]; + unsigned char sym0v[16], sym1v[16]; + unsigned short simd_epi16; + unsigned int first_symbol; + unsigned int second_symbol; + + // Set up for the first two symbols (0 and 1) + metric0 = mm0; + path0 = pp0; + metric1 = mm1; + path1 = pp1; + first_symbol = 0; + second_symbol = first_symbol + 1; + for (int j = 0; j < 16; j++) { + sym0v[j] = symbols[first_symbol]; + sym1v[j] = symbols[second_symbol]; + } + + for (int s = 0; s < 2; s++) { // iterate across the 2 symbol groups + // This is the basic viterbi butterfly for 2 symbols (we need therefore 2 passes + // for 4 total symbols) + for (int i = 0; i < 2; i++) { + if (symbols[first_symbol] == 2) { + for (int j = 0; j < 16; j++) { + // metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; + metsvm[j] = d_brtab27[1][(i * 16) + j] ^ sym1v[j]; + metsv[j] = 1 - metsvm[j]; + } + } + else if (symbols[second_symbol] == 2) { + for (int j = 0; j < 16; j++) { + // metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; + metsvm[j] = d_brtab27[0][(i * 16) + j] ^ sym0v[j]; + metsv[j] = 1 - metsvm[j]; + } + } + else { + for (int j = 0; j < 16; j++) { + // metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + + // (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); + metsvm[j] = (d_brtab27[0][(i * 16) + j] ^ sym0v[j]) + + (d_brtab27[1][(i * 16) + j] ^ sym1v[j]); + metsv[j] = 2 - metsvm[j]; + } + } + + for (int j = 0; j < 16; j++) { + m0[j] = metric0[(i * 16) + j] + metsv[j]; + m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j]; + m2[j] = metric0[(i * 16) + j] + metsvm[j]; + m3[j] = metric0[((i + 2) * 16) + j] + metsv[j]; + } + + for (int j = 0; j < 16; j++) { + decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; + decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; + survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); + survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); + } + + for (int j = 0; j < 16; j += 2) { + simd_epi16 = path0[(i * 16) + j]; + simd_epi16 |= path0[(i * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift0[j] = simd_epi16; + shift0[j + 1] = simd_epi16 >> 8; + + simd_epi16 = path0[((i + 2) * 16) + j]; + simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift1[j] = simd_epi16; + shift1[j + 1] = simd_epi16 >> 8; + } + for (int j = 0; j < 16; j++) { + shift1[j] = shift1[j] + 1; + } + + for (int j = 0, k = 0; j < 16; j += 2, k++) { + metric1[(2 * i * 16) + j] = survivor0[k]; + metric1[(2 * i * 16) + (j + 1)] = survivor1[k]; + } + for (int j = 0; j < 16; j++) { + tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); + } + + for (int j = 0, k = 8; j < 16; j += 2, k++) { + metric1[((2 * i + 1) * 16) + j] = survivor0[k]; + metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k]; + } + for (int j = 0; j < 16; j++) { + tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); + } + + for (int j = 0, k = 0; j < 16; j += 2, k++) { + path1[(2 * i * 16) + j] = tmp0[k]; + path1[(2 * i * 16) + (j + 1)] = tmp1[k]; + } + for (int j = 0, k = 8; j < 16; j += 2, k++) { + path1[((2 * i + 1) * 16) + j] = tmp0[k]; + path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k]; + } + } + + // Set up for the second two symbols (2 and 3) + metric0 = mm1; + path0 = pp1; + metric1 = mm0; + path1 = pp0; + first_symbol = 2; + second_symbol = first_symbol + 1; + for (int j = 0; j < 16; j++) { + sym0v[j] = symbols[first_symbol]; + sym1v[j] = symbols[second_symbol]; + } + } + } // END of call to viterbi_butterfly2_generic + viterbi_butterfly_calls++; // Do not increment until after the comparison code. + + if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 + unsigned char c; + // Find current best path + // + // INPUTS/OUTPUTS: + // RET_VAL : (ignored) + // mm0 : INPUT/OUTPUT : Array [ 64 ] + // mm1 : INPUT/OUTPUT : Array [ 64 ] + // pp0 : INPUT/OUTPUT : Array [ 64 ] + // pp1 : INPUT/OUTPUT : Array [ 64 ] + // ntraceback : INPUT : int (I think effectively const for given run + // type; here 5 I think) outbuf : OUTPUT : 1 byte l_store_pos : + // GLOBAL IN/OUT : int (position in circular traceback buffer?) + + // l_mmresult : GLOBAL OUTPUT : Array [ 64 bytes ] + // l_ppresult : GLOBAL OUTPUT : Array [ntraceback][ 64 bytes ] + + // CALL : viterbi_get_output_generic(l_metric0_generic, l_path0_generic, + // in_ntraceback, &c); unsigned char viterbi_get_output_generic(unsigned char *mm0, + // unsigned char *pp0, int ntraceback, unsigned char *outbuf) + { + unsigned char *mm0 = l_metric0_generic; + unsigned char *pp0 = l_path0_generic; + int ntraceback = in_ntraceback; + unsigned char *outbuf = &c; + + int i; + int bestmetric, minmetric; + int beststate = 0; + int pos = 0; + int j; + + // circular buffer with the last ntraceback paths + l_store_pos = (l_store_pos + 1) % ntraceback; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 16; j++) { + l_mmresult[(i * 16) + j] = mm0[(i * 16) + j]; + l_ppresult[l_store_pos][(i * 16) + j] = pp0[(i * 16) + j]; + } + } + + // Find out the best final state + bestmetric = l_mmresult[beststate]; + minmetric = l_mmresult[beststate]; + + for (i = 1; i < 64; i++) { + if (l_mmresult[i] > bestmetric) { + bestmetric = l_mmresult[i]; + beststate = i; + } + if (l_mmresult[i] < minmetric) { minmetric = l_mmresult[i]; } + } + + // Trace back + for (i = 0, pos = l_store_pos; i < (ntraceback - 1); i++) { + // Obtain the state from the output bits + // by clocking in the output bits in reverse order. + // The state has only 6 bits + beststate = l_ppresult[pos][beststate] >> 2; + pos = (pos - 1 + ntraceback) % ntraceback; + } + + // Store output byte + *outbuf = l_ppresult[pos][beststate]; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 16; j++) { + pp0[(i * 16) + j] = 0; + mm0[(i * 16) + j] = mm0[(i * 16) + j] - minmetric; + } + } + + // return bestmetric; + } + + // std::cout << "OUTPUT: " << (unsigned int)c << std::endl; + if (out_count >= in_ntraceback) { + for (int i = 0; i < 8; i++) { + l_decoded[(out_count - in_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; + /* if (n_decoded < 16) { */ + /* printf("l_decoded[ %u ] written as %u\n", (out_count - in_ntraceback) * + * 8 + i, l_decoded[(out_count - in_ntraceback) * 8 + i]); */ + /* } */ + n_decoded++; + } + } + out_count++; + } + } + in_count++; } - printf("\n"); - printf("\n"); - }); + VERBOSE({ + printf("\nVBS: Final l_decoded : %p\n", l_decoded); + int per_row = 0; + printf("%p : ", &l_decoded[0]); + for (int ti = 0; ti < (MAX_ENCODED_BITS * 3 / 4); ti++) { + per_row++; + if ((per_row % 8) == 0) { printf(" "); } + printf("%u", l_decoded[ti]); + if (per_row == 39) { + printf("\n"); + printf("%p : ", &l_decoded[ti]); + per_row = 0; + } + } + printf("\n"); + printf("\n"); + }); } - diff --git a/accelerators/stratus_hls/vitdodec_stratus/hw/tb/sc_main.cpp b/accelerators/stratus_hls/vitdodec_stratus/hw/tb/sc_main.cpp index c465ccc433..cffde7e61b 100644 --- a/accelerators/stratus_hls/vitdodec_stratus/hw/tb/sc_main.cpp +++ b/accelerators/stratus_hls/vitdodec_stratus/hw/tb/sc_main.cpp @@ -5,44 +5,44 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; extern void esc_elaborate() { - // Creating the whole system - testbench = new system_t("testbench"); + // Creating the whole system + testbench = new system_t("testbench"); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); - esc_cleanup(); + esc_log_pass(); + esc_cleanup(); - return 0; + return 0; } diff --git a/accelerators/stratus_hls/vitdodec_stratus/sw/baremetal/do_decoding.c b/accelerators/stratus_hls/vitdodec_stratus/sw/baremetal/do_decoding.c index 4b2955d819..3df8de0165 100644 --- a/accelerators/stratus_hls/vitdodec_stratus/sw/baremetal/do_decoding.c +++ b/accelerators/stratus_hls/vitdodec_stratus/sw/baremetal/do_decoding.c @@ -34,14 +34,13 @@ typedef unsigned char uint8_t; #include "do_decoding.h" - // GLOBAL VARIABLES -#define TRACEBACK_MAX 11 +#define TRACEBACK_MAX 11 -#define MAX_PAYLOAD_SIZE 1500 -#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC -#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) -#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288) +#define MAX_PAYLOAD_SIZE 1500 +#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC +#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) +#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288) /* This is the main "do_decoding" function; takes the necessary inputs * from the decode call (above) and does the decoding, outputing the decoded result. @@ -52,8 +51,9 @@ typedef unsigned char uint8_t; // in_n_data_bits : INPUT : X : int = 4 bytes (REGISTER) // d_branchtab27_generic : INPUT : 0 : uint8_t[2][32] = 64 bytes // in_depuncture_pattern : INPUT : 64 : uint8_t[8] (max is 6 bytes + 2 padding bytes) -// depd_data : INPUT : 72 : uint8_t[MAX_ENCODED_BITS == 24780] (depunctured data) -// : OUTPUT : 24852 : uint8_t[MAX_ENCODED_BITS * 3 / 4 == 18585 ] : The decoded data stream +// depd_data : INPUT : 72 : uint8_t[MAX_ENCODED_BITS == 24780] (depunctured +// data) : OUTPUT : 24852 : uint8_t[MAX_ENCODED_BITS * 3 / 4 == 18585 ] : +// The decoded data stream /* THESE ARE JUST USED LOCALLY IN THIS FUNCTION NOW */ /* BUT they must reset to zero on each invocation */ @@ -63,373 +63,372 @@ typedef unsigned char uint8_t; // d_path0_generic : INPUT : uint8_t[64] // d_path1_generic : INPUT : uint8_t[64] // d_store_pos : INPUT : int (position in circular traceback buffer?) -// d_mmresult : OUTPUT : uint8_t[64] +// d_mmresult : OUTPUT : uint8_t[64] // d_ppresult : OUTPUT : uint8_t[ntraceback_MAX][ 64 bytes ] - -void do_decoding(int in_n_data_bits, int in_cbps, int in_ntraceback, unsigned char *inMemory, unsigned char *l_decoded) +void do_decoding(int in_n_data_bits, int in_cbps, int in_ntraceback, unsigned char *inMemory, + unsigned char *l_decoded) { - int in_count = 0; - int out_count = 0; - int n_decoded = 0; - - unsigned char* d_brtab27[2] = { &(inMemory[ 0]), - &(inMemory[ 32]) }; - unsigned char* in_depuncture_pattern = &(inMemory[ 64]); - uint8_t* depd_data = &(inMemory[ 72]); - - VERBOSE(if(1) { - printf("\nVBS: in_cbps = %u\n", in_cbps); - printf("VBS: in_ntraceback = %u\n", in_ntraceback); - printf("VBS: in_n_data_bits = %u\n", in_n_data_bits); - for (int ti = 0; ti < 2; ti ++) { - printf("d_brtab[%u] = [ ", ti); - for (int tj = 0; tj < 32; tj++) { - if (tj > 0) { printf(", "); } - printf("%u", d_brtab27[ti][tj]); - } - printf(" ]\n"); - } - printf("VBS: in_depuncture_pattern = [ "); - for (int ti = 0; ti < 6; ti ++) { - if (ti > 0) { printf(", "); } - printf("%02x", in_depuncture_pattern[ti]); - } - printf("]\n"); - printf("\nVBS: depd_data : %p\n", depd_data); - { - int per_row = 0; - printf("%p : ", &depd_data[0]); - for (int ti = 0; ti < MAX_ENCODED_BITS; ti++) { - per_row++; - if ((per_row % 8) == 0) { - printf(" "); - } - printf("%u", depd_data[ti]); - if (per_row == 39) { - printf("\n"); - printf("%p : ", &depd_data[ti]); - per_row = 0; - } - } - printf("\n"); - } - printf("\n\n"); + int in_count = 0; + int out_count = 0; + int n_decoded = 0; + + unsigned char *d_brtab27[2] = {&(inMemory[0]), &(inMemory[32])}; + unsigned char *in_depuncture_pattern = &(inMemory[64]); + uint8_t *depd_data = &(inMemory[72]); + + VERBOSE(if (1) { + printf("\nVBS: in_cbps = %u\n", in_cbps); + printf("VBS: in_ntraceback = %u\n", in_ntraceback); + printf("VBS: in_n_data_bits = %u\n", in_n_data_bits); + for (int ti = 0; ti < 2; ti++) { + printf("d_brtab[%u] = [ ", ti); + for (int tj = 0; tj < 32; tj++) { + if (tj > 0) { printf(", "); } + printf("%u", d_brtab27[ti][tj]); + } + printf(" ]\n"); + } + printf("VBS: in_depuncture_pattern = [ "); + for (int ti = 0; ti < 6; ti++) { + if (ti > 0) { printf(", "); } + printf("%02x", in_depuncture_pattern[ti]); + } + printf("]\n"); + printf("\nVBS: depd_data : %p\n", depd_data); + { + int per_row = 0; + printf("%p : ", &depd_data[0]); + for (int ti = 0; ti < MAX_ENCODED_BITS; ti++) { + per_row++; + if ((per_row % 8) == 0) { printf(" "); } + printf("%u", depd_data[ti]); + if (per_row == 39) { + printf("\n"); + printf("%p : ", &depd_data[ti]); + per_row = 0; + } + } + printf("\n"); + } + printf("\n\n"); }); - - uint8_t l_metric0_generic[64]; - uint8_t l_metric1_generic[64]; - uint8_t l_path0_generic[64]; - uint8_t l_path1_generic[64]; - uint8_t l_mmresult[64]; - uint8_t l_ppresult[TRACEBACK_MAX][64]; - int l_store_pos = 0; - - // This is the "reset" portion: - // Do this before the real operation so local memories are "cleared to zero" - // d_store_pos = 0; - for (int i = 0; i < 64; i++) { - l_metric0_generic[i] = 0; - l_path0_generic[i] = 0; - l_metric1_generic[i] = 0; - l_path1_generic[i] = 0; - l_mmresult[i] = 0; - for (int j = 0; j < TRACEBACK_MAX; j++) { - l_ppresult[j][i] = 0; - } - } - - int viterbi_butterfly_calls = 0; - //while(n_decoded < d_frame->n_data_bits) { - while(n_decoded < in_n_data_bits) { - //printf("n_decoded = %d vs %d = in_n_data_bits\n", n_decoded, in_n_data_bits); - if ((in_count % 4) == 0) { //0 or 3 - //printf(" Viterbi_Butterfly Call,%d,n_decoded,%d,n_data_bits,%d,in_count,%d,%d\n", viterbi_butterfly_calls, n_decoded, in_n_data_bits, in_count, (in_count & 0xfffffffc)); - - //CALL viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc], l_metric0_generic, l_metric1_generic, l_path0_generic, l_path1_generic); - /* The basic Viterbi decoder operation, called a "butterfly" - * operation because of the way it looks on a trellis diagram. Each - * butterfly involves an Add-Compare-Select (ACS) operation on the two nodes - * where the 0 and 1 paths from the current node merge at the next step of - * the trellis. - * - * The code polynomials are assumed to have 1's on both ends. Given a - * function encode_state() that returns the two symbols for a given - * encoder state in the low two bits, such a code will have the following - * identities for even 'n' < 64: - * - * encode_state(n) = encode_state(n+65) - * encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n)) - * - * Any convolutional code you would actually want to use will have - * these properties, so these assumptions aren't too limiting. - * - * Doing this as a macro lets the compiler evaluate at compile time the - * many expressions that depend on the loop index and encoder state and - * emit them as immediate arguments. - * This makes an enormous difference on register-starved machines such - * as the Intel x86 family where evaluating these expressions at runtime - * would spill over into memory. - */ - - // INPUTS/OUTPUTS: All are 64-entry (bytes) arrays randomly accessed. - // symbols : INPUT : Array [ 4 bytes ] - // mm0 : INPUT/OUTPUT : Array [ 64 bytes ] - // mm1 : INPUT/OUTPUT : Array [ 64 bytes ] - // pp0 : INPUT/OUTPUT : Array [ 64 bytes ] - // pp1 : INPUT/OUTPUT : Array [ 64 bytes ] - // d_branchtab27_generic[1].c[] : INPUT : Array [2].c[32] {GLOBAL} - // - - /* void viterbi_butterfly2_generic(unsigned char *symbols, */ - /* unsigned char *mm0, unsigned char *mm1, */ - /* unsigned char *pp0, unsigned char *pp1) */ - { - unsigned char *mm0 = l_metric0_generic; - unsigned char *mm1 = l_metric1_generic; - unsigned char *pp0 = l_path0_generic; - unsigned char *pp1 = l_path1_generic; - unsigned char *symbols = &depd_data[in_count & 0xfffffffc]; - - // These are used to "virtually" rename the uses below (for symmetry; reduces code size) - // Really these are functionally "offset pointers" into the above arrays.... - unsigned char *metric0, *metric1; - unsigned char *path0, *path1; - - // Operate on 4 symbols (2 bits) at a time - - unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], survivor0[16], survivor1[16]; - unsigned char metsv[16], metsvm[16]; - unsigned char shift0[16], shift1[16]; - unsigned char tmp0[16], tmp1[16]; - unsigned char sym0v[16], sym1v[16]; - unsigned short simd_epi16; - unsigned int first_symbol; - unsigned int second_symbol; - - // Set up for the first two symbols (0 and 1) - metric0 = mm0; - path0 = pp0; - metric1 = mm1; - path1 = pp1; - first_symbol = 0; - second_symbol = first_symbol+1; - for (int j = 0; j < 16; j++) { - sym0v[j] = symbols[first_symbol]; - sym1v[j] = symbols[second_symbol]; - } - - for (int s = 0; s < 2; s++) { // iterate across the 2 symbol groups - // This is the basic viterbi butterfly for 2 symbols (we need therefore 2 passes for 4 total symbols) - for (int i = 0; i < 2; i++) { - if (symbols[first_symbol] == 2) { - for (int j = 0; j < 16; j++) { - //metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; - metsvm[j] = d_brtab27[1][(i*16) + j] ^ sym1v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else if (symbols[second_symbol] == 2) { - for (int j = 0; j < 16; j++) { - //metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; - metsvm[j] = d_brtab27[0][(i*16) + j] ^ sym0v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else { - for (int j = 0; j < 16; j++) { - //metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); - metsvm[j] = (d_brtab27[0][(i*16) + j] ^ sym0v[j]) + (d_brtab27[1][(i*16) + j] ^ sym1v[j]); - metsv[j] = 2 - metsvm[j]; - } - } - - for (int j = 0; j < 16; j++) { - m0[j] = metric0[(i*16) + j] + metsv[j]; - m1[j] = metric0[((i+2)*16) + j] + metsvm[j]; - m2[j] = metric0[(i*16) + j] + metsvm[j]; - m3[j] = metric0[((i+2)*16) + j] + metsv[j]; - } - - for (int j = 0; j < 16; j++) { - decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; - decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; - survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); - survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); - } - - for (int j = 0; j < 16; j += 2) { - simd_epi16 = path0[(i*16) + j]; - simd_epi16 |= path0[(i*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift0[j] = simd_epi16; - shift0[j+1] = simd_epi16 >> 8; - - simd_epi16 = path0[((i+2)*16) + j]; - simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift1[j] = simd_epi16; - shift1[j+1] = simd_epi16 >> 8; - } - for (int j = 0; j < 16; j++) { - shift1[j] = shift1[j] + 1; - } - - for (int j = 0, k = 0; j < 16; j += 2, k++) { - metric1[(2*i*16) + j] = survivor0[k]; - metric1[(2*i*16) + (j+1)] = survivor1[k]; - } - for (int j = 0; j < 16; j++) { - tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); - } - - for (int j = 0, k = 8; j < 16; j += 2, k++) { - metric1[((2*i+1)*16) + j] = survivor0[k]; - metric1[((2*i+1)*16) + (j+1)] = survivor1[k]; - } - for (int j = 0; j < 16; j++) { - tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); - } - - for (int j = 0, k = 0; j < 16; j += 2, k++) { - path1[(2*i*16) + j] = tmp0[k]; - path1[(2*i*16) + (j+1)] = tmp1[k]; - } - for (int j = 0, k = 8; j < 16; j += 2, k++) { - path1[((2*i+1)*16) + j] = tmp0[k]; - path1[((2*i+1)*16) + (j+1)] = tmp1[k]; - } - } - - // Set up for the second two symbols (2 and 3) - metric0 = mm1; - path0 = pp1; - metric1 = mm0; - path1 = pp0; - first_symbol = 2; - second_symbol = first_symbol+1; - for (int j = 0; j < 16; j++) { - sym0v[j] = symbols[first_symbol]; - sym1v[j] = symbols[second_symbol]; - } - } - } // END of call to viterbi_butterfly2_generic - viterbi_butterfly_calls++; // Do not increment until after the comparison code. - - if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 - unsigned char c; - // Find current best path - // - // INPUTS/OUTPUTS: - // RET_VAL : (ignored) - // mm0 : INPUT/OUTPUT : Array [ 64 ] - // mm1 : INPUT/OUTPUT : Array [ 64 ] - // pp0 : INPUT/OUTPUT : Array [ 64 ] - // pp1 : INPUT/OUTPUT : Array [ 64 ] - // ntraceback : INPUT : int (I think effectively const for given run type; here 5 I think) - // outbuf : OUTPUT : 1 byte - // l_store_pos : GLOBAL IN/OUT : int (position in circular traceback buffer?) - - - // l_mmresult : GLOBAL OUTPUT : Array [ 64 bytes ] - // l_ppresult : GLOBAL OUTPUT : Array [ntraceback][ 64 bytes ] - - // CALL : viterbi_get_output_generic(l_metric0_generic, l_path0_generic, in_ntraceback, &c); - // unsigned char viterbi_get_output_generic(unsigned char *mm0, unsigned char *pp0, int ntraceback, unsigned char *outbuf) - { - unsigned char *mm0 = l_metric0_generic; - unsigned char *pp0 = l_path0_generic; - int ntraceback = in_ntraceback; - unsigned char *outbuf = &c; - - int i; - int bestmetric, minmetric; - int beststate = 0; - int pos = 0; - int j; - - // circular buffer with the last ntraceback paths - l_store_pos = (l_store_pos + 1) % ntraceback; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 16; j++) { - l_mmresult[(i*16) + j] = mm0[(i*16) + j]; - l_ppresult[l_store_pos][(i*16) + j] = pp0[(i*16) + j]; - } - } - - // Find out the best final state - bestmetric = l_mmresult[beststate]; - minmetric = l_mmresult[beststate]; - - for (i = 1; i < 64; i++) { - if (l_mmresult[i] > bestmetric) { - bestmetric = l_mmresult[i]; - beststate = i; - } - if (l_mmresult[i] < minmetric) { - minmetric = l_mmresult[i]; - } - } - - // Trace back - for (i = 0, pos = l_store_pos; i < (ntraceback - 1); i++) { - // Obtain the state from the output bits - // by clocking in the output bits in reverse order. - // The state has only 6 bits - beststate = l_ppresult[pos][beststate] >> 2; - pos = (pos - 1 + ntraceback) % ntraceback; - } - - // Store output byte - *outbuf = l_ppresult[pos][beststate]; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 16; j++) { - pp0[(i*16) + j] = 0; - mm0[(i*16) + j] = mm0[(i*16) + j] - minmetric; - } - } - - //return bestmetric; - } - - //std::cout << "OUTPUT: " << (unsigned int)c << std::endl; - if (out_count >= in_ntraceback) { - for (int i= 0; i < 8; i++) { - l_decoded[(out_count - in_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; - /* if (n_decoded < 16) { */ - /* printf("l_decoded[ %u ] written as %u\n", (out_count - in_ntraceback) * 8 + i, l_decoded[(out_count - in_ntraceback) * 8 + i]); */ - /* } */ - n_decoded++; - } - } - out_count++; - } + uint8_t l_metric0_generic[64]; + uint8_t l_metric1_generic[64]; + uint8_t l_path0_generic[64]; + uint8_t l_path1_generic[64]; + uint8_t l_mmresult[64]; + uint8_t l_ppresult[TRACEBACK_MAX][64]; + int l_store_pos = 0; + + // This is the "reset" portion: + // Do this before the real operation so local memories are "cleared to zero" + // d_store_pos = 0; + for (int i = 0; i < 64; i++) { + l_metric0_generic[i] = 0; + l_path0_generic[i] = 0; + l_metric1_generic[i] = 0; + l_path1_generic[i] = 0; + l_mmresult[i] = 0; + for (int j = 0; j < TRACEBACK_MAX; j++) { + l_ppresult[j][i] = 0; + } } - in_count++; - } - - VERBOSE(if(1) { - printf("\nVBS: Final l_decoded : %p\n", l_decoded); - int per_row = 0; - printf("%p : ", &l_decoded[0]); - for (int ti = 0; ti < (MAX_ENCODED_BITS * 3 / 4); ti ++) { - per_row++; - if ((per_row % 8) == 0) { - printf(" "); - } - printf("%u", l_decoded[ti]); - if (per_row == 39) { - printf("\n"); - printf("%p : ", &l_decoded[ti]); - per_row = 0; - } + + int viterbi_butterfly_calls = 0; + // while(n_decoded < d_frame->n_data_bits) { + while (n_decoded < in_n_data_bits) { + // printf("n_decoded = %d vs %d = in_n_data_bits\n", n_decoded, in_n_data_bits); + if ((in_count % 4) == 0) { // 0 or 3 + // printf(" Viterbi_Butterfly Call,%d,n_decoded,%d,n_data_bits,%d,in_count,%d,%d\n", + // viterbi_butterfly_calls, n_decoded, in_n_data_bits, in_count, (in_count & + // 0xfffffffc)); + + // CALL viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc], + // l_metric0_generic, l_metric1_generic, l_path0_generic, l_path1_generic); + /* The basic Viterbi decoder operation, called a "butterfly" + * operation because of the way it looks on a trellis diagram. Each + * butterfly involves an Add-Compare-Select (ACS) operation on the two nodes + * where the 0 and 1 paths from the current node merge at the next step of + * the trellis. + * + * The code polynomials are assumed to have 1's on both ends. Given a + * function encode_state() that returns the two symbols for a given + * encoder state in the low two bits, such a code will have the following + * identities for even 'n' < 64: + * + * encode_state(n) = encode_state(n+65) + * encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n)) + * + * Any convolutional code you would actually want to use will have + * these properties, so these assumptions aren't too limiting. + * + * Doing this as a macro lets the compiler evaluate at compile time the + * many expressions that depend on the loop index and encoder state and + * emit them as immediate arguments. + * This makes an enormous difference on register-starved machines such + * as the Intel x86 family where evaluating these expressions at runtime + * would spill over into memory. + */ + + // INPUTS/OUTPUTS: All are 64-entry (bytes) arrays randomly accessed. + // symbols : INPUT : Array [ 4 bytes ] + // mm0 : INPUT/OUTPUT : Array [ 64 bytes ] + // mm1 : INPUT/OUTPUT : Array [ 64 bytes ] + // pp0 : INPUT/OUTPUT : Array [ 64 bytes ] + // pp1 : INPUT/OUTPUT : Array [ 64 bytes ] + // d_branchtab27_generic[1].c[] : INPUT : Array [2].c[32] {GLOBAL} + // + + /* void viterbi_butterfly2_generic(unsigned char *symbols, */ + /* unsigned char *mm0, unsigned char *mm1, */ + /* unsigned char *pp0, unsigned char *pp1) */ + { + unsigned char *mm0 = l_metric0_generic; + unsigned char *mm1 = l_metric1_generic; + unsigned char *pp0 = l_path0_generic; + unsigned char *pp1 = l_path1_generic; + unsigned char *symbols = &depd_data[in_count & 0xfffffffc]; + + // These are used to "virtually" rename the uses below (for symmetry; reduces code + // size) + // Really these are functionally "offset pointers" into the above arrays.... + unsigned char *metric0, *metric1; + unsigned char *path0, *path1; + + // Operate on 4 symbols (2 bits) at a time + + unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], + survivor0[16], survivor1[16]; + unsigned char metsv[16], metsvm[16]; + unsigned char shift0[16], shift1[16]; + unsigned char tmp0[16], tmp1[16]; + unsigned char sym0v[16], sym1v[16]; + unsigned short simd_epi16; + unsigned int first_symbol; + unsigned int second_symbol; + + // Set up for the first two symbols (0 and 1) + metric0 = mm0; + path0 = pp0; + metric1 = mm1; + path1 = pp1; + first_symbol = 0; + second_symbol = first_symbol + 1; + for (int j = 0; j < 16; j++) { + sym0v[j] = symbols[first_symbol]; + sym1v[j] = symbols[second_symbol]; + } + + for (int s = 0; s < 2; s++) { // iterate across the 2 symbol groups + // This is the basic viterbi butterfly for 2 symbols (we need therefore 2 passes + // for 4 total symbols) + for (int i = 0; i < 2; i++) { + if (symbols[first_symbol] == 2) { + for (int j = 0; j < 16; j++) { + // metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; + metsvm[j] = d_brtab27[1][(i * 16) + j] ^ sym1v[j]; + metsv[j] = 1 - metsvm[j]; + } + } + else if (symbols[second_symbol] == 2) { + for (int j = 0; j < 16; j++) { + // metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; + metsvm[j] = d_brtab27[0][(i * 16) + j] ^ sym0v[j]; + metsv[j] = 1 - metsvm[j]; + } + } + else { + for (int j = 0; j < 16; j++) { + // metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + + // (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); + metsvm[j] = (d_brtab27[0][(i * 16) + j] ^ sym0v[j]) + + (d_brtab27[1][(i * 16) + j] ^ sym1v[j]); + metsv[j] = 2 - metsvm[j]; + } + } + + for (int j = 0; j < 16; j++) { + m0[j] = metric0[(i * 16) + j] + metsv[j]; + m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j]; + m2[j] = metric0[(i * 16) + j] + metsvm[j]; + m3[j] = metric0[((i + 2) * 16) + j] + metsv[j]; + } + + for (int j = 0; j < 16; j++) { + decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; + decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; + survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); + survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); + } + + for (int j = 0; j < 16; j += 2) { + simd_epi16 = path0[(i * 16) + j]; + simd_epi16 |= path0[(i * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift0[j] = simd_epi16; + shift0[j + 1] = simd_epi16 >> 8; + + simd_epi16 = path0[((i + 2) * 16) + j]; + simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift1[j] = simd_epi16; + shift1[j + 1] = simd_epi16 >> 8; + } + for (int j = 0; j < 16; j++) { + shift1[j] = shift1[j] + 1; + } + + for (int j = 0, k = 0; j < 16; j += 2, k++) { + metric1[(2 * i * 16) + j] = survivor0[k]; + metric1[(2 * i * 16) + (j + 1)] = survivor1[k]; + } + for (int j = 0; j < 16; j++) { + tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); + } + + for (int j = 0, k = 8; j < 16; j += 2, k++) { + metric1[((2 * i + 1) * 16) + j] = survivor0[k]; + metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k]; + } + for (int j = 0; j < 16; j++) { + tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); + } + + for (int j = 0, k = 0; j < 16; j += 2, k++) { + path1[(2 * i * 16) + j] = tmp0[k]; + path1[(2 * i * 16) + (j + 1)] = tmp1[k]; + } + for (int j = 0, k = 8; j < 16; j += 2, k++) { + path1[((2 * i + 1) * 16) + j] = tmp0[k]; + path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k]; + } + } + + // Set up for the second two symbols (2 and 3) + metric0 = mm1; + path0 = pp1; + metric1 = mm0; + path1 = pp0; + first_symbol = 2; + second_symbol = first_symbol + 1; + for (int j = 0; j < 16; j++) { + sym0v[j] = symbols[first_symbol]; + sym1v[j] = symbols[second_symbol]; + } + } + } // END of call to viterbi_butterfly2_generic + viterbi_butterfly_calls++; // Do not increment until after the comparison code. + + if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 + unsigned char c; + // Find current best path + // + // INPUTS/OUTPUTS: + // RET_VAL : (ignored) + // mm0 : INPUT/OUTPUT : Array [ 64 ] + // mm1 : INPUT/OUTPUT : Array [ 64 ] + // pp0 : INPUT/OUTPUT : Array [ 64 ] + // pp1 : INPUT/OUTPUT : Array [ 64 ] + // ntraceback : INPUT : int (I think effectively const for given run + // type; here 5 I think) outbuf : OUTPUT : 1 byte l_store_pos : + // GLOBAL IN/OUT : int (position in circular traceback buffer?) + + // l_mmresult : GLOBAL OUTPUT : Array [ 64 bytes ] + // l_ppresult : GLOBAL OUTPUT : Array [ntraceback][ 64 bytes ] + + // CALL : viterbi_get_output_generic(l_metric0_generic, l_path0_generic, + // in_ntraceback, &c); unsigned char viterbi_get_output_generic(unsigned char *mm0, + // unsigned char *pp0, int ntraceback, unsigned char *outbuf) + { + unsigned char *mm0 = l_metric0_generic; + unsigned char *pp0 = l_path0_generic; + int ntraceback = in_ntraceback; + unsigned char *outbuf = &c; + + int i; + int bestmetric, minmetric; + int beststate = 0; + int pos = 0; + int j; + + // circular buffer with the last ntraceback paths + l_store_pos = (l_store_pos + 1) % ntraceback; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 16; j++) { + l_mmresult[(i * 16) + j] = mm0[(i * 16) + j]; + l_ppresult[l_store_pos][(i * 16) + j] = pp0[(i * 16) + j]; + } + } + + // Find out the best final state + bestmetric = l_mmresult[beststate]; + minmetric = l_mmresult[beststate]; + + for (i = 1; i < 64; i++) { + if (l_mmresult[i] > bestmetric) { + bestmetric = l_mmresult[i]; + beststate = i; + } + if (l_mmresult[i] < minmetric) { minmetric = l_mmresult[i]; } + } + + // Trace back + for (i = 0, pos = l_store_pos; i < (ntraceback - 1); i++) { + // Obtain the state from the output bits + // by clocking in the output bits in reverse order. + // The state has only 6 bits + beststate = l_ppresult[pos][beststate] >> 2; + pos = (pos - 1 + ntraceback) % ntraceback; + } + + // Store output byte + *outbuf = l_ppresult[pos][beststate]; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 16; j++) { + pp0[(i * 16) + j] = 0; + mm0[(i * 16) + j] = mm0[(i * 16) + j] - minmetric; + } + } + + // return bestmetric; + } + + // std::cout << "OUTPUT: " << (unsigned int)c << std::endl; + if (out_count >= in_ntraceback) { + for (int i = 0; i < 8; i++) { + l_decoded[(out_count - in_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; + /* if (n_decoded < 16) { */ + /* printf("l_decoded[ %u ] written as %u\n", (out_count - in_ntraceback) * + * 8 + i, l_decoded[(out_count - in_ntraceback) * 8 + i]); */ + /* } */ + n_decoded++; + } + } + out_count++; + } + } + in_count++; } - printf("\n"); - printf("\n"); - }); + VERBOSE(if (1) { + printf("\nVBS: Final l_decoded : %p\n", l_decoded); + int per_row = 0; + printf("%p : ", &l_decoded[0]); + for (int ti = 0; ti < (MAX_ENCODED_BITS * 3 / 4); ti++) { + per_row++; + if ((per_row % 8) == 0) { printf(" "); } + printf("%u", l_decoded[ti]); + if (per_row == 39) { + printf("\n"); + printf("%p : ", &l_decoded[ti]); + per_row = 0; + } + } + printf("\n"); + printf("\n"); + }); } - diff --git a/accelerators/stratus_hls/vitdodec_stratus/sw/linux/app/do_decoding.c b/accelerators/stratus_hls/vitdodec_stratus/sw/linux/app/do_decoding.c index 804d945ecd..c2ad06ed21 100644 --- a/accelerators/stratus_hls/vitdodec_stratus/sw/linux/app/do_decoding.c +++ b/accelerators/stratus_hls/vitdodec_stratus/sw/linux/app/do_decoding.c @@ -28,19 +28,18 @@ * Some modifications from original Karn code by Matt Ettus * Major modifications by adding SSE2 code by Bogdan Diaconescu */ -#include #include +#include #include "do_decoding.h" - // GLOBAL VARIABLES -#define TRACEBACK_MAX 11 +#define TRACEBACK_MAX 11 -#define MAX_PAYLOAD_SIZE 1500 -#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC -#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) -#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288) +#define MAX_PAYLOAD_SIZE 1500 +#define MAX_PSDU_SIZE (MAX_PAYLOAD_SIZE + 28) // MAC, CRC +#define MAX_SYM (((16 + 8 * MAX_PSDU_SIZE + 6) / 24) + 1) +#define MAX_ENCODED_BITS ((16 + 8 * MAX_PSDU_SIZE + 6) * 2 + 288) /* This is the main "do_decoding" function; takes the necessary inputs * from the decode call (above) and does the decoding, outputing the decoded result. @@ -51,8 +50,9 @@ // in_n_data_bits : INPUT : X : int = 4 bytes (REGISTER) // d_branchtab27_generic : INPUT : 0 : uint8_t[2][32] = 64 bytes // in_depuncture_pattern : INPUT : 64 : uint8_t[8] (max is 6 bytes + 2 padding bytes) -// depd_data : INPUT : 72 : uint8_t[MAX_ENCODED_BITS == 24780] (depunctured data) -// : OUTPUT : 24852 : uint8_t[MAX_ENCODED_BITS * 3 / 4 == 18585 ] : The decoded data stream +// depd_data : INPUT : 72 : uint8_t[MAX_ENCODED_BITS == 24780] (depunctured +// data) : OUTPUT : 24852 : uint8_t[MAX_ENCODED_BITS * 3 / 4 == 18585 ] : +// The decoded data stream /* THESE ARE JUST USED LOCALLY IN THIS FUNCTION NOW */ /* BUT they must reset to zero on each invocation */ @@ -62,373 +62,372 @@ // d_path0_generic : INPUT : uint8_t[64] // d_path1_generic : INPUT : uint8_t[64] // d_store_pos : INPUT : int (position in circular traceback buffer?) -// d_mmresult : OUTPUT : uint8_t[64] +// d_mmresult : OUTPUT : uint8_t[64] // d_ppresult : OUTPUT : uint8_t[ntraceback_MAX][ 64 bytes ] - -void do_decoding(int in_n_data_bits, int in_cbps, int in_ntraceback, unsigned char *inMemory, unsigned char *l_decoded) +void do_decoding(int in_n_data_bits, int in_cbps, int in_ntraceback, unsigned char *inMemory, + unsigned char *l_decoded) { - int in_count = 0; - int out_count = 0; - int n_decoded = 0; - - unsigned char* d_brtab27[2] = { &(inMemory[ 0]), - &(inMemory[ 32]) }; - unsigned char* in_depuncture_pattern __attribute__((unused)) = &(inMemory[ 64]); - uint8_t* depd_data = &(inMemory[ 72]); - - VERBOSE(if(1) { - printf("\nVBS: in_cbps = %u\n", in_cbps); - printf("VBS: in_ntraceback = %u\n", in_ntraceback); - printf("VBS: in_n_data_bits = %u\n", in_n_data_bits); - for (int ti = 0; ti < 2; ti ++) { - printf("d_brtab[%u] = [ ", ti); - for (int tj = 0; tj < 32; tj++) { - if (tj > 0) { printf(", "); } - printf("%u", d_brtab27[ti][tj]); - } - printf(" ]\n"); - } - printf("VBS: in_depuncture_pattern = [ "); - for (int ti = 0; ti < 6; ti ++) { - if (ti > 0) { printf(", "); } - printf("%02x", in_depuncture_pattern[ti]); - } - printf("]\n"); - printf("\nVBS: depd_data : %p\n", depd_data); - { - int per_row = 0; - printf("%p : ", &depd_data[0]); - for (int ti = 0; ti < MAX_ENCODED_BITS; ti++) { - per_row++; - if ((per_row % 8) == 0) { - printf(" "); - } - printf("%u", depd_data[ti]); - if (per_row == 39) { - printf("\n"); - printf("%p : ", &depd_data[ti]); - per_row = 0; - } - } - printf("\n"); - } - printf("\n\n"); + int in_count = 0; + int out_count = 0; + int n_decoded = 0; + + unsigned char *d_brtab27[2] = {&(inMemory[0]), &(inMemory[32])}; + unsigned char *in_depuncture_pattern __attribute__((unused)) = &(inMemory[64]); + uint8_t *depd_data = &(inMemory[72]); + + VERBOSE(if (1) { + printf("\nVBS: in_cbps = %u\n", in_cbps); + printf("VBS: in_ntraceback = %u\n", in_ntraceback); + printf("VBS: in_n_data_bits = %u\n", in_n_data_bits); + for (int ti = 0; ti < 2; ti++) { + printf("d_brtab[%u] = [ ", ti); + for (int tj = 0; tj < 32; tj++) { + if (tj > 0) { printf(", "); } + printf("%u", d_brtab27[ti][tj]); + } + printf(" ]\n"); + } + printf("VBS: in_depuncture_pattern = [ "); + for (int ti = 0; ti < 6; ti++) { + if (ti > 0) { printf(", "); } + printf("%02x", in_depuncture_pattern[ti]); + } + printf("]\n"); + printf("\nVBS: depd_data : %p\n", depd_data); + { + int per_row = 0; + printf("%p : ", &depd_data[0]); + for (int ti = 0; ti < MAX_ENCODED_BITS; ti++) { + per_row++; + if ((per_row % 8) == 0) { printf(" "); } + printf("%u", depd_data[ti]); + if (per_row == 39) { + printf("\n"); + printf("%p : ", &depd_data[ti]); + per_row = 0; + } + } + printf("\n"); + } + printf("\n\n"); }); - - uint8_t l_metric0_generic[64]; - uint8_t l_metric1_generic[64]; - uint8_t l_path0_generic[64]; - uint8_t l_path1_generic[64]; - uint8_t l_mmresult[64]; - uint8_t l_ppresult[TRACEBACK_MAX][64]; - int l_store_pos = 0; - - // This is the "reset" portion: - // Do this before the real operation so local memories are "cleared to zero" - // d_store_pos = 0; - for (int i = 0; i < 64; i++) { - l_metric0_generic[i] = 0; - l_path0_generic[i] = 0; - l_metric1_generic[i] = 0; - l_path1_generic[i] = 0; - l_mmresult[i] = 0; - for (int j = 0; j < TRACEBACK_MAX; j++) { - l_ppresult[j][i] = 0; + uint8_t l_metric0_generic[64]; + uint8_t l_metric1_generic[64]; + uint8_t l_path0_generic[64]; + uint8_t l_path1_generic[64]; + uint8_t l_mmresult[64]; + uint8_t l_ppresult[TRACEBACK_MAX][64]; + int l_store_pos = 0; + + // This is the "reset" portion: + // Do this before the real operation so local memories are "cleared to zero" + // d_store_pos = 0; + for (int i = 0; i < 64; i++) { + l_metric0_generic[i] = 0; + l_path0_generic[i] = 0; + l_metric1_generic[i] = 0; + l_path1_generic[i] = 0; + l_mmresult[i] = 0; + for (int j = 0; j < TRACEBACK_MAX; j++) { + l_ppresult[j][i] = 0; + } } - } - - int viterbi_butterfly_calls = 0; - //while(n_decoded < d_frame->n_data_bits) { - while(n_decoded < in_n_data_bits) { - //printf("n_decoded = %d vs %d = in_n_data_bits\n", n_decoded, in_n_data_bits); - if ((in_count % 4) == 0) { //0 or 3 - //printf(" Viterbi_Butterfly Call,%d,n_decoded,%d,n_data_bits,%d,in_count,%d,%d\n", viterbi_butterfly_calls, n_decoded, in_n_data_bits, in_count, (in_count & 0xfffffffc)); - - //CALL viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc], l_metric0_generic, l_metric1_generic, l_path0_generic, l_path1_generic); - /* The basic Viterbi decoder operation, called a "butterfly" - * operation because of the way it looks on a trellis diagram. Each - * butterfly involves an Add-Compare-Select (ACS) operation on the two nodes - * where the 0 and 1 paths from the current node merge at the next step of - * the trellis. - * - * The code polynomials are assumed to have 1's on both ends. Given a - * function encode_state() that returns the two symbols for a given - * encoder state in the low two bits, such a code will have the following - * identities for even 'n' < 64: - * - * encode_state(n) = encode_state(n+65) - * encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n)) - * - * Any convolutional code you would actually want to use will have - * these properties, so these assumptions aren't too limiting. - * - * Doing this as a macro lets the compiler evaluate at compile time the - * many expressions that depend on the loop index and encoder state and - * emit them as immediate arguments. - * This makes an enormous difference on register-starved machines such - * as the Intel x86 family where evaluating these expressions at runtime - * would spill over into memory. - */ - - // INPUTS/OUTPUTS: All are 64-entry (bytes) arrays randomly accessed. - // symbols : INPUT : Array [ 4 bytes ] - // mm0 : INPUT/OUTPUT : Array [ 64 bytes ] - // mm1 : INPUT/OUTPUT : Array [ 64 bytes ] - // pp0 : INPUT/OUTPUT : Array [ 64 bytes ] - // pp1 : INPUT/OUTPUT : Array [ 64 bytes ] - // d_branchtab27_generic[1].c[] : INPUT : Array [2].c[32] {GLOBAL} - // - - /* void viterbi_butterfly2_generic(unsigned char *symbols, */ - /* unsigned char *mm0, unsigned char *mm1, */ - /* unsigned char *pp0, unsigned char *pp1) */ - { - unsigned char *mm0 = l_metric0_generic; - unsigned char *mm1 = l_metric1_generic; - unsigned char *pp0 = l_path0_generic; - unsigned char *pp1 = l_path1_generic; - unsigned char *symbols = &depd_data[in_count & 0xfffffffc]; - - // These are used to "virtually" rename the uses below (for symmetry; reduces code size) - // Really these are functionally "offset pointers" into the above arrays.... - unsigned char *metric0, *metric1; - unsigned char *path0, *path1; - - // Operate on 4 symbols (2 bits) at a time - - unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], survivor0[16], survivor1[16]; - unsigned char metsv[16], metsvm[16]; - unsigned char shift0[16], shift1[16]; - unsigned char tmp0[16], tmp1[16]; - unsigned char sym0v[16], sym1v[16]; - unsigned short simd_epi16; - unsigned int first_symbol; - unsigned int second_symbol; - - // Set up for the first two symbols (0 and 1) - metric0 = mm0; - path0 = pp0; - metric1 = mm1; - path1 = pp1; - first_symbol = 0; - second_symbol = first_symbol+1; - for (int j = 0; j < 16; j++) { - sym0v[j] = symbols[first_symbol]; - sym1v[j] = symbols[second_symbol]; - } - - for (int s = 0; s < 2; s++) { // iterate across the 2 symbol groups - // This is the basic viterbi butterfly for 2 symbols (we need therefore 2 passes for 4 total symbols) - for (int i = 0; i < 2; i++) { - if (symbols[first_symbol] == 2) { - for (int j = 0; j < 16; j++) { - //metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; - metsvm[j] = d_brtab27[1][(i*16) + j] ^ sym1v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else if (symbols[second_symbol] == 2) { - for (int j = 0; j < 16; j++) { - //metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; - metsvm[j] = d_brtab27[0][(i*16) + j] ^ sym0v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else { - for (int j = 0; j < 16; j++) { - //metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); - metsvm[j] = (d_brtab27[0][(i*16) + j] ^ sym0v[j]) + (d_brtab27[1][(i*16) + j] ^ sym1v[j]); - metsv[j] = 2 - metsvm[j]; - } - } - - for (int j = 0; j < 16; j++) { - m0[j] = metric0[(i*16) + j] + metsv[j]; - m1[j] = metric0[((i+2)*16) + j] + metsvm[j]; - m2[j] = metric0[(i*16) + j] + metsvm[j]; - m3[j] = metric0[((i+2)*16) + j] + metsv[j]; - } - - for (int j = 0; j < 16; j++) { - decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; - decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; - survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); - survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); - } - - for (int j = 0; j < 16; j += 2) { - simd_epi16 = path0[(i*16) + j]; - simd_epi16 |= path0[(i*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift0[j] = simd_epi16; - shift0[j+1] = simd_epi16 >> 8; - - simd_epi16 = path0[((i+2)*16) + j]; - simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift1[j] = simd_epi16; - shift1[j+1] = simd_epi16 >> 8; - } - for (int j = 0; j < 16; j++) { - shift1[j] = shift1[j] + 1; - } - - for (int j = 0, k = 0; j < 16; j += 2, k++) { - metric1[(2*i*16) + j] = survivor0[k]; - metric1[(2*i*16) + (j+1)] = survivor1[k]; - } - for (int j = 0; j < 16; j++) { - tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); - } - - for (int j = 0, k = 8; j < 16; j += 2, k++) { - metric1[((2*i+1)*16) + j] = survivor0[k]; - metric1[((2*i+1)*16) + (j+1)] = survivor1[k]; - } - for (int j = 0; j < 16; j++) { - tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); - } - - for (int j = 0, k = 0; j < 16; j += 2, k++) { - path1[(2*i*16) + j] = tmp0[k]; - path1[(2*i*16) + (j+1)] = tmp1[k]; - } - for (int j = 0, k = 8; j < 16; j += 2, k++) { - path1[((2*i+1)*16) + j] = tmp0[k]; - path1[((2*i+1)*16) + (j+1)] = tmp1[k]; - } - } - - // Set up for the second two symbols (2 and 3) - metric0 = mm1; - path0 = pp1; - metric1 = mm0; - path1 = pp0; - first_symbol = 2; - second_symbol = first_symbol+1; - for (int j = 0; j < 16; j++) { - sym0v[j] = symbols[first_symbol]; - sym1v[j] = symbols[second_symbol]; - } - } - } // END of call to viterbi_butterfly2_generic - viterbi_butterfly_calls++; // Do not increment until after the comparison code. - - if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 - unsigned char c; - // Find current best path - // - // INPUTS/OUTPUTS: - // RET_VAL : (ignored) - // mm0 : INPUT/OUTPUT : Array [ 64 ] - // mm1 : INPUT/OUTPUT : Array [ 64 ] - // pp0 : INPUT/OUTPUT : Array [ 64 ] - // pp1 : INPUT/OUTPUT : Array [ 64 ] - // ntraceback : INPUT : int (I think effectively const for given run type; here 5 I think) - // outbuf : OUTPUT : 1 byte - // l_store_pos : GLOBAL IN/OUT : int (position in circular traceback buffer?) - - - // l_mmresult : GLOBAL OUTPUT : Array [ 64 bytes ] - // l_ppresult : GLOBAL OUTPUT : Array [ntraceback][ 64 bytes ] - - // CALL : viterbi_get_output_generic(l_metric0_generic, l_path0_generic, in_ntraceback, &c); - // unsigned char viterbi_get_output_generic(unsigned char *mm0, unsigned char *pp0, int ntraceback, unsigned char *outbuf) - { - unsigned char *mm0 = l_metric0_generic; - unsigned char *pp0 = l_path0_generic; - int ntraceback = in_ntraceback; - unsigned char *outbuf = &c; - - int i; - int bestmetric, minmetric; - int beststate = 0; - int pos = 0; - int j; - - // circular buffer with the last ntraceback paths - l_store_pos = (l_store_pos + 1) % ntraceback; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 16; j++) { - l_mmresult[(i*16) + j] = mm0[(i*16) + j]; - l_ppresult[l_store_pos][(i*16) + j] = pp0[(i*16) + j]; - } - } - - // Find out the best final state - bestmetric = l_mmresult[beststate]; - minmetric = l_mmresult[beststate]; - - for (i = 1; i < 64; i++) { - if (l_mmresult[i] > bestmetric) { - bestmetric = l_mmresult[i]; - beststate = i; - } - if (l_mmresult[i] < minmetric) { - minmetric = l_mmresult[i]; - } - } - - // Trace back - for (i = 0, pos = l_store_pos; i < (ntraceback - 1); i++) { - // Obtain the state from the output bits - // by clocking in the output bits in reverse order. - // The state has only 6 bits - beststate = l_ppresult[pos][beststate] >> 2; - pos = (pos - 1 + ntraceback) % ntraceback; - } - - // Store output byte - *outbuf = l_ppresult[pos][beststate]; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 16; j++) { - pp0[(i*16) + j] = 0; - mm0[(i*16) + j] = mm0[(i*16) + j] - minmetric; - } - } - - //return bestmetric; - } - - //std::cout << "OUTPUT: " << (unsigned int)c << std::endl; - if (out_count >= in_ntraceback) { - for (int i= 0; i < 8; i++) { - l_decoded[(out_count - in_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; - /* if (n_decoded < 16) { */ - /* printf("l_decoded[ %u ] written as %u\n", (out_count - in_ntraceback) * 8 + i, l_decoded[(out_count - in_ntraceback) * 8 + i]); */ - /* } */ - n_decoded++; - } - } - out_count++; - } - } - in_count++; - } - - VERBOSE(if(1) { - printf("\nVBS: Final l_decoded : %p\n", l_decoded); - int per_row = 0; - printf("%p : ", &l_decoded[0]); - for (int ti = 0; ti < (MAX_ENCODED_BITS * 3 / 4); ti ++) { - per_row++; - if ((per_row % 8) == 0) { - printf(" "); - } - printf("%u", l_decoded[ti]); - if (per_row == 39) { - printf("\n"); - printf("%p : ", &l_decoded[ti]); - per_row = 0; - } + + int viterbi_butterfly_calls = 0; + // while(n_decoded < d_frame->n_data_bits) { + while (n_decoded < in_n_data_bits) { + // printf("n_decoded = %d vs %d = in_n_data_bits\n", n_decoded, in_n_data_bits); + if ((in_count % 4) == 0) { // 0 or 3 + // printf(" Viterbi_Butterfly Call,%d,n_decoded,%d,n_data_bits,%d,in_count,%d,%d\n", + // viterbi_butterfly_calls, n_decoded, in_n_data_bits, in_count, (in_count & + // 0xfffffffc)); + + // CALL viterbi_butterfly2_generic(&depunctured[in_count & 0xfffffffc], + // l_metric0_generic, l_metric1_generic, l_path0_generic, l_path1_generic); + /* The basic Viterbi decoder operation, called a "butterfly" + * operation because of the way it looks on a trellis diagram. Each + * butterfly involves an Add-Compare-Select (ACS) operation on the two nodes + * where the 0 and 1 paths from the current node merge at the next step of + * the trellis. + * + * The code polynomials are assumed to have 1's on both ends. Given a + * function encode_state() that returns the two symbols for a given + * encoder state in the low two bits, such a code will have the following + * identities for even 'n' < 64: + * + * encode_state(n) = encode_state(n+65) + * encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n)) + * + * Any convolutional code you would actually want to use will have + * these properties, so these assumptions aren't too limiting. + * + * Doing this as a macro lets the compiler evaluate at compile time the + * many expressions that depend on the loop index and encoder state and + * emit them as immediate arguments. + * This makes an enormous difference on register-starved machines such + * as the Intel x86 family where evaluating these expressions at runtime + * would spill over into memory. + */ + + // INPUTS/OUTPUTS: All are 64-entry (bytes) arrays randomly accessed. + // symbols : INPUT : Array [ 4 bytes ] + // mm0 : INPUT/OUTPUT : Array [ 64 bytes ] + // mm1 : INPUT/OUTPUT : Array [ 64 bytes ] + // pp0 : INPUT/OUTPUT : Array [ 64 bytes ] + // pp1 : INPUT/OUTPUT : Array [ 64 bytes ] + // d_branchtab27_generic[1].c[] : INPUT : Array [2].c[32] {GLOBAL} + // + + /* void viterbi_butterfly2_generic(unsigned char *symbols, */ + /* unsigned char *mm0, unsigned char *mm1, */ + /* unsigned char *pp0, unsigned char *pp1) */ + { + unsigned char *mm0 = l_metric0_generic; + unsigned char *mm1 = l_metric1_generic; + unsigned char *pp0 = l_path0_generic; + unsigned char *pp1 = l_path1_generic; + unsigned char *symbols = &depd_data[in_count & 0xfffffffc]; + + // These are used to "virtually" rename the uses below (for symmetry; reduces code + // size) + // Really these are functionally "offset pointers" into the above arrays.... + unsigned char *metric0, *metric1; + unsigned char *path0, *path1; + + // Operate on 4 symbols (2 bits) at a time + + unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], + survivor0[16], survivor1[16]; + unsigned char metsv[16], metsvm[16]; + unsigned char shift0[16], shift1[16]; + unsigned char tmp0[16], tmp1[16]; + unsigned char sym0v[16], sym1v[16]; + unsigned short simd_epi16; + unsigned int first_symbol; + unsigned int second_symbol; + + // Set up for the first two symbols (0 and 1) + metric0 = mm0; + path0 = pp0; + metric1 = mm1; + path1 = pp1; + first_symbol = 0; + second_symbol = first_symbol + 1; + for (int j = 0; j < 16; j++) { + sym0v[j] = symbols[first_symbol]; + sym1v[j] = symbols[second_symbol]; + } + + for (int s = 0; s < 2; s++) { // iterate across the 2 symbol groups + // This is the basic viterbi butterfly for 2 symbols (we need therefore 2 passes + // for 4 total symbols) + for (int i = 0; i < 2; i++) { + if (symbols[first_symbol] == 2) { + for (int j = 0; j < 16; j++) { + // metsvm[j] = d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; + metsvm[j] = d_brtab27[1][(i * 16) + j] ^ sym1v[j]; + metsv[j] = 1 - metsvm[j]; + } + } + else if (symbols[second_symbol] == 2) { + for (int j = 0; j < 16; j++) { + // metsvm[j] = d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; + metsvm[j] = d_brtab27[0][(i * 16) + j] ^ sym0v[j]; + metsv[j] = 1 - metsvm[j]; + } + } + else { + for (int j = 0; j < 16; j++) { + // metsvm[j] = (d_branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + + // (d_branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); + metsvm[j] = (d_brtab27[0][(i * 16) + j] ^ sym0v[j]) + + (d_brtab27[1][(i * 16) + j] ^ sym1v[j]); + metsv[j] = 2 - metsvm[j]; + } + } + + for (int j = 0; j < 16; j++) { + m0[j] = metric0[(i * 16) + j] + metsv[j]; + m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j]; + m2[j] = metric0[(i * 16) + j] + metsvm[j]; + m3[j] = metric0[((i + 2) * 16) + j] + metsv[j]; + } + + for (int j = 0; j < 16; j++) { + decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; + decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; + survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); + survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); + } + + for (int j = 0; j < 16; j += 2) { + simd_epi16 = path0[(i * 16) + j]; + simd_epi16 |= path0[(i * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift0[j] = simd_epi16; + shift0[j + 1] = simd_epi16 >> 8; + + simd_epi16 = path0[((i + 2) * 16) + j]; + simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift1[j] = simd_epi16; + shift1[j + 1] = simd_epi16 >> 8; + } + for (int j = 0; j < 16; j++) { + shift1[j] = shift1[j] + 1; + } + + for (int j = 0, k = 0; j < 16; j += 2, k++) { + metric1[(2 * i * 16) + j] = survivor0[k]; + metric1[(2 * i * 16) + (j + 1)] = survivor1[k]; + } + for (int j = 0; j < 16; j++) { + tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); + } + + for (int j = 0, k = 8; j < 16; j += 2, k++) { + metric1[((2 * i + 1) * 16) + j] = survivor0[k]; + metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k]; + } + for (int j = 0; j < 16; j++) { + tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); + } + + for (int j = 0, k = 0; j < 16; j += 2, k++) { + path1[(2 * i * 16) + j] = tmp0[k]; + path1[(2 * i * 16) + (j + 1)] = tmp1[k]; + } + for (int j = 0, k = 8; j < 16; j += 2, k++) { + path1[((2 * i + 1) * 16) + j] = tmp0[k]; + path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k]; + } + } + + // Set up for the second two symbols (2 and 3) + metric0 = mm1; + path0 = pp1; + metric1 = mm0; + path1 = pp0; + first_symbol = 2; + second_symbol = first_symbol + 1; + for (int j = 0; j < 16; j++) { + sym0v[j] = symbols[first_symbol]; + sym1v[j] = symbols[second_symbol]; + } + } + } // END of call to viterbi_butterfly2_generic + viterbi_butterfly_calls++; // Do not increment until after the comparison code. + + if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 + unsigned char c; + // Find current best path + // + // INPUTS/OUTPUTS: + // RET_VAL : (ignored) + // mm0 : INPUT/OUTPUT : Array [ 64 ] + // mm1 : INPUT/OUTPUT : Array [ 64 ] + // pp0 : INPUT/OUTPUT : Array [ 64 ] + // pp1 : INPUT/OUTPUT : Array [ 64 ] + // ntraceback : INPUT : int (I think effectively const for given run + // type; here 5 I think) outbuf : OUTPUT : 1 byte l_store_pos : + // GLOBAL IN/OUT : int (position in circular traceback buffer?) + + // l_mmresult : GLOBAL OUTPUT : Array [ 64 bytes ] + // l_ppresult : GLOBAL OUTPUT : Array [ntraceback][ 64 bytes ] + + // CALL : viterbi_get_output_generic(l_metric0_generic, l_path0_generic, + // in_ntraceback, &c); unsigned char viterbi_get_output_generic(unsigned char *mm0, + // unsigned char *pp0, int ntraceback, unsigned char *outbuf) + { + unsigned char *mm0 = l_metric0_generic; + unsigned char *pp0 = l_path0_generic; + int ntraceback = in_ntraceback; + unsigned char *outbuf = &c; + + int i; + int bestmetric, minmetric; + int beststate = 0; + int pos = 0; + int j; + + // circular buffer with the last ntraceback paths + l_store_pos = (l_store_pos + 1) % ntraceback; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 16; j++) { + l_mmresult[(i * 16) + j] = mm0[(i * 16) + j]; + l_ppresult[l_store_pos][(i * 16) + j] = pp0[(i * 16) + j]; + } + } + + // Find out the best final state + bestmetric = l_mmresult[beststate]; + minmetric = l_mmresult[beststate]; + + for (i = 1; i < 64; i++) { + if (l_mmresult[i] > bestmetric) { + bestmetric = l_mmresult[i]; + beststate = i; + } + if (l_mmresult[i] < minmetric) { minmetric = l_mmresult[i]; } + } + + // Trace back + for (i = 0, pos = l_store_pos; i < (ntraceback - 1); i++) { + // Obtain the state from the output bits + // by clocking in the output bits in reverse order. + // The state has only 6 bits + beststate = l_ppresult[pos][beststate] >> 2; + pos = (pos - 1 + ntraceback) % ntraceback; + } + + // Store output byte + *outbuf = l_ppresult[pos][beststate]; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 16; j++) { + pp0[(i * 16) + j] = 0; + mm0[(i * 16) + j] = mm0[(i * 16) + j] - minmetric; + } + } + + // return bestmetric; + } + + // std::cout << "OUTPUT: " << (unsigned int)c << std::endl; + if (out_count >= in_ntraceback) { + for (int i = 0; i < 8; i++) { + l_decoded[(out_count - in_ntraceback) * 8 + i] = (c >> (7 - i)) & 0x1; + /* if (n_decoded < 16) { */ + /* printf("l_decoded[ %u ] written as %u\n", (out_count - in_ntraceback) * + * 8 + i, l_decoded[(out_count - in_ntraceback) * 8 + i]); */ + /* } */ + n_decoded++; + } + } + out_count++; + } + } + in_count++; } - printf("\n"); - printf("\n"); - }); + VERBOSE(if (1) { + printf("\nVBS: Final l_decoded : %p\n", l_decoded); + int per_row = 0; + printf("%p : ", &l_decoded[0]); + for (int ti = 0; ti < (MAX_ENCODED_BITS * 3 / 4); ti++) { + per_row++; + if ((per_row % 8) == 0) { printf(" "); } + printf("%u", l_decoded[ti]); + if (per_row == 39) { + printf("\n"); + printf("%p : ", &l_decoded[ti]); + per_row = 0; + } + } + printf("\n"); + printf("\n"); + }); } - diff --git a/accelerators/stratus_hls/vitdodec_stratus/sw/linux/driver/vitdodec_stratus.c b/accelerators/stratus_hls/vitdodec_stratus/sw/linux/driver/vitdodec_stratus.c index 59942840e9..86e17dd4ba 100644 --- a/accelerators/stratus_hls/vitdodec_stratus/sw/linux/driver/vitdodec_stratus.c +++ b/accelerators/stratus_hls/vitdodec_stratus/sw/linux/driver/vitdodec_stratus.c @@ -1,133 +1,125 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include "vitdodec_stratus.h" -#define DRV_NAME "vitdodec_stratus" +#define DRV_NAME "vitdodec_stratus" /* <<--regs-->> */ -#define VITDODEC_CBPS_REG 0x48 +#define VITDODEC_CBPS_REG 0x48 #define VITDODEC_NTRACEBACK_REG 0x44 -#define VITDODEC_DATA_BITS_REG 0x40 +#define VITDODEC_DATA_BITS_REG 0x40 struct vitdodec_stratus_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver vitdodec_driver; static struct of_device_id vitdodec_device_ids[] = { - { - .name = "SLD_VITDODEC_STRATUS", - }, - { - .name = "eb_030", - }, - { - .compatible = "sld,vitdodec_stratus", - }, - { }, + { + .name = "SLD_VITDODEC_STRATUS", + }, + { + .name = "eb_030", + }, + { + .compatible = "sld,vitdodec_stratus", + }, + {}, }; static int vitdodec_devs; static inline struct vitdodec_stratus_device *to_vitdodec(struct esp_device *esp) { - return container_of(esp, struct vitdodec_stratus_device, esp); + return container_of(esp, struct vitdodec_stratus_device, esp); } static void vitdodec_prep_xfer(struct esp_device *esp, void *arg) { - struct vitdodec_stratus_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->cbps, esp->iomem + VITDODEC_CBPS_REG); - iowrite32be(a->ntraceback, esp->iomem + VITDODEC_NTRACEBACK_REG); - iowrite32be(a->data_bits, esp->iomem + VITDODEC_DATA_BITS_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); - + struct vitdodec_stratus_access *a = arg; + + /* <<--regs-config-->> */ + iowrite32be(a->cbps, esp->iomem + VITDODEC_CBPS_REG); + iowrite32be(a->ntraceback, esp->iomem + VITDODEC_NTRACEBACK_REG); + iowrite32be(a->data_bits, esp->iomem + VITDODEC_DATA_BITS_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool vitdodec_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct vitdodec_stratus_device *vitdodec = to_vitdodec(esp); */ - /* struct vitdodec_stratus_access *a = arg; */ + /* struct vitdodec_stratus_device *vitdodec = to_vitdodec(esp); */ + /* struct vitdodec_stratus_access *a = arg; */ - return true; + return true; } static int vitdodec_probe(struct platform_device *pdev) { - struct vitdodec_stratus_device *vitdodec; - struct esp_device *esp; - int rc; - - vitdodec = kzalloc(sizeof(*vitdodec), GFP_KERNEL); - if (vitdodec == NULL) - return -ENOMEM; - esp = &vitdodec->esp; - esp->module = THIS_MODULE; - esp->number = vitdodec_devs; - esp->driver = &vitdodec_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - vitdodec_devs++; - return 0; - err: - kfree(vitdodec); - return rc; + struct vitdodec_stratus_device *vitdodec; + struct esp_device *esp; + int rc; + + vitdodec = kzalloc(sizeof(*vitdodec), GFP_KERNEL); + if (vitdodec == NULL) return -ENOMEM; + esp = &vitdodec->esp; + esp->module = THIS_MODULE; + esp->number = vitdodec_devs; + esp->driver = &vitdodec_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + vitdodec_devs++; + return 0; +err: + kfree(vitdodec); + return rc; } static int __exit vitdodec_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct vitdodec_stratus_device *vitdodec = to_vitdodec(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct vitdodec_stratus_device *vitdodec = to_vitdodec(esp); - esp_device_unregister(esp); - kfree(vitdodec); - return 0; + esp_device_unregister(esp); + kfree(vitdodec); + return 0; } static struct esp_driver vitdodec_driver = { - .plat = { - .probe = vitdodec_probe, - .remove = vitdodec_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = vitdodec_device_ids, - }, - }, - .xfer_input_ok = vitdodec_xfer_input_ok, - .prep_xfer = vitdodec_prep_xfer, - .ioctl_cm = VITDODEC_STRATUS_IOC_ACCESS, - .arg_size = sizeof(struct vitdodec_stratus_access), + .plat = + { + .probe = vitdodec_probe, + .remove = vitdodec_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = vitdodec_device_ids, + }, + }, + .xfer_input_ok = vitdodec_xfer_input_ok, + .prep_xfer = vitdodec_prep_xfer, + .ioctl_cm = VITDODEC_STRATUS_IOC_ACCESS, + .arg_size = sizeof(struct vitdodec_stratus_access), }; -static int __init vitdodec_init(void) -{ - return esp_driver_register(&vitdodec_driver); -} +static int __init vitdodec_init(void) { return esp_driver_register(&vitdodec_driver); } -static void __exit vitdodec_exit(void) -{ - esp_driver_unregister(&vitdodec_driver); -} +static void __exit vitdodec_exit(void) { esp_driver_unregister(&vitdodec_driver); } -module_init(vitdodec_init) -module_exit(vitdodec_exit) +module_init(vitdodec_init) module_exit(vitdodec_exit) -MODULE_DEVICE_TABLE(of, vitdodec_device_ids); + MODULE_DEVICE_TABLE(of, vitdodec_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/stratus_hls/vitdodec_stratus/sw/linux/include/vitdodec_stratus.h b/accelerators/stratus_hls/vitdodec_stratus/sw/linux/include/vitdodec_stratus.h index eade37b6fd..80ef8d74a1 100644 --- a/accelerators/stratus_hls/vitdodec_stratus/sw/linux/include/vitdodec_stratus.h +++ b/accelerators/stratus_hls/vitdodec_stratus/sw/linux/include/vitdodec_stratus.h @@ -4,29 +4,29 @@ #define _VITDODEC_STRATUS_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct vitdodec_stratus_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned cbps; - unsigned ntraceback; - unsigned data_bits; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned cbps; + unsigned ntraceback; + unsigned data_bits; + unsigned src_offset; + unsigned dst_offset; }; -#define VITDODEC_STRATUS_IOC_ACCESS _IOW ('S', 0, struct vitdodec_stratus_access) +#define VITDODEC_STRATUS_IOC_ACCESS _IOW('S', 0, struct vitdodec_stratus_access) #endif /* _VITDODEC_STRATUS_H_ */ diff --git a/accelerators/third-party/NV_NVDLA/NV_NVDLA_wrapper.v b/accelerators/third-party/NV_NVDLA/NV_NVDLA_wrapper.v index 4a69e23c0d..48e4a5a7ae 100644 --- a/accelerators/third-party/NV_NVDLA/NV_NVDLA_wrapper.v +++ b/accelerators/third-party/NV_NVDLA/NV_NVDLA_wrapper.v @@ -1,246 +1,243 @@ // File Name: NV_NVDLA_wrapper.v -module NV_NVDLA_wrapper - ( - dla_core_clk, - dla_csb_clk, - dla_reset_rstn, - direct_reset, - paddr, - penable, - psel, - pwdata, - pwrite, - prdata, - pready, - pslverr, - nvdla_core2dbb_awvalid, - nvdla_core2dbb_awready, - nvdla_core2dbb_awid, - nvdla_core2dbb_awlen, - nvdla_core2dbb_awaddr, - nvdla_core2dbb_wvalid, - nvdla_core2dbb_wready, - nvdla_core2dbb_wdata, - nvdla_core2dbb_wstrb, - nvdla_core2dbb_wlast, - nvdla_core2dbb_arvalid, - nvdla_core2dbb_arready, - nvdla_core2dbb_arid, - nvdla_core2dbb_arlen, - nvdla_core2dbb_araddr, - nvdla_core2dbb_bresp, - nvdla_core2dbb_bvalid, - nvdla_core2dbb_bready, - nvdla_core2dbb_bid, - nvdla_core2dbb_rvalid, - nvdla_core2dbb_rready, - nvdla_core2dbb_rid, - nvdla_core2dbb_rlast, - nvdla_core2dbb_rdata, - nvdla_core2dbb_rresp, - nvdla_core2dbb_awsize, - nvdla_core2dbb_arsize, - nvdla_core2dbb_awburst, - nvdla_core2dbb_arburst, - nvdla_core2dbb_awlock, - nvdla_core2dbb_arlock, - nvdla_core2dbb_awcache, - nvdla_core2dbb_arcache, - nvdla_core2dbb_awprot, - nvdla_core2dbb_arprot, - nvdla_core2dbb_awqos, - nvdla_core2dbb_awatop, - nvdla_core2dbb_awregion, - nvdla_core2dbb_arqos, - nvdla_core2dbb_arregion, - dla_intr - ); +module NV_NVDLA_wrapper ( + dla_core_clk, + dla_csb_clk, + dla_reset_rstn, + direct_reset, + paddr, + penable, + psel, + pwdata, + pwrite, + prdata, + pready, + pslverr, + nvdla_core2dbb_awvalid, + nvdla_core2dbb_awready, + nvdla_core2dbb_awid, + nvdla_core2dbb_awlen, + nvdla_core2dbb_awaddr, + nvdla_core2dbb_wvalid, + nvdla_core2dbb_wready, + nvdla_core2dbb_wdata, + nvdla_core2dbb_wstrb, + nvdla_core2dbb_wlast, + nvdla_core2dbb_arvalid, + nvdla_core2dbb_arready, + nvdla_core2dbb_arid, + nvdla_core2dbb_arlen, + nvdla_core2dbb_araddr, + nvdla_core2dbb_bresp, + nvdla_core2dbb_bvalid, + nvdla_core2dbb_bready, + nvdla_core2dbb_bid, + nvdla_core2dbb_rvalid, + nvdla_core2dbb_rready, + nvdla_core2dbb_rid, + nvdla_core2dbb_rlast, + nvdla_core2dbb_rdata, + nvdla_core2dbb_rresp, + nvdla_core2dbb_awsize, + nvdla_core2dbb_arsize, + nvdla_core2dbb_awburst, + nvdla_core2dbb_arburst, + nvdla_core2dbb_awlock, + nvdla_core2dbb_arlock, + nvdla_core2dbb_awcache, + nvdla_core2dbb_arcache, + nvdla_core2dbb_awprot, + nvdla_core2dbb_arprot, + nvdla_core2dbb_awqos, + nvdla_core2dbb_awatop, + nvdla_core2dbb_awregion, + nvdla_core2dbb_arqos, + nvdla_core2dbb_arregion, + dla_intr +); - //////////////////////////////////////////////////////////////////////////////// - input dla_core_clk; - input dla_csb_clk; - input dla_reset_rstn; - input direct_reset; - //apb - input psel; - input penable; - input pwrite; - input [31:0] paddr; - input [31:0] pwdata; - output [31:0] prdata; - output pready; - output pslverr; - /////////////// - output wire nvdla_core2dbb_awvalid; - input wire nvdla_core2dbb_awready; - output wire [7:0] nvdla_core2dbb_awid; - output wire [7:0] nvdla_core2dbb_awlen; - output wire [32 -1:0] nvdla_core2dbb_awaddr; - output wire nvdla_core2dbb_wvalid; - input wire nvdla_core2dbb_wready; - output wire [64 -1:0] nvdla_core2dbb_wdata; - output wire [64/8-1:0] nvdla_core2dbb_wstrb; - output wire nvdla_core2dbb_wlast; - output wire nvdla_core2dbb_arvalid; - input wire nvdla_core2dbb_arready; - output wire [7:0] nvdla_core2dbb_arid; - output wire [7:0] nvdla_core2dbb_arlen; - output wire [32 -1:0] nvdla_core2dbb_araddr; - input wire [1:0] nvdla_core2dbb_bresp; - input wire nvdla_core2dbb_bvalid; - output wire nvdla_core2dbb_bready; - input wire [7:0] nvdla_core2dbb_bid; - input wire nvdla_core2dbb_rvalid; - output wire nvdla_core2dbb_rready; - input wire [7:0] nvdla_core2dbb_rid; - input wire nvdla_core2dbb_rlast; - input wire [64 -1:0] nvdla_core2dbb_rdata; - input wire [1:0] nvdla_core2dbb_rresp; - output wire [2:0] nvdla_core2dbb_awsize; - output wire [2:0] nvdla_core2dbb_arsize; - output wire [1:0] nvdla_core2dbb_awburst; - output wire [1:0] nvdla_core2dbb_arburst; - output wire nvdla_core2dbb_awlock; - output wire nvdla_core2dbb_arlock; - output wire [3:0] nvdla_core2dbb_awcache; - output wire [3:0] nvdla_core2dbb_arcache; - output wire [2:0] nvdla_core2dbb_awprot; - output wire [2:0] nvdla_core2dbb_arprot; - output wire [3:0] nvdla_core2dbb_awqos; - output wire [5:0] nvdla_core2dbb_awatop; - output wire [3:0] nvdla_core2dbb_awregion; - output wire [3:0] nvdla_core2dbb_arqos; - output wire [3:0] nvdla_core2dbb_arregion; - /////////////// - output dla_intr; - //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + input dla_core_clk; + input dla_csb_clk; + input dla_reset_rstn; + input direct_reset; + //apb + input psel; + input penable; + input pwrite; + input [31:0] paddr; + input [31:0] pwdata; + output [31:0] prdata; + output pready; + output pslverr; + /////////////// + output wire nvdla_core2dbb_awvalid; + input wire nvdla_core2dbb_awready; + output wire [7:0] nvdla_core2dbb_awid; + output wire [7:0] nvdla_core2dbb_awlen; + output wire [32 -1:0] nvdla_core2dbb_awaddr; + output wire nvdla_core2dbb_wvalid; + input wire nvdla_core2dbb_wready; + output wire [64 -1:0] nvdla_core2dbb_wdata; + output wire [64/8-1:0] nvdla_core2dbb_wstrb; + output wire nvdla_core2dbb_wlast; + output wire nvdla_core2dbb_arvalid; + input wire nvdla_core2dbb_arready; + output wire [7:0] nvdla_core2dbb_arid; + output wire [7:0] nvdla_core2dbb_arlen; + output wire [32 -1:0] nvdla_core2dbb_araddr; + input wire [1:0] nvdla_core2dbb_bresp; + input wire nvdla_core2dbb_bvalid; + output wire nvdla_core2dbb_bready; + input wire [7:0] nvdla_core2dbb_bid; + input wire nvdla_core2dbb_rvalid; + output wire nvdla_core2dbb_rready; + input wire [7:0] nvdla_core2dbb_rid; + input wire nvdla_core2dbb_rlast; + input wire [64 -1:0] nvdla_core2dbb_rdata; + input wire [1:0] nvdla_core2dbb_rresp; + output wire [2:0] nvdla_core2dbb_awsize; + output wire [2:0] nvdla_core2dbb_arsize; + output wire [1:0] nvdla_core2dbb_awburst; + output wire [1:0] nvdla_core2dbb_arburst; + output wire nvdla_core2dbb_awlock; + output wire nvdla_core2dbb_arlock; + output wire [3:0] nvdla_core2dbb_awcache; + output wire [3:0] nvdla_core2dbb_arcache; + output wire [2:0] nvdla_core2dbb_awprot; + output wire [2:0] nvdla_core2dbb_arprot; + output wire [3:0] nvdla_core2dbb_awqos; + output wire [5:0] nvdla_core2dbb_awatop; + output wire [3:0] nvdla_core2dbb_awregion; + output wire [3:0] nvdla_core2dbb_arqos; + output wire [3:0] nvdla_core2dbb_arregion; + /////////////// + output dla_intr; + //////////////////////////////////////////////////////////////////////////////// - // CSB connections - wire csb2nvdla_valid; - wire csb2nvdla_ready; - wire [15:0] csb2nvdla_addr; - wire [31:0] csb2nvdla_wdat; - wire csb2nvdla_write; - wire csb2nvdla_nposted; - wire nvdla2csb_valid; - wire [31:0] nvdla2csb_data; - // NVDLA ports not used - wire global_clk_ovr_on; - wire tmc2slcg_disable_clock_gating; - wire test_mode; - wire nvdla2csb_wr_complete; - wire [31:0] nvdla_pwrbus_ram_c_pd; - wire [31:0] nvdla_pwrbus_ram_ma_pd; - wire [31:0] nvdla_pwrbus_ram_mb_pd; - wire [31:0] nvdla_pwrbus_ram_p_pd; - wire [31:0] nvdla_pwrbus_ram_o_pd; - wire [31:0] nvdla_pwrbus_ram_a_pd; - /////////////// + // CSB connections + wire csb2nvdla_valid; + wire csb2nvdla_ready; + wire [15:0] csb2nvdla_addr; + wire [31:0] csb2nvdla_wdat; + wire csb2nvdla_write; + wire csb2nvdla_nposted; + wire nvdla2csb_valid; + wire [31:0] nvdla2csb_data; + // NVDLA ports not used + wire global_clk_ovr_on; + wire tmc2slcg_disable_clock_gating; + wire test_mode; + wire nvdla2csb_wr_complete; + wire [31:0] nvdla_pwrbus_ram_c_pd; + wire [31:0] nvdla_pwrbus_ram_ma_pd; + wire [31:0] nvdla_pwrbus_ram_mb_pd; + wire [31:0] nvdla_pwrbus_ram_p_pd; + wire [31:0] nvdla_pwrbus_ram_o_pd; + wire [31:0] nvdla_pwrbus_ram_a_pd; + /////////////// - // set NVDLA ports not used - assign global_clk_ovr_on = 1'b0; - assign tmc2slcg_disable_clock_gating = 1'b0; - assign test_mode = 1'b0; - assign nvdla_pwrbus_ram_c_pd = 32'b0; - assign nvdla_pwrbus_ram_ma_pd = 32'b0; - assign nvdla_pwrbus_ram_mb_pd = 32'b0; - assign nvdla_pwrbus_ram_p_pd = 32'b0; - assign nvdla_pwrbus_ram_o_pd = 32'b0; - assign nvdla_pwrbus_ram_a_pd = 32'b0; - assign pslverr = 1'b0; - - // map NVDLA dbb channel to an AXI channel - // set AXI channel ports not present on the NVDLA interface - assign nvdla_core2dbb_awsize = 3'b011; - assign nvdla_core2dbb_arsize = 3'b011; - assign nvdla_core2dbb_awburst = 2'b01; - assign nvdla_core2dbb_arburst = 2'b01; - assign nvdla_core2dbb_awlock = 1'b0; - assign nvdla_core2dbb_arlock = 1'b0; - assign nvdla_core2dbb_awcache = 4'b0011; - assign nvdla_core2dbb_arcache = 4'b0011; - assign nvdla_core2dbb_awprot = 3'b010; - assign nvdla_core2dbb_arprot = 3'b010; - assign nvdla_core2dbb_awqos = 4'b0000; - assign nvdla_core2dbb_arqos = 4'b0000; - assign nvdla_core2dbb_awatop = 6'b000000; - assign nvdla_core2dbb_awregion = 4'b0000; - assign nvdla_core2dbb_arregion = 4'b0000; + // set NVDLA ports not used + assign global_clk_ovr_on = 1'b0; + assign tmc2slcg_disable_clock_gating = 1'b0; + assign test_mode = 1'b0; + assign nvdla_pwrbus_ram_c_pd = 32'b0; + assign nvdla_pwrbus_ram_ma_pd = 32'b0; + assign nvdla_pwrbus_ram_mb_pd = 32'b0; + assign nvdla_pwrbus_ram_p_pd = 32'b0; + assign nvdla_pwrbus_ram_o_pd = 32'b0; + assign nvdla_pwrbus_ram_a_pd = 32'b0; + assign pslverr = 1'b0; - assign nvdla_core2dbb_awlen[7:4] = 4'b0000; - assign nvdla_core2dbb_arlen[7:4] = 4'b0000; + // map NVDLA dbb channel to an AXI channel + // set AXI channel ports not present on the NVDLA interface + assign nvdla_core2dbb_awsize = 3'b011; + assign nvdla_core2dbb_arsize = 3'b011; + assign nvdla_core2dbb_awburst = 2'b01; + assign nvdla_core2dbb_arburst = 2'b01; + assign nvdla_core2dbb_awlock = 1'b0; + assign nvdla_core2dbb_arlock = 1'b0; + assign nvdla_core2dbb_awcache = 4'b0011; + assign nvdla_core2dbb_arcache = 4'b0011; + assign nvdla_core2dbb_awprot = 3'b010; + assign nvdla_core2dbb_arprot = 3'b010; + assign nvdla_core2dbb_awqos = 4'b0000; + assign nvdla_core2dbb_arqos = 4'b0000; + assign nvdla_core2dbb_awatop = 6'b000000; + assign nvdla_core2dbb_awregion = 4'b0000; + assign nvdla_core2dbb_arregion = 4'b0000; - NV_nvdla NV_nvdla_0 - ( - .dla_core_clk(dla_core_clk) //|< i - ,.dla_csb_clk(dla_csb_clk) //|< i - ,.global_clk_ovr_on(global_clk_ovr_on) //|< i - ,.tmc2slcg_disable_clock_gating(tmc2slcg_disable_clock_gating) //|< i - ,.dla_reset_rstn(dla_reset_rstn) //|< i - ,.direct_reset_(direct_reset) //|< i - ,.test_mode(test_mode) //|< i - ,.csb2nvdla_valid(csb2nvdla_valid) //|< i - ,.csb2nvdla_ready(csb2nvdla_ready) //|> o - ,.csb2nvdla_addr(csb2nvdla_addr) //|< i - ,.csb2nvdla_wdat(csb2nvdla_wdat) //|< i - ,.csb2nvdla_write(csb2nvdla_write) //|< i - ,.csb2nvdla_nposted(csb2nvdla_nposted) //|< i - ,.nvdla2csb_valid(nvdla2csb_valid) //|> o - ,.nvdla2csb_data(nvdla2csb_data) //|> o - ,.nvdla2csb_wr_complete() //|> o - ,.nvdla_core2dbb_aw_awvalid(nvdla_core2dbb_awvalid) //|> o - ,.nvdla_core2dbb_aw_awready(nvdla_core2dbb_awready) //|< i - ,.nvdla_core2dbb_aw_awid(nvdla_core2dbb_awid) //|> o - ,.nvdla_core2dbb_aw_awlen(nvdla_core2dbb_awlen[3:0]) //|> o - ,.nvdla_core2dbb_aw_awaddr(nvdla_core2dbb_awaddr) //|> o - ,.nvdla_core2dbb_w_wvalid(nvdla_core2dbb_wvalid) //|> o - ,.nvdla_core2dbb_w_wready(nvdla_core2dbb_wready) //|< i - ,.nvdla_core2dbb_w_wdata(nvdla_core2dbb_wdata) //|> o - ,.nvdla_core2dbb_w_wstrb(nvdla_core2dbb_wstrb) //|> o - ,.nvdla_core2dbb_w_wlast(nvdla_core2dbb_wlast) //|> o - ,.nvdla_core2dbb_b_bvalid(nvdla_core2dbb_bvalid) //|< i - ,.nvdla_core2dbb_b_bready(nvdla_core2dbb_bready) //|> o - ,.nvdla_core2dbb_b_bid(nvdla_core2dbb_bid) //|< i - ,.nvdla_core2dbb_ar_arvalid(nvdla_core2dbb_arvalid) //|> o - ,.nvdla_core2dbb_ar_arready(nvdla_core2dbb_arready) //|< i - ,.nvdla_core2dbb_ar_arid(nvdla_core2dbb_arid) //|> o - ,.nvdla_core2dbb_ar_arlen(nvdla_core2dbb_arlen[3:0]) //|> o - ,.nvdla_core2dbb_ar_araddr(nvdla_core2dbb_araddr) //|> o - ,.nvdla_core2dbb_r_rvalid(nvdla_core2dbb_rvalid) //|< i - ,.nvdla_core2dbb_r_rready(nvdla_core2dbb_rready) //|> o - ,.nvdla_core2dbb_r_rid(nvdla_core2dbb_rid) //|< i - ,.nvdla_core2dbb_r_rlast(nvdla_core2dbb_rlast) //|< i - ,.nvdla_core2dbb_r_rdata(nvdla_core2dbb_rdata) //|< i - ,.dla_intr(dla_intr) //|> o - ,.nvdla_pwrbus_ram_c_pd(nvdla_pwrbus_ram_c_pd) //|< i - ,.nvdla_pwrbus_ram_ma_pd(nvdla_pwrbus_ram_ma_pd) //|< i * - ,.nvdla_pwrbus_ram_mb_pd(nvdla_pwrbus_ram_mb_pd) //|< i * - ,.nvdla_pwrbus_ram_p_pd(nvdla_pwrbus_ram_p_pd) //|< i - ,.nvdla_pwrbus_ram_o_pd(nvdla_pwrbus_ram_o_pd) //|< i - ,.nvdla_pwrbus_ram_a_pd(nvdla_pwrbus_ram_a_pd) //|< i - ); + assign nvdla_core2dbb_awlen[7:4] = 4'b0000; + assign nvdla_core2dbb_arlen[7:4] = 4'b0000; + + NV_nvdla NV_nvdla_0 ( + .dla_core_clk(dla_core_clk) //|< i + , .dla_csb_clk(dla_csb_clk) //|< i + , .global_clk_ovr_on(global_clk_ovr_on) //|< i + , .tmc2slcg_disable_clock_gating(tmc2slcg_disable_clock_gating) //|< i + , .dla_reset_rstn(dla_reset_rstn) //|< i + , .direct_reset_(direct_reset) //|< i + , .test_mode(test_mode) //|< i + , .csb2nvdla_valid(csb2nvdla_valid) //|< i + , .csb2nvdla_ready(csb2nvdla_ready) //|> o + , .csb2nvdla_addr(csb2nvdla_addr) //|< i + , .csb2nvdla_wdat(csb2nvdla_wdat) //|< i + , .csb2nvdla_write(csb2nvdla_write) //|< i + , .csb2nvdla_nposted(csb2nvdla_nposted) //|< i + , .nvdla2csb_valid(nvdla2csb_valid) //|> o + , .nvdla2csb_data(nvdla2csb_data) //|> o + , .nvdla2csb_wr_complete() //|> o + , .nvdla_core2dbb_aw_awvalid(nvdla_core2dbb_awvalid) //|> o + , .nvdla_core2dbb_aw_awready(nvdla_core2dbb_awready) //|< i + , .nvdla_core2dbb_aw_awid(nvdla_core2dbb_awid) //|> o + , .nvdla_core2dbb_aw_awlen(nvdla_core2dbb_awlen[3:0]) //|> o + , .nvdla_core2dbb_aw_awaddr(nvdla_core2dbb_awaddr) //|> o + , .nvdla_core2dbb_w_wvalid(nvdla_core2dbb_wvalid) //|> o + , .nvdla_core2dbb_w_wready(nvdla_core2dbb_wready) //|< i + , .nvdla_core2dbb_w_wdata(nvdla_core2dbb_wdata) //|> o + , .nvdla_core2dbb_w_wstrb(nvdla_core2dbb_wstrb) //|> o + , .nvdla_core2dbb_w_wlast(nvdla_core2dbb_wlast) //|> o + , .nvdla_core2dbb_b_bvalid(nvdla_core2dbb_bvalid) //|< i + , .nvdla_core2dbb_b_bready(nvdla_core2dbb_bready) //|> o + , .nvdla_core2dbb_b_bid(nvdla_core2dbb_bid) //|< i + , .nvdla_core2dbb_ar_arvalid(nvdla_core2dbb_arvalid) //|> o + , .nvdla_core2dbb_ar_arready(nvdla_core2dbb_arready) //|< i + , .nvdla_core2dbb_ar_arid(nvdla_core2dbb_arid) //|> o + , .nvdla_core2dbb_ar_arlen(nvdla_core2dbb_arlen[3:0]) //|> o + , .nvdla_core2dbb_ar_araddr(nvdla_core2dbb_araddr) //|> o + , .nvdla_core2dbb_r_rvalid(nvdla_core2dbb_rvalid) //|< i + , .nvdla_core2dbb_r_rready(nvdla_core2dbb_rready) //|> o + , .nvdla_core2dbb_r_rid(nvdla_core2dbb_rid) //|< i + , .nvdla_core2dbb_r_rlast(nvdla_core2dbb_rlast) //|< i + , .nvdla_core2dbb_r_rdata(nvdla_core2dbb_rdata) //|< i + , .dla_intr(dla_intr) //|> o + , .nvdla_pwrbus_ram_c_pd(nvdla_pwrbus_ram_c_pd) //|< i + , .nvdla_pwrbus_ram_ma_pd(nvdla_pwrbus_ram_ma_pd) //|< i * + , .nvdla_pwrbus_ram_mb_pd(nvdla_pwrbus_ram_mb_pd) //|< i * + , .nvdla_pwrbus_ram_p_pd(nvdla_pwrbus_ram_p_pd) //|< i + , .nvdla_pwrbus_ram_o_pd(nvdla_pwrbus_ram_o_pd) //|< i + , .nvdla_pwrbus_ram_a_pd(nvdla_pwrbus_ram_a_pd) //|< i + ); + + NV_NVDLA_apb2csb apb2csb_0 ( + .pclk(dla_csb_clk) + , .prstn(dla_reset_rstn) + , .csb2nvdla_ready(csb2nvdla_ready) + , .nvdla2csb_data(nvdla2csb_data) + , .nvdla2csb_valid(nvdla2csb_valid) + , .paddr(paddr) + , .penable(penable) + , .psel(psel) + , .pwdata(pwdata) + , .pwrite(pwrite) + , .csb2nvdla_addr(csb2nvdla_addr) + , .csb2nvdla_nposted(csb2nvdla_nposted) + , .csb2nvdla_valid(csb2nvdla_valid) + , .csb2nvdla_wdat(csb2nvdla_wdat) + , .csb2nvdla_write(csb2nvdla_write) + , .prdata(prdata) + , .pready(pready) + ); - NV_NVDLA_apb2csb apb2csb_0 - ( - .pclk(dla_csb_clk) - ,.prstn(dla_reset_rstn) - ,.csb2nvdla_ready(csb2nvdla_ready) - ,.nvdla2csb_data(nvdla2csb_data) - ,.nvdla2csb_valid(nvdla2csb_valid) - ,.paddr(paddr) - ,.penable(penable) - ,.psel(psel) - ,.pwdata(pwdata) - ,.pwrite(pwrite) - ,.csb2nvdla_addr(csb2nvdla_addr) - ,.csb2nvdla_nposted(csb2nvdla_nposted) - ,.csb2nvdla_valid(csb2nvdla_valid) - ,.csb2nvdla_wdat(csb2nvdla_wdat) - ,.csb2nvdla_write(csb2nvdla_write) - ,.prdata(prdata) - ,.pready(pready) - ); - endmodule diff --git a/accelerators/vivado_hls/adder_vivado/hw/inc/espacc.h b/accelerators/vivado_hls/adder_vivado/hw/inc/espacc.h index 11dc801df4..d0e538dc45 100644 --- a/accelerators/vivado_hls/adder_vivado/hw/inc/espacc.h +++ b/accelerators/vivado_hls/adder_vivado/hw/inc/espacc.h @@ -12,27 +12,27 @@ // Data types and constants #define VALUES_PER_WORD (DMA_SIZE / DATA_BITWIDTH) #if ((SIZE_IN_CHUNK_DATA % VALUES_PER_WORD) == 0) -#define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD) + #define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD) #else -#define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD + 1) + #define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD + 1) #endif #if ((SIZE_OUT_CHUNK_DATA % VALUES_PER_WORD) == 0) -#define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD) + #define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD) #else -#define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD + 1) + #define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD + 1) #endif // data word -#if (IS_TYPE_FIXED_POINT == 1) -typedef ap_fixed word_t; +#if (IS_TYPE_FIXED_POINT == 1) +typedef ap_fixed word_t; #elif (IS_TYPE_UINT == 1) typedef ap_uint word_t; #elif (IS_TYPE_FLOAT == 1) -#if (DATA_BITWIDTH == 32) + #if (DATA_BITWIDTH == 32) typedef float word_t; -#else -#error "Floating point word bitwidth not supported. Only 32 is supported." -#endif + #else + #error "Floating point word bitwidth not supported. Only 32 is supported." + #endif #else // (IS_TYPE_INT == 1) typedef ap_int word_t; #endif @@ -53,26 +53,24 @@ typedef struct dma_info { // The 'size' variable of 'dma_info' indicates the bit-width of the words // processed by the accelerator. Here are the encodings: -#define SIZE_BYTE 0 -#define SIZE_HWORD 1 -#define SIZE_WORD 2 -#define SIZE_DWORD 3 +#define SIZE_BYTE 0 +#define SIZE_HWORD 1 +#define SIZE_WORD 2 +#define SIZE_DWORD 3 #if (DATA_BITWIDTH == 8) -#define SIZE_WORD_T SIZE_BYTE + #define SIZE_WORD_T SIZE_BYTE #elif (DATA_BITWIDTH == 16) -#define SIZE_WORD_T SIZE_HWORD + #define SIZE_WORD_T SIZE_HWORD #elif (DATA_BITWIDTH == 32) -#define SIZE_WORD_T SIZE_WORD + #define SIZE_WORD_T SIZE_WORD #else // if (DATA_BITWIDTH == 64) -#define SIZE_WORD_T SIZE_DWORD + #define SIZE_WORD_T SIZE_DWORD #endif -void top(dma_word_t *out, dma_word_t *in1, - const unsigned conf_info_nbursts, - dma_info_t &load_ctrl, dma_info_t &store_ctrl); +void top(dma_word_t *out, dma_word_t *in1, const unsigned conf_info_nbursts, dma_info_t &load_ctrl, + dma_info_t &store_ctrl); -void compute(word_t _inbuff[SIZE_IN_CHUNK_DATA], - word_t _outbuff[SIZE_OUT_CHUNK_DATA]); +void compute(word_t _inbuff[SIZE_IN_CHUNK_DATA], word_t _outbuff[SIZE_OUT_CHUNK_DATA]); #endif diff --git a/accelerators/vivado_hls/adder_vivado/sw/baremetal/adder.c b/accelerators/vivado_hls/adder_vivado/sw/baremetal/adder.c index ffd2d1d3b7..44f0b7692e 100644 --- a/accelerators/vivado_hls/adder_vivado/sw/baremetal/adder.c +++ b/accelerators/vivado_hls/adder_vivado/sw/baremetal/adder.c @@ -6,18 +6,18 @@ * Select Scatter-Gather in ESP configuration */ -#include -#include #include #include #include +#include +#include ///////////////////////////////// // TODO include accelerators configuration header // instead of copying its content here // #include "espacc_config.h" // In/out arrays -#define SIZE_IN_CHUNK_DATA 64 +#define SIZE_IN_CHUNK_DATA 64 #define SIZE_OUT_CHUNK_DATA 32 ///////////////////////////////// @@ -25,9 +25,9 @@ // TODO read HLS config directly from the accelerator registers // instead of setting it here #ifndef __riscv -#define DMA_SIZE 32 + #define DMA_SIZE 32 #else -#define DMA_SIZE 64 + #define DMA_SIZE 64 #endif #define DATA_BITWIDTH 32 @@ -36,32 +36,30 @@ typedef int32_t word_t; ///////////////////////////////// // Specify accelerator type -#define SLD_ADDER 0x40 -#define DEV_NAME "sld,adder_vivado" +#define SLD_ADDER 0x40 +#define DEV_NAME "sld,adder_vivado" // Sizes -#define NINVOKE 4 -#define NBURSTS 4 -#define IN_SIZE_DATA (SIZE_IN_CHUNK_DATA * NBURSTS) +#define NINVOKE 4 +#define NBURSTS 4 +#define IN_SIZE_DATA (SIZE_IN_CHUNK_DATA * NBURSTS) #define OUT_SIZE_DATA (SIZE_OUT_CHUNK_DATA * NBURSTS) -#define IN_SIZE (IN_SIZE_DATA * sizeof(word_t)) -#define OUT_SIZE (OUT_SIZE_DATA * sizeof(word_t)) -#define SIZE_DATA (IN_SIZE_DATA + OUT_SIZE_DATA) -#define SIZE (IN_SIZE + OUT_SIZE) +#define IN_SIZE (IN_SIZE_DATA * sizeof(word_t)) +#define OUT_SIZE (OUT_SIZE_DATA * sizeof(word_t)) +#define SIZE_DATA (IN_SIZE_DATA + OUT_SIZE_DATA) +#define SIZE (IN_SIZE + OUT_SIZE) /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 9 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK ((SIZE % CHUNK_SIZE == 0) ? \ - (SIZE / CHUNK_SIZE) : \ - (SIZE / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK ((SIZE % CHUNK_SIZE == 0) ? (SIZE / CHUNK_SIZE) : (SIZE / CHUNK_SIZE) + 1) // User defined registers -#define NBURSTS_REG 0x40 +#define NBURSTS_REG 0x40 //#define VERBOSE -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { int n, k; int ndev; @@ -72,137 +70,139 @@ int main(int argc, char * argv[]) ndev = probe(&espdevs, VENDOR_SLD, SLD_ADDER, DEV_NAME); if (!ndev) { - printf("Error: device not found!"); - printf(DEV_NAME); - exit(EXIT_FAILURE); + printf("Error: device not found!"); + printf(DEV_NAME); + exit(EXIT_FAILURE); } for (n = 0; n < ndev; n++) { - for (k = 0; k < NINVOKE; ++k) { - - coherence = ACC_COH_NONE; - - struct esp_device *dev = &espdevs[n]; - int done; - int i; - unsigned **ptable = NULL; - word_t *mem; - unsigned errors = 0; - int scatter_gather = 1; - - printf("\n********************************\n"); - printf("Process input # "); - printf("%u\n", (unsigned) k); - - // Check access ok (TODO) - - // Check if scatter-gather DMA is disabled - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled; revert to contiguous buffer.\n"); - scatter_gather = 0; - } else { - printf(" -> scatter-gather DMA is enabled.\n"); - } - - if (scatter_gather) { - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { - printf(" Trying to allocate # chunks on # TLB available entries: \n"); - printf("%u\t%u\n", (unsigned) NCHUNK, (unsigned) ioread32(dev, PT_NCHUNK_MAX_REG)); - break; - } - } - - // Allocate memory (will be contiguos anyway in baremetal) - mem = aligned_malloc(SIZE); - printf(" memory buffer base-address = %lu\n", (unsigned long) mem); - - if (scatter_gather) { - // Allocate and populate page table - ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); - for (i = 0; i < NCHUNK; i++) - ptable[i] = (unsigned *) - &mem[i * (CHUNK_SIZE / sizeof(unsigned))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK); - } - - // Initialize input and output - for (i = 0; i < IN_SIZE_DATA; ++i) - mem[i] = i; - for (; i < SIZE_DATA; ++i) - mem[i] = 63; - - // Allocate memory for gold output - word_t *mem_gold; - mem_gold = aligned_malloc(OUT_SIZE); - printf(" memory buffer base-address = %lu\n", (unsigned long) mem_gold); - - // Populate memory for gold output - for (i = 0; i < OUT_SIZE_DATA; ++i) { - mem_gold[i] = mem[i*2] + mem[i*2+1]; - } - - // Configure device - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); - - if (scatter_gather) { - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - iowrite32(dev, SRC_OFFSET_REG, 0); - iowrite32(dev, DST_OFFSET_REG, 0); - } else { - iowrite32(dev, SRC_OFFSET_REG, (unsigned long) mem); - iowrite32(dev, DST_OFFSET_REG, (unsigned long) mem); - } - - // Accelerator-specific registers - iowrite32(dev, NBURSTS_REG, 4); - - // Flush for non-coherent DMA - esp_flush(coherence); - - // Start accelerator - printf(" Start..\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - done = 0; - - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - - iowrite32(dev, CMD_REG, 0x0); - printf(" Done\n"); - - /* Validation */ - printf(" validating...\n"); - - errors = 0; - for (i = 0; i < OUT_SIZE_DATA; i++) { - if (mem[i + IN_SIZE_DATA] != mem_gold[i]) { - errors++; - printf("ERROR: i mem mem_gold\n"); - printf("%d\n%lu\n%lu\n", i, mem[i + IN_SIZE_DATA], mem_gold[i]); - } else { + for (k = 0; k < NINVOKE; ++k) { + + coherence = ACC_COH_NONE; + + struct esp_device *dev = &espdevs[n]; + int done; + int i; + unsigned **ptable = NULL; + word_t *mem; + unsigned errors = 0; + int scatter_gather = 1; + + printf("\n********************************\n"); + printf("Process input # "); + printf("%u\n", (unsigned)k); + + // Check access ok (TODO) + + // Check if scatter-gather DMA is disabled + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled; revert to contiguous buffer.\n"); + scatter_gather = 0; + } + else { + printf(" -> scatter-gather DMA is enabled.\n"); + } + + if (scatter_gather) { + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK) { + printf(" Trying to allocate # chunks on # TLB available entries: \n"); + printf("%u\t%u\n", (unsigned)NCHUNK, + (unsigned)ioread32(dev, PT_NCHUNK_MAX_REG)); + break; + } + } + + // Allocate memory (will be contiguos anyway in baremetal) + mem = aligned_malloc(SIZE); + printf(" memory buffer base-address = %lu\n", (unsigned long)mem); + + if (scatter_gather) { + // Allocate and populate page table + ptable = aligned_malloc(NCHUNK * sizeof(unsigned *)); + for (i = 0; i < NCHUNK; i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(unsigned))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK); + } + + // Initialize input and output + for (i = 0; i < IN_SIZE_DATA; ++i) + mem[i] = i; + for (; i < SIZE_DATA; ++i) + mem[i] = 63; + + // Allocate memory for gold output + word_t *mem_gold; + mem_gold = aligned_malloc(OUT_SIZE); + printf(" memory buffer base-address = %lu\n", (unsigned long)mem_gold); + + // Populate memory for gold output + for (i = 0; i < OUT_SIZE_DATA; ++i) { + mem_gold[i] = mem[i * 2] + mem[i * 2 + 1]; + } + + // Configure device + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); + + if (scatter_gather) { + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + iowrite32(dev, SRC_OFFSET_REG, 0); + iowrite32(dev, DST_OFFSET_REG, 0); + } + else { + iowrite32(dev, SRC_OFFSET_REG, (unsigned long)mem); + iowrite32(dev, DST_OFFSET_REG, (unsigned long)mem); + } + + // Accelerator-specific registers + iowrite32(dev, NBURSTS_REG, 4); + + // Flush for non-coherent DMA + esp_flush(coherence); + + // Start accelerator + printf(" Start..\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + done = 0; + + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + + iowrite32(dev, CMD_REG, 0x0); + printf(" Done\n"); + + /* Validation */ + printf(" validating...\n"); + + errors = 0; + for (i = 0; i < OUT_SIZE_DATA; i++) { + if (mem[i + IN_SIZE_DATA] != mem_gold[i]) { + errors++; + printf("ERROR: i mem mem_gold\n"); + printf("%d\n%lu\n%lu\n", i, mem[i + IN_SIZE_DATA], mem_gold[i]); + } + else { #ifdef VERBOSE - printf("ERROR: i mem mem_gold\n"); - printf("%u\n%u\n%u\n", (uint32_t) i, (uint32_t) mem[i + IN_SIZE_DATA], - (uint32_t) mem_gold[i]); + printf("ERROR: i mem mem_gold\n"); + printf("%u\n%u\n%u\n", (uint32_t)i, (uint32_t)mem[i + IN_SIZE_DATA], + (uint32_t)mem_gold[i]); #endif - } - } - - if (!errors) { - printf("\n Test PASSED!\n"); - } else { - printf("\n Test FAILED. Number of errors: %d\n", errors); - } - } + } + } + + if (!errors) { printf("\n Test PASSED!\n"); } + else { + printf("\n Test FAILED. Number of errors: %d\n", errors); + } + } } return 0; diff --git a/accelerators/vivado_hls/adder_vivado/sw/linux/app/adder.c b/accelerators/vivado_hls/adder_vivado/sw/linux/app/adder.c index 6b890335c1..3e62f30c3d 100644 --- a/accelerators/vivado_hls/adder_vivado/sw/linux/app/adder.c +++ b/accelerators/vivado_hls/adder_vivado/sw/linux/app/adder.c @@ -1,36 +1,35 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 +#include #include +#include #include #include #include -#include -#include +#include #include #include #include -#include #define DEVNAME "/dev/adder_vivado.0" -#define NAME "adder_vivado" +#define NAME "adder_vivado" // Default command line arguments #define DEFAULT_NBURSTS 4 // TODO pass as command line argument and use it #define DEFAULT_NINVOKE 4 - ///////////////////////////////// // TODO include accelerators configuration header // instead of copying its content here // #include "espacc_config.h" #define IS_TYPE_FIXED_POINT 0 -#define FRAC_BITS 0 -#define IS_TYPE_UINT 0 -#define IS_TYPE_INT 1 +#define FRAC_BITS 0 +#define IS_TYPE_UINT 0 +#define IS_TYPE_INT 1 // In/out arrays -#define SIZE_IN_CHUNK_DATA 64 +#define SIZE_IN_CHUNK_DATA 64 #define SIZE_OUT_CHUNK_DATA 32 ///////////////////////////////// @@ -38,9 +37,9 @@ // TODO read HLS config directly from the accelerator registers // instead of setting it here #ifndef __riscv -#define DMA_SIZE 32 + #define DMA_SIZE 32 #else -#define DMA_SIZE 64 + #define DMA_SIZE 64 #endif #define DATA_BITWIDTH 32 @@ -49,235 +48,228 @@ // Define datatype // TODO this app currently doesn't support fixed point #if (DATA_BITWIDTH == 8) -#if (IS_TYPE_UINT == 1) + #if (IS_TYPE_UINT == 1) typedef uint8_t word_t; -#elif (IS_TYPE_INT == 1) + #elif (IS_TYPE_INT == 1) typedef int8_t word_t; -#else -// fixed point not supported right now -#endif + #else + // fixed point not supported right now + #endif #elif (DATA_BITWIDTH == 16) -#if (IS_TYPE_UINT == 1) + #if (IS_TYPE_UINT == 1) typedef uint16_t word_t; -#elif (IS_TYPE_INT == 1) + #elif (IS_TYPE_INT == 1) typedef int16_t word_t; -#else -// fixed point not supported right now -#endif + #else + // fixed point not supported right now + #endif #elif (DATA_BITWIDTH == 32) -#if (IS_TYPE_UINT == 1) + #if (IS_TYPE_UINT == 1) typedef uint32_t word_t; -#elif (IS_TYPE_INT == 1) + #elif (IS_TYPE_INT == 1) typedef int32_t word_t; -#else -// fixed point not supported right now -#endif + #else + // fixed point not supported right now + #endif #else // other bitwidths not supported right now #endif - static const char usage_str[] = - "usage: ./adder_vivado.exe coherence [size] [-v]\n" - " coherence: non-coh-dma|llc-coh-dma|coh-dma|coh\n" - "\n" - "Optional arguments:.\n" - " nbursts : # of memory bursts for 1 invocation of the accelerator. Default: 4\n" - "\n" - "The remaining option is only optional for 'test':\n" - " -v: enable verbose output for output-to-gold comparison\n"; + "usage: ./adder_vivado.exe coherence [size] [-v]\n" + " coherence: non-coh-dma|llc-coh-dma|coh-dma|coh\n" + "\n" + "Optional arguments:.\n" + " nbursts : # of memory bursts for 1 invocation of the accelerator. Default: 4\n" + "\n" + "The remaining option is only optional for 'test':\n" + " -v: enable verbose output for output-to-gold comparison\n"; struct adder_test { - struct test_info info; - struct adder_vivado_access desc; - unsigned int nbursts; - word_t *hbuf; - word_t *sbuf; - bool verbose; + struct test_info info; + struct adder_vivado_access desc; + unsigned int nbursts; + word_t *hbuf; + word_t *sbuf; + bool verbose; }; static inline struct adder_test *to_adder(struct test_info *info) { - return container_of(info, struct adder_test, info); + return container_of(info, struct adder_test, info); } -static int check_gold (word_t *gold, word_t *array, unsigned len, bool verbose) +static int check_gold(word_t *gold, word_t *array, unsigned len, bool verbose) { - int i; - int rtn = 0; - for (i = 0; i < len; i++) { - if ((array[i]) != gold[i]) { - if (verbose) - printf("A[%d]: array=%d; gold=%d\n", - i, array[i], gold[i]); - rtn++; - } - } - - return rtn; + int i; + int rtn = 0; + for (i = 0; i < len; i++) { + if ((array[i]) != gold[i]) { + if (verbose) printf("A[%d]: array=%d; gold=%d\n", i, array[i], gold[i]); + rtn++; + } + } + + return rtn; } -static void init_buf (struct adder_test *t) +static void init_buf(struct adder_test *t) { - // ======================== ^ - // | in | | input (in bytes) - // ======================== v - // | out | | output (in bytes) - // ======================== v - - printf("init buffers\n"); - - int i = 0; - - const unsigned IN_SIZE_DATA = (SIZE_IN_CHUNK_DATA * t->nbursts); - const unsigned OUT_SIZE_DATA = (SIZE_OUT_CHUNK_DATA * t->nbursts); - const unsigned SIZE_DATA = (IN_SIZE_DATA + OUT_SIZE_DATA); - - // Initialize input and output - for (i = 0; i < IN_SIZE_DATA; i++) { - t->hbuf[i] = i; - t->sbuf[i] = i; - } - for (; i < SIZE_DATA; i++) { - t->hbuf[i] = 10; - t->sbuf[i] = 10; - } + // ======================== ^ + // | in | | input (in bytes) + // ======================== v + // | out | | output (in bytes) + // ======================== v + + printf("init buffers\n"); + + int i = 0; + + const unsigned IN_SIZE_DATA = (SIZE_IN_CHUNK_DATA * t->nbursts); + const unsigned OUT_SIZE_DATA = (SIZE_OUT_CHUNK_DATA * t->nbursts); + const unsigned SIZE_DATA = (IN_SIZE_DATA + OUT_SIZE_DATA); + + // Initialize input and output + for (i = 0; i < IN_SIZE_DATA; i++) { + t->hbuf[i] = i; + t->sbuf[i] = i; + } + for (; i < SIZE_DATA; i++) { + t->hbuf[i] = 10; + t->sbuf[i] = 10; + } } static inline size_t adder_size(struct adder_test *t) { - const unsigned IN_SIZE_DATA = (SIZE_IN_CHUNK_DATA * t->nbursts); - const unsigned OUT_SIZE_DATA = (SIZE_OUT_CHUNK_DATA * t->nbursts); - const unsigned IN_SIZE = (IN_SIZE_DATA * sizeof(word_t)); - const unsigned OUT_SIZE = (OUT_SIZE_DATA * sizeof(word_t)); - const unsigned SIZE = (IN_SIZE + OUT_SIZE); + const unsigned IN_SIZE_DATA = (SIZE_IN_CHUNK_DATA * t->nbursts); + const unsigned OUT_SIZE_DATA = (SIZE_OUT_CHUNK_DATA * t->nbursts); + const unsigned IN_SIZE = (IN_SIZE_DATA * sizeof(word_t)); + const unsigned OUT_SIZE = (OUT_SIZE_DATA * sizeof(word_t)); + const unsigned SIZE = (IN_SIZE + OUT_SIZE); - return SIZE; + return SIZE; } static void adder_alloc_buf(struct test_info *info) { - struct adder_test *t = to_adder(info); + struct adder_test *t = to_adder(info); - t->hbuf = malloc0_check(adder_size(t)); - if (!strcmp(info->cmd, "test")) { - t->sbuf = malloc0_check(adder_size(t)); - } + t->hbuf = malloc0_check(adder_size(t)); + if (!strcmp(info->cmd, "test")) { t->sbuf = malloc0_check(adder_size(t)); } } static void adder_alloc_contig(struct test_info *info) { - struct adder_test *t = to_adder(info); + struct adder_test *t = to_adder(info); - printf("HW buf size: %zu kB\n", adder_size(t) / 1000); - if (contig_alloc(adder_size(t), &info->contig) == NULL) - die_errno(__func__); + printf("HW buf size: %zu kB\n", adder_size(t) / 1000); + if (contig_alloc(adder_size(t), &info->contig) == NULL) die_errno(__func__); } static void adder_init_bufs(struct test_info *info) { - struct adder_test *t = to_adder(info); + struct adder_test *t = to_adder(info); - init_buf(t); - contig_copy_to(info->contig, 0, t->hbuf, adder_size(t)); + init_buf(t); + contig_copy_to(info->contig, 0, t->hbuf, adder_size(t)); } static void adder_set_access(struct test_info *info) { - struct adder_test *t = to_adder(info); + struct adder_test *t = to_adder(info); - t->desc.nbursts = t->nbursts; + t->desc.nbursts = t->nbursts; } static void adder_comp(struct test_info *info) { - struct adder_test *t = to_adder(info); - int i; + struct adder_test *t = to_adder(info); + int i; - const unsigned IN_SIZE_DATA = (SIZE_IN_CHUNK_DATA * t->nbursts); - const unsigned OUT_SIZE_DATA = (SIZE_OUT_CHUNK_DATA * t->nbursts); + const unsigned IN_SIZE_DATA = (SIZE_IN_CHUNK_DATA * t->nbursts); + const unsigned OUT_SIZE_DATA = (SIZE_OUT_CHUNK_DATA * t->nbursts); - // Populate memory for gold output - for (i = 0; i < OUT_SIZE_DATA; ++i) { - t->sbuf[i + IN_SIZE_DATA] = i * 4 + 1; - } + // Populate memory for gold output + for (i = 0; i < OUT_SIZE_DATA; ++i) { + t->sbuf[i + IN_SIZE_DATA] = i * 4 + 1; + } } static bool adder_diff_ok(struct test_info *info) { - struct adder_test *t = to_adder(info); - const unsigned SIZE_DATA = adder_size(t) / (DMA_SIZE / sizeof(word_t)); - int err = 0; + struct adder_test *t = to_adder(info); + const unsigned SIZE_DATA = adder_size(t) / (DMA_SIZE / sizeof(word_t)); + int err = 0; - contig_copy_from(t->hbuf, info->contig, 0, adder_size(t)); + contig_copy_from(t->hbuf, info->contig, 0, adder_size(t)); - err = check_gold(t->sbuf, t->hbuf, SIZE_DATA, t->verbose); - if (err) - printf("Test FAILED: %d mismatches\n", err); - else - printf("Test PASSED: %d mismatches\n", err); + err = check_gold(t->sbuf, t->hbuf, SIZE_DATA, t->verbose); + if (err) printf("Test FAILED: %d mismatches\n", err); + else + printf("Test PASSED: %d mismatches\n", err); - return !err; + return !err; } static struct adder_test adder_test = { - .info = { - .name = NAME, - .devname = DEVNAME, - .alloc_buf = adder_alloc_buf, - .alloc_contig = adder_alloc_contig, - .init_bufs = adder_init_bufs, - .set_access = adder_set_access, - .comp = adder_comp, - .diff_ok = adder_diff_ok, - .esp = &adder_test.desc.esp, - .cm = ADDER_VIVADO_IOC_ACCESS, - }, + .info = + { + .name = NAME, + .devname = DEVNAME, + .alloc_buf = adder_alloc_buf, + .alloc_contig = adder_alloc_contig, + .init_bufs = adder_init_bufs, + .set_access = adder_set_access, + .comp = adder_comp, + .diff_ok = adder_diff_ok, + .esp = &adder_test.desc.esp, + .cm = ADDER_VIVADO_IOC_ACCESS, + }, }; static void NORETURN usage(void) { - fprintf(stderr, "%s", usage_str); - exit(1); + fprintf(stderr, "%s", usage_str); + exit(1); } int main(int argc, char *argv[]) { - if (argc < 2 || argc > 4) { - usage(); - - } else { - printf("\nCommand line arguments received:\n"); - printf("\tcoherence: %s\n", argv[1]); - - if (argc == 3) { - if (strcmp(argv[2], "-v")) { - adder_test.nbursts = strtol(argv[2], NULL, 10); - printf("\tnbursts: %u\n", adder_test.nbursts); - } else { - adder_test.nbursts = DEFAULT_NBURSTS; - adder_test.verbose = true; - printf("\tverbose enabled\n"); - } - } else { - adder_test.nbursts = DEFAULT_NBURSTS; - } - - if (argc == 4) { - if (strcmp(argv[3], "-v")) { - usage(); - } else { - adder_test.nbursts = strtol(argv[2], NULL, 10); - printf("\tnbursts: %u\n", adder_test.nbursts); - adder_test.verbose = true; - printf("\tverbose enabled\n"); - } - } - printf("\n"); - } - - return test_main(&adder_test.info, argv[1], "test"); + if (argc < 2 || argc > 4) { usage(); } + else { + printf("\nCommand line arguments received:\n"); + printf("\tcoherence: %s\n", argv[1]); + + if (argc == 3) { + if (strcmp(argv[2], "-v")) { + adder_test.nbursts = strtol(argv[2], NULL, 10); + printf("\tnbursts: %u\n", adder_test.nbursts); + } + else { + adder_test.nbursts = DEFAULT_NBURSTS; + adder_test.verbose = true; + printf("\tverbose enabled\n"); + } + } + else { + adder_test.nbursts = DEFAULT_NBURSTS; + } + + if (argc == 4) { + if (strcmp(argv[3], "-v")) { usage(); } + else { + adder_test.nbursts = strtol(argv[2], NULL, 10); + printf("\tnbursts: %u\n", adder_test.nbursts); + adder_test.verbose = true; + printf("\tverbose enabled\n"); + } + } + printf("\n"); + } + + return test_main(&adder_test.info, argv[1], "test"); } diff --git a/accelerators/vivado_hls/adder_vivado/sw/linux/driver/adder_vivado.c b/accelerators/vivado_hls/adder_vivado/sw/linux/driver/adder_vivado.c index 9387ca93b0..a47f91e1d9 100644 --- a/accelerators/vivado_hls/adder_vivado/sw/linux/driver/adder_vivado.c +++ b/accelerators/vivado_hls/adder_vivado/sw/linux/driver/adder_vivado.c @@ -1,122 +1,112 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include -#include #include +#include +#include #include -#include #include +#include #include "adder_vivado.h" -#define DRV_NAME "adder_vivado" +#define DRV_NAME "adder_vivado" #define ADDER_NBURSTS_REG 0x40 struct adder_vivado_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver adder_driver; static struct of_device_id adder_device_ids[] = { - { - .name = "SLD_ADDER_VIVADO", - }, - { - .name = "eb_040", - }, - { - .compatible = "sld,adder_vivado", - }, - { }, + { + .name = "SLD_ADDER_VIVADO", + }, + { + .name = "eb_040", + }, + { + .compatible = "sld,adder_vivado", + }, + {}, }; static int adder_devs; static inline struct adder_vivado_device *to_adder(struct esp_device *esp) { - return container_of(esp, struct adder_vivado_device, esp); + return container_of(esp, struct adder_vivado_device, esp); } static void adder_prep_xfer(struct esp_device *esp, void *arg) { - struct adder_vivado_access *a = arg; + struct adder_vivado_access *a = arg; - iowrite32be(a->nbursts, esp->iomem + ADDER_NBURSTS_REG); + iowrite32be(a->nbursts, esp->iomem + ADDER_NBURSTS_REG); } -static bool adder_xfer_input_ok(struct esp_device *esp, void *arg) -{ - return true; -} +static bool adder_xfer_input_ok(struct esp_device *esp, void *arg) { return true; } static int adder_probe(struct platform_device *pdev) { - struct adder_vivado_device *adder; - struct esp_device *esp; - int rc; - - adder = kzalloc(sizeof(*adder), GFP_KERNEL); - if (adder == NULL) - return -ENOMEM; - esp = &adder->esp; - esp->module = THIS_MODULE; - esp->number = adder_devs; - esp->driver = &adder_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - adder_devs++; - return 0; - err: - kfree(adder); - return rc; + struct adder_vivado_device *adder; + struct esp_device *esp; + int rc; + + adder = kzalloc(sizeof(*adder), GFP_KERNEL); + if (adder == NULL) return -ENOMEM; + esp = &adder->esp; + esp->module = THIS_MODULE; + esp->number = adder_devs; + esp->driver = &adder_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + adder_devs++; + return 0; +err: + kfree(adder); + return rc; } static int __exit adder_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct adder_vivado_device *adder = to_adder(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct adder_vivado_device *adder = to_adder(esp); - esp_device_unregister(esp); - kfree(adder); - return 0; + esp_device_unregister(esp); + kfree(adder); + return 0; } static struct esp_driver adder_driver = { - .plat = { - .probe = adder_probe, - .remove = adder_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = adder_device_ids, - }, - }, - .xfer_input_ok = adder_xfer_input_ok, - .prep_xfer = adder_prep_xfer, - .ioctl_cm = ADDER_VIVADO_IOC_ACCESS, - .arg_size = sizeof(struct adder_vivado_access), + .plat = + { + .probe = adder_probe, + .remove = adder_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = adder_device_ids, + }, + }, + .xfer_input_ok = adder_xfer_input_ok, + .prep_xfer = adder_prep_xfer, + .ioctl_cm = ADDER_VIVADO_IOC_ACCESS, + .arg_size = sizeof(struct adder_vivado_access), }; -static int __init adder_init(void) -{ - return esp_driver_register(&adder_driver); -} +static int __init adder_init(void) { return esp_driver_register(&adder_driver); } -static void __exit adder_exit(void) -{ - esp_driver_unregister(&adder_driver); -} +static void __exit adder_exit(void) { esp_driver_unregister(&adder_driver); } -module_init(adder_init) -module_exit(adder_exit) +module_init(adder_init) module_exit(adder_exit) -MODULE_DEVICE_TABLE(of, adder_device_ids); + MODULE_DEVICE_TABLE(of, adder_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/vivado_hls/adder_vivado/sw/linux/include/adder_vivado.h b/accelerators/vivado_hls/adder_vivado/sw/linux/include/adder_vivado.h index 23a2aa68bb..8b424cd762 100644 --- a/accelerators/vivado_hls/adder_vivado/sw/linux/include/adder_vivado.h +++ b/accelerators/vivado_hls/adder_vivado/sw/linux/include/adder_vivado.h @@ -4,24 +4,24 @@ #define _ADDER_VIVADO_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct adder_vivado_access { - struct esp_access esp; - unsigned int nbursts; + struct esp_access esp; + unsigned int nbursts; }; -#define ADDER_VIVADO_IOC_ACCESS _IOW ('S', 0, struct adder_vivado_access) +#define ADDER_VIVADO_IOC_ACCESS _IOW('S', 0, struct adder_vivado_access) #endif /* _ADDER_VIVADO_H_ */ diff --git a/accelerators/vivado_hls/svd_vivado/hw/inc/espacc.h b/accelerators/vivado_hls/svd_vivado/hw/inc/espacc.h index 561769ca91..e2ad47e5d0 100644 --- a/accelerators/vivado_hls/svd_vivado/hw/inc/espacc.h +++ b/accelerators/vivado_hls/svd_vivado/hw/inc/espacc.h @@ -4,35 +4,35 @@ #include "../inc/espacc_config.h" #include +#include "hls_linear_algebra.h" #include #include -#include "hls_linear_algebra.h" using namespace hls; #define __round_mask(x, y) ((y)-1) -#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) +#define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1) // Data types and constants #define VALUES_PER_WORD (DMA_SIZE / DATA_BITWIDTH) // = 2 #if (VALUES_PER_WORD == 2) -#define LOG_VALUES_PER_WORD 1 + #define LOG_VALUES_PER_WORD 1 #else -#define LOG_VALUES_PER_WORD 0 + #define LOG_VALUES_PER_WORD 0 #endif #if ((SIZE_IN_CHUNK_DATA % VALUES_PER_WORD) == 0) -#define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD) + #define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD) #else -#define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD + 1) + #define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD + 1) #endif #if ((SIZE_OUT_CHUNK_DATA % VALUES_PER_WORD) == 0) -#define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD) + #define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD) #else -#define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD + 1) + #define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD + 1) #endif // data word -#if (IS_TYPE_FIXED_POINT == 1) -typedef ap_fixed word_t; +#if (IS_TYPE_FIXED_POINT == 1) +typedef ap_fixed word_t; #elif (IS_TYPE_UINT == 1) typedef ap_uint word_t; #elif (IS_TYPE_INT == 1) @@ -42,10 +42,10 @@ typedef float word_t; #endif #if (IS_TYPE_OUT_FIXED_POINT == 1) -typedef ap_fixed word_out_t; +typedef ap_fixed word_out_t; #endif -typedef ap_fixed word_fixed_t; +typedef ap_fixed word_fixed_t; typedef struct dma_word { word_t word[VALUES_PER_WORD]; @@ -63,100 +63,83 @@ typedef struct dma_info { // The 'size' variable of 'dma_info' indicates the bit-width of the words // processed by the accelerator. Here are the encodings: -#define SIZE_BYTE 0 -#define SIZE_HWORD 1 -#define SIZE_WORD 2 -#define SIZE_DWORD 3 +#define SIZE_BYTE 0 +#define SIZE_HWORD 1 +#define SIZE_WORD 2 +#define SIZE_DWORD 3 #if (DATA_BITWIDTH == 8) -#define SIZE_WORD_T SIZE_BYTE + #define SIZE_WORD_T SIZE_BYTE #elif (DATA_BITWIDTH == 16) -#define SIZE_WORD_T SIZE_HWORD + #define SIZE_WORD_T SIZE_HWORD #elif (DATA_BITWIDTH == 32) -#define SIZE_WORD_T SIZE_WORD + #define SIZE_WORD_T SIZE_WORD #else // if (DATA_BITWIDTH == 64) -#define SIZE_WORD_T SIZE_DWORD + #define SIZE_WORD_T SIZE_DWORD #endif -#define P_MAX 240 //230, 232, 240, 256 +#define P_MAX 240 // 230, 232, 240, 256 #define Q_MAX 180 #define M_MAX 3 void top(dma_word_t *out, dma_word_t *in1, - /* <<--params-->> */ - const unsigned conf_info_q, - const unsigned conf_info_p, - const unsigned conf_info_m, - const unsigned conf_info_p2p_out, - const unsigned conf_info_p2p_in, - const unsigned conf_info_p2p_iter, - const unsigned conf_info_load_state, - dma_info_t &load_ctrl, dma_info_t &store_ctrl); - -void compute(word_t Q[P_MAX][Q_MAX], word_t X[P_MAX][M_MAX], - word_t Y[Q_MAX][M_MAX], word_t T[M_MAX][M_MAX], word_t &P, - const unsigned q, - const unsigned p, - const unsigned m, - const unsigned p2p_out, - const unsigned load_state, - unsigned &b, - const unsigned p2p_iter, - word_t _outbuff[SIZE_OUT_CHUNK_DATA]); - -void load(word_t Q[P_MAX][Q_MAX], word_t X[P_MAX][M_MAX], - word_t Y[Q_MAX][M_MAX], word_t T[M_MAX][M_MAX], word_t &P, dma_word_t *in1, - const unsigned q, - const unsigned p, - const unsigned m, - const unsigned p2p_in, - const unsigned b, - const unsigned load_state, - dma_info_t &load_ctrl); - -void store(word_t _outbuff[SIZE_OUT_CHUNK_DATA], dma_word_t *out, - const unsigned q, - const unsigned p, - const unsigned m, - const unsigned p2p_out, - const unsigned b, - const unsigned load_state, - dma_info_t &store_ctrl); - -struct TRAITS_SVD: - hls::svd_traits{ - static const int NUM_SWEEPS = 6; - static const int OFF_DIAG_II = 20; - static const int DIAG_II = 32; - static const int ALLOCATION = 1; + /* <<--params-->> */ + const unsigned conf_info_q, const unsigned conf_info_p, const unsigned conf_info_m, + const unsigned conf_info_p2p_out, const unsigned conf_info_p2p_in, + const unsigned conf_info_p2p_iter, const unsigned conf_info_load_state, + dma_info_t &load_ctrl, dma_info_t &store_ctrl); + +void compute(word_t Q[P_MAX][Q_MAX], word_t X[P_MAX][M_MAX], word_t Y[Q_MAX][M_MAX], + word_t T[M_MAX][M_MAX], word_t &P, const unsigned q, const unsigned p, + const unsigned m, const unsigned p2p_out, const unsigned load_state, unsigned &b, + const unsigned p2p_iter, word_t _outbuff[SIZE_OUT_CHUNK_DATA]); + +void load(word_t Q[P_MAX][Q_MAX], word_t X[P_MAX][M_MAX], word_t Y[Q_MAX][M_MAX], + word_t T[M_MAX][M_MAX], word_t &P, dma_word_t *in1, const unsigned q, const unsigned p, + const unsigned m, const unsigned p2p_in, const unsigned b, const unsigned load_state, + dma_info_t &load_ctrl); + +void store(word_t _outbuff[SIZE_OUT_CHUNK_DATA], dma_word_t *out, const unsigned q, + const unsigned p, const unsigned m, const unsigned p2p_out, const unsigned b, + const unsigned load_state, dma_info_t &store_ctrl); + +struct TRAITS_SVD : hls::svd_traits { + static const int NUM_SWEEPS = 6; + static const int OFF_DIAG_II = 20; + static const int DIAG_II = 32; + static const int ALLOCATION = 1; }; -struct TRAITS_C: -hls::matrix_multiply_traits{ - static const int ARCH = 2; - //static const int INNER_II = 3; - static const int UNROLL_FACTOR = 16; +struct TRAITS_C : + hls::matrix_multiply_traits { + static const int ARCH = 2; + // static const int INNER_II = 3; + static const int UNROLL_FACTOR = 16; }; -struct TRAITS_A: -hls::matrix_multiply_traits{ - static const int ARCH = 2; - //static const int INNER_II = 9; - //static const int UNROLL_FACTOR = 3; +struct TRAITS_A : + hls::matrix_multiply_traits { + static const int ARCH = 2; + // static const int INNER_II = 9; + // static const int UNROLL_FACTOR = 3; }; -struct TRAITS_A_F: -hls::matrix_multiply_traits{ - static const int ARCH = 3; - //static const int INNER_II = 9; - //static const int UNROLL_FACTOR = 3; Possible +struct TRAITS_A_F : + hls::matrix_multiply_traits { + static const int ARCH = 3; + // static const int INNER_II = 9; + // static const int UNROLL_FACTOR = 3; Possible }; -struct TRAITS_X_SINK: -hls::matrix_multiply_traits{ - static const int ARCH = 2; - //static const int INNER_II = 16; - //static const int UNROLL_FACTOR = 3; +struct TRAITS_X_SINK : + hls::matrix_multiply_traits { + static const int ARCH = 2; + // static const int INNER_II = 16; + // static const int UNROLL_FACTOR = 3; }; #endif diff --git a/accelerators/vivado_hls/svd_vivado/sw/baremetal/svd_fixed.c b/accelerators/vivado_hls/svd_vivado/sw/baremetal/svd_fixed.c index 37990811f2..a026e8108f 100644 --- a/accelerators/vivado_hls/svd_vivado/sw/baremetal/svd_fixed.c +++ b/accelerators/vivado_hls/svd_vivado/sw/baremetal/svd_fixed.c @@ -3,7 +3,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -14,23 +14,19 @@ typedef int32_t token_t; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} - +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } -#define SLD_SVD 0x222 +#define SLD_SVD 0x222 #define DEV_NAME "sld,svd_vivado" /* <<--params-->> */ -const int32_t p2p_out = 0; -const int32_t p2p_in = 0; -const int32_t p2p_iter = 1; +const int32_t p2p_out = 0; +const int32_t p2p_in = 0; +const int32_t p2p_iter = 1; const int32_t load_state = 0; -const int32_t q = 177; -const int32_t p = 229; -const int32_t m = 3; +const int32_t q = 177; +const int32_t p = 229; +const int32_t m = 3; static unsigned in_words_adj; static unsigned out_words_adj; @@ -43,277 +39,275 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ #define SVD_LOAD_STATE_REG 0x58 -#define SVD_P2P_ITER_REG 0x54 -#define SVD_P2P_IN_REG 0x50 -#define SVD_P2P_OUT_REG 0x4C -#define SVD_Q_REG 0x48 -#define SVD_P_REG 0x44 -#define SVD_M_REG 0x40 - +#define SVD_P2P_ITER_REG 0x54 +#define SVD_P2P_IN_REG 0x50 +#define SVD_P2P_OUT_REG 0x4C +#define SVD_Q_REG 0x48 +#define SVD_P_REG 0x44 +#define SVD_M_REG 0x40 static int validate_buf(token_t *out, float *gold) { - int i; - int j; - float MAE, MAE_sum, num; - unsigned errors = 0; - MAE_sum = 0; - - for (i = 0; i < 1; i++) - for (j = 0; j < m*m+m*p; j++) - { + int i; + int j; + float MAE, MAE_sum, num; + unsigned errors = 0; + MAE_sum = 0; + + for (i = 0; i < 1; i++) + for (j = 0; j < m * m + m * p; j++) { + + float val = fixed32_to_float(out[i * out_words_adj + j], 11); + float gold_val = gold[i * out_words_adj + j]; + + // MAE = (out[i * out_words_adj + j] - gold[i * out_words_adj + j]) + // / gold[i * out_words_adj + j]; + + MAE = (val - gold_val) / gold_val; + + if (j < m * m) { + uint32_t *tmp1 = (uint32_t *)&gold[i * out_words_adj + j]; + print_uart("gold = "); + print_uart_int(*tmp1); + print_uart(" "); + uint32_t *tmp2 = (uint32_t *)&val; + print_uart("out = "); + print_uart_int(*tmp2); + print_uart("\n"); + } + + MAE_sum += MAE * MAE; + + if (MAE > 0.15 || MAE < -0.15) { + print_uart("Error for j = "); + print_uart_int(j); + print_uart("\n"); + errors++; + uint32_t *tmp3 = (uint32_t *)&gold_val; + print_uart("gold = "); + print_uart_int(*tmp3); + print_uart(" "); + uint32_t *tmp4 = (uint32_t *)&val; + print_uart("out = "); + print_uart_int(*tmp4); + print_uart("\n"); + } + } + + num = m * m + p * m; + if (MAE_sum / num > 0.01) errors++; + + printf("Sum of errors is %d \n", errors); + + return errors; +} - float val = fixed32_to_float(out[i * out_words_adj + j], 11); - float gold_val = gold[i * out_words_adj + j]; +static void init_buf(token_t *in, float *gold) +{ + int i; + int j; + int k, x, y, t; - //MAE = (out[i * out_words_adj + j] - gold[i * out_words_adj + j]) - // / gold[i * out_words_adj + j]; + printf("initialize buffer \n"); - MAE = (val - gold_val) / gold_val; + for (i = 0; i < 1; i++) { + for (j = 0; j < p * q; j++) // Q + { + // print_uart("saving Q[");print_uart_int(j);print_uart("]\n"); + float val = (float)1 / (p * q); + in[i * in_words_adj + j] = (token_t)float_to_fixed32(val, 11); + // in[i * in_words_adj + j] = (token_t) j; + } - if(j < m*m){ - uint32_t* tmp1 = (uint32_t*) &gold[i * out_words_adj + j]; - print_uart("gold = ");print_uart_int(*tmp1);print_uart(" "); - uint32_t* tmp2 = (uint32_t*) &val; - print_uart("out = ");print_uart_int(*tmp2);print_uart("\n"); - } + printf(" Generated Q \n"); - MAE_sum += MAE*MAE; + for (x = 0; x < m * p; x++) // X + in[i * in_words_adj + j + x] = (token_t)float_to_fixed32(inputX[x], 11); - if (MAE > 0.15 || MAE < -0.15) - { - print_uart("Error for j = ");print_uart_int(j);print_uart("\n"); - errors++; - uint32_t* tmp3 = (uint32_t*) &gold_val; - print_uart("gold = ");print_uart_int(*tmp3);print_uart(" "); - uint32_t* tmp4 = (uint32_t*) &val; - print_uart("out = ");print_uart_int(*tmp4);print_uart("\n"); - } + printf(" Generated X \n"); - } + for (y = 0; y < m * q; y++) // Y + in[i * in_words_adj + j + x + y] = (token_t)float_to_fixed32(inputY[y], 11); - num = m*m+p*m; - if (MAE_sum / num > 0.01) - errors++; + printf(" Generated Y \n"); - printf("Sum of errors is %d \n", errors); + for (t = 0; t < m * m; t++) // T + in[i * in_words_adj + j + x + y + t] = (token_t)float_to_fixed32(inputT[t], 11); - return errors; -} + printf(" Generated T \n"); + in[i * in_words_adj + j + x + y + t] = (token_t)float_to_fixed32(inputP, 11); -static void init_buf (token_t *in, float * gold) -{ - int i; - int j; - int k, x, y, t; + printf(" Generated P \n"); + } - printf("initialize buffer \n"); + print_uart(" Generated all inputs \n"); - for (i = 0; i < 1; i++) - { - for(j = 0; j < p*q; j++) //Q - { - //print_uart("saving Q[");print_uart_int(j);print_uart("]\n"); - float val = (float) 1/(p * q); - in[i * in_words_adj + j] = (token_t) float_to_fixed32(val, 11); - //in[i * in_words_adj + j] = (token_t) j; - } + for (k = 0; k < m; k++) + for (j = 0; j < p; j++) + gold_out_sink[k][j] = 0.0; - printf(" Generated Q \n"); + for (k = 0; k < m; k++) + for (i = 0; i < p; i++) + for (j = 0; j < m; j++) + gold_out_sink[k][i] += inputX[i * m + j] * gold_out[k * m + j]; - for(x = 0; x < m*p; x++) //X - in[i * in_words_adj + j + x] = (token_t) float_to_fixed32(inputX[x], 11); + print_uart(" Generated golden output for sinkhorn \n"); - printf(" Generated X \n"); + for (i = 0; i < 1; i++) { + for (j = 0; j < m * m; j++) + gold[i * out_words_adj + j] = gold_out[j]; - for(y = 0; y < m*q; y++) //Y - in[i * in_words_adj + j + x + y] = (token_t) float_to_fixed32(inputY[y], 11); + for (k = 0; k < m * p; k++) + gold[i * out_words_adj + j + k] = gold_out_sink[k / p][k % p]; + } - printf(" Generated Y \n"); + printf(" Generated output \n"); +} - for(t = 0; t < m*m; t++) //T - in[i * in_words_adj + j + x + y + t] = (token_t) float_to_fixed32(inputT[t], 11); +int main(int argc, char *argv[]) +{ + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable; + token_t *mem; + float *gold; + unsigned errors = 0; + unsigned coherence; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = p * q + m * p + m * q + m * m + 1; + out_words_adj = m * m + m * p; + } + else { + in_words_adj = + round_up(p * q + m * p + m * q + m * m + 1, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(m * m + m * p, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (1); + out_len = out_words_adj * (1); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_SVD, DEV_NAME); + if (ndev == 0) { + printf("svd not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + printf("**************** %s.%d ****************\n", DEV_NAME, n); + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_size); + mem = aligned_malloc(mem_size); + + printf(" memory buffer base-address = %p\n", mem); + + for (int i = 0; i < mem_size / sizeof(token_t); i++) + mem[i] = 0; + + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); - printf(" Generated T \n"); +#ifndef __riscv + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { +#else + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; +#endif - in[i * in_words_adj + j + x + y + t] = (token_t) float_to_fixed32(inputP, 11); + printf(" Generate input...\n"); - printf(" Generated P \n"); + init_buf(mem, gold); - } + // Pass common configuration parameters - print_uart(" Generated all inputs \n"); + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); - for(k = 0; k < m; k++) - for(j = 0; j < p; j++) - gold_out_sink[k][j] = 0.0; + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - for(k = 0; k < m; k++) - for(i = 0; i < p; i++) - for(j = 0; j < m; j++) - gold_out_sink[k][i] += inputX[i * m + j] * gold_out[k * m + j]; + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); - print_uart(" Generated golden output for sinkhorn \n"); + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + iowrite32(dev, SVD_P2P_OUT_REG, p2p_out); + iowrite32(dev, SVD_P2P_IN_REG, p2p_in); + iowrite32(dev, SVD_P2P_ITER_REG, p2p_iter); + iowrite32(dev, SVD_LOAD_STATE_REG, load_state); + iowrite32(dev, SVD_Q_REG, q); + iowrite32(dev, SVD_P_REG, p); + iowrite32(dev, SVD_M_REG, m); - for (i = 0; i < 1; i++) - { - for(j = 0; j < m*m; j++) - gold[i * out_words_adj + j] = gold_out[j]; + // Flush (customize coherence model here) + esp_flush(coherence); - for(k = 0; k < m*p; k++) - gold[i * out_words_adj + j + k] = gold_out_sink[k / p][k % p]; - } + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); - printf(" Generated output \n"); -} + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + printf(" Done\n"); + printf(" validating...\n"); -int main(int argc, char * argv[]) -{ - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable; - token_t *mem; - float *gold; - unsigned errors = 0; - unsigned coherence; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = p*q+m*p+m*q+m*m+1; - out_words_adj = m*m+m*p; - } else { - in_words_adj = round_up(p*q+m*p+m*q+m*m+1, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(m*m+m*p, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (1); - out_len = out_words_adj * (1); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_SVD, DEV_NAME); - if (ndev == 0) { - printf("svd not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - printf("**************** %s.%d ****************\n", DEV_NAME, n); - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_size); - mem = aligned_malloc(mem_size); - - printf(" memory buffer base-address = %p\n", mem); - - for(int i = 0; i < mem_size/sizeof(token_t); i++) - mem[i] = 0; - - // Alocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); -#ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { -#else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; -#endif + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } - printf(" Generate input...\n"); - - init_buf(mem, gold); - - // Pass common configuration parameters - - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, ACC_COH_NONE); - - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - iowrite32(dev, SVD_P2P_OUT_REG, p2p_out); - iowrite32(dev, SVD_P2P_IN_REG, p2p_in); - iowrite32(dev, SVD_P2P_ITER_REG, p2p_iter); - iowrite32(dev, SVD_LOAD_STATE_REG, load_state); - iowrite32(dev, SVD_Q_REG, q); - iowrite32(dev, SVD_P_REG, p); - iowrite32(dev, SVD_M_REG, m); - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + return 0; } diff --git a/accelerators/vivado_hls/svd_vivado/sw/linux/app/c_run.cpp b/accelerators/vivado_hls/svd_vivado/sw/linux/app/c_run.cpp index b5e2535ccb..77827fbcce 100644 --- a/accelerators/vivado_hls/svd_vivado/sw/linux/app/c_run.cpp +++ b/accelerators/vivado_hls/svd_vivado/sw/linux/app/c_run.cpp @@ -1,60 +1,56 @@ #include "c_run.h" #include "eigen/Eigen/Dense" #include "eigen/Eigen/SVD" -#include #include -#include #include +#include +#include using namespace Eigen; using namespace std; extern "C" { - Matrix3f R; - - void c_run_svd(float inputP, float* inputX, float* inputY, float* inputT) - { - //Variables - float inputQ[229*177]; - int p = 229, q = 177; - for(int j = 0; j < p*q; j++) //Q - inputQ[j] = (float) 1/(p * q); - - Matrix3f A; - //float Q[229*177]; - MatrixXf Q = Map >(inputQ); - MatrixXf C; - MatrixXf X = Map >(inputX); - MatrixXf Y = Map >(inputY); - Matrix3f T = Map >(inputT); - - //Measure time - //struct timespec startn, endn; - //unsigned long long sw_ns; - - //gettime(&startn); - - //Run svd software - get R, X*R and Y.T - A = Y*Q*X.transpose()*2*inputP+T; - JacobiSVD svd(A, ComputeFullU | ComputeFullV); - Matrix3f U = svd.matrixU(); - Matrix3f Vh = svd.matrixV().transpose(); - R = U * Vh; - MatrixXf X_res = X.transpose()*R; - MatrixXf Y_res = Y; - - //gettime(&endn); - - //sw_ns = ts_subtract(&startn, &endn); - //printf(" > Software test time: %llu ns\n", sw_ns); - //printf(" + CP_sum: %f\n", sum); - - } - - void printR() - { - cout <<"\n+ Software matrix R is:\n" << R << endl; - } +Matrix3f R; + +void c_run_svd(float inputP, float *inputX, float *inputY, float *inputT) +{ + // Variables + float inputQ[229 * 177]; + int p = 229, q = 177; + for (int j = 0; j < p * q; j++) // Q + inputQ[j] = (float)1 / (p * q); + + Matrix3f A; + // float Q[229*177]; + MatrixXf Q = Map>(inputQ); + MatrixXf C; + MatrixXf X = Map>(inputX); + MatrixXf Y = Map>(inputY); + Matrix3f T = Map>(inputT); + + // Measure time + // struct timespec startn, endn; + // unsigned long long sw_ns; + + // gettime(&startn); + + // Run svd software - get R, X*R and Y.T + A = Y * Q * X.transpose() * 2 * inputP + T; + JacobiSVD svd(A, ComputeFullU | ComputeFullV); + Matrix3f U = svd.matrixU(); + Matrix3f Vh = svd.matrixV().transpose(); + R = U * Vh; + MatrixXf X_res = X.transpose() * R; + MatrixXf Y_res = Y; + + // gettime(&endn); + + // sw_ns = ts_subtract(&startn, &endn); + // printf(" > Software test time: %llu ns\n", sw_ns); + // printf(" + CP_sum: %f\n", sum); +} + +void printR() { cout << "\n+ Software matrix R is:\n" << R << endl; } } /* extern "C" */ diff --git a/accelerators/vivado_hls/svd_vivado/sw/linux/app/svd.c b/accelerators/vivado_hls/svd_vivado/sw/linux/app/svd.c index 048a3f3e13..26e62aec62 100644 --- a/accelerators/vivado_hls/svd_vivado/sw/linux/app/svd.c +++ b/accelerators/vivado_hls/svd_vivado/sw/linux/app/svd.c @@ -1,6 +1,6 @@ -#include "libesp.h" -#include "cfg.h" #include "c_run.h" +#include "cfg.h" +#include "libesp.h" static unsigned in_words_adj; static unsigned out_words_adj; @@ -14,124 +14,119 @@ static unsigned size; /* User-defined code */ static int validate_buffer(token_t *out, token_t *gold) { - int i; - int j; - unsigned errors = 0; - float MAE, MAE_sum, num; - MAE_sum = 0.0; + int i; + int j; + unsigned errors = 0; + float MAE, MAE_sum, num; + MAE_sum = 0.0; - for (i = 0; i < 1; i++) - for (j = 0; j < m*m+m*p; j++) - { + for (i = 0; i < 1; i++) + for (j = 0; j < m * m + m * p; j++) { - float val_out, val_gold; - val_out = fixed32_to_float(out[i * out_words_adj + j], 11); - val_gold = fixed32_to_float(gold[i * out_words_adj + j], 11); + float val_out, val_gold; + val_out = fixed32_to_float(out[i * out_words_adj + j], 11); + val_gold = fixed32_to_float(gold[i * out_words_adj + j], 11); - MAE = (val_out - val_gold) / val_gold; + MAE = (val_out - val_gold) / val_gold; - //printf("%d: out = %.20f , gold = %.20f \n", j, val_out, val_gold); + // printf("%d: out = %.20f , gold = %.20f \n", j, val_out, val_gold); - MAE_sum += pow(MAE,2); - if (MAE < -0.15 || MAE > 0.15) - errors++; + MAE_sum += pow(MAE, 2); + if (MAE < -0.15 || MAE > 0.15) errors++; + } - } + num = m * m + p * m; + if (MAE_sum / num > 0.01) errors++; - num = m*m+p*m; - if (MAE_sum / num > 0.01) - errors++; + printf("Sum of errors is %d \n", errors); - printf("Sum of errors is %d \n", errors); - - return errors; + return errors; } - /* User-defined code */ -static void init_buffer(token_t *in, token_t * gold) +static void init_buffer(token_t *in, token_t *gold) { - int i; - int j; - int k, x, y, t; - - for (i = 0; i < 1; i++) - { - for(j = 0; j < p*q; j++) //Q - { - float val = (float) 1/(p * q); - in[i * in_words_adj + j] = (token_t) float_to_fixed32(val, 11); - } - - for(x = 0; x < m*p; x++) //X - { - in[i * in_words_adj + j + x] = (token_t) float_to_fixed32(inputX[x], 11); - //printf(" in[%d] = %f \n", i * in_words_adj + j + x, in[i * in_words_adj + j + x]); - } - - for(y = 0; y < m*q; y++) //Y - { - in[i * in_words_adj + j + x + y] = (token_t) float_to_fixed32(inputY[y], 11); - //printf(" in[%d] = %f \n", i * in_words_adj + j + x + y, in[i * in_words_adj + j + x +y]); - } - - for(t = 0; t < m*m; t++) //T - { - in[i * in_words_adj + j + x + y + t] = (token_t) float_to_fixed32(inputT[t], 11); - //printf(" in[%d] = %f \n", i * in_words_adj + j + x + y + t, in[i * in_words_adj + j + x + y + t]); - } - - in[i * in_words_adj + j + x + y + t] = (token_t) float_to_fixed32(inputP, 11); - //printf(" in[%d] = %f \n", i * in_words_adj + j + x + y + t, in[i * in_words_adj + j + x + y + t]); - - } - - printf(" Generated all inputs \n"); - - for(k = 0; k < m; k++) - for(j = 0; j < p; j++) - gold_out_sink[k][j] = 0.0; - - for(k = 0; k < m; k++) - for(i = 0; i < p; i++) - for(j = 0; j < m; j++) - gold_out_sink[k][i] += inputX[i * m + j] * gold_out[k * m + j]; - - for (i = 0; i < 1; i++) - { - for(j = 0; j < m*m; j++) - { - gold[i * out_words_adj + j] = (token_t) float_to_fixed32(gold_out[j], 11); - //printf("gold: %d: val = %f \n", j, gold_out[j]); - } - - for(k = 0; k < m*p; k++) - { - gold[i * out_words_adj + j + k] = (token_t) float_to_fixed32(gold_out_sink[k / p][k % p], 11); - //printf("gold: %d: val = %f \n", k, gold_out_sink[k/p][k%p]); - } - } - - printf(" Generated golden output \n"); + int i; + int j; + int k, x, y, t; + + for (i = 0; i < 1; i++) { + for (j = 0; j < p * q; j++) // Q + { + float val = (float)1 / (p * q); + in[i * in_words_adj + j] = (token_t)float_to_fixed32(val, 11); + } + + for (x = 0; x < m * p; x++) // X + { + in[i * in_words_adj + j + x] = (token_t)float_to_fixed32(inputX[x], 11); + // printf(" in[%d] = %f \n", i * in_words_adj + j + x, in[i * in_words_adj + j + x]); + } + + for (y = 0; y < m * q; y++) // Y + { + in[i * in_words_adj + j + x + y] = (token_t)float_to_fixed32(inputY[y], 11); + // printf(" in[%d] = %f \n", i * in_words_adj + j + x + y, in[i * in_words_adj + j + x + // +y]); + } + + for (t = 0; t < m * m; t++) // T + { + in[i * in_words_adj + j + x + y + t] = (token_t)float_to_fixed32(inputT[t], 11); + // printf(" in[%d] = %f \n", i * in_words_adj + j + x + y + t, in[i * in_words_adj + j + + // x + y + t]); + } + + in[i * in_words_adj + j + x + y + t] = (token_t)float_to_fixed32(inputP, 11); + // printf(" in[%d] = %f \n", i * in_words_adj + j + x + y + t, in[i * in_words_adj + j + x + + // y + t]); + } + + printf(" Generated all inputs \n"); + + for (k = 0; k < m; k++) + for (j = 0; j < p; j++) + gold_out_sink[k][j] = 0.0; + + for (k = 0; k < m; k++) + for (i = 0; i < p; i++) + for (j = 0; j < m; j++) + gold_out_sink[k][i] += inputX[i * m + j] * gold_out[k * m + j]; + + for (i = 0; i < 1; i++) { + for (j = 0; j < m * m; j++) { + gold[i * out_words_adj + j] = (token_t)float_to_fixed32(gold_out[j], 11); + // printf("gold: %d: val = %f \n", j, gold_out[j]); + } + + for (k = 0; k < m * p; k++) { + gold[i * out_words_adj + j + k] = + (token_t)float_to_fixed32(gold_out_sink[k / p][k % p], 11); + // printf("gold: %d: val = %f \n", k, gold_out_sink[k/p][k%p]); + } + } + + printf(" Generated golden output \n"); } - /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = p*q+m*p+m*q+m*m+1; - out_words_adj = m*m+m*p; - } else { - in_words_adj = round_up(p*q+m*p+m*q+m*m+1, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(m*m+m*p, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (1); - out_len = out_words_adj * (1); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = in_len; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = p * q + m * p + m * q + m * m + 1; + out_words_adj = m * m + m * p; + } + else { + in_words_adj = + round_up(p * q + m * p + m * q + m * m + 1, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(m * m + m * p, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (1); + out_len = out_words_adj * (1); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = in_len; + size = (out_offset * sizeof(token_t)) + out_size; } /* void c_run() */ @@ -174,89 +169,86 @@ static void init_parameters() int main(int argc, char **argv) { - int errors; - - token_t *gold; - token_t *buf; + int errors; - //Measure time - struct timespec startn, endn; - unsigned long long sw_ns; + token_t *gold; + token_t *buf; - init_parameters(); + // Measure time + struct timespec startn, endn; + unsigned long long sw_ns; - buf = (token_t *) esp_alloc(size); - gold = malloc(out_size); + init_parameters(); - for(int i = 0; i < size/sizeof(token_t); i++) - buf[i] = 0; + buf = (token_t *)esp_alloc(size); + gold = malloc(out_size); - cfg_000[0].hw_buf = buf; + for (int i = 0; i < size / sizeof(token_t); i++) + buf[i] = 0; - printf("\nClean SVD - send all zeros\n"); - esp_run(&cfg_000[0], 1); + cfg_000[0].hw_buf = buf; - init_buffer(buf, gold); + printf("\nClean SVD - send all zeros\n"); + esp_run(&cfg_000[0], 1); - printf("\n====== %s ======\n\n", cfg_000[0].devname); - /* <<--print-params-->> */ - printf(" .q = %d\n", q); - printf(" .p = %d\n", p); - printf(" .m = %d\n", m); + init_buffer(buf, gold); - printf("\n ** START **\n"); + printf("\n====== %s ======\n\n", cfg_000[0].devname); + /* <<--print-params-->> */ + printf(" .q = %d\n", q); + printf(" .p = %d\n", p); + printf(" .m = %d\n", m); - //Run svd software - gettime(&startn); - c_run_svd(inputP, inputX, inputY, inputT); - gettime(&endn); - sw_ns = ts_subtract(&startn, &endn); - printf(" > Software test time: %llu ns\n", sw_ns); + printf("\n ** START **\n"); - cfg_000[0].hw_buf = buf; + // Run svd software + gettime(&startn); + c_run_svd(inputP, inputX, inputY, inputT); + gettime(&endn); + sw_ns = ts_subtract(&startn, &endn); + printf(" > Software test time: %llu ns\n", sw_ns); - //Run SVD hardware - esp_run(cfg_000, NACC); + cfg_000[0].hw_buf = buf; - printR(); + // Run SVD hardware + esp_run(cfg_000, NACC); - printf("\n ** DONE **\n"); + printR(); - errors = validate_buffer(&buf[out_offset], gold); + printf("\n ** DONE **\n"); - if (!errors) - printf("+ Test PASSED\n"); - else - printf("+ Test FAILED\n"); + errors = validate_buffer(&buf[out_offset], gold); - printf("\n====== %s ======\n\n", cfg_000[0].devname); + if (!errors) printf("+ Test PASSED\n"); + else + printf("+ Test FAILED\n"); - //In case we have more than one sinkhorn - check maximum 4 - for(int8_t i = 1; i < 4; i++){ - char acc[3][11]; - sprintf(acc[i-1], "/dev/svd.%d", i); + printf("\n====== %s ======\n\n", cfg_000[0].devname); - if(access(acc[i-1], F_OK) == 0){ + // In case we have more than one sinkhorn - check maximum 4 + for (int8_t i = 1; i < 4; i++) { + char acc[3][11]; + sprintf(acc[i - 1], "/dev/svd.%d", i); - printf("\nAdditional accelerator: %s\n\n", acc[i-1]); + if (access(acc[i - 1], F_OK) == 0) { - cfg_000[i].hw_buf = buf; - esp_run(&cfg_000[i], 1); + printf("\nAdditional accelerator: %s\n\n", acc[i - 1]); - errors = validate_buffer(&buf[out_offset], gold); + cfg_000[i].hw_buf = buf; + esp_run(&cfg_000[i], 1); - if (!errors) - printf("+ Test PASSED for %s\n", acc[i-1]); - else - printf("+ Test FAILED for %s\n", acc[i-1]); - } - } + errors = validate_buffer(&buf[out_offset], gold); + if (!errors) printf("+ Test PASSED for %s\n", acc[i - 1]); + else + printf("+ Test FAILED for %s\n", acc[i - 1]); + } + } - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - free(gold); - esp_free(buf); + free(gold); + esp_free(buf); - return errors; + return errors; } diff --git a/accelerators/vivado_hls/svd_vivado/sw/linux/driver/svd_vivado.c b/accelerators/vivado_hls/svd_vivado/sw/linux/driver/svd_vivado.c index 50ed6af396..0e2a2401f4 100644 --- a/accelerators/vivado_hls/svd_vivado/sw/linux/driver/svd_vivado.c +++ b/accelerators/vivado_hls/svd_vivado/sw/linux/driver/svd_vivado.c @@ -1,139 +1,131 @@ -#include #include +#include #include -#include #include +#include #include "svd_vivado.h" -#define DRV_NAME "svd" +#define DRV_NAME "svd" /* <<--regs-->> */ #define SVD_LOAD_STATE_REG 0x58 -#define SVD_P2P_ITER_REG 0x54 -#define SVD_P2P_IN_REG 0x50 -#define SVD_P2P_OUT_REG 0x4C -#define SVD_Q_REG 0x48 -#define SVD_P_REG 0x44 -#define SVD_M_REG 0x40 +#define SVD_P2P_ITER_REG 0x54 +#define SVD_P2P_IN_REG 0x50 +#define SVD_P2P_OUT_REG 0x4C +#define SVD_Q_REG 0x48 +#define SVD_P_REG 0x44 +#define SVD_M_REG 0x40 struct svd_device { - struct esp_device esp; + struct esp_device esp; }; static struct esp_driver svd_driver; static struct of_device_id svd_device_ids[] = { - { - .name = "SLD_SVD_VIVADO", - }, - { - .name = "eb_222", - }, - { - .compatible = "sld,svd_vivado", - }, - { }, + { + .name = "SLD_SVD_VIVADO", + }, + { + .name = "eb_222", + }, + { + .compatible = "sld,svd_vivado", + }, + {}, }; static int svd_devs; static inline struct svd_device *to_svd(struct esp_device *esp) { - return container_of(esp, struct svd_device, esp); + return container_of(esp, struct svd_device, esp); } static void svd_prep_xfer(struct esp_device *esp, void *arg) { - struct svd_access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->load_state, esp->iomem + SVD_LOAD_STATE_REG); - iowrite32be(a->p2p_iter, esp->iomem + SVD_P2P_ITER_REG); - iowrite32be(a->p2p_in, esp->iomem + SVD_P2P_IN_REG); - iowrite32be(a->p2p_out, esp->iomem + SVD_P2P_OUT_REG); - iowrite32be(a->q, esp->iomem + SVD_Q_REG); - iowrite32be(a->p, esp->iomem + SVD_P_REG); - iowrite32be(a->m, esp->iomem + SVD_M_REG); - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); - + struct svd_access *a = arg; + + /* <<--regs-config-->> */ + iowrite32be(a->load_state, esp->iomem + SVD_LOAD_STATE_REG); + iowrite32be(a->p2p_iter, esp->iomem + SVD_P2P_ITER_REG); + iowrite32be(a->p2p_in, esp->iomem + SVD_P2P_IN_REG); + iowrite32be(a->p2p_out, esp->iomem + SVD_P2P_OUT_REG); + iowrite32be(a->q, esp->iomem + SVD_Q_REG); + iowrite32be(a->p, esp->iomem + SVD_P_REG); + iowrite32be(a->m, esp->iomem + SVD_M_REG); + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } static bool svd_xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct svd_device *svd = to_svd(esp); */ - /* struct svd_access *a = arg; */ + /* struct svd_device *svd = to_svd(esp); */ + /* struct svd_access *a = arg; */ - return true; + return true; } static int svd_probe(struct platform_device *pdev) { - struct svd_device *svd; - struct esp_device *esp; - int rc; - - svd = kzalloc(sizeof(*svd), GFP_KERNEL); - if (svd == NULL) - return -ENOMEM; - esp = &svd->esp; - esp->module = THIS_MODULE; - esp->number = svd_devs; - esp->driver = &svd_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - svd_devs++; - return 0; - err: - kfree(svd); - return rc; + struct svd_device *svd; + struct esp_device *esp; + int rc; + + svd = kzalloc(sizeof(*svd), GFP_KERNEL); + if (svd == NULL) return -ENOMEM; + esp = &svd->esp; + esp->module = THIS_MODULE; + esp->number = svd_devs; + esp->driver = &svd_driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + svd_devs++; + return 0; +err: + kfree(svd); + return rc; } static int __exit svd_remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct svd_device *svd = to_svd(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct svd_device *svd = to_svd(esp); - esp_device_unregister(esp); - kfree(svd); - return 0; + esp_device_unregister(esp); + kfree(svd); + return 0; } static struct esp_driver svd_driver = { - .plat = { - .probe = svd_probe, - .remove = svd_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = svd_device_ids, - }, - }, - .xfer_input_ok = svd_xfer_input_ok, - .prep_xfer = svd_prep_xfer, - .ioctl_cm = SVD_IOC_ACCESS, - .arg_size = sizeof(struct svd_access), + .plat = + { + .probe = svd_probe, + .remove = svd_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = svd_device_ids, + }, + }, + .xfer_input_ok = svd_xfer_input_ok, + .prep_xfer = svd_prep_xfer, + .ioctl_cm = SVD_IOC_ACCESS, + .arg_size = sizeof(struct svd_access), }; -static int __init svd_init(void) -{ - return esp_driver_register(&svd_driver); -} +static int __init svd_init(void) { return esp_driver_register(&svd_driver); } -static void __exit svd_exit(void) -{ - esp_driver_unregister(&svd_driver); -} +static void __exit svd_exit(void) { esp_driver_unregister(&svd_driver); } -module_init(svd_init) -module_exit(svd_exit) +module_init(svd_init) module_exit(svd_exit) -MODULE_DEVICE_TABLE(of, svd_device_ids); + MODULE_DEVICE_TABLE(of, svd_device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/accelerators/vivado_hls/svd_vivado/sw/linux/include/svd_vivado.h b/accelerators/vivado_hls/svd_vivado/sw/linux/include/svd_vivado.h index 27b04c05f0..de7b9b0f02 100644 --- a/accelerators/vivado_hls/svd_vivado/sw/linux/include/svd_vivado.h +++ b/accelerators/vivado_hls/svd_vivado/sw/linux/include/svd_vivado.h @@ -2,33 +2,33 @@ #define _SVD_VIVADO_H_ #ifdef __KERNEL__ -#include -#include + #include + #include #else -#include -#include -#ifndef __user -#define __user -#endif + #include + #include + #ifndef __user + #define __user + #endif #endif /* __KERNEL__ */ #include #include struct svd_access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned q; - unsigned p; - unsigned m; - unsigned p2p_out; - unsigned p2p_in; - unsigned p2p_iter; - unsigned load_state; - unsigned src_offset; - unsigned dst_offset; + struct esp_access esp; + /* <<--regs-->> */ + unsigned q; + unsigned p; + unsigned m; + unsigned p2p_out; + unsigned p2p_in; + unsigned p2p_iter; + unsigned load_state; + unsigned src_offset; + unsigned dst_offset; }; -#define SVD_IOC_ACCESS _IOW ('S', 0, struct svd_access) +#define SVD_IOC_ACCESS _IOW('S', 0, struct svd_access) #endif /* _SVD_VIVADO_H_ */ diff --git a/rtl/caches/cachepackage.vhd b/rtl/caches/cachepackage.vhd index 0d0d8a6cc6..aa15b39066 100644 --- a/rtl/caches/cachepackage.vhd +++ b/rtl/caches/cachepackage.vhd @@ -2,16 +2,16 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.esp_global.all; -use work.amba.all; -use work.stdlib.all; -use work.gencomp.all; -use work.nocpackage.all; -use work.misc.all; -use work.monitor_pkg.all; -use work.allcaches.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.esp_global.all; + use work.amba.all; + use work.stdlib.all; + use work.gencomp.all; + use work.nocpackage.all; + use work.misc.all; + use work.monitor_pkg.all; + use work.allcaches.all; package cachepackage is @@ -34,7 +34,7 @@ package cachepackage is constant AS_AHBS_INV_FIFO : integer := 11; constant AS_AHBS_NON_CACHEABLE : integer := 12; - constant AS_INV_STATE : integer := 13; + constant AS_INV_STATE : integer := 13; -- constant AS_AHBM_ : integer := 0; -- constant AS_REQ_ : integer := 0; @@ -70,16 +70,16 @@ package cachepackage is -- Ongoing transaction buffers constant N_REQS : integer := 4; - constant LINE_RANGE_HI : integer := (ADDR_BITS - 1); - constant LINE_RANGE_LO : integer := (OFFSET_BITS); - constant OFF_RANGE_HI : integer := (OFFSET_BITS - 1); - constant OFF_RANGE_LO : integer := 0; - constant W_OFF_RANGE_HI : integer := (OFFSET_BITS - 1); - constant W_OFF_RANGE_LO : integer := (OFFSET_BITS - WORD_OFFSET_BITS); + constant LINE_RANGE_HI : integer := (ADDR_BITS - 1); + constant LINE_RANGE_LO : integer := (OFFSET_BITS); + constant OFF_RANGE_HI : integer := (OFFSET_BITS - 1); + constant OFF_RANGE_LO : integer := 0; + constant W_OFF_RANGE_HI : integer := (OFFSET_BITS - 1); + constant W_OFF_RANGE_LO : integer := (OFFSET_BITS - WORD_OFFSET_BITS); constant DMA_OFF_RANGE_HI : integer := (OFFSET_BITS - 1); constant DMA_OFF_RANGE_LO : integer := (OFFSET_BITS - DMA_WORD_OFFSET_BITS); - constant B_OFF_RANGE_HI : integer := (BYTE_OFFSET_BITS - 1); - constant B_OFF_RANGE_LO : integer := 0; + constant B_OFF_RANGE_HI : integer := (BYTE_OFFSET_BITS - 1); + constant B_OFF_RANGE_LO : integer := 0; ----------------------------------------------------------------------------- -- Types @@ -105,8 +105,8 @@ package cachepackage is -- subtype llc_set_t is std_logic_vector(SET_BITS - 1 downto 0); subtype invack_cnt_t is std_logic_vector(INVACK_CNT_WIDTH - 1 downto 0); subtype invack_cnt_calc_t is std_logic_vector(INVACK_CNT_CALC_WIDTH - 1 downto 0); - --subtype asserts_t is std_logic_vector(ASSERTS_WIDTH - 1 downto 0); - --subtype llc_asserts_t is std_logic_vector(LLC_ASSERTS_WIDTH - 1 downto 0); + -- subtype asserts_t is std_logic_vector(ASSERTS_WIDTH - 1 downto 0); + -- subtype llc_asserts_t is std_logic_vector(LLC_ASSERTS_WIDTH - 1 downto 0); subtype asserts_ahbs_t is std_logic_vector(ASSERTS_AHBS_WIDTH - 1 downto 0); subtype asserts_ahbm_t is std_logic_vector(ASSERTS_AHBM_WIDTH - 1 downto 0); subtype asserts_req_t is std_logic_vector(ASSERTS_REQ_WIDTH - 1 downto 0); @@ -114,9 +114,9 @@ package cachepackage is subtype asserts_fwd_t is std_logic_vector(ASSERTS_FWD_WIDTH - 1 downto 0); subtype asserts_rsp_out_t is std_logic_vector(ASSERTS_RSP_OUT_WIDTH - 1 downto 0); subtype asserts_llc_ahbm_t is std_logic_vector(ASSERTS_LLC_AHBM_WIDTH - 1 downto 0); - --subtype bookmark_t is std_logic_vector(BOOKMARK_WIDTH - 1 downto 0); - --subtype llc_bookmark_t is std_logic_vector(LLC_BOOKMARK_WIDTH - 1 downto 0); - --subtype custom_dbg_t is std_logic_vector(31 downto 0); + -- subtype bookmark_t is std_logic_vector(BOOKMARK_WIDTH - 1 downto 0); + -- subtype llc_bookmark_t is std_logic_vector(LLC_BOOKMARK_WIDTH - 1 downto 0); + -- subtype custom_dbg_t is std_logic_vector(31 downto 0); subtype cache_id_t is std_logic_vector(NL2_MAX_LOG2 - 1 downto 0); subtype llc_coh_dev_id_t is std_logic_vector(NLLC_MAX_LOG2 - 1 downto 0); -- hprot @@ -127,51 +127,85 @@ package cachepackage is constant HSIZE_HW : hsize_t := "001"; constant HSIZE_W : hsize_t := "010"; - constant dma_words : integer := DMA_NOC_WIDTH / 32; + constant DMA_WORDS : integer := DMA_NOC_WIDTH / 32; -- Constants to handle special case in which there is no memory tile -- In this case LLC and memory-related components won't be present in the -- system. This constant simply fixes CAD tools complains about null ranges - constant MEM_ID_RANGE_MSB : integer := set_mem_id_range; + constant MEM_ID_RANGE_MSB : integer := set_mem_id_range; constant SLMDDR_ID_RANGE_MSB : integer := set_slmddr_id_range; ----------------------------------------------------------------------------- -- Functions ----------------------------------------------------------------------------- - function read_from_line (addr : addr_t; line : line_t) + + function read_from_line ( + addr : addr_t; + line : line_t + ) return word_t; - function read_word (line : line_t; w_off : integer) + function read_word ( + line : line_t; + w_off : integer + ) return word_t; - function read_coh_noc_word (line : line_t; w_off : integer) + function read_coh_noc_word ( + line : line_t; + w_off : integer + ) return coh_noc_word_t; - function read_dma_noc_word (line : line_t; w_off : integer) + function read_dma_noc_word ( + line : line_t; + w_off : integer + ) return dma_noc_word_t; - function read_word32 (line : line_t; w_off : integer; w32_off : integer) + function read_word32 ( + line : line_t; + w_off : integer; + w32_off : integer + ) return dma_noc_word_t; - function make_header (coh_msg : coh_msg_t; mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); - mem_num : integer; hprot : hprot_t; addr : line_addr_t; - local_x : local_yx; local_y : local_yx; - to_req : std_ulogic; req_id : cache_id_t; - cache_x : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - cache_y : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - word_mask : word_mask_t) + function make_header ( + coh_msg : coh_msg_t; + mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); + mem_num : integer; + hprot : hprot_t; + addr : line_addr_t; + local_x : local_yx; + local_y : local_yx; + to_req : std_ulogic; + req_id : cache_id_t; + cache_x : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + cache_y : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + word_mask : word_mask_t + ) return coh_noc_flit_type; - function make_dcs_header (coh_msg : coh_msg_t; mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); - mem_num : integer; hprot : hprot_t; addr : line_addr_t; - local_x : local_yx; local_y : local_yx; - to_req : std_ulogic; req_id : cache_id_t; src_id : cache_id_t; - cache_x : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - cache_y : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - word_mask : word_mask_t) + function make_dcs_header ( + coh_msg : coh_msg_t; + mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); + mem_num : integer; + hprot : hprot_t; + addr : line_addr_t; + local_x : local_yx; + local_y : local_yx; + to_req : std_ulogic; + req_id : cache_id_t; + src_id : cache_id_t; + cache_x : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + cache_y : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + word_mask : word_mask_t + ) return coh_noc_flit_type; - function get_owner_bits (ncpu_bits : integer) + function get_owner_bits ( + ncpu_bits : integer + ) return integer; ----------------------------------------------------------------------------- @@ -180,137 +214,139 @@ package cachepackage is component l2_wrapper is generic ( - tech : integer := virtex7; - sets : integer := 256; - ways : integer := 8; - little_end : integer range 0 to 1 := 1; - hindex_mst : integer := 0; - pindex : integer range 0 to NAPBSLV - 1 := 6; - pirq : integer := 4; - mem_hindex : integer := 4; - mem_hconfig : ahb_config_type; - mem_num : integer := 1; - mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); - cache_y : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - cache_x : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - cache_tile_id : cache_attribute_array); + tech : integer := virtex7; + sets : integer := 256; + ways : integer := 8; + little_end : integer range 0 to 1 := 1; + hindex_mst : integer := 0; + pindex : integer range 0 to NAPBSLV - 1 := 6; + pirq : integer := 4; + mem_hindex : integer := 4; + mem_hconfig : ahb_config_type; + mem_num : integer := 1; + mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); + cache_y : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + cache_x : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + cache_tile_id : cache_attribute_array + ); port ( - rst : in std_ulogic; - clk : in std_ulogic; + rst : in std_ulogic; + clk : in std_ulogic; - local_y : in local_yx; - local_x : in local_yx; - pconfig : in apb_config_type; - cache_id : in integer; - tile_id : in integer range 0 to CFG_TILES_NUM - 1; + local_y : in local_yx; + local_x : in local_yx; + pconfig : in apb_config_type; + cache_id : in integer; + tile_id : in integer range 0 to CFG_TILES_NUM - 1; -- frontend (cache - AMBA) - ahbsi : in ahb_slv_in_type; - ahbso : out ahb_slv_out_type; - ahbmi : in ahb_mst_in_type; - ahbmo : out ahb_mst_out_type; - mosi : in axi_mosi_type; - somi : out axi_somi_type; - ace_req : out ace_req_type; - ace_resp: in ace_resp_type; - apbi : in apb_slv_in_type; - apbo : out apb_slv_out_type; - flush : in std_ulogic; -- flush request from CPU - flush_l1 : out std_ulogic; + ahbsi : in ahb_slv_in_type; + ahbso : out ahb_slv_out_type; + ahbmi : in ahb_mst_in_type; + ahbmo : out ahb_mst_out_type; + mosi : in axi_mosi_type; + somi : out axi_somi_type; + ace_req : out ace_req_type; + ace_resp : in ace_resp_type; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type; + flush : in std_ulogic; + flush_l1 : out std_ulogic; -- fence to L2 - fence_l2 : in std_logic_vector(1 downto 0); + fence_l2 : in std_logic_vector(1 downto 0); -- backend (cache - NoC) -- tile->NoC1 - coherence_req_wrreq : out std_ulogic; - coherence_req_data_in : out coh_noc_flit_type; - coherence_req_full : in std_ulogic; + coherence_req_wrreq : out std_ulogic; + coherence_req_data_in : out coh_noc_flit_type; + coherence_req_full : in std_ulogic; -- NoC2->tile - coherence_fwd_rdreq : out std_ulogic; - coherence_fwd_data_out : in coh_noc_flit_type; - coherence_fwd_empty : in std_ulogic; + coherence_fwd_rdreq : out std_ulogic; + coherence_fwd_data_out : in coh_noc_flit_type; + coherence_fwd_empty : in std_ulogic; -- Noc3->tile - coherence_rsp_rcv_rdreq : out std_ulogic; - coherence_rsp_rcv_data_out : in coh_noc_flit_type; - coherence_rsp_rcv_empty : in std_ulogic; + coherence_rsp_rcv_rdreq : out std_ulogic; + coherence_rsp_rcv_data_out : in coh_noc_flit_type; + coherence_rsp_rcv_empty : in std_ulogic; -- tile->Noc3 - coherence_rsp_snd_wrreq : out std_ulogic; - coherence_rsp_snd_data_in : out coh_noc_flit_type; - coherence_rsp_snd_full : in std_ulogic; + coherence_rsp_snd_wrreq : out std_ulogic; + coherence_rsp_snd_data_in : out coh_noc_flit_type; + coherence_rsp_snd_full : in std_ulogic; -- tile->Noc3 - coherence_fwd_snd_wrreq : out std_ulogic; - coherence_fwd_snd_data_in : out coh_noc_flit_type; - coherence_fwd_snd_full : in std_ulogic; + coherence_fwd_snd_wrreq : out std_ulogic; + coherence_fwd_snd_data_in : out coh_noc_flit_type; + coherence_fwd_snd_full : in std_ulogic; - mon_cache : out monitor_cache_type - ); + mon_cache : out monitor_cache_type + ); end component; component l2_acc_wrapper is generic ( - tech : integer := virtex7; - sets : integer := 256; - ways : integer := 8; - little_end : integer range 0 to 1 := 1; - mem_num : integer := 1; - mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); - cache_y : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - cache_x : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - cache_tile_id : cache_attribute_array); + tech : integer := virtex7; + sets : integer := 256; + ways : integer := 8; + little_end : integer range 0 to 1 := 1; + mem_num : integer := 1; + mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); + cache_y : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + cache_x : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + cache_tile_id : cache_attribute_array + ); port ( - rst : in std_ulogic; - clk : in std_ulogic; + rst : in std_ulogic; + clk : in std_ulogic; - local_y : in local_yx; - local_x : in local_yx; - tile_id : in integer range 0 to CFG_TILES_NUM - 1; + local_y : in local_yx; + local_x : in local_yx; + tile_id : in integer range 0 to CFG_TILES_NUM - 1; -- frontend (cache - Accelerator DMA) -- header / lenght parallel ports - dma_read : in std_ulogic; - dma_write : in std_ulogic; - dma_length : in addr_t; - dma_address : in addr_t; - dma_ready : out std_ulogic; + dma_read : in std_ulogic; + dma_write : in std_ulogic; + dma_length : in addr_t; + dma_address : in addr_t; + dma_ready : out std_ulogic; -- cahce->acc (data only) - dma_rcv_ready : in std_ulogic; - dma_rcv_data : out dma_noc_flit_type; - dma_rcv_valid : out std_ulogic; + dma_rcv_ready : in std_ulogic; + dma_rcv_data : out dma_noc_flit_type; + dma_rcv_valid : out std_ulogic; -- acc->cache (data only) - dma_snd_valid : in std_ulogic; - dma_snd_data : in dma_noc_flit_type; - dma_snd_ready : out std_ulogic; + dma_snd_valid : in std_ulogic; + dma_snd_data : in dma_noc_flit_type; + dma_snd_ready : out std_ulogic; -- Accelerator done causes a flush - flush : in std_ulogic; - aq : in std_ulogic; - rl : in std_ulogic; - spandex_conf : in std_logic_vector(31 downto 0); - acc_flush_done : out std_ulogic; + flush : in std_ulogic; + aq : in std_ulogic; + rl : in std_ulogic; + spandex_conf : in std_logic_vector(31 downto 0); + acc_flush_done : out std_ulogic; -- backend (cache - NoC) -- tile->NoC1 - coherence_req_wrreq : out std_ulogic; - coherence_req_data_in : out coh_noc_flit_type; - coherence_req_full : in std_ulogic; + coherence_req_wrreq : out std_ulogic; + coherence_req_data_in : out coh_noc_flit_type; + coherence_req_full : in std_ulogic; -- NoC2->tile - coherence_fwd_rdreq : out std_ulogic; - coherence_fwd_data_out : in coh_noc_flit_type; - coherence_fwd_empty : in std_ulogic; + coherence_fwd_rdreq : out std_ulogic; + coherence_fwd_data_out : in coh_noc_flit_type; + coherence_fwd_empty : in std_ulogic; -- Noc3->tile - coherence_rsp_rcv_rdreq : out std_ulogic; - coherence_rsp_rcv_data_out : in coh_noc_flit_type; - coherence_rsp_rcv_empty : in std_ulogic; + coherence_rsp_rcv_rdreq : out std_ulogic; + coherence_rsp_rcv_data_out : in coh_noc_flit_type; + coherence_rsp_rcv_empty : in std_ulogic; -- tile->Noc3 - coherence_rsp_snd_wrreq : out std_ulogic; - coherence_rsp_snd_data_in : out coh_noc_flit_type; - coherence_rsp_snd_full : in std_ulogic; + coherence_rsp_snd_wrreq : out std_ulogic; + coherence_rsp_snd_data_in : out coh_noc_flit_type; + coherence_rsp_snd_full : in std_ulogic; -- tile->Noc3 - coherence_fwd_snd_wrreq : out std_ulogic; - coherence_fwd_snd_data_in : out coh_noc_flit_type; - coherence_fwd_snd_full : in std_ulogic; + coherence_fwd_snd_wrreq : out std_ulogic; + coherence_fwd_snd_data_in : out coh_noc_flit_type; + coherence_fwd_snd_full : in std_ulogic; - mon_cache : out monitor_cache_type - ); + mon_cache : out monitor_cache_type + ); end component; ----------------------------------------------------------------------------- @@ -319,104 +355,108 @@ package cachepackage is component llc_wrapper is generic ( - tech : integer := virtex7; - sets : integer := 256; - ways : integer := 16; - ahb_if_en : integer range 0 to 1 := 1; - nl2 : integer := 4; - nllc : integer := 1; - noc_xlen : integer := 2; - noc_ylen : integer := 2; - hindex : integer range 0 to NAHBSLV - 1 := 4; - pindex : integer range 0 to NAPBSLV - 1 := 5; - pirq : integer := 4; - cacheline : integer; - little_end : integer range 0 to 1 := 0; - l2_cache_en : integer := 0; + tech : integer := virtex7; + sets : integer := 256; + ways : integer := 16; + ahb_if_en : integer range 0 to 1 := 1; + nl2 : integer := 4; + nllc : integer := 1; + noc_xlen : integer := 2; + noc_ylen : integer := 2; + hindex : integer range 0 to NAHBSLV - 1 := 4; + pindex : integer range 0 to NAPBSLV - 1 := 5; + pirq : integer := 4; + cacheline : integer; + little_end : integer range 0 to 1 := 0; + l2_cache_en : integer := 0; cache_tile_id : cache_attribute_array; dma_tile_id : dma_attribute_array; tile_cache_id : attribute_vector(0 to CFG_TILES_NUM - 1); tile_dma_id : attribute_vector(0 to CFG_TILES_NUM - 1); eth_dma_id : integer; - dma_y : yx_vec(0 to 2**NLLC_MAX_LOG2 - 1); - dma_x : yx_vec(0 to 2**NLLC_MAX_LOG2 - 1); - cache_y : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - cache_x : yx_vec(0 to 2**NL2_MAX_LOG2 - 1)); + dma_y : yx_vec(0 to 2 ** NLLC_MAX_LOG2 - 1); + dma_x : yx_vec(0 to 2 ** NLLC_MAX_LOG2 - 1); + cache_y : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + cache_x : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1) + ); port ( - rst : in std_ulogic; - clk : in std_ulogic; + rst : in std_ulogic; + clk : in std_ulogic; - local_y : in local_yx; - local_x : in local_yx; - pconfig : in apb_config_type; + local_y : in local_yx; + local_x : in local_yx; + pconfig : in apb_config_type; - ahbmi : in ahb_mst_in_type; - ahbmo : out ahb_mst_out_type; - apbi : in apb_slv_in_type; - apbo : out apb_slv_out_type; + ahbmi : in ahb_mst_in_type; + ahbmo : out ahb_mst_out_type; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type; -- NoC1->tile - coherence_req_rdreq : out std_ulogic; - coherence_req_data_out : in coh_noc_flit_type; - coherence_req_empty : in std_ulogic; + coherence_req_rdreq : out std_ulogic; + coherence_req_data_out : in coh_noc_flit_type; + coherence_req_empty : in std_ulogic; -- tile->NoC2 - coherence_fwd_wrreq : out std_ulogic; - coherence_fwd_data_in : out coh_noc_flit_type; - coherence_fwd_full : in std_ulogic; + coherence_fwd_wrreq : out std_ulogic; + coherence_fwd_data_in : out coh_noc_flit_type; + coherence_fwd_full : in std_ulogic; -- tile->NoC3 - coherence_rsp_snd_wrreq : out std_ulogic; - coherence_rsp_snd_data_in : out coh_noc_flit_type; - coherence_rsp_snd_full : in std_ulogic; + coherence_rsp_snd_wrreq : out std_ulogic; + coherence_rsp_snd_data_in : out coh_noc_flit_type; + coherence_rsp_snd_full : in std_ulogic; -- NoC3->tile - coherence_rsp_rcv_rdreq : out std_ulogic; - coherence_rsp_rcv_data_out : in coh_noc_flit_type; - coherence_rsp_rcv_empty : in std_ulogic; + coherence_rsp_rcv_rdreq : out std_ulogic; + coherence_rsp_rcv_data_out : in coh_noc_flit_type; + coherence_rsp_rcv_empty : in std_ulogic; -- -- NoC4->tile - dma_rcv_rdreq : out std_ulogic; - dma_rcv_data_out : in dma_noc_flit_type; - dma_rcv_empty : in std_ulogic; + dma_rcv_rdreq : out std_ulogic; + dma_rcv_data_out : in dma_noc_flit_type; + dma_rcv_empty : in std_ulogic; -- -- tile->NoC4 - dma_snd_wrreq : out std_ulogic; - dma_snd_data_in : out dma_noc_flit_type; - dma_snd_full : in std_ulogic; + dma_snd_wrreq : out std_ulogic; + dma_snd_data_in : out dma_noc_flit_type; + dma_snd_full : in std_ulogic; -- LLC->ext - ext_req_ready : in std_ulogic; - ext_req_valid : out std_ulogic; - ext_req_data : out std_logic_vector(CFG_MEM_LINK_BITS - 1 downto 0); + ext_req_ready : in std_ulogic; + ext_req_valid : out std_ulogic; + ext_req_data : out std_logic_vector(CFG_MEM_LINK_BITS - 1 downto 0); -- ext->LLC - ext_rsp_ready : out std_ulogic; - ext_rsp_valid : in std_ulogic; - ext_rsp_data : in std_logic_vector(CFG_MEM_LINK_BITS- 1 downto 0); - mon_cache : out monitor_cache_type - ); + ext_rsp_ready : out std_ulogic; + ext_rsp_valid : in std_ulogic; + ext_rsp_data : in std_logic_vector(CFG_MEM_LINK_BITS - 1 downto 0); + mon_cache : out monitor_cache_type + ); end component; - component fifo_custom is - generic( + generic ( depth : integer := 5; - width : integer := 18); - port( - clk : in std_logic; - rst : in std_logic; - - rdreq : in std_logic; - wrreq : in std_logic; - data_in : in std_logic_vector(width-1 downto 0); - - --request registers - empty : out std_logic; - full : out std_logic; - almost_empty : out std_logic; - data_out : out std_logic_vector(width-1 downto 0)); - + width : integer := 18 + ); + port ( + clk : in std_logic; + rst : in std_logic; + + rdreq : in std_logic; + wrreq : in std_logic; + data_in : in std_logic_vector(width - 1 downto 0); + + -- request registers + empty : out std_logic; + full : out std_logic; + almost_empty : out std_logic; + data_out : out std_logic_vector(width - 1 downto 0) + ); end component; -end cachepackage; +end package cachepackage; package body cachepackage is - function read_from_line (addr : addr_t; line : line_t) return word_t is + function read_from_line ( + addr : addr_t; + line : line_t + ) return word_t is variable w_off : integer; variable word : word_t; @@ -424,15 +464,18 @@ package body cachepackage is begin w_off := to_integer(unsigned(addr(W_OFF_RANGE_HI downto W_OFF_RANGE_LO))); - word := read_word(line, w_off); + word := read_word(line, w_off); return word; end function read_from_line; - function read_word (line : line_t; w_off : integer) return word_t is + function read_word ( + line : line_t; + w_off : integer + ) return word_t is - variable word : word_t; + variable word : word_t; begin @@ -442,9 +485,12 @@ package body cachepackage is end function read_word; - function read_coh_noc_word (line : line_t; w_off : integer) return coh_noc_word_t is + function read_coh_noc_word ( + line : line_t; + w_off : integer + ) return coh_noc_word_t is - variable word : coh_noc_word_t; + variable word : coh_noc_word_t; begin @@ -454,9 +500,12 @@ package body cachepackage is end function read_coh_noc_word; - function read_dma_noc_word (line : line_t; w_off : integer) return dma_noc_word_t is + function read_dma_noc_word ( + line : line_t; + w_off : integer + ) return dma_noc_word_t is - variable word : dma_noc_word_t; + variable word : dma_noc_word_t; begin @@ -466,140 +515,163 @@ package body cachepackage is end function read_dma_noc_word; - function read_word32 (line : line_t; w_off : integer; w32_off : integer) return dma_noc_word_t is + function read_word32 ( + line : line_t; + w_off : integer; + w32_off : integer + ) return dma_noc_word_t is - variable word : dma_noc_word_t; + variable word : dma_noc_word_t; begin - word := (others => '0'); + word := (others => '0'); word(31 downto 0) := line((w_off * DMA_NOC_WIDTH) + (w32_off * 32) + 32 - 1 downto (w_off * DMA_NOC_WIDTH) + (w32_off * 32)); return word; end function read_word32; - function make_header (coh_msg : coh_msg_t; mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); - mem_num : integer; hprot : hprot_t; addr : line_addr_t; - local_x : local_yx; local_y : local_yx; - to_req : std_ulogic; req_id : cache_id_t; - cache_x : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - cache_y : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - word_mask : word_mask_t) + function make_header ( + coh_msg : coh_msg_t; + mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); + mem_num : integer; + hprot : hprot_t; + addr : line_addr_t; + local_x : local_yx; + local_y : local_yx; + to_req : std_ulogic; + req_id : cache_id_t; + cache_x : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + cache_y : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + word_mask : word_mask_t + ) return coh_noc_flit_type is variable header : coh_noc_flit_type; variable dest_x, dest_y : local_yx; variable dest_init : integer; - variable reserved : std_logic_vector(RESERVED_WIDTH-1 downto 0); + variable reserved : std_logic_vector(RESERVED_WIDTH - 1 downto 0); variable noc_msg : noc_msg_type; begin - if to_req = '0' then - + if (to_req = '0') then dest_x := mem_info(0).x; dest_y := mem_info(0).y; - if mem_num /= 1 then + if (mem_num /= 1) then + for i in 0 to mem_num - 1 loop - if ((addr(LINE_ADDR_BITS - 1 downto LINE_ADDR_BITS - 12) - xor conv_std_logic_vector(mem_info(i).haddr, 12)) - and conv_std_logic_vector(mem_info(i).hmask, 12)) = x"000" then + + if (((addr(LINE_ADDR_BITS - 1 downto LINE_ADDR_BITS - 12) + xor conv_std_logic_vector(mem_info(i).haddr, 12)) + and conv_std_logic_vector(mem_info(i).hmask, 12)) = x"000") then dest_x := mem_info(i).x; dest_y := mem_info(i).y; end if; + end loop; - end if; + end if; else - - if req_id >= "0" then + if (req_id >= "0") then dest_init := to_integer(unsigned(req_id)); - if dest_init >= 0 then + if (dest_init >= 0) then dest_x := cache_x(dest_init); dest_y := cache_y(dest_init); end if; end if; - end if; -- compose header - if USE_SPANDEX = 0 then - noc_msg := '1' & coh_msg; + if (USE_SPANDEX = 0) then + noc_msg := '1' & coh_msg; reserved := std_logic_vector(resize(unsigned(hprot), RESERVED_WIDTH)); else - noc_msg := '0' & coh_msg; + noc_msg := '0' & coh_msg; reserved := word_mask & std_logic_vector(resize(unsigned(hprot), RESERVED_WIDTH - WORDS_PER_LINE)); end if; + header := create_header(COH_NOC_FLIT_SIZE, local_y, local_x, dest_y, dest_x, noc_msg, reserved); return header; end function make_header; - function make_dcs_header (coh_msg : coh_msg_t; mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); - mem_num : integer; hprot : hprot_t; addr : line_addr_t; - local_x : local_yx; local_y : local_yx; - to_req : std_ulogic; req_id : cache_id_t; src_id : cache_id_t; - cache_x : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - cache_y : yx_vec(0 to 2**NL2_MAX_LOG2 - 1); - word_mask : word_mask_t) + function make_dcs_header ( + coh_msg : coh_msg_t; + mem_info : tile_mem_info_vector(0 to MEM_ID_RANGE_MSB); + mem_num : integer; + hprot : hprot_t; + addr : line_addr_t; + local_x : local_yx; + local_y : local_yx; + to_req : std_ulogic; + req_id : cache_id_t; + src_id : cache_id_t; + cache_x : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + cache_y : yx_vec(0 to 2 ** NL2_MAX_LOG2 - 1); + word_mask : word_mask_t + ) return coh_noc_flit_type is variable header : coh_noc_flit_type; variable dest_x, dest_y : local_yx; variable dest_init : integer; - variable reserved : std_logic_vector(RESERVED_WIDTH-1 downto 0); + variable reserved : std_logic_vector(RESERVED_WIDTH - 1 downto 0); begin - if to_req = '0' then - + if (to_req = '0') then dest_x := mem_info(0).x; dest_y := mem_info(0).y; - if mem_num /= 1 then + if (mem_num /= 1) then + for i in 0 to mem_num - 1 loop - if ((addr(LINE_ADDR_BITS - 1 downto LINE_ADDR_BITS - 12) - xor conv_std_logic_vector(mem_info(i).haddr, 12)) - and conv_std_logic_vector(mem_info(i).hmask, 12)) = x"000" then + + if (((addr(LINE_ADDR_BITS - 1 downto LINE_ADDR_BITS - 12) + xor conv_std_logic_vector(mem_info(i).haddr, 12)) + and conv_std_logic_vector(mem_info(i).hmask, 12)) = x"000") then dest_x := mem_info(i).x; dest_y := mem_info(i).y; end if; + end loop; - end if; + end if; else - - if req_id >= "0" then + if (req_id >= "0") then dest_init := to_integer(unsigned(req_id)); - if dest_init >= 0 then + if (dest_init >= 0) then dest_x := cache_x(dest_init); dest_y := cache_y(dest_init); end if; end if; - end if; -- compose header - if USE_SPANDEX = 0 then + if (USE_SPANDEX = 0) then reserved := std_logic_vector(resize(unsigned(src_id), RESERVED_WIDTH)); else reserved := word_mask & std_logic_vector(resize(unsigned(src_id), RESERVED_WIDTH - WORDS_PER_LINE)); end if; + header := create_header(COH_NOC_FLIT_SIZE, local_y, local_x, dest_y, dest_x, '0' & coh_msg, reserved); return header; end function make_dcs_header; - function get_owner_bits (ncpu_bits : integer) + function get_owner_bits ( + ncpu_bits : integer + ) return integer is variable owner_bits : integer; - + begin - if ncpu_bits = 0 then + if (ncpu_bits = 0) then owner_bits := 1; else owner_bits := ncpu_bits; @@ -609,5 +681,4 @@ package body cachepackage is end function get_owner_bits; - end package body cachepackage; diff --git a/rtl/cores/ariane/ariane_axi_wrap.vhd b/rtl/cores/ariane/ariane_axi_wrap.vhd index 4123ce6220..bbec0e2b02 100644 --- a/rtl/cores/ariane/ariane_axi_wrap.vhd +++ b/rtl/cores/ariane/ariane_axi_wrap.vhd @@ -2,337 +2,335 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; - -use work.esp_global.all; -use work.stdlib.all; -use work.amba.all; -use work.ariane_esp_pkg.all; - + use ieee.std_logic_1164.all; + use work.esp_global.all; + use work.stdlib.all; + use work.amba.all; + use work.ariane_esp_pkg.all; entity ariane_axi_wrap is generic ( - NMST : integer := 2; - NSLV : integer := 6; - ROMBase : std_logic_vector(63 downto 0) := X"0000_0000_0001_0000"; - ROMLength : std_logic_vector(63 downto 0) := X"0000_0000_0001_0000"; - APBBase : std_logic_vector(63 downto 0) := X"0000_0000_6000_0000"; - APBLength : std_logic_vector(63 downto 0) := X"0000_0000_1000_0000"; - CLINTBase : std_logic_vector(63 downto 0) := X"0000_0000_0200_0000"; - CLINTLength : std_logic_vector(63 downto 0) := X"0000_0000_000C_0000"; - SLMBase : std_logic_vector(63 downto 0) := X"0000_0000_0400_0000"; - SLMLength : std_logic_vector(63 downto 0) := X"0000_0000_0400_0000"; - SLMDDRBase : std_logic_vector(63 downto 0) := X"0000_0000_C000_0000"; - SLMDDRLength : std_logic_vector(63 downto 0) := X"0000_0000_4000_0000"; - DRAMBase : std_logic_vector(63 downto 0) := X"0000_0000_8000_0000"; - DRAMLength : std_logic_vector(63 downto 0) := X"0000_0000_2000_0000"; - DRAMCachedLength : std_logic_vector(63 downto 0) := X"0000_0000_2000_0000"); + nmst : integer := 2; + nslv : integer := 6; + rombase : std_logic_vector(63 downto 0) := X"0000_0000_0001_0000"; + romlength : std_logic_vector(63 downto 0) := X"0000_0000_0001_0000"; + apbbase : std_logic_vector(63 downto 0) := X"0000_0000_6000_0000"; + apblength : std_logic_vector(63 downto 0) := X"0000_0000_1000_0000"; + clintbase : std_logic_vector(63 downto 0) := X"0000_0000_0200_0000"; + clintlength : std_logic_vector(63 downto 0) := X"0000_0000_000C_0000"; + slmbase : std_logic_vector(63 downto 0) := X"0000_0000_0400_0000"; + slmlength : std_logic_vector(63 downto 0) := X"0000_0000_0400_0000"; + slmddrbase : std_logic_vector(63 downto 0) := X"0000_0000_C000_0000"; + slmddrlength : std_logic_vector(63 downto 0) := X"0000_0000_4000_0000"; + drambase : std_logic_vector(63 downto 0) := X"0000_0000_8000_0000"; + dramlength : std_logic_vector(63 downto 0) := X"0000_0000_2000_0000"; + dramcachedlength : std_logic_vector(63 downto 0) := X"0000_0000_2000_0000" + ); port ( - clk : in std_logic; - rstn : in std_logic; - HART_ID : in std_logic_vector(63 downto 0); - irq : in std_logic_vector(1 downto 0); - timer_irq : in std_logic; - ipi : in std_logic; - romi : out axi_mosi_type; - romo : in axi_somi_type; - drami : out axi_mosi_type; - dramo : in axi_somi_type; - clinti : out axi_mosi_type; - clinto : in axi_somi_type; - slmi : out axi_mosi_type; - slmo : in axi_somi_type; - slmddri : out axi_mosi_type; - slmddro : in axi_somi_type; - apbi : out apb_slv_in_type; - apbo : in apb_slv_out_vector; - apb_req : out std_ulogic; - apb_ack : in std_ulogic; - ace_req : in ace_req_type; - ace_resp : out ace_resp_type; - fence_l2 : out std_logic_vector(1 downto 0); - flush_l1 : in std_logic; - flush_done : out std_logic - ); - -end ariane_axi_wrap; - + clk : in std_logic; + rstn : in std_logic; + hart_id : in std_logic_vector(63 downto 0); + irq : in std_logic_vector(1 downto 0); + timer_irq : in std_logic; + ipi : in std_logic; + romi : out axi_mosi_type; + romo : in axi_somi_type; + drami : out axi_mosi_type; + dramo : in axi_somi_type; + clinti : out axi_mosi_type; + clinto : in axi_somi_type; + slmi : out axi_mosi_type; + slmo : in axi_somi_type; + slmddri : out axi_mosi_type; + slmddro : in axi_somi_type; + apbi : out apb_slv_in_type; + apbo : in apb_slv_out_vector; + apb_req : out std_ulogic; + apb_ack : in std_ulogic; + ace_req : in ace_req_type; + ace_resp : out ace_resp_type; + fence_l2 : out std_logic_vector(1 downto 0); + flush_l1 : in std_logic; + flush_done : out std_logic + ); +end entity ariane_axi_wrap; architecture rtl of ariane_axi_wrap is component ariane_wrap is generic ( - NMST : integer; - NSLV : integer; - AXI_ID_WIDTH : integer; - AXI_ID_WIDTH_SLV : integer; - AXI_ADDR_WIDTH : integer; - AXI_DATA_WIDTH : integer; - AXI_USER_WIDTH : integer; - AXI_STRB_WIDTH : integer; - USE_SPANDEX : integer; - ROMBase : std_logic_vector(63 downto 0); - ROMLength : std_logic_vector(63 downto 0); - APBBase : std_logic_vector(63 downto 0); - APBLength : std_logic_vector(63 downto 0); - CLINTBase : std_logic_vector(63 downto 0); - CLINTLength : std_logic_vector(63 downto 0); - SLMBase : std_logic_vector(63 downto 0); - SLMLength : std_logic_vector(63 downto 0); - SLMDDRBase : std_logic_vector(63 downto 0); - SLMDDRLength : std_logic_vector(63 downto 0); - DRAMBase : std_logic_vector(63 downto 0); - DRAMLength : std_logic_vector(63 downto 0); - DRAMCachedLength : std_logic_vector(63 downto 0)); + nmst : integer; + nslv : integer; + axi_id_width : integer; + axi_id_width_slv : integer; + axi_addr_width : integer; + axi_data_width : integer; + axi_user_width : integer; + axi_strb_width : integer; + use_spandex : integer; + rombase : std_logic_vector(63 downto 0); + romlength : std_logic_vector(63 downto 0); + apbbase : std_logic_vector(63 downto 0); + apblength : std_logic_vector(63 downto 0); + clintbase : std_logic_vector(63 downto 0); + clintlength : std_logic_vector(63 downto 0); + slmbase : std_logic_vector(63 downto 0); + slmlength : std_logic_vector(63 downto 0); + slmddrbase : std_logic_vector(63 downto 0); + slmddrlength : std_logic_vector(63 downto 0); + drambase : std_logic_vector(63 downto 0); + dramlength : std_logic_vector(63 downto 0); + dramcachedlength : std_logic_vector(63 downto 0) + ); port ( - clk : in std_logic; - rstn : in std_logic; - HART_ID : in std_logic_vector(63 downto 0); - irq : in std_logic_vector(1 downto 0); - timer_irq : in std_logic; - ipi : in std_logic; - rom_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - rom_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - rom_aw_len : out std_logic_vector(7 downto 0); - rom_aw_size : out std_logic_vector(2 downto 0); - rom_aw_burst : out std_logic_vector(1 downto 0); - rom_aw_lock : out std_logic; - rom_aw_cache : out std_logic_vector(3 downto 0); - rom_aw_prot : out std_logic_vector(2 downto 0); - rom_aw_qos : out std_logic_vector(3 downto 0); - rom_aw_atop : out std_logic_vector(5 downto 0); - rom_aw_region : out std_logic_vector(3 downto 0); - rom_aw_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - rom_aw_valid : out std_logic; - rom_aw_ready : in std_logic; - rom_w_data : out std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - rom_w_strb : out std_logic_vector(AXI_STRB_WIDTH-1 downto 0); - rom_w_last : out std_logic; - rom_w_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - rom_w_valid : out std_logic; - rom_w_ready : in std_logic; - rom_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - rom_b_resp : in std_logic_vector(1 downto 0); - rom_b_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - rom_b_valid : in std_logic; - rom_b_ready : out std_logic; - rom_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - rom_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - rom_ar_len : out std_logic_vector(7 downto 0); - rom_ar_size : out std_logic_vector(2 downto 0); - rom_ar_burst : out std_logic_vector(1 downto 0); - rom_ar_lock : out std_logic; - rom_ar_cache : out std_logic_vector(3 downto 0); - rom_ar_prot : out std_logic_vector(2 downto 0); - rom_ar_qos : out std_logic_vector(3 downto 0); - rom_ar_region : out std_logic_vector(3 downto 0); - rom_ar_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - rom_ar_valid : out std_logic; - rom_ar_ready : in std_logic; - rom_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - rom_r_data : in std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - rom_r_resp : in std_logic_vector(1 downto 0); - rom_r_last : in std_logic; - rom_r_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - rom_r_valid : in std_logic; - rom_r_ready : out std_logic; - dram_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - dram_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - dram_aw_len : out std_logic_vector(7 downto 0); - dram_aw_size : out std_logic_vector(2 downto 0); - dram_aw_burst : out std_logic_vector(1 downto 0); - dram_aw_lock : out std_logic; - dram_aw_cache : out std_logic_vector(3 downto 0); - dram_aw_prot : out std_logic_vector(2 downto 0); - dram_aw_qos : out std_logic_vector(3 downto 0); - dram_aw_atop : out std_logic_vector(5 downto 0); - dram_aw_region : out std_logic_vector(3 downto 0); - dram_aw_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - dram_aw_valid : out std_logic; - dram_aw_ready : in std_logic; - dram_ac_addr : in std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - dram_ac_prot : in std_logic_vector(2 downto 0); - dram_ac_snoop : in std_logic_vector(3 downto 0); - dram_ac_valid : in std_logic; - dram_ac_ready : out std_logic; - dram_w_data : out std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - dram_w_strb : out std_logic_vector(AXI_STRB_WIDTH-1 downto 0); - dram_w_last : out std_logic; - dram_w_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - dram_w_valid : out std_logic; - dram_w_ready : in std_logic; - dram_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - dram_b_resp : in std_logic_vector(1 downto 0); - dram_b_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - dram_b_valid : in std_logic; - dram_b_ready : out std_logic; - dram_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - dram_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - dram_ar_len : out std_logic_vector(7 downto 0); - dram_ar_size : out std_logic_vector(2 downto 0); - dram_ar_burst : out std_logic_vector(1 downto 0); - dram_ar_lock : out std_logic; - dram_ar_cache : out std_logic_vector(3 downto 0); - dram_ar_prot : out std_logic_vector(2 downto 0); - dram_ar_qos : out std_logic_vector(3 downto 0); - dram_ar_region : out std_logic_vector(3 downto 0); - dram_ar_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - dram_ar_valid : out std_logic; - dram_ar_ready : in std_logic; - dram_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - dram_r_data : in std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - dram_r_resp : in std_logic_vector(1 downto 0); - dram_r_last : in std_logic; - dram_r_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - dram_r_valid : in std_logic; - dram_r_ready : out std_logic; - clint_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - clint_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - clint_aw_len : out std_logic_vector(7 downto 0); - clint_aw_size : out std_logic_vector(2 downto 0); - clint_aw_burst : out std_logic_vector(1 downto 0); - clint_aw_lock : out std_logic; - clint_aw_cache : out std_logic_vector(3 downto 0); - clint_aw_prot : out std_logic_vector(2 downto 0); - clint_aw_qos : out std_logic_vector(3 downto 0); - clint_aw_atop : out std_logic_vector(5 downto 0); - clint_aw_region : out std_logic_vector(3 downto 0); - clint_aw_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - clint_aw_valid : out std_logic; - clint_aw_ready : in std_logic; - clint_w_data : out std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - clint_w_strb : out std_logic_vector(AXI_STRB_WIDTH-1 downto 0); - clint_w_last : out std_logic; - clint_w_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - clint_w_valid : out std_logic; - clint_w_ready : in std_logic; - clint_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - clint_b_resp : in std_logic_vector(1 downto 0); - clint_b_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - clint_b_valid : in std_logic; - clint_b_ready : out std_logic; - clint_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - clint_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - clint_ar_len : out std_logic_vector(7 downto 0); - clint_ar_size : out std_logic_vector(2 downto 0); - clint_ar_burst : out std_logic_vector(1 downto 0); - clint_ar_lock : out std_logic; - clint_ar_cache : out std_logic_vector(3 downto 0); - clint_ar_prot : out std_logic_vector(2 downto 0); - clint_ar_qos : out std_logic_vector(3 downto 0); - clint_ar_region : out std_logic_vector(3 downto 0); - clint_ar_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - clint_ar_valid : out std_logic; - clint_ar_ready : in std_logic; - clint_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - clint_r_data : in std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - clint_r_resp : in std_logic_vector(1 downto 0); - clint_r_last : in std_logic; - clint_r_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - clint_r_valid : in std_logic; - clint_r_ready : out std_logic; - slm_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - slm_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - slm_aw_len : out std_logic_vector(7 downto 0); - slm_aw_size : out std_logic_vector(2 downto 0); - slm_aw_burst : out std_logic_vector(1 downto 0); - slm_aw_lock : out std_logic; - slm_aw_cache : out std_logic_vector(3 downto 0); - slm_aw_prot : out std_logic_vector(2 downto 0); - slm_aw_qos : out std_logic_vector(3 downto 0); - slm_aw_atop : out std_logic_vector(5 downto 0); - slm_aw_region : out std_logic_vector(3 downto 0); - slm_aw_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slm_aw_valid : out std_logic; - slm_aw_ready : in std_logic; - slm_w_data : out std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - slm_w_strb : out std_logic_vector(AXI_STRB_WIDTH-1 downto 0); - slm_w_last : out std_logic; - slm_w_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slm_w_valid : out std_logic; - slm_w_ready : in std_logic; - slm_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - slm_b_resp : in std_logic_vector(1 downto 0); - slm_b_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slm_b_valid : in std_logic; - slm_b_ready : out std_logic; - slm_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - slm_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - slm_ar_len : out std_logic_vector(7 downto 0); - slm_ar_size : out std_logic_vector(2 downto 0); - slm_ar_burst : out std_logic_vector(1 downto 0); - slm_ar_lock : out std_logic; - slm_ar_cache : out std_logic_vector(3 downto 0); - slm_ar_prot : out std_logic_vector(2 downto 0); - slm_ar_qos : out std_logic_vector(3 downto 0); - slm_ar_region : out std_logic_vector(3 downto 0); - slm_ar_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slm_ar_valid : out std_logic; - slm_ar_ready : in std_logic; - slm_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - slm_r_data : in std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - slm_r_resp : in std_logic_vector(1 downto 0); - slm_r_last : in std_logic; - slm_r_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slm_r_valid : in std_logic; - slm_r_ready : out std_logic; - slmddr_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - slmddr_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - slmddr_aw_len : out std_logic_vector(7 downto 0); - slmddr_aw_size : out std_logic_vector(2 downto 0); - slmddr_aw_burst : out std_logic_vector(1 downto 0); - slmddr_aw_lock : out std_logic; - slmddr_aw_cache : out std_logic_vector(3 downto 0); - slmddr_aw_prot : out std_logic_vector(2 downto 0); - slmddr_aw_qos : out std_logic_vector(3 downto 0); - slmddr_aw_atop : out std_logic_vector(5 downto 0); - slmddr_aw_region : out std_logic_vector(3 downto 0); - slmddr_aw_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slmddr_aw_valid : out std_logic; - slmddr_aw_ready : in std_logic; - slmddr_w_data : out std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - slmddr_w_strb : out std_logic_vector(AXI_STRB_WIDTH-1 downto 0); - slmddr_w_last : out std_logic; - slmddr_w_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slmddr_w_valid : out std_logic; - slmddr_w_ready : in std_logic; - slmddr_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - slmddr_b_resp : in std_logic_vector(1 downto 0); - slmddr_b_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slmddr_b_valid : in std_logic; - slmddr_b_ready : out std_logic; - slmddr_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - slmddr_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH-1 downto 0); - slmddr_ar_len : out std_logic_vector(7 downto 0); - slmddr_ar_size : out std_logic_vector(2 downto 0); - slmddr_ar_burst : out std_logic_vector(1 downto 0); - slmddr_ar_lock : out std_logic; - slmddr_ar_cache : out std_logic_vector(3 downto 0); - slmddr_ar_prot : out std_logic_vector(2 downto 0); - slmddr_ar_qos : out std_logic_vector(3 downto 0); - slmddr_ar_region : out std_logic_vector(3 downto 0); - slmddr_ar_user : out std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slmddr_ar_valid : out std_logic; - slmddr_ar_ready : in std_logic; - slmddr_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV-1 downto 0); - slmddr_r_data : in std_logic_vector(AXI_DATA_WIDTH-1 downto 0); - slmddr_r_resp : in std_logic_vector(1 downto 0); - slmddr_r_last : in std_logic; - slmddr_r_user : in std_logic_vector(AXI_USER_WIDTH-1 downto 0); - slmddr_r_valid : in std_logic; - slmddr_r_ready : out std_logic; - penable : out std_logic; - pwrite : out std_logic; - paddr : out std_logic_vector(31 downto 0); - psel : out std_logic; - pwdata : out std_logic_vector(31 downto 0); - prdata : in std_logic_vector(31 downto 0); - pready : in std_logic; - pslverr : in std_logic; - fence_l2 : out std_logic_vector(1 downto 0); - flush_l1 : in std_logic; - flush_done : out std_logic - ); + clk : in std_logic; + rstn : in std_logic; + hart_id : in std_logic_vector(63 downto 0); + irq : in std_logic_vector(1 downto 0); + timer_irq : in std_logic; + ipi : in std_logic; + rom_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + rom_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + rom_aw_len : out std_logic_vector(7 downto 0); + rom_aw_size : out std_logic_vector(2 downto 0); + rom_aw_burst : out std_logic_vector(1 downto 0); + rom_aw_lock : out std_logic; + rom_aw_cache : out std_logic_vector(3 downto 0); + rom_aw_prot : out std_logic_vector(2 downto 0); + rom_aw_qos : out std_logic_vector(3 downto 0); + rom_aw_atop : out std_logic_vector(5 downto 0); + rom_aw_region : out std_logic_vector(3 downto 0); + rom_aw_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + rom_aw_valid : out std_logic; + rom_aw_ready : in std_logic; + rom_w_data : out std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + rom_w_strb : out std_logic_vector(AXI_STRB_WIDTH - 1 downto 0); + rom_w_last : out std_logic; + rom_w_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + rom_w_valid : out std_logic; + rom_w_ready : in std_logic; + rom_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + rom_b_resp : in std_logic_vector(1 downto 0); + rom_b_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + rom_b_valid : in std_logic; + rom_b_ready : out std_logic; + rom_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + rom_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + rom_ar_len : out std_logic_vector(7 downto 0); + rom_ar_size : out std_logic_vector(2 downto 0); + rom_ar_burst : out std_logic_vector(1 downto 0); + rom_ar_lock : out std_logic; + rom_ar_cache : out std_logic_vector(3 downto 0); + rom_ar_prot : out std_logic_vector(2 downto 0); + rom_ar_qos : out std_logic_vector(3 downto 0); + rom_ar_region : out std_logic_vector(3 downto 0); + rom_ar_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + rom_ar_valid : out std_logic; + rom_ar_ready : in std_logic; + rom_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + rom_r_data : in std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + rom_r_resp : in std_logic_vector(1 downto 0); + rom_r_last : in std_logic; + rom_r_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + rom_r_valid : in std_logic; + rom_r_ready : out std_logic; + dram_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + dram_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + dram_aw_len : out std_logic_vector(7 downto 0); + dram_aw_size : out std_logic_vector(2 downto 0); + dram_aw_burst : out std_logic_vector(1 downto 0); + dram_aw_lock : out std_logic; + dram_aw_cache : out std_logic_vector(3 downto 0); + dram_aw_prot : out std_logic_vector(2 downto 0); + dram_aw_qos : out std_logic_vector(3 downto 0); + dram_aw_atop : out std_logic_vector(5 downto 0); + dram_aw_region : out std_logic_vector(3 downto 0); + dram_aw_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + dram_aw_valid : out std_logic; + dram_aw_ready : in std_logic; + dram_ac_addr : in std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + dram_ac_prot : in std_logic_vector(2 downto 0); + dram_ac_snoop : in std_logic_vector(3 downto 0); + dram_ac_valid : in std_logic; + dram_ac_ready : out std_logic; + dram_w_data : out std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + dram_w_strb : out std_logic_vector(AXI_STRB_WIDTH - 1 downto 0); + dram_w_last : out std_logic; + dram_w_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + dram_w_valid : out std_logic; + dram_w_ready : in std_logic; + dram_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + dram_b_resp : in std_logic_vector(1 downto 0); + dram_b_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + dram_b_valid : in std_logic; + dram_b_ready : out std_logic; + dram_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + dram_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + dram_ar_len : out std_logic_vector(7 downto 0); + dram_ar_size : out std_logic_vector(2 downto 0); + dram_ar_burst : out std_logic_vector(1 downto 0); + dram_ar_lock : out std_logic; + dram_ar_cache : out std_logic_vector(3 downto 0); + dram_ar_prot : out std_logic_vector(2 downto 0); + dram_ar_qos : out std_logic_vector(3 downto 0); + dram_ar_region : out std_logic_vector(3 downto 0); + dram_ar_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + dram_ar_valid : out std_logic; + dram_ar_ready : in std_logic; + dram_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + dram_r_data : in std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + dram_r_resp : in std_logic_vector(1 downto 0); + dram_r_last : in std_logic; + dram_r_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + dram_r_valid : in std_logic; + dram_r_ready : out std_logic; + clint_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + clint_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + clint_aw_len : out std_logic_vector(7 downto 0); + clint_aw_size : out std_logic_vector(2 downto 0); + clint_aw_burst : out std_logic_vector(1 downto 0); + clint_aw_lock : out std_logic; + clint_aw_cache : out std_logic_vector(3 downto 0); + clint_aw_prot : out std_logic_vector(2 downto 0); + clint_aw_qos : out std_logic_vector(3 downto 0); + clint_aw_atop : out std_logic_vector(5 downto 0); + clint_aw_region : out std_logic_vector(3 downto 0); + clint_aw_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + clint_aw_valid : out std_logic; + clint_aw_ready : in std_logic; + clint_w_data : out std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + clint_w_strb : out std_logic_vector(AXI_STRB_WIDTH - 1 downto 0); + clint_w_last : out std_logic; + clint_w_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + clint_w_valid : out std_logic; + clint_w_ready : in std_logic; + clint_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + clint_b_resp : in std_logic_vector(1 downto 0); + clint_b_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + clint_b_valid : in std_logic; + clint_b_ready : out std_logic; + clint_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + clint_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + clint_ar_len : out std_logic_vector(7 downto 0); + clint_ar_size : out std_logic_vector(2 downto 0); + clint_ar_burst : out std_logic_vector(1 downto 0); + clint_ar_lock : out std_logic; + clint_ar_cache : out std_logic_vector(3 downto 0); + clint_ar_prot : out std_logic_vector(2 downto 0); + clint_ar_qos : out std_logic_vector(3 downto 0); + clint_ar_region : out std_logic_vector(3 downto 0); + clint_ar_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + clint_ar_valid : out std_logic; + clint_ar_ready : in std_logic; + clint_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + clint_r_data : in std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + clint_r_resp : in std_logic_vector(1 downto 0); + clint_r_last : in std_logic; + clint_r_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + clint_r_valid : in std_logic; + clint_r_ready : out std_logic; + slm_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + slm_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + slm_aw_len : out std_logic_vector(7 downto 0); + slm_aw_size : out std_logic_vector(2 downto 0); + slm_aw_burst : out std_logic_vector(1 downto 0); + slm_aw_lock : out std_logic; + slm_aw_cache : out std_logic_vector(3 downto 0); + slm_aw_prot : out std_logic_vector(2 downto 0); + slm_aw_qos : out std_logic_vector(3 downto 0); + slm_aw_atop : out std_logic_vector(5 downto 0); + slm_aw_region : out std_logic_vector(3 downto 0); + slm_aw_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slm_aw_valid : out std_logic; + slm_aw_ready : in std_logic; + slm_w_data : out std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + slm_w_strb : out std_logic_vector(AXI_STRB_WIDTH - 1 downto 0); + slm_w_last : out std_logic; + slm_w_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slm_w_valid : out std_logic; + slm_w_ready : in std_logic; + slm_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + slm_b_resp : in std_logic_vector(1 downto 0); + slm_b_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slm_b_valid : in std_logic; + slm_b_ready : out std_logic; + slm_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + slm_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + slm_ar_len : out std_logic_vector(7 downto 0); + slm_ar_size : out std_logic_vector(2 downto 0); + slm_ar_burst : out std_logic_vector(1 downto 0); + slm_ar_lock : out std_logic; + slm_ar_cache : out std_logic_vector(3 downto 0); + slm_ar_prot : out std_logic_vector(2 downto 0); + slm_ar_qos : out std_logic_vector(3 downto 0); + slm_ar_region : out std_logic_vector(3 downto 0); + slm_ar_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slm_ar_valid : out std_logic; + slm_ar_ready : in std_logic; + slm_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + slm_r_data : in std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + slm_r_resp : in std_logic_vector(1 downto 0); + slm_r_last : in std_logic; + slm_r_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slm_r_valid : in std_logic; + slm_r_ready : out std_logic; + slmddr_aw_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + slmddr_aw_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + slmddr_aw_len : out std_logic_vector(7 downto 0); + slmddr_aw_size : out std_logic_vector(2 downto 0); + slmddr_aw_burst : out std_logic_vector(1 downto 0); + slmddr_aw_lock : out std_logic; + slmddr_aw_cache : out std_logic_vector(3 downto 0); + slmddr_aw_prot : out std_logic_vector(2 downto 0); + slmddr_aw_qos : out std_logic_vector(3 downto 0); + slmddr_aw_atop : out std_logic_vector(5 downto 0); + slmddr_aw_region : out std_logic_vector(3 downto 0); + slmddr_aw_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slmddr_aw_valid : out std_logic; + slmddr_aw_ready : in std_logic; + slmddr_w_data : out std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + slmddr_w_strb : out std_logic_vector(AXI_STRB_WIDTH - 1 downto 0); + slmddr_w_last : out std_logic; + slmddr_w_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slmddr_w_valid : out std_logic; + slmddr_w_ready : in std_logic; + slmddr_b_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + slmddr_b_resp : in std_logic_vector(1 downto 0); + slmddr_b_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slmddr_b_valid : in std_logic; + slmddr_b_ready : out std_logic; + slmddr_ar_id : out std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + slmddr_ar_addr : out std_logic_vector(AXI_ADDR_WIDTH - 1 downto 0); + slmddr_ar_len : out std_logic_vector(7 downto 0); + slmddr_ar_size : out std_logic_vector(2 downto 0); + slmddr_ar_burst : out std_logic_vector(1 downto 0); + slmddr_ar_lock : out std_logic; + slmddr_ar_cache : out std_logic_vector(3 downto 0); + slmddr_ar_prot : out std_logic_vector(2 downto 0); + slmddr_ar_qos : out std_logic_vector(3 downto 0); + slmddr_ar_region : out std_logic_vector(3 downto 0); + slmddr_ar_user : out std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slmddr_ar_valid : out std_logic; + slmddr_ar_ready : in std_logic; + slmddr_r_id : in std_logic_vector(AXI_ID_WIDTH_SLV - 1 downto 0); + slmddr_r_data : in std_logic_vector(AXI_DATA_WIDTH - 1 downto 0); + slmddr_r_resp : in std_logic_vector(1 downto 0); + slmddr_r_last : in std_logic; + slmddr_r_user : in std_logic_vector(AXI_USER_WIDTH - 1 downto 0); + slmddr_r_valid : in std_logic; + slmddr_r_ready : out std_logic; + penable : out std_logic; + pwrite : out std_logic; + paddr : out std_logic_vector(31 downto 0); + psel : out std_logic; + pwdata : out std_logic_vector(31 downto 0); + prdata : in std_logic_vector(31 downto 0); + pready : in std_logic; + pslverr : in std_logic; + fence_l2 : out std_logic_vector(1 downto 0); + flush_l1 : in std_logic; + flush_done : out std_logic + ); end component ariane_wrap; signal penable : std_logic; @@ -345,227 +343,228 @@ architecture rtl of ariane_axi_wrap is signal psel_idx_reg : integer range 0 to NAPBSLV - 1; signal psel_sig : std_logic_vector(0 to NAPBSLV - 1); - constant ARIANE_AXI_ID_WIDTH : integer := 4; - constant ARIANE_AXI_ID_WIDTH_SLV : integer := ARIANE_AXI_ID_WIDTH + log2(NMST); + constant ARIANE_AXI_ID_WIDTH : integer := 4; + constant ARIANE_AXI_ID_WIDTH_SLV : integer := ARIANE_AXI_ID_WIDTH + log2(nmst); begin -- architecture rtl - ariane_wrap_1 : ariane_wrap + ariane_wrap_1 : component ariane_wrap generic map ( - NMST => NMST, - NSLV => NSLV, - AXI_ID_WIDTH => ARIANE_AXI_ID_WIDTH, - AXI_ID_WIDTH_SLV => ARIANE_AXI_ID_WIDTH_SLV, - AXI_ADDR_WIDTH => GLOB_PHYS_ADDR_BITS, - AXI_DATA_WIDTH => ARCH_BITS, - AXI_USER_WIDTH => XUSER_WIDTH, - AXI_STRB_WIDTH => ARCH_BITS / 8, - USE_SPANDEX => USE_SPANDEX, - ROMBase => ROMBase, - ROMLength => ROMLength, - APBBase => APBBase, - APBLength => APBLength, - CLINTBase => CLINTBase, - CLINTLength => CLINTLength, - SLMBase => SLMBase, - SLMLength => SLMLength, - SLMDDRBase => SLMDDRBase, - SLMDDRLength => SLMDDRLength, - DRAMBase => DRAMBase, - DRAMLength => DRAMLength, - DRAMCachedLength => DRAMCachedLength) + nmst => NMST, + nslv => NSLV, + axi_id_width => ARIANE_AXI_ID_WIDTH, + axi_id_width_slv => ARIANE_AXI_ID_WIDTH_SLV, + axi_addr_width => GLOB_PHYS_ADDR_BITS, + axi_data_width => ARCH_BITS, + axi_user_width => XUSER_WIDTH, + axi_strb_width => ARCH_BITS / 8, + use_spandex => USE_SPANDEX, + rombase => ROMBase, + romlength => ROMLength, + apbbase => APBBase, + apblength => APBLength, + clintbase => CLINTBase, + clintlength => CLINTLength, + slmbase => SLMBase, + slmlength => SLMLength, + slmddrbase => SLMDDRBase, + slmddrlength => SLMDDRLength, + drambase => DRAMBase, + dramlength => DRAMLength, + dramcachedlength => DRAMCachedLength + ) port map ( - clk => clk, - rstn => rstn, - HART_ID => HART_ID, - irq => irq, - timer_irq => timer_irq, - ipi => ipi, - rom_aw_id => romi.aw.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - rom_aw_addr => romi.aw.addr, - rom_aw_len => romi.aw.len, - rom_aw_size => romi.aw.size, - rom_aw_burst => romi.aw.burst, - rom_aw_lock => romi.aw.lock, - rom_aw_cache => romi.aw.cache, - rom_aw_prot => romi.aw.prot, - rom_aw_qos => romi.aw.qos, - rom_aw_atop => romi.aw.atop, - rom_aw_region => romi.aw.region, - rom_aw_user => romi.aw.user, - rom_aw_valid => romi.aw.valid, - rom_aw_ready => romo.aw.ready, - rom_w_data => romi.w.data, - rom_w_strb => romi.w.strb, - rom_w_last => romi.w.last, - rom_w_user => romi.w.user, - rom_w_valid => romi.w.valid, - rom_w_ready => romo.w.ready, - rom_b_id => romo.b.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - rom_b_resp => romo.b.resp, - rom_b_user => romo.b.user, - rom_b_valid => romo.b.valid, - rom_b_ready => romi.b.ready, - rom_ar_id => romi.ar.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - rom_ar_addr => romi.ar.addr, - rom_ar_len => romi.ar.len, - rom_ar_size => romi.ar.size, - rom_ar_burst => romi.ar.burst, - rom_ar_lock => romi.ar.lock, - rom_ar_cache => romi.ar.cache, - rom_ar_prot => romi.ar.prot, - rom_ar_qos => romi.ar.qos, - rom_ar_region => romi.ar.region, - rom_ar_user => romi.ar.user, - rom_ar_valid => romi.ar.valid, - rom_ar_ready => romo.ar.ready, - rom_r_id => romo.r.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - rom_r_data => romo.r.data, - rom_r_resp => romo.r.resp, - rom_r_last => romo.r.last, - rom_r_user => romo.r.user, - rom_r_valid => romo.r.valid, - rom_r_ready => romi.r.ready, - dram_aw_id => drami.aw.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - dram_aw_addr => drami.aw.addr, - dram_aw_len => drami.aw.len, - dram_aw_size => drami.aw.size, - dram_aw_burst => drami.aw.burst, - dram_aw_lock => drami.aw.lock, - dram_aw_cache => drami.aw.cache, - dram_aw_prot => drami.aw.prot, - dram_aw_qos => drami.aw.qos, - dram_aw_atop => drami.aw.atop, - dram_aw_region => drami.aw.region, - dram_aw_user => drami.aw.user, - dram_aw_valid => drami.aw.valid, - dram_aw_ready => dramo.aw.ready, - dram_ac_addr => ace_req.ac.addr, - dram_ac_prot => ace_req.ac.prot, - dram_ac_snoop => ace_req.ac.snoop, - dram_ac_valid => ace_req.ac.valid, - dram_ac_ready => ace_resp.ac.ready, - dram_w_data => drami.w.data, - dram_w_strb => drami.w.strb, - dram_w_last => drami.w.last, - dram_w_user => drami.w.user, - dram_w_valid => drami.w.valid, - dram_w_ready => dramo.w.ready, - dram_b_id => dramo.b.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - dram_b_resp => dramo.b.resp, - dram_b_user => dramo.b.user, - dram_b_valid => dramo.b.valid, - dram_b_ready => drami.b.ready, - dram_ar_id => drami.ar.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - dram_ar_addr => drami.ar.addr, - dram_ar_len => drami.ar.len, - dram_ar_size => drami.ar.size, - dram_ar_burst => drami.ar.burst, - dram_ar_lock => drami.ar.lock, - dram_ar_cache => drami.ar.cache, - dram_ar_prot => drami.ar.prot, - dram_ar_qos => drami.ar.qos, - dram_ar_region => drami.ar.region, - dram_ar_user => drami.ar.user, - dram_ar_valid => drami.ar.valid, - dram_ar_ready => dramo.ar.ready, - dram_r_id => dramo.r.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - dram_r_data => dramo.r.data, - dram_r_resp => dramo.r.resp, - dram_r_last => dramo.r.last, - dram_r_user => dramo.r.user, - dram_r_valid => dramo.r.valid, - dram_r_ready => drami.r.ready, - clint_aw_id => clinti.aw.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - clint_aw_addr => clinti.aw.addr, - clint_aw_len => clinti.aw.len, - clint_aw_size => clinti.aw.size, - clint_aw_burst => clinti.aw.burst, - clint_aw_lock => clinti.aw.lock, - clint_aw_cache => clinti.aw.cache, - clint_aw_prot => clinti.aw.prot, - clint_aw_qos => clinti.aw.qos, - clint_aw_atop => clinti.aw.atop, - clint_aw_region => clinti.aw.region, - clint_aw_user => clinti.aw.user, - clint_aw_valid => clinti.aw.valid, - clint_aw_ready => clinto.aw.ready, - clint_w_data => clinti.w.data, - clint_w_strb => clinti.w.strb, - clint_w_last => clinti.w.last, - clint_w_user => clinti.w.user, - clint_w_valid => clinti.w.valid, - clint_w_ready => clinto.w.ready, - clint_b_id => clinto.b.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - clint_b_resp => clinto.b.resp, - clint_b_user => clinto.b.user, - clint_b_valid => clinto.b.valid, - clint_b_ready => clinti.b.ready, - clint_ar_id => clinti.ar.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - clint_ar_addr => clinti.ar.addr, - clint_ar_len => clinti.ar.len, - clint_ar_size => clinti.ar.size, - clint_ar_burst => clinti.ar.burst, - clint_ar_lock => clinti.ar.lock, - clint_ar_cache => clinti.ar.cache, - clint_ar_prot => clinti.ar.prot, - clint_ar_qos => clinti.ar.qos, - clint_ar_region => clinti.ar.region, - clint_ar_user => clinti.ar.user, - clint_ar_valid => clinti.ar.valid, - clint_ar_ready => clinto.ar.ready, - clint_r_id => clinto.r.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - clint_r_data => clinto.r.data, - clint_r_resp => clinto.r.resp, - clint_r_last => clinto.r.last, - clint_r_user => clinto.r.user, - clint_r_valid => clinto.r.valid, - clint_r_ready => clinti.r.ready, - slm_aw_id => slmi.aw.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - slm_aw_addr => slmi.aw.addr, - slm_aw_len => slmi.aw.len, - slm_aw_size => slmi.aw.size, - slm_aw_burst => slmi.aw.burst, - slm_aw_lock => slmi.aw.lock, - slm_aw_cache => slmi.aw.cache, - slm_aw_prot => slmi.aw.prot, - slm_aw_qos => slmi.aw.qos, - slm_aw_atop => slmi.aw.atop, - slm_aw_region => slmi.aw.region, - slm_aw_user => slmi.aw.user, - slm_aw_valid => slmi.aw.valid, - slm_aw_ready => slmo.aw.ready, - slm_w_data => slmi.w.data, - slm_w_strb => slmi.w.strb, - slm_w_last => slmi.w.last, - slm_w_user => slmi.w.user, - slm_w_valid => slmi.w.valid, - slm_w_ready => slmo.w.ready, - slm_b_id => slmo.b.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - slm_b_resp => slmo.b.resp, - slm_b_user => slmo.b.user, - slm_b_valid => slmo.b.valid, - slm_b_ready => slmi.b.ready, - slm_ar_id => slmi.ar.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - slm_ar_addr => slmi.ar.addr, - slm_ar_len => slmi.ar.len, - slm_ar_size => slmi.ar.size, - slm_ar_burst => slmi.ar.burst, - slm_ar_lock => slmi.ar.lock, - slm_ar_cache => slmi.ar.cache, - slm_ar_prot => slmi.ar.prot, - slm_ar_qos => slmi.ar.qos, - slm_ar_region => slmi.ar.region, - slm_ar_user => slmi.ar.user, - slm_ar_valid => slmi.ar.valid, - slm_ar_ready => slmo.ar.ready, - slm_r_id => slmo.r.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), - slm_r_data => slmo.r.data, - slm_r_resp => slmo.r.resp, - slm_r_last => slmo.r.last, - slm_r_user => slmo.r.user, - slm_r_valid => slmo.r.valid, - slm_r_ready => slmi.r.ready, + clk => clk, + rstn => rstn, + hart_id => hart_id, + irq => irq, + timer_irq => timer_irq, + ipi => ipi, + rom_aw_id => romi.aw.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + rom_aw_addr => romi.aw.addr, + rom_aw_len => romi.aw.len, + rom_aw_size => romi.aw.size, + rom_aw_burst => romi.aw.burst, + rom_aw_lock => romi.aw.lock, + rom_aw_cache => romi.aw.cache, + rom_aw_prot => romi.aw.prot, + rom_aw_qos => romi.aw.qos, + rom_aw_atop => romi.aw.atop, + rom_aw_region => romi.aw.region, + rom_aw_user => romi.aw.user, + rom_aw_valid => romi.aw.valid, + rom_aw_ready => romo.aw.ready, + rom_w_data => romi.w.data, + rom_w_strb => romi.w.strb, + rom_w_last => romi.w.last, + rom_w_user => romi.w.user, + rom_w_valid => romi.w.valid, + rom_w_ready => romo.w.ready, + rom_b_id => romo.b.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + rom_b_resp => romo.b.resp, + rom_b_user => romo.b.user, + rom_b_valid => romo.b.valid, + rom_b_ready => romi.b.ready, + rom_ar_id => romi.ar.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + rom_ar_addr => romi.ar.addr, + rom_ar_len => romi.ar.len, + rom_ar_size => romi.ar.size, + rom_ar_burst => romi.ar.burst, + rom_ar_lock => romi.ar.lock, + rom_ar_cache => romi.ar.cache, + rom_ar_prot => romi.ar.prot, + rom_ar_qos => romi.ar.qos, + rom_ar_region => romi.ar.region, + rom_ar_user => romi.ar.user, + rom_ar_valid => romi.ar.valid, + rom_ar_ready => romo.ar.ready, + rom_r_id => romo.r.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + rom_r_data => romo.r.data, + rom_r_resp => romo.r.resp, + rom_r_last => romo.r.last, + rom_r_user => romo.r.user, + rom_r_valid => romo.r.valid, + rom_r_ready => romi.r.ready, + dram_aw_id => drami.aw.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + dram_aw_addr => drami.aw.addr, + dram_aw_len => drami.aw.len, + dram_aw_size => drami.aw.size, + dram_aw_burst => drami.aw.burst, + dram_aw_lock => drami.aw.lock, + dram_aw_cache => drami.aw.cache, + dram_aw_prot => drami.aw.prot, + dram_aw_qos => drami.aw.qos, + dram_aw_atop => drami.aw.atop, + dram_aw_region => drami.aw.region, + dram_aw_user => drami.aw.user, + dram_aw_valid => drami.aw.valid, + dram_aw_ready => dramo.aw.ready, + dram_ac_addr => ace_req.ac.addr, + dram_ac_prot => ace_req.ac.prot, + dram_ac_snoop => ace_req.ac.snoop, + dram_ac_valid => ace_req.ac.valid, + dram_ac_ready => ace_resp.ac.ready, + dram_w_data => drami.w.data, + dram_w_strb => drami.w.strb, + dram_w_last => drami.w.last, + dram_w_user => drami.w.user, + dram_w_valid => drami.w.valid, + dram_w_ready => dramo.w.ready, + dram_b_id => dramo.b.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + dram_b_resp => dramo.b.resp, + dram_b_user => dramo.b.user, + dram_b_valid => dramo.b.valid, + dram_b_ready => drami.b.ready, + dram_ar_id => drami.ar.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + dram_ar_addr => drami.ar.addr, + dram_ar_len => drami.ar.len, + dram_ar_size => drami.ar.size, + dram_ar_burst => drami.ar.burst, + dram_ar_lock => drami.ar.lock, + dram_ar_cache => drami.ar.cache, + dram_ar_prot => drami.ar.prot, + dram_ar_qos => drami.ar.qos, + dram_ar_region => drami.ar.region, + dram_ar_user => drami.ar.user, + dram_ar_valid => drami.ar.valid, + dram_ar_ready => dramo.ar.ready, + dram_r_id => dramo.r.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + dram_r_data => dramo.r.data, + dram_r_resp => dramo.r.resp, + dram_r_last => dramo.r.last, + dram_r_user => dramo.r.user, + dram_r_valid => dramo.r.valid, + dram_r_ready => drami.r.ready, + clint_aw_id => clinti.aw.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + clint_aw_addr => clinti.aw.addr, + clint_aw_len => clinti.aw.len, + clint_aw_size => clinti.aw.size, + clint_aw_burst => clinti.aw.burst, + clint_aw_lock => clinti.aw.lock, + clint_aw_cache => clinti.aw.cache, + clint_aw_prot => clinti.aw.prot, + clint_aw_qos => clinti.aw.qos, + clint_aw_atop => clinti.aw.atop, + clint_aw_region => clinti.aw.region, + clint_aw_user => clinti.aw.user, + clint_aw_valid => clinti.aw.valid, + clint_aw_ready => clinto.aw.ready, + clint_w_data => clinti.w.data, + clint_w_strb => clinti.w.strb, + clint_w_last => clinti.w.last, + clint_w_user => clinti.w.user, + clint_w_valid => clinti.w.valid, + clint_w_ready => clinto.w.ready, + clint_b_id => clinto.b.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + clint_b_resp => clinto.b.resp, + clint_b_user => clinto.b.user, + clint_b_valid => clinto.b.valid, + clint_b_ready => clinti.b.ready, + clint_ar_id => clinti.ar.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + clint_ar_addr => clinti.ar.addr, + clint_ar_len => clinti.ar.len, + clint_ar_size => clinti.ar.size, + clint_ar_burst => clinti.ar.burst, + clint_ar_lock => clinti.ar.lock, + clint_ar_cache => clinti.ar.cache, + clint_ar_prot => clinti.ar.prot, + clint_ar_qos => clinti.ar.qos, + clint_ar_region => clinti.ar.region, + clint_ar_user => clinti.ar.user, + clint_ar_valid => clinti.ar.valid, + clint_ar_ready => clinto.ar.ready, + clint_r_id => clinto.r.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + clint_r_data => clinto.r.data, + clint_r_resp => clinto.r.resp, + clint_r_last => clinto.r.last, + clint_r_user => clinto.r.user, + clint_r_valid => clinto.r.valid, + clint_r_ready => clinti.r.ready, + slm_aw_id => slmi.aw.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + slm_aw_addr => slmi.aw.addr, + slm_aw_len => slmi.aw.len, + slm_aw_size => slmi.aw.size, + slm_aw_burst => slmi.aw.burst, + slm_aw_lock => slmi.aw.lock, + slm_aw_cache => slmi.aw.cache, + slm_aw_prot => slmi.aw.prot, + slm_aw_qos => slmi.aw.qos, + slm_aw_atop => slmi.aw.atop, + slm_aw_region => slmi.aw.region, + slm_aw_user => slmi.aw.user, + slm_aw_valid => slmi.aw.valid, + slm_aw_ready => slmo.aw.ready, + slm_w_data => slmi.w.data, + slm_w_strb => slmi.w.strb, + slm_w_last => slmi.w.last, + slm_w_user => slmi.w.user, + slm_w_valid => slmi.w.valid, + slm_w_ready => slmo.w.ready, + slm_b_id => slmo.b.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + slm_b_resp => slmo.b.resp, + slm_b_user => slmo.b.user, + slm_b_valid => slmo.b.valid, + slm_b_ready => slmi.b.ready, + slm_ar_id => slmi.ar.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + slm_ar_addr => slmi.ar.addr, + slm_ar_len => slmi.ar.len, + slm_ar_size => slmi.ar.size, + slm_ar_burst => slmi.ar.burst, + slm_ar_lock => slmi.ar.lock, + slm_ar_cache => slmi.ar.cache, + slm_ar_prot => slmi.ar.prot, + slm_ar_qos => slmi.ar.qos, + slm_ar_region => slmi.ar.region, + slm_ar_user => slmi.ar.user, + slm_ar_valid => slmi.ar.valid, + slm_ar_ready => slmo.ar.ready, + slm_r_id => slmo.r.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), + slm_r_data => slmo.r.data, + slm_r_resp => slmo.r.resp, + slm_r_last => slmo.r.last, + slm_r_user => slmo.r.user, + slm_r_valid => slmo.r.valid, + slm_r_ready => slmi.r.ready, slmddr_aw_id => slmddri.aw.id(ARIANE_AXI_ID_WIDTH_SLV - 1 downto 0), slmddr_aw_addr => slmddri.aw.addr, slmddr_aw_len => slmddri.aw.len, @@ -611,30 +610,30 @@ begin -- architecture rtl slmddr_r_user => slmddro.r.user, slmddr_r_valid => slmddro.r.valid, slmddr_r_ready => slmddri.r.ready, - penable => penable, - pwrite => pwrite, - paddr => paddr, - psel => psel, - pwdata => pwdata, - prdata => prdata, - pready => apb_ack, - pslverr => '0', - fence_l2 => fence_l2, - flush_l1 => flush_l1, - flush_done => flush_done - ); + penable => penable, + pwrite => pwrite, + paddr => paddr, + psel => psel, + pwdata => pwdata, + prdata => prdata, + pready => apb_ack, + pslverr => '0', + fence_l2 => fence_l2, + flush_l1 => flush_l1, + flush_done => flush_done + ); -- Unused extended AXI ID - romi.aw.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); - romi.ar.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); - drami.aw.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); - drami.ar.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); + romi.aw.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); + romi.ar.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); + drami.aw.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); + drami.ar.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); clinti.aw.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); clinti.ar.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); - slmi.aw.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); - slmi.ar.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); - slmddri.aw.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); - slmddri.ar.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); + slmi.aw.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); + slmi.ar.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); + slmddri.aw.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); + slmddri.ar.id(XID_WIDTH - 1 downto ARIANE_AXI_ID_WIDTH_SLV) <= (others => '0'); -- Unused apbi.pirq <= (others => '0'); @@ -647,18 +646,23 @@ begin -- architecture rtl -- APB slave input apb_req <= psel and penable; - psel_gen: for i in 0 to NAPBSLV - 1 generate + psel_gen : for i in 0 to NAPBSLV - 1 generate psel_sig(i) <= apb_slv_decode(apbo(i).pconfig, paddr(19 downto 8), paddr(27 downto 20)) and psel; end generate psel_gen; - psel_idx_gen: process (psel_sig) is + psel_idx_gen : process (psel_sig) is begin -- process psel_gen + psel_idx <= 0; + for i in 0 to NAPBSLV - 1 loop - if psel_sig(i) = '1' then + + if (psel_sig(i) = '1') then psel_idx <= i; end if; + end loop; + end process psel_idx_gen; apbi.penable <= penable; @@ -667,16 +671,17 @@ begin -- architecture rtl apbi.pwdata <= pwdata; apbi.psel <= psel_sig; + psel_reg_gen : process (clk, rstn) is + begin -- process psel_reg_gen - psel_reg_gen: process (clk, rstn) is - begin -- process psel_reg_gen - if rstn = '0' then -- asynchronous reset (active low) + if (rstn = '0') then -- asynchronous reset (active low) psel_idx_reg <= 0; - elsif clk'event and clk = '1' then -- rising clock edge - if (psel and penable) = '1' then + elsif (clk'event and clk = '1') then -- rising clock edge + if ((psel and penable) = '1') then psel_idx_reg <= psel_idx; end if; end if; + end process psel_reg_gen; prdata <= apbo(psel_idx_reg).prdata; diff --git a/rtl/cores/ibex/ibex_ahb_wrap.vhd b/rtl/cores/ibex/ibex_ahb_wrap.vhd index 83c447709d..41c415d216 100644 --- a/rtl/cores/ibex/ibex_ahb_wrap.vhd +++ b/rtl/cores/ibex/ibex_ahb_wrap.vhd @@ -2,68 +2,70 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.esp_global.all; -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; -use work.genacc.all; - + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.esp_global.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.genacc.all; entity ibex_ahb_wrap is generic ( hindex : integer range 0 to NAHBSLV - 1 := 0; - ROMBase : std_logic_vector(31 downto 0) := X"0001_0000"); + rombase : std_logic_vector(31 downto 0) := X"0001_0000" + ); port ( - rstn : in std_ulogic; - clk : in std_ulogic; - HART_ID : in std_logic_vector(31 downto 0); + rstn : in std_ulogic; + clk : in std_ulogic; + hart_id : in std_logic_vector(31 downto 0); -- Interrupts - irq : in std_logic_vector(1 downto 0); - timer_irq : in std_ulogic; - ipi : in std_ulogic; + irq : in std_logic_vector(1 downto 0); + timer_irq : in std_ulogic; + ipi : in std_ulogic; -- idle - core_idle : out std_ulogic; + core_idle : out std_ulogic; -- AHB master interface - ahbmi : in ahb_mst_in_type; - ahbmo : out ahb_mst_out_type - ); -end ibex_ahb_wrap; - + ahbmi : in ahb_mst_in_type; + ahbmo : out ahb_mst_out_type + ); +end entity ibex_ahb_wrap; architecture rtl of ibex_ahb_wrap is - constant hconfig : ahb_config_type := ( + constant HCONFIG : ahb_config_type := + ( 0 => ahb_device_reg (VENDOR_LOWRISC, LOWRISC_IBEX_SMALL, 0, 0, 0), - others => zero32); + others => zero32 + ); component ibex_wrap is generic ( - ROMBase : std_logic_vector(31 downto 0)); + rombase : std_logic_vector(31 downto 0) + ); port ( - clk : in std_ulogic; - rstn : in std_ulogic; - HART_ID : in std_logic_vector(31 downto 0); - instr_req_o : out std_ulogic; - instr_gnt_i : in std_ulogic; - instr_rvalid_i : in std_ulogic; - instr_addr_o : out std_logic_vector(31 downto 0); - instr_rdata_i : in std_logic_vector(31 downto 0); - data_req_o : out std_ulogic; - data_gnt_i : in std_ulogic; - data_rvalid_i : in std_ulogic; - data_we_o : out std_ulogic; - data_be_o : out std_logic_vector(3 downto 0); - data_addr_o : out std_logic_vector(31 downto 0); - data_wdata_o : out std_logic_vector(31 downto 0); - data_rdata_i : in std_logic_vector(31 downto 0); - irq : in std_logic_vector(1 downto 0); - timer_irq : in std_ulogic; - ipi : in std_ulogic; - core_sleep_o : out std_ulogic); + clk : in std_ulogic; + rstn : in std_ulogic; + hart_id : in std_logic_vector(31 downto 0); + instr_req_o : out std_ulogic; + instr_gnt_i : in std_ulogic; + instr_rvalid_i : in std_ulogic; + instr_addr_o : out std_logic_vector(31 downto 0); + instr_rdata_i : in std_logic_vector(31 downto 0); + data_req_o : out std_ulogic; + data_gnt_i : in std_ulogic; + data_rvalid_i : in std_ulogic; + data_we_o : out std_ulogic; + data_be_o : out std_logic_vector(3 downto 0); + data_addr_o : out std_logic_vector(31 downto 0); + data_wdata_o : out std_logic_vector(31 downto 0); + data_rdata_i : in std_logic_vector(31 downto 0); + irq : in std_logic_vector(1 downto 0); + timer_irq : in std_ulogic; + ipi : in std_ulogic; + core_sleep_o : out std_ulogic + ); end component ibex_wrap; signal instr_req_o : std_ulogic; @@ -81,6 +83,7 @@ architecture rtl of ibex_ahb_wrap is signal data_rdata_i : std_logic_vector(31 downto 0); type ahbm_state_t is (idle, ird, dwr, drd); + type ahbm_fsm_t is record state : ahbm_state_t; hbusreq : std_ulogic; @@ -92,8 +95,9 @@ architecture rtl of ibex_ahb_wrap is misaligned : std_ulogic; end record ahbm_fsm_t; - signal r, rin : ahbm_fsm_t; - constant AHBM_DEFAULT : ahbm_fsm_t := ( + signal r, rin : ahbm_fsm_t; + constant AHBM_DEFAULT : ahbm_fsm_t := + ( state => idle, hbusreq => '0', htrans => HTRANS_IDLE, @@ -102,86 +106,155 @@ architecture rtl of ibex_ahb_wrap is hwrite => '0', hwdata => (others => '0'), misaligned => '0' - ); + ); - procedure set_bus_control( + procedure set_bus_control ( byte_mask : in std_logic_vector(3 downto 0); addr : in std_logic_vector(31 downto 0); hsize : out std_logic_vector(2 downto 0); haddr : out std_logic_vector(31 downto 0); misaligned : out std_ulogic - ) is + ) is + variable haddr_lsb : std_logic_vector(1 downto 0); + begin + misaligned := '0'; + case byte_mask is - when "1111" => hsize := HSIZE_WORD; haddr_lsb := "00"; - when "0011" => hsize := HSIZE_HWORD; haddr_lsb := "00"; - when "1100" => hsize := HSIZE_HWORD; haddr_lsb := "10"; - when "0001" => hsize := HSIZE_BYTE; haddr_lsb := "00"; - when "0010" => hsize := HSIZE_BYTE; haddr_lsb := "01"; - when "0100" => hsize := HSIZE_BYTE; haddr_lsb := "10"; - when "1000" => hsize := HSIZE_BYTE; haddr_lsb := "11"; + + when "1111" => + + hsize := HSIZE_WORD; haddr_lsb := "00"; + + when "0011" => + + hsize := HSIZE_HWORD; haddr_lsb := "00"; + + when "1100" => + + hsize := HSIZE_HWORD; haddr_lsb := "10"; + + when "0001" => + + hsize := HSIZE_BYTE; haddr_lsb := "00"; + + when "0010" => + + hsize := HSIZE_BYTE; haddr_lsb := "01"; + + when "0100" => + + hsize := HSIZE_BYTE; haddr_lsb := "10"; + + when "1000" => + + hsize := HSIZE_BYTE; haddr_lsb := "11"; + when others => + hsize := HSIZE_WORD; haddr_lsb := "00"; -- pragma translate_off misaligned := '1'; - -- pragma translate_on + -- pragma translate_on + end case; + haddr := addr(31 downto 2) & haddr_lsb; - end; - procedure set_bus_data( + end procedure; + + procedure set_bus_data ( byte_mask : in std_logic_vector(3 downto 0); wdata : in std_logic_vector(31 downto 0); hwdata : out std_logic_vector(31 downto 0) - ) is + ) is begin + case byte_mask is - when "1111" => hwdata := ahbdrivedata(wdata); - when "0011" => hwdata := ahbdrivedata(wdata(15 downto 0)); - when "1100" => hwdata := ahbdrivedata(wdata(31 downto 16)); - when "0001" => hwdata := ahbdrivedata(wdata(7 downto 0)); - when "0010" => hwdata := ahbdrivedata(wdata(15 downto 8)); - when "0100" => hwdata := ahbdrivedata(wdata(23 downto 16)); - when "1000" => hwdata := ahbdrivedata(wdata(31 downto 24)); + + when "1111" => + + hwdata := ahbdrivedata(wdata); + + when "0011" => + + hwdata := ahbdrivedata(wdata(15 downto 0)); + + when "1100" => + + hwdata := ahbdrivedata(wdata(31 downto 16)); + + when "0001" => + + hwdata := ahbdrivedata(wdata(7 downto 0)); + + when "0010" => + + hwdata := ahbdrivedata(wdata(15 downto 8)); + + when "0100" => + + hwdata := ahbdrivedata(wdata(23 downto 16)); + + when "1000" => + + hwdata := ahbdrivedata(wdata(31 downto 24)); + when others => + hwdata := ahbdrivedata(wdata); + end case; - end; + + end procedure; function is_seq_trans ( signal addr : std_logic_vector(31 downto 0); - signal addr_r : std_logic_vector(31 downto 0)) + signal addr_r : std_logic_vector(31 downto 0) + ) return std_ulogic is + variable addr_msb_incr : std_logic_vector(29 downto 0); + begin + addr_msb_incr := addr_r(31 downto 2) + ("00" & X"0000001"); - if addr_msb_incr = addr(31 downto 2) then + + if (addr_msb_incr = addr(31 downto 2)) then return '1'; else return '0'; end if; - end; + + end function; begin -- architecture rtl ahbm_reg : process (clk, rstn) is - begin -- process ahbm_reg - if rstn = '0' then -- asynchronous reset (active low) + begin -- process ahbm_reg + + if (rstn = '0') then -- asynchronous reset (active low) r <= AHBM_DEFAULT; - elsif clk'event and clk = '1' then -- rising clock edge + elsif (clk'event and clk = '1') then -- rising clock edge r <= rin; -- pragma translate_off - assert r.misaligned = '0' report "misaligned bus transaction is not supported" severity failure; - -- pragma translate_on + assert r.misaligned = '0' + report "misaligned bus transaction is not supported" + severity failure; + -- pragma translate_on end if; + end process ahbm_reg; ahbm_fsm : process (r, ahbmi, instr_req_o, instr_addr_o, data_req_o, data_we_o, data_be_o, data_addr_o, data_wdata_o) is + variable v : ahbm_fsm_t; variable granted : std_ulogic; + begin -- process ahbm_fsm + v := r; granted := ahbmi.hgrant(hindex); @@ -193,40 +266,44 @@ begin -- architecture rtl data_rvalid_i <= '0'; case r.state is + when idle => + v.hbusreq := '0'; v.htrans := HTRANS_IDLE; - if data_req_o = '1' then + + if (data_req_o = '1') then set_bus_control(data_be_o, data_addr_o, v.hsize, v.haddr, v.misaligned); set_bus_data(data_be_o, data_wdata_o, v.hwdata); v.hbusreq := '1'; v.htrans := HTRANS_NONSEQ; v.hwrite := data_we_o; - if (ahbmi.hready and granted) = '1' then + if ((ahbmi.hready and granted) = '1') then data_gnt_i <= '1'; - if data_we_o = '1' then + if (data_we_o = '1') then v.state := dwr; else v.state := drd; end if; end if; - elsif instr_req_o = '1' then + elsif (instr_req_o = '1') then v.hbusreq := '1'; v.htrans := HTRANS_NONSEQ; v.hsize := HSIZE_WORD; v.haddr := instr_addr_o; v.hwrite := '0'; - if (ahbmi.hready and granted) = '1' then + if ((ahbmi.hready and granted) = '1') then instr_gnt_i <= '1'; v.state := ird; end if; end if; when ird => - if ahbmi.hready = '1' then - v.haddr := instr_addr_o; - if instr_req_o = '1' then - if is_seq_trans(instr_addr_o, r.haddr) = '1' then + + if (ahbmi.hready = '1') then + v.haddr := instr_addr_o; + if (instr_req_o = '1') then + if (is_seq_trans(instr_addr_o, r.haddr) = '1') then -- continue sequential burst v.htrans := HTRANS_SEQ; else @@ -237,24 +314,25 @@ begin -- architecture rtl v.htrans := HTRANS_IDLE; end if; - if granted = '1' then + if (granted = '1') then instr_rvalid_i <= '1'; - if instr_req_o = '1' then + if (instr_req_o = '1') then instr_gnt_i <= '1'; else - v.state := idle; + v.state := idle; end if; end if; end if; when drd => - if ahbmi.hready = '1' then + + if (ahbmi.hready = '1') then set_bus_control(data_be_o, data_addr_o, v.hsize, v.haddr, v.misaligned); set_bus_data(data_be_o, data_wdata_o, v.hwdata); - if data_req_o = '1' then - if data_we_o = '0' then - if data_be_o = "1111" and is_seq_trans(data_addr_o, r.haddr) = '1' then + if (data_req_o = '1') then + if (data_we_o = '0') then + if (data_be_o = "1111" and is_seq_trans(data_addr_o, r.haddr) = '1') then -- continue sequential burst v.htrans := HTRANS_SEQ; else @@ -270,28 +348,29 @@ begin -- architecture rtl v.htrans := HTRANS_IDLE; end if; - if granted = '1' then + if (granted = '1') then data_rvalid_i <= '1'; - if data_req_o = '1' then + if (data_req_o = '1') then data_gnt_i <= '1'; - if data_we_o /= '0' then + if (data_we_o /= '0') then -- Move to data write - v.state := dwr; + v.state := dwr; end if; else - v.state := idle; + v.state := idle; end if; end if; end if; when dwr => - if ahbmi.hready = '1' then + + if (ahbmi.hready = '1') then set_bus_control(data_be_o, data_addr_o, v.hsize, v.haddr, v.misaligned); set_bus_data(data_be_o, data_wdata_o, v.hwdata); - if data_req_o = '1' then - if data_we_o = '1' then - if data_be_o = "1111" and is_seq_trans(data_addr_o, r.haddr) = '1' then + if (data_req_o = '1') then + if (data_we_o = '1') then + if (data_be_o = "1111" and is_seq_trans(data_addr_o, r.haddr) = '1') then -- continue sequential burst v.htrans := HTRANS_SEQ; else @@ -307,21 +386,22 @@ begin -- architecture rtl v.htrans := HTRANS_IDLE; end if; - if granted = '1' then + if (granted = '1') then data_rvalid_i <= '1'; - if data_req_o = '1' then + if (data_req_o = '1') then data_gnt_i <= '1'; - if data_we_o /= '1' then + if (data_we_o /= '1') then -- Move to data read - v.state := drd; + v.state := drd; end if; else - v.state := idle; + v.state := idle; end if; end if; end if; when others => + v.hbusreq := '0'; v.htrans := HTRANS_IDLE; v.state := idle; @@ -335,29 +415,31 @@ begin -- architecture rtl ahbmo.hsize <= v.hsize; ahbmo.hwrite <= v.hwrite; -- State register input - rin <= v; + rin <= v; + end process ahbm_fsm; -- Sequential bus control signals (pipeline between address and data) - ahbmo.hwdata <= ahbdrivedata(r.hwdata); + ahbmo.hwdata <= ahbdrivedata(r.hwdata); -- Constant bus control signals ahbmo.hprot <= "0011"; ahbmo.hlock <= '0'; ahbmo.hirq <= (others => '0'); - ahbmo.hconfig <= hconfig; + ahbmo.hconfig <= HCONFIG; ahbmo.hindex <= hindex; ahbmo.hburst <= HBURST_INCR; instr_rdata_i <= ahbmi.hrdata(31 downto 0); data_rdata_i <= ahbmi.hrdata(31 downto 0); - ibex_wrap_i : ibex_wrap + ibex_wrap_i : component ibex_wrap generic map ( - ROMBase => ROMBase) + rombase => ROMBase + ) port map ( clk => clk, rstn => rstn, - HART_ID => HART_ID, + hart_id => hart_id, instr_req_o => instr_req_o, instr_gnt_i => instr_gnt_i, instr_rvalid_i => instr_rvalid_i, @@ -374,6 +456,7 @@ begin -- architecture rtl irq => irq, timer_irq => timer_irq, ipi => ipi, - core_sleep_o => core_idle); + core_sleep_o => core_idle + ); end architecture rtl; diff --git a/rtl/cores/ibex/ibex_timer_wrap.sv b/rtl/cores/ibex/ibex_timer_wrap.sv index ebba4c123e..cf60101738 100644 --- a/rtl/cores/ibex/ibex_timer_wrap.sv +++ b/rtl/cores/ibex/ibex_timer_wrap.sv @@ -1,45 +1,44 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -module ibex_timer_wrap - ( - input logic rstn, - input logic clk, - input logic penable, - input logic psel, - input logic pwrite, - input logic [31:0] paddr, - input logic [31:0] pwdata, - output logic [31:0] prdata, - output logic pready, - output logic pslverr, - output logic timer_irq - ); +module ibex_timer_wrap ( + input logic rstn, + input logic clk, + input logic penable, + input logic psel, + input logic pwrite, + input logic [31:0] paddr, + input logic [31:0] pwdata, + output logic [31:0] prdata, + output logic pready, + output logic pslverr, + output logic timer_irq +); - // Adapt from APB - logic req; - assign req = penable & psel; + // Adapt from APB + logic req; + assign req = penable & psel; - // Only 32-bit words read or write allowed (may require adapting the device driver) - logic [3:0] be; - assign be = 4'b1111; + // Only 32-bit words read or write allowed (may require adapting the device driver) + logic [3:0] be; + assign be = 4'b1111; - timer #( - .DataWidth (32), - .AddressWidth (32) + timer #( + .DataWidth (32), + .AddressWidth(32) ) u_timer ( - .clk_i (clk), - .rst_ni (rstn), + .clk_i (clk), + .rst_ni(rstn), - .timer_req_i (req), - .timer_we_i (pwrite), - .timer_be_i (be), - .timer_addr_i (paddr), - .timer_wdata_i (pwdata), - .timer_rvalid_o (pready), - .timer_rdata_o (prdata), - .timer_err_o (pslverr), - .timer_intr_o (timer_irq) + .timer_req_i (req), + .timer_we_i (pwrite), + .timer_be_i (be), + .timer_addr_i (paddr), + .timer_wdata_i (pwdata), + .timer_rvalid_o(pready), + .timer_rdata_o (prdata), + .timer_err_o (pslverr), + .timer_intr_o (timer_irq) ); diff --git a/rtl/cores/leon3/arith.vhd b/rtl/cores/leon3/arith.vhd index a884f8aad9..dfdda7da2b 100644 --- a/rtl/cores/leon3/arith.vhd +++ b/rtl/cores/leon3/arith.vhd @@ -16,136 +16,159 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------- --- Package: arith --- File: arith.vhd --- Author: Jiri Gaisler, Gaisler Research --- Description: Declaration of mul/div components +-- Package: arith +-- File: arith.vhd +-- Author: Jiri Gaisler, Gaisler Research +-- Description: Declaration of mul/div components ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; package arith is -type div32_in_type is record - y : std_logic_vector(32 downto 0); -- Y (MSB divident) - op1 : std_logic_vector(32 downto 0); -- operand 1 (LSB divident) - op2 : std_logic_vector(32 downto 0); -- operand 2 (divisor) - flush : std_logic; - signed : std_logic; - start : std_logic; -end record; - -type div32_out_type is record - ready : std_logic; - nready : std_logic; - icc : std_logic_vector(3 downto 0); -- ICC - result : std_logic_vector(31 downto 0); -- div result -end record; - -type mul32_in_type is record - op1 : std_logic_vector(32 downto 0); -- operand 1 - op2 : std_logic_vector(32 downto 0); -- operand 2 - flush : std_logic; - signed : std_logic; - start : std_logic; - mac : std_logic; - acc : std_logic_vector(39 downto 0); - --y : std_logic_vector(7 downto 0); -- Y (MSB MAC register) - --asr18 : std_logic_vector(31 downto 0); -- LSB MAC register -end record; - -type mul32_out_type is record - ready : std_logic; - nready : std_logic; - icc : std_logic_vector(3 downto 0); -- ICC - result : std_logic_vector(63 downto 0); -- mul result -end record; - -component div32 -generic (scantest : integer := 0); -port ( - rst : in std_ulogic; - clk : in std_ulogic; - holdn : in std_ulogic; - divi : in div32_in_type; - divo : out div32_out_type; - testen : in std_ulogic := '0'; - testrst : in std_ulogic := '1' -); -end component; - -component mul32 -generic ( - tech : integer := 0; - multype : integer := 0; - pipe : integer := 0; - mac : integer := 0; - arch : integer range 0 to 3 := 0; - scantest: integer := 0 -); -port ( - rst : in std_ulogic; - clk : in std_ulogic; - holdn : in std_ulogic; - muli : in mul32_in_type; - mulo : out mul32_out_type; - testen : in std_ulogic := '0'; - testrst : in std_ulogic := '1' -); -end component; - -function smult ( a, b : in std_logic_vector) return std_logic_vector; -function umult ( a, b : in std_logic_vector) return std_logic_vector; - -end; + type div32_in_type is record + y : std_logic_vector(32 downto 0); -- Y (MSB divident) + op1 : std_logic_vector(32 downto 0); -- operand 1 (LSB divident) + op2 : std_logic_vector(32 downto 0); -- operand 2 (divisor) + flush : std_logic; + signed : std_logic; + start : std_logic; + end record div32_in_type; + + type div32_out_type is record + ready : std_logic; + nready : std_logic; + icc : std_logic_vector(3 downto 0); -- ICC + result : std_logic_vector(31 downto 0); -- div result + end record div32_out_type; + + type mul32_in_type is record + op1 : std_logic_vector(32 downto 0); -- operand 1 + op2 : std_logic_vector(32 downto 0); -- operand 2 + flush : std_logic; + signed : std_logic; + start : std_logic; + mac : std_logic; + acc : std_logic_vector(39 downto 0); + -- y : std_logic_vector(7 downto 0); -- Y (MSB MAC register) + -- asr18 : std_logic_vector(31 downto 0); -- LSB MAC register + end record mul32_in_type; + + type mul32_out_type is record + ready : std_logic; + nready : std_logic; + icc : std_logic_vector(3 downto 0); -- ICC + result : std_logic_vector(63 downto 0); -- mul result + end record mul32_out_type; + + component div32 is + generic ( + scantest : integer := 0 + ); + port ( + rst : in std_ulogic; + clk : in std_ulogic; + holdn : in std_ulogic; + divi : in div32_in_type; + divo : out div32_out_type; + testen : in std_ulogic := '0'; + testrst : in std_ulogic := '1' + ); + end component; + + component mul32 is + generic ( + tech : integer := 0; + multype : integer := 0; + pipe : integer := 0; + mac : integer := 0; + arch : integer range 0 to 3 := 0; + scantest : integer := 0 + ); + port ( + rst : in std_ulogic; + clk : in std_ulogic; + holdn : in std_ulogic; + muli : in mul32_in_type; + mulo : out mul32_out_type; + testen : in std_ulogic := '0'; + testrst : in std_ulogic := '1' + ); + end component; + + function smult ( + a, + b : in std_logic_vector + ) return std_logic_vector; + + function umult ( + a, + b : in std_logic_vector + ) return std_logic_vector; + +end package arith; package body arith is -function smult ( a, b : in std_logic_vector) return std_logic_vector is - variable sa : signed (a'length-1 downto 0); - variable sb : signed (b'length-1 downto 0); - variable sc : signed ((a'length + b'length) -1 downto 0); - variable res : std_logic_vector ((a'length + b'length) -1 downto 0); -begin - - sa := signed(a); sb := signed(b); --- pragma translate_off - if is_x(a) or is_x(b) then - sc := (others => 'X'); - else --- pragma translate_on - sc := sa * sb; --- pragma translate_off - end if; --- pragma translate_on - res := std_logic_vector(sc); - return(res); -end; - -function umult ( a, b : in std_logic_vector) return std_logic_vector is - variable sa : unsigned (a'length-1 downto 0); - variable sb : unsigned (b'length-1 downto 0); - variable sc : unsigned ((a'length + b'length) -1 downto 0); - variable res : std_logic_vector ((a'length + b'length) -1 downto 0); -begin - - sa := unsigned(a); sb := unsigned(b); --- pragma translate_off - if is_x(a) or is_x(b) then - sc := (others => 'X'); - else --- pragma translate_on - sc := sa * sb; --- pragma translate_off - end if; --- pragma translate_on - res := std_logic_vector(sc); - return(res); -end; - -end; + function smult ( + a, + b : in std_logic_vector + ) return std_logic_vector is + + variable sa : signed (a'length-1 downto 0); + variable sb : signed (b'length-1 downto 0); + variable sc : signed ((a'length + b'length) - 1 downto 0); + variable res : std_logic_vector((a'length + b'length) - 1 downto 0); + + begin + + sa := signed(a); sb := signed(b); + -- pragma translate_off + if (is_x(a) or is_x(b)) then + sc := (others => 'X'); + else + -- pragma translate_on + sc := sa * sb; + -- pragma translate_off + end if; + + -- pragma translate_on + res := std_logic_vector(sc); + return(res); + + end function; + + function umult ( + a, + b : in std_logic_vector + ) return std_logic_vector is + + variable sa : unsigned (a'length-1 downto 0); + variable sb : unsigned (b'length-1 downto 0); + variable sc : unsigned ((a'length + b'length) - 1 downto 0); + variable res : std_logic_vector((a'length + b'length) - 1 downto 0); + + begin + + sa := unsigned(a); sb := unsigned(b); + -- pragma translate_off + if (is_x(a) or is_x(b)) then + sc := (others => 'X'); + else + -- pragma translate_on + sc := sa * sb; + -- pragma translate_off + end if; + + -- pragma translate_on + res := std_logic_vector(sc); + return(res); + + end function; + +end package body arith; diff --git a/rtl/cores/leon3/sldfpu/add160.vhd b/rtl/cores/leon3/sldfpu/add160.vhd index a56b3e9d4a..a26a5ca8ad 100644 --- a/rtl/cores/leon3/sldfpu/add160.vhd +++ b/rtl/cores/leon3/sldfpu/add160.vhd @@ -2,137 +2,153 @@ -- SPDX-License-Identifier: Apache-2.0 ----------------------------------------------------------------------------- --- Entity: add160b --- File: add160b.vhd --- Author: Paolo Mantovani - SLD @ Columbia University --- Description: 160 bits, 40 operands Carry Save Adder +-- Entity: add160b +-- File: add160b.vhd +-- Author: Paolo Mantovani - SLD @ Columbia University +-- Description: 160 bits, 40 operands Carry Save Adder ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; - -use work.bw.all; + use ieee.std_logic_1164.all; + use work.bw.all; entity add160b is - port ( - add : in add160b_in_type; - css : out std_logic_vector(159 downto 0); --Carry save S - csc : out std_logic_vector(159 downto 0)); --Carry save C - -end add160b; - + add : in add160b_in_type; + css : out std_logic_vector(159 downto 0); -- Carry save S + csc : out std_logic_vector(159 downto 0) -- Carry save C + ); +end entity add160b; architecture rtl of add160b is - signal a : csa40op_a_type; + signal a : csa40op_a_type; signal x : compressor42_mat; signal ci : csa40op_c_type; signal co : csa40op_c_type; - signal S : csa40op_c_type; - signal C : csa40op_c_type; - + signal s : csa40op_c_type; + signal c : csa40op_c_type; + begin -- rtl -- Carry Save Adder array. - input_routing: for i in 159 downto 0 generate + + input_routing : for i in 159 downto 0 generate -- group bits from the same column i - bit_routign: for j in 39 downto 0 generate + + bit_routign : for j in 39 downto 0 generate a(i)(j) <= add(j)(i); end generate bit_routign; -- compressors from 0 to 9 are always at -- level 0 in the tree - x(i)(0) <= a(i)(39 downto 36); - x(i)(1) <= a(i)(35 downto 32); - x(i)(2) <= a(i)(31 downto 28); - x(i)(3) <= a(i)(27 downto 24); - x(i)(4) <= a(i)(23 downto 20); - x(i)(5) <= a(i)(19 downto 16); - x(i)(6) <= a(i)(15 downto 12); + x(i)(0) <= a(i)(39 downto 36); + x(i)(1) <= a(i)(35 downto 32); + x(i)(2) <= a(i)(31 downto 28); + x(i)(3) <= a(i)(27 downto 24); + x(i)(4) <= a(i)(23 downto 20); + x(i)(5) <= a(i)(19 downto 16); + x(i)(6) <= a(i)(15 downto 12); x(i)(7) <= a(i)(11 downto 8); x(i)(8) <= a(i)(7 downto 4); x(i)(9) <= a(i)(3 downto 0); - l0_i0: if i=0 generate - ci(i)(0 to 9) <= (others => '0'); --no global carry in + + l0_i0 : if i=0 generate + ci(i)(0 to 9) <= (others => '0'); -- no global carry in end generate l0_i0; - l0_i: if i>0 generate - ci(i)(0 to 9) <= co(i-1)(0 to 9); + + l0_i : if i>0 generate + ci(i)(0 to 9) <= co(i - 1)(0 to 9); end generate l0_i; - + -- compressors from 10 to 14 are always at -- level 1 in the tree - l1_i0: if i=0 generate - x(i)(10) <= '0' & S(0)(0) & '0' & S(0)(1); - x(i)(11) <= '0' & S(0)(2) & '0' & S(0)(3); - x(i)(12) <= '0' & S(0)(4) & '0' & S(0)(5); - x(i)(13) <= '0' & S(0)(6) & '0' & S(0)(7); - x(i)(14) <= '0' & S(0)(8) & '0' & S(0)(9); - ci(i)(10 to 14) <= (others => '0'); --no global carry in + + l1_i0 : if i=0 generate + x(i)(10) <= '0' & s(0)(0) & '0' & s(0)(1); + x(i)(11) <= '0' & s(0)(2) & '0' & s(0)(3); + x(i)(12) <= '0' & s(0)(4) & '0' & s(0)(5); + x(i)(13) <= '0' & s(0)(6) & '0' & s(0)(7); + x(i)(14) <= '0' & s(0)(8) & '0' & s(0)(9); + ci(i)(10 to 14) <= (others => '0'); -- no global carry in end generate l1_i0; - l1_i: if i>0 generate - x(i)(10) <= C(i-1)(0) & S(i)(0) & C(i-1)(1) & S(i)(1); - x(i)(11) <= C(i-1)(2) & S(i)(2) & C(i-1)(3) & S(i)(3); - x(i)(12) <= C(i-1)(4) & S(i)(4) & C(i-1)(5) & S(i)(5); - x(i)(13) <= C(i-1)(6) & S(i)(6) & C(i-1)(7) & S(i)(7); - x(i)(14) <= C(i-1)(8) & S(i)(8) & C(i-1)(9) & S(i)(9); - ci(i)(10 to 14) <= co(i-1)(10 to 14); + + l1_i : if i>0 generate + x(i)(10) <= c(i - 1)(0) & s(i)(0) & c(i - 1)(1) & s(i)(1); + x(i)(11) <= c(i - 1)(2) & s(i)(2) & c(i - 1)(3) & s(i)(3); + x(i)(12) <= c(i - 1)(4) & s(i)(4) & c(i - 1)(5) & s(i)(5); + x(i)(13) <= c(i - 1)(6) & s(i)(6) & c(i - 1)(7) & s(i)(7); + x(i)(14) <= c(i - 1)(8) & s(i)(8) & c(i - 1)(9) & s(i)(9); + ci(i)(10 to 14) <= co(i - 1)(10 to 14); end generate l1_i; -- compressors from 15 to 16 are always at -- level 2 in the tree - l2_i0: if i=0 generate - x(i)(15) <= '0' & S(i)(10) & '0' & S(i)(11); - x(i)(16) <= '0' & S(i)(12) & '0' & S(i)(13); - ci(i)(15 to 16) <= (others => '0'); --no global carry in + + l2_i0 : if i=0 generate + x(i)(15) <= '0' & s(i)(10) & '0' & s(i)(11); + x(i)(16) <= '0' & s(i)(12) & '0' & s(i)(13); + ci(i)(15 to 16) <= (others => '0'); -- no global carry in end generate l2_i0; - l2_i: if i>0 generate - x(i)(15) <= C(i-1)(10) & S(i)(10) & C(i-1)(11) & S(i)(11); - x(i)(16) <= C(i-1)(12) & S(i)(12) & C(i-1)(13) & S(i)(13); - ci(i)(15 to 16) <= co(i-1)(15 to 16); + + l2_i : if i>0 generate + x(i)(15) <= c(i - 1)(10) & s(i)(10) & c(i - 1)(11) & s(i)(11); + x(i)(16) <= c(i - 1)(12) & s(i)(12) & c(i - 1)(13) & s(i)(13); + ci(i)(15 to 16) <= co(i - 1)(15 to 16); end generate l2_i; -- compressor 17 is always at -- level 3 in the tree - l3_i0: if i=0 generate - x(i)(17) <= '0' & S(i)(15) & '0' & S(i)(16); - ci(i)(17) <= '0'; --no global carry in + + l3_i0 : if i=0 generate + x(i)(17) <= '0' & s(i)(15) & '0' & s(i)(16); + ci(i)(17) <= '0'; -- no global carry in end generate l3_i0; - l3_i: if i>0 generate - x(i)(17) <= C(i-1)(15) & S(i)(15) & C(i-1)(16) & S(i)(16); - ci(i)(17) <= co(i-1)(17); --no global carry in + + l3_i : if i>0 generate + x(i)(17) <= c(i - 1)(15) & s(i)(15) & c(i - 1)(16) & s(i)(16); + ci(i)(17) <= co(i - 1)(17); -- no global carry in end generate l3_i; -- compressor 18 is the last level of the tree - l4_i0: if i=0 generate - x(i)(18) <= '0' & S(i)(17) & '0' & S(i)(14); + + l4_i0 : if i=0 generate + x(i)(18) <= '0' & s(i)(17) & '0' & s(i)(14); ci(i)(18) <= '0'; end generate l4_i0; - l4_i: if i>0 generate - x(i)(18) <= C(i-1)(17) & S(i)(17) & C(i-1)(14) & S(i)(14); - ci(i)(18) <= co(i-1)(18); + + l4_i : if i>0 generate + x(i)(18) <= c(i - 1)(17) & s(i)(17) & c(i - 1)(14) & s(i)(14); + ci(i)(18) <= co(i - 1)(18); end generate l4_i; + end generate input_routing; - -- Compressors instantiation - ct: for i in 0 to 159 generate - csa: for j in 0 to 18 generate - compressor42_1_7_i: compressor42 + + ct : for i in 0 to 159 generate + + csa : for j in 0 to 18 generate + + compressor42_1_7_i : component compressor42 port map ( x => x(i)(j), ci => ci(i)(j), - S => S(i)(j), - C => C(i)(j), - co => co(i)(j)); + s => s(i)(j), + c => c(i)(j), + co => co(i)(j) + ); + end generate csa; + end generate ct; - + -- Ouput in Carry Save form - carry_save: for i in 159 downto 0 generate - csc(i) <= C(i)(18); - css(i) <= S(i)(18); + + carry_save : for i in 159 downto 0 generate + csc(i) <= c(i)(18); + css(i) <= s(i)(18); end generate carry_save; -end rtl; +end architecture rtl; diff --git a/rtl/misc/ahbram.vhd b/rtl/misc/ahbram.vhd index 221a201c0c..f8477dd358 100644 --- a/rtl/misc/ahbram.vhd +++ b/rtl/misc/ahbram.vhd @@ -16,24 +16,23 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------- --- Entity: ahbram --- File: ahbram.vhd --- Author: Jiri Gaisler - Gaisler Research +-- Entity: ahbram +-- File: ahbram.vhd +-- Author: Jiri Gaisler - Gaisler Research -- Modified: Jan Andersson - Aeroflex Gaisler --- Description: AHB ram. 0-waitstate read, 0/1-waitstate write. +-- Description: AHB ram. 0-waitstate read, 0/1-waitstate write. ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; - -use work.config_types.all; -use work.config.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gencomp.all; + use ieee.std_logic_1164.all; + use work.config_types.all; + use work.config.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gencomp.all; entity ahbram is generic ( @@ -44,190 +43,272 @@ entity ahbram is pipe : integer := 0; maccsz : integer := AHBDW; scantest : integer := 0; - endianness : integer := 0); + endianness : integer := 0 + ); port ( - rst : in std_ulogic; - clk : in std_ulogic; - haddr : in integer range 0 to 4095; - hmask : in integer range 0 to 4095; - ahbsi : in ahb_slv_in_type; - ahbso : out ahb_slv_out_type + rst : in std_ulogic; + clk : in std_ulogic; + haddr : in integer range 0 to 4095; + hmask : in integer range 0 to 4095; + ahbsi : in ahb_slv_in_type; + ahbso : out ahb_slv_out_type ); -end; +end entity ahbram; architecture rtl of ahbram is -constant abits : integer := log2ext(kbytes) + 8 - maccsz/64; - -constant dw : integer := maccsz; + constant ABITS : integer := log2ext(kbytes) + 8 - maccsz / 64; -signal hconfig : ahb_config_type; + constant DW : integer := maccsz; -type reg_type is record - hwrite : std_ulogic; - hready : std_ulogic; - hsel : std_ulogic; - addr : std_logic_vector(abits-1+log2(dw/8) downto 0); - size : std_logic_vector(2 downto 0); - prdata : std_logic_vector((dw-1)*pipe downto 0); - pwrite : std_ulogic; - pready : std_ulogic; -end record; + signal hconfig : ahb_config_type; -constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; -constant RES : reg_type := - (hwrite => '0', hready => '1', hsel => '0', addr => (others => '0'), - size => (others => '0'), prdata => (others => '0'), pwrite => '0', - pready => '1'); + type reg_type is record + hwrite : std_ulogic; + hready : std_ulogic; + hsel : std_ulogic; + addr : std_logic_vector(ABITS - 1 + log2(DW / 8) downto 0); + size : std_logic_vector(2 downto 0); + prdata : std_logic_vector((DW - 1) * pipe downto 0); + pwrite : std_ulogic; + pready : std_ulogic; + end record reg_type; + constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; + constant RES : reg_type := + ( + hwrite => '0', + hready => '1', + hsel => '0', + addr => (others => '0'), + size => (others => '0'), + prdata => (others => '0'), + pwrite => '0', + pready => '1' + ); -signal r, c : reg_type; -signal ramsel : std_logic_vector(dw/8-1 downto 0); -signal write : std_logic_vector(dw/8-1 downto 0); -signal ramaddr : std_logic_vector(abits-1 downto 0); -signal ramdata : std_logic_vector(dw-1 downto 0); -signal hwdata : std_logic_vector(dw-1 downto 0); + signal r, c : reg_type; + signal ramsel : std_logic_vector(DW / 8 - 1 downto 0); + signal write : std_logic_vector(DW / 8 - 1 downto 0); + signal ramaddr : std_logic_vector(ABITS - 1 downto 0); + signal ramdata : std_logic_vector(DW - 1 downto 0); + signal hwdata : std_logic_vector(DW - 1 downto 0); begin - hconfig <= ( - 0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_AHBRAM, 0, abits+2+maccsz/64, 0), - 4 => ahb_membar(haddr, '1', '1', hmask), - others => zero32); + hconfig <= + ( + 0 => ahb_device_reg (VENDOR_GAISLER, GAISLER_AHBRAM, 0, ABITS + 2 + maccsz / 64, 0), + 4 => ahb_membar(haddr, '1', '1', hmask), + others => zero32 + ); + comb : process (ahbsi, r, rst, ramdata) is - comb : process (ahbsi, r, rst, ramdata) - variable bs : std_logic_vector(dw/8-1 downto 0); - variable v : reg_type; - variable haddr : std_logic_vector(abits-1 downto 0); - variable hrdata : std_logic_vector(dw-1 downto 0); - variable wdata : std_logic_vector(dw-1 downto 0); - variable seldata : std_logic_vector(dw-1 downto 0); - variable raddr : std_logic_vector(3 downto 2); - variable adsel : std_logic; + variable bs : std_logic_vector(DW / 8 - 1 downto 0); + variable v : reg_type; + variable haddr : std_logic_vector(ABITS - 1 downto 0); + variable hrdata : std_logic_vector(DW - 1 downto 0); + variable wdata : std_logic_vector(DW - 1 downto 0); + variable seldata : std_logic_vector(DW - 1 downto 0); + variable raddr : std_logic_vector(3 downto 2); + variable adsel : std_logic; - function reversedata(data : std_logic_vector; step : integer) + function reversedata ( + data : std_logic_vector; + step : integer + ) return std_logic_vector is - variable rdata: std_logic_vector(data'length-1 downto 0); - begin - for i in 0 to (data'length/step-1) loop - rdata(i*step+step-1 downto i*step) := data(data'length-i*step-1 downto data'length-i*step-step); - end loop; - return rdata; - end function reversedata; + + variable rdata : std_logic_vector(data'length-1 downto 0); + + begin + + for i in 0 to (data'length / step - 1) loop + + rdata(i * step + step - 1 downto i * step) := data(data'length-i * step - 1 downto data'length-i * step - step); + + end loop; + + return rdata; + + end function reversedata; begin - v := r; v.hready := '1'; bs := (others => '0'); + + v := r; v.hready := '1'; bs := (others => '0'); v.pready := r.hready; - if pipe=0 then + + if (pipe=0) then adsel := r.hwrite or not r.hready; else - adsel := r.hwrite or r.pwrite; + adsel := r.hwrite or r.pwrite; v.hready := r.hready or not r.pwrite; end if; - if adsel = '1' then - haddr := r.addr(abits-1+log2(dw/8) downto log2(dw/8)); + + if (adsel = '1') then + haddr := r.addr(ABITS - 1 + log2(DW / 8) downto log2(DW / 8)); else - haddr := ahbsi.haddr(abits-1+log2(dw/8) downto log2(dw/8)); - bs := (others => '0'); + haddr := ahbsi.haddr(ABITS - 1 + log2(DW / 8) downto log2(DW / 8)); + bs := (others => '0'); end if; + raddr := (others => '0'); v.pwrite := '0'; - if pipe/=0 and (r.hready='1' or r.pwrite='0') then - v.addr := ahbsi.haddr(abits-1+log2(dw/8) downto 0); + + if (pipe/=0 and (r.hready='1' or r.pwrite='0')) then + v.addr := ahbsi.haddr(ABITS - 1 + log2(DW / 8) downto 0); end if; - if ahbsi.hready = '1' then - if pipe=0 then - v.addr := ahbsi.haddr(abits-1+log2(dw/8) downto 0); - end if; - v.hsel := ahbsi.hsel(hindex) and ahbsi.htrans(1); - v.size := ahbsi.hsize(2 downto 0); + + if (ahbsi.hready = '1') then + if (pipe=0) then + v.addr := ahbsi.haddr(ABITS - 1 + log2(DW / 8) downto 0); + end if; + v.hsel := ahbsi.hsel(hindex) and ahbsi.htrans(1); + v.size := ahbsi.hsize(2 downto 0); v.hwrite := ahbsi.hwrite and v.hsel; - if pipe = 1 and v.hsel = '1' and ahbsi.hwrite = '0' and (r.pready='1' or ahbsi.htrans(0)='0') then + if (pipe = 1 and v.hsel = '1' and ahbsi.hwrite = '0' and (r.pready='1' or ahbsi.htrans(0)='0')) then v.hready := '0'; v.pwrite := r.hwrite; end if; end if; - if r.hwrite = '1' then + if (r.hwrite = '1') then + case r.size is - when HSIZE_BYTE => - bs(bs'left-conv_integer(r.addr(log2(dw/16) downto 0))) := '1'; - when HSIZE_HWORD => - for i in 0 to dw/16-1 loop - if i = conv_integer(r.addr(log2(dw/16) downto 1)) then - bs(bs'left-i*2 downto bs'left-i*2-1) := (others => '1'); - end if; - end loop; -- i - when HSIZE_WORD => - if dw = 32 then bs := (others => '1'); - else - for i in 0 to dw/32-1 loop - if i = conv_integer(r.addr(log2(dw/8)-1 downto 2)) then - bs(bs'left-i*4 downto bs'left-i*4-3) := (others => '1'); - end if; - end loop; -- i - end if; - when HSIZE_DWORD => - if dw = 32 then null; - elsif dw = 64 then bs := (others => '1'); - else - for i in 0 to dw/64-1 loop - if i = conv_integer(r.addr(3)) then - bs(bs'left-i*8 downto bs'left-i*8-7) := (others => '1'); - end if; - end loop; -- i - end if; - when HSIZE_4WORD => - if dw < 128 then null; - elsif dw = 128 then bs := (others => '1'); - else - for i in 0 to dw/64-1 loop - if i = conv_integer(r.addr(3)) then - bs(bs'left-i*8 downto bs'left-i*8-7) := (others => '1'); + + when HSIZE_BYTE => + + bs(bs'left - conv_integer(r.addr(log2(dw / 16) downto 0))) := '1'; + + when HSIZE_HWORD => + + for i in 0 to DW / 16 - 1 loop + + if (i = conv_integer(r.addr(log2(DW / 16) downto 1))) then + bs(bs'left - i * 2 downto bs'left - i * 2 - 1) := (others => '1'); end if; - end loop; -- i - end if; - when others => --HSIZE_8WORD - if dw < 256 then null; - else bs := (others => '1'); end if; + + end loop; -- i + + when HSIZE_WORD => + + if (DW = 32) then + bs := (others => '1'); + else + + for i in 0 to DW / 32 - 1 loop + + if (i = conv_integer(r.addr(log2(DW / 8) - 1 downto 2))) then + bs(bs'left - i * 4 downto bs'left - i * 4 - 3) := (others => '1'); + end if; + + end loop; -- i + + end if; + + when HSIZE_DWORD => + + if (DW = 32) then + null; + elsif (DW = 64) then + bs := (others => '1'); + else + + for i in 0 to DW / 64 - 1 loop + + if (i = conv_integer(r.addr(3))) then + bs(bs'left - i * 8 downto bs'left - i * 8 - 7) := (others => '1'); + end if; + + end loop; -- i + + end if; + + when HSIZE_4WORD => + + if (DW < 128) then + null; + elsif (DW = 128) then + bs := (others => '1'); + else + + for i in 0 to DW / 64 - 1 loop + + if (i = conv_integer(r.addr(3))) then + bs(bs'left - i * 8 downto bs'left - i * 8 - 7) := (others => '1'); + end if; + + end loop; -- i + + end if; + + when others => -- HSIZE_8WORD + + if (DW < 256) then + null; + else + bs := (others => '1'); + end if; + end case; + v.hready := not (v.hsel and not ahbsi.hwrite); v.hwrite := v.hwrite and v.hready; end if; -- Duplicate read data on word basis, unless CORE_ACDM is enabled - if CORE_ACDM = 0 then - if dw = 32 then + if (CORE_ACDM = 0) then + if (DW = 32) then seldata := ramdata; - elsif dw = 64 then - if r.size = HSIZE_DWORD then seldata := ramdata; else - if r.addr(2) = '0' then - seldata(dw/2-1 downto 0) := ramdata(dw-1 downto dw/2); - else - seldata(dw/2-1 downto 0) := ramdata(dw/2-1 downto 0); - end if; - seldata(dw-1 downto dw/2) := seldata(dw/2-1 downto 0); + elsif (DW = 64) then + if (r.size = HSIZE_DWORD) then + seldata := ramdata; + else + if (r.addr(2) = '0') then + seldata(dw / 2 - 1 downto 0) := ramdata(DW - 1 downto DW / 2); + else + seldata(dw / 2 - 1 downto 0) := ramdata(DW / 2 - 1 downto 0); + end if; + seldata(dw - 1 downto dw / 2) := seldata(DW / 2 - 1 downto 0); end if; - elsif dw = 128 then - if r.size = HSIZE_4WORD then + elsif (DW = 128) then + if (r.size = HSIZE_4WORD) then seldata := ramdata; - elsif r.size = HSIZE_DWORD then - if r.addr(3) = '0' then seldata(dw/2-1 downto 0) := ramdata(dw-1 downto dw/2); - else seldata(dw/2-1 downto 0) := ramdata(dw/2-1 downto 0); end if; - seldata(dw-1 downto dw/2) := seldata(dw/2-1 downto 0); + elsif (r.size = HSIZE_DWORD) then + if (r.addr(3) = '0') then + seldata(dw / 2 - 1 downto 0) := ramdata(DW - 1 downto DW / 2); + else + seldata(dw / 2 - 1 downto 0) := ramdata(DW / 2 - 1 downto 0); + end if; + seldata(dw - 1 downto dw / 2) := seldata(DW / 2 - 1 downto 0); else raddr := r.addr(3 downto 2); + case raddr is - when "00" => seldata(dw/4-1 downto 0) := ramdata(4*dw/4-1 downto 3*dw/4); - when "01" => seldata(dw/4-1 downto 0) := ramdata(3*dw/4-1 downto 2*dw/4); - when "10" => seldata(dw/4-1 downto 0) := ramdata(2*dw/4-1 downto 1*dw/4); - when others => seldata(dw/4-1 downto 0) := ramdata(dw/4-1 downto 0); + + when "00" => + + seldata(dw / 4 - 1 downto 0) := ramdata(4 * DW / 4 - 1 downto 3 * DW / 4); + + when "01" => + + seldata(dw / 4 - 1 downto 0) := ramdata(3 * DW / 4 - 1 downto 2 * DW / 4); + + when "10" => + + seldata(dw / 4 - 1 downto 0) := ramdata(2 * DW / 4 - 1 downto 1 * DW / 4); + + when others => + + seldata(dw / 4 - 1 downto 0) := ramdata(DW / 4 - 1 downto 0); + end case; - seldata(dw-1 downto dw/4) := seldata(dw/4-1 downto 0) & - seldata(dw/4-1 downto 0) & - seldata(dw/4-1 downto 0); + + seldata(dw - 1 downto dw / 4) := seldata(DW / 4 - 1 downto 0) & + seldata(DW / 4 - 1 downto 0) & + seldata(DW / 4 - 1 downto 0); end if; else seldata := ahbselectdata(ramdata, r.addr(4 downto 2), r.size); @@ -236,73 +317,90 @@ begin seldata := ramdata; end if; - if pipe = 0 then + if (pipe = 0) then v.prdata := (others => '0'); - hrdata := seldata; + hrdata := seldata; else v.prdata := seldata; - hrdata := r.prdata; + hrdata := r.prdata; end if; -- Endianness conversion wdata := ahbsi.hwdata; - if endianness = 1 then - hrdata := reversedata(hrdata, 8); - wdata := reversedata(wdata, 8); + if (endianness = 1) then + hrdata := reversedata(hrdata, 8); + wdata := reversedata(wdata, 8); end if; - if (not RESET_ALL) and (rst = '0') then + if ((not RESET_ALL) and (rst = '0')) then v.hwrite := RES.hwrite; v.hready := RES.hready; end if; - write <= bs; for i in 0 to dw/8-1 loop ramsel(i) <= v.hsel or r.hwrite; end loop; - ramaddr <= haddr; c <= v; + + write <= bs; + + for i in 0 to DW / 8 - 1 loop + + ramsel(i) <= v.hsel or r.hwrite; + + end loop; + + ramaddr <= haddr; + c <= v; ahbso.hrdata <= ahbdrivedata(hrdata); ahbso.hready <= r.hready; -- Select correct write data - hwdata <= ahbreaddata(wdata, r.addr(4 downto 2), conv_std_logic_vector(log2(dw/8), 3)); - - end process; + hwdata <= ahbreaddata(wdata, r.addr(4 downto 2), conv_std_logic_vector(log2(DW / 8), 3)); - ahbso.hresp <= "00"; - ahbso.hsplit <= (others => '0'); + end process comb; + + ahbso.hresp <= "00"; + ahbso.hsplit <= (others => '0'); ahbso.hirq <= (others => '0'); ahbso.hconfig <= hconfig; ahbso.hindex <= hindex; - - aram : syncrambw + + aram : component syncrambw generic map ( - tech => tech, - abits => abits, - dbits => dw, - testen => scantest, - custombits => 1, - large_banks => large_banks) + tech => tech, + abits => abits, + dbits => dw, + testen => scantest, + custombits => 1, + large_banks => large_banks + ) port map ( - clk => clk, - address => ramaddr, - datain => hwdata, - dataout => ramdata, - enable => ramsel, - write => write, - testin => ahbsi.testin); - - reg : process (clk) + clk => clk, + address => ramaddr, + datain => hwdata, + dataout => ramdata, + enable => ramsel, + write => write, + testin => ahbsi.testin + ); + + reg : process (clk) is begin + if rising_edge(clk) then r <= c; - if RESET_ALL and rst = '0' then + if (RESET_ALL and rst = '0') then r <= RES; end if; end if; - end process; --- pragma translate_off - bootmsg : report_version - generic map ("ahbram" & tost(hindex) & - ": AHB SRAM Module rev 1, " & tost(kbytes) & " kbytes"); + end process reg; + + -- pragma translate_off + bootmsg : component report_version + generic map ( +"ahbram" & tost(hindex) & + ": AHB SRAM Module rev 1, " & tost(kbytes) & " kbytes" + ); + -- pragma translate_on -end; + +end architecture rtl; diff --git a/rtl/misc/esplink.sv b/rtl/misc/esplink.sv index a3dea04065..bb2da43e9f 100644 --- a/rtl/misc/esplink.sv +++ b/rtl/misc/esplink.sv @@ -1,128 +1,122 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -module esplink - #( +module esplink #( parameter APB_DW = 32, parameter APB_AW = 32, parameter REV_ENDIAN = 0 - ) - ( - input logic clk, - input logic rstn, - output logic srst, +) ( + input logic clk, + input logic rstn, + output logic srst, // APB - input logic psel, - input logic penable, - input logic pwrite, - input logic [APB_AW - 1:0] paddr, - input logic [APB_DW - 1:0] pwdata, - output logic pready, - output logic pslverr, + input logic psel, + input logic penable, + input logic pwrite, + input logic [APB_AW - 1:0] paddr, + input logic [APB_DW - 1:0] pwdata, + output logic pready, + output logic pslverr, output logic [APB_DW - 1:0] prdata - ); - - // Command register - localparam C_REG_ID = 0; - localparam C_SRST_BIT = 0; - localparam C_REG_MASK = 32'h1; - - // Status register - localparam S_REG_ID = 1; - localparam S_SRST_BIT = 0; // soft-reset pending - - // Number of registers - localparam NREG = S_REG_ID + 1; - - // Byte offset - localparam APB_BYTE_OFFSET_BITS = $clog2(APB_DW / 8); - localparam OFFSET_MAX = (NREG - 1) << APB_BYTE_OFFSET_BITS; - localparam APB_ADDR_MSB = $clog2(NREG) + APB_BYTE_OFFSET_BITS - 1; - localparam APB_ADDR_LSB = APB_BYTE_OFFSET_BITS; - - // Internal wires and registers - logic [APB_DW - 1 : 0] bankreg[NREG - 1 : 0]; - logic [APB_ADDR_MSB : APB_ADDR_LSB] selected; - logic do_access; - logic access_error; - logic do_write; - - // Fix endian - logic [APB_DW - 1:0] pwdata_rev; - logic [APB_DW - 1:0] prdata_rev; - - // Timer - logic timer_en; - logic [11:0] timestamp; - - genvar i; - - // - // Decode APB command - // - assign selected = paddr[APB_ADDR_MSB : APB_ADDR_LSB]; - assign do_access = psel & penable; - assign access_error = 0; - assign do_write = do_access & ~access_error & pwrite; - assign do_cmd = do_write == 1'b1 && selected == C_REG_ID ? 1'b1 : 1'b0; - - generate - for (i = 0; i < APB_DW / 8; i ++) begin : fix_endian - assign pwdata_rev[(i + 1) * 8 - 1 : i * 8] = REV_ENDIAN == 0 ? pwdata[(i + 1) * 8 - 1 : i * 8] : pwdata[APB_DW - i * 8 - 1 : APB_DW - (i + 1) * 8]; - assign prdata[(i + 1) * 8 - 1 : i * 8] = REV_ENDIAN == 0 ? prdata_rev[(i + 1) * 8 - 1 : i * 8] : prdata_rev[APB_DW - i * 8 - 1 : APB_DW - (i + 1) * 8]; - end - endgenerate - - // - // APB Read - // - assign pslverr = access_error; - assign prdata_rev = bankreg[selected]; - assign pready = 1'b1; - - - // - // Command register - // - assign bankreg[C_REG_ID] = do_cmd == 1'b1 ? pwdata_rev & C_REG_MASK : '0; - - // - // Status register - // - - always_ff @(posedge clk) begin : update_s_reg - if (rstn == 1'b0) begin - bankreg[S_REG_ID] <= '0; - end - else begin - // soft reset pending - bankreg[S_REG_ID][S_SRST_BIT] <= timer_en; - end - end - - // - // Timer - // - - assign srst = timer_en; - - - always_ff @(posedge clk) begin - if (rstn == 1'b0) begin - timer_en <= 1'b0; - timestamp <= '0; - end - else begin - if (bankreg[C_REG_ID][C_SRST_BIT] == 1'b1) - timer_en <= 1'b1; - - if (timer_en == 1'b1) begin - timestamp <= timestamp + 1; - if (timestamp == 12'hFFF) - timer_en <= 1'b0; - end - end - end +); + + // Command register + localparam C_REG_ID = 0; + localparam C_SRST_BIT = 0; + localparam C_REG_MASK = 32'h1; + + // Status register + localparam S_REG_ID = 1; + localparam S_SRST_BIT = 0; // soft-reset pending + + // Number of registers + localparam NREG = S_REG_ID + 1; + + // Byte offset + localparam APB_BYTE_OFFSET_BITS = $clog2(APB_DW / 8); + localparam OFFSET_MAX = (NREG - 1) << APB_BYTE_OFFSET_BITS; + localparam APB_ADDR_MSB = $clog2(NREG) + APB_BYTE_OFFSET_BITS - 1; + localparam APB_ADDR_LSB = APB_BYTE_OFFSET_BITS; + + // Internal wires and registers + logic [ APB_DW - 1 : 0] bankreg [NREG - 1 : 0]; + logic [APB_ADDR_MSB : APB_ADDR_LSB] selected; + logic do_access; + logic access_error; + logic do_write; + + // Fix endian + logic [ APB_DW - 1:0] pwdata_rev; + logic [ APB_DW - 1:0] prdata_rev; + + // Timer + logic timer_en; + logic [ 11:0] timestamp; + + genvar i; + + // + // Decode APB command + // + assign selected = paddr[APB_ADDR_MSB : APB_ADDR_LSB]; + assign do_access = psel & penable; + assign access_error = 0; + assign do_write = do_access & ~access_error & pwrite; + assign do_cmd = do_write == 1'b1 && selected == C_REG_ID ? 1'b1 : 1'b0; + + generate + for (i = 0; i < APB_DW / 8; i++) begin : fix_endian + assign pwdata_rev[(i + 1) * 8 - 1 : i * 8] = REV_ENDIAN == 0 ? pwdata[(i + 1) * 8 - 1 : i * 8] : pwdata[APB_DW - i * 8 - 1 : APB_DW - (i + 1) * 8]; + assign prdata[(i + 1) * 8 - 1 : i * 8] = REV_ENDIAN == 0 ? prdata_rev[(i + 1) * 8 - 1 : i * 8] : prdata_rev[APB_DW - i * 8 - 1 : APB_DW - (i + 1) * 8]; + end + endgenerate + + // + // APB Read + // + assign pslverr = access_error; + assign prdata_rev = bankreg[selected]; + assign pready = 1'b1; + + + // + // Command register + // + assign bankreg[C_REG_ID] = do_cmd == 1'b1 ? pwdata_rev & C_REG_MASK : '0; + + // + // Status register + // + + always_ff @(posedge clk) begin : update_s_reg + if (rstn == 1'b0) begin + bankreg[S_REG_ID] <= '0; + end else begin + // soft reset pending + bankreg[S_REG_ID][S_SRST_BIT] <= timer_en; + end + end + + // + // Timer + // + + assign srst = timer_en; + + + always_ff @(posedge clk) begin + if (rstn == 1'b0) begin + timer_en <= 1'b0; + timestamp <= '0; + end else begin + if (bankreg[C_REG_ID][C_SRST_BIT] == 1'b1) timer_en <= 1'b1; + + if (timer_en == 1'b1) begin + timestamp <= timestamp + 1; + if (timestamp == 12'hFFF) timer_en <= 1'b0; + end + end + end endmodule diff --git a/rtl/misc/stdlib/config.vhd b/rtl/misc/stdlib/config.vhd index 424f529dfd..3a3c4aa02e 100644 --- a/rtl/misc/stdlib/config.vhd +++ b/rtl/misc/stdlib/config.vhd @@ -16,62 +16,63 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------- --- Package: config --- File: config.vhd --- Description: GRLIB Global configuration package. Can be overriden --- by local config packages in template designs. +-- Package: config +-- File: config.vhd +-- Description: GRLIB Global configuration package. Can be overriden +-- by local config packages in template designs. ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.esp_global.all; -use work.config_types.all; + use ieee.std_logic_1164.all; + use work.esp_global.all; + use work.config_types.all; package config is --- AHBDW - AHB data with --- --- Valid values are 32, 64, 128 and 256 --- --- The value here sets the width of the AMBA AHB data vectors for all --- cores in the library. --- -constant CFG_AHBDW : integer := ARCH_BITS; + -- AHBDW - AHB data with + -- + -- Valid values are 32, 64, 128 and 256 + -- + -- The value here sets the width of the AMBA AHB data vectors for all + -- cores in the library. + -- + constant CFG_AHBDW : integer := ARCH_BITS; + -- CFG_AHB_ACDM - Enable AMBA Compliant Data Muxing in cores + -- + -- Valid values are 0 and 1 + -- + -- 0: All GRLIB cores that use the ahbread* programs defined in the AMBA package + -- will read their data from the low part of the AHB data vector. + -- + -- 1: All GRLIB cores that use the ahbread* programs defined in the AMBA package + -- will select valid data, as defined in the AMBA AHB standard, from the + -- AHB data vectors based on the address input. If a core uses a function + -- that does not have the address input, a failure will be asserted. + -- + -- The value of CFG_AHB_ACDM is assigned to the constant CORE_ACDM in the + -- grlib.amba package. Note that this setting is separate from the ACDM setting + -- of the AHBCTRL core (which is set directly via a AHBCTRL VHDL generic). + -- + constant CFG_AHB_ACDM : integer := 0; --- CFG_AHB_ACDM - Enable AMBA Compliant Data Muxing in cores --- --- Valid values are 0 and 1 --- --- 0: All GRLIB cores that use the ahbread* programs defined in the AMBA package --- will read their data from the low part of the AHB data vector. --- --- 1: All GRLIB cores that use the ahbread* programs defined in the AMBA package --- will select valid data, as defined in the AMBA AHB standard, from the --- AHB data vectors based on the address input. If a core uses a function --- that does not have the address input, a failure will be asserted. --- --- The value of CFG_AHB_ACDM is assigned to the constant CORE_ACDM in the --- grlib.amba package. Note that this setting is separate from the ACDM setting --- of the AHBCTRL core (which is set directly via a AHBCTRL VHDL generic). --- -constant CFG_AHB_ACDM : integer := 0; - --- GRLIB_CONFIG_ARRAY - Array of configuration values --- --- The length of this array and the meaning of different positions is defined --- in the grlib.config_types package. -constant GRLIB_CONFIG_ARRAY : grlib_config_array_type := ( - grlib_debug_level => 0, - grlib_debug_mask => 0, - grlib_techmap_strict_ram => 0, - grlib_techmap_testin_extra => 0, - grlib_sync_reset_enable_all => 0, - grlib_async_reset_enable => 0, - grlib_amba_inc_nirq => 0, - others => 0); + -- GRLIB_CONFIG_ARRAY - Array of configuration values + -- + -- The length of this array and the meaning of different positions is defined + -- in the grlib.config_types package. + constant GRLIB_CONFIG_ARRAY : grlib_config_array_type := + ( + grlib_debug_level => 0, + grlib_debug_mask => 0, + grlib_techmap_strict_ram => 0, + grlib_techmap_testin_extra => 0, + grlib_sync_reset_enable_all => 0, + grlib_async_reset_enable => 0, + grlib_amba_inc_nirq => 0, + others => 0 + ); -end; +end package config; diff --git a/rtl/noc/router/lookahead_router.sv b/rtl/noc/router/lookahead_router.sv index 57239cb6b8..6f84243c8f 100644 --- a/rtl/noc/router/lookahead_router.sv +++ b/rtl/noc/router/lookahead_router.sv @@ -50,469 +50,479 @@ // Author: Michele Petracca //////////////////////////////////////////////////////////////////////////////// -module lookahead_router - #( +module lookahead_router #( parameter noc::noc_flow_control_t FlowControl = noc::kFlowControlAckNack, parameter int unsigned DataWidth = 32, parameter int unsigned PortWidth = DataWidth + $bits(noc::preamble_t), parameter bit [4:0] Ports = noc::AllPorts - ) - ( - input logic clk, - input logic rst, - // Coordinates - input noc::xy_t position, - // Input ports - input logic [PortWidth-1:0] data_n_in, - input logic [PortWidth-1:0] data_s_in, - input logic [PortWidth-1:0] data_w_in, - input logic [PortWidth-1:0] data_e_in, - input logic [PortWidth-1:0] data_p_in, - input logic [4:0] data_void_in, - output logic [4:0] stop_out, - // Output ports - output logic [PortWidth-1:0] data_n_out, - output logic [PortWidth-1:0] data_s_out, - output logic [PortWidth-1:0] data_w_out, - output logic [PortWidth-1:0] data_e_out, - output logic [PortWidth-1:0] data_p_out, - output logic [4:0] data_void_out, - input logic [4:0] stop_in - ); - - localparam bit FifoBypassEnable = FlowControl == noc::kFlowControlAckNack; - - localparam int unsigned ReservedWidth = - DataWidth - $bits(noc::packet_info_t) - $bits(noc::direction_t); - - typedef struct packed { - noc::preamble_t preamble; - noc::packet_info_t info; - logic [ReservedWidth-1:0] reserved; - noc::direction_t routing; - } header_t; - - typedef logic [PortWidth-1:0] payload_t; - - typedef union packed { - header_t header; - payload_t flit; - } flit_t; - - typedef enum logic { - kHeadFlit = 1'b0, - kPayloadFlits = 1'b1 - } state_t; - - state_t [4:0] state; - state_t [4:0] new_state; - - flit_t [4:0] data_in; - flit_t [4:0] fifo_head; - flit_t [4:0] data_out_crossbar; - flit_t [4:0] last_flit; - - logic [4:0][4:0] saved_routing_request; - logic [4:0][4:0] final_routing_request; // ri lint_check_waive NOT_READ - logic [4:0][4:0] next_hop_routing; - - logic [4:0][3:0] transp_final_routing_request; - - logic [4:0][4:0] enhanc_routing_configuration; - - logic [4:0][3:0] routing_configuration; - logic [4:0][3:0] saved_routing_configuration; - logic [4:0][3:0] grant; - logic [4:0] grant_valid; - - logic [4:0][4:0] rd_fifo; - logic [4:0] no_backpressure; - logic [4:0] rd_fifo_or; - - logic [4:0] in_unvalid_flit; - logic [4:0] out_unvalid_flit; - logic [4:0] in_valid_head; - - logic [4:0] full; - logic [4:0] empty; - logic [4:0] wr_fifo; - - noc::credits_t credits; - - logic [4:0] forwarding_tail; - logic [4:0] forwarding_head; - logic [4:0] forwarding_in_progress; - logic [4:0] insert_lookahead_routing; - - assign data_in[noc::kNorthPort] = data_n_in; - assign data_in[noc::kSouthPort] = data_s_in; - assign data_in[noc::kWestPort] = data_w_in; - assign data_in[noc::kEastPort] = data_e_in; - assign data_in[noc::kLocalPort] = data_p_in; - - // This router has a single cycle delay. - // When using ready-valid protocol, the register is placed at the output; for credit-based, - // the register is the input FIFO (not bypassable) and the output of the crossbar is not - // registered. - assign data_n_out = FifoBypassEnable ? last_flit[noc::kNorthPort] : +) ( + input logic clk, + input logic rst, + // Coordinates + input noc::xy_t position, + // Input ports + input logic [PortWidth-1:0] data_n_in, + input logic [PortWidth-1:0] data_s_in, + input logic [PortWidth-1:0] data_w_in, + input logic [PortWidth-1:0] data_e_in, + input logic [PortWidth-1:0] data_p_in, + input logic [4:0] data_void_in, + output logic [4:0] stop_out, + // Output ports + output logic [PortWidth-1:0] data_n_out, + output logic [PortWidth-1:0] data_s_out, + output logic [PortWidth-1:0] data_w_out, + output logic [PortWidth-1:0] data_e_out, + output logic [PortWidth-1:0] data_p_out, + output logic [4:0] data_void_out, + input logic [4:0] stop_in +); + + localparam bit FifoBypassEnable = FlowControl == noc::kFlowControlAckNack; + + localparam int unsigned ReservedWidth = DataWidth - $bits( + noc::packet_info_t + ) - $bits( + noc::direction_t + ); + + typedef struct packed { + noc::preamble_t preamble; + noc::packet_info_t info; + logic [ReservedWidth-1:0] reserved; + noc::direction_t routing; + } header_t; + + typedef logic [PortWidth-1:0] payload_t; + + typedef union packed { + header_t header; + payload_t flit; + } flit_t; + + typedef enum logic { + kHeadFlit = 1'b0, + kPayloadFlits = 1'b1 + } state_t; + + state_t [4:0] state; + state_t [4:0] new_state; + + flit_t [4:0] data_in; + flit_t [4:0] fifo_head; + flit_t [4:0] data_out_crossbar; + flit_t [4:0] last_flit; + + logic [4:0][4:0] saved_routing_request; + logic [4:0][4:0] final_routing_request; // ri lint_check_waive NOT_READ + logic [4:0][4:0] next_hop_routing; + + logic [4:0][3:0] transp_final_routing_request; + + logic [4:0][4:0] enhanc_routing_configuration; + + logic [4:0][3:0] routing_configuration; + logic [4:0][3:0] saved_routing_configuration; + logic [4:0][3:0] grant; + logic [4:0] grant_valid; + + logic [4:0][4:0] rd_fifo; + logic [4:0] no_backpressure; + logic [4:0] rd_fifo_or; + + logic [4:0] in_unvalid_flit; + logic [4:0] out_unvalid_flit; + logic [4:0] in_valid_head; + + logic [4:0] full; + logic [4:0] empty; + logic [4:0] wr_fifo; + + noc::credits_t credits; + + logic [4:0] forwarding_tail; + logic [4:0] forwarding_head; + logic [4:0] forwarding_in_progress; + logic [4:0] insert_lookahead_routing; + + assign data_in[noc::kNorthPort] = data_n_in; + assign data_in[noc::kSouthPort] = data_s_in; + assign data_in[noc::kWestPort] = data_w_in; + assign data_in[noc::kEastPort] = data_e_in; + assign data_in[noc::kLocalPort] = data_p_in; + + // This router has a single cycle delay. + // When using ready-valid protocol, the register is placed at the output; for credit-based, + // the register is the input FIFO (not bypassable) and the output of the crossbar is not + // registered. + assign data_n_out = FifoBypassEnable ? last_flit[noc::kNorthPort] : data_out_crossbar[noc::kNorthPort]; - assign data_s_out = FifoBypassEnable ? last_flit[noc::kSouthPort] : + assign data_s_out = FifoBypassEnable ? last_flit[noc::kSouthPort] : data_out_crossbar[noc::kSouthPort]; - assign data_w_out = FifoBypassEnable ? last_flit[noc::kWestPort] : + assign data_w_out = FifoBypassEnable ? last_flit[noc::kWestPort] : data_out_crossbar[noc::kWestPort]; - assign data_e_out = FifoBypassEnable ? last_flit[noc::kEastPort] : + assign data_e_out = FifoBypassEnable ? last_flit[noc::kEastPort] : data_out_crossbar[noc::kEastPort]; - assign data_p_out = FifoBypassEnable ? last_flit[noc::kLocalPort] : + assign data_p_out = FifoBypassEnable ? last_flit[noc::kLocalPort] : data_out_crossbar[noc::kLocalPort]; - genvar g_i; + genvar g_i; - ////////////////////////////////////////////////////////////////////////////// - // Input FIFOs and look-ahead routing - ////////////////////////////////////////////////////////////////////////////// - for (g_i = 0; g_i < 5; g_i++) begin : gen_input_fifo - if (Ports[g_i]) begin : gen_input_port_enabled + ////////////////////////////////////////////////////////////////////////////// + // Input FIFOs and look-ahead routing + ////////////////////////////////////////////////////////////////////////////// + for (g_i = 0; g_i < 5; g_i++) begin : gen_input_fifo + if (Ports[g_i]) begin : gen_input_port_enabled - // Read FIFO if any of the output ports requests data. - // The FIFO won't update read pointer if empty - assign rd_fifo_or[g_i] = rd_fifo[0][g_i] | rd_fifo[1][g_i] | rd_fifo[2][g_i] | + // Read FIFO if any of the output ports requests data. + // The FIFO won't update read pointer if empty + assign rd_fifo_or[g_i] = rd_fifo[0][g_i] | rd_fifo[1][g_i] | rd_fifo[2][g_i] | rd_fifo[3][g_i] | rd_fifo[4][g_i]; - // Write FIFO if data is valid. - // The FIFO won't accept the write if full. - assign wr_fifo[g_i] = ~data_void_in[g_i]; - - // Input FIFO - router_fifo - #( - .BypassEnable(FifoBypassEnable), - .Depth(noc::PortQueueDepth), - .Width(PortWidth) - ) - input_queue ( - .clk, - .rst, - .rdreq(rd_fifo_or[g_i]), - .wrreq(wr_fifo[g_i]), - .data_in(data_in[g_i]), - .empty(empty[g_i]), - .full(full[g_i]), - .data_out(fifo_head[g_i]) + // Write FIFO if data is valid. + // The FIFO won't accept the write if full. + assign wr_fifo[g_i] = ~data_void_in[g_i]; + + // Input FIFO + router_fifo #( + .BypassEnable(FifoBypassEnable), + .Depth(noc::PortQueueDepth), + .Width(PortWidth) + ) input_queue ( + .clk, + .rst, + .rdreq(rd_fifo_or[g_i]), + .wrreq(wr_fifo[g_i]), + .data_in(data_in[g_i]), + .empty(empty[g_i]), + .full(full[g_i]), + .data_out(fifo_head[g_i]) ); - assign in_unvalid_flit[g_i] = FifoBypassEnable ? empty[g_i] & data_void_in[g_i] : empty[g_i]; - assign in_valid_head[g_i] = fifo_head[g_i].header.preamble.head & ~in_unvalid_flit[g_i]; - - always_ff @(posedge clk) begin - if (rst) begin - saved_routing_request[g_i] <= '0; - end else begin - if (fifo_head[g_i].header.preamble.tail) begin - // Clear saved_routing_request if tail is next - saved_routing_request[g_i] <= '0; - end else if (in_valid_head[g_i]) begin - // Sample saved_routing_request if valid head flit - saved_routing_request[g_i] <= fifo_head[g_i].header.routing; - end - end - end - - assign final_routing_request[g_i] = in_valid_head[g_i] ? fifo_head[g_i].header.routing : + assign in_unvalid_flit[g_i] = FifoBypassEnable ? empty[g_i] & data_void_in[g_i] : empty[g_i]; + assign in_valid_head[g_i] = fifo_head[g_i].header.preamble.head & ~in_unvalid_flit[g_i]; + + always_ff @(posedge clk) begin + if (rst) begin + saved_routing_request[g_i] <= '0; + end else begin + if (fifo_head[g_i].header.preamble.tail) begin + // Clear saved_routing_request if tail is next + saved_routing_request[g_i] <= '0; + end else if (in_valid_head[g_i]) begin + // Sample saved_routing_request if valid head flit + saved_routing_request[g_i] <= fifo_head[g_i].header.routing; + end + end + end + + assign final_routing_request[g_i] = in_valid_head[g_i] ? fifo_head[g_i].header.routing : saved_routing_request[g_i]; - // AckNack: stop data at input port if FIFO is full - // CreditBased: send credits when reading from the input FIFO - assign stop_out[g_i] = FifoBypassEnable ? full[g_i] : + // AckNack: stop data at input port if FIFO is full + // CreditBased: send credits when reading from the input FIFO + assign stop_out[g_i] = FifoBypassEnable ? full[g_i] : ~(rd_fifo_or[g_i] & ~in_unvalid_flit[g_i]); - lookahead_routing lookahead_routing_i - ( - .clk, - .position, - .destination(fifo_head[g_i].header.info.destination), - .current_routing(fifo_head[g_i].header.routing), - .next_routing(next_hop_routing[g_i]) - ); - - end else begin : gen_input_port_disabled - - assign stop_out[g_i] = 1'b1; - assign final_routing_request[g_i] = '0; - assign saved_routing_request[g_i] = '0; - assign in_unvalid_flit[g_i] = '1; - assign fifo_head[g_i] = '0; - assign empty[g_i] = 1'b1; - assign full[g_i] = '0; - assign next_hop_routing[g_i] = '0; - assign rd_fifo_or[g_i] = '0; - assign wr_fifo[g_i] = '0; - assign in_valid_head[g_i] = 1'b0; - - end // if (Ports[g_i]) - - end // for gen_input_fifo - - - ////////////////////////////////////////////////////////////////////////////// - // Output crossbar and arbitration - ////////////////////////////////////////////////////////////////////////////// - for (g_i = 0; g_i < 5; g_i++) begin : gen_output_control - if (Ports[g_i]) begin : gen_output_port_enabled - - genvar g_j; - for (g_j = 0; g_j < 5; g_j++) begin : gen_transpose_routing - // transpose current routing request for easier accesss, but - // allow routing only to output port different from input port - if (g_j < g_i) begin : gen_transpose_routin_j_lt_i - assign transp_final_routing_request[g_i][g_j] = final_routing_request[g_j][g_i]; - assign enhanc_routing_configuration[g_i][g_j] = routing_configuration[g_i][g_j]; - end else if (g_j > g_i) begin : gen_transpose_routin_j_gt_i - assign transp_final_routing_request[g_i][g_j-1] = final_routing_request[g_j][g_i]; - assign enhanc_routing_configuration[g_i][g_j] = routing_configuration[g_i][g_j-1]; - end else begin : gen_transpose_routin_j_eq_i - assign enhanc_routing_configuration[g_i][g_j] = 1'b0; - end - end // for gen_transpose_routing - - // Arbitration - router_arbiter arbiter_i ( - .clk(clk), - .rst(rst), - .request(transp_final_routing_request[g_i]), - .forwarding_head(forwarding_head[g_i]), - .forwarding_tail(forwarding_tail[g_i]), - .grant(grant[g_i]), - .grant_valid(grant_valid[g_i]) - ); - - // Sample current routing configuration - always_ff @(posedge clk) begin - if (forwarding_in_progress[g_i]) begin - saved_routing_configuration[g_i] <= routing_configuration[g_i]; - end - end - - // Set to overwrite routing info only on the head flit - always_ff @(posedge clk) begin - if (rst) begin - // First flit must be head - insert_lookahead_routing[g_i] <= 1'b1; - end else begin - if (forwarding_tail[g_i]) begin - // Next flit will be head (convers single-flit packet) - insert_lookahead_routing[g_i] <= 1'b1; - end else if (forwarding_head[g_i]) begin - // Next flit will not be head - insert_lookahead_routing[g_i] <= 1'b0; - end - end - end - - // Crossbar - always_comb begin - data_out_crossbar[g_i] = '0; - rd_fifo[g_i] = '0; - out_unvalid_flit[g_i] = 1'b1; - - unique case (enhanc_routing_configuration[g_i]) - noc::goNorth : begin - data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kNorthPort] : + lookahead_routing lookahead_routing_i ( + .clk, + .position, + .destination(fifo_head[g_i].header.info.destination), + .current_routing(fifo_head[g_i].header.routing), + .next_routing(next_hop_routing[g_i]) + ); + + end else begin : gen_input_port_disabled + + assign stop_out[g_i] = 1'b1; + assign final_routing_request[g_i] = '0; + assign saved_routing_request[g_i] = '0; + assign in_unvalid_flit[g_i] = '1; + assign fifo_head[g_i] = '0; + assign empty[g_i] = 1'b1; + assign full[g_i] = '0; + assign next_hop_routing[g_i] = '0; + assign rd_fifo_or[g_i] = '0; + assign wr_fifo[g_i] = '0; + assign in_valid_head[g_i] = 1'b0; + + end // if (Ports[g_i]) + + end // for gen_input_fifo + + + ////////////////////////////////////////////////////////////////////////////// + // Output crossbar and arbitration + ////////////////////////////////////////////////////////////////////////////// + for (g_i = 0; g_i < 5; g_i++) begin : gen_output_control + if (Ports[g_i]) begin : gen_output_port_enabled + + genvar g_j; + for (g_j = 0; g_j < 5; g_j++) begin : gen_transpose_routing + // transpose current routing request for easier accesss, but + // allow routing only to output port different from input port + if (g_j < g_i) begin : gen_transpose_routin_j_lt_i + assign transp_final_routing_request[g_i][g_j] = final_routing_request[g_j][g_i]; + assign enhanc_routing_configuration[g_i][g_j] = routing_configuration[g_i][g_j]; + end else if (g_j > g_i) begin : gen_transpose_routin_j_gt_i + assign transp_final_routing_request[g_i][g_j-1] = final_routing_request[g_j][g_i]; + assign enhanc_routing_configuration[g_i][g_j] = routing_configuration[g_i][g_j-1]; + end else begin : gen_transpose_routin_j_eq_i + assign enhanc_routing_configuration[g_i][g_j] = 1'b0; + end + end // for gen_transpose_routing + + // Arbitration + router_arbiter arbiter_i ( + .clk(clk), + .rst(rst), + .request(transp_final_routing_request[g_i]), + .forwarding_head(forwarding_head[g_i]), + .forwarding_tail(forwarding_tail[g_i]), + .grant(grant[g_i]), + .grant_valid(grant_valid[g_i]) + ); + + // Sample current routing configuration + always_ff @(posedge clk) begin + if (forwarding_in_progress[g_i]) begin + saved_routing_configuration[g_i] <= routing_configuration[g_i]; + end + end + + // Set to overwrite routing info only on the head flit + always_ff @(posedge clk) begin + if (rst) begin + // First flit must be head + insert_lookahead_routing[g_i] <= 1'b1; + end else begin + if (forwarding_tail[g_i]) begin + // Next flit will be head (convers single-flit packet) + insert_lookahead_routing[g_i] <= 1'b1; + end else if (forwarding_head[g_i]) begin + // Next flit will not be head + insert_lookahead_routing[g_i] <= 1'b0; + end + end + end + + // Crossbar + always_comb begin + data_out_crossbar[g_i] = '0; + rd_fifo[g_i] = '0; + out_unvalid_flit[g_i] = 1'b1; + + unique case (enhanc_routing_configuration[g_i]) + noc::goNorth: begin + data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kNorthPort] : {fifo_head[noc::kNorthPort].flit[PortWidth-1:5], next_hop_routing[noc::kNorthPort]}; - rd_fifo[g_i][noc::kNorthPort] = no_backpressure[g_i]; - out_unvalid_flit[g_i] = in_unvalid_flit[noc::kNorthPort]; - end + rd_fifo[g_i][noc::kNorthPort] = no_backpressure[g_i]; + out_unvalid_flit[g_i] = in_unvalid_flit[noc::kNorthPort]; + end - noc::goSouth : begin - data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kSouthPort] : + noc::goSouth: begin + data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kSouthPort] : {fifo_head[noc::kSouthPort].flit[PortWidth-1:5], next_hop_routing[noc::kSouthPort]}; - rd_fifo[g_i][noc::kSouthPort] = no_backpressure[g_i]; - out_unvalid_flit[g_i] = in_unvalid_flit[noc::kSouthPort]; - end + rd_fifo[g_i][noc::kSouthPort] = no_backpressure[g_i]; + out_unvalid_flit[g_i] = in_unvalid_flit[noc::kSouthPort]; + end - noc::goWest : begin - data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kWestPort] : + noc::goWest: begin + data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kWestPort] : {fifo_head[noc::kWestPort].flit[PortWidth-1:5], next_hop_routing[noc::kWestPort]}; - rd_fifo[g_i][noc::kWestPort] = no_backpressure[g_i]; - out_unvalid_flit[g_i] = in_unvalid_flit[noc::kWestPort]; - end + rd_fifo[g_i][noc::kWestPort] = no_backpressure[g_i]; + out_unvalid_flit[g_i] = in_unvalid_flit[noc::kWestPort]; + end - noc::goEast : begin - data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kEastPort] : + noc::goEast: begin + data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kEastPort] : {fifo_head[noc::kEastPort].flit[PortWidth-1:5], next_hop_routing[noc::kEastPort]}; - rd_fifo[g_i][noc::kEastPort] = no_backpressure[g_i]; - out_unvalid_flit[g_i] = in_unvalid_flit[noc::kEastPort]; - end + rd_fifo[g_i][noc::kEastPort] = no_backpressure[g_i]; + out_unvalid_flit[g_i] = in_unvalid_flit[noc::kEastPort]; + end - noc::goLocal : begin - data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kLocalPort] : + noc::goLocal: begin + data_out_crossbar[g_i] = ~insert_lookahead_routing[g_i] ? fifo_head[noc::kLocalPort] : {fifo_head[noc::kLocalPort].flit[PortWidth-1:5], next_hop_routing[noc::kLocalPort]}; - rd_fifo[g_i][noc::kLocalPort] = no_backpressure[g_i]; - out_unvalid_flit[g_i] = in_unvalid_flit[noc::kLocalPort]; - end - - default : begin - end - endcase - end - - - // Sample output - always_ff @(posedge clk) begin - if (rst) begin - last_flit[g_i] <= '0; - end else begin - if (FifoBypassEnable) begin - if (no_backpressure[g_i] & forwarding_in_progress[g_i] & ~out_unvalid_flit[g_i]) begin - last_flit[g_i] <= data_out_crossbar[g_i]; + rd_fifo[g_i][noc::kLocalPort] = no_backpressure[g_i]; + out_unvalid_flit[g_i] = in_unvalid_flit[noc::kLocalPort]; + end + + default: begin + end + endcase end - end else begin - if (~data_void_out[g_i]) begin - last_flit[g_i] <= data_out_crossbar[g_i]; + + + // Sample output + always_ff @(posedge clk) begin + if (rst) begin + last_flit[g_i] <= '0; + end else begin + if (FifoBypassEnable) begin + if (no_backpressure[g_i] & forwarding_in_progress[g_i] & ~out_unvalid_flit[g_i]) begin + last_flit[g_i] <= data_out_crossbar[g_i]; + end + end else begin + if (~data_void_out[g_i]) begin + last_flit[g_i] <= data_out_crossbar[g_i]; + end + end + end end - end - end - end - // Flow control - assign no_backpressure[g_i] = FifoBypassEnable ? ~stop_in[g_i] : credits[g_i] != '0; - assign forwarding_tail[g_i] = data_out_crossbar[g_i].header.preamble.tail & + // Flow control + assign no_backpressure[g_i] = FifoBypassEnable ? ~stop_in[g_i] : credits[g_i] != '0; + assign forwarding_tail[g_i] = data_out_crossbar[g_i].header.preamble.tail & ~out_unvalid_flit[g_i] & no_backpressure[g_i]; - assign forwarding_head[g_i] = data_out_crossbar[g_i].header.preamble.head & + assign forwarding_head[g_i] = data_out_crossbar[g_i].header.preamble.head & ~out_unvalid_flit[g_i] & no_backpressure[g_i]; - always_comb begin : flow_control_fsm - new_state[g_i] = state[g_i]; - routing_configuration[g_i] = '0; - forwarding_in_progress[g_i] = 1'b0; - - unique case (state[g_i]) - kHeadFlit : begin - if (grant_valid[g_i] & no_backpressure[g_i]) begin - // First flit of a new packet can be forwarded - routing_configuration[g_i] = grant[g_i]; - forwarding_in_progress[g_i] = 1'b1; - if (~data_out_crossbar[g_i].header.preamble.tail) begin - // Non-single-flit packet; expecting more payload flit - new_state[g_i] = kPayloadFlits; - end + always_comb begin : flow_control_fsm + new_state[g_i] = state[g_i]; + routing_configuration[g_i] = '0; + forwarding_in_progress[g_i] = 1'b0; + + unique case (state[g_i]) + kHeadFlit: begin + if (grant_valid[g_i] & no_backpressure[g_i]) begin + // First flit of a new packet can be forwarded + routing_configuration[g_i] = grant[g_i]; + forwarding_in_progress[g_i] = 1'b1; + if (~data_out_crossbar[g_i].header.preamble.tail) begin + // Non-single-flit packet; expecting more payload flit + new_state[g_i] = kPayloadFlits; + end + end + end + + kPayloadFlits: begin + // Payload of a packet is being forwarded; do not change routing configuration + routing_configuration[g_i] = saved_routing_configuration[g_i]; + forwarding_in_progress[g_i] = 1'b1; + if (forwarding_tail[g_i]) begin + // Next flit must be head + new_state[g_i] = kHeadFlit; + end + end + + default: begin + end + endcase // unique case (state[g_i]) end - end - - kPayloadFlits : begin - // Payload of a packet is being forwarded; do not change routing configuration - routing_configuration[g_i] = saved_routing_configuration[g_i]; - forwarding_in_progress[g_i] = 1'b1; - if (forwarding_tail[g_i]) begin - // Next flit must be head - new_state[g_i] = kHeadFlit; - end - end - - default : begin - end - endcase // unique case (state[g_i]) - end - - always_ff @(posedge clk) begin - if (rst) begin - state[g_i] <= kHeadFlit; - end else begin - state[g_i] <= new_state[g_i]; - end - end - - // Data void out and credits - if (FifoBypassEnable) begin : gen_data_void_out_acknack - always_ff @(posedge clk) begin - if (rst) begin - data_void_out[g_i] <= 1'b1; - end else begin - if (~forwarding_in_progress[g_i] && no_backpressure[g_i]) begin - data_void_out[g_i] <= 1'b1; - end else if (no_backpressure[g_i]) begin - data_void_out[g_i] <= out_unvalid_flit[g_i]; + + always_ff @(posedge clk) begin + if (rst) begin + state[g_i] <= kHeadFlit; + end else begin + state[g_i] <= new_state[g_i]; + end end - end - end - assign credits[g_i] = '0; - end else begin : gen_data_void_out_creditbased - assign data_void_out[g_i] = forwarding_in_progress[g_i] & no_backpressure[g_i] ? + + // Data void out and credits + if (FifoBypassEnable) begin : gen_data_void_out_acknack + always_ff @(posedge clk) begin + if (rst) begin + data_void_out[g_i] <= 1'b1; + end else begin + if (~forwarding_in_progress[g_i] && no_backpressure[g_i]) begin + data_void_out[g_i] <= 1'b1; + end else if (no_backpressure[g_i]) begin + data_void_out[g_i] <= out_unvalid_flit[g_i]; + end + end + end + assign credits[g_i] = '0; + end else begin : gen_data_void_out_creditbased + assign data_void_out[g_i] = forwarding_in_progress[g_i] & no_backpressure[g_i] ? out_unvalid_flit[g_i] : 1'b1; - always_ff @(posedge clk) begin - if (rst) begin - credits[g_i] = noc::PortQueueDepth; - end else begin - if (~data_void_out[g_i]) begin - credits[g_i] = credits[g_i] - stop_in[g_i]; - end else begin - credits[g_i] = credits[g_i] + ~stop_in[g_i]; + always_ff @(posedge clk) begin + if (rst) begin + credits[g_i] = noc::PortQueueDepth; + end else begin + if (~data_void_out[g_i]) begin + credits[g_i] = credits[g_i] - stop_in[g_i]; + end else begin + credits[g_i] = credits[g_i] + ~stop_in[g_i]; + end + end + end end - end - end - end - - - - end else begin : gen_input_port_disabled - assign grant_valid[g_i] = '0; - assign grant[g_i] = '0; - assign data_void_out[g_i] = '1; - assign out_unvalid_flit[g_i] = '1; - assign data_out_crossbar[g_i] = '0; - assign last_flit[g_i] = '0; - assign routing_configuration[g_i] = '0; - assign saved_routing_configuration[g_i] = '0; - assign rd_fifo[g_i] = '0; - assign no_backpressure[g_i] = '1; - assign forwarding_tail[g_i] = '0; - assign forwarding_head[g_i] = '0; - assign forwarding_in_progress[g_i] = '0; - assign insert_lookahead_routing[g_i] = '0; - assign credits[g_i] = '0; - end // block: gen_output_port_enabled - - end // for gen_output_control - - ////////////////////////////////////////////////////////////////////////////// - // Assertions - ////////////////////////////////////////////////////////////////////////////// + + + + end else begin : gen_input_port_disabled + assign grant_valid[g_i] = '0; + assign grant[g_i] = '0; + assign data_void_out[g_i] = '1; + assign out_unvalid_flit[g_i] = '1; + assign data_out_crossbar[g_i] = '0; + assign last_flit[g_i] = '0; + assign routing_configuration[g_i] = '0; + assign saved_routing_configuration[g_i] = '0; + assign rd_fifo[g_i] = '0; + assign no_backpressure[g_i] = '1; + assign forwarding_tail[g_i] = '0; + assign forwarding_head[g_i] = '0; + assign forwarding_in_progress[g_i] = '0; + assign insert_lookahead_routing[g_i] = '0; + assign credits[g_i] = '0; + end // block: gen_output_port_enabled + + end // for gen_output_control + + ////////////////////////////////////////////////////////////////////////////// + // Assertions + ////////////////////////////////////////////////////////////////////////////// `ifndef SYNTHESIS -// pragma coverage off -//VCS coverage off - - if (DataWidth < $bits(noc::packet_info_t) + $bits(noc::direction_t)) begin : gen_a_data_width - $fatal(2'd2, "Fail: DataWidth insufficient to hold packet and routing information."); - end - - if ($bits(header_t) != DataWidth + $bits(noc::preamble_t)) begin : gen_a_header_width - $fatal(2'd2, "Fail: header_t width (%02d) must be DataWidth (%02d) + preamble_t width (%01d)", - $bits(header_t), DataWidth, $bits(noc::preamble_t)); - end - - if (PortWidth != $bits(header_t)) begin : gen_a_port_width - $fatal(2'd2, "Fail: PortWidth must match header_t width."); - end - - for (g_i = 0; g_i < 4; g_i++) begin : gen_assert_legal_routing_request - a_no_request_to_same_port: assert property (@(posedge clk) disable iff(rst) - final_routing_request[g_i][g_i] == 1'b0) - else $error("Fail: a_no_request_to_same_port"); - a_enhanc_routing_configuration_onehot: assert property (@(posedge clk) disable iff(rst) - $onehot0(enhanc_routing_configuration[g_i])) - else $error("Fail: a_enhanc_routing_configuration_onehot"); - a_expect_head_flit: assert property (@(posedge clk) disable iff(rst) + // pragma coverage off + //VCS coverage off + + if (DataWidth < $bits(noc::packet_info_t) + $bits(noc::direction_t)) begin : gen_a_data_width + $fatal(2'd2, "Fail: DataWidth insufficient to hold packet and routing information."); + end + + if ($bits(header_t) != DataWidth + $bits(noc::preamble_t)) begin : gen_a_header_width + $fatal( + 2'd2, + "Fail: header_t width (%02d) must be DataWidth (%02d) + preamble_t width (%01d)", + $bits( + header_t + ), + DataWidth, + $bits( + noc::preamble_t + ) + ); + end + + if (PortWidth != $bits(header_t)) begin : gen_a_port_width + $fatal(2'd2, "Fail: PortWidth must match header_t width."); + end + + for (g_i = 0; g_i < 4; g_i++) begin : gen_assert_legal_routing_request + a_no_request_to_same_port : + assert property (@(posedge clk) disable iff (rst) final_routing_request[g_i][g_i] == 1'b0) + else $error("Fail: a_no_request_to_same_port"); + a_enhanc_routing_configuration_onehot : + assert property (@(posedge clk) disable iff (rst) $onehot0( + enhanc_routing_configuration[g_i] + )) + else $error("Fail: a_enhanc_routing_configuration_onehot"); + a_expect_head_flit : + assert property (@(posedge clk) disable iff(rst) ~out_unvalid_flit[g_i] & state[g_i] == kHeadFlit |-> data_out_crossbar[g_i].header.preamble.head) - else $error("Fail: a_expect_head_flit"); - a_credits_in_range: assert property (@(posedge clk) disable iff(rst) - credits[g_i] <= noc::PortQueueDepth) - else $error("Fail: a_enhanc_routing_configuration_onehot"); - end - -// pragma coverage on -//VCS coverage on -`endif // ~SYNTHESIS + else $error("Fail: a_expect_head_flit"); + a_credits_in_range : + assert property (@(posedge clk) disable iff (rst) credits[g_i] <= noc::PortQueueDepth) + else $error("Fail: a_enhanc_routing_configuration_onehot"); + end + + // pragma coverage on + //VCS coverage on +`endif // ~SYNTHESIS endmodule diff --git a/rtl/peripherals/ddr/ahb2bsg_dmc.vhd b/rtl/peripherals/ddr/ahb2bsg_dmc.vhd index 9d9a28cbeb..7649d8e32d 100644 --- a/rtl/peripherals/ddr/ahb2bsg_dmc.vhd +++ b/rtl/peripherals/ddr/ahb2bsg_dmc.vhd @@ -11,318 +11,473 @@ ------------------------------------------------------------------------------- library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.all; -use work.ahb2mig_7series_pkg.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.config_types.all; -use work.config.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.all; + use work.ahb2mig_7series_pkg.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.config_types.all; + use work.config.all; + library std; -use std.textio.all; + use std.textio.all; entity ahb2bsg_dmc is - port( - hindex : in integer; - haddr : in integer range 0 to 4095; - hmask : in integer range 0 to 4095; - lpddr_ck_p : out std_logic; - lpddr_ck_n : out std_logic; - lpddr_cke : out std_logic; - lpddr_ba : out std_logic_vector(2 downto 0); - lpddr_addr : out std_logic_vector(15 downto 0); - lpddr_cs_n : out std_logic; - lpddr_ras_n : out std_logic; - lpddr_cas_n : out std_logic; - lpddr_we_n : out std_logic; - lpddr_reset_n : out std_logic; - lpddr_odt : out std_logic; - lpddr_dm_oen : out std_logic_vector(3 downto 0); - lpddr_dm : out std_logic_vector(3 downto 0); - lpddr_dqs_p_oen : out std_logic_vector(3 downto 0); - lpddr_dqs_p_ien : out std_logic_vector(3 downto 0); - lpddr_dqs_p_o : out std_logic_vector(3 downto 0); - lpddr_dqs_p_i : in std_logic_vector(3 downto 0); - lpddr_dqs_n_oen : out std_logic_vector(3 downto 0); - lpddr_dqs_n_ien : out std_logic_vector(3 downto 0); - lpddr_dqs_n_o : out std_logic_vector(3 downto 0); - lpddr_dqs_n_i : in std_logic_vector(3 downto 0); - lpddr_dq_oen : out std_logic_vector(31 downto 0); - lpddr_dq_o : out std_logic_vector(31 downto 0); - lpddr_dq_i : in std_logic_vector(31 downto 0); - ddr_cfg0 : in std_logic_vector(31 downto 0); - ddr_cfg1 : in std_logic_vector(31 downto 0); - ddr_cfg2 : in std_logic_vector(31 downto 0); - ahbso : out ahb_slv_out_type; - ahbsi : in ahb_slv_in_type; - calib_done : out std_logic; - ui_clk : in std_logic; - ui_rstn : in std_logic; - phy_clk_1x : in std_logic; - phy_clk_2x : in std_logic; - phy_rstn : in std_logic - ); -end; + port ( + hindex : in integer; + haddr : in integer range 0 to 4095; + hmask : in integer range 0 to 4095; + lpddr_ck_p : out std_logic; + lpddr_ck_n : out std_logic; + lpddr_cke : out std_logic; + lpddr_ba : out std_logic_vector(2 downto 0); + lpddr_addr : out std_logic_vector(15 downto 0); + lpddr_cs_n : out std_logic; + lpddr_ras_n : out std_logic; + lpddr_cas_n : out std_logic; + lpddr_we_n : out std_logic; + lpddr_reset_n : out std_logic; + lpddr_odt : out std_logic; + lpddr_dm_oen : out std_logic_vector(3 downto 0); + lpddr_dm : out std_logic_vector(3 downto 0); + lpddr_dqs_p_oen : out std_logic_vector(3 downto 0); + lpddr_dqs_p_ien : out std_logic_vector(3 downto 0); + lpddr_dqs_p_o : out std_logic_vector(3 downto 0); + lpddr_dqs_p_i : in std_logic_vector(3 downto 0); + lpddr_dqs_n_oen : out std_logic_vector(3 downto 0); + lpddr_dqs_n_ien : out std_logic_vector(3 downto 0); + lpddr_dqs_n_o : out std_logic_vector(3 downto 0); + lpddr_dqs_n_i : in std_logic_vector(3 downto 0); + lpddr_dq_oen : out std_logic_vector(31 downto 0); + lpddr_dq_o : out std_logic_vector(31 downto 0); + lpddr_dq_i : in std_logic_vector(31 downto 0); + ddr_cfg0 : in std_logic_vector(31 downto 0); + ddr_cfg1 : in std_logic_vector(31 downto 0); + ddr_cfg2 : in std_logic_vector(31 downto 0); + ahbso : out ahb_slv_out_type; + ahbsi : in ahb_slv_in_type; + calib_done : out std_logic; + ui_clk : in std_logic; + ui_rstn : in std_logic; + phy_clk_1x : in std_logic; + phy_clk_2x : in std_logic; + phy_rstn : in std_logic + ); +end entity ahb2bsg_dmc; architecture rtl of ahb2bsg_dmc is component bsg_dmc_wrap is generic ( - ui_addr_width_p : integer := 28; - ui_data_width_p : integer := 64; + ui_addr_width_p : integer := 28; + ui_data_width_p : integer := 64; ui_burst_length_p : integer := 8; - dq_data_width_p : integer := 32; + dq_data_width_p : integer := 32; cmd_afifo_depth_p : integer := 4; cmd_sfifo_depth_p : integer := 4 - ); + ); port ( -- User interface input signals - app_addr : in std_logic_vector(ui_addr_width_p - 1 downto 0); - app_cmd : in std_logic_vector(2 downto 0); - app_en : in std_logic; - app_wdf_data : in std_logic_vector(ui_data_width_p - 1 downto 0); - app_wdf_end : in std_logic; - app_wdf_mask : in std_logic_vector((ui_data_width_p / 8) - 1 downto 0); - app_wdf_wren : in std_logic; + app_addr : in std_logic_vector(ui_addr_width_p - 1 downto 0); + app_cmd : in std_logic_vector(2 downto 0); + app_en : in std_logic; + app_wdf_data : in std_logic_vector(ui_data_width_p - 1 downto 0); + app_wdf_end : in std_logic; + app_wdf_mask : in std_logic_vector((ui_data_width_p / 8) - 1 downto 0); + app_wdf_wren : in std_logic; -- User interface output signals - app_rd_data : out std_logic_vector(ui_data_width_p - 1 downto 0); - app_rd_data_end : out std_logic; - app_rd_data_valid : out std_logic; - app_rdy : out std_logic; - app_wdf_rdy : out std_logic; + app_rd_data : out std_logic_vector(ui_data_width_p - 1 downto 0); + app_rd_data_end : out std_logic; + app_rd_data_valid : out std_logic; + app_rdy : out std_logic; + app_wdf_rdy : out std_logic; -- Status signal - init_calib_complete : out std_logic; + init_calib_complete : out std_logic; -- Tile clock == DDR clock (200 MHz rotated 90 degrees) and tile synchronous reset - ui_clk_i : in std_logic; - ui_reset_i : in std_logic; + ui_clk_i : in std_logic; + ui_reset_i : in std_logic; -- PHY 2x clock (400 MHz) and 1x clock (200 MHz) with synchronous reset - dfi_clk_2x_i : in std_logic; - dfi_clk_1x_i : in std_logic; - dfi_reset_i : in std_logic; + dfi_clk_2x_i : in std_logic; + dfi_clk_1x_i : in std_logic; + dfi_reset_i : in std_logic; -- Command and Address interface - ddr_ck_p_o : out std_logic; - ddr_ck_n_o : out std_logic; - ddr_cke_o : out std_logic; - ddr_ba_o : out std_logic_vector(2 downto 0); - ddr_addr_o : out std_logic_vector(15 downto 0); - ddr_cs_n_o : out std_logic; - ddr_ras_n_o : out std_logic; - ddr_cas_n_o : out std_logic; - ddr_we_n_o : out std_logic; - ddr_reset_n_o : out std_logic; - ddr_odt_o : out std_logic; + ddr_ck_p_o : out std_logic; + ddr_ck_n_o : out std_logic; + ddr_cke_o : out std_logic; + ddr_ba_o : out std_logic_vector(2 downto 0); + ddr_addr_o : out std_logic_vector(15 downto 0); + ddr_cs_n_o : out std_logic; + ddr_ras_n_o : out std_logic; + ddr_cas_n_o : out std_logic; + ddr_we_n_o : out std_logic; + ddr_reset_n_o : out std_logic; + ddr_odt_o : out std_logic; -- Data interface - ddr_dm_oen_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dm_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dqs_p_oen_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dqs_p_ien_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dqs_p_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dqs_p_i : in std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dqs_n_oen_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dqs_n_ien_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dqs_n_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dqs_n_i : in std_logic_vector((dq_data_width_p / 8) - 1 downto 0); - ddr_dq_oen_o : out std_logic_vector(dq_data_width_p - 1 downto 0); - ddr_dq_o : out std_logic_vector(dq_data_width_p - 1 downto 0); - ddr_dq_i : in std_logic_vector(dq_data_width_p - 1 downto 0); + ddr_dm_oen_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dm_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dqs_p_oen_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dqs_p_ien_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dqs_p_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dqs_p_i : in std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dqs_n_oen_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dqs_n_ien_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dqs_n_o : out std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dqs_n_i : in std_logic_vector((dq_data_width_p / 8) - 1 downto 0); + ddr_dq_oen_o : out std_logic_vector(dq_data_width_p - 1 downto 0); + ddr_dq_o : out std_logic_vector(dq_data_width_p - 1 downto 0); + ddr_dq_i : in std_logic_vector(dq_data_width_p - 1 downto 0); -- Delay line configuration - delay_sel_i : in std_logic_vector(3 downto 0); + delay_sel_i : in std_logic_vector(3 downto 0); -- DDR controller configuration - trefi_i : in std_logic_vector(12 downto 0); - tmrd_i : in std_logic_vector(3 downto 0); - trfc_i : in std_logic_vector(3 downto 0); - trc_i : in std_logic_vector(3 downto 0); - trp_i : in std_logic_vector(3 downto 0); - tras_i : in std_logic_vector(3 downto 0); - trrd_i : in std_logic_vector(3 downto 0); - trcd_i : in std_logic_vector(3 downto 0); - twr_i : in std_logic_vector(3 downto 0); - twtr_i : in std_logic_vector(3 downto 0); - trtp_i : in std_logic_vector(3 downto 0); - tcas_i : in std_logic_vector(3 downto 0); - col_width_i : in std_logic_vector(3 downto 0); - row_width_i : in std_logic_vector(3 downto 0); - bank_width_i : in std_logic_vector(1 downto 0); - bank_pos_i : in std_logic_vector(5 downto 0); - dqs_sel_cal_i : in std_logic_vector(2 downto 0); - init_cycles_i : in std_logic_vector(15 downto 0) - ); + trefi_i : in std_logic_vector(12 downto 0); + tmrd_i : in std_logic_vector(3 downto 0); + trfc_i : in std_logic_vector(3 downto 0); + trc_i : in std_logic_vector(3 downto 0); + trp_i : in std_logic_vector(3 downto 0); + tras_i : in std_logic_vector(3 downto 0); + trrd_i : in std_logic_vector(3 downto 0); + trcd_i : in std_logic_vector(3 downto 0); + twr_i : in std_logic_vector(3 downto 0); + twtr_i : in std_logic_vector(3 downto 0); + trtp_i : in std_logic_vector(3 downto 0); + tcas_i : in std_logic_vector(3 downto 0); + col_width_i : in std_logic_vector(3 downto 0); + row_width_i : in std_logic_vector(3 downto 0); + bank_width_i : in std_logic_vector(1 downto 0); + bank_pos_i : in std_logic_vector(5 downto 0); + dqs_sel_cal_i : in std_logic_vector(2 downto 0); + init_cycles_i : in std_logic_vector(15 downto 0) + ); end component bsg_dmc_wrap; -- Calibration complete flag synchronizer signal init_calib_complete : std_logic_vector(0 to 7); - signal calib_done_delayed : std_ulogic; - signal calib_done_count : std_logic_vector(4 downto 0); + signal calib_done_delayed : std_ulogic; + signal calib_done_count : std_logic_vector(4 downto 0); - attribute ASYNC_REG : string; - attribute ASYNC_REG of init_calib_complete: signal is "TRUE"; + attribute async_reg : string; + attribute async_reg of init_calib_complete : signal is "TRUE"; signal trefi_ext : std_logic_vector(12 downto 0); - signal ui_rst : std_logic; + signal ui_rst : std_logic; signal phy_rst : std_logic; signal ddr_dqs_p_ien : std_logic_vector(3 downto 0); - signal ddr_dqs_p_i : std_logic_vector(3 downto 0); + signal ddr_dqs_p_i : std_logic_vector(3 downto 0); signal ddr_dqs_n_ien : std_logic_vector(3 downto 0); - signal ddr_dqs_n_i : std_logic_vector(3 downto 0); + signal ddr_dqs_n_i : std_logic_vector(3 downto 0); signal hconfig : ahb_config_type; type reg_type is record -- MIG inputs - addr : std_logic_vector(27 downto 0); - cmd : std_logic_vector(2 downto 0); - en : std_logic; + addr : std_logic_vector(27 downto 0); + cmd : std_logic_vector(2 downto 0); + en : std_logic; wdf_wren : std_logic; - wdf_end : std_logic; - wdf_data : std_Logic_vector(64 - 1 downto 0); - wdf_mask : std_logic_vector(AHBDW/8 - 1 downto 0); + wdf_end : std_logic; + wdf_data : std_logic_vector(64 - 1 downto 0); + wdf_mask : std_logic_vector(AHBDW / 8 - 1 downto 0); -- AHB slv - valid : std_logic; - hwrite : std_logic; - hready : std_logic; - hrdata : std_logic_vector(AHBDW - 1 downto 0); + valid : std_logic; + hwrite : std_logic; + hready : std_logic; + hrdata : std_logic_vector(AHBDW - 1 downto 0); haddr_offset : std_logic_vector(2 downto 0); - hsize : std_logic_vector(2 downto 0); - end record; - - constant REG_RESET : reg_type := ( - addr => (others => '0'), - cmd => (others => '0'), - en => '0', - wdf_wren => '0', - wdf_end => '0', - wdf_data => (others => '0'), - wdf_mask => (others => '0'), - valid => '0', - hwrite => '0', - hready => '1', - hrdata => (others => '0'), + hsize : std_logic_vector(2 downto 0); + end record reg_type; + + constant REG_RESET : reg_type := + ( + addr => (others => '0'), + cmd => (others => '0'), + en => '0', + wdf_wren => '0', + wdf_end => '0', + wdf_data => (others => '0'), + wdf_mask => (others => '0'), + valid => '0', + hwrite => '0', + hready => '1', + hrdata => (others => '0'), haddr_offset => (others => '0'), - hsize => HSIZE_DWORD - ); + hsize => HSIZE_DWORD + ); type mig_in_type is record - app_addr : std_logic_vector(27 downto 0); - app_cmd : std_logic_vector(2 downto 0); - app_en : std_logic; - app_hi_pri : std_logic; + app_addr : std_logic_vector(27 downto 0); + app_cmd : std_logic_vector(2 downto 0); + app_en : std_logic; + app_hi_pri : std_logic; app_wdf_data : std_logic_vector(64 - 1 downto 0); - app_wdf_end : std_logic; + app_wdf_end : std_logic; app_wdf_mask : std_logic_vector(8 - 1 downto 0); app_wdf_wren : std_logic; - end record; + end record mig_in_type; type mig_out_type is record - app_rd_data : std_logic_vector(64 - 1 downto 0); - app_rd_data_end : std_logic; + app_rd_data : std_logic_vector(64 - 1 downto 0); + app_rd_data_end : std_logic; app_rd_data_valid : std_logic; - app_rdy : std_logic; - app_wdf_rdy : std_logic; - end record; + app_rdy : std_logic; + app_wdf_rdy : std_logic; + end record mig_out_type; type ahb_mig_state_type is (idle, read_wait); signal current_state, next_state : ahb_mig_state_type; - signal rin, r, rnxt, rnxtin, rprev, rprevin : reg_type; - signal migin : mig_in_type; - signal migout : mig_out_type; + signal rin : reg_type; + signal r : reg_type; + signal rnxt : reg_type; + signal rnxtin : reg_type; + signal rprev : reg_type; + signal rprevin : reg_type; + signal migin : mig_in_type; + signal migout : mig_out_type; function select_rd_data ( signal data : std_logic_vector(63 downto 0); signal offset : std_logic_vector(2 downto 0); - signal hsize : std_logic_vector(2 downto 0)) + signal hsize : std_logic_vector(2 downto 0) + ) return std_logic_vector is + variable hrdata : std_logic_vector(AHBDW - 1 downto 0); + begin + hrdata := (others => '0'); + case hsize is + when HSIZE_BYTE => + case offset is - when "111" => hrdata := ahbdrivedata(data(7 downto 0)); - when "110" => hrdata := ahbdrivedata(data(15 downto 8)); - when "101" => hrdata := ahbdrivedata(data(23 downto 16)); - when "100" => hrdata := ahbdrivedata(data(31 downto 24)); - when "011" => hrdata := ahbdrivedata(data(39 downto 32)); - when "010" => hrdata := ahbdrivedata(data(47 downto 40)); - when "001" => hrdata := ahbdrivedata(data(55 downto 48)); - when "000" => hrdata := ahbdrivedata(data(63 downto 56)); - when others => hrdata := ahbdrivedata(data(7 downto 0)); + + when "111" => + + hrdata := ahbdrivedata(data(7 downto 0)); + + when "110" => + + hrdata := ahbdrivedata(data(15 downto 8)); + + when "101" => + + hrdata := ahbdrivedata(data(23 downto 16)); + + when "100" => + + hrdata := ahbdrivedata(data(31 downto 24)); + + when "011" => + + hrdata := ahbdrivedata(data(39 downto 32)); + + when "010" => + + hrdata := ahbdrivedata(data(47 downto 40)); + + when "001" => + + hrdata := ahbdrivedata(data(55 downto 48)); + + when "000" => + + hrdata := ahbdrivedata(data(63 downto 56)); + + when others => + + hrdata := ahbdrivedata(data(7 downto 0)); + end case; + when HSIZE_HWORD => + case offset(2 downto 1) is - when "11" => hrdata := ahbdrivedata(data(15 downto 0)); - when "10" => hrdata := ahbdrivedata(data(31 downto 16)); - when "01" => hrdata := ahbdrivedata(data(47 downto 32)); - when "00" => hrdata := ahbdrivedata(data(63 downto 48)); - when others => hrdata := ahbdrivedata(data(15 downto 0)); + + when "11" => + + hrdata := ahbdrivedata(data(15 downto 0)); + + when "10" => + + hrdata := ahbdrivedata(data(31 downto 16)); + + when "01" => + + hrdata := ahbdrivedata(data(47 downto 32)); + + when "00" => + + hrdata := ahbdrivedata(data(63 downto 48)); + + when others => + + hrdata := ahbdrivedata(data(15 downto 0)); + end case; + when HSIZE_WORD => + case offset(2) is - when '1' => hrdata := ahbdrivedata(data(31 downto 0)); - when '0' => hrdata := ahbdrivedata(data(63 downto 32)); - when others => hrdata := ahbdrivedata(data(32 downto 0)); + + when '1' => + + hrdata := ahbdrivedata(data(31 downto 0)); + + when '0' => + + hrdata := ahbdrivedata(data(63 downto 32)); + + when others => + + hrdata := ahbdrivedata(data(32 downto 0)); + end case; - when others => hrdata := ahbdrivedata(data); + + when others => + + hrdata := ahbdrivedata(data); + end case; + return hrdata; + end function; function set_wdf_data ( - signal hwdata : in std_logic_vector(AHBDW - 1 downto 0)) + signal hwdata : in std_logic_vector(AHBDW - 1 downto 0) + ) return std_logic_vector is + variable data : std_logic_vector(63 downto 0); + begin - if AHBDW = 32 then + + if (AHBDW = 32) then data(31 downto 0) := hwdata(31 downto 0); data(63 downto 32) := data(31 downto 0); else data := hwdata; end if; + return data; + end function; function set_wdf_mask ( signal offset : std_logic_vector(2 downto 0); - signal hsize : std_logic_vector(2 downto 0)) + signal hsize : std_logic_vector(2 downto 0) + ) return std_logic_vector is + variable mask : std_logic_vector(8 - 1 downto 0); + begin + mask := "00000000"; + case hsize is + when HSIZE_BYTE => + case offset is - when "111" => mask := "11111110"; - when "110" => mask := "11111101"; - when "101" => mask := "11111011"; - when "100" => mask := "11110111"; - when "011" => mask := "11101111"; - when "010" => mask := "11011111"; - when "001" => mask := "10111111"; - when "000" => mask := "01111111"; - when others => mask := "00000000"; + + when "111" => + + mask := "11111110"; + + when "110" => + + mask := "11111101"; + + when "101" => + + mask := "11111011"; + + when "100" => + + mask := "11110111"; + + when "011" => + + mask := "11101111"; + + when "010" => + + mask := "11011111"; + + when "001" => + + mask := "10111111"; + + when "000" => + + mask := "01111111"; + + when others => + + mask := "00000000"; + end case; + when HSIZE_HWORD => + case offset(2 downto 1) is - when "11" => mask := "11111100"; - when "10" => mask := "11110011"; - when "01" => mask := "11001111"; - when "00" => mask := "00111111"; - when others => mask := "00000000"; + + when "11" => + + mask := "11111100"; + + when "10" => + + mask := "11110011"; + + when "01" => + + mask := "11001111"; + + when "00" => + + mask := "00111111"; + + when others => + + mask := "00000000"; + end case; + when HSIZE_WORD => + case offset(2) is - when '1' => mask := "11110000"; - when '0' => mask := "00001111"; - when others => mask := "00000000"; + + when '1' => + + mask := "11110000"; + + when '0' => + + mask := "00001111"; + + when others => + + mask := "00000000"; + end case; - when others => mask := "00000000"; + + when others => + + mask := "00000000"; + end case; + return mask; - end; + + end function; begin @@ -330,17 +485,21 @@ begin -- This ID is irrelevant from the perspective of functionality, because the -- adapter is transparent to software. However, the AHB bus controller from -- GRLIB requires a valid hconfig for every device. - hconfig <= ( - 0 => ahb_device_reg (VENDOR_GAISLER, GAISLER_MIG_7SERIES, 0, 0, 0), - 4 => ahb_membar(haddr, '1', '1', hmask), - others => zero32); - - comb : process(current_state, r, rnxt, rprev, ahbsi, migin, migout, hindex, calib_done_delayed) - variable vprev : reg_type; - variable vnxt : reg_type; - variable v : reg_type; + hconfig <= + ( + 0 => ahb_device_reg (VENDOR_GAISLER, GAISLER_MIG_7SERIES, 0, 0, 0), + 4 => ahb_membar(haddr, '1', '1', hmask), + others => zero32 + ); + + comb : process (current_state, r, rnxt, rprev, ahbsi, migin, migout, hindex, calib_done_delayed) is + + variable vprev : reg_type; + variable vnxt : reg_type; + variable v : reg_type; variable vready : std_logic_vector(1 downto 0); variable commit : std_logic; + begin -- Default @@ -350,8 +509,7 @@ begin next_state <= current_state; -- Wait 4K cycles after calibration is complete before serving any request - if calib_done_delayed = '1' then - + if (calib_done_delayed = '1') then -- We need three registers because we want to break the combinational path -- between MIG ready/valid flags and the AHB bus. This improves timing closure. -- @@ -366,15 +524,15 @@ begin vready := ahbsi.hready & (migout.app_wdf_rdy and migout.app_rdy); -- Set vnxt -- - if ahbsi.hready = '0' then + if (ahbsi.hready = '0') then -- Save previous transaction vnxt := rnxt; - elsif (ahbsi.hsel(hindex) and ahbsi.htrans(1)) = '1' then + elsif ((ahbsi.hsel(hindex) and ahbsi.htrans(1)) = '1') then vnxt := rnxt; -- Mark as valid new transfer - vnxt.valid := '1'; + vnxt.valid := '1'; vnxt.hwrite := ahbsi.hwrite; - vnxt.cmd := "00" & not ahbsi.hwrite; + vnxt.cmd := "00" & not ahbsi.hwrite; -- Update address (Addressing 64-bit words) vnxt.addr := ahbsi.haddr(29 downto 3) & "0"; vnxt.haddr_offset := ahbsi.haddr(2 downto 0); @@ -387,7 +545,7 @@ begin end if; -- Set vprev -- - if vready /= "00" then + if (vready /= "00") then vprev := rprev; -- Update address and data vprev.addr := rnxt.addr; @@ -398,15 +556,18 @@ begin vprev.hwrite := rnxt.hwrite; vprev.cmd := rnxt.cmd; -- Check if it was valid - vprev.valid := rnxt.valid; + vprev.valid := rnxt.valid; else vprev := rprev; end if; -- Set v -- v := r; + case vready is + when "11" => + -- Data is read combinationally from AHB bus. -- Zero additional latency when bus and MIG are both ready. v.addr := rnxt.addr; @@ -419,6 +580,7 @@ begin v.valid := rnxt.valid; when "01" => + v.addr := rprev.addr; v.haddr_offset := rprev.haddr_offset; v.hsize := rprev.hsize; @@ -429,40 +591,44 @@ begin v.valid := rprev.valid; when others => + v := r; + end case; - if migin.app_en = '1' and migin.app_wdf_wren = '0' and migout.app_rdy = '1' and migout.app_wdf_rdy = '1' then + if (migin.app_en = '1' and migin.app_wdf_wren = '0' and migout.app_rdy = '1' and migout.app_wdf_rdy = '1') then v.valid := '0'; end if; - if ahbsi.hready = '1' and ahbsi.htrans = "11" then - if ahbsi.hwrite = '0' then - v.addr := vnxt.addr; - v.haddr_offset := vnxt.haddr_offset; - v.hsize := vnxt.hsize; - v.wdf_mask := vnxt.wdf_mask; - v.wdf_data := set_wdf_data(ahbsi.hwdata); - v.hwrite := vnxt.hwrite; - v.cmd := vnxt.cmd; - elsif migin.app_en = '1' and migout.app_rdy = '1' and migout.app_wdf_rdy = '1' then - v.addr := rnxt.addr; - v.haddr_offset := rnxt.haddr_offset; - v.hsize := rnxt.hsize; - v.wdf_mask := rnxt.wdf_mask; - v.wdf_data := set_wdf_data(ahbsi.hwdata); - v.hwrite := rnxt.hwrite; - v.cmd := rnxt.cmd; - v.valid := rnxt.valid; + if (ahbsi.hready = '1' and ahbsi.htrans = "11") then + if (ahbsi.hwrite = '0') then + v.addr := vnxt.addr; + v.haddr_offset := vnxt.haddr_offset; + v.hsize := vnxt.hsize; + v.wdf_mask := vnxt.wdf_mask; + v.wdf_data := set_wdf_data(ahbsi.hwdata); + v.hwrite := vnxt.hwrite; + v.cmd := vnxt.cmd; + elsif (migin.app_en = '1' and migout.app_rdy = '1' and migout.app_wdf_rdy = '1') then + v.addr := rnxt.addr; + v.haddr_offset := rnxt.haddr_offset; + v.hsize := rnxt.hsize; + v.wdf_mask := rnxt.wdf_mask; + v.wdf_data := set_wdf_data(ahbsi.hwdata); + v.hwrite := rnxt.hwrite; + v.cmd := rnxt.cmd; + v.valid := rnxt.valid; end if; end if; -- Special handling for reads -- case current_state is + when idle => - if (ahbsi.hready and ahbsi.hsel(hindex) and ahbsi.htrans(1) and (not ahbsi.hwrite)) = '1' then + + if ((ahbsi.hready and ahbsi.hsel(hindex) and ahbsi.htrans(1) and (not ahbsi.hwrite)) = '1') then -- accepting read command from bus -> hold data transfer until MIG reply - v.hready := '0'; + v.hready := '0'; next_state <= read_wait; else -- propagate backpressure from MIG to bus @@ -470,188 +636,204 @@ begin end if; when read_wait => - if migout.app_rd_data_valid = '1' then - v.hrdata := select_rd_data(migout.app_rd_data, rnxt.haddr_offset, rnxt.hsize); - v.hready := '1'; + + if (migout.app_rd_data_valid = '1') then + v.hrdata := select_rd_data(migout.app_rd_data, rnxt.haddr_offset, rnxt.hsize); + v.hready := '1'; next_state <= idle; else v.hready := '0'; end if; when others => + next_state <= idle; - v.hready := '0'; + v.hready := '0'; end case; -- Do not send commands to MIG unless valid and ready - v.en := v.valid; + v.en := v.valid; v.wdf_wren := v.valid and v.hwrite; - v.wdf_end := v.valid and v.hwrite; - + v.wdf_end := v.valid and v.hwrite; else v.hready := '0'; end if; -- calib_done_delayed = '1' -- Set registers input - rin <= v; - rnxtin <= vnxt; + rin <= v; + rnxtin <= vnxt; rprevin <= vprev; - end process; + end process comb; ahbso.hready <= r.hready; - ahbso.hresp <= "00"; + ahbso.hresp <= "00"; ahbso.hrdata <= r.hrdata; migin.app_addr <= r.addr; - migin.app_cmd <= r.cmd; + migin.app_cmd <= r.cmd; -- synchronize wdf write enable and command enable to ease AHB pipeline handling - migin.app_en <= r.en when r.wdf_wren = '0' else r.en and migout.app_wdf_rdy; + migin.app_en <= r.en when r.wdf_wren = '0' else + r.en and migout.app_wdf_rdy; migin.app_hi_pri <= '0'; - migin.app_wdf_data <= r.wdf_data; - migin.app_wdf_end <= r.wdf_end; - migin.app_wdf_mask(AHBDW/8 - 1 downto 0) <= r.wdf_mask; + migin.app_wdf_data <= r.wdf_data; + migin.app_wdf_end <= r.wdf_end; + migin.app_wdf_mask(AHBDW / 8 - 1 downto 0) <= r.wdf_mask; + broken_32bit_bus_gen : if (AHBDW = 32) generate -- TODO: supporting only 64-bit AHB bus migin.app_wdf_mask(8 - 1 downto 4) <= (others => '0'); end generate broken_32bit_bus_gen; + migin.app_wdf_wren <= r.wdf_wren and migout.app_rdy; ahbso.hconfig <= hconfig; - ahbso.hirq <= (others => '0'); - ahbso.hindex <= hindex; - ahbso.hsplit <= (others => '0'); + ahbso.hirq <= (others => '0'); + ahbso.hindex <= hindex; + ahbso.hsplit <= (others => '0'); - regs : process(ui_clk) + regs : process (ui_clk) is begin + if rising_edge(ui_clk) then - if ui_rstn = '0' then - r <= REG_RESET; - rnxt <= REG_RESET; - rprev <= REG_RESET; + if (ui_rstn = '0') then + r <= REG_RESET; + rnxt <= REG_RESET; + rprev <= REG_RESET; current_state <= idle; else - r <= rin; - rnxt <= rnxtin; - rprev <= rprevin; + r <= rin; + rnxt <= rnxtin; + rprev <= rprevin; current_state <= next_state; end if; end if; - end process; + + end process regs; -- bsg_dmc reset is active high - ui_rst <= not ui_rstn; + ui_rst <= not ui_rstn; phy_rst <= not phy_rstn; ddr_dqs_inout_gen : for i in 0 to 3 generate lpddr_dqs_p_ien(i) <= ddr_dqs_p_ien(i); lpddr_dqs_n_ien(i) <= ddr_dqs_n_ien(i); - ddr_dqs_p_i(i) <= lpddr_dqs_p_i(i) when ddr_dqs_p_ien(i) = '0' else '0'; - ddr_dqs_n_i(i) <= lpddr_dqs_n_i(i) when ddr_dqs_n_ien(i) = '0' else '1'; + ddr_dqs_p_i(i) <= lpddr_dqs_p_i(i) when ddr_dqs_p_ien(i) = '0' else + '0'; + ddr_dqs_n_i(i) <= lpddr_dqs_n_i(i) when ddr_dqs_n_ien(i) = '0' else + '1'; end generate ddr_dqs_inout_gen; - bsg_dmc_wrap_1 : bsg_dmc_wrap + bsg_dmc_wrap_1 : component bsg_dmc_wrap generic map ( - ui_addr_width_p => 28, - ui_data_width_p => AHBDW, + ui_addr_width_p => 28, + ui_data_width_p => AHBDW, ui_burst_length_p => 1, - dq_data_width_p => 32, + dq_data_width_p => 32, cmd_afifo_depth_p => 4, - cmd_sfifo_depth_p => 4) + cmd_sfifo_depth_p => 4 + ) port map ( - app_addr => migin.app_addr, - app_cmd => migin.app_cmd, - app_en => migin.app_en, - app_wdf_data => migin.app_wdf_data, - app_wdf_end => migin.app_wdf_end, - app_wdf_mask => migin.app_wdf_mask, - app_wdf_wren => migin.app_wdf_wren, - app_rd_data => migout.app_rd_data, - app_rd_data_end => migout.app_rd_data_end, - app_rd_data_valid => migout.app_rd_data_valid, - app_rdy => migout.app_rdy, - app_wdf_rdy => migout.app_wdf_rdy, + app_addr => migin.app_addr, + app_cmd => migin.app_cmd, + app_en => migin.app_en, + app_wdf_data => migin.app_wdf_data, + app_wdf_end => migin.app_wdf_end, + app_wdf_mask => migin.app_wdf_mask, + app_wdf_wren => migin.app_wdf_wren, + app_rd_data => migout.app_rd_data, + app_rd_data_end => migout.app_rd_data_end, + app_rd_data_valid => migout.app_rd_data_valid, + app_rdy => migout.app_rdy, + app_wdf_rdy => migout.app_wdf_rdy, init_calib_complete => init_calib_complete(0), - ui_clk_i => ui_clk, - ui_reset_i => ui_rst, - dfi_clk_2x_i => phy_clk_2x, - dfi_clk_1x_i => phy_clk_1x, - dfi_reset_i => phy_rst, - ddr_ck_p_o => lpddr_ck_p, - ddr_ck_n_o => lpddr_ck_n, - ddr_cke_o => lpddr_cke, - ddr_ba_o => lpddr_ba, - ddr_addr_o => lpddr_addr, - ddr_cs_n_o => lpddr_cs_n, - ddr_ras_n_o => lpddr_ras_n, - ddr_cas_n_o => lpddr_cas_n, - ddr_we_n_o => lpddr_we_n, - ddr_reset_n_o => lpddr_reset_n, - ddr_odt_o => lpddr_odt, - ddr_dm_oen_o => lpddr_dm_oen, - ddr_dm_o => lpddr_dm, - ddr_dqs_p_oen_o => lpddr_dqs_p_oen, - ddr_dqs_p_ien_o => ddr_dqs_p_ien, - ddr_dqs_p_o => lpddr_dqs_p_o, - ddr_dqs_p_i => ddr_dqs_p_i, - ddr_dqs_n_oen_o => lpddr_dqs_n_oen, - ddr_dqs_n_ien_o => ddr_dqs_n_ien, - ddr_dqs_n_o => lpddr_dqs_n_o, - ddr_dqs_n_i => ddr_dqs_n_i, - ddr_dq_oen_o => lpddr_dq_oen, - ddr_dq_o => lpddr_dq_o, - ddr_dq_i => lpddr_dq_i, - delay_sel_i => ddr_cfg0(3 downto 0), - trefi_i => trefi_ext, - tmrd_i => ddr_cfg0(19 downto 16), - trfc_i => ddr_cfg0(23 downto 20), - trc_i => ddr_cfg0(27 downto 24), - trp_i => ddr_cfg0(31 downto 28), - tras_i => ddr_cfg1(3 downto 0), - trrd_i => ddr_cfg1(7 downto 4), - trcd_i => ddr_cfg1(11 downto 8), - twr_i => ddr_cfg1(15 downto 12), - twtr_i => ddr_cfg1(19 downto 16), - trtp_i => ddr_cfg1(23 downto 20), - tcas_i => ddr_cfg1(27 downto 24), - col_width_i => ddr_cfg1(31 downto 28), - row_width_i => ddr_cfg2(3 downto 0), - bank_width_i => ddr_cfg2(5 downto 4), - bank_pos_i => ddr_cfg2(11 downto 6), - dqs_sel_cal_i => ddr_cfg2(14 downto 12), - init_cycles_i => ddr_cfg2(30 downto 15) - ); + ui_clk_i => ui_clk, + ui_reset_i => ui_rst, + dfi_clk_2x_i => phy_clk_2x, + dfi_clk_1x_i => phy_clk_1x, + dfi_reset_i => phy_rst, + ddr_ck_p_o => lpddr_ck_p, + ddr_ck_n_o => lpddr_ck_n, + ddr_cke_o => lpddr_cke, + ddr_ba_o => lpddr_ba, + ddr_addr_o => lpddr_addr, + ddr_cs_n_o => lpddr_cs_n, + ddr_ras_n_o => lpddr_ras_n, + ddr_cas_n_o => lpddr_cas_n, + ddr_we_n_o => lpddr_we_n, + ddr_reset_n_o => lpddr_reset_n, + ddr_odt_o => lpddr_odt, + ddr_dm_oen_o => lpddr_dm_oen, + ddr_dm_o => lpddr_dm, + ddr_dqs_p_oen_o => lpddr_dqs_p_oen, + ddr_dqs_p_ien_o => ddr_dqs_p_ien, + ddr_dqs_p_o => lpddr_dqs_p_o, + ddr_dqs_p_i => ddr_dqs_p_i, + ddr_dqs_n_oen_o => lpddr_dqs_n_oen, + ddr_dqs_n_ien_o => ddr_dqs_n_ien, + ddr_dqs_n_o => lpddr_dqs_n_o, + ddr_dqs_n_i => ddr_dqs_n_i, + ddr_dq_oen_o => lpddr_dq_oen, + ddr_dq_o => lpddr_dq_o, + ddr_dq_i => lpddr_dq_i, + delay_sel_i => ddr_cfg0(3 downto 0), + trefi_i => trefi_ext, + tmrd_i => ddr_cfg0(19 downto 16), + trfc_i => ddr_cfg0(23 downto 20), + trc_i => ddr_cfg0(27 downto 24), + trp_i => ddr_cfg0(31 downto 28), + tras_i => ddr_cfg1(3 downto 0), + trrd_i => ddr_cfg1(7 downto 4), + trcd_i => ddr_cfg1(11 downto 8), + twr_i => ddr_cfg1(15 downto 12), + twtr_i => ddr_cfg1(19 downto 16), + trtp_i => ddr_cfg1(23 downto 20), + tcas_i => ddr_cfg1(27 downto 24), + col_width_i => ddr_cfg1(31 downto 28), + row_width_i => ddr_cfg2(3 downto 0), + bank_width_i => ddr_cfg2(5 downto 4), + bank_pos_i => ddr_cfg2(11 downto 6), + dqs_sel_cal_i => ddr_cfg2(14 downto 12), + init_cycles_i => ddr_cfg2(30 downto 15) + ); trefi_ext <= ddr_cfg2(31) & ddr_cfg0(15 downto 4); - init_calib_sync_gen: for i in 1 to 7 generate + init_calib_sync_gen : for i in 1 to 7 generate + process (ui_clk, ui_rstn) is begin -- process - if ui_rstn = '0' then + + if (ui_rstn = '0') then init_calib_complete(i) <= '0'; elsif rising_edge(ui_clk) then init_calib_complete(i) <= init_calib_complete(i - 1); end if; + end process; + end generate init_calib_sync_gen; process (ui_clk, ui_rstn) is begin -- process - if ui_rstn = '0' then + + if (ui_rstn = '0') then calib_done_count <= (others => '0'); elsif rising_edge(ui_clk) then - if init_calib_complete(7) = '1' then - if calib_done_count /= "11111" then + if (init_calib_complete(7) = '1') then + if (calib_done_count /= "11111") then calib_done_count <= calib_done_count + "00001"; end if; end if; end if; + end process; - calib_done_delayed <= '1' when calib_done_count = "11111" else '0'; - calib_done <= calib_done_delayed; + calib_done_delayed <= '1' when calib_done_count = "11111" else + '0'; + calib_done <= calib_done_delayed; -end; +end architecture rtl; diff --git a/rtl/peripherals/ddr/bsg_dmc_wrap.v b/rtl/peripherals/ddr/bsg_dmc_wrap.v index 9828cb55bc..03f372edc8 100644 --- a/rtl/peripherals/ddr/bsg_dmc_wrap.v +++ b/rtl/peripherals/ddr/bsg_dmc_wrap.v @@ -3,16 +3,14 @@ import bsg_dmc_pkg::*; -module bsg_dmc_wrap - #( - parameter ui_addr_width_p = 28, - parameter ui_data_width_p = 64, - parameter ui_burst_length_p = 1, - parameter dq_data_width_p = 32, - parameter cmd_afifo_depth_p = 4, - parameter cmd_sfifo_depth_p = 4 - ) - ( +module bsg_dmc_wrap #( + parameter ui_addr_width_p = 28, + parameter ui_data_width_p = 64, + parameter ui_burst_length_p = 1, + parameter dq_data_width_p = 32, + parameter cmd_afifo_depth_p = 4, + parameter cmd_sfifo_depth_p = 4 +) ( // User interface input signals input logic [ui_addr_width_p-1:0] app_addr, input logic [2:0] app_cmd, @@ -85,183 +83,189 @@ module bsg_dmc_wrap input logic [5:0] bank_pos_i, input logic [2:0] dqs_sel_cal_i, input logic [15:0] init_cycles_i - ); +); - localparam burst_data_width_lp = ui_data_width_p * ui_burst_length_p; - localparam dfi_data_width_lp = dq_data_width_p << 1; - localparam dfi_mask_width_lp = (dq_data_width_p >> 3) << 1; + localparam burst_data_width_lp = ui_data_width_p * ui_burst_length_p; + localparam dfi_data_width_lp = dq_data_width_p << 1; + localparam dfi_mask_width_lp = (dq_data_width_p >> 3) << 1; - genvar i; + genvar i; - // app_cmd data type conversion - app_cmd_e app_cmd_int; + // app_cmd data type conversion + app_cmd_e app_cmd_int; - // DFI 1.0 compatible - wire [2:0] dfi_bank; - wire [15:0] dfi_address; - wire dfi_cke; - wire dfi_cs_n; - wire dfi_ras_n; - wire dfi_cas_n; - wire dfi_we_n; - wire dfi_reset_n; - wire dfi_odt; - wire dfi_wrdata_en; - wire [dfi_data_width_lp-1:0] dfi_wrdata; - wire [dfi_mask_width_lp-1:0] dfi_wrdata_mask; - wire dfi_rddata_en; - wire [dfi_data_width_lp-1:0] dfi_rddata; - wire dfi_rddata_valid; - wire [(dq_data_width_p>>3)-1:0] dqs_p_li; + // DFI 1.0 compatible + wire [ 2:0] dfi_bank; + wire [ 15:0] dfi_address; + wire dfi_cke; + wire dfi_cs_n; + wire dfi_ras_n; + wire dfi_cas_n; + wire dfi_we_n; + wire dfi_reset_n; + wire dfi_odt; + wire dfi_wrdata_en; + wire [ dfi_data_width_lp-1:0] dfi_wrdata; + wire [ dfi_mask_width_lp-1:0] dfi_wrdata_mask; + wire dfi_rddata_en; + wire [ dfi_data_width_lp-1:0] dfi_rddata; + wire dfi_rddata_valid; + wire [(dq_data_width_p>>3)-1:0] dqs_p_li; - generate - for (i = 0; i < (dq_data_width_p>>3); i++) begin : dqs_delay_gen - // Delay line (GF12 only) - DELAY_CELL_GF12_C14 dly_line_i - ( - .DATA_IN(ddr_dqs_p_i[i]), - .DATA_OUT(dqs_p_li[i]), - .SEL(delay_sel_i) - ); - end; - endgenerate + generate + for (i = 0; i < (dq_data_width_p >> 3); i++) begin : dqs_delay_gen + // Delay line (GF12 only) + DELAY_CELL_GF12_C14 dly_line_i ( + .DATA_IN(ddr_dqs_p_i[i]), + .DATA_OUT(dqs_p_li[i]), + .SEL(delay_sel_i) + ); + end + ; + endgenerate - always_comb begin - case(app_cmd) - 3'b000 : app_cmd_int = WR; - 3'b001 : app_cmd_int = RD; - 3'b010 : app_cmd_int = WP; - 3'b011 : app_cmd_int = RP; - default : app_cmd_int = RP; - endcase - end + always_comb begin + case (app_cmd) + 3'b000: app_cmd_int = WR; + 3'b001: app_cmd_int = RD; + 3'b010: app_cmd_int = WP; + 3'b011: app_cmd_int = RP; + default: app_cmd_int = RP; + endcase + end - // Configuration - bsg_dmc_s dmc_p; + // Configuration + bsg_dmc_s dmc_p; - // DDR controller configuration - assign dmc_p.trefi = {3'b000, trefi_i}; - assign dmc_p.tmrd = tmrd_i; - assign dmc_p.trfc = trfc_i; - assign dmc_p.trc = trc_i; - assign dmc_p.trp = trp_i; - assign dmc_p.tras = tras_i; - assign dmc_p.trrd = trrd_i; - assign dmc_p.trcd = trcd_i; - assign dmc_p.twr = twr_i; - assign dmc_p.twtr = twtr_i; - assign dmc_p.trtp = trtp_i; - assign dmc_p.tcas = tcas_i; - assign dmc_p.col_width = col_width_i; - assign dmc_p.row_width = row_width_i; - assign dmc_p.bank_width = bank_width_i; - assign dmc_p.bank_pos = bank_pos_i; - assign dmc_p.dqs_sel_cal = dqs_sel_cal_i; - assign dmc_p.init_cycles = init_cycles_i; + // DDR controller configuration + assign dmc_p.trefi = {3'b000, trefi_i}; + assign dmc_p.tmrd = tmrd_i; + assign dmc_p.trfc = trfc_i; + assign dmc_p.trc = trc_i; + assign dmc_p.trp = trp_i; + assign dmc_p.tras = tras_i; + assign dmc_p.trrd = trrd_i; + assign dmc_p.trcd = trcd_i; + assign dmc_p.twr = twr_i; + assign dmc_p.twtr = twtr_i; + assign dmc_p.trtp = trtp_i; + assign dmc_p.tcas = tcas_i; + assign dmc_p.col_width = col_width_i; + assign dmc_p.row_width = row_width_i; + assign dmc_p.bank_width = bank_width_i; + assign dmc_p.bank_pos = bank_pos_i; + assign dmc_p.dqs_sel_cal = dqs_sel_cal_i; + assign dmc_p.init_cycles = init_cycles_i; - // -- bdg_dmc controller and PHY instances - bsg_dmc_controller # - (.ui_addr_width_p ( ui_addr_width_p ), - .ui_data_width_p ( ui_data_width_p ), - .burst_data_width_p ( burst_data_width_lp ), - .dfi_data_width_p ( dfi_data_width_lp ), - .cmd_afifo_depth_p ( cmd_afifo_depth_p ), - .cmd_sfifo_depth_p ( cmd_sfifo_depth_p )) - controller - // User interface clock and reset - (.ui_clk_i ( ui_clk_i ), - .ui_clk_sync_rst_i ( ui_reset_i ), - // User interface signals - .app_addr_i ( app_addr ), - .app_cmd_i ( app_cmd_int ), - .app_en_i ( app_en ), - .app_rdy_o ( app_rdy ), - .app_wdf_wren_i ( app_wdf_wren ), - .app_wdf_data_i ( app_wdf_data ), - .app_wdf_mask_i ( app_wdf_mask ), - .app_wdf_end_i ( app_wdf_end ), - .app_wdf_rdy_o ( app_wdf_rdy ), - .app_rd_data_valid_o ( app_rd_data_valid ), - .app_rd_data_o ( app_rd_data ), - .app_rd_data_end_o ( app_rd_data_end ), - .app_ref_req_i ( 1'b0 ), - .app_ref_ack_o ( ), - .app_zq_req_i ( 1'b0 ), - .app_zq_ack_o ( ), - .app_sr_req_i ( 1'b0 ), - .app_sr_active_o ( ), - // DDR PHY interface clock and reset - .dfi_clk_i ( dfi_clk_1x_i ), - .dfi_clk_sync_rst_i ( dfi_reset_i ), - // DDR PHY interface signals - .dfi_bank_o ( dfi_bank ), - .dfi_address_o ( dfi_address ), - .dfi_cke_o ( dfi_cke ), - .dfi_cs_n_o ( dfi_cs_n ), - .dfi_ras_n_o ( dfi_ras_n ), - .dfi_cas_n_o ( dfi_cas_n ), - .dfi_we_n_o ( dfi_we_n ), - .dfi_reset_n_o ( dfi_reset_n ), - .dfi_odt_o ( dfi_odt ), - .dfi_wrdata_en_o ( dfi_wrdata_en ), - .dfi_wrdata_o ( dfi_wrdata ), - .dfi_wrdata_mask_o ( dfi_wrdata_mask ), - .dfi_rddata_en_o ( dfi_rddata_en ), - .dfi_rddata_i ( dfi_rddata ), - .dfi_rddata_valid_i ( dfi_rddata_valid ), - // Control and Status Registers - .dmc_p_i ( dmc_p ), - // - .init_calib_complete_o ( init_calib_complete )); + // -- bdg_dmc controller and PHY instances + bsg_dmc_controller #( + .ui_addr_width_p (ui_addr_width_p), + .ui_data_width_p (ui_data_width_p), + .burst_data_width_p(burst_data_width_lp), + .dfi_data_width_p (dfi_data_width_lp), + .cmd_afifo_depth_p (cmd_afifo_depth_p), + .cmd_sfifo_depth_p (cmd_sfifo_depth_p) + ) controller + // User interface clock and reset + ( + .ui_clk_i (ui_clk_i), + .ui_clk_sync_rst_i (ui_reset_i), + // User interface signals + .app_addr_i (app_addr), + .app_cmd_i (app_cmd_int), + .app_en_i (app_en), + .app_rdy_o (app_rdy), + .app_wdf_wren_i (app_wdf_wren), + .app_wdf_data_i (app_wdf_data), + .app_wdf_mask_i (app_wdf_mask), + .app_wdf_end_i (app_wdf_end), + .app_wdf_rdy_o (app_wdf_rdy), + .app_rd_data_valid_o (app_rd_data_valid), + .app_rd_data_o (app_rd_data), + .app_rd_data_end_o (app_rd_data_end), + .app_ref_req_i (1'b0), + .app_ref_ack_o (), + .app_zq_req_i (1'b0), + .app_zq_ack_o (), + .app_sr_req_i (1'b0), + .app_sr_active_o (), + // DDR PHY interface clock and reset + .dfi_clk_i (dfi_clk_1x_i), + .dfi_clk_sync_rst_i (dfi_reset_i), + // DDR PHY interface signals + .dfi_bank_o (dfi_bank), + .dfi_address_o (dfi_address), + .dfi_cke_o (dfi_cke), + .dfi_cs_n_o (dfi_cs_n), + .dfi_ras_n_o (dfi_ras_n), + .dfi_cas_n_o (dfi_cas_n), + .dfi_we_n_o (dfi_we_n), + .dfi_reset_n_o (dfi_reset_n), + .dfi_odt_o (dfi_odt), + .dfi_wrdata_en_o (dfi_wrdata_en), + .dfi_wrdata_o (dfi_wrdata), + .dfi_wrdata_mask_o (dfi_wrdata_mask), + .dfi_rddata_en_o (dfi_rddata_en), + .dfi_rddata_i (dfi_rddata), + .dfi_rddata_valid_i (dfi_rddata_valid), + // Control and Status Registers + .dmc_p_i (dmc_p), + // + .init_calib_complete_o(init_calib_complete) + ); - bsg_dmc_phy #(.dq_data_width_p(dq_data_width_p)) phy - // DDR PHY interface clock and reset - (.dfi_clk_1x_i ( dfi_clk_1x_i ), - .dfi_clk_2x_i ( dfi_clk_2x_i ), - .dfi_rst_i ( dfi_reset_i ), - // DFI interface signals - .dfi_bank_i ( dfi_bank ), - .dfi_address_i ( dfi_address ), - .dfi_cke_i ( dfi_cke ), - .dfi_cs_n_i ( dfi_cs_n ), - .dfi_ras_n_i ( dfi_ras_n ), - .dfi_cas_n_i ( dfi_cas_n ), - .dfi_we_n_i ( dfi_we_n ), - .dfi_reset_n_i ( dfi_reset_n ), - .dfi_odt_i ( dfi_odt ), - .dfi_wrdata_en_i ( dfi_wrdata_en ), - .dfi_wrdata_i ( dfi_wrdata ), - .dfi_wrdata_mask_i ( dfi_wrdata_mask ), - .dfi_rddata_en_i ( dfi_rddata_en ), - .dfi_rddata_o ( dfi_rddata ), - .dfi_rddata_valid_o ( dfi_rddata_valid ), - // DDR interface signals - .ck_p_o ( ddr_ck_p_o ), - .ck_n_o ( ddr_ck_n_o ), - .cke_o ( ddr_cke_o ), - .ba_o ( ddr_ba_o ), - .a_o ( ddr_addr_o ), - .cs_n_o ( ddr_cs_n_o ), - .ras_n_o ( ddr_ras_n_o ), - .cas_n_o ( ddr_cas_n_o ), - .we_n_o ( ddr_we_n_o ), - .reset_o ( ddr_reset_n_o ), - .odt_o ( ddr_odt_o ), - .dm_oe_n_o ( ddr_dm_oen_o ), - .dm_o ( ddr_dm_o ), - .dqs_p_oe_n_o ( ddr_dqs_p_oen_o ), - .dqs_p_ie_n_o ( ddr_dqs_p_ien_o ), - .dqs_p_o ( ddr_dqs_p_o ), - .dqs_p_i ( dqs_p_li ), - .dqs_n_oe_n_o ( ddr_dqs_n_oen_o ), - .dqs_n_ie_n_o ( ddr_dqs_n_ien_o ), - .dqs_n_o ( ddr_dqs_n_o ), - .dqs_n_i ( ~dqs_p_li ), - .dq_oe_n_o ( ddr_dq_oen_o ), - .dq_o ( ddr_dq_o ), - .dq_i ( ddr_dq_i ), - // Control and Status Registers - .dqs_sel_cal ( dmc_p.dqs_sel_cal )); + bsg_dmc_phy #( + .dq_data_width_p(dq_data_width_p) + ) phy + // DDR PHY interface clock and reset + ( + .dfi_clk_1x_i (dfi_clk_1x_i), + .dfi_clk_2x_i (dfi_clk_2x_i), + .dfi_rst_i (dfi_reset_i), + // DFI interface signals + .dfi_bank_i (dfi_bank), + .dfi_address_i (dfi_address), + .dfi_cke_i (dfi_cke), + .dfi_cs_n_i (dfi_cs_n), + .dfi_ras_n_i (dfi_ras_n), + .dfi_cas_n_i (dfi_cas_n), + .dfi_we_n_i (dfi_we_n), + .dfi_reset_n_i (dfi_reset_n), + .dfi_odt_i (dfi_odt), + .dfi_wrdata_en_i (dfi_wrdata_en), + .dfi_wrdata_i (dfi_wrdata), + .dfi_wrdata_mask_i (dfi_wrdata_mask), + .dfi_rddata_en_i (dfi_rddata_en), + .dfi_rddata_o (dfi_rddata), + .dfi_rddata_valid_o(dfi_rddata_valid), + // DDR interface signals + .ck_p_o (ddr_ck_p_o), + .ck_n_o (ddr_ck_n_o), + .cke_o (ddr_cke_o), + .ba_o (ddr_ba_o), + .a_o (ddr_addr_o), + .cs_n_o (ddr_cs_n_o), + .ras_n_o (ddr_ras_n_o), + .cas_n_o (ddr_cas_n_o), + .we_n_o (ddr_we_n_o), + .reset_o (ddr_reset_n_o), + .odt_o (ddr_odt_o), + .dm_oe_n_o (ddr_dm_oen_o), + .dm_o (ddr_dm_o), + .dqs_p_oe_n_o (ddr_dqs_p_oen_o), + .dqs_p_ie_n_o (ddr_dqs_p_ien_o), + .dqs_p_o (ddr_dqs_p_o), + .dqs_p_i (dqs_p_li), + .dqs_n_oe_n_o (ddr_dqs_n_oen_o), + .dqs_n_ie_n_o (ddr_dqs_n_ien_o), + .dqs_n_o (ddr_dqs_n_o), + .dqs_n_i (~dqs_p_li), + .dq_oe_n_o (ddr_dq_oen_o), + .dq_o (ddr_dq_o), + .dq_i (ddr_dq_i), + // Control and Status Registers + .dqs_sel_cal (dmc_p.dqs_sel_cal) + ); endmodule diff --git a/rtl/peripherals/ethernet/eth_ahb_mst.vhd b/rtl/peripherals/ethernet/eth_ahb_mst.vhd index 6e8e61ad36..880025ca59 100644 --- a/rtl/peripherals/ethernet/eth_ahb_mst.vhd +++ b/rtl/peripherals/ethernet/eth_ahb_mst.vhd @@ -16,178 +16,237 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------- --- Entity: eth_ahb_mst +-- Entity: eth_ahb_mst -- File: eth_ahb_mst.vhd -- Author: Marko Isomaki - Gaisler Research -- Description: Ethernet MAC AHB master interface ------------------------------------------------------------------------------- + library ieee; -use ieee.std_logic_1164.all; -use work.stdlib.all; -use work.grethpkg.all; + use ieee.std_logic_1164.all; + use work.stdlib.all; + use work.grethpkg.all; entity eth_ahb_mst is - port( - rst : in std_ulogic; - clk : in std_ulogic; - ahbmi : in ahbc_mst_in_type; - ahbmo : out ahbc_mst_out_type; - tmsti : in eth_tx_ahb_in_type; - tmsto : out eth_tx_ahb_out_type; - rmsti : in eth_rx_ahb_in_type; - rmsto : out eth_rx_ahb_out_type + port ( + rst : in std_ulogic; + clk : in std_ulogic; + ahbmi : in ahbc_mst_in_type; + ahbmo : out ahbc_mst_out_type; + tmsti : in eth_tx_ahb_in_type; + tmsto : out eth_tx_ahb_out_type; + rmsti : in eth_rx_ahb_in_type; + rmsto : out eth_rx_ahb_out_type ); attribute sync_set_reset of rst : signal is "true"; -end entity; +end entity eth_ahb_mst; architecture rtl of eth_ahb_mst is + type reg_type is record - bg : std_ulogic; --bus granted - bo : std_ulogic; --bus owner, 0=rx, 1=tx - ba : std_ulogic; --bus active - bb : std_ulogic; --1kB burst boundary detected - retry : std_ulogic; - error : std_ulogic; - end record; + bg : std_ulogic; -- bus granted + bo : std_ulogic; -- bus owner, 0=rx, 1=tx + ba : std_ulogic; -- bus active + bb : std_ulogic; -- 1kB burst boundary detected + retry : std_ulogic; + error : std_ulogic; + end record reg_type; signal r, rin : reg_type; + begin - comb : process(rst, r, tmsti, rmsti, ahbmi) is - variable v : reg_type; - variable htrans : std_logic_vector(1 downto 0); - variable hbusreq : std_ulogic; - variable hwrite : std_ulogic; - variable haddr : std_logic_vector(31 downto 0); - variable hwdata : std_logic_vector(31 downto 0); - variable nbo : std_ulogic; - variable tretry : std_ulogic; - variable rretry : std_ulogic; - variable rready : std_ulogic; - variable tready : std_ulogic; - variable rerror : std_ulogic; - variable terror : std_ulogic; - variable tgrant : std_ulogic; - variable rgrant : std_ulogic; + + comb : process (rst, r, tmsti, rmsti, ahbmi) is + + variable v : reg_type; + variable htrans : std_logic_vector(1 downto 0); + variable hbusreq : std_ulogic; + variable hwrite : std_ulogic; + variable haddr : std_logic_vector(31 downto 0); + variable hwdata : std_logic_vector(31 downto 0); + variable nbo : std_ulogic; + variable tretry : std_ulogic; + variable rretry : std_ulogic; + variable rready : std_ulogic; + variable tready : std_ulogic; + variable rerror : std_ulogic; + variable terror : std_ulogic; + variable tgrant : std_ulogic; + variable rgrant : std_ulogic; + begin - v := r; htrans := HTRANS_IDLE; rready := '0'; tready := '0'; tretry := '0'; + + v := r; htrans := HTRANS_IDLE; rready := '0'; tready := '0'; tretry := '0'; rretry := '0'; rerror := '0'; terror := '0'; tgrant := '0'; rgrant := '0'; - - if r.bo = '0' then hwdata := rmsti.data; - else hwdata := tmsti.data; end if; - + + if (r.bo = '0') then + hwdata := rmsti.data; + else + hwdata := tmsti.data; + end if; + hbusreq := tmsti.req or rmsti.req; - if hbusreq = '1' then htrans := HTRANS_NONSEQ; end if; - if r.retry = '0' then + if (hbusreq = '1') then + htrans := HTRANS_NONSEQ; + end if; + + if (r.retry = '0') then nbo := tmsti.req and not (rmsti.req and not r.bo); else nbo := r.bo; end if; - if nbo = '0' then + if (nbo = '0') then haddr := rmsti.addr; hwrite := rmsti.write; - if (rmsti.req and r.ba and not r.bo and not r.retry) = '1' then - htrans := HTRANS_SEQ; + if ((rmsti.req and r.ba and not r.bo and not r.retry) = '1') then + htrans := HTRANS_SEQ; + end if; + if ((rmsti.req and r.bg and ahbmi.hready and not r.retry) = '1') then + rgrant := '1'; end if; - if (rmsti.req and r.bg and ahbmi.hready and not r.retry) = '1' - then rgrant := '1'; end if; else haddr := tmsti.addr; hwrite := tmsti.write; - if (tmsti.req and r.ba and r.bo and not r.retry) = '1' then - htrans := HTRANS_SEQ; + if ((tmsti.req and r.ba and r.bo and not r.retry) = '1') then + htrans := HTRANS_SEQ; + end if; + if ((tmsti.req and r.bg and ahbmi.hready and not r.retry) = '1') then + tgrant := '1'; end if; - if (tmsti.req and r.bg and ahbmi.hready and not r.retry) = '1' - then tgrant := '1'; end if; end if; - --1 kB burst boundary - if ahbmi.hready = '1' then - if haddr(9 downto 2) = "11111111" then + -- 1 kB burst boundary + if (ahbmi.hready = '1') then + if (haddr(9 downto 2) = "11111111") then v.bb := '1'; else v.bb := '0'; end if; end if; - if (r.bb = '1') and (htrans /= HTRANS_IDLE) then + if ((r.bb = '1') and (htrans /= HTRANS_IDLE)) then htrans := HTRANS_NONSEQ; end if; - - if r.bo = '0' then - if r.ba = '1' then - if ahbmi.hready = '1' then + + if (r.bo = '0') then + if (r.ba = '1') then + if (ahbmi.hready = '1') then + case ahbmi.hresp is - when HRESP_OKAY => rready := '1'; - when HRESP_SPLIT | HRESP_RETRY => rretry := '1'; - when HRESP_ERROR => rerror := '1'; - when others => null; - end case; + + when HRESP_OKAY => + + rready := '1'; + + when HRESP_SPLIT | HRESP_RETRY => + + rretry := '1'; + + when HRESP_ERROR => + + rerror := '1'; + + when others => + + null; + + end case; + end if; end if; else - if r.ba = '1' then - if ahbmi.hready = '1' then + if (r.ba = '1') then + if (ahbmi.hready = '1') then + case ahbmi.hresp is - when HRESP_OKAY => tready := '1'; - when HRESP_SPLIT | HRESP_RETRY => tretry := '1'; - when HRESP_ERROR => terror := '1'; - when others => null; - end case; + + when HRESP_OKAY => + + tready := '1'; + + when HRESP_SPLIT | HRESP_RETRY => + + tretry := '1'; + + when HRESP_ERROR => + + terror := '1'; + + when others => + + null; + + end case; + end if; end if; end if; - if (r.ba = '1') and - ((ahbmi.hresp = HRESP_RETRY) or (ahbmi.hresp = HRESP_SPLIT)) - then v.retry := not ahbmi.hready; else v.retry := '0'; end if; - - if (r.ba = '1') and - (ahbmi.hresp = HRESP_ERROR) - then v.error := not ahbmi.hready; else v.error := '0'; end if; - - if (r.retry or r.error) = '1' then htrans := HTRANS_IDLE; end if; - - if ahbmi.hready = '1' then + if ((r.ba = '1') and + ((ahbmi.hresp = HRESP_RETRY) or (ahbmi.hresp = HRESP_SPLIT))) then + v.retry := not ahbmi.hready; + else + v.retry := '0'; + end if; + + if ((r.ba = '1') and + (ahbmi.hresp = HRESP_ERROR)) then + v.error := not ahbmi.hready; + else + v.error := '0'; + end if; + + if ((r.retry or r.error) = '1') then + htrans := HTRANS_IDLE; + end if; + + if (ahbmi.hready = '1') then v.bo := nbo; v.bg := ahbmi.hgrant; - if (htrans = HTRANS_NONSEQ) or (htrans = HTRANS_SEQ) then + if ((htrans = HTRANS_NONSEQ) or (htrans = HTRANS_SEQ)) then v.ba := r.bg; else v.ba := '0'; end if; end if; - if rst = '0' then + if (rst = '0') then v.bg := '0'; v.ba := '0'; v.bo := '0'; v.bb := '0'; end if; - - rin <= v; - tmsto.data <= ahbmi.hrdata; - rmsto.data <= ahbmi.hrdata; - tmsto.error <= terror; - tmsto.retry <= tretry; - tmsto.ready <= tready; - rmsto.error <= rerror; - rmsto.retry <= rretry; - rmsto.ready <= rready; - tmsto.grant <= tgrant; - rmsto.grant <= rgrant; - ahbmo.htrans <= htrans; - ahbmo.hbusreq <= hbusreq; - ahbmo.haddr <= haddr; - ahbmo.hwrite <= hwrite; - ahbmo.hwdata <= hwdata; - end process; - - regs : process(clk) + + rin <= v; + tmsto.data <= ahbmi.hrdata; + rmsto.data <= ahbmi.hrdata; + tmsto.error <= terror; + tmsto.retry <= tretry; + tmsto.ready <= tready; + rmsto.error <= rerror; + rmsto.retry <= rretry; + rmsto.ready <= rready; + tmsto.grant <= tgrant; + rmsto.grant <= rgrant; + ahbmo.htrans <= htrans; + ahbmo.hbusreq <= hbusreq; + ahbmo.haddr <= haddr; + ahbmo.hwrite <= hwrite; + ahbmo.hwdata <= hwdata; + + end process comb; + + regs : process (clk) is begin - if rising_edge(clk) then r <= rin; end if; - end process; - - ahbmo.hlock <= '0'; - ahbmo.hsize <= HSIZE_WORD; - ahbmo.hburst <= HBURST_INCR; - ahbmo.hprot <= "0011"; -end architecture; + + if rising_edge(clk) then + r <= rin; + end if; + + end process regs; + + ahbmo.hlock <= '0'; + ahbmo.hsize <= HSIZE_WORD; + ahbmo.hburst <= HBURST_INCR; + ahbmo.hprot <= "0011"; + +end architecture rtl; diff --git a/rtl/peripherals/interrupt/irqmp.vhd b/rtl/peripherals/interrupt/irqmp.vhd index ef2710881a..188bf6c4a2 100644 --- a/rtl/peripherals/interrupt/irqmp.vhd +++ b/rtl/peripherals/interrupt/irqmp.vhd @@ -16,25 +16,25 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------- --- Entity: irqmp --- File: irqmp.vhd --- Author: Jiri Gaisler - Gaisler Research --- Description: Multi-processor APB interrupt controller. Implements a --- two-level interrupt controller for 15 interrupts. +-- Entity: irqmp +-- File: irqmp.vhd +-- Author: Jiri Gaisler - Gaisler Research +-- Description: Multi-processor APB interrupt controller. Implements a +-- two-level interrupt controller for 15 interrupts. ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.config_types.all; -use work.config.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.leon3.all; -use work.coretypes.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.config_types.all; + use work.config.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.leon3.all; + use work.coretypes.all; entity irqmp is generic ( @@ -47,457 +47,678 @@ entity irqmp is bootreg : integer := 1 ); port ( - rst : in std_ulogic; - clk : in std_ulogic; - apbi : in apb_slv_in_type; - apbo : out apb_slv_out_type; - irqi : in irq_out_vector(0 to ncpu-1); - irqo : out irq_in_vector(0 to ncpu-1) + rst : in std_ulogic; + clk : in std_ulogic; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type; + irqi : in irq_out_vector(0 to ncpu - 1); + irqo : out irq_in_vector(0 to ncpu - 1) ); -end; +end entity irqmp; architecture rtl of irqmp is -constant REVISION : integer := 4; + constant REVISION : integer := 4; -constant pconfig : apb_config_type := ( - 0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_IRQMP, 0, REVISION, 0), - 1 => apb_iobar(paddr, pmask), - 2 => (others => '0')); + constant PCONFIG : apb_config_type := + ( + 0 => ahb_device_reg (VENDOR_GAISLER, GAISLER_IRQMP, 0, REVISION, 0), + 1 => apb_iobar(paddr, pmask), + 2 => (others => '0') + ); -function IMAP_HIGH return integer is -begin - if irqmap = 0 then - return 0; - elsif eirq /= 0 or irqmap = 2 then - return 31; - end if; - return 15; -end function IMAP_HIGH; -constant IMAP_LOW : integer := 0; -- allow remap of irq line 0 -function IMAP_LEN return integer is -begin - if irqmap = 0 then - return 1; - elsif eirq /= 0 then - return 5; - end if; - return 4; -end function IMAP_LEN; - -type mask_type is array (0 to ncpu-1) of std_logic_vector(15 downto 1); -type mask2_type is array (0 to ncpu-1) of std_logic_vector(15 downto 0); -type irl_type is array (0 to ncpu-1) of std_logic_vector(3 downto 0); -type irl2_type is array (0 to ncpu-1) of std_logic_vector(4 downto 0); -type irqmap_type is array (IMAP_LOW to (IMAP_HIGH)) of std_logic_vector(IMAP_LEN-1 downto 0); - -type reg_type is record - imask : mask_type; - ilevel : std_logic_vector(15 downto 1); - ipend : std_logic_vector(15 downto 1); - iforce : mask_type; - ibroadcast : std_logic_vector(15 downto 1); - irl : irl_type; - cpurst : std_logic_vector(ncpu-1 downto 0); - imap : irqmap_type; - setaddr : std_logic_vector(ncpu-1 downto 0); - newaddr : std_logic_vector(31 downto 2); - setaddrboot : std_ulogic; - forceerr : std_logic_vector(ncpu-1 downto 0); - clkcount : std_logic_vector(2 downto 0); -end record; - -type ereg_type is record - imask : mask2_type; - ipend : std_logic_vector(15 downto 0); - irl : irl2_type; -end record; - -constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; -constant RRES : reg_type := ( - imask => (others => (others => '0')), ilevel => (others => '0'), - ipend => (others => '0'), iforce => (others => (others => '0')), - ibroadcast => (others => '0'), irl => (others => (others => '0')), - cpurst => (others => '0'), imap => (others => (others => '0')), - setaddr => (others => '0'), newaddr => (others => '0'), setaddrboot => '0', - forceerr => (others => '0'), clkcount => "000"); -constant ERES : ereg_type := ( - imask => (others => (others => '0')), ipend => (others => '0'), - irl => (others => (others => '0'))); - - -function prioritize(b : std_logic_vector(15 downto 0)) return std_logic_vector is -variable a : std_logic_vector(15 downto 0); -variable irl : std_logic_vector(3 downto 0); -variable level : integer range 0 to 15; -begin - irl := "0000"; level := 0; a := b; - for i in 15 downto 0 loop - level := i; - if a(i) = '1' then exit; end if; - end loop; - irl := conv_std_logic_vector(level, 4); - return(irl); -end; - -signal r, rin : reg_type; -signal r2, r2in : ereg_type; + function imap_high return integer is + begin + + if (irqmap = 0) then + return 0; + elsif (eirq /= 0 or irqmap = 2) then + return 31; + end if; + + return 15; + + end function imap_high; + + constant IMAP_LOW : integer := 0; -- allow remap of irq line 0 + + function imap_len return integer is + begin + + if (irqmap = 0) then + return 1; + elsif (eirq /= 0) then + return 5; + end if; + + return 4; + + end function imap_len; + + type mask_type is array (0 to ncpu - 1) of std_logic_vector(15 downto 1); + + type mask2_type is array (0 to ncpu - 1) of std_logic_vector(15 downto 0); + + type irl_type is array (0 to ncpu - 1) of std_logic_vector(3 downto 0); + + type irl2_type is array (0 to ncpu - 1) of std_logic_vector(4 downto 0); + + type irqmap_type is array (IMAP_LOW to (imap_high)) of std_logic_vector(imap_len - 1 downto 0); + + type reg_type is record + imask : mask_type; + ilevel : std_logic_vector(15 downto 1); + ipend : std_logic_vector(15 downto 1); + iforce : mask_type; + ibroadcast : std_logic_vector(15 downto 1); + irl : irl_type; + cpurst : std_logic_vector(ncpu - 1 downto 0); + imap : irqmap_type; + setaddr : std_logic_vector(ncpu - 1 downto 0); + newaddr : std_logic_vector(31 downto 2); + setaddrboot : std_ulogic; + forceerr : std_logic_vector(ncpu - 1 downto 0); + clkcount : std_logic_vector(2 downto 0); + end record reg_type; + + type ereg_type is record + imask : mask2_type; + ipend : std_logic_vector(15 downto 0); + irl : irl2_type; + end record ereg_type; + + constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; + constant RRES : reg_type := + ( + imask => (others => (others => '0')), + ilevel => (others => '0'), + ipend => (others => '0'), + iforce => (others => (others => '0')), + ibroadcast => (others => '0'), + irl => (others => (others => '0')), + cpurst => (others => '0'), + imap => (others => (others => '0')), + setaddr => (others => '0'), + newaddr => (others => '0'), + setaddrboot => '0', + forceerr => (others => '0'), + clkcount => "000" + ); + constant ERES : ereg_type := + ( + imask => (others => (others => '0')), + ipend => (others => '0'), + irl => (others => (others => '0')) + ); + + function prioritize ( + b : std_logic_vector(15 downto 0) + ) return std_logic_vector is + + variable a : std_logic_vector(15 downto 0); + variable irl : std_logic_vector(3 downto 0); + variable level : integer range 0 to 15; + + begin + + irl := "0000"; level := 0; a := b; + + for i in 15 downto 0 loop + + level := i; + + if (a(i) = '1') then + exit; + end if; + + end loop; + + irl := conv_std_logic_vector(level, 4); + return(irl); + + end function; + + signal r, rin : reg_type; + signal r2, r2in : ereg_type; begin - comb : process(rst, r, r2, apbi, irqi) - variable v : reg_type; - variable temp : mask_type; - variable prdata : std_logic_vector(31 downto 0); - variable tmpirq : std_logic_vector(15 downto 0); - variable tmpvar : std_logic_vector(15 downto 1); - variable cpurun : std_logic_vector(ncpu-1 downto 0); - variable v2 : ereg_type; - variable irl2 : std_logic_vector(3 downto 0); - variable ipend2 : std_logic_vector(ncpu-1 downto 0); - variable temp2 : mask2_type; - variable irq : std_logic_vector(NAHBIRQ-1 downto 0); - variable vcpu : std_logic_vector(3 downto 0); - variable bootreg_sel : std_ulogic; - variable paddr : std_logic_vector(19 downto 2); - + comb : process (rst, r, r2, apbi, irqi) is + + variable v : reg_type; + variable temp : mask_type; + variable prdata : std_logic_vector(31 downto 0); + variable tmpirq : std_logic_vector(15 downto 0); + variable tmpvar : std_logic_vector(15 downto 1); + variable cpurun : std_logic_vector(ncpu - 1 downto 0); + variable v2 : ereg_type; + variable irl2 : std_logic_vector(3 downto 0); + variable ipend2 : std_logic_vector(ncpu - 1 downto 0); + variable temp2 : mask2_type; + variable irq : std_logic_vector(NAHBIRQ - 1 downto 0); + variable vcpu : std_logic_vector(3 downto 0); + variable bootreg_sel : std_ulogic; + variable paddr : std_logic_vector(19 downto 2); + begin - v := r; v.cpurst := (others => '0'); + v := r; v.cpurst := (others => '0'); cpurun := (others => '0'); cpurun(0) := '1'; tmpvar := (others => '0'); ipend2 := (others => '0'); - v2 := r2; + v2 := r2; - paddr := apbi.paddr(19 downto 2); - paddr(19 downto 8) := paddr(19 downto 8) and not std_logic_vector(to_unsigned(pmask,12)); + paddr := apbi.paddr(19 downto 2); + paddr(19 downto 8) := paddr(19 downto 8) and not std_logic_vector(to_unsigned(pmask, 12)); --- prioritize interrupts + -- prioritize interrupts - if eirq /= 0 then - for i in 0 to ncpu-1 loop - temp2(i) := r2.ipend and r2.imask(i); + if (eirq /= 0) then + + for i in 0 to ncpu - 1 loop + + temp2(i) := r2.ipend and r2.imask(i); ipend2(i) := orv(temp2(i)); + end loop; + end if; - for i in 0 to ncpu-1 loop + for i in 0 to ncpu - 1 loop + temp(i) := ((r.iforce(i) or r.ipend) and r.imask(i)); - if eirq /= 0 then temp(i)(eirq) := temp(i)(eirq) or ipend2(i); end if; + + if (eirq /= 0) then + temp(i)(eirq) := temp(i)(eirq) or ipend2(i); + end if; + v.irl(i) := prioritize((temp(i) and r.ilevel) & '0'); - if v.irl(i) = "0000" then - if eirq /= 0 then temp(i)(eirq) := temp(i)(eirq) or ipend2(i); end if; + + if (v.irl(i) = "0000") then + if (eirq /= 0) then + temp(i)(eirq) := temp(i)(eirq) or ipend2(i); + end if; v.irl(i) := prioritize((temp(i) and not r.ilevel) & '0'); end if; + end loop; - if bootreg /= 0 then - if r.clkcount/="000" then - v.clkcount := std_logic_vector(unsigned(r.clkcount)-1); + if (bootreg /= 0) then + if (r.clkcount/="000") then + v.clkcount := std_logic_vector(unsigned(r.clkcount) - 1); end if; end if; --- register read + -- register read prdata := (others => '0'); - case apbi.paddr(7 downto 6) is - when "00" => - case apbi.paddr(4 downto 2) is - when "000" => prdata(15 downto 1) := r.ilevel; - when "001" => - prdata(15 downto 1) := r.ipend; - if eirq /= 0 then prdata(31 downto 16) := r2.ipend; end if; - when "010" => prdata(15 downto 1) := r.iforce(0); - when "011" => - when "100" | "101" => - prdata(31 downto 28) := conv_std_logic_vector(ncpu-1, 4); - prdata(19 downto 16) := conv_std_logic_vector(eirq, 4); - for i in 0 to ncpu -1 loop prdata(i) := irqi(i).pwd; end loop; - if ncpu > 1 then - prdata(27) := '1'; - case apbi.paddr(4 downto 2) is - when "101" => - prdata := (others => '0'); - prdata(15 downto 1) := r.ibroadcast; - when others => - end case; - end if; - if bootreg /= 0 then - prdata(26) := '1'; - end if; - when "110" => - for i in 0 to ncpu-1 loop prdata(i):=irqi(i).err; end loop; - when others => - end case; - when "01" => - for i in 0 to ncpu-1 loop - if i = conv_integer( apbi.paddr(5 downto 2)) then - prdata(15 downto 1) := r.imask(i); - if eirq /= 0 then prdata(31 downto 16) := r2.imask(i); end if; - end if; - end loop; - when "10" => - for i in 0 to ncpu-1 loop - if i = conv_integer( apbi.paddr(5 downto 2)) then - prdata(15 downto 1) := r.iforce(i); - end if; - end loop; - when "11" => - if eirq /= 0 then - for i in 0 to ncpu-1 loop - if i = conv_integer( apbi.paddr(5 downto 2)) then - prdata(4 downto 0) := r2.irl(i); - end if; - end loop; - end if; - when others => - end case; --- register write + case apbi.paddr(7 downto 6) is - if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' and - ((irqmap = 0 and bootreg=0) or paddr(9 downto 8) = "00") then - case apbi.paddr(7 downto 6) is when "00" => + case apbi.paddr(4 downto 2) is - when "000" => v.ilevel := apbi.pwdata(15 downto 1); - when "001" => v.ipend := apbi.pwdata(15 downto 1); - if eirq /= 0 then v2.ipend := apbi.pwdata(31 downto 16); end if; - when "010" => v.iforce(0) := apbi.pwdata(15 downto 1); - when "011" => v.ipend := r.ipend and not apbi.pwdata(15 downto 1); - if eirq /= 0 then v2.ipend := r2.ipend and not apbi.pwdata(31 downto 16); end if; - when "100" => - for i in 0 to ncpu -1 loop v.cpurst(i) := apbi.pwdata(i); end loop; - when "110" => - if bootreg /= 0 then - v.forceerr := v.forceerr or apbi.pwdata(ncpu-1 downto 0); - v.clkcount := "111"; - end if; - when others => - if ncpu > 1 then - case apbi.paddr(4 downto 2) is - when "101" => - v.ibroadcast := apbi.pwdata(15 downto 1); - when others => - end case; - end if; + + when "000" => + + prdata(15 downto 1) := r.ilevel; + + when "001" => + + prdata(15 downto 1) := r.ipend; + + if (eirq /= 0) then + prdata(31 downto 16) := r2.ipend; + end if; + + when "010" => + + prdata(15 downto 1) := r.iforce(0); + + when "011" => + + when "100" | "101" => + + prdata(31 downto 28) := conv_std_logic_vector(ncpu - 1, 4); + prdata(19 downto 16) := conv_std_logic_vector(eirq, 4); + + for i in 0 to ncpu - 1 loop + + prdata(i) := irqi(i).pwd; + + end loop; + + if (ncpu > 1) then + prdata(27) := '1'; + + case apbi.paddr(4 downto 2) is + + when "101" => + + prdata := (others => '0'); + prdata(15 downto 1) := r.ibroadcast; + + when others => + + end case; + + end if; + + if (bootreg /= 0) then + prdata(26) := '1'; + end if; + + when "110" => + + for i in 0 to ncpu - 1 loop + + prdata(i) :=irqi(i).err; + + end loop; + + when others => + end case; + when "01" => - for i in 0 to ncpu-1 loop - if i = conv_integer( apbi.paddr(5 downto 2)) then - v.imask(i) := apbi.pwdata(15 downto 1); - if eirq /= 0 then v2.imask(i) := apbi.pwdata(31 downto 16); end if; - end if; + + for i in 0 to ncpu - 1 loop + + if (i = conv_integer(apbi.paddr(5 downto 2))) then + prdata(15 downto 1) := r.imask(i); + if (eirq /= 0) then + prdata(31 downto 16) := r2.imask(i); + end if; + end if; + end loop; + when "10" => - for i in 0 to ncpu-1 loop - if i = conv_integer( apbi.paddr(5 downto 2)) then - v.iforce(i) := (r.iforce(i) or apbi.pwdata(15 downto 1)) and - not apbi.pwdata(31 downto 17); - end if; + + for i in 0 to ncpu - 1 loop + + if (i = conv_integer(apbi.paddr(5 downto 2))) then + prdata(15 downto 1) := r.iforce(i); + end if; + end loop; + + when "11" => + + if (eirq /= 0) then + + for i in 0 to ncpu - 1 loop + + if (i = conv_integer(apbi.paddr(5 downto 2))) then + prdata(4 downto 0) := r2.irl(i); + end if; + + end loop; + + end if; + when others => + + end case; + + -- register write + + if ((apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' and + ((irqmap = 0 and bootreg=0) or paddr(9 downto 8) = "00")) then + + case apbi.paddr(7 downto 6) is + + when "00" => + + case apbi.paddr(4 downto 2) is + + when "000" => + + v.ilevel := apbi.pwdata(15 downto 1); + + when "001" => + + v.ipend := apbi.pwdata(15 downto 1); + if (eirq /= 0) then + v2.ipend := apbi.pwdata(31 downto 16); + end if; + + when "010" => + + v.iforce(0) := apbi.pwdata(15 downto 1); + + when "011" => + + v.ipend := r.ipend and not apbi.pwdata(15 downto 1); + if (eirq /= 0) then + v2.ipend := r2.ipend and not apbi.pwdata(31 downto 16); + end if; + + when "100" => + + for i in 0 to ncpu - 1 loop + + v.cpurst(i) := apbi.pwdata(i); + + end loop; + + when "110" => + + if (bootreg /= 0) then + v.forceerr := v.forceerr or apbi.pwdata(ncpu - 1 downto 0); + v.clkcount := "111"; + end if; + + when others => + + if (ncpu > 1) then + + case apbi.paddr(4 downto 2) is + + when "101" => + + v.ibroadcast := apbi.pwdata(15 downto 1); + + when others => + + end case; + + end if; + + end case; + + when "01" => + + for i in 0 to ncpu - 1 loop + + if (i = conv_integer(apbi.paddr(5 downto 2))) then + v.imask(i) := apbi.pwdata(15 downto 1); + if (eirq /= 0) then + v2.imask(i) := apbi.pwdata(31 downto 16); + end if; + end if; + + end loop; + + when "10" => + + for i in 0 to ncpu - 1 loop + + if (i = conv_integer(apbi.paddr(5 downto 2))) then + v.iforce(i) := (r.iforce(i) or apbi.pwdata(15 downto 1)) and + not apbi.pwdata(31 downto 17); + end if; + + end loop; + + when others => + end case; + end if; --- implement processor reboot / monitor regs - vcpu := apbi.paddr(5 downto 2); + -- implement processor reboot / monitor regs + vcpu := apbi.paddr(5 downto 2); bootreg_sel := '0'; - if bootreg /= 0 then - if r.clkcount="000" then - if orv(r.setaddr)='1' then - if r.newaddr(2)='0' then - v.newaddr(2):='1'; + if (bootreg /= 0) then + if (r.clkcount="000") then + if (orv(r.setaddr)='1') then + if (r.newaddr(2)='0') then + v.newaddr(2) :='1'; else - if r.setaddrboot='1' then + if (r.setaddrboot='1') then v.cpurst := v.cpurst or r.setaddr; end if; v.setaddr := (others => '0'); end if; end if; - for i in 0 to ncpu-1 loop + + for i in 0 to ncpu - 1 loop + v.forceerr(i) := v.forceerr(i) and not irqi(i).err; + end loop; + end if; -- Alias bootregs into 256B space if ncpu <= 8 - if paddr(9 downto 6)="1000" then bootreg_sel:='1'; end if; - if ncpu <= 8 and paddr(9 downto 6)="0001" and apbi.paddr(5)='1' then + if (paddr(9 downto 6)="1000") then + bootreg_sel :='1'; + end if; + if (ncpu <= 8 and paddr(9 downto 6)="0001" and apbi.paddr(5)='1') then bootreg_sel := '1'; end if; - if ncpu <= 8 then vcpu(3):='0'; end if; - if (apbi.psel(pindex) and apbi.penable)='1' and bootreg_sel='1' then + if (ncpu <= 8) then + vcpu(3) :='0'; + end if; + if ((apbi.psel(pindex) and apbi.penable)='1' and bootreg_sel='1') then -- Reg read prdata := (others => '0'); -- Reg write - if apbi.pwrite='1' then - for i in 0 to ncpu-1 loop - if i = conv_integer( vcpu) then - v.setaddr(i) := '1'; + if (apbi.pwrite='1') then + + for i in 0 to ncpu - 1 loop + + if (i = conv_integer(vcpu)) then + v.setaddr(i) := '1'; v.setaddrboot := apbi.pwdata(0); end if; + end loop; - v.newaddr := apbi.pwdata(31 downto 3) & "0"; + + v.newaddr := apbi.pwdata(31 downto 3) & "0"; v.clkcount := "111"; - end if; -- pwrite - end if; -- psel/paddr - end if; -- bootreg/=0 + end if; -- pwrite + end if; -- psel/paddr + end if; -- bootreg/=0 --- optionally remap interrupts + -- optionally remap interrupts irq := (others => '0'); - if irqmap /= 0 then - if (apbi.psel(pindex) and apbi.penable)='1' and apbi.paddr(9 downto 8) = "11" then + + if (irqmap /= 0) then + if ((apbi.psel(pindex) and apbi.penable)='1' and apbi.paddr(9 downto 8) = "11") then prdata := (others => '0'); + for i in r.imap'range loop - if i/4 = conv_integer(apbi.paddr(4 downto 2)) then - prdata(IMAP_LEN-1+(24-(i mod 4)*8) downto (24-(i mod 4)*8)) := r.imap(i); - if apbi.pwrite = '1' then - v.imap(i) := apbi.pwdata(IMAP_LEN-1+(24-(i mod 4)*8) downto (24-(i mod 4)*8)); + + if (i / 4 = conv_integer(apbi.paddr(4 downto 2))) then + prdata(IMAP_LEN - 1 + (24 - (i mod 4) * 8) downto (24 - (i mod 4) * 8)) := r.imap(i); + if (apbi.pwrite = '1') then + v.imap(i) := apbi.pwdata(imap_len - 1 + (24 - (i mod 4) * 8) downto (24 - (i mod 4) * 8)); end if; end if; + end loop; + end if; - for i in 0 to IMAP_HIGH loop - if i > NAHBIRQ-1 then + for i in 0 to imap_high loop + + if (i > NAHBIRQ - 1) then exit; end if; - if apbi.pirq(i) = '1' then + if (apbi.pirq(i) = '1') then irq(conv_integer(r.imap(i))) := '1'; end if; + end loop; + else - irq := apbi.pirq; + irq := apbi.pirq; v.imap := RRES.IMAP; end if; --- register new interrupts + -- register new interrupts for i in 1 to 15 loop - if i > NAHBIRQ-1 then - exit; + + if (i > NAHBIRQ - 1) then + exit; end if; - if ncpu = 1 then + + if (ncpu = 1) then v.ipend(i) := v.ipend(i) or irq(i); - else + else v.ipend(i) := v.ipend(i) or (irq(i) and not r.ibroadcast(i)); - for j in 0 to ncpu-1 loop - tmpvar := v.iforce(j); - tmpvar(i) := tmpvar(i) or (irq(i) and r.ibroadcast(i)); + + for j in 0 to ncpu - 1 loop + + tmpvar := v.iforce(j); + tmpvar(i) := tmpvar(i) or (irq(i) and r.ibroadcast(i)); v.iforce(j) := tmpvar; + end loop; + end if; + end loop; - if eirq /= 0 then + if (eirq /= 0) then + for i in 16 to 31 loop - if i > NAHBIRQ-1 then exit; end if; - v2.ipend(i-16) := v2.ipend(i-16) or irq(i); + + if (i > NAHBIRQ - 1) then + exit; + end if; + v2.ipend(i - 16) := v2.ipend(i - 16) or irq(i); + end loop; + end if; --- interrupt acknowledge + -- interrupt acknowledge - for i in 0 to ncpu-1 loop - if irqi(i).intack = '1' then - tmpirq := decode(irqi(i).irl); - temp(i) := tmpirq(15 downto 1); + for i in 0 to ncpu - 1 loop + + if (irqi(i).intack = '1') then + tmpirq := decode(irqi(i).irl); + temp(i) := tmpirq(15 downto 1); v.iforce(i) := v.iforce(i) and not temp(i); - v.ipend := v.ipend and not ((not r.iforce(i)) and temp(i)); - if eirq /= 0 then - if eirq = conv_integer(irqi(i).irl) then + v.ipend := v.ipend and not ((not r.iforce(i)) and temp(i)); + if (eirq /= 0) then + if (eirq = conv_integer(irqi(i).irl)) then v2.irl(i) := orv(temp2(i)) & prioritize(temp2(i)); - if v2.irl(i)(4) = '1' then - v2.ipend(conv_integer(v2.irl(i)(3 downto 0))) := '0'; + if (v2.irl(i)(4) = '1') then + v2.ipend(conv_integer(v2.irl(i)(3 downto 0))) := '0'; end if; - end if; - end if; + end if; + end if; end if; + end loop; --- reset + -- reset - if (not RESET_ALL) and (rst = '0') then + if ((not RESET_ALL) and (rst = '0')) then v.imask := RRES.imask; v.iforce := RRES.iforce; v.ipend := RRES.ipend; - if ncpu > 1 then + if (ncpu > 1) then v.ibroadcast := RRES.ibroadcast; end if; - if irqmap /= 0 then + if (irqmap /= 0) then + for i in r.imap'range loop - v.imap(i) := conv_std_logic_vector(i, IMAP_LEN); + + v.imap(i) := conv_std_logic_vector(i, imap_len); + end loop; + end if; v.forceerr := RRES.forceerr; - v.setaddr := RRES.setaddr; - v2.ipend := ERES.ipend; v2.imask := ERES.imask; v2.irl := ERES.irl; + v.setaddr := RRES.setaddr; + v2.ipend := ERES.ipend; v2.imask := ERES.imask; v2.irl := ERES.irl; end if; - if bootreg=0 then + + if (bootreg=0) then v.forceerr := RRES.forceerr; - v.setaddr := RRES.setaddr; - v.newaddr := RRES.newaddr; + v.setaddr := RRES.setaddr; + v.newaddr := RRES.newaddr; end if; apbo.prdata <= prdata; - for i in 0 to ncpu-1 loop - irqo(i).irl <= r.irl(i); irqo(i).resume <= r.cpurst(i); - irqo(i).forceerr <= r.forceerr(i); + + for i in 0 to ncpu - 1 loop + + irqo(i).irl <= r.irl(i); + irqo(i).resume <= r.cpurst(i); + irqo(i).forceerr <= r.forceerr(i); irqo(i).pwdsetaddr <= r.setaddr(i); irqo(i).pwdnewaddr <= r.newaddr; - irqo(i).rstrun <= cpurun(i); - irqo(i).rstvec <= (others => '0'); -- Alternate reset vector - irqo(i).index <= conv_std_logic_vector(i, 4); + irqo(i).rstrun <= cpurun(i); + irqo(i).rstvec <= (others => '0'); -- Alternate reset vector + irqo(i).index <= conv_std_logic_vector(i, 4); + end loop; - rin <= v; r2in <= v2; - - end process; + rin <= v; + r2in <= v2; - apbo.pirq <= (others => '0'); - apbo.pconfig <= pconfig; - apbo.pindex <= pindex; + end process comb; - regs : process(clk) + apbo.pirq <= (others => '0'); + apbo.pconfig <= PCONFIG; + apbo.pindex <= pindex; + + regs : process (clk) is begin + if rising_edge(clk) then r <= rin; - if RESET_ALL and (rst = '0') then r <= RRES; end if; + if (RESET_ALL and (rst = '0')) then + r <= RRES; + end if; end if; - end process; - + + end process regs; + dor2regs : if eirq /= 0 generate - regs : process(clk) + + regs : process (clk) is begin + if rising_edge(clk) then r2 <= r2in; - if RESET_ALL and (rst = '0') then r2 <= ERES; end if; + if (RESET_ALL and (rst = '0')) then + r2 <= ERES; + end if; end if; - end process; - end generate; + + end process regs; + + end generate dor2regs; + nor2regs : if eirq = 0 generate --- r2 <= ((others => "0000000000000000"), "0000000000000000", (others => "00000")); + -- r2 <= ((others => "0000000000000000"), "0000000000000000", (others => "00000")); r2.ipend <= (others => '0'); - driveregs: for i in 0 to (ncpu-1) generate + + driveregs : for i in 0 to (ncpu - 1) generate r2.imask(i) <= (others => '0'); - r2.irl(i) <= (others => '0'); - end generate driveregs; - end generate; + r2.irl(i) <= (others => '0'); + end generate driveregs; --- pragma translate_off - bootmsg : report_version - generic map ("irqmp" & + end generate nor2regs; + + -- pragma translate_off + bootmsg : component report_version + generic map ( +"irqmp" & ": Multi-processor Interrupt Controller rev " & tost(REVISION) & - ", #cpu " & tost(NCPU) & ", eirq " & tost(eirq)); --- pragma translate_on + ", #cpu " & tost(NCPU) & ", eirq " & tost(eirq) + ); + + -- pragma translate_on --- pragma translate_off - cproc : process + -- pragma translate_off + cproc : process is begin + assert (irqmap = 0) or (apb_membar_size(pmask) >= 1024) report "IRQMP: irqmap /= 0 requires pmask to give memory area >= 1024 bytes" severity failure; wait; - end process; + + end process cproc; + -- pragma translate_on -end; +end architecture rtl; diff --git a/rtl/peripherals/timer/gptimer.vhd b/rtl/peripherals/timer/gptimer.vhd index e701d1cd16..6c2262a709 100644 --- a/rtl/peripherals/timer/gptimer.vhd +++ b/rtl/peripherals/timer/gptimer.vhd @@ -16,12 +16,12 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------- -- Entity: gptimer -- File: gptimer.vhd -- Author: Jiri Gaisler - Gaisler Research --- Description: This unit implemets a set of general-purpose timers with a +-- Description: This unit implemets a set of general-purpose timers with a -- common prescaler. Then number of timers and the width of -- the timers is propgrammable through generics -- @@ -32,7 +32,7 @@ -- -- This unit also implements a latching register for each timer, latching the -- timer value on the occurence of an interrupt on the apbi.priq input. The --- interrupt selection in possible via a mask register. +-- interrupt selection in possible via a mask register. -- -- This unit also implements loading of all timers on the event of a selected -- incoming interrupt. @@ -40,551 +40,803 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.config_types.all; -use work.config.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gptimer_pkg.all; ---pragma translate_off -use std.textio.all; ---pragma translate_on + use ieee.std_logic_1164.all; + use work.config_types.all; + use work.config.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gptimer_pkg.all; + -- pragma translate_off + use std.textio.all; +-- pragma translate_on entity gptimer is generic ( - pindex : integer := 0; - paddr : integer := 0; - pmask : integer := 16#fff#; - pirq : integer := 0; - sepirq : integer := 0; -- use separate interrupts for each timer - sbits : integer := 16; -- scaler bits - ntimers : integer range 1 to 7 := 1; -- number of timers - nbits : integer := 32; -- timer bits - wdog : integer := 0; - ewdogen : integer := 0; - glatch : integer := 0; - gextclk : integer := 0; - gset : integer := 0; - gelatch : integer range 0 to 2 := 0; - wdogwin : integer := 0 + pindex : integer := 0; + paddr : integer := 0; + pmask : integer := 16#fff#; + pirq : integer := 0; + sepirq : integer := 0; -- use separate interrupts for each timer + sbits : integer := 16; -- scaler bits + ntimers : integer range 1 to 7 := 1; -- number of timers + nbits : integer := 32; -- timer bits + wdog : integer := 0; + ewdogen : integer := 0; + glatch : integer := 0; + gextclk : integer := 0; + gset : integer := 0; + gelatch : integer range 0 to 2 := 0; + wdogwin : integer := 0 ); port ( - rst : in std_ulogic; - clk : in std_ulogic; - apbi : in apb_slv_in_type; - apbo : out apb_slv_out_type; - gpti : in gptimer_in_type; - gpto : out gptimer_out_type + rst : in std_ulogic; + clk : in std_ulogic; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type; + gpti : in gptimer_in_type; + gpto : out gptimer_out_type ); -end; - +end entity gptimer; + architecture rtl of gptimer is -constant REVISION : integer := 1; - -constant pconfig : apb_config_type := ( - 0 => ahb_device_reg (VENDOR_GAISLER, GAISLER_GPTIMER, 0, REVISION, pirq), - 1 => apb_iobar(paddr, pmask), - 2 => (others => '0')); - -type timer_reg is record - enable : std_ulogic; -- enable counter - load : std_ulogic; -- load counter - restart : std_ulogic; -- restart counter - irqpen : std_ulogic; -- interrupt pending - irqen : std_ulogic; -- interrupt enable - irq : std_ulogic; -- interrupt pulse - chain : std_ulogic; -- chain with previous timer - value : std_logic_vector(nbits-1 downto 0); - reload : std_logic_vector(nbits-1 downto 0); - latch : std_logic_vector(glatch*(nbits-1) downto 0); -end record; - -type timer_reg_vector is array (Natural range <> ) of timer_reg; - -constant TBITS : integer := log2x(ntimers+1); - -type registers is record - scaler : std_logic_vector(sbits-1 downto 0); - reload : std_logic_vector(sbits-1 downto 0); - tick : std_ulogic; - tsel : integer range 0 to ntimers; - timers : timer_reg_vector(1 to ntimers); - dishlt : std_ulogic; - wdogn : std_ulogic; - wdog : std_ulogic; - wdogdis : std_ulogic; - wdognmi : std_ulogic; - wdogwc : std_logic_vector(15 downto 0); - wdogwcr : std_logic_vector(15 downto 0); -end record; - -type registers2 is record - setdis : std_ulogic; - latchdis : std_ulogic; - elatchen : std_ulogic; - latchsel : std_logic_vector(NAHBIRQ-1 downto 0); - latchen : std_ulogic; - latchdel : std_ulogic; - extclken : std_ulogic; - extclk : std_logic_vector(2 downto 0); - seten : std_ulogic; - setdel : std_ulogic; -end record; - -constant NMI : integer := 15; - -constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; -function RESVAL_FUNC return registers is - variable vres : registers; -begin - vres.scaler := (others => '1'); - vres.reload := (others => '1'); - vres.tick := '0'; - vres.tsel := 0; - for i in 1 to ntimers loop - vres.timers(i).enable := '0'; - vres.timers(i).load := '0'; - vres.timers(i).restart := '0'; - vres.timers(i).irqpen := '0'; - vres.timers(i).irqen := '0'; - vres.timers(i).irq := '0'; - vres.timers(i).chain := '0'; - vres.timers(i).value := (others => '0'); - vres.timers(i).reload := (others => '0'); - vres.timers(i).latch := (others => '0'); - end loop; - if wdog /= 0 then - vres.timers(ntimers).enable := '1'; -- May be overriden by ewdogen - vres.timers(ntimers).load := '1'; - vres.timers(ntimers).reload := conv_std_logic_vector(wdog, nbits); - vres.timers(ntimers).irqen := '1'; - end if; - vres.dishlt := '0'; - vres.wdogn := '1'; - vres.wdog := '0'; - vres.wdogdis := '0'; - vres.wdognmi := '0'; - vres.wdogwc := (others => '0'); - vres.wdogwcr := (others => '0'); - return vres; -end function RESVAL_FUNC; -constant RESVAL : registers := RESVAL_FUNC; -constant RESVAL2 : registers2 := ( - setdis => '0', - latchdis => '0', - elatchen => '0', - latchsel => (others => '0'), - latchen => '0', - latchdel => '0', - extclken => '0', - extclk => (others => '0'), - seten => '0', - setdel => '0'); - -signal r, rin : registers; -signal r2, rin2 : registers2; + constant REVISION : integer := 1; + + constant PCONFIG : apb_config_type := + ( + 0 => ahb_device_reg (VENDOR_GAISLER, GAISLER_GPTIMER, 0, REVISION, pirq), + 1 => apb_iobar(paddr, pmask), + 2 => (others => '0') + ); + + type timer_reg is record + enable : std_ulogic; -- enable counter + load : std_ulogic; -- load counter + restart : std_ulogic; -- restart counter + irqpen : std_ulogic; -- interrupt pending + irqen : std_ulogic; -- interrupt enable + irq : std_ulogic; -- interrupt pulse + chain : std_ulogic; -- chain with previous timer + value : std_logic_vector(nbits - 1 downto 0); + reload : std_logic_vector(nbits - 1 downto 0); + latch : std_logic_vector(glatch * (nbits - 1) downto 0); + end record timer_reg; + + type timer_reg_vector is array (Natural range <>) of timer_reg; + + constant TBITS : integer := log2x(ntimers + 1); + + type registers is record + scaler : std_logic_vector(sbits - 1 downto 0); + reload : std_logic_vector(sbits - 1 downto 0); + tick : std_ulogic; + tsel : integer range 0 to ntimers; + timers : timer_reg_vector(1 to ntimers); + dishlt : std_ulogic; + wdogn : std_ulogic; + wdog : std_ulogic; + wdogdis : std_ulogic; + wdognmi : std_ulogic; + wdogwc : std_logic_vector(15 downto 0); + wdogwcr : std_logic_vector(15 downto 0); + end record registers; + + type registers2 is record + setdis : std_ulogic; + latchdis : std_ulogic; + elatchen : std_ulogic; + latchsel : std_logic_vector(NAHBIRQ - 1 downto 0); + latchen : std_ulogic; + latchdel : std_ulogic; + extclken : std_ulogic; + extclk : std_logic_vector(2 downto 0); + seten : std_ulogic; + setdel : std_ulogic; + end record registers2; + + constant NMI : integer := 15; + + constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; + + function resval_func return registers is + + variable vres : registers; + + begin + + vres.scaler := (others => '1'); + vres.reload := (others => '1'); + vres.tick := '0'; + vres.tsel := 0; + + for i in 1 to ntimers loop + + vres.timers(i).enable := '0'; + vres.timers(i).load := '0'; + vres.timers(i).restart := '0'; + vres.timers(i).irqpen := '0'; + vres.timers(i).irqen := '0'; + vres.timers(i).irq := '0'; + vres.timers(i).chain := '0'; + vres.timers(i).value := (others => '0'); + vres.timers(i).reload := (others => '0'); + vres.timers(i).latch := (others => '0'); + + end loop; + + if (wdog /= 0) then + vres.timers(ntimers).enable := '1'; -- May be overriden by ewdogen + vres.timers(ntimers).load := '1'; + vres.timers(ntimers).reload := conv_std_logic_vector(wdog, nbits); + vres.timers(ntimers).irqen := '1'; + end if; + + vres.dishlt := '0'; + vres.wdogn := '1'; + vres.wdog := '0'; + vres.wdogdis := '0'; + vres.wdognmi := '0'; + vres.wdogwc := (others => '0'); + vres.wdogwcr := (others => '0'); + return vres; + + end function resval_func; + + constant RESVAL : registers := resval_func; + constant RESVAL2 : registers2 := + ( + setdis => '0', + latchdis => '0', + elatchen => '0', + latchsel => (others => '0'), + latchen => '0', + latchdel => '0', + extclken => '0', + extclk => (others => '0'), + seten => '0', + setdel => '0' + ); + + signal r, rin : registers; + signal r2, rin2 : registers2; begin - comb : process(rst, r, r2, apbi, gpti) - variable scaler : std_logic_vector(sbits downto 0); - variable readdata, timer1 : std_logic_vector(31 downto 0); - variable res, addin : std_logic_vector(nbits-1 downto 0); - variable v : registers; - variable z : std_ulogic; - variable vtimers : timer_reg_vector(0 to ntimers); - variable xirq : std_logic_vector(NAHBIRQ-1 downto 0); - variable nirq : std_logic_vector(0 to ntimers-1); - variable tick : std_logic_vector(1 to 7); - variable latch : std_ulogic; - variable latchval : std_logic_vector(NAHBIRQ-1 downto 0); - variable latchd : std_ulogic; - variable v2 : registers2; - variable wdogwc : std_logic_vector(r.wdogwc'left+1 downto 0); - variable timeren : std_logic; + comb : process (rst, r, r2, apbi, gpti) is + + variable scaler : std_logic_vector(sbits downto 0); + variable readdata, timer1 : std_logic_vector(31 downto 0); + variable res, addin : std_logic_vector(nbits - 1 downto 0); + variable v : registers; + variable z : std_ulogic; + variable vtimers : timer_reg_vector(0 to ntimers); + variable xirq : std_logic_vector(NAHBIRQ - 1 downto 0); + variable nirq : std_logic_vector(0 to ntimers - 1); + variable tick : std_logic_vector(1 to 7); + variable latch : std_ulogic; + variable latchval : std_logic_vector(NAHBIRQ - 1 downto 0); + variable latchd : std_ulogic; + variable v2 : registers2; + variable wdogwc : std_logic_vector(r.wdogwc'left+1 downto 0); + variable timeren : std_logic; + begin - v := r; v2 := r2; v.tick := '0'; tick := (others => '0'); latch := '0'; - latchval := apbi.pirq; latchd := '0'; - vtimers(0) := ('0', '0', '0', '0', '0', '0', '0', - zero32(nbits-1 downto 0), zero32(nbits-1 downto 0), - zero32(glatch*(nbits-1) downto 0)); + v := r; v2 := r2; v.tick := '0'; tick := (others => '0'); latch := '0'; + latchval := apbi.pirq; latchd := '0'; + vtimers(0) := + ( + '0', + '0', + '0', + '0', + '0', + '0', + '0', + zero32(nbits - 1 downto 0), + zero32(nbits - 1 downto 0), + zero32(glatch * (nbits - 1) downto 0) + ); vtimers(1 to ntimers) := r.timers; xirq := (others => '0'); + for i in 1 to ntimers loop + v.timers(i).irq := '0'; v.timers(i).load := '0'; - tick(i) := r.timers(i).irq; + tick(i) := r.timers(i).irq; + end loop; - v.wdog := r.timers(ntimers).irqpen and not r.wdogdis; + + v.wdog := r.timers(ntimers).irqpen and not r.wdogdis; v.wdogn := not v.wdog; - --- wdog timer window counter - - if wdogwin /= 0 and wdog /= 0 then - wdogwc := ('0' & r.wdogwc) - 1; -- decrement scaler - if wdogwc(wdogwc'left) = '0' then + + -- wdog timer window counter + + if (wdogwin /= 0 and wdog /= 0) then + wdogwc := ('0' & r.wdogwc) - 1; -- decrement scaler + if (wdogwc(wdogwc'left) = '0') then v.wdogwc := wdogwc(v.wdogwc'range); end if; else wdogwc := (others => '0'); end if; --- scaler operation - - timeren := '0'; -- set if any of the timers are enabled - for i in 1 to ntimers loop timeren := timeren or r.timers(i).enable; end loop; - scaler := ('0' & r.scaler) - 1; -- decrement scaler + -- scaler operation + + timeren := '0'; -- set if any of the timers are enabled + + for i in 1 to ntimers loop - if gextclk = 1 then -- optional external timer clock + timeren := timeren or r.timers(i).enable; + + end loop; + + scaler := ('0' & r.scaler) - 1; -- decrement scaler + + if (gextclk = 1) then -- optional external timer clock v2.extclk := r2.extclk(1 downto 0) & gpti.extclk; end if; if ((gextclk=0) or (gextclk=1 and r2.extclken='0') or (gextclk=1 and r2.extclken='1' and r2.extclk(2 downto 1) = "01")) then - if (not gpti.dhalt or r.dishlt) = '1' -- halt timers in debug mode. - and timeren = '1' then -- scaler is halted when all timers are disabled + if ((not gpti.dhalt or r.dishlt) = '1' -- halt timers in debug mode. + and timeren = '1') then -- scaler is halted when all timers are disabled if (scaler(sbits) = '1') then - v.scaler := r.reload; v.tick := '1'; -- reload scaler - else v.scaler := scaler(sbits-1 downto 0); end if; + v.scaler := r.reload; v.tick := '1'; -- reload scaler + else + v.scaler := scaler(sbits - 1 downto 0); + end if; end if; end if; --- timer operation + -- timer operation - if (r.tick = '1') or (r.tsel /= 0) then - if r.tsel = ntimers then v.tsel := 0; - else v.tsel := r.tsel + 1; end if; + if ((r.tick = '1') or (r.tsel /= 0)) then + if (r.tsel = ntimers) then + v.tsel := 0; + else + v.tsel := r.tsel + 1; + end if; end if; - res := vtimers(r.tsel).value - 1; -- decrement selected timer - if (res(nbits-1) = '1') and ((vtimers(r.tsel).value(nbits-1) = '0')) - then z := '1'; else z := '0'; end if; -- undeflow detect + res := vtimers(r.tsel).value - 1; -- decrement selected timer + + if ((res(nbits - 1) = '1') and ((vtimers(r.tsel).value(nbits - 1) = '0'))) then + z := '1'; + else + z := '0'; + end if; -- undeflow detect + + -- update corresponding register and generate irq --- update corresponding register and generate irq + for i in 1 to ntimers - 1 loop + + nirq(i) := r.timers(i).irq; + + end loop; - for i in 1 to ntimers-1 loop nirq(i) := r.timers(i).irq; end loop; nirq(0) := r.timers(ntimers).irq; for i in 1 to ntimers loop - if i = r.tsel then - if (r.timers(i).enable = '1') and - (((r.timers(i).chain and nirq(i-1)) or not (r.timers(i).chain)) = '1') - then + if (i = r.tsel) then + if ((r.timers(i).enable = '1') and + (((r.timers(i).chain and nirq(i - 1)) or not (r.timers(i).chain)) = '1')) then v.timers(i).irq := z and not r.timers(i).load; - if (v.timers(i).irq and r.timers(i).irqen) = '1' then + if ((v.timers(i).irq and r.timers(i).irqen) = '1') then v.timers(i).irqpen := '1'; end if; v.timers(i).value := res; - if (z and not r.timers(i).load) = '1' then + if ((z and not r.timers(i).load) = '1') then v.timers(i).enable := r.timers(i).restart; - if r.timers(i).restart = '1' then + if (r.timers(i).restart = '1') then v.timers(i).value := r.timers(i).reload; end if; end if; end if; end if; - if r.timers(i).load = '1' then + + if (r.timers(i).load = '1') then v.timers(i).value := r.timers(i).reload; - if (i = ntimers) and wdogwin /= 0 and wdog /= 0 then + if ((i = ntimers) and wdogwin /= 0 and wdog /= 0) then v.wdogwc := r.wdogwcr; - if wdogwc(wdogwc'left) = '0' then - v.timers(i).irq := '1'; + if (wdogwc(wdogwc'left) = '0') then + v.timers(i).irq := '1'; v.timers(i).irqpen := '1'; end if; end if; end if; + end loop; --- timer external set - if gset = 1 then - if gelatch /= 0 and r2.elatchen = '1' then + -- timer external set + if (gset = 1) then + if (gelatch /= 0 and r2.elatchen = '1') then latchval := gpti.latchv; end if; - if NAHBIRQ <= 32 then - for i in NAHBIRQ-1 downto 0 loop + if (NAHBIRQ <= 32) then + + for i in NAHBIRQ - 1 downto 0 loop + latch := latch or (v2.latchsel(i) and latchval(i)); - if gelatch = 2 then latchd := latchd or (v2.latchsel(i) and gpti.latchd(i)); end if; + if (gelatch = 2) then + latchd := latchd or (v2.latchsel(i) and gpti.latchd(i)); + end if; + end loop; + else + for i in 31 downto 0 loop + latch := latch or (v2.latchsel(i) and latchval(i)); - if gelatch = 2 then latchd := latchd or (v2.latchsel(i) and gpti.latchd(i)); end if; + if (gelatch = 2) then + latchd := latchd or (v2.latchsel(i) and gpti.latchd(i)); + end if; + end loop; + end if; - if gelatch = 2 and (r2.seten = '1' and r2.elatchen = '1') then - if latchd = '1' then + if (gelatch = 2 and (r2.seten = '1' and r2.elatchen = '1')) then + if (latchd = '1') then v2.setdis := '1'; end if; - if r2.setdis = '1' and r.tsel = 0 then + if (r2.setdis = '1' and r.tsel = 0) then v2.setdis := '0'; v2.seten := '0'; v2.setdel := '0'; end if; end if; - if (latch='1' and r2.seten='1' and r.tsel = 0) or - (r2.setdel = '1' and r2.seten='1' and r.tsel = 0) then + if ((latch='1' and r2.seten='1' and r.tsel = 0) or + (r2.setdel = '1' and r2.seten='1' and r.tsel = 0)) then + for i in 1 to ntimers loop + v.timers(i).value := r.timers(i).reload; + end loop; + v2.setdel := '0'; - if gelatch < 2 or (gelatch = 2 and (r2.elatchen = '0' or v2.setdis = '1')) then + if (gelatch < 2 or (gelatch = 2 and (r2.elatchen = '0' or v2.setdis = '1'))) then v2.seten := '0'; - if gelatch = 2 then v2.setdis := '0'; end if; + if (gelatch = 2) then + v2.setdis := '0'; + end if; end if; - elsif latch='1' and r2.seten='1' and r.tsel /= 0 then + elsif (latch='1' and r2.seten='1' and r.tsel /= 0) then v2.setdel := '1'; end if; end if; - - if sepirq /= 0 then - for i in 1 to ntimers loop - xirq(i-1+pirq) := r.timers(i).irq and r.timers(i).irqen; + + if (sepirq /= 0) then + + for i in 1 to ntimers loop + + xirq(i - 1 + pirq) := r.timers(i).irq and r.timers(i).irqen; + end loop; - else + + else + for i in 1 to ntimers loop + xirq(pirq) := xirq(pirq) or (r.timers(i).irq and r.timers(i).irqen); + end loop; + end if; - if wdog /= 0 then - if (r.wdognmi and r.timers(ntimers).irq and r.timers(ntimers).irqen) = '1' then + + if (wdog /= 0) then + if ((r.wdognmi and r.timers(ntimers).irq and r.timers(ntimers).irqen) = '1') then xirq(NMI) := '1'; end if; end if; --- read registers + -- read registers readdata := (others => '0'); + case apbi.paddr(6 downto 2) is - when "00000" => readdata(sbits-1 downto 0) := r.scaler; - when "00001" => readdata(sbits-1 downto 0) := r.reload; - when "00010" => - readdata(2 downto 0) := conv_std_logic_vector(ntimers, 3) ; - readdata(7 downto 3) := conv_std_logic_vector(pirq, 5) ; - if (sepirq /= 0) then readdata(8) := '1'; end if; + + when "00000" => + + readdata(sbits - 1 downto 0) := r.scaler; + + when "00001" => + + readdata(sbits - 1 downto 0) := r.reload; + + when "00010" => + + readdata(2 downto 0) := conv_std_logic_vector(ntimers, 3); + readdata(7 downto 3) := conv_std_logic_vector(pirq, 5); + + if (sepirq /= 0) then + readdata(8) := '1'; + end if; + readdata(9) := r.dishlt; - if gextclk = 1 then readdata(10) := r2.extclken; end if; - if glatch = 1 then readdata(11) := r2.latchen; end if; - if gset = 1 then readdata(12) := r2.seten; end if; - if gelatch /= 0 then readdata(13) := r2.elatchen; end if; - when "00011" => - if glatch = 1 then - if NAHBIRQ <= 32 then - for i in NAHBIRQ-1 downto 0 loop - readdata(i) := r2.latchsel(i); - end loop; - else - for i in 31 downto 0 loop - readdata(i) := r2.latchsel(i); - end loop; + + if (gextclk = 1) then + readdata(10) := r2.extclken; end if; - end if; - when others => - for i in 1 to ntimers loop - if conv_integer(apbi.paddr(6 downto 4)) = i then - case apbi.paddr(3 downto 2) is - when "00" => readdata(nbits-1 downto 0) := r.timers(i).value; - when "01" => readdata(nbits-1 downto 0) := r.timers(i).reload; - when "10" => - if wdog /= 0 and i = ntimers then - if wdogwin /= 0 then - readdata(31 downto 16) := r.wdogwcr; - end if; - readdata(8 downto 7) := r.wdogdis & r.wdognmi; - end if; - readdata(6 downto 0) := - gpti.dhalt & r.timers(i).chain & - r.timers(i).irqpen & r.timers(i).irqen & r.timers(i).load & - r.timers(i).restart & r.timers(i).enable; - when "11" => - if glatch = 1 then - readdata(glatch*(nbits-1) downto 0) := r.timers(i).latch; - end if; - when others => - end case; + + if (glatch = 1) then + readdata(11) := r2.latchen; end if; - end loop; - end case; --- write registers + if (gset = 1) then + readdata(12) := r2.seten; + end if; + + if (gelatch /= 0) then + readdata(13) := r2.elatchen; + end if; - if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then - case apbi.paddr(6 downto 2) is - when "00000" => v.scaler := apbi.pwdata(sbits-1 downto 0); - when "00001" => v.reload := apbi.pwdata(sbits-1 downto 0); - v.scaler := apbi.pwdata(sbits-1 downto 0); - when "00010" => v.dishlt := apbi.pwdata(9); - if gextclk = 1 then v2.extclken := apbi.pwdata(10); end if; - if glatch = 1 then v2.latchen := apbi.pwdata(11); end if; - if gset = 1 then v2.seten := apbi.pwdata(12); end if; - if gelatch /= 0 then v2.elatchen := apbi.pwdata(13); end if; - for i in 1 to ntimers loop - v.timers(i).enable := r.timers(i).enable or apbi.pwdata(15+i); - end loop; when "00011" => - if glatch=1 then - if NAHBIRQ <= 32 then - for i in NAHBIRQ-1 downto 0 loop - v2.latchsel(i) := apbi.pwdata(i); + + if (glatch = 1) then + if (NAHBIRQ <= 32) then + + for i in NAHBIRQ - 1 downto 0 loop + + readdata(i) := r2.latchsel(i); + end loop; + else + for i in 31 downto 0 loop - v2.latchsel(i) := apbi.pwdata(i); + + readdata(i) := r2.latchsel(i); + end loop; + end if; end if; - when others => + + when others => + for i in 1 to ntimers loop - if conv_integer(apbi.paddr(6 downto 4)) = i then + + if (conv_integer(apbi.paddr(6 downto 4)) = i) then + case apbi.paddr(3 downto 2) is - when "00" => v.timers(i).value := apbi.pwdata(nbits-1 downto 0); - when "01" => v.timers(i).reload := apbi.pwdata(nbits-1 downto 0); - when "10" => if wdog /= 0 and i = ntimers then - if wdogwin /= 0 then - v.wdogwcr := apbi.pwdata(31 downto 16); - end if; - v.wdogdis := apbi.pwdata(8); - v.wdognmi := apbi.pwdata(7); - end if; - v.timers(i).chain := apbi.pwdata(5); - v.timers(i).irqpen := v.timers(i).irqpen and not apbi.pwdata(4); - v.timers(i).irqen := apbi.pwdata(3); - v.timers(i).load := apbi.pwdata(2); - v.timers(i).restart := apbi.pwdata(1); - v.timers(i).enable := apbi.pwdata(0); - when others => + + when "00" => + + readdata(nbits - 1 downto 0) := r.timers(i).value; + + when "01" => + + readdata(nbits - 1 downto 0) := r.timers(i).reload; + + when "10" => + + if (wdog /= 0 and i = ntimers) then + if (wdogwin /= 0) then + readdata(31 downto 16) := r.wdogwcr; + end if; + readdata(8 downto 7) := r.wdogdis & r.wdognmi; + end if; + readdata(6 downto 0) := gpti.dhalt & r.timers(i).chain & + r.timers(i).irqpen & r.timers(i).irqen & r.timers(i).load & + r.timers(i).restart & r.timers(i).enable; + + when "11" => + + if (glatch = 1) then + readdata(glatch * (nbits - 1) downto 0) := r.timers(i).latch; + end if; + + when others => + end case; + end if; + end loop; + + end case; + + -- write registers + + if ((apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1') then + + case apbi.paddr(6 downto 2) is + + when "00000" => + + v.scaler := apbi.pwdata(sbits - 1 downto 0); + + when "00001" => + + v.reload := apbi.pwdata(sbits - 1 downto 0); + v.scaler := apbi.pwdata(sbits - 1 downto 0); + + when "00010" => + + v.dishlt := apbi.pwdata(9); + if (gextclk = 1) then + v2.extclken := apbi.pwdata(10); + end if; + if (glatch = 1) then + v2.latchen := apbi.pwdata(11); + end if; + if (gset = 1) then + v2.seten := apbi.pwdata(12); + end if; + if (gelatch /= 0) then + v2.elatchen := apbi.pwdata(13); + end if; + + for i in 1 to ntimers loop + + v.timers(i).enable := r.timers(i).enable or apbi.pwdata(15 + i); + + end loop; + + when "00011" => + + if (glatch=1) then + if (NAHBIRQ <= 32) then + + for i in NAHBIRQ - 1 downto 0 loop + + v2.latchsel(i) := apbi.pwdata(i); + + end loop; + + else + + for i in 31 downto 0 loop + + v2.latchsel(i) := apbi.pwdata(i); + + end loop; + + end if; + end if; + + when others => + + for i in 1 to ntimers loop + + if (conv_integer(apbi.paddr(6 downto 4)) = i) then + + case apbi.paddr(3 downto 2) is + + when "00" => + + v.timers(i).value := apbi.pwdata(nbits - 1 downto 0); + + when "01" => + + v.timers(i).reload := apbi.pwdata(nbits - 1 downto 0); + + when "10" => + + if (wdog /= 0 and i = ntimers) then + if (wdogwin /= 0) then + v.wdogwcr := apbi.pwdata(31 downto 16); + end if; + v.wdogdis := apbi.pwdata(8); + v.wdognmi := apbi.pwdata(7); + end if; + v.timers(i).chain := apbi.pwdata(5); + v.timers(i).irqpen := v.timers(i).irqpen and not apbi.pwdata(4); + v.timers(i).irqen := apbi.pwdata(3); + v.timers(i).load := apbi.pwdata(2); + v.timers(i).restart := apbi.pwdata(1); + v.timers(i).enable := apbi.pwdata(0); + + when others => + + end case; + + end if; + + end loop; + end case; + end if; --- timer latches - if glatch=1 then + -- timer latches + if (glatch=1) then latch := '0'; latchd := '0'; - if gelatch /= 0 and r2.elatchen = '1' then + if (gelatch /= 0 and r2.elatchen = '1') then latchval := gpti.latchv; end if; - if NAHBIRQ <= 32 then - for i in NAHBIRQ-1 downto 0 loop + if (NAHBIRQ <= 32) then + + for i in NAHBIRQ - 1 downto 0 loop + latch := latch or (v2.latchsel(i) and latchval(i)); - if gelatch = 2 then latchd := latchd or (v2.latchsel(i) and gpti.latchd(i)); end if; + if (gelatch = 2) then + latchd := latchd or (v2.latchsel(i) and gpti.latchd(i)); + end if; + end loop; + else + for i in 31 downto 0 loop + latch := latch or (v2.latchsel(i) and latchval(i)); - if gelatch = 2 then latchd := latchd or (v2.latchsel(i) and gpti.latchd(i)); end if; + if (gelatch = 2) then + latchd := latchd or (v2.latchsel(i) and gpti.latchd(i)); + end if; + end loop; + end if; - if gelatch /= 0 and (r2.latchen = '1' and r2.elatchen = '1') then - if latchd = '1' then + if (gelatch /= 0 and (r2.latchen = '1' and r2.elatchen = '1')) then + if (latchd = '1') then v2.latchdis := '1'; end if; - if r2.latchdis = '1' and r.tsel = 0 then + if (r2.latchdis = '1' and r.tsel = 0) then v2.latchdis := '0'; v2.latchen := '0'; v2.latchdel := '0'; end if; end if; if ((latch='1' and r2.latchen='1' and r.tsel = 0) or (r2.latchdel = '1' and r2.latchen='1' and r.tsel = 0)) then + for i in 1 to ntimers loop - v.timers(i).latch := r.timers(i).value(glatch*(nbits-1) downto 0); + + v.timers(i).latch := r.timers(i).value(glatch * (nbits - 1) downto 0); + end loop; + v2.latchdel := '0'; - if gelatch < 2 or (gelatch = 2 and (r2.elatchen = '0' or v2.latchdis = '1')) then + if (gelatch < 2 or (gelatch = 2 and (r2.elatchen = '0' or v2.latchdis = '1'))) then v2.latchen := '0'; - if gelatch = 2 then v2.latchdis := '0'; end if; + if (gelatch = 2) then + v2.latchdis := '0'; + end if; end if; - elsif latch='1' and r2.latchen='1' and r.tsel /= 0 then + elsif (latch='1' and r2.latchen='1' and r.tsel /= 0) then v2.latchdel := '1'; end if; end if; --- reset operation + -- reset operation + + if ((not RESET_ALL) and (rst = '0')) then - if (not RESET_ALL) and (rst = '0') then for i in 1 to ntimers loop + v.timers(i).enable := RESVAL.timers(i).enable; - v.timers(i).irqen := RESVAL.timers(i).irqen; + v.timers(i).irqen := RESVAL.timers(i).irqen; v.timers(i).irqpen := RESVAL.timers(i).irqpen; - v.timers(i).irq := RESVAL.timers(i).irq; + v.timers(i).irq := RESVAL.timers(i).irq; + end loop; - v.scaler := RESVAL.scaler; v.reload := RESVAL.reload; - v.tsel := RESVAL.tsel; v.dishlt := RESVAL.dishlt; - v.timers(ntimers).irq := RESVAL.timers(ntimers).irq; + + v.scaler := RESVAL.scaler; v.reload := RESVAL.reload; + v.tsel := RESVAL.tsel; v.dishlt := RESVAL.dishlt; + v.timers(ntimers).irq := RESVAL.timers(ntimers).irq; if (wdog /= 0) then - if ewdogen /= 0 then v.timers(ntimers).enable := gpti.wdogen; - else v.timers(ntimers).enable := RESVAL.timers(ntimers).enable; end if; - v.timers(ntimers).load := RESVAL.timers(ntimers).load; - v.timers(ntimers).reload := RESVAL.timers(ntimers).reload; - v.timers(ntimers).chain := RESVAL.timers(ntimers).chain; - v.timers(ntimers).irqen := RESVAL.timers(ntimers).irqen; - v.timers(ntimers).irqpen := RESVAL.timers(ntimers).irqpen; + if (ewdogen /= 0) then + v.timers(ntimers).enable := gpti.wdogen; + else + v.timers(ntimers).enable := RESVAL.timers(ntimers).enable; + end if; + v.timers(ntimers).load := RESVAL.timers(ntimers).load; + v.timers(ntimers).reload := RESVAL.timers(ntimers).reload; + v.timers(ntimers).chain := RESVAL.timers(ntimers).chain; + v.timers(ntimers).irqen := RESVAL.timers(ntimers).irqen; + v.timers(ntimers).irqpen := RESVAL.timers(ntimers).irqpen; v.timers(ntimers).restart := RESVAL.timers(ntimers).restart; end if; v.wdogdis := RESVAL.wdogdis; v.wdognmi := RESVAL.wdognmi; v.wdogwcr := RESVAL.wdogwcr; - if glatch = 1 then - for i in 1 to ntimers loop v.timers(i).latch := RESVAL.timers(i).latch; end loop; - if gelatch /= 0 then v2.elatchen := RESVAL2.elatchen; end if; - if gelatch = 2 then v2.setdis := '0'; v2.latchdis := '0'; end if; - v2.latchen := RESVAL2.latchen; v2.latchdel := RESVAL2.latchdel; + if (glatch = 1) then + + for i in 1 to ntimers loop + + v.timers(i).latch := RESVAL.timers(i).latch; + + end loop; + + if (gelatch /= 0) then + v2.elatchen := RESVAL2.elatchen; + end if; + if (gelatch = 2) then + v2.setdis := '0'; v2.latchdis := '0'; + end if; + v2.latchen := RESVAL2.latchen; v2.latchdel := RESVAL2.latchdel; v2.latchsel := RESVAL2.latchsel; end if; - if gextclk = 1 then + if (gextclk = 1) then v2.extclken := RESVAL2.extclken; - v2.extclk := RESVAL2.extclk; + v2.extclk := RESVAL2.extclk; + end if; + if (gset = 1) then + v2.seten := RESVAL2.seten; v2.setdel := RESVAL2.setdel; end if; - if gset = 1 then v2.seten := RESVAL2.seten; v2.setdel := RESVAL2.setdel; end if; end if; - if wdog = 0 then v.wdogdis := '0'; v.wdognmi := '0'; end if; - if wdogwin = 0 then v.wdogwc := (others => '0'); v.wdogwcr := (others => '0'); end if; - if glatch = 0 then - for i in 1 to ntimers loop v.timers(i).latch := (others => '0'); end loop; + + if (wdog = 0) then + v.wdogdis := '0'; v.wdognmi := '0'; + end if; + + if (wdogwin = 0) then + v.wdogwc := (others => '0'); v.wdogwcr := (others => '0'); + end if; + + if (glatch = 0) then + + for i in 1 to ntimers loop + + v.timers(i).latch := (others => '0'); + + end loop; + v2.latchen := '0'; v2.latchdel := '0'; v2.latchsel := (others => '0'); end if; - if glatch = 0 or gelatch = 0 then v2.elatchen := '0'; end if; - if glatch = 0 or gelatch < 2 then v2.latchdis := '0'; v2.setdis := '0'; end if; - if gextclk = 0 then v2.extclken := '0'; v2.extclk := (others => '0'); end if; - if gset = 0 then v2.seten := '0'; v2.setdel := '0'; end if; - - timer1 := (others => '0'); timer1(nbits-1 downto 0) := r.timers(1).value; - - rin <= v; rin2 <= v2; - apbo.prdata <= readdata; -- drive apb read bus - apbo.pirq <= xirq; + + if (glatch = 0 or gelatch = 0) then + v2.elatchen := '0'; + end if; + + if (glatch = 0 or gelatch < 2) then + v2.latchdis := '0'; v2.setdis := '0'; + end if; + + if (gextclk = 0) then + v2.extclken := '0'; v2.extclk := (others => '0'); + end if; + + if (gset = 0) then + v2.seten := '0'; v2.setdel := '0'; + end if; + + timer1 := (others => '0'); timer1(nbits - 1 downto 0) := r.timers(1).value; + + rin <= v; + rin2 <= v2; + apbo.prdata <= readdata; -- drive apb read bus + apbo.pirq <= xirq; apbo.pindex <= pindex; - gpto.tick <= r.tick & tick; - gpto.timer1 <= timer1; -- output timer1 value for debugging - gpto.wdogn <= r.wdogn; - gpto.wdog <= r.wdog; + gpto.tick <= r.tick & tick; + gpto.timer1 <= timer1; -- output timer1 value for debugging + gpto.wdogn <= r.wdogn; + gpto.wdog <= r.wdog; - end process; + end process comb; - apbo.pconfig <= pconfig; + apbo.pconfig <= PCONFIG; --- registers + -- registers - regs : process(clk) + regs : process (clk) is begin + if rising_edge(clk) then - r <= rin; r2 <= rin2; - if RESET_ALL and rst = '0' then - r <= RESVAL; r2 <= RESVAL2; - if wdog /= 0 and ewdogen /= 0 then + r <= rin; + r2 <= rin2; + if (RESET_ALL and rst = '0') then + r <= RESVAL; + r2 <= RESVAL2; + if (wdog /= 0 and ewdogen /= 0) then r.timers(ntimers).enable <= gpti.wdogen; end if; end if; end if; - end process; --- boot message + end process regs; + + -- boot message + + -- pragma translate_off + bootmsg : component report_version + generic map ( +"gptimer" & tost(pindex) & + ": Timer Unit rev " & tost(REVISION) & + ", " & tost(sbits) & "-bit scaler, " & tost(ntimers) & + " " & tost(nbits) & "-bit timers" & ", irq " & tost(pirq) + ); --- pragma translate_off - bootmsg : report_version - generic map ("gptimer" & tost(pindex) & - ": Timer Unit rev " & tost(REVISION) & - ", " & tost(sbits) & "-bit scaler, " & tost(ntimers) & - " " & tost(nbits) & "-bit timers" & ", irq " & tost(pirq)); -- pragma translate_on -end; +end architecture rtl; diff --git a/rtl/peripherals/uart/ahbuart.vhd b/rtl/peripherals/uart/ahbuart.vhd index ecf16f2acb..66e8914d20 100644 --- a/rtl/peripherals/uart/ahbuart.vhd +++ b/rtl/peripherals/uart/ahbuart.vhd @@ -16,66 +16,100 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------ +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +----------------------------------------------------------------------------- -- Entity: ahbuart -- File: ahbuart.vhd -- Author: Jiri Gaisler - Gaisler Research -- Description: UART with AHB master interface ------------------------------------------------------------------------------- +------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.misc.all; -use work.uart.all; -use work.libdcom.all; + use ieee.std_logic_1164.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.misc.all; + use work.uart.all; + use work.libdcom.all; entity ahbuart is generic ( - hindex : integer := 0; - pindex : integer := 0; - paddr : integer := 0; - pmask : integer := 16#fff# + hindex : integer := 0; + pindex : integer := 0; + paddr : integer := 0; + pmask : integer := 16#fff# ); port ( - rst : in std_ulogic; - clk : in std_ulogic; - uarti : in uart_in_type; - uarto : out uart_out_type; - apbi : in apb_slv_in_type; - apbo : out apb_slv_out_type; - ahbi : in ahb_mst_in_type; - ahbo : out ahb_mst_out_type ); -end; + rst : in std_ulogic; + clk : in std_ulogic; + uarti : in uart_in_type; + uarto : out uart_out_type; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type; + ahbi : in ahb_mst_in_type; + ahbo : out ahb_mst_out_type + ); +end entity ahbuart; architecture struct of ahbuart is -constant REVISION : integer := 0; + constant REVISION : integer := 0; -signal dmai : ahb_dma_in_type; -signal dmao : ahb_dma_out_type; -signal duarti : dcom_uart_in_type; -signal duarto : dcom_uart_out_type; + signal dmai : ahb_dma_in_type; + signal dmao : ahb_dma_out_type; + signal duarti : dcom_uart_in_type; + signal duarto : dcom_uart_out_type; begin - ahbmst0 : ahbmst - generic map (hindex => hindex, venid => VENDOR_GAISLER, devid => GAISLER_AHBUART) - port map (rst, clk, dmai, dmao, ahbi, ahbo); + ahbmst0 : component ahbmst + generic map ( + hindex => hindex, venid => VENDOR_GAISLER, devid => GAISLER_AHBUART + ) + port map ( +rst, + clk, + dmai, + dmao, + ahbi, + ahbo + ); + + dcom_uart0 : component dcom_uart + generic map ( +pindex, paddr, pmask + ) + port map ( +rst, + clk, + uarti, + uarto, + apbi, + apbo, + duarti, + duarto + ); - dcom_uart0 : dcom_uart generic map (pindex, paddr, pmask) - port map (rst, clk, uarti, uarto, apbi, apbo, duarti, duarto); + dcom0 : component dcom + port map ( +rst, + clk, + dmai, + dmao, + duarti, + duarto, + ahbi + ); - dcom0 : dcom port map (rst, clk, dmai, dmao, duarti, duarto, ahbi); + -- pragma translate_off + bootmsg : component report_version + generic map ( +"ahbuart" & tost(pindex) & + ": AHB Debug UART rev " & tost(REVISION) + ); --- pragma translate_off - bootmsg : report_version - generic map ("ahbuart" & tost(pindex) & - ": AHB Debug UART rev " & tost(REVISION)); -- pragma translate_on -end; +end architecture struct; diff --git a/rtl/peripherals/video/svga2tfp410.vhd b/rtl/peripherals/video/svga2tfp410.vhd index 9aa62b9d50..ddc68b4f1c 100644 --- a/rtl/peripherals/video/svga2tfp410.vhd +++ b/rtl/peripherals/video/svga2tfp410.vhd @@ -22,57 +22,57 @@ ------------------------------------------------------------------------------- library ieee; -use ieee.std_logic_1164.all; - -use work.misc.all; -use work.stdlib.all; + use ieee.std_logic_1164.all; + use work.misc.all; + use work.stdlib.all; -- pragma translate_off + library unisim; -use unisim.BUFG; --- pragma translate_on -use work.gencomp.all; -use work.svga_pkg.all; + use unisim.bufg; + -- pragma translate_on + use work.gencomp.all; + use work.svga_pkg.all; entity svga2tfp410 is - generic ( - tech : integer := 0 - ); + tech : integer := 0 + ); port ( - clk : in std_ulogic; - rstn : in std_ulogic; - vgao : in apbvga_out_type; - vgaclk_fb : in std_ulogic; - vgaclk : out std_ulogic; - idck_p : out std_ulogic; - idck_n : out std_ulogic; - data : out std_logic_vector(23 downto 0); - hsync : out std_ulogic; - vsync : out std_ulogic; - de : out std_ulogic; - dken : out std_ulogic; - ctl1_a1_dk1 : out std_ulogic; - ctl2_a2_dk2 : out std_ulogic; - a3_dk3 : out std_ulogic; - isel : out std_ulogic; - bsel : out std_ulogic; - dsel : out std_ulogic; - edge : out std_ulogic; - npd : out std_ulogic - ); - -end svga2tfp410; + clk : in std_ulogic; + rstn : in std_ulogic; + vgao : in apbvga_out_type; + vgaclk_fb : in std_ulogic; + vgaclk : out std_ulogic; + idck_p : out std_ulogic; + idck_n : out std_ulogic; + data : out std_logic_vector(23 downto 0); + hsync : out std_ulogic; + vsync : out std_ulogic; + de : out std_ulogic; + dken : out std_ulogic; + ctl1_a1_dk1 : out std_ulogic; + ctl2_a2_dk2 : out std_ulogic; + a3_dk3 : out std_ulogic; + isel : out std_ulogic; + bsel : out std_ulogic; + dsel : out std_ulogic; + edge : out std_ulogic; + npd : out std_ulogic + ); +end entity svga2tfp410; architecture rtl of svga2tfp410 is - component BUFG + component bufg is port ( - O : out std_logic; - I : in std_logic - ); + o : out std_logic; + i : in std_logic + ); end component; - signal red, green, blue : std_logic_vector(7 downto 0); + signal red : std_logic_vector(7 downto 0); + signal green : std_logic_vector(7 downto 0); + signal blue : std_logic_vector(7 downto 0); signal clk40 : std_ulogic; @@ -93,26 +93,26 @@ begin -- rtl a3_dk3 <= '0'; -- Disable I2C - isel <= '0'; + isel <= '0'; -- 24-bits color schime single edge - bsel <= '1'; + bsel <= '1'; -- Single-ended clock - dsel <= '0'; + dsel <= '0'; -- sample at risign edge - edge <= '1'; + edge <= '1'; -- normal operation (Use '0' for powerdown. Could be dynamically set from SVGA) - npd <= '1'; + npd <= '1'; ----------------------------------------------------------------------------- -- RGB data ----------------------------------------------------------------------------- - red <= vgao.video_out_r; + red <= vgao.video_out_r; green <= vgao.video_out_g; - blue <= vgao.video_out_b; + blue <= vgao.video_out_b; data <= red & green & blue; @@ -120,25 +120,38 @@ begin -- rtl -- Sync signals ----------------------------------------------------------------------------- - process (vgaclk_fb) + process (vgaclk_fb) is begin -- process + if rising_edge(vgaclk_fb) then hsync <= vgao.hsync; vsync <= vgao.vsync; de <= vgao.blank; end if; + end process; ----------------------------------------------------------------------------- -- Clock generation ----------------------------------------------------------------------------- - ddroreg_p : ddr_oreg generic map (tech) - port map (q => idck_p, c1 => vgaclk_fb, c2 => gnd, ce => vcc, - d1 => vcc, d2 => gnd, r => gnd, s => gnd); + ddroreg_p : component ddr_oreg + generic map ( +tech + ) + port map ( + q => idck_p, + c1 => vgaclk_fb, + c2 => gnd, + ce => vcc, + d1 => vcc, + d2 => gnd, + r => gnd, + s => gnd + ); -- Differential clock - --ddroreg_n : ddr_oreg generic map (tech) + -- ddroreg_n : ddr_oreg generic map (tech) -- port map (q => idck_n, c1 => vgaclk_fb, c2 => gnd, ce => vcc, -- d1 => gnd, d2 => vcc, r => gnd, s => gnd); @@ -147,18 +160,21 @@ begin -- rtl -- Clock selection is disabled: we only support 40MHz pixel clock to reduce -- clock resources usage. - clkdiv : process(clk, rstn) + clkdiv : process (clk, rstn) is begin - if rstn = '0' then + + if (rstn = '0') then clk40 <= '0'; elsif rising_edge(clk) then clk40 <= not clk40; end if; - end process; - bufg0 : BUFG + end process clkdiv; + + bufg0 : component bufg port map ( - I => clk40, - O => vgaclk); + i => clk40, + o => vgaclk + ); -end rtl; +end architecture rtl; diff --git a/rtl/sim/models/ahbram_sim.vhd b/rtl/sim/models/ahbram_sim.vhd index 78694e2b86..5b90f82ca4 100644 --- a/rtl/sim/models/ahbram_sim.vhd +++ b/rtl/sim/models/ahbram_sim.vhd @@ -29,216 +29,297 @@ -- pragma translate_off library ieee; -use ieee.std_logic_1164.all; -use std.textio.all; -use IEEE.Numeric_Std.all; - -use work.config_types.all; -use work.config.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.stdio.all; - -use work.gencomp.all; + use ieee.std_logic_1164.all; + use std.textio.all; + use ieee.numeric_std.all; + use work.config_types.all; + use work.config.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.stdio.all; + use work.gencomp.all; entity ahbram_sim is generic ( - hindex : integer := 0; - tech : integer := DEFMEMTECH; - kbytes : integer := 1; - pipe : integer := 0; - maccsz : integer := AHBDW; - endianness : integer := 0; --0 access as BE - --1 access as LE - fname : string := "ram.dat" - ); + hindex : integer := 0; + tech : integer := DEFMEMTECH; + kbytes : integer := 1; + pipe : integer := 0; + maccsz : integer := AHBDW; + endianness : integer := 0; -- 0 access as BE + -- 1 access as LE + fname : string := "ram.dat" + ); port ( - rst : in std_ulogic; - clk : in std_ulogic; - haddr : in integer := 0; - hmask : in integer := 16#fff#; - ahbsi : in ahb_slv_in_type; - ahbso : out ahb_slv_out_type + rst : in std_ulogic; + clk : in std_ulogic; + haddr : in integer := 0; + hmask : in integer := 16#fff#; + ahbsi : in ahb_slv_in_type; + ahbso : out ahb_slv_out_type ); -end; +end entity ahbram_sim; architecture rtl of ahbram_sim is -constant dw : integer := maccsz; + constant DW : integer := maccsz; + + constant ABITS : integer := log2ext(kbytes) + 10 - log2(DW / 8); + + signal hconfig : ahb_config_type; + + type reg_type is record + hwrite : std_ulogic; + hready : std_ulogic; + hsel : std_ulogic; + addr : std_logic_vector(ABITS - 1 + log2(DW / 8) downto 0); + size : std_logic_vector(2 downto 0); + prdata : std_logic_vector((DW - 1) * pipe downto 0); + pwrite : std_ulogic; + pready : std_ulogic; + end record reg_type; + + constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; + constant RES : reg_type := + ( + hwrite => '0', + hready => '1', + hsel => '0', + addr => (others => '0'), + size => (others => '0'), + prdata => (others => '0'), + pwrite => '0', + pready => '1' + ); -constant abits : integer := log2ext(kbytes) + 10 - log2(dw/8); + signal r, c : reg_type; + signal ramsel : std_logic_vector(DW / 8 - 1 downto 0); + signal write : std_logic_vector(DW / 8 - 1 downto 0); + signal ramaddr : std_logic_vector(ABITS - 1 downto 0); + signal ramdata : std_logic_vector(DW - 1 downto 0); + signal hwdata : std_logic_vector(DW - 1 downto 0); -signal hconfig : ahb_config_type; + type ram_type is array (0 to (2 ** ramaddr'length) - 1) of std_logic_vector(ramdata'range); -type reg_type is record - hwrite : std_ulogic; - hready : std_ulogic; - hsel : std_ulogic; - addr : std_logic_vector(abits-1+log2(dw/8) downto 0); - size : std_logic_vector(2 downto 0); - prdata : std_logic_vector((dw-1)*pipe downto 0); - pwrite : std_ulogic; - pready : std_ulogic; -end record; + signal ram : ram_type; + signal read_address : std_logic_vector(ramaddr'range); -constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; -constant RES : reg_type := - (hwrite => '0', hready => '1', hsel => '0', addr => (others => '0'), - size => (others => '0'), prdata => (others => '0'), pwrite => '0', - pready => '1'); +begin + hconfig <= + ( + 0 => ahb_device_reg (VENDOR_GAISLER, GAISLER_AHBRAM, 0, ABITS + 2 + maccsz / 64, 0), + 4 => ahb_membar(haddr, '1', '1', hmask), + others => zero32 + ); -signal r, c : reg_type; -signal ramsel : std_logic_vector(dw/8-1 downto 0); -signal write : std_logic_vector(dw/8-1 downto 0); -signal ramaddr : std_logic_vector(abits-1 downto 0); -signal ramdata : std_logic_vector(dw-1 downto 0); -signal hwdata : std_logic_vector(dw-1 downto 0); + comb : process (ahbsi, r, rst, ramdata) is + + variable bs : std_logic_vector(DW / 8 - 1 downto 0); + variable v : reg_type; + variable haddr : std_logic_vector(ABITS - 1 downto 0); + variable hrdata : std_logic_vector(DW - 1 downto 0); + variable wdata : std_logic_vector(DW - 1 downto 0); + variable seldata : std_logic_vector(DW - 1 downto 0); + variable raddr : std_logic_vector(3 downto 2); + variable adsel : std_logic; + + function reversedata ( + data : std_logic_vector; + step : integer + ) + return std_logic_vector is -type ram_type is array (0 to (2**ramaddr'length)-1) of std_logic_vector(ramdata'range); -signal ram : ram_type; -signal read_address : std_logic_vector(ramaddr'range); + variable rdata : std_logic_vector(data'length-1 downto 0); -begin + begin - hconfig <= ( - 0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_AHBRAM, 0, abits+2+maccsz/64, 0), - 4 => ahb_membar(haddr, '1', '1', hmask), - others => zero32); - - comb : process (ahbsi, r, rst, ramdata) - variable bs : std_logic_vector(dw/8-1 downto 0); - variable v : reg_type; - variable haddr : std_logic_vector(abits-1 downto 0); - variable hrdata : std_logic_vector(dw-1 downto 0); - variable wdata : std_logic_vector(dw-1 downto 0); - variable seldata : std_logic_vector(dw-1 downto 0); - variable raddr : std_logic_vector(3 downto 2); - variable adsel : std_logic; - - function reversedata(data : std_logic_vector; step : integer) - return std_logic_vector is - variable rdata: std_logic_vector(data'length-1 downto 0); - begin - for i in 0 to (data'length/step-1) loop - rdata(i*step+step-1 downto i*step) := data(data'length-i*step-1 downto data'length-i*step-step); - end loop; - return rdata; - end function reversedata; + for i in 0 to (data'length / step - 1) loop + + rdata(i * step + step - 1 downto i * step) := data(data'length-i * step - 1 downto data'length-i * step - step); + + end loop; + + return rdata; + + end function reversedata; begin - v := r; v.hready := '1'; bs := (others => '0'); + + v := r; v.hready := '1'; bs := (others => '0'); v.pready := r.hready; - if pipe=0 then + + if (pipe=0) then adsel := r.hwrite or not r.hready; else - adsel := r.hwrite or r.pwrite; + adsel := r.hwrite or r.pwrite; v.hready := r.hready or not r.pwrite; end if; - if adsel = '1' then - haddr := r.addr(abits-1+log2(dw/8) downto log2(dw/8)); + + if (adsel = '1') then + haddr := r.addr(ABITS - 1 + log2(DW / 8) downto log2(DW / 8)); else - haddr := ahbsi.haddr(abits-1+log2(dw/8) downto log2(dw/8)); - bs := (others => '0'); + haddr := ahbsi.haddr(ABITS - 1 + log2(DW / 8) downto log2(DW / 8)); + bs := (others => '0'); end if; + raddr := (others => '0'); v.pwrite := '0'; - if pipe/=0 and (r.hready='1' or r.pwrite='0') then - v.addr := ahbsi.haddr(abits-1+log2(dw/8) downto 0); + + if (pipe/=0 and (r.hready='1' or r.pwrite='0')) then + v.addr := ahbsi.haddr(ABITS - 1 + log2(DW / 8) downto 0); end if; - if ahbsi.hready = '1' then - if pipe=0 then - v.addr := ahbsi.haddr(abits-1+log2(dw/8) downto 0); + + if (ahbsi.hready = '1') then + if (pipe=0) then + v.addr := ahbsi.haddr(ABITS - 1 + log2(DW / 8) downto 0); end if; - v.hsel := ahbsi.hsel(hindex) and ahbsi.htrans(1); - v.size := ahbsi.hsize(2 downto 0); + v.hsel := ahbsi.hsel(hindex) and ahbsi.htrans(1); + v.size := ahbsi.hsize(2 downto 0); v.hwrite := ahbsi.hwrite and v.hsel; - if pipe = 1 and v.hsel = '1' and ahbsi.hwrite = '0' and (r.pready='1' or ahbsi.htrans(0)='0') then + if (pipe = 1 and v.hsel = '1' and ahbsi.hwrite = '0' and (r.pready='1' or ahbsi.htrans(0)='0')) then v.hready := '0'; v.pwrite := r.hwrite; end if; end if; - if r.hwrite = '1' then + if (r.hwrite = '1') then + case r.size is - when HSIZE_BYTE => - bs(bs'left-conv_integer(r.addr(log2(dw/16) downto 0))) := '1'; - when HSIZE_HWORD => - for i in 0 to dw/16-1 loop - if i = conv_integer(r.addr(log2(dw/16) downto 1)) then - bs(bs'left-i*2 downto bs'left-i*2-1) := (others => '1'); - end if; - end loop; -- i - when HSIZE_WORD => - if dw = 32 then bs := (others => '1'); - else - for i in 0 to dw/32-1 loop - if i = conv_integer(r.addr(log2(dw/8)-1 downto 2)) then - bs(bs'left-i*4 downto bs'left-i*4-3) := (others => '1'); - end if; - end loop; -- i - end if; - when HSIZE_DWORD => - if dw = 32 then null; - elsif dw = 64 then bs := (others => '1'); - else - for i in 0 to dw/64-1 loop - if i = conv_integer(r.addr(3)) then - bs(bs'left-i*8 downto bs'left-i*8-7) := (others => '1'); - end if; - end loop; -- i - end if; - when HSIZE_4WORD => - if dw < 128 then null; - elsif dw = 128 then bs := (others => '1'); - else - for i in 0 to dw/64-1 loop - if i = conv_integer(r.addr(3)) then - bs(bs'left-i*8 downto bs'left-i*8-7) := (others => '1'); + + when HSIZE_BYTE => + + bs(bs'left - conv_integer(r.addr(log2(dw / 16) downto 0))) := '1'; + + when HSIZE_HWORD => + + for i in 0 to DW / 16 - 1 loop + + if (i = conv_integer(r.addr(log2(DW / 16) downto 1))) then + bs(bs'left - i * 2 downto bs'left - i * 2 - 1) := (others => '1'); end if; - end loop; -- i - end if; - when others => --HSIZE_8WORD - if dw < 256 then null; - else bs := (others => '1'); end if; + + end loop; -- i + + when HSIZE_WORD => + + if (DW = 32) then + bs := (others => '1'); + else + + for i in 0 to DW / 32 - 1 loop + + if (i = conv_integer(r.addr(log2(DW / 8) - 1 downto 2))) then + bs(bs'left - i * 4 downto bs'left - i * 4 - 3) := (others => '1'); + end if; + + end loop; -- i + + end if; + + when HSIZE_DWORD => + + if (DW = 32) then + null; + elsif (DW = 64) then + bs := (others => '1'); + else + + for i in 0 to DW / 64 - 1 loop + + if (i = conv_integer(r.addr(3))) then + bs(bs'left - i * 8 downto bs'left - i * 8 - 7) := (others => '1'); + end if; + + end loop; -- i + + end if; + + when HSIZE_4WORD => + + if (DW < 128) then + null; + elsif (DW = 128) then + bs := (others => '1'); + else + + for i in 0 to DW / 64 - 1 loop + + if (i = conv_integer(r.addr(3))) then + bs(bs'left - i * 8 downto bs'left - i * 8 - 7) := (others => '1'); + end if; + + end loop; -- i + + end if; + + when others => -- HSIZE_8WORD + + if (DW < 256) then + null; + else + bs := (others => '1'); + end if; + end case; + v.hready := not (v.hsel and not ahbsi.hwrite); v.hwrite := v.hwrite and v.hready; end if; -- Duplicate read data on word basis, unless CORE_ACDM is enabled - if CORE_ACDM = 0 then - if dw = 32 then + if (CORE_ACDM = 0) then + if (DW = 32) then seldata := ramdata; - elsif dw = 64 then - if r.size = HSIZE_DWORD then seldata := ramdata; else - if r.addr(2) = '0' then - seldata(dw/2-1 downto 0) := ramdata(dw-1 downto dw/2); - else - seldata(dw/2-1 downto 0) := ramdata(dw/2-1 downto 0); - end if; - seldata(dw-1 downto dw/2) := seldata(dw/2-1 downto 0); + elsif (DW = 64) then + if (r.size = HSIZE_DWORD) then + seldata := ramdata; + else + if (r.addr(2) = '0') then + seldata(dw / 2 - 1 downto 0) := ramdata(DW - 1 downto DW / 2); + else + seldata(dw / 2 - 1 downto 0) := ramdata(DW / 2 - 1 downto 0); + end if; + seldata(dw - 1 downto dw / 2) := seldata(DW / 2 - 1 downto 0); end if; - elsif dw = 128 then - if r.size = HSIZE_4WORD then + elsif (DW = 128) then + if (r.size = HSIZE_4WORD) then seldata := ramdata; - elsif r.size = HSIZE_DWORD then - if r.addr(3) = '0' then seldata(dw/2-1 downto 0) := ramdata(dw-1 downto dw/2); - else seldata(dw/2-1 downto 0) := ramdata(dw/2-1 downto 0); end if; - seldata(dw-1 downto dw/2) := seldata(dw/2-1 downto 0); + elsif (r.size = HSIZE_DWORD) then + if (r.addr(3) = '0') then + seldata(dw / 2 - 1 downto 0) := ramdata(DW - 1 downto DW / 2); + else + seldata(dw / 2 - 1 downto 0) := ramdata(DW / 2 - 1 downto 0); + end if; + seldata(dw - 1 downto dw / 2) := seldata(DW / 2 - 1 downto 0); else raddr := r.addr(3 downto 2); + case raddr is - when "00" => seldata(dw/4-1 downto 0) := ramdata(4*dw/4-1 downto 3*dw/4); - when "01" => seldata(dw/4-1 downto 0) := ramdata(3*dw/4-1 downto 2*dw/4); - when "10" => seldata(dw/4-1 downto 0) := ramdata(2*dw/4-1 downto 1*dw/4); - when others => seldata(dw/4-1 downto 0) := ramdata(dw/4-1 downto 0); + + when "00" => + + seldata(dw / 4 - 1 downto 0) := ramdata(4 * DW / 4 - 1 downto 3 * DW / 4); + + when "01" => + + seldata(dw / 4 - 1 downto 0) := ramdata(3 * DW / 4 - 1 downto 2 * DW / 4); + + when "10" => + + seldata(dw / 4 - 1 downto 0) := ramdata(2 * DW / 4 - 1 downto 1 * DW / 4); + + when others => + + seldata(dw / 4 - 1 downto 0) := ramdata(DW / 4 - 1 downto 0); + end case; - seldata(dw-1 downto dw/4) := seldata(dw/4-1 downto 0) & - seldata(dw/4-1 downto 0) & - seldata(dw/4-1 downto 0); + + seldata(dw - 1 downto dw / 4) := seldata(DW / 4 - 1 downto 0) & + seldata(DW / 4 - 1 downto 0) & + seldata(DW / 4 - 1 downto 0); end if; else seldata := ahbselectdata(ramdata, r.addr(4 downto 2), r.size); @@ -247,35 +328,44 @@ begin seldata := ramdata; end if; - if pipe = 0 then + if (pipe = 0) then v.prdata := (others => '0'); - hrdata := seldata; + hrdata := seldata; else v.prdata := seldata; - hrdata := r.prdata; + hrdata := r.prdata; end if; wdata := ahbsi.hwdata; -- Revert endianness - if endianness = 1 then - hrdata := reversedata(hrdata, 8); - wdata := reversedata(wdata, 8); + if (endianness = 1) then + hrdata := reversedata(hrdata, 8); + wdata := reversedata(wdata, 8); end if; - if (not RESET_ALL) and (rst = '0') then + if ((not RESET_ALL) and (rst = '0')) then v.hwrite := RES.hwrite; v.hready := RES.hready; end if; - write <= bs; for i in 0 to dw/8-1 loop ramsel(i) <= v.hsel or r.hwrite; end loop; - ramaddr <= haddr; c <= v; + + write <= bs; + + for i in 0 to DW / 8 - 1 loop + + ramsel(i) <= v.hsel or r.hwrite; + + end loop; + + ramaddr <= haddr; + c <= v; ahbso.hrdata <= ahbdrivedata(hrdata); ahbso.hready <= r.hready; -- Select correct write data - hwdata <= ahbreaddata(wdata, r.addr(4 downto 2), conv_std_logic_vector(log2(dw/8), 3)); + hwdata <= ahbreaddata(wdata, r.addr(4 downto 2), conv_std_logic_vector(log2(DW / 8), 3)); - end process; + end process comb; ahbso.hresp <= "00"; ahbso.hsplit <= (others => '0'); @@ -283,35 +373,40 @@ begin ahbso.hconfig <= hconfig; ahbso.hindex <= hindex; --- aram : syncrambw generic map (tech, abits, dw, scantest) port map ( --- clk, ramaddr, hwdata, ramdata, ramsel, write, ahbsi.testin); - RamProc: process(clk) is - - variable L1 : line; - variable FIRST : boolean := true; - variable SECOND : boolean := false; - variable ADR : std_logic_vector(19 downto 0); - variable BUF : std_logic_vector(31 downto 0); - variable CH : character; - variable ai : integer := 0; - variable len : integer := 0; - variable wrd : integer := 0; - variable bts_pre : integer := 0; - variable bts_post : integer := 0; - file TCF : text open read_mode is fname; - variable rectype : std_logic_vector(3 downto 0); - variable recaddr : std_logic_vector(31 downto 0); - variable reclen : std_logic_vector(7 downto 0); - variable recdata : std_logic_vector(0 to 16*8-1); + -- aram : syncrambw generic map (tech, abits, dw, scantest) port map ( + -- clk, ramaddr, hwdata, ramdata, ramsel, write, ahbsi.testin); + ramproc : process (clk) is + + variable l1 : line; + variable first : boolean := true; + variable second : boolean := false; + variable adr : std_logic_vector(19 downto 0); + variable buf : std_logic_vector(31 downto 0); + variable ch : character; + variable ai : integer := 0; + variable len : integer := 0; + variable wrd : integer := 0; + variable bts_pre : integer := 0; + variable bts_post : integer := 0; + file TCF : text open read_mode is fname; + variable rectype : std_logic_vector(3 downto 0); + variable recaddr : std_logic_vector(31 downto 0); + variable reclen : std_logic_vector(7 downto 0); + variable recdata : std_logic_vector(0 to 16 * 8 - 1); begin + if rising_edge(clk) then - if conv_integer(write) > 0 then - for i in 0 to dw/8-1 loop - if (write(i) = '1') then - ram(to_integer(unsigned(ramaddr)))(i*8+7 downto i*8) <= hwdata(i*8+7 downto i*8); - end if; + if (conv_integer(write) > 0) then + + for i in 0 to DW / 8 - 1 loop + + if (write(i) = '1') then + ram(to_integer(unsigned(ramaddr)))(i * 8 + 7 downto i * 8) <= hwdata(i * 8 + 7 downto i * 8); + end if; + end loop; + end if; read_address <= ramaddr; end if; @@ -323,90 +418,118 @@ begin -- SECOND := false; -- end if; - if (rst = '0') and (FIRST = true) then - ram <= (others => (others => '0')); - SECOND := true; + if ((rst = '0') and (first = true)) then + ram <= (others => (others => '0')); + second := true; + + l1 := new string'(""); - L1:= new string'(""); while not endfile(TCF) loop - readline(TCF,L1); - if (L1'length /= 0) then --' - while (not (L1'length=0)) and (L1(L1'left) = ' ') loop - std.textio.read(L1,CH); + + readline(TCF, L1); + if (l1'length /= 0) then -- ' + + while (not (l1'length=0)) and (L1(l1'left) = ' ') loop + + std.textio.read(L1, CH); + end loop; - if L1'length > 0 then --' + if (l1'length > 0) then -- ' read(L1, ch); - if (ch = 'S') or (ch = 's') then + if ((ch = 'S') or (ch = 's')) then hread(L1, rectype); hread(L1, reclen); recaddr := (others => '0'); + case rectype is + when "0001" => + hread(L1, recaddr(15 downto 0)); - len := conv_integer(reclen)-3; + len := conv_integer(reclen) - 3; + when "0010" => + hread(L1, recaddr(23 downto 0)); - len := conv_integer(reclen)-4; + len := conv_integer(reclen) - 4; + when "0011" => + hread(L1, recaddr); - len := conv_integer(reclen)-5; - when others => next; + len := conv_integer(reclen) - 5; + + when others => + + next; + end case; - hread(L1, recdata(0 to len*8-1)); - recaddr(31 downto abits+log2(dw/8)) := (others => '0'); - ai := conv_integer(recaddr)/(dw/8); - bts_pre := ((dw/8) - (conv_integer(recaddr) mod (dw/8))) mod (dw/8); - len := len - bts_pre; - wrd := len / (dw/8); - bts_post := len mod (dw/8); + hread(L1, recdata(0 to len * 8 - 1)); + + recaddr(31 downto abits + log2(dw / 8)) := (others => '0'); + ai := conv_integer(recaddr) / (DW / 8); + bts_pre := ((DW / 8) - (conv_integer(recaddr) mod (DW / 8))) mod (DW / 8); + len := len - bts_pre; + wrd := len / (DW / 8); + bts_post := len mod (DW / 8); for i in bts_pre - 1 downto 0 loop + ram(ai)((i + 1) * 8 - 1 downto i * 8) <= recdata((bts_pre - i - 1) * 8 to (bts_pre - i) * 8 - 1); - end loop; -- i - if bts_pre /= 0 then + end loop; -- i + + if (bts_pre /= 0) then ai := ai + 1; end if; - for i in 0 to wrd-1 loop - ram(ai+i) <= recdata(i*dw + bts_pre * 8 to i*dw+dw-1 + bts_pre * 8); + for i in 0 to wrd - 1 loop + + ram(ai + i) <= recdata(i * DW + bts_pre * 8 to i * DW + DW - 1 + bts_pre * 8); + end loop; for i in 0 to bts_post - 1 loop - ram(ai + wrd)(dw - i * 8 - 1 downto dw - (i + 1) * 8) <= recdata(wrd * dw + (bts_pre + i) * 8 to wrd * dw + (bts_pre + i + 1) * 8 - 1); - end loop; -- i - if ai = 0 then + ram(ai + wrd)(dw - i * 8 - 1 downto dw - (i + 1) * 8) <= recdata(wrd * DW + (bts_pre + i) * 8 to wrd * DW + (bts_pre + i + 1) * 8 - 1); + + end loop; -- i + + if (ai = 0) then ai := 1; end if; end if; end if; end if; - end loop; - FIRST := false; + end loop; + first := false; end if; - end process RamProc; + end process ramproc; ramdata <= ram(to_integer(unsigned(read_address))); - reg : process (clk) + reg : process (clk) is begin + if rising_edge(clk) then r <= c; - if RESET_ALL and rst = '0' then + if (RESET_ALL and rst = '0') then r <= RES; end if; end if; - end process; - bootmsg : report_version - generic map ("ahbram" & tost(hindex) & - ": AHB SRAM Module rev 1, " & tost(kbytes) & " kbytes"); -end; + end process reg; + + bootmsg : component report_version + generic map ( +"ahbram" & tost(hindex) & + ": AHB SRAM Module rev 1, " & tost(kbytes) & " kbytes" + ); + +end architecture rtl; -- pragma translate_on diff --git a/rtl/sim/tb/tb_iolink.vhd b/rtl/sim/tb/tb_iolink.vhd index 4dc1b2cf78..2df4f7e762 100644 --- a/rtl/sim/tb/tb_iolink.vhd +++ b/rtl/sim/tb/tb_iolink.vhd @@ -2,29 +2,30 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.esp_global.all; -use work.stdlib.all; --- pragma translate_off -use work.sim.all; -use std.textio.all; -use work.stdio.all; --- pragma translate_on -use work.tb_pkg.all; -use work.esp_global.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.esp_global.all; + use work.stdlib.all; + -- pragma translate_off + use work.sim.all; + use std.textio.all; + use work.stdio.all; + -- pragma translate_on + use work.tb_pkg.all; + use work.esp_global.all; entity tb_iolink is port ( - reset : in std_ulogic; - iolink_clk_in_int : in std_ulogic; - iolink_valid_in_int : in std_ulogic; - iolink_data_in_int : in std_logic_vector(CFG_IOLINK_BITS - 1 downto 0); - iolink_clk_out_int : in std_ulogic; - iolink_credit_out_int : out std_ulogic; - iolink_valid_out_int : out std_ulogic; - iolink_data_out_int : out std_logic_vector(CFG_IOLINK_BITS - 1 downto 0); - iolink_data_oen : out std_ulogic); + reset : in std_ulogic; + iolink_clk_in_int : in std_ulogic; + iolink_valid_in_int : in std_ulogic; + iolink_data_in_int : in std_logic_vector(CFG_IOLINK_BITS - 1 downto 0); + iolink_clk_out_int : in std_ulogic; + iolink_credit_out_int : out std_ulogic; + iolink_valid_out_int : out std_ulogic; + iolink_data_out_int : out std_logic_vector(CFG_IOLINK_BITS - 1 downto 0); + iolink_data_oen : out std_ulogic + ); end entity tb_iolink; architecture rtl of tb_iolink is @@ -42,10 +43,10 @@ begin --------------------------------------------------------------------------- -- Basic testbench for ESP SoC using IOLink --------------------------------------------------------------------------- - test_iolink : process + test_iolink : process is file bootloader : text open read_mode is "../soft-build/" & CPU_STR & "/prom.txt"; - --file program : text open read_mode is "../soft-build/ariane/systest.txt"; + -- file program : text open read_mode is "../soft-build/ariane/systest.txt"; variable text_word, text_data : line; variable word_var : std_logic_vector(31 downto 0); @@ -67,70 +68,71 @@ begin -- TEST of CSR Read through IOLink; uncomment to run -- send address - --word <= X"000000006009078D"; - --snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); + -- word <= X"000000006009078D"; + -- snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); -- send length - --word <= X"0000000000000001"; - --snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); + -- word <= X"0000000000000001"; + -- snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); - --word <= X"0000000000014085"; - --snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); + -- word <= X"0000000000014085"; + -- snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); - --iolink_data_oen <= '0'; + -- iolink_data_oen <= '0'; - --while true loop + -- while true loop -- wait until rising_edge(iolink_clk_in_int); -- if iolink_valid_in_int = '1' then -- word(15 downto 0) <= iolink_data_in_int; -- exit; -- end if; - --end loop; + -- end loop; - --while true loop + -- while true loop -- wait until rising_edge(iolink_clk_in_int); -- if iolink_valid_in_int = '1' then -- word(31 downto 16) <= iolink_data_in_int; -- exit; -- end if; - --end loop; + -- end loop; - --while true loop + -- while true loop -- wait until rising_edge(iolink_clk_in_int); -- if iolink_valid_in_int = '1' then -- word(47 downto 32) <= iolink_data_in_int; -- exit; -- end if; - --end loop; + -- end loop; - --while true loop + -- while true loop -- wait until rising_edge(iolink_clk_in_int); -- if iolink_valid_in_int = '1' then -- word(63 downto 48) <= iolink_data_in_int; -- exit; -- end if; - --end loop; + -- end loop; - --wait until rising_edge(iolink_clk_out_int); - --iolink_credit_out_int <= '1'; - --wait until rising_edge(iolink_clk_out_int); - --iolink_credit_out_int <= '0'; - --iolink_data_oen <= '1'; + -- wait until rising_edge(iolink_clk_out_int); + -- iolink_credit_out_int <= '1'; + -- wait until rising_edge(iolink_clk_out_int); + -- iolink_credit_out_int <= '0'; + -- iolink_data_oen <= '1'; - --wait for 0.2 ns; - - --report "word: " & integer'image(to_integer(unsigned(word))); + -- wait for 0.2 ns; + -- report "word: " & integer'image(to_integer(unsigned(word))); --------------------------------------------------------------------------- -- send first 2 soft resets --------------------------------------------------------------------------- for i in 0 to 1 loop + -- send address - if CPU_STR = "leon3" then + if (CPU_STR = "leon3") then word <= X"80000401"; else word <= X"60000401"; end if; + snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); -- send length word <= X"00000001"; @@ -139,19 +141,21 @@ begin word <= X"00000001"; snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); wait for 100000 ns; - end loop; -- i + + end loop; -- i --------------------------------------------------------------------------- -- Send bootloader binary --------------------------------------------------------------------------- -- send address - if CPU_STR = "ibex" then + if (CPU_STR = "ibex") then word <= X"00000081"; - elsif CPU_STR = "ariane" then + elsif (CPU_STR = "ariane") then word <= X"00010001"; else word <= X"00000001"; end if; + snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); -- send length readline(bootloader, text_word); @@ -160,47 +164,50 @@ begin snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); -- send data while not endfile(bootloader) loop + readline(bootloader, text_word); hread(text_word, word_var, ok); word <= word_var; snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); + end loop; --------------------------------------------------------------------------- -- Send program binary --------------------------------------------------------------------------- -- send address - --word <= X"0000000080000001"; - --snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); + -- word <= X"0000000080000001"; + -- snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); -- send length - --readline(program, text_word); - --hread(text_word, word_var, ok); - --program_length := to_integer(unsigned(word_var)); - --word <= word_var + X"3e8"; -- add 0s at the end of the prorgam (TODO is it needed?) - --snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); + -- readline(program, text_word); + -- hread(text_word, word_var, ok); + -- program_length := to_integer(unsigned(word_var)); + -- word <= word_var + X"3e8"; -- add 0s at the end of the prorgam (TODO is it needed?) + -- snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); -- send data - --while not endfile(program) loop + -- while not endfile(program) loop -- readline(program, text_word); -- hread(text_word, word_var, ok); -- word <= word_var; -- snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); - --end loop; - --word <= X"0000000000000000"; -- add 0s at the end of the prorgam (TODO is it needed?) - --for i in 0 to 999 loop + -- end loop; + -- word <= X"0000000000000000"; -- add 0s at the end of the prorgam (TODO is it needed?) + -- for i in 0 to 999 loop -- snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); - --end loop; - + -- end loop; --------------------------------------------------------------------------- -- Send last 2 soft resets --------------------------------------------------------------------------- for i in 0 to 1 loop + -- send address - if CPU_STR = "leon3" then + if (CPU_STR = "leon3") then word <= X"80000401"; else word <= X"60000401"; end if; + snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); -- send length word <= X"00000001"; @@ -209,8 +216,11 @@ begin word <= X"00000001"; snd_flit_iolink(iolink_clk_out_int, word, valid_out, data_out); wait for 100000 ns; - end loop; -- i - end process; - -- pragma translate_on + + end loop; -- i + + end process test_iolink; + +-- pragma translate_on end architecture rtl; diff --git a/rtl/sim/utils/cpu_disas.vhd b/rtl/sim/utils/cpu_disas.vhd index 925a0cab0e..fca77fb287 100644 --- a/rtl/sim/utils/cpu_disas.vhd +++ b/rtl/sim/utils/cpu_disas.vhd @@ -16,120 +16,131 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------- --- Package: cpu_disas --- File: cpu_disas.vhd --- Author: Jiri Gaisler, Gaisler Research --- Description: SPARC disassembler according to SPARC V8 manual +-- Package: cpu_disas +-- File: cpu_disas.vhd +-- Author: Jiri Gaisler, Gaisler Research +-- Description: SPARC disassembler according to SPARC V8 manual ------------------------------------------------------------------------------ -- pragma translate_off library ieee; -use ieee.std_logic_1164.all; -use work.stdlib.all; -use work.sparc.all; -use work.sparc_disas.all; + use ieee.std_logic_1164.all; + use work.stdlib.all; + use work.sparc.all; + use work.sparc_disas.all; entity cpu_disas is -port ( - clk : in std_ulogic; - rstn : in std_ulogic; - dummy : out std_ulogic; - inst : in std_logic_vector(31 downto 0); - pc : in std_logic_vector(31 downto 2); - result: in std_logic_vector(31 downto 0); - index : in std_logic_vector(3 downto 0); - wreg : in std_ulogic; - annul : in std_ulogic; - holdn : in std_ulogic; - pv : in std_ulogic; - trap : in std_ulogic; - disas : in std_ulogic); -end; + port ( + clk : in std_ulogic; + rstn : in std_ulogic; + dummy : out std_ulogic; + inst : in std_logic_vector(31 downto 0); + pc : in std_logic_vector(31 downto 2); + result : in std_logic_vector(31 downto 0); + index : in std_logic_vector(3 downto 0); + wreg : in std_ulogic; + annul : in std_ulogic; + holdn : in std_ulogic; + pv : in std_ulogic; + trap : in std_ulogic; + disas : in std_ulogic + ); +end entity cpu_disas; architecture behav of cpu_disas is + begin dummy <= '1'; - trc : process(clk) - variable valid : boolean; - variable op : std_logic_vector(1 downto 0); - variable op3 : std_logic_vector(5 downto 0); - variable fpins, fpld : boolean; - variable iindex : integer; + trc : process (clk) is + + variable valid : boolean; + variable op : std_logic_vector(1 downto 0); + variable op3 : std_logic_vector(5 downto 0); + variable fpins, fpld : boolean; + variable iindex : integer; + begin - iindex := conv_integer(index); - op := inst(31 downto 30); op3 := inst(24 downto 19); - fpins := (op = FMT3) and ((op3 = FPOP1) or (op3 = FPOP2)); - fpld := (op = LDST) and ((op3 = LDF) or (op3 = LDDF) or (op3 = LDFSR)); - valid := (((not annul) and pv) = '1'); --and (not ((fpins or fpld) and (trap = '0'))); - valid := valid and (holdn = '1'); - if rising_edge(clk) and (rstn = '1') then - print_insn (iindex, pc(31 downto 2) & "00", inst, + + iindex := conv_integer(index); + op := inst(31 downto 30); op3 := inst(24 downto 19); + fpins := (op = FMT3) and ((op3 = FPOP1) or (op3 = FPOP2)); + fpld := (op = LDST) and ((op3 = LDF) or (op3 = LDDF) or (op3 = LDFSR)); + valid := (((not annul) and pv) = '1'); -- and (not ((fpins or fpld) and (trap = '0'))); + valid := valid and (holdn = '1'); + + if (rising_edge(clk) and (rstn = '1')) then + print_insn (iindex, pc(31 downto 2) & "00", inst, result, valid, trap = '1', wreg = '1' - ); + ); end if; - end process; -end; - + end process trc; + +end architecture behav; library ieee; -use ieee.std_logic_1164.all; -use work.stdlib.all; -use work.sparc.all; -use work.sparc_disas.all; + use ieee.std_logic_1164.all; + use work.stdlib.all; + use work.sparc.all; + use work.sparc_disas.all; entity fpu_disas is -port ( - clk : in std_ulogic; - rstn : in std_ulogic; - dummy : out std_ulogic; - wr2inst : in std_logic_vector(31 downto 0); - wr2pc : in std_logic_vector(31 downto 2); - divinst : in std_logic_vector(31 downto 0); - divpc : in std_logic_vector(31 downto 2); - dbg_wrdata: in std_logic_vector(63 downto 0); - index : in std_logic_vector(3 downto 0); - dbg_wren : in std_logic_vector(1 downto 0); - resv : in std_ulogic; - ld : in std_ulogic; - rdwr : in std_ulogic; - ccwr : in std_ulogic; - rdd : in std_ulogic; - div_valid : in std_ulogic; - holdn : in std_ulogic; - disas : in std_ulogic); -end; + port ( + clk : in std_ulogic; + rstn : in std_ulogic; + dummy : out std_ulogic; + wr2inst : in std_logic_vector(31 downto 0); + wr2pc : in std_logic_vector(31 downto 2); + divinst : in std_logic_vector(31 downto 0); + divpc : in std_logic_vector(31 downto 2); + dbg_wrdata : in std_logic_vector(63 downto 0); + index : in std_logic_vector(3 downto 0); + dbg_wren : in std_logic_vector(1 downto 0); + resv : in std_ulogic; + ld : in std_ulogic; + rdwr : in std_ulogic; + ccwr : in std_ulogic; + rdd : in std_ulogic; + div_valid : in std_ulogic; + holdn : in std_ulogic; + disas : in std_ulogic + ); +end entity fpu_disas; architecture behav of fpu_disas is + begin dummy <= '1'; - trc : process(clk) - variable valid : boolean; - variable op : std_logic_vector(1 downto 0); - variable op3 : std_logic_vector(5 downto 0); - variable fpins, fpld : boolean; - variable iindex : integer; + trc : process (clk) is + + variable valid : boolean; + variable op : std_logic_vector(1 downto 0); + variable op3 : std_logic_vector(5 downto 0); + variable fpins, fpld : boolean; + variable iindex : integer; + begin + iindex := conv_integer(index); - if rising_edge(clk) and (rstn = '1') then - valid := ((((rdwr and not ld) or ccwr or (ld and resv)) and holdn) = '1'); - print_fpinsn(0, wr2pc(31 downto 2) & "00", wr2inst, dbg_wrdata, - (rdd = '1'), valid, false, (dbg_wren /= "00")); - print_fpinsn(0, divpc(31 downto 2) & "00", divinst, dbg_wrdata, - (rdd = '1'), (div_valid and holdn) = '1', false, (dbg_wren /= "00")); + if (rising_edge(clk) and (rstn = '1')) then + valid := ((((rdwr and not ld) or ccwr or (ld and resv)) and holdn) = '1'); + print_fpinsn(0, wr2pc(31 downto 2) & "00", wr2inst, dbg_wrdata, + (rdd = '1'), valid, false, (dbg_wren /= "00")); + print_fpinsn(0, divpc(31 downto 2) & "00", divinst, dbg_wrdata, + (rdd = '1'), (div_valid and holdn) = '1', false, (dbg_wren /= "00")); end if; - end process; -end; + end process trc; +end architecture behav; -- pragma translate_on diff --git a/rtl/sockets/adapters/ahb2axi_l.vhd b/rtl/sockets/adapters/ahb2axi_l.vhd index ffc4788090..2d25d02aab 100644 --- a/rtl/sockets/adapters/ahb2axi_l.vhd +++ b/rtl/sockets/adapters/ahb2axi_l.vhd @@ -25,40 +25,38 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - ---pragma translate_off -use STD.textio.all; -use ieee.std_logic_textio.all; ---pragma translate_on - -use work.config_types.all; -use work.config.all; -use work.stdlib.all; -use work.amba.all; -use work.sld_devices.all; -use work.devices.all; - -use work.gencomp.all; - + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + + -- pragma translate_off + use std.textio.all; + use ieee.std_logic_textio.all; + -- pragma translate_on + use work.config_types.all; + use work.config.all; + use work.stdlib.all; + use work.amba.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; entity ahb2axi_l is generic ( hindex : integer := 0; hconfig : ahb_config_type; - aximid : integer range 0 to 15 := 0; --AXI master transaction ID + aximid : integer range 0 to 15 := 0; -- AXI master transaction ID axisecure : boolean := true; - scantest : integer := 0); + scantest : integer := 0 + ); port ( - rst : in std_logic; - clk : in std_logic; - ahbsi : in ahb_slv_in_type; - ahbso : out ahb_slv_out_type; - aximi : in axi_somi_type; - aximo : out axi_mosi_type); -end ahb2axi_l; - + rst : in std_logic; + clk : in std_logic; + ahbsi : in ahb_slv_in_type; + ahbso : out ahb_slv_out_type; + aximi : in axi_somi_type; + aximo : out axi_mosi_type + ); +end entity ahb2axi_l; architecture rtl of ahb2axi_l is @@ -67,24 +65,23 @@ architecture rtl of ahb2axi_l is type ahb_slv_out_local_type is record hready : std_ulogic; hresp : std_logic_vector(1 downto 0); - hrdata : std_logic_vector(AHBDW-1 downto 0); - end record; - + hrdata : std_logic_vector(AHBDW - 1 downto 0); + end record ahb_slv_out_local_type; type reg_type is record state : ahb_to_axi_state; ahbsout : ahb_slv_out_local_type; aximout : axi_mosi_type; - addr_strb : std_logic_vector(log2(AXIDW/8)-1 downto 0); + addr_strb : std_logic_vector(log2(AXIDW / 8) - 1 downto 0); read_error : std_logic; read_validated : std_logic; write_error : std_logic; wr_word_valid : std_logic; write_validated : std_logic; - end record; + end record reg_type; - - constant rac_reset : axi_ar_mosi_type := ( + constant RAC_RESET : axi_ar_mosi_type := + ( id => (others => '0'), addr => (others => '0'), len => (others => '0'), @@ -96,12 +93,16 @@ architecture rtl of ahb2axi_l is qos => (others => '0'), region => (others => '0'), user => (others => '0'), - valid => '0'); + valid => '0' + ); - constant rdc_reset : axi_r_mosi_type := ( - ready => '0'); + constant RDC_RESET : axi_r_mosi_type := + ( + ready => '0' + ); - constant wac_reset : axi_aw_mosi_type := ( + constant WAC_RESET : axi_aw_mosi_type := + ( id => (others => '0'), addr => (others => '0'), len => (others => '0'), @@ -114,41 +115,51 @@ architecture rtl of ahb2axi_l is atop => (others => '0'), region => (others => '0'), user => (others => '0'), - valid => '0'); + valid => '0' + ); - constant wdc_reset : axi_w_mosi_type := ( + constant WDC_RESET : axi_w_mosi_type := + ( data => (others => '0'), strb => (others => '0'), last => '0', user => (others => '0'), - valid => '0'); - - constant wrc_reset : axi_b_mosi_type := ( - ready => '0'); - - constant aximout_res_t : axi_mosi_type := ( - aw => wac_reset, - w => wdc_reset, - b => wrc_reset, - ar => rac_reset, - r => rdc_reset); - - constant ahbsout_reset : ahb_slv_out_local_type := ( + valid => '0' + ); + + constant WRC_RESET : axi_b_mosi_type := + ( + ready => '0' + ); + + constant AXIMOUT_RES_T : axi_mosi_type := + ( + aw => WAC_RESET, + w => WDC_RESET, + b => WRC_RESET, + ar => RAC_RESET, + r => RDC_RESET + ); + + constant AHBSOUT_RESET : ahb_slv_out_local_type := + ( hready => '1', hresp => HRESP_OKAY, - hrdata => (others => '0')); + hrdata => (others => '0') + ); - constant RES_T : reg_type := ( + constant RES_T : reg_type := + ( state => idle, - ahbsout => ahbsout_reset, - aximout => aximout_res_t, + ahbsout => AHBSOUT_RESET, + aximout => AXIMOUT_RES_T, addr_strb => (others => '0'), read_error => '0', read_validated => '0', write_error => '0', wr_word_valid => '0', write_validated => '0' - ); + ); constant ASYNC_RESET : boolean := GRLIB_CONFIG_ARRAY(grlib_async_reset_enable) = 1; @@ -174,13 +185,15 @@ begin aximo.r <= r.aximout.r; aximo.w <= r.aximout.w; - comb : process(r, ahbsi, aximi) + comb : process (r, ahbsi, aximi) is + variable v : reg_type; + begin v := r; - if axisecure = true then + if (axisecure = true) then v.aximout.ar.prot(1) := '0'; v.aximout.aw.prot(1) := '0'; else @@ -188,19 +201,19 @@ begin v.aximout.aw.prot(1) := '1'; end if; - --locked access disabled + -- locked access disabled v.aximout.ar.lock := '0'; v.aximout.aw.lock := '0'; - --read and write allocate currently disabled + -- read and write allocate currently disabled v.aximout.ar.cache(2) := '0'; v.aximout.ar.cache(3) := '0'; v.aximout.aw.cache(2) := '0'; v.aximout.aw.cache(3) := '0'; - --AXI ID for write operations + -- AXI ID for write operations v.aximout.aw.id := std_logic_vector(to_unsigned(aximid, XID_WIDTH)); - --AXI ID for read operations + -- AXI ID for read operations v.aximout.ar.id := std_logic_vector(to_unsigned(aximid, XID_WIDTH)); case r.state is @@ -216,15 +229,15 @@ begin v.aximout.b.ready := '0'; if (ahbsi.hsel(hindex) = '1' and ahbsi.hready = '1') then - if (ahbsi.htrans = HTRANS_NONSEQ) or (ahbsi.htrans = HTRANS_SEQ) then + if ((ahbsi.htrans = HTRANS_NONSEQ) or (ahbsi.htrans = HTRANS_SEQ)) then v.ahbsout.hready := '0'; - if ahbsi.hwrite = '0' then - v.state := read; - v.read_error := '0'; - v.read_validated := '0'; - v.aximout.ar.valid := '1'; - v.addr_strb := ahbsi.haddr(log2(AXIDW/8)-1 downto 0); - --sample for the read address channel + if (ahbsi.hwrite = '0') then + v.state := read; + v.read_error := '0'; + v.read_validated := '0'; + v.aximout.ar.valid := '1'; + v.addr_strb := ahbsi.haddr(log2(AXIDW / 8) - 1 downto 0); + -- sample for the read address channel v.aximout.ar.addr := ahbsi.haddr; v.aximout.ar.size := ahbsi.hsize; v.aximout.ar.len := (others => '0'); @@ -234,13 +247,13 @@ begin v.aximout.ar.cache(0) := ahbsi.hprot(2); v.aximout.ar.cache(1) := ahbsi.hprot(3); else - v.state := write; - v.write_error := '0'; - v.wr_word_valid := '0'; - v.write_validated := '0'; - v.aximout.aw.valid := '1'; - v.addr_strb := ahbsi.haddr(log2(AXIDW/8)-1 downto 0); - --sample for the write address channel + v.state := write; + v.write_error := '0'; + v.wr_word_valid := '0'; + v.write_validated := '0'; + v.aximout.aw.valid := '1'; + v.addr_strb := ahbsi.haddr(log2(AXIDW / 8) - 1 downto 0); + -- sample for the write address channel v.aximout.aw.addr := ahbsi.haddr; v.aximout.aw.size := ahbsi.hsize; v.aximout.aw.len := (others => '0'); @@ -257,59 +270,58 @@ begin v.ahbsout.hready := '0'; - if r.aximout.ar.valid = '1' and aximi.ar.ready = '1' then + if (r.aximout.ar.valid = '1' and aximi.ar.ready = '1') then v.aximout.ar.valid := '0'; end if; - if r.read_validated = '0' then + if (r.read_validated = '0') then v.aximout.r.ready := '1'; end if; - if aximi.r.valid = '1' and r.aximout.r.ready = '1' then - v.aximout.r.ready := '0'; - v.read_validated := '1'; - v.ahbsout.hrdata := aximi.r.data; + if (aximi.r.valid = '1' and r.aximout.r.ready = '1') then + v.aximout.r.ready := '0'; + v.read_validated := '1'; + v.ahbsout.hrdata := aximi.r.data; if (aximi.r.resp = XRESP_SLVERR or aximi.r.resp = XRESP_DECERR) then v.read_error := '1'; end if; end if; - --make sure the read transaction dependencies has been met - if v.aximout.ar.valid = '0' and v.aximout.r.ready = '0' and v.read_validated = '1' then + -- make sure the read transaction dependencies has been met + if (v.aximout.ar.valid = '0' and v.aximout.r.ready = '0' and v.read_validated = '1') then v.state := idle; - if v.read_error = '0' then + if (v.read_error = '0') then v.ahbsout.hready := '1'; else - --read error, start two cycle propagation + -- read error, start two cycle propagation v.ahbsout.hresp := HRESP_ERROR; v.state := error_p; end if; end if; - when write => v.ahbsout.hready := '0'; - if r.aximout.aw.valid = '1' and aximi.aw.ready = '1' then + if (r.aximout.aw.valid = '1' and aximi.aw.ready = '1') then v.aximout.aw.valid := '0'; end if; - if r.wr_word_valid = '0' then + if (r.wr_word_valid = '0') then v.aximout.w.valid := '1'; v.aximout.w.last := '1'; v.wr_word_valid := '1'; v.aximout.b.ready := '1'; v.aximout.w.data := ahbsi.hwdata; - v.aximout.w.strb := (others => '1'); + v.aximout.w.strb := (others => '1'); end if; - if r.aximout.w.valid = '1' and aximi.w.ready = '1' then + if (r.aximout.w.valid = '1' and aximi.w.ready = '1') then v.aximout.w.valid := '0'; v.aximout.w.last := '0'; end if; - if r.aximout.b.ready = '1' and aximi.b.valid = '1' then + if (r.aximout.b.ready = '1' and aximi.b.valid = '1') then v.aximout.b.ready := '0'; v.write_validated := '1'; if (aximi.b.resp = XRESP_SLVERR or aximi.b.resp = XRESP_DECERR) then @@ -317,19 +329,20 @@ begin end if; end if; - --make sure the write transaction dependencies has been met - if v.aximout.aw.valid = '0' and v.aximout.w.valid = '0' and v.write_validated = '1' then + -- make sure the write transaction dependencies has been met + if (v.aximout.aw.valid = '0' and v.aximout.w.valid = '0' and v.write_validated = '1') then v.state := idle; - if v.write_error = '0' then + if (v.write_error = '0') then v.ahbsout.hready := '1'; else - --error start two cycle propagation + -- error start two cycle propagation v.ahbsout.hresp := HRESP_ERROR; v.state := error_p; end if; end if; when error_p => + v.ahbsout.hresp := HRESP_ERROR; v.ahbsout.hready := '1'; v.state := idle; @@ -343,29 +356,37 @@ begin -- slave configuration info ahbso.hconfig <= hconfig; - end process; + end process comb; syncregs : if not ASYNC_RESET generate - regs : process(clk) + + regs : process (clk) is begin + if rising_edge(clk) then r <= rin; - if rst = '0' then + if (rst = '0') then r <= RES_T; end if; end if; - end process; - end generate; + + end process regs; + + end generate syncregs; asyncregs : if ASYNC_RESET generate - regs : process(arst, clk) + + regs : process (arst, clk) is begin - if arst = '0' then + + if (arst = '0') then r <= RES_T; elsif rising_edge(clk) then r <= rin; end if; - end process; - end generate; -end rtl; + end process regs; + + end generate asyncregs; + +end architecture rtl; diff --git a/rtl/sockets/adapters/apb2axil.sv b/rtl/sockets/adapters/apb2axil.sv index 59e944448d..565f6557d5 100644 --- a/rtl/sockets/adapters/apb2axil.sv +++ b/rtl/sockets/adapters/apb2axil.sv @@ -1,215 +1,202 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -module apb2axil - ( - clk, - rstn, - paddr, - penable, - psel, - pwdata, - pwrite, - prdata, - pready, - pslverr, - s_axil_awvalid, - s_axil_awready, - s_axil_awaddr, - s_axil_wvalid, - s_axil_wready, - s_axil_wdata, - s_axil_wstrb, - s_axil_arvalid, - s_axil_arready, - s_axil_araddr, - s_axil_rvalid, - s_axil_rready, - s_axil_rdata, - s_axil_rresp, - s_axil_bvalid, - s_axil_bready, - s_axil_bresp - ); - - input clk; - input rstn; - // APB - input psel; - input penable; - input pwrite; - input [31:0] paddr; - input [31:0] pwdata; - output reg [31:0] prdata; - output reg pready; - output reg pslverr; - // AXI-L - output reg s_axil_awvalid; - input s_axil_awready; - output [31:0] s_axil_awaddr; - output reg s_axil_wvalid; - input s_axil_wready; - output [31:0] s_axil_wdata; - output [3:0] s_axil_wstrb; - output reg s_axil_arvalid; - input s_axil_arready; - output [31:0] s_axil_araddr; - input s_axil_rvalid; - output reg s_axil_rready; - input [31:0] s_axil_rdata; - input [1:0] s_axil_rresp; - input wire s_axil_bvalid; - output reg s_axil_bready; - input wire [1:0] s_axil_bresp; - - localparam apb2axil_idle = 3'b000; - localparam apb2axil_write = 3'b001; - localparam apb2axil_write_data = 3'b010; - localparam apb2axil_write_ack = 3'b011; - localparam apb2axil_read = 3'b100; - localparam apb2axil_read_data = 3'b101; - - // APB2AXI-Lite - reg [2:0] apb2axil_state; - reg [2:0] apb2axil_next; - - assign s_axil_awaddr = paddr[31:0]; - assign s_axil_wdata = pwdata; - assign s_axil_wstrb = 4'b1111; - assign s_axil_araddr = paddr[31:0]; - - always @ (*) begin - pready = 1'b0; - pslverr = 1'b0; - prdata = '0; - s_axil_awvalid = 1'b0; - s_axil_wvalid = 1'b0; - s_axil_arvalid = 1'b0; - s_axil_rready = 1'b0; - s_axil_bready = 1'b0; - - case (apb2axil_state) - apb2axil_idle : begin - pready = 1'b0; - pslverr = 1'b0; - prdata = '0; - s_axil_awvalid = 1'b0; - s_axil_wvalid = 1'b0; - s_axil_arvalid = 1'b0; - s_axil_rready = 1'b0; - s_axil_bready = 1'b0; - - if ((psel & penable) == 1'b1) begin - if (pwrite == 1'b1) begin - apb2axil_next = apb2axil_write; - end else begin - apb2axil_next = apb2axil_read; - end - end else begin - apb2axil_next = apb2axil_idle; - end - end // case: idle - - apb2axil_write : begin - s_axil_awvalid = 1'b1; - pready = 1'b0; - pslverr = 1'b0; - prdata = '0; - s_axil_wvalid = 1'b1; - s_axil_arvalid = 1'b0; - s_axil_rready = 1'b0; - s_axil_bready = 1'b0; - if ((s_axil_awready & s_axil_wready) == 1'b1) - apb2axil_next = apb2axil_write_ack; - else if (s_axil_awready == 1'b1) - apb2axil_next = apb2axil_write_data; - else - apb2axil_next = apb2axil_write; - end // case: write - - apb2axil_write_data : begin - s_axil_awvalid = 1'b0; - pready = 1'b0; - pslverr = 1'b0; - prdata = '0; - s_axil_wvalid = 1'b1; - s_axil_arvalid = 1'b0; - s_axil_rready = 1'b0; - s_axil_bready = 1'b0; - if (s_axil_wready == 1'b1) - apb2axil_next = apb2axil_write_ack; - else - apb2axil_next = apb2axil_write_data; - end // case: write_data - - apb2axil_write_ack : begin - s_axil_awvalid = 1'b0; - pready = s_axil_bvalid; - pslverr = s_axil_bresp == '0 ? 1'b0 : s_axil_bvalid; - prdata = '0; - s_axil_wvalid = 1'b0; - s_axil_arvalid = 1'b0; - s_axil_rready = 1'b0; - s_axil_bready = 1'b1; - if (s_axil_bvalid == 1'b1) - apb2axil_next = apb2axil_idle; - else - apb2axil_next = apb2axil_write_ack; - end // case: write_ack - - apb2axil_read : begin - pready = s_axil_arready & s_axil_rvalid; - pslverr = s_axil_rresp == '0 ? 1'b0 : s_axil_rvalid; - prdata = s_axil_rdata; - s_axil_awvalid = 1'b0; - s_axil_wvalid = 1'b0; - s_axil_arvalid = 1'b1; - s_axil_rready = 1'b1; - s_axil_bready = 1'b0; - if ((s_axil_arready & s_axil_rvalid) == 1'b1) - apb2axil_next = apb2axil_idle; - else if (s_axil_arready == 1'b1) - apb2axil_next = apb2axil_read_data; - else - apb2axil_next = apb2axil_read; - end // case: read - - apb2axil_read_data : begin - pready = s_axil_rvalid; - pslverr = s_axil_rresp == '0 ? 1'b0 : s_axil_rvalid; - prdata = s_axil_rdata; - s_axil_awvalid = 1'b0; - s_axil_wvalid = 1'b0; - s_axil_arvalid = 1'b0; - s_axil_rready = 1'b1; - s_axil_bready = 1'b0; - if (s_axil_rvalid == 1'b1) - apb2axil_next = apb2axil_idle; - else - apb2axil_next = apb2axil_read_data; - end // case: read_data - - default: begin - pready = 1'b0; - pslverr = 1'b0; - prdata = '0; - s_axil_awvalid = 1'b0; - s_axil_wvalid = 1'b0; - s_axil_arvalid = 1'b0; - s_axil_rready = 1'b0; - s_axil_bready = 1'b0; - apb2axil_next = apb2axil_idle; - end - - endcase // case (apb2axil_state) - end // always @ (*) - - // State update - always @(posedge clk) begin - if (rstn == 1'b0) begin - apb2axil_state <= apb2axil_idle; - end else begin - apb2axil_state <= apb2axil_next; - end - end - -endmodule // apb2axil +module apb2axil ( + clk, + rstn, + paddr, + penable, + psel, + pwdata, + pwrite, + prdata, + pready, + pslverr, + s_axil_awvalid, + s_axil_awready, + s_axil_awaddr, + s_axil_wvalid, + s_axil_wready, + s_axil_wdata, + s_axil_wstrb, + s_axil_arvalid, + s_axil_arready, + s_axil_araddr, + s_axil_rvalid, + s_axil_rready, + s_axil_rdata, + s_axil_rresp, + s_axil_bvalid, + s_axil_bready, + s_axil_bresp +); + + input clk; + input rstn; + // APB + input psel; + input penable; + input pwrite; + input [31:0] paddr; + input [31:0] pwdata; + output reg [31:0] prdata; + output reg pready; + output reg pslverr; + // AXI-L + output reg s_axil_awvalid; + input s_axil_awready; + output [31:0] s_axil_awaddr; + output reg s_axil_wvalid; + input s_axil_wready; + output [31:0] s_axil_wdata; + output [3:0] s_axil_wstrb; + output reg s_axil_arvalid; + input s_axil_arready; + output [31:0] s_axil_araddr; + input s_axil_rvalid; + output reg s_axil_rready; + input [31:0] s_axil_rdata; + input [1:0] s_axil_rresp; + input wire s_axil_bvalid; + output reg s_axil_bready; + input wire [1:0] s_axil_bresp; + + localparam apb2axil_idle = 3'b000; + localparam apb2axil_write = 3'b001; + localparam apb2axil_write_data = 3'b010; + localparam apb2axil_write_ack = 3'b011; + localparam apb2axil_read = 3'b100; + localparam apb2axil_read_data = 3'b101; + + // APB2AXI-Lite + reg [2:0] apb2axil_state; + reg [2:0] apb2axil_next; + + assign s_axil_awaddr = paddr[31:0]; + assign s_axil_wdata = pwdata; + assign s_axil_wstrb = 4'b1111; + assign s_axil_araddr = paddr[31:0]; + + always @(*) begin + pready = 1'b0; + pslverr = 1'b0; + prdata = '0; + s_axil_awvalid = 1'b0; + s_axil_wvalid = 1'b0; + s_axil_arvalid = 1'b0; + s_axil_rready = 1'b0; + s_axil_bready = 1'b0; + + case (apb2axil_state) + apb2axil_idle: begin + pready = 1'b0; + pslverr = 1'b0; + prdata = '0; + s_axil_awvalid = 1'b0; + s_axil_wvalid = 1'b0; + s_axil_arvalid = 1'b0; + s_axil_rready = 1'b0; + s_axil_bready = 1'b0; + + if ((psel & penable) == 1'b1) begin + if (pwrite == 1'b1) begin + apb2axil_next = apb2axil_write; + end else begin + apb2axil_next = apb2axil_read; + end + end else begin + apb2axil_next = apb2axil_idle; + end + end // case: idle + + apb2axil_write: begin + s_axil_awvalid = 1'b1; + pready = 1'b0; + pslverr = 1'b0; + prdata = '0; + s_axil_wvalid = 1'b1; + s_axil_arvalid = 1'b0; + s_axil_rready = 1'b0; + s_axil_bready = 1'b0; + if ((s_axil_awready & s_axil_wready) == 1'b1) apb2axil_next = apb2axil_write_ack; + else if (s_axil_awready == 1'b1) apb2axil_next = apb2axil_write_data; + else apb2axil_next = apb2axil_write; + end // case: write + + apb2axil_write_data: begin + s_axil_awvalid = 1'b0; + pready = 1'b0; + pslverr = 1'b0; + prdata = '0; + s_axil_wvalid = 1'b1; + s_axil_arvalid = 1'b0; + s_axil_rready = 1'b0; + s_axil_bready = 1'b0; + if (s_axil_wready == 1'b1) apb2axil_next = apb2axil_write_ack; + else apb2axil_next = apb2axil_write_data; + end // case: write_data + + apb2axil_write_ack: begin + s_axil_awvalid = 1'b0; + pready = s_axil_bvalid; + pslverr = s_axil_bresp == '0 ? 1'b0 : s_axil_bvalid; + prdata = '0; + s_axil_wvalid = 1'b0; + s_axil_arvalid = 1'b0; + s_axil_rready = 1'b0; + s_axil_bready = 1'b1; + if (s_axil_bvalid == 1'b1) apb2axil_next = apb2axil_idle; + else apb2axil_next = apb2axil_write_ack; + end // case: write_ack + + apb2axil_read: begin + pready = s_axil_arready & s_axil_rvalid; + pslverr = s_axil_rresp == '0 ? 1'b0 : s_axil_rvalid; + prdata = s_axil_rdata; + s_axil_awvalid = 1'b0; + s_axil_wvalid = 1'b0; + s_axil_arvalid = 1'b1; + s_axil_rready = 1'b1; + s_axil_bready = 1'b0; + if ((s_axil_arready & s_axil_rvalid) == 1'b1) apb2axil_next = apb2axil_idle; + else if (s_axil_arready == 1'b1) apb2axil_next = apb2axil_read_data; + else apb2axil_next = apb2axil_read; + end // case: read + + apb2axil_read_data: begin + pready = s_axil_rvalid; + pslverr = s_axil_rresp == '0 ? 1'b0 : s_axil_rvalid; + prdata = s_axil_rdata; + s_axil_awvalid = 1'b0; + s_axil_wvalid = 1'b0; + s_axil_arvalid = 1'b0; + s_axil_rready = 1'b1; + s_axil_bready = 1'b0; + if (s_axil_rvalid == 1'b1) apb2axil_next = apb2axil_idle; + else apb2axil_next = apb2axil_read_data; + end // case: read_data + + default: begin + pready = 1'b0; + pslverr = 1'b0; + prdata = '0; + s_axil_awvalid = 1'b0; + s_axil_wvalid = 1'b0; + s_axil_arvalid = 1'b0; + s_axil_rready = 1'b0; + s_axil_bready = 1'b0; + apb2axil_next = apb2axil_idle; + end + + endcase // case (apb2axil_state) + end // always @ (*) + + // State update + always @(posedge clk) begin + if (rstn == 1'b0) begin + apb2axil_state <= apb2axil_idle; + end else begin + apb2axil_state <= apb2axil_next; + end + end + +endmodule // apb2axil diff --git a/rtl/sockets/bus/ahbctrl.vhd b/rtl/sockets/bus/ahbctrl.vhd index fc7fbb75c1..5804ae0e30 100644 --- a/rtl/sockets/bus/ahbctrl.vhd +++ b/rtl/sockets/bus/ahbctrl.vhd @@ -16,7 +16,7 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------- -- Entity: ahbctrl -- File: ahbctrl.vhd @@ -26,403 +26,546 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.stdlib.all; -use work.amba.all; -use work.config_types.all; -use work.config.all; --- pragma translate_off -use work.devices.all; -use std.textio.all; + use ieee.std_logic_1164.all; + use work.stdlib.all; + use work.amba.all; + use work.config_types.all; + use work.config.all; + -- pragma translate_off + use work.devices.all; + use std.textio.all; -- pragma translate_on entity ahbctrl is generic ( - defmast : integer := 0; -- default master - split : integer := 0; -- split support - rrobin : integer := 0; -- round-robin arbitration - timeout : integer range 0 to 255 := 0; -- HREADY timeout - ioaddr : ahb_addr_type := 16#fff#; -- I/O area MSB address - iomask : ahb_addr_type := 16#fff#; -- I/O area address mask - cfgaddr : ahb_addr_type := 16#ff0#; -- config area MSB address - cfgmask : ahb_addr_type := 16#ff0#; -- config area address mask + defmast : integer := 0; -- default master + split : integer := 0; -- split support + rrobin : integer := 0; -- round-robin arbitration + timeout : integer range 0 to 255 := 0; -- HREADY timeout + ioaddr : ahb_addr_type := 16#fff#; -- I/O area MSB address + iomask : ahb_addr_type := 16#fff#; -- I/O area address mask + cfgaddr : ahb_addr_type := 16#ff0#; -- config area MSB address + cfgmask : ahb_addr_type := 16#ff0#; -- config area address mask nahbm : integer range 1 to NAHBMST := NAHBMST; -- number of masters nahbs : integer range 1 to NAHBSLV := NAHBSLV; -- number of slaves - ioen : integer range 0 to 15 := 1; -- enable I/O area - disirq : integer range 0 to 1 := 0; -- disable interrupt routing - fixbrst : integer range 0 to 1 := 0; -- support fix-length bursts - debug : integer range 0 to 2 := 2; -- report cores to console - fpnpen : integer range 0 to 1 := 0; -- full PnP configuration decoding - icheck : integer range 0 to 1 := 1; - devid : integer := 0; -- unique device ID - enbusmon : integer range 0 to 1 := 0; --enable bus monitor - assertwarn : integer range 0 to 1 := 0; --enable assertions for warnings - asserterr : integer range 0 to 1 := 0; --enable assertions for errors - hmstdisable : integer := 0; --disable master checks - hslvdisable : integer := 0; --disable slave checks - arbdisable : integer := 0; --disable arbiter checks - mprio : integer := 0; --master with highest priority - mcheck : integer range 0 to 2 := 1; --check memory map for intersects - ccheck : integer range 0 to 1 := 1; --perform sanity checks on pnp config - acdm : integer := 0; --AMBA compliant data muxing (for hsize > word) - index : integer := 0; --Index for trace print-out - ahbtrace : integer := 0; --AHB trace enable - hwdebug : integer := 0; --Hardware debug - fourgslv : integer := 0 --1=Single slave with single 4 GB bar + ioen : integer range 0 to 15 := 1; -- enable I/O area + disirq : integer range 0 to 1 := 0; -- disable interrupt routing + fixbrst : integer range 0 to 1 := 0; -- support fix-length bursts + debug : integer range 0 to 2 := 2; -- report cores to console + fpnpen : integer range 0 to 1 := 0; -- full PnP configuration decoding + icheck : integer range 0 to 1 := 1; + devid : integer := 0; -- unique device ID + enbusmon : integer range 0 to 1 := 0; -- enable bus monitor + assertwarn : integer range 0 to 1 := 0; -- enable assertions for warnings + asserterr : integer range 0 to 1 := 0; -- enable assertions for errors + hmstdisable : integer := 0; -- disable master checks + hslvdisable : integer := 0; -- disable slave checks + arbdisable : integer := 0; -- disable arbiter checks + mprio : integer := 0; -- master with highest priority + mcheck : integer range 0 to 2 := 1; -- check memory map for intersects + ccheck : integer range 0 to 1 := 1; -- perform sanity checks on pnp config + acdm : integer := 0; -- AMBA compliant data muxing (for hsize > word) + index : integer := 0; -- Index for trace print-out + ahbtrace : integer := 0; -- AHB trace enable + hwdebug : integer := 0; -- Hardware debug + fourgslv : integer := 0 -- 1=Single slave with single 4 GB bar ); port ( - rst : in std_ulogic; - clk : in std_ulogic; - msti : out ahb_mst_in_type; - msto : in ahb_mst_out_vector; - slvi : out ahb_slv_in_type; - slvo : in ahb_slv_out_vector; - testen : in std_ulogic := '0'; - testrst : in std_ulogic := '1'; - scanen : in std_ulogic := '0'; - testoen : in std_ulogic := '1'; - testsig : in std_logic_vector(1+GRLIB_CONFIG_ARRAY(grlib_techmap_testin_extra) downto 0) := (others => '0') + rst : in std_ulogic; + clk : in std_ulogic; + msti : out ahb_mst_in_type; + msto : in ahb_mst_out_vector; + slvi : out ahb_slv_in_type; + slvo : in ahb_slv_out_vector; + testen : in std_ulogic := '0'; + testrst : in std_ulogic := '1'; + scanen : in std_ulogic := '0'; + testoen : in std_ulogic := '1'; + testsig : in std_logic_vector(1 + GRLIB_CONFIG_ARRAY(grlib_techmap_testin_extra) downto 0) := (others => '0') ); -end; +end entity ahbctrl; architecture rtl of ahbctrl is -constant nahbmx : integer := 2**log2(nahbm); -type nmstarr is array (1 to 3) of integer range 0 to nahbmx-1; -type nvalarr is array (1 to 3) of boolean; - -type reg_type is record - hmaster : integer range 0 to nahbmx -1; - hmasterd : integer range 0 to nahbmx -1; - hslave : integer range 0 to nahbs-1; - hmasterlock : std_ulogic; - hmasterlockd : std_ulogic; - hready : std_ulogic; - defslv : std_ulogic; - htrans : std_logic_vector(1 downto 0); - hsize : std_logic_vector(2 downto 0); - haddr : std_logic_vector(15 downto 2); - cfgsel : std_ulogic; - cfga11 : std_ulogic; - hrdatam : std_logic_vector(31 downto 0); - hrdatas : std_logic_vector(31 downto 0); - beat : std_logic_vector(3 downto 0); - defmst : std_ulogic; - ldefmst : std_ulogic; - lsplmst : integer range 0 to nahbmx-1; -end record; - -constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; -constant RES_r : reg_type := ( - hmaster => 0, hmasterd => 0, hslave => 0, hmasterlock => '0', - hmasterlockd => '0', hready => '1', defslv => '0', - htrans => HTRANS_IDLE, hsize => (others => '0'), - haddr => (others => '0'), cfgsel => '0', cfga11 => '0', - hrdatam => (others => '0'), hrdatas => (others => '0'), - beat => (others => '0'), defmst => '0', ldefmst => '0', - lsplmst => 0); -constant RES_split : std_logic_vector(0 to nahbmx-1) := (others => '0'); - - - constant primst : std_logic_vector(NAHBMST downto 0) := conv_std_logic_vector(mprio, NAHBMST+1); + constant NAHBMX : integer := 2 ** log2(nahbm); + + type nmstarr is array (1 to 3) of integer range 0 to NAHBMX - 1; + + type nvalarr is array (1 to 3) of boolean; + + type reg_type is record + hmaster : integer range 0 to NAHBMX - 1; + hmasterd : integer range 0 to NAHBMX - 1; + hslave : integer range 0 to nahbs - 1; + hmasterlock : std_ulogic; + hmasterlockd : std_ulogic; + hready : std_ulogic; + defslv : std_ulogic; + htrans : std_logic_vector(1 downto 0); + hsize : std_logic_vector(2 downto 0); + haddr : std_logic_vector(15 downto 2); + cfgsel : std_ulogic; + cfga11 : std_ulogic; + hrdatam : std_logic_vector(31 downto 0); + hrdatas : std_logic_vector(31 downto 0); + beat : std_logic_vector(3 downto 0); + defmst : std_ulogic; + ldefmst : std_ulogic; + lsplmst : integer range 0 to NAHBMX - 1; + end record reg_type; + + constant RESET_ALL : boolean := GRLIB_CONFIG_ARRAY(grlib_sync_reset_enable_all) = 1; + constant RES_R : reg_type := + ( + hmaster => 0, + hmasterd => 0, + hslave => 0, + hmasterlock => '0', + hmasterlockd => '0', + hready => '1', + defslv => '0', + htrans => HTRANS_IDLE, + hsize => (others => '0'), + haddr => (others => '0'), + cfgsel => '0', + cfga11 => '0', + hrdatam => (others => '0'), + hrdatas => (others => '0'), + beat => (others => '0'), + defmst => '0', + ldefmst => '0', + lsplmst => 0 + ); + constant RES_SPLIT : std_logic_vector(0 to NAHBMX - 1) := (others => '0'); + + constant PRIMST : std_logic_vector(NAHBMST downto 0) := conv_std_logic_vector(mprio, NAHBMST + 1); + type l0_type is array (0 to 15) of std_logic_vector(2 downto 0); + type l1_type is array (0 to 7) of std_logic_vector(3 downto 0); + type l2_type is array (0 to 3) of std_logic_vector(4 downto 0); + type l3_type is array (0 to 1) of std_logic_vector(5 downto 0); type tztab_type is array (0 to 15) of std_logic_vector(2 downto 0); + -- returns the index number of the highest priority request + -- signal in the two lsb bits when indexed with a 4-bit + -- request vector with the highest priority signal on the + -- lsb. the returned msb bit indicates if a request was + -- active ('1' = no request active corresponds to "0000") + constant TZTAB : tztab_type := + ( + "100", + "000", + "001", + "000", + "010", + "000", + "001", + "000", + "011", + "000", + "001", + "000", + "010", + "000", + "001", + "000" + ); - --returns the index number of the highest priority request - --signal in the two lsb bits when indexed with a 4-bit - --request vector with the highest priority signal on the - --lsb. the returned msb bit indicates if a request was - --active ('1' = no request active corresponds to "0000") - constant tztab : tztab_type := ("100", "000", "001", "000", - "010", "000", "001", "000", - "011", "000", "001", "000", - "010", "000", "001", "000"); - - - --calculate the number of the highest priority request signal(up to 64 - --requests are supported) in vect_in using a divide and conquer - --algorithm. The lower the index in the vector the higher the priority - --of the signal. First 4-bit slices are indexed in tztab and the msb - --indicates whether there is an active request or not. Then the resulting - --3 bit vectors are compared in pairs (the one corresponding to (3:0) with - --(7:4), (11:8) with (15:12) and so on). If the least significant of the two - --contains an active signal a '0' is added to the msb side (the vector - --becomes one bit wider at each level) to the next level to indicate that - --there are active signals in the lower nibble of the two. Otherwise - --the msb is removed from the vector corresponding to the higher nibble - --and "10" is added if it does not contain active requests and "01" if - --does contain active signals. Thus the msb still indicates if the new - --slice contains active signals and a '1' is added if it is the higher - --part. This results in a 6-bit vector containing the index number - --of the highest priority master in 5:0 if bit 6 is '0' otherwise - --no master requested the bus. - function tz(vect_in : std_logic_vector) return std_logic_vector is - variable vect : std_logic_vector(63 downto 0); - variable l0 : l0_type; - variable l1 : l1_type; - variable l2 : l2_type; - variable l3 : l3_type; - variable l4 : std_logic_vector(6 downto 0); + -- calculate the number of the highest priority request signal(up to 64 + -- requests are supported) in vect_in using a divide and conquer + -- algorithm. The lower the index in the vector the higher the priority + -- of the signal. First 4-bit slices are indexed in tztab and the msb + -- indicates whether there is an active request or not. Then the resulting + -- 3 bit vectors are compared in pairs (the one corresponding to (3:0) with + -- (7:4), (11:8) with (15:12) and so on). If the least significant of the two + -- contains an active signal a '0' is added to the msb side (the vector + -- becomes one bit wider at each level) to the next level to indicate that + -- there are active signals in the lower nibble of the two. Otherwise + -- the msb is removed from the vector corresponding to the higher nibble + -- and "10" is added if it does not contain active requests and "01" if + -- does contain active signals. Thus the msb still indicates if the new + -- slice contains active signals and a '1' is added if it is the higher + -- part. This results in a 6-bit vector containing the index number + -- of the highest priority master in 5:0 if bit 6 is '0' otherwise + -- no master requested the bus. + + function tz ( + vect_in : std_logic_vector + ) return std_logic_vector is + + variable vect : std_logic_vector(63 downto 0); + variable l0 : l0_type; + variable l1 : l1_type; + variable l2 : l2_type; + variable l3 : l3_type; + variable l4 : std_logic_vector(6 downto 0); variable bci_lsb, bci_msb : std_logic_vector(3 downto 0); variable bco_lsb, bco_msb : std_logic_vector(2 downto 0); - variable sel : std_logic; + variable sel : std_logic; + begin - vect := (others => '1'); - vect(vect_in'length-1 downto 0) := vect_in; + vect := (others => '1'); + vect(vect_in'length - 1 downto 0) := vect_in; -- level 0 for i in 0 to 7 loop - bci_lsb := vect(8*i+3 downto 8*i); - bci_msb := vect(8*i+7 downto 8*i+4); - --lookup the highest priority request in each nibble + + bci_lsb := vect(8 * i + 3 downto 8 * i); + bci_msb := vect(8 * i + 7 downto 8 * i + 4); + -- lookup the highest priority request in each nibble bco_lsb := tztab(conv_integer(bci_lsb)); bco_msb := tztab(conv_integer(bci_msb)); - --select which of two nibbles contain the highest priority ACTIVE - --signal, and forward the corresponding vector to the next level + -- select which of two nibbles contain the highest priority ACTIVE + -- signal, and forward the corresponding vector to the next level sel := bco_lsb(2); - if sel = '0' then l1(i) := '0' & bco_lsb; - else l1(i) := bco_msb(2) & not bco_msb(2) & bco_msb(1 downto 0); end if; + + if (sel = '0') then + l1(i) := '0' & bco_lsb; + else + l1(i) := bco_msb(2) & not bco_msb(2) & bco_msb(1 downto 0); + end if; + end loop; -- level 1 for i in 0 to 3 loop - sel := l1(2*i)(3); - --select which of two 8-bit vectors contain the - --highest priority ACTIVE signal. the msb set at the previous level - --for each 8-bit slice determines this - if sel = '0' then l2(i) := '0' & l1(2*i); + + sel := l1(2 * i)(3); + -- select which of two 8-bit vectors contain the + -- highest priority ACTIVE signal. the msb set at the previous level + -- for each 8-bit slice determines this + if (sel = '0') then + l2(i) := '0' & l1(2 * i); else - l2(i) := l1(2*i+1)(3) & not l1(2*i+1)(3) & l1(2*i+1)(2 downto 0); + l2(i) := l1(2 * i + 1)(3) & not l1(2 * i + 1)(3) & l1(2 * i + 1)(2 downto 0); end if; + end loop; -- level 2 for i in 0 to 1 loop - --16-bit vectors, the msb set at the previous level for each 16-bit - --slice determines the higher priority slice - sel := l2(2*i)(4); - if sel = '0' then l3(i) := '0' & l2(2*i); + + -- 16-bit vectors, the msb set at the previous level for each 16-bit + -- slice determines the higher priority slice + sel := l2(2 * i)(4); + + if (sel = '0') then + l3(i) := '0' & l2(2 * i); else - l3(i) := l2(2*i+1)(4) & not l2(2*i+1)(4) & l2(2*i+1)(3 downto 0); + l3(i) := l2(2 * i + 1)(4) & not l2(2 * i + 1)(4) & l2(2 * i + 1)(3 downto 0); end if; + end loop; - --level 3 - --32-bit vectors, the msb set at the previous level for each 32-bit - --slice determines the higher priority slice - if l3(0)(5) = '0' then l4 := '0' & l3(0); - else l4 := l3(1)(5) & not l3(1)(5) & l3(1)(4 downto 0); end if; + -- level 3 + -- 32-bit vectors, the msb set at the previous level for each 32-bit + -- slice determines the higher priority slice + if (l3(0)(5) = '0') then + l4 := '0' & l3(0); + else + l4 := l3(1)(5) & not l3(1)(5) & l3(1)(4 downto 0); + end if; return(l4); - end; - --invert the bit order of the hbusreq signals located in vect_in - --since the highest hbusreq has the highest priority but the - --algorithm in tz has the highest priority on lsb - function lz(vect_in : std_logic_vector) return std_logic_vector is - variable vect : std_logic_vector(vect_in'length-1 downto 0); + end function; + + -- invert the bit order of the hbusreq signals located in vect_in + -- since the highest hbusreq has the highest priority but the + -- algorithm in tz has the highest priority on lsb + + function lz ( + vect_in : std_logic_vector + ) return std_logic_vector is + + variable vect : std_logic_vector(vect_in'length-1 downto 0); variable vect2 : std_logic_vector(vect_in'length-1 downto 0); + begin + vect := vect_in; + for i in vect'right to vect'left loop + vect2(i) := vect(vect'left-i); + end loop; + return(tz(vect2)); - end; - --- Find next master: --- * 2 arbitration policies: fixed priority or round-robin --- * Fixed priority: priority is fixed, highest index has highest priority --- * Round-robin: arbiter maintains circular queue of masters --- * (master 0, master 1, ..., master (nahbmx-1)). First requesting master --- * in the queue is granted access to the bus and moved to the end of the queue. --- * splitted masters are not granted --- * bus is re-arbited when current owner does not request the bus, --- or when it performs non-burst accesses --- * fix length burst transfers will not be interrupted --- * incremental bursts should assert hbusreq until last access - - procedure selmast(r : in reg_type; - msto : in ahb_mst_out_vector; - rsplit : in std_logic_vector(0 to nahbmx-1); - mast : out integer range 0 to nahbmx-1; - defmst : out std_ulogic) is - variable nmst : nmstarr; - variable nvalid : nvalarr; - - variable rrvec : std_logic_vector(nahbmx*2-1 downto 0); - variable zcnt : std_logic_vector(log2(nahbmx)+1 downto 0); - variable hpvec : std_logic_vector(nahbmx-1 downto 0); - variable zcnt2 : std_logic_vector(log2(nahbmx) downto 0); + + end function; + + -- Find next master: + -- * 2 arbitration policies: fixed priority or round-robin + -- * Fixed priority: priority is fixed, highest index has highest priority + -- * Round-robin: arbiter maintains circular queue of masters + -- * (master 0, master 1, ..., master (nahbmx-1)). First requesting master + -- * in the queue is granted access to the bus and moved to the end of the queue. + -- * splitted masters are not granted + -- * bus is re-arbited when current owner does not request the bus, + -- or when it performs non-burst accesses + -- * fix length burst transfers will not be interrupted + -- * incremental bursts should assert hbusreq until last access + + procedure selmast ( + r : in reg_type; + msto : in ahb_mst_out_vector; + rsplit : in std_logic_vector(0 to NAHBMX - 1); + mast : out integer range 0 to NAHBMX - 1; + defmst : out std_ulogic + ) is + + variable nmst : nmstarr; + variable nvalid : nvalarr; + + variable rrvec : std_logic_vector(nahbmx * 2 - 1 downto 0); + variable zcnt : std_logic_vector(log2(nahbmx) + 1 downto 0); + variable hpvec : std_logic_vector(nahbmx - 1 downto 0); + variable zcnt2 : std_logic_vector(log2(nahbmx) downto 0); begin nvalid(1 to 3) := (others => false); nmst(1 to 3) := (others => 0); - mast := r.hmaster; - defmst := '0'; + mast := r.hmaster; + defmst := '0'; - if nahbm = 1 then + if (nahbm = 1) then mast := 0; - elsif rrobin = 0 then + elsif (rrobin = 0) then hpvec := (others => '0'); - for i in 0 to nahbmx-1 loop - --masters which have received split are not granted + + for i in 0 to nahbmx - 1 loop + + -- masters which have received split are not granted if ((rsplit(i) = '0') or (split = 0)) then hpvec(i) := msto(i).hbusreq; end if; + end loop; - --check if any bus requests are active (nvalid(2) set to true) - --and determine the index (zcnt2) of the highest priority master + + -- check if any bus requests are active (nvalid(2) set to true) + -- and determine the index (zcnt2) of the highest priority master zcnt2 := lz(hpvec)(log2(nahbmx) downto 0); - if zcnt2(log2(nahbmx)) = '0' then nvalid(2) := true; end if; - nmst(2) := conv_integer(not (zcnt2(log2(nahbmx)-1 downto 0))); - --find the default master number - for i in 0 to nahbmx-1 loop - if not ((nmst(3) = defmast) and nvalid(3)) then + if (zcnt2(log2(nahbmx)) = '0') then + nvalid(2) := true; + end if; + nmst(2) := conv_integer(not (zcnt2(log2(nahbmx) - 1 downto 0))); + -- find the default master number + for i in 0 to nahbmx - 1 loop + + if (not ((nmst(3) = defmast) and nvalid(3))) then nmst(3) := i; nvalid(3) := true; end if; + end loop; + else rrvec := (others => '0'); - --mask requests up to and including current master. Concatenate - --an unmasked request vector above the masked vector. Otherwise - --the rules are the same as for fixed priority - for i in 0 to nahbmx-1 loop + -- mask requests up to and including current master. Concatenate + -- an unmasked request vector above the masked vector. Otherwise + -- the rules are the same as for fixed priority + for i in 0 to nahbmx - 1 loop + if ((rsplit(i) = '0') or (split = 0)) then - if (i <= r.hmaster) then rrvec(i) := '0'; - else rrvec(i) := msto(i).hbusreq; end if; - rrvec(nahbmx+i) := msto(i).hbusreq; + if (i <= r.hmaster) then + rrvec(i) := '0'; + else + rrvec(i) := msto(i).hbusreq; + end if; + rrvec(nahbmx + i) := msto(i).hbusreq; end if; + end loop; - --find the next master uzing tz which gives priority to lower - --indexes - zcnt := tz(rrvec)(log2(nahbmx)+1 downto 0); - --was there a master requesting the bus? - if zcnt(log2(nahbmx)+1) = '0' then nvalid(2) := true; end if; - nmst(2) := conv_integer(zcnt(log2(nahbmx)-1 downto 0)); - --if no other master is requesting the bus select the current one + + -- find the next master uzing tz which gives priority to lower + -- indexes + zcnt := tz(rrvec)(log2(nahbmx) + 1 downto 0); + -- was there a master requesting the bus? + if (zcnt(log2(nahbmx) + 1) = '0') then + nvalid(2) := true; + end if; + nmst(2) := conv_integer(zcnt(log2(nahbmx) - 1 downto 0)); + -- if no other master is requesting the bus select the current one nmst(3) := r.hmaster; nvalid(3) := true; - --check if any masters configured with higher priority are requesting - --the bus - if mprio /= 0 then - for i in 0 to nahbm-1 loop + -- check if any masters configured with higher priority are requesting + -- the bus + if (mprio /= 0) then + + for i in 0 to nahbm - 1 loop + if (((rsplit(i) = '0') or (split = 0)) and (primst(i) = '1')) then - if msto(i).hbusreq = '1' then nmst(1) := i; nvalid(1) := true; end if; + if (msto(i).hbusreq = '1') then + nmst(1) := i; nvalid(1) := true; + end if; end if; + end loop; + end if; end if; - --select the next master. If for round robin a high priority master - --(mprio) requested the bus if nvalid(1) is true. Otherwise - --if nvalid(2) is true at least one master was requesting the bus - --and the one with highest priority was selected. If none of these - --were true then the default master is selected (nvalid(3) true) + -- select the next master. If for round robin a high priority master + -- (mprio) requested the bus if nvalid(1) is true. Otherwise + -- if nvalid(2) is true at least one master was requesting the bus + -- and the one with highest priority was selected. If none of these + -- were true then the default master is selected (nvalid(3) true) for i in 1 to 3 loop - if nvalid(i) then mast := nmst(i); exit; end if; + + if nvalid(i) then + mast := nmst(i); exit; + end if; + end loop; - --if no master was requesting the bus and split is enabled - --then select builtin dummy master which only does - --idle transfers - if (not (nvalid(1) or nvalid(2))) and (split /= 0) then + -- if no master was requesting the bus and split is enabled + -- then select builtin dummy master which only does + -- idle transfers + if ((not (nvalid(1) or nvalid(2))) and (split /= 0)) then defmst := orv(rsplit); end if; - end; + end procedure; - constant MIMAX : integer := log2x(nahbmx) - 1; - constant SIMAX : integer := log2x(nahbs) - 1; - constant IOAREA : std_logic_vector(11 downto 0) := - conv_std_logic_vector(ioaddr, 12); - constant IOMSK : std_logic_vector(11 downto 0) := - conv_std_logic_vector(iomask, 12); + constant MIMAX : integer := log2x(NAHBMX) - 1; + constant SIMAX : integer := log2x(nahbs) - 1; + constant IOAREA : std_logic_vector(11 downto 0) := + conv_std_logic_vector(ioaddr, 12); + constant IOMSK : std_logic_vector(11 downto 0) := + conv_std_logic_vector(iomask, 12); constant CFGAREA : std_logic_vector(11 downto 0) := - conv_std_logic_vector(cfgaddr, 12); + conv_std_logic_vector(cfgaddr, 12); constant CFGMSK : std_logic_vector(11 downto 0) := - conv_std_logic_vector(cfgmask, 12); - constant FULLPNP : boolean := (fpnpen /= 0); + conv_std_logic_vector(cfgmask, 12); + constant FULLPNP : boolean := (fpnpen /= 0); - signal r, rin : reg_type; - signal rsplit, rsplitin : std_logic_vector(0 to nahbmx-1); + signal r, rin : reg_type; + signal rsplit, rsplitin : std_logic_vector(0 to NAHBMX - 1); --- pragma translate_off + -- pragma translate_off signal lmsti : ahb_mst_in_type; signal lslvi : ahb_slv_in_type; -- pragma translate_on begin - comb : process(rst, msto, slvo, r, rsplit, testen, testrst, scanen, testoen, testsig) - variable v : reg_type; - variable nhmaster: integer range 0 to nahbmx -1; - variable hgrant : std_logic_vector(0 to NAHBMST-1); -- bus grant - variable hsel : std_logic_vector(0 to 31); -- slave select - variable hmbsel : std_logic_vector(0 to NAHBAMR-1); - variable nslave : natural range 0 to 31; - variable vsplit : std_logic_vector(0 to nahbmx-1); - variable bnslave : std_logic_vector(3 downto 0); - variable area : std_logic_vector(1 downto 0); - variable hready : std_ulogic; - variable defslv : std_ulogic; - variable cfgsel : std_ulogic; - variable hresp : std_logic_vector(1 downto 0); - variable hrdata : std_logic_vector(AHBDW-1 downto 0); - variable haddr : std_logic_vector(31 downto 0); - variable hirq : std_logic_vector(NAHBIRQ-1 downto 0); - variable arb : std_ulogic; - variable hconfndx : integer range 0 to 7; - variable vslvi : ahb_slv_in_type; - variable defmst : std_ulogic; - variable tmpv : std_logic_vector(0 to nahbmx-1); + comb : process (rst, msto, slvo, r, rsplit, testen, testrst, scanen, testoen, testsig) is + + variable v : reg_type; + variable nhmaster : integer range 0 to NAHBMX - 1; + variable hgrant : std_logic_vector(0 to NAHBMST - 1); -- bus grant + variable hsel : std_logic_vector(0 to 31); -- slave select + variable hmbsel : std_logic_vector(0 to NAHBAMR - 1); + variable nslave : natural range 0 to 31; + variable vsplit : std_logic_vector(0 to NAHBMX - 1); + variable bnslave : std_logic_vector(3 downto 0); + variable area : std_logic_vector(1 downto 0); + variable hready : std_ulogic; + variable defslv : std_ulogic; + variable cfgsel : std_ulogic; + variable hresp : std_logic_vector(1 downto 0); + variable hrdata : std_logic_vector(AHBDW - 1 downto 0); + variable haddr : std_logic_vector(31 downto 0); + variable hirq : std_logic_vector(NAHBIRQ - 1 downto 0); + variable arb : std_ulogic; + variable hconfndx : integer range 0 to 7; + variable vslvi : ahb_slv_in_type; + variable defmst : std_ulogic; + variable tmpv : std_logic_vector(0 to NAHBMX - 1); begin - v := r; hgrant := (others => '0'); defmst := '0'; + v := r; hgrant := (others => '0'); defmst := '0'; haddr := msto(r.hmaster).haddr; nhmaster := r.hmaster; - --determine if bus should be rearbitrated. This is done if the current - --master is not performing a locked transfer and if not in the middle - --of burst + -- determine if bus should be rearbitrated. This is done if the current + -- master is not performing a locked transfer and if not in the middle + -- of burst arb := '0'; - if (r.hmasterlock or r.ldefmst) = '0' then + + if ((r.hmasterlock or r.ldefmst) = '0') then + case msto(r.hmaster).htrans is - when HTRANS_IDLE => arb := '1'; + + when HTRANS_IDLE => + + arb := '1'; + when HTRANS_NONSEQ => + case msto(r.hmaster).hburst is - when HBURST_SINGLE => arb := '1'; - when HBURST_INCR => arb := not msto(r.hmaster).hbusreq; + + when HBURST_SINGLE => + + arb := '1'; + + when HBURST_INCR => + + arb := not msto(r.hmaster).hbusreq; + when others => + end case; + when HTRANS_SEQ => + case msto(r.hmaster).hburst is - when HBURST_WRAP4 | HBURST_INCR4 => if (fixbrst = 1) and (r.beat(1 downto 0) = "11") then arb := '1'; end if; - when HBURST_WRAP8 | HBURST_INCR8 => if (fixbrst = 1) and (r.beat(2 downto 0) = "111") then arb := '1'; end if; - when HBURST_WRAP16 | HBURST_INCR16 => if (fixbrst = 1) and (r.beat(3 downto 0) = "1111") then arb := '1'; end if; - when HBURST_INCR => arb := not msto(r.hmaster).hbusreq; + + when HBURST_WRAP4 | HBURST_INCR4 => + + if ((fixbrst = 1) and (r.beat(1 downto 0) = "11")) then + arb := '1'; + end if; + + when HBURST_WRAP8 | HBURST_INCR8 => + + if ((fixbrst = 1) and (r.beat(2 downto 0) = "111")) then + arb := '1'; + end if; + + when HBURST_WRAP16 | HBURST_INCR16 => + + if ((fixbrst = 1) and (r.beat(3 downto 0) = "1111")) then + arb := '1'; + end if; + + when HBURST_INCR => + + arb := not msto(r.hmaster).hbusreq; + when others => + end case; - when others => arb := '0'; + + when others => + + arb := '0'; + end case; + end if; if (split /= 0) then - for i in 0 to nahbmx-1 loop + + for i in 0 to NAHBMX - 1 loop + tmpv(i) := (msto(i).htrans(1) or (msto(i).hbusreq)) and not rsplit(i) and not r.ldefmst; + end loop; - if (r.defmst and orv(tmpv)) = '1' then arb := '1'; end if; + + if ((r.defmst and orv(tmpv)) = '1') then + arb := '1'; + end if; end if; - --rearbitrate bus with selmast. If not arbitrated one must - --ensure that the dummy master is selected for locked splits. + -- rearbitrate bus with selmast. If not arbitrated one must + -- ensure that the dummy master is selected for locked splits. if (arb = '1') then selmast(r, msto, rsplit, nhmaster, defmst); elsif (split /= 0) then @@ -433,34 +576,51 @@ begin hsel := (others => '0'); hmbsel := (others => '0'); - if fourgslv = 0 then - for i in 0 to nahbs-1 loop - for j in NAHBIR to NAHBCFG-1 loop + if (fourgslv = 0) then + + for i in 0 to nahbs - 1 loop + + for j in NAHBIR to NAHBCFG - 1 loop + area := slvo(i).hconfig(j)(1 downto 0); + case area is + when "10" => - if ((ioen = 0) or ((IOAREA and IOMSK) /= (haddr(31 downto 20) and IOMSK))) and - ((slvo(i).hconfig(j)(31 downto 20) and slvo(i).hconfig(j)(15 downto 4)) = - (haddr(31 downto 20) and slvo(i).hconfig(j)(15 downto 4))) and - (slvo(i).hconfig(j)(15 downto 4) /= "000000000000") - then hsel(i) := '1'; hmbsel(j-NAHBIR) := '1'; end if; + + if (((ioen = 0) or ((IOAREA and IOMSK) /= (haddr(31 downto 20) and IOMSK))) and + ((slvo(i).hconfig(j)(31 downto 20) and slvo(i).hconfig(j)(15 downto 4)) = + (haddr(31 downto 20) and slvo(i).hconfig(j)(15 downto 4))) and + (slvo(i).hconfig(j)(15 downto 4) /= "000000000000")) then + hsel(i) := '1'; hmbsel(j - NAHBIR) := '1'; + end if; + when "11" => - if ((ioen /= 0) and ((IOAREA and IOMSK) = (haddr(31 downto 20) and IOMSK))) and - ((slvo(i).hconfig(j)(31 downto 20) and slvo(i).hconfig(j)(15 downto 4)) = - (haddr(19 downto 8) and slvo(i).hconfig(j)(15 downto 4))) and - (slvo(i).hconfig(j)(15 downto 4) /= "000000000000") - then hsel(i) := '1'; hmbsel(j-NAHBIR) := '1'; end if; + + if (((ioen /= 0) and ((IOAREA and IOMSK) = (haddr(31 downto 20) and IOMSK))) and + ((slvo(i).hconfig(j)(31 downto 20) and slvo(i).hconfig(j)(15 downto 4)) = + (haddr(19 downto 8) and slvo(i).hconfig(j)(15 downto 4))) and + (slvo(i).hconfig(j)(15 downto 4) /= "000000000000")) then + hsel(i) := '1'; hmbsel(j - NAHBIR) := '1'; + end if; + when others => + end case; + end loop; + end loop; + else -- There is only one slave on the bus. The slave has only one bar, which -- maps 4 GB address space. hsel(0) := '1'; hmbsel(0) := '1'; end if; - if r.defmst = '1' then hsel := (others => '0'); end if; + if (r.defmst = '1') then + hsel := (others => '0'); + end if; bnslave(0) := hsel(1) or hsel(3) or hsel(5) or hsel(7) or hsel(9) or hsel(11) or hsel(13) or hsel(15); @@ -470,29 +630,35 @@ begin hsel(12) or hsel(13) or hsel(14) or hsel(15); bnslave(3) := hsel(8) or hsel(9) or hsel(10) or hsel(11) or hsel(12) or hsel(13) or hsel(14) or hsel(15); - nslave := conv_integer(bnslave(SIMAX downto 0)); + nslave := conv_integer(bnslave(SIMAX downto 0)); - if ((((IOAREA and IOMSK) = (haddr(31 downto 20) and IOMSK)) and (ioen /= 0)) - or ((IOAREA = haddr(31 downto 20)) and (ioen = 0))) and - ((CFGAREA and CFGMSK) = (haddr(19 downto 8) and CFGMSK)) - and (cfgmask /= 0) - then cfgsel := '1'; hsel := (others => '0'); - else cfgsel := '0'; end if; + if (((((IOAREA and IOMSK) = (haddr(31 downto 20) and IOMSK)) and (ioen /= 0)) + or ((IOAREA = haddr(31 downto 20)) and (ioen = 0))) and + ((CFGAREA and CFGMSK) = (haddr(19 downto 8) and CFGMSK)) + and (cfgmask /= 0)) then + cfgsel := '1'; hsel := (others => '0'); + else + cfgsel := '0'; + end if; - if (nslave = 0) and (hsel(0) = '0') and (cfgsel = '0') then defslv := '1'; - else defslv := '0'; end if; + if ((nslave = 0) and (hsel(0) = '0') and (cfgsel = '0')) then + defslv := '1'; + else + defslv := '0'; + end if; - if r.defmst = '1' then + if (r.defmst = '1') then cfgsel := '0'; defslv := '1'; end if; --- error response on undecoded area + -- error response on undecoded area v.hready := '0'; - hready := slvo(r.hslave).hready; hresp := slvo(r.hslave).hresp; - if r.defslv = '1' then + hready := slvo(r.hslave).hready; hresp := slvo(r.hslave).hresp; + + if (r.defslv = '1') then -- default slave - if (r.htrans = HTRANS_IDLE) or (r.htrans = HTRANS_BUSY) then + if ((r.htrans = HTRANS_IDLE) or (r.htrans = HTRANS_BUSY)) then hresp := HRESP_OKAY; hready := '1'; else -- return two-cycle error in case of unimplemented slave access @@ -500,150 +666,205 @@ begin end if; end if; - if acdm = 0 then + if (acdm = 0) then hrdata := slvo(r.hslave).hrdata; else hrdata := ahbselectdata(slvo(r.hslave).hrdata, r.haddr(4 downto 2), r.hsize); end if; - if cfgmask /= 0 then + if (cfgmask /= 0) then -- plug&play information for masters - if FULLPNP then hconfndx := conv_integer(r.haddr(4 downto 2)); else hconfndx := 0; end if; - if (r.haddr(10 downto MIMAX+6) = zero32(10 downto MIMAX+6)) and (FULLPNP or (r.haddr(4 downto 2) = "000")) - then v.hrdatam := msto(conv_integer(r.haddr(MIMAX+5 downto 5))).hconfig(hconfndx); - else v.hrdatam := (others => '0'); end if; + if (FULLPNP) then + hconfndx := conv_integer(r.haddr(4 downto 2)); + else + hconfndx := 0; + end if; + if ((r.haddr(10 downto MIMAX + 6) = zero32(10 downto MIMAX + 6)) and (FULLPNP or (r.haddr(4 downto 2) = "000"))) then + v.hrdatam := msto(conv_integer(r.haddr(MIMAX + 5 downto 5))).hconfig(hconfndx); + else + v.hrdatam := (others => '0'); + end if; -- plug&play information for slaves - if (r.haddr(10 downto SIMAX+6) = zero32(10 downto SIMAX+6)) and - (FULLPNP or (r.haddr(4 downto 2) = "000") or (r.haddr(4) = '1')) - then v.hrdatas := slvo(conv_integer(r.haddr(SIMAX+5 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2))); - else v.hrdatas := (others => '0'); end if; + if ((r.haddr(10 downto SIMAX + 6) = zero32(10 downto SIMAX + 6)) and + (FULLPNP or (r.haddr(4 downto 2) = "000") or (r.haddr(4) = '1'))) then + v.hrdatas := slvo(conv_integer(r.haddr(SIMAX + 5 downto 5))).hconfig(conv_integer(r.haddr(4 downto 2))); + else + v.hrdatas := (others => '0'); + end if; -- device ID, library build and potentially debug information - if r.haddr(10 downto 4) = "1111111" then - if hwdebug = 0 or r.haddr(3 downto 2) = "00" then - v.hrdatas(15 downto 0) := conv_std_logic_vector(LIBVHDL_BUILD, 16); + if (r.haddr(10 downto 4) = "1111111") then + if (hwdebug = 0 or r.haddr(3 downto 2) = "00") then + v.hrdatas(15 downto 0) := conv_std_logic_vector(LIBVHDL_BUILD, 16); v.hrdatas(31 downto 16) := conv_std_logic_vector(devid, 16); - elsif r.haddr(3 downto 2) = "01" then - for i in 0 to nahbmx-1 loop v.hrdatas(i) := msto(i).hbusreq; end loop; + elsif (r.haddr(3 downto 2) = "01") then + + for i in 0 to NAHBMX - 1 loop + + v.hrdatas(i) := msto(i).hbusreq; + + end loop; + else - for i in 0 to nahbmx-1 loop v.hrdatas(i) := rsplit(i); end loop; + + for i in 0 to NAHBMX - 1 loop + + v.hrdatas(i) := rsplit(i); + + end loop; + end if; end if; - if r.cfgsel = '1' then + if (r.cfgsel = '1') then hrdata := (others => '0'); -- default slave - if (r.htrans = HTRANS_IDLE) or (r.htrans = HTRANS_BUSY) then + if ((r.htrans = HTRANS_IDLE) or (r.htrans = HTRANS_BUSY)) then hresp := HRESP_OKAY; hready := '1'; else -- return two-cycle read/write respons hresp := HRESP_OKAY; hready := r.hready; v.hready := not r.hready; end if; - if r.cfga11 = '0' then hrdata := ahbdrivedata(r.hrdatam); - else hrdata := ahbdrivedata(r.hrdatas); end if; + if (r.cfga11 = '0') then + hrdata := ahbdrivedata(r.hrdatam); + else + hrdata := ahbdrivedata(r.hrdatas); + end if; end if; end if; - --degrant all masters when split occurs for locked access + -- degrant all masters when split occurs for locked access if (r.hmasterlockd = '1') then - if (hresp = HRESP_RETRY) or ((split /= 0) and (hresp = HRESP_SPLIT)) then + if ((hresp = HRESP_RETRY) or ((split /= 0) and (hresp = HRESP_SPLIT))) then nhmaster := r.hmaster; end if; - if split /= 0 then - if hresp = HRESP_SPLIT then + if (split /= 0) then + if (hresp = HRESP_SPLIT) then v.ldefmst := '1'; defmst := '1'; v.lsplmst := nhmaster; end if; end if; end if; - if split /= 0 and r.ldefmst = '1' then - if rsplit(r.lsplmst) = '0' then + if (split /= 0 and r.ldefmst = '1') then + if (rsplit(r.lsplmst) = '0') then v.ldefmst := '0'; defmst := '0'; end if; end if; - if (split = 0) or (defmst = '0') then hgrant(nhmaster) := '1'; end if; + if ((split = 0) or (defmst = '0')) then + hgrant(nhmaster) := '1'; + end if; -- latch active master and slave - if hready = '1' then - v.hmaster := nhmaster; v.hmasterd := r.hmaster; - v.hsize := msto(r.hmaster).hsize; - v.hslave := nslave; v.defslv := defslv; + if (hready = '1') then + v.hmaster := nhmaster; v.hmasterd := r.hmaster; + v.hsize := msto(r.hmaster).hsize; + v.hslave := nslave; v.defslv := defslv; v.hmasterlockd := r.hmasterlock; - if (split = 0) or (r.defmst = '0') then v.htrans := msto(r.hmaster).htrans; - else v.htrans := HTRANS_IDLE; end if; + if ((split = 0) or (r.defmst = '0')) then + v.htrans := msto(r.hmaster).htrans; + else + v.htrans := HTRANS_IDLE; + end if; v.cfgsel := cfgsel; v.cfga11 := msto(r.hmaster).haddr(11); - v.haddr := msto(r.hmaster).haddr(15 downto 2); - if (msto(r.hmaster).htrans = HTRANS_NONSEQ) or (msto(r.hmaster).htrans = HTRANS_IDLE) then + v.haddr := msto(r.hmaster).haddr(15 downto 2); + if ((msto(r.hmaster).htrans = HTRANS_NONSEQ) or (msto(r.hmaster).htrans = HTRANS_IDLE)) then v.beat := "0001"; elsif (msto(r.hmaster).htrans = HTRANS_SEQ) then - if (fixbrst = 1) then v.beat := r.beat + 1; end if; + if (fixbrst = 1) then + v.beat := r.beat + 1; + end if; + end if; + if (split /= 0) then + v.defmst := defmst; end if; - if (split /= 0) then v.defmst := defmst; end if; end if; - --assign new hmasterlock, v.hmaster is used because if hready - --then master can have changed, and when not hready then the - --previous master will still be selected + -- assign new hmasterlock, v.hmaster is used because if hready + -- then master can have changed, and when not hready then the + -- previous master will still be selected v.hmasterlock := msto(v.hmaster).hlock or (r.hmasterlock and not hready); - --if the master asserting hlock received a SPLIT/RETRY response - --to the previous access then disregard the current lock request. - --the bus will otherwise be locked when the previous access is - --retried instead of treating hlock as coupled to the next access. - --use hmasterlockd to keep the bus locked for SPLIT/RETRY to locked - --accesses. - if v.hmaster = r.hmasterd and slvo(r.hslave).hresp(1) = '1' then - if r.hmasterlockd = '0' then + -- if the master asserting hlock received a SPLIT/RETRY response + -- to the previous access then disregard the current lock request. + -- the bus will otherwise be locked when the previous access is + -- retried instead of treating hlock as coupled to the next access. + -- use hmasterlockd to keep the bus locked for SPLIT/RETRY to locked + -- accesses. + if (v.hmaster = r.hmasterd and slvo(r.hslave).hresp(1) = '1') then + if (r.hmasterlockd = '0') then v.hmasterlock := '0'; v.hmasterlockd := '0'; end if; end if; -- split support vsplit := (others => '0'); - if SPLIT /= 0 then + + if (split /= 0) then vsplit := rsplit; - if slvo(r.hslave).hresp = HRESP_SPLIT then vsplit(r.hmasterd) := '1'; end if; - for i in 0 to nahbs-1 loop - for j in 0 to nahbmx-1 loop + if (slvo(r.hslave).hresp = HRESP_SPLIT) then + vsplit(r.hmasterd) := '1'; + end if; + + for i in 0 to nahbs - 1 loop + + for j in 0 to NAHBMX - 1 loop + vsplit(j) := vsplit(j) and not slvo(i).hsplit(j); + end loop; + end loop; + end if; -- interrupt merging hirq := (others => '0'); - if disirq = 0 then - for i in 0 to nahbs-1 loop hirq := hirq or slvo(i).hirq; end loop; - for i in 0 to nahbm-1 loop hirq := hirq or msto(i).hirq; end loop; + + if (disirq = 0) then + + for i in 0 to nahbs - 1 loop + + hirq := hirq or slvo(i).hirq; + + end loop; + + for i in 0 to nahbm - 1 loop + + hirq := hirq or msto(i).hirq; + + end loop; + end if; - if (split = 0) or (r.defmst = '0') then - vslvi.haddr := haddr; - vslvi.htrans := msto(r.hmaster).htrans; - vslvi.hwrite := msto(r.hmaster).hwrite; - vslvi.hsize := msto(r.hmaster).hsize; - vslvi.hburst := msto(r.hmaster).hburst; - vslvi.hready := hready; - vslvi.hprot := msto(r.hmaster).hprot; --- vslvi.hmastlock := msto(r.hmaster).hlock; - vslvi.hmastlock := r.hmasterlock; - vslvi.hmaster := conv_std_logic_vector(r.hmaster, 4); - vslvi.hsel := hsel(0 to NAHBSLV-1); - vslvi.hmbsel := hmbsel; - vslvi.hirq := hirq; + if ((split = 0) or (r.defmst = '0')) then + vslvi.haddr := haddr; + vslvi.htrans := msto(r.hmaster).htrans; + vslvi.hwrite := msto(r.hmaster).hwrite; + vslvi.hsize := msto(r.hmaster).hsize; + vslvi.hburst := msto(r.hmaster).hburst; + vslvi.hready := hready; + vslvi.hprot := msto(r.hmaster).hprot; + -- vslvi.hmastlock := msto(r.hmaster).hlock; + vslvi.hmastlock := r.hmasterlock; + vslvi.hmaster := conv_std_logic_vector(r.hmaster, 4); + vslvi.hsel := hsel(0 to NAHBSLV - 1); + vslvi.hmbsel := hmbsel; + vslvi.hirq := hirq; else - vslvi := ahbs_in_none; + vslvi := ahbs_in_none; vslvi.hready := hready; vslvi.hirq := hirq; end if; - if acdm = 0 then + + if (acdm = 0) then vslvi.hwdata := msto(r.hmasterd).hwdata; else vslvi.hwdata := ahbselectdata(msto(r.hmasterd).hwdata, r.haddr(4 downto 2), r.hsize); end if; + vslvi.testen := testen; vslvi.testrst := testrst; vslvi.scanen := scanen and testen; @@ -651,12 +872,12 @@ begin vslvi.testin := testen & (scanen and testen) & testsig; -- reset operation - if (not RESET_ALL) and (rst = '0') then + if ((not RESET_ALL) and (rst = '0')) then v.hmaster := RES_r.hmaster; v.hmasterlock := RES_r.hmasterlock; - vsplit := (others => '0'); - v.htrans := RES_r.htrans; v.defslv := RES_r.defslv; - v.hslave := RES_r.hslave; v.cfgsel := RES_r.cfgsel; - v.defmst := RES_r.defmst; v.ldefmst := RES_r.ldefmst; + vsplit := (others => '0'); + v.htrans := RES_r.htrans; v.defslv := RES_r.defslv; + v.hslave := RES_r.hslave; v.cfgsel := RES_r.cfgsel; + v.defmst := RES_r.defmst; v.ldefmst := RES_r.ldefmst; end if; -- drive master inputs @@ -672,334 +893,449 @@ begin msti.testin <= testen & (scanen and testen) & testsig; -- drive slave inputs - slvi <= vslvi; + slvi <= vslvi; --- pragma translate_off - --drive internal signals to bus monitor - lslvi <= vslvi; + -- pragma translate_off + -- drive internal signals to bus monitor + lslvi <= vslvi; - lmsti.hgrant <= hgrant; - lmsti.hready <= hready; - lmsti.hresp <= hresp; - lmsti.hrdata <= hrdata; - lmsti.hirq <= hirq; --- pragma translate_on - - if split = 0 then v.ldefmst := '0'; v.lsplmst := 0; end if; + lmsti.hgrant <= hgrant; + lmsti.hready <= hready; + lmsti.hresp <= hresp; + lmsti.hrdata <= hrdata; + lmsti.hirq <= hirq; + -- pragma translate_on - rin <= v; rsplitin <= vsplit; + if (split = 0) then + v.ldefmst := '0'; v.lsplmst := 0; + end if; - end process; + rin <= v; + rsplitin <= vsplit; + end process comb; - reg0 : process(clk) + reg0 : process (clk) is begin + if rising_edge(clk) then r <= rin; - if RESET_ALL and rst = '0' then - r <= RES_r; + if (RESET_ALL and rst = '0') then + r <= RES_R; end if; end if; - if (split = 0) then r.defmst <= '0'; end if; - end process; - splitreg : if SPLIT /= 0 generate - reg1 : process(clk) + if (split = 0) then + r.defmst <= '0'; + end if; + + end process reg0; + + splitreg : if split /= 0 generate + + reg1 : process (clk) is begin + if rising_edge(clk) then rsplit <= rsplitin; - if RESET_ALL and rst = '0' then - rsplit <= RES_split; + if (RESET_ALL and rst = '0') then + rsplit <= RES_SPLIT; end if; end if; - end process; - end generate; - nosplitreg : if SPLIT = 0 generate + end process reg1; + + end generate splitreg; + + nosplitreg : if split = 0 generate rsplit <= (others => '0'); - end generate; + end generate nosplitreg; + + -- pragma translate_off --- pragma translate_off ahblog : if ahbtrace /= 0 generate - log : process (clk) - variable hwrite : std_logic; - variable hsize : std_logic_vector(2 downto 0); - variable htrans : std_logic_vector(1 downto 0); - variable hmaster : std_logic_vector(3 downto 0); - variable haddr : std_logic_vector(31 downto 0); - variable hwdata, hrdata : std_logic_vector(127 downto 0); - variable mbit, bitoffs : integer; - variable t : integer; + + log : process (clk) is + + variable hwrite : std_logic; + variable hsize : std_logic_vector(2 downto 0); + variable htrans : std_logic_vector(1 downto 0); + variable hmaster : std_logic_vector(3 downto 0); + variable haddr : std_logic_vector(31 downto 0); + variable hwdata, hrdata : std_logic_vector(127 downto 0); + variable mbit, bitoffs : integer; + variable t : integer; + begin + if rising_edge(clk) then - if htrans(1)='1' and lmsti.hready='0' and (lmsti.hresp="01") then - if hwrite = '1' then - work.testlib.print("mst" & tost(hmaster) & ": " & tost(haddr) & " write " & tost(mbit/8) & " bytes [" & tost(lslvi.hwdata(mbit-1+bitoffs downto bitoffs)) & "] - ERROR!"); + if (htrans(1)='1' and lmsti.hready='0' and (lmsti.hresp="01")) then + if (hwrite = '1') then + work.testlib.print("mst" & tost(hmaster) & ": " & tost(haddr) & " write " & tost(mbit / 8) & " bytes [" & tost(lslvi.hwdata(mbit - 1 + bitoffs downto bitoffs)) & "] - ERROR!"); else - work.testlib.print("mst" & tost(hmaster) & ": " & tost(haddr) & " read " & tost(mbit/8) & " bytes [" & tost(lmsti.hrdata(mbit-1+bitoffs downto bitoffs)) & "] - ERROR!"); + work.testlib.print("mst" & tost(hmaster) & ": " & tost(haddr) & " read " & tost(mbit / 8) & " bytes [" & tost(lmsti.hrdata(mbit - 1 + bitoffs downto bitoffs)) & "] - ERROR!"); end if; end if; - if ((htrans(1) and lmsti.hready) = '1') and (lmsti.hresp = "00") then - mbit := 2**conv_integer(hsize)*8; + if (((htrans(1) and lmsti.hready) = '1') and (lmsti.hresp = "00")) then + mbit := 2 ** conv_integer(hsize) * 8; bitoffs := 0; - if mbit < ahbdw then - bitoffs := mbit * conv_integer(haddr(log2(ahbdw/8)-1 downto conv_integer(hsize))); - bitoffs := lslvi.hwdata'length-mbit-bitoffs; + if (mbit < ahbdw) then + bitoffs := mbit * conv_integer(haddr(log2(ahbdw / 8) - 1 downto conv_integer(hsize))); + bitoffs := lslvi.hwdata'length-mbit - bitoffs; end if; - t := (now/1 ns); - if hwrite = '1' then - work.testlib.print("mst" & tost(hmaster) & ": " & tost(haddr) & " write " & tost(mbit/8) & " bytes [" & tost(lslvi.hwdata(mbit-1+bitoffs downto bitoffs)) & "]"); + t := (now / 1 ns); + if (hwrite = '1') then + work.testlib.print("mst" & tost(hmaster) & ": " & tost(haddr) & " write " & tost(mbit / 8) & " bytes [" & tost(lslvi.hwdata(mbit - 1 + bitoffs downto bitoffs)) & "]"); else - work.testlib.print("mst" & tost(hmaster) & ": " & tost(haddr) & " read " & tost(mbit/8) & " bytes [" & tost(lmsti.hrdata(mbit-1+bitoffs downto bitoffs)) & "]"); + work.testlib.print("mst" & tost(hmaster) & ": " & tost(haddr) & " read " & tost(mbit / 8) & " bytes [" & tost(lmsti.hrdata(mbit - 1 + bitoffs downto bitoffs)) & "]"); end if; end if; - if lmsti.hready = '1' then - hwrite := lslvi.hwrite; - hsize := lslvi.hsize; - haddr := lslvi.haddr; - htrans := lslvi.htrans; + if (lmsti.hready = '1') then + hwrite := lslvi.hwrite; + hsize := lslvi.hsize; + haddr := lslvi.haddr; + htrans := lslvi.htrans; hmaster := lslvi.hmaster; end if; end if; - end process; - end generate; + + end process log; + + end generate ahblog; mon0 : if enbusmon /= 0 generate - mon : ahbmon - generic map( + + mon : component ahbmon + generic map ( asserterr => asserterr, assertwarn => assertwarn, hmstdisable => hmstdisable, hslvdisable => hslvdisable, arbdisable => arbdisable, nahbm => nahbm, - nahbs => nahbs) - port map( - rst => rst, - clk => clk, - ahbmi => lmsti, - ahbmo => msto, - ahbsi => lslvi, - ahbso => slvo, - err => open); - end generate; - - diag : process - type ahbsbank_type is record - start : std_logic_vector(31 downto 8); - stop : std_logic_vector(31 downto 8); - io : std_ulogic; - end record; - type ahbsbanks_type is array (0 to 3) of ahbsbank_type; - type memmap_type is array (0 to nahbs-1) of ahbsbanks_type; - variable k : integer; - variable mask : std_logic_vector(11 downto 0); - variable device : std_logic_vector(11 downto 0); - variable devicei : integer; - variable vendor : std_logic_vector( 7 downto 0); - variable area : std_logic_vector( 1 downto 0); - variable vendori : integer; - variable iosize, tmp : integer; - variable iounit : string(1 to 5) := " byte"; - variable memtype : string(1 to 9); - variable iostart : std_logic_vector(11 downto 0) := IOAREA and IOMSK; - variable cfgstart : std_logic_vector(11 downto 0) := CFGAREA and CFGMSK; - variable L1 : line := new string'(""); - variable S1 : string(1 to 255); - variable memmap : memmap_type; + nahbs => nahbs + ) + port map ( + rst => rst, + clk => clk, + ahbmi => lmsti, + ahbmo => msto, + ahbsi => lslvi, + ahbso => slvo, + err => open + ); + + end generate mon0; + + diag : process is + + type ahbsbank_type is record + start : std_logic_vector(31 downto 8); + stop : std_logic_vector(31 downto 8); + io : std_ulogic; + end record ahbsbank_type; + + type ahbsbanks_type is array (0 to 3) of ahbsbank_type; + + type memmap_type is array (0 to nahbs - 1) of ahbsbanks_type; + + variable k : integer; + variable mask : std_logic_vector(11 downto 0); + variable device : std_logic_vector(11 downto 0); + variable devicei : integer; + variable vendor : std_logic_vector( 7 downto 0); + variable area : std_logic_vector( 1 downto 0); + variable vendori : integer; + variable iosize, tmp : integer; + variable iounit : string(1 to 5) := " byte"; + variable memtype : string(1 to 9); + variable iostart : std_logic_vector(11 downto 0) := IOAREA and IOMSK; + variable cfgstart : std_logic_vector(11 downto 0) := CFGAREA and CFGMSK; + variable l1 : line := new string'(""); + variable s1 : string(1 to 255); + variable memmap : memmap_type; begin + wait for 2 ns; - if debug = 0 then wait; end if; - if debug > 0 then + + if (debug = 0) then + wait; + end if; + + if (debug > 0) then k := 0; mask := IOMSK; - while (k<12) and (mask(k) = '0') loop k := k+1; end loop; + + while (k<12) and (mask(k) = '0') loop + + k := k + 1; + + end loop; + print("ahbctrl: AHB arbiter/multiplexer rev 1"); - if ioen /= 0 then - print("ahbctrl: Common I/O area at " & tost(iostart) & "00000, " & tost(2**k) & " Mbyte"); + if (ioen /= 0) then + print("ahbctrl: Common I/O area at " & tost(iostart) & "00000, " & tost(2 ** k) & " Mbyte"); else print("ahbctrl: Common I/O area disabled"); end if; print("ahbctrl: AHB masters: " & tost(nahbm) & ", AHB slaves: " & tost(nahbs)); - if cfgmask /= 0 then + if (cfgmask /= 0) then print("ahbctrl: Configuration area at " & tost(iostart & cfgstart) & "00, 4 kbyte"); else print("ahbctrl: Configuration area disabled"); end if; end if; - for i in 0 to nahbm-1 loop - vendor := msto(i).hconfig(0)(31 downto 24); + + for i in 0 to nahbm - 1 loop + + vendor := msto(i).hconfig(0)(31 downto 24); vendori := conv_integer(vendor); - if vendori /= 0 then - if debug > 1 then - device := msto(i).hconfig(0)(23 downto 12); + + if (vendori /= 0) then + if (debug > 1) then + device := msto(i).hconfig(0)(23 downto 12); devicei := conv_integer(device); print("ahbctrl: mst" & tost(i) & ": " & iptable(vendori).vendordesc & iptable(vendori).device_table(devicei)); end if; - for j in 1 to NAHBIR-1 loop + + for j in 1 to NAHBIR - 1 loop + assert (msto(i).hconfig(j) = zx or FULLPNP or ccheck = 0 or cfgmask = 0) report "AHB master " & tost(i) & " propagates non-zero user defined PnP data, " & - "but AHBCTRL full PnP decoding has not been enabled (check fpnpen VHDL generic)" + "but AHBCTRL full PnP decoding has not been enabled (check fpnpen VHDL generic)" severity warning; + end loop; + assert (msto(i).hindex = i) or (icheck = 0) - report "AHB master index error on master " & tost(i) & - ". Detected index value " & tost(msto(i).hindex) severity failure; + report "AHB master index error on master " & tost(i) & + ". Detected index value " & tost(msto(i).hindex) + severity failure; else - for j in 0 to NAHBCFG-1 loop + + for j in 0 to NAHBCFG - 1 loop + assert (msto(i).hconfig(j) = zx or ccheck = 0) report "AHB master " & tost(i) & " appears to be disabled, " & - "but the master config record is not driven to zero " & - "(check vendor ID or drive unused bus index with appropriate values)." + "but the master config record is not driven to zero " & + "(check vendor ID or drive unused bus index with appropriate values)." severity warning; + end loop; + end if; + end loop; - if nahbm < NAHBMST then - for i in nahbm to NAHBMST-1 loop - for j in 0 to NAHBCFG-1 loop + + if (nahbm < NAHBMST) then + + for i in nahbm to NAHBMST - 1 loop + + for j in 0 to NAHBCFG - 1 loop + assert (msto(i).hconfig(j) = zx or ccheck = 0) report "AHB master " & tost(i) & " is outside the range of " & - "decoded master indexes but the master config record is not driven to zero " & - "(check nahbm VHDL generic)." + "decoded master indexes but the master config record is not driven to zero " & + "(check nahbm VHDL generic)." severity warning; + end loop; + end loop; + end if; - for i in 0 to nahbs-1 loop - vendor := slvo(i).hconfig(0)(31 downto 24); + + for i in 0 to nahbs - 1 loop + + vendor := slvo(i).hconfig(0)(31 downto 24); vendori := conv_integer(vendor); - if vendori /= 0 then - if debug > 1 then - device := slvo(i).hconfig(0)(23 downto 12); + + if (vendori /= 0) then + if (debug > 1) then + device := slvo(i).hconfig(0)(23 downto 12); devicei := conv_integer(device); std.textio.write(L1, "ahbctrl: slv" & tost(i) & ": " & iptable(vendori).vendordesc & iptable(vendori).device_table(devicei)); std.textio.writeline(OUTPUT, L1); end if; - for j in 1 to NAHBIR-1 loop + + for j in 1 to NAHBIR - 1 loop + assert (slvo(i).hconfig(j) = zx or FULLPNP or ccheck = 0 or cfgmask = 0) report "AHB slave " & tost(i) & " propagates non-zero user defined PnP data, " & - "but AHBCTRL full PnP decoding has not been enabled (check fpnpen VHDL generic)." + "but AHBCTRL full PnP decoding has not been enabled (check fpnpen VHDL generic)." severity warning; + end loop; - for j in NAHBIR to NAHBCFG-1 loop - area := slvo(i).hconfig(j)(1 downto 0); - mask := slvo(i).hconfig(j)(15 downto 4); + + for j in NAHBIR to NAHBCFG - 1 loop + + area := slvo(i).hconfig(j)(1 downto 0); + mask := slvo(i).hconfig(j)(15 downto 4); memmap(i)(j mod NAHBIR).start := (others => '0'); - memmap(i)(j mod NAHBIR).stop := (others => '0'); - memmap(i)(j mod NAHBIR).io := slvo(i).hconfig(j)(0); + memmap(i)(j mod NAHBIR).stop := (others => '0'); + memmap(i)(j mod NAHBIR).io := slvo(i).hconfig(j)(0); if (mask /= "000000000000" or fourgslv = 1) then + case area is - when "01" => - when "10" => - k := 0; - while (k<12) and (mask(k) = '0') loop k := k+1; end loop; - if debug > 1 then - std.textio.write(L1, "ahbctrl: memory at " & - tost(slvo(i).hconfig(j)(31 downto 20) and mask) & - "00000, size "& tost(2**k) & " Mbyte"); - if slvo(i).hconfig(j)(16) = '1' then - std.textio.write(L1, string'(", cacheable")); - end if; - if slvo(i).hconfig(j)(17) = '1' then - std.textio.write(L1, string'(", prefetch")); - end if; - std.textio.writeline(OUTPUT, L1); - end if; - memmap(i)(j mod NAHBIR).start(31 downto 20) := slvo(i).hconfig(j)(31 downto 20); - memmap(i)(j mod NAHBIR).start(31 downto 20) := - (slvo(i).hconfig(j)(31 downto 20) and mask); - memmap(i)(j mod NAHBIR).start(19 downto 8) := (others => '0'); - memmap(i)(j mod NAHBIR).stop := memmap(i)(j mod NAHBIR).start + 2**(k+12) - 1; - -- Be verbose if an address with bits set outside the area - -- selected by the mask is encountered - assert ((slvo(i).hconfig(j)(31 downto 20) and not mask) = zero32(11 downto 0)) report - "AHB slave " & tost(i) & " may decode an area larger than intended. Bar " & - tost(j mod NAHBIR) & " will have base address " & - tost(slvo(i).hconfig(j)(31 downto 20) and mask) & - "00000, the intended base address may have been " & - tost(slvo(i).hconfig(j)(31 downto 20)) & "00000" - severity warning; - when "11" => - if ioen /= 0 then + + when "01" => + + when "10" => + k := 0; - while (k<12) and (mask(k) = '0') loop k := k+1; end loop; - memmap(i)(j mod NAHBIR).start := iostart & (slvo(i).hconfig(j)(31 downto 20) and - slvo(i).hconfig(j)(15 downto 4)); - memmap(i)(j mod NAHBIR).stop := memmap(i)(j mod NAHBIR).start + 2**k - 1; - if debug > 1 then - iosize := 256 * 2**k; iounit(1) := ' '; - if (iosize > 1023) then - iosize := iosize/1024; iounit(1) := 'k'; + + while (k<12) and (mask(k) = '0') loop + + k := k + 1; + + end loop; + + if (debug > 1) then + std.textio.write(L1, "ahbctrl: memory at " & + tost(slvo(i).hconfig(j)(31 downto 20) and mask) & + "00000, size "& tost(2 ** k) & " Mbyte"); + if (slvo(i).hconfig(j)(16) = '1') then + std.textio.write(L1, string'(", cacheable")); end if; - print("ahbctrl: I/O port at " & tost(iostart & - ((slvo(i).hconfig(j)(31 downto 20)) and slvo(i).hconfig(j)(15 downto 4))) & - "00, size "& tost(iosize) & iounit); + if (slvo(i).hconfig(j)(17) = '1') then + std.textio.write(L1, string'(", prefetch")); + end if; + std.textio.writeline(OUTPUT, L1); end if; - assert ((slvo(i).hconfig(j)(31 downto 20) and not mask) = zero32(11 downto 0)) report - "AHB slave " & tost(i) & " may decode an I/O area larger than intended. Bar " & - tost(j mod NAHBIR) & " will have base address " & - tost(iostart & (slvo(i).hconfig(j)(31 downto 20) and mask)) & - "00, the intended base address may have been " & - tost(iostart & slvo(i).hconfig(j)(31 downto 20)) & "00" - severity warning; - else - assert false report - "AHB slave " & tost(i) & " maps bar " & tost(j mod NAHBIR) & - " to the IO area, but this AHBCTRL has been configured with VHDL generic ioen = 0" + memmap(i)(j mod NAHBIR).start(31 downto 20) := slvo(i).hconfig(j)(31 downto 20); + memmap(i)(j mod NAHBIR).start(31 downto 20) := (slvo(i).hconfig(j)(31 downto 20) and mask); + memmap(i)(j mod NAHBIR).start(19 downto 8) := (others => '0'); + memmap(i)(j mod NAHBIR).stop := memmap(i)(j mod NAHBIR).start + 2 ** (k + 12) - 1; + -- Be verbose if an address with bits set outside the area + -- selected by the mask is encountered + assert ((slvo(i).hconfig(j)(31 downto 20) and not mask) = zero32(11 downto 0)) + report + "AHB slave " & tost(i) & " may decode an area larger than intended. Bar " & + tost(j mod NAHBIR) & " will have base address " & + tost(slvo(i).hconfig(j)(31 downto 20) and mask) & + "00000, the intended base address may have been " & + tost(slvo(i).hconfig(j)(31 downto 20)) & "00000" severity warning; - end if; - when others => + + when "11" => + + if (ioen /= 0) then + k := 0; + + while (k<12) and (mask(k) = '0') loop + + k := k + 1; + + end loop; + + memmap(i)(j mod NAHBIR).start := iostart & (slvo(i).hconfig(j)(31 downto 20) and + slvo(i).hconfig(j)(15 downto 4)); + memmap(i)(j mod NAHBIR).stop := memmap(i)(j mod NAHBIR).start + 2 ** k - 1; + if (debug > 1) then + iosize := 256 * 2 ** k; iounit(1) := ' '; + if (iosize > 1023) then + iosize := iosize / 1024; iounit(1) := 'k'; + end if; + print("ahbctrl: I/O port at " & tost(iostart & + ((slvo(i).hconfig(j)(31 downto 20)) and slvo(i).hconfig(j)(15 downto 4))) & + "00, size "& tost(iosize) & iounit); + end if; + assert ((slvo(i).hconfig(j)(31 downto 20) and not mask) = zero32(11 downto 0)) + report + "AHB slave " & tost(i) & " may decode an I/O area larger than intended. Bar " & + tost(j mod NAHBIR) & " will have base address " & + tost(iostart & (slvo(i).hconfig(j)(31 downto 20) and mask)) & + "00, the intended base address may have been " & + tost(iostart & slvo(i).hconfig(j)(31 downto 20)) & "00" + severity warning; + else + assert false + report + "AHB slave " & tost(i) & " maps bar " & tost(j mod NAHBIR) & + " to the IO area, but this AHBCTRL has been configured with VHDL generic ioen = 0" + severity warning; + end if; + + when others => + end case; + end if; + end loop; + assert (slvo(i).hindex = i) or (icheck = 0) - report "AHB slave index error on slave " & tost(i) & - ". Detected index value " & tost(slvo(i).hindex) severity failure; - if mcheck /= 0 then + report "AHB slave index error on slave " & tost(i) & + ". Detected index value " & tost(slvo(i).hindex) + severity failure; + if (mcheck /= 0) then + for j in 0 to i loop + for k in memmap(i)'range loop - if memmap(i)(k).stop /= zero32(memmap(i)(k).stop'range) then + + if (memmap(i)(k).stop /= zero32(memmap(i)(k).stop'range)) then + for l in memmap(j)'range loop + assert ((memmap(i)(k).start >= memmap(j)(l).stop) or (memmap(i)(k).stop <= memmap(j)(l).start) or (mcheck /= 2 and (memmap(i)(k).io xor memmap(j)(l).io) = '1') or (i = j and k = l)) report "AHB slave " & tost(i) & " bank " & tost(k) & - " intersects with AHB slave " & tost(j) & " bank " & tost(l) + " intersects with AHB slave " & tost(j) & " bank " & tost(l) severity failure; + end loop; + end if; + end loop; + end loop; + end if; else - for j in 0 to NAHBCFG-1 loop + + for j in 0 to NAHBCFG - 1 loop + assert (slvo(i).hconfig(j) = zx or ccheck = 0) report "AHB slave " & tost(i) & " appears to be disabled, " & - "but the slave config record is not driven to zero " & - "(check vendor ID or drive unused bus index with appropriate values)." + "but the slave config record is not driven to zero " & + "(check vendor ID or drive unused bus index with appropriate values)." severity warning; + end loop; + end if; + end loop; - if nahbs < NAHBSLV then - for i in nahbs to NAHBSLV-1 loop - for j in 0 to NAHBCFG-1 loop + + if (nahbs < NAHBSLV) then + + for i in nahbs to NAHBSLV - 1 loop + + for j in 0 to NAHBCFG - 1 loop + assert (slvo(i).hconfig(j) = zx or ccheck = 0) report "AHB slave " & tost(i) & " is outside the range of " & - "decoded slave indexes but the slave config record is not driven to zero " & - "(check nahbs VHDL generic)." + "decoded slave indexes but the slave config record is not driven to zero " & + "(check nahbs VHDL generic)." severity warning; + end loop; + end loop; + end if; + wait; - end process; + + end process diag; -- pragma translate_on -end; +end architecture rtl; diff --git a/rtl/sockets/csr/esp_csr_pkg.vhd b/rtl/sockets/csr/esp_csr_pkg.vhd index ee0bee1613..1a64cf3555 100644 --- a/rtl/sockets/csr/esp_csr_pkg.vhd +++ b/rtl/sockets/csr/esp_csr_pkg.vhd @@ -2,88 +2,89 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; - -use work.esp_global.all; -use work.amba.all; -use work.monitor_pkg.all; + use ieee.std_logic_1164.all; + use work.esp_global.all; + use work.amba.all; + use work.monitor_pkg.all; package esp_csr_pkg is constant ESP_CSR_8_LSB : integer := 79 + CFG_NCPU_TILE * 2 * 3; constant ESP_CSR_WIDTH : integer := 98 + ESP_CSR_8_LSB; - constant ESP_CSR_VALID_ADDR : integer range 0 to 31 := 0; - constant ESP_CSR_VALID_LSB : integer range 0 to ESP_CSR_WIDTH-1 := 0; - constant ESP_CSR_VALID_MSB : integer range 0 to ESP_CSR_WIDTH-1 := 0; + constant ESP_CSR_VALID_ADDR : integer range 0 to 31 := 0; + constant ESP_CSR_VALID_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 0; + constant ESP_CSR_VALID_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 0; - constant ESP_CSR_TILE_ID_ADDR : integer range 0 to 31 := 1; - constant ESP_CSR_TILE_ID_LSB : integer range 0 to ESP_CSR_WIDTH-1 := 1; - constant ESP_CSR_TILE_ID_MSB : integer range 0 to ESP_CSR_WIDTH-1 := 8; + constant ESP_CSR_TILE_ID_ADDR : integer range 0 to 31 := 1; + constant ESP_CSR_TILE_ID_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 1; + constant ESP_CSR_TILE_ID_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 8; - constant ESP_CSR_PAD_CFG_ADDR : integer range 0 to 31 := 2; - constant ESP_CSR_PAD_CFG_LSB : integer range 0 to ESP_CSR_WIDTH-1 := 9; - constant ESP_CSR_PAD_CFG_MSB : integer range 0 to ESP_CSR_WIDTH-1 := 11; + constant ESP_CSR_PAD_CFG_ADDR : integer range 0 to 31 := 2; + constant ESP_CSR_PAD_CFG_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 9; + constant ESP_CSR_PAD_CFG_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 11; - constant ESP_CSR_DCO_CFG_ADDR : integer range 0 to 31 := 3; - constant ESP_CSR_DCO_CFG_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 12; - constant ESP_CSR_DCO_CFG_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 42; + constant ESP_CSR_DCO_CFG_ADDR : integer range 0 to 31 := 3; + constant ESP_CSR_DCO_CFG_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 12; + constant ESP_CSR_DCO_CFG_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 42; - constant ESP_CSR_DCO_NOC_CFG_ADDR : integer range 0 to 31 := 4; - constant ESP_CSR_DCO_NOC_CFG_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 43; - constant ESP_CSR_DCO_NOC_CFG_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 61; + constant ESP_CSR_DCO_NOC_CFG_ADDR : integer range 0 to 31 := 4; + constant ESP_CSR_DCO_NOC_CFG_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 43; + constant ESP_CSR_DCO_NOC_CFG_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 61; - constant ESP_CSR_MDC_SCALER_CFG_ADDR : integer range 0 to 31 := 5; - constant ESP_CSR_MDC_SCALER_CFG_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 62; - constant ESP_CSR_MDC_SCALER_CFG_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 72; + constant ESP_CSR_MDC_SCALER_CFG_ADDR : integer range 0 to 31 := 5; + constant ESP_CSR_MDC_SCALER_CFG_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 62; + constant ESP_CSR_MDC_SCALER_CFG_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 72; - constant ESP_CSR_ARIANE_HARTID_ADDR : integer range 0 to 31 := 6; - constant ESP_CSR_ARIANE_HARTID_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 73; - constant ESP_CSR_ARIANE_HARTID_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 77; + constant ESP_CSR_ARIANE_HARTID_ADDR : integer range 0 to 31 := 6; + constant ESP_CSR_ARIANE_HARTID_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 73; + constant ESP_CSR_ARIANE_HARTID_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 77; - constant ESP_CSR_CPU_LOC_OVR_ADDR : integer range 0 to 31 := 7; - constant ESP_CSR_CPU_LOC_OVR_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 78; - constant ESP_CSR_CPU_LOC_OVR_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 78 + CFG_NCPU_TILE * 2 * 3; + constant ESP_CSR_CPU_LOC_OVR_ADDR : integer range 0 to 31 := 7; + constant ESP_CSR_CPU_LOC_OVR_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 78; + constant ESP_CSR_CPU_LOC_OVR_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 78 + CFG_NCPU_TILE * 2 * 3; - constant ESP_CSR_DDR_CFG0_ADDR : integer range 0 to 31 := 8; - constant ESP_CSR_DDR_CFG0_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := ESP_CSR_8_LSB; - constant ESP_CSR_DDR_CFG0_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 31 + ESP_CSR_8_LSB; + constant ESP_CSR_DDR_CFG0_ADDR : integer range 0 to 31 := 8; + constant ESP_CSR_DDR_CFG0_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := ESP_CSR_8_LSB; + constant ESP_CSR_DDR_CFG0_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 31 + ESP_CSR_8_LSB; - constant ESP_CSR_DDR_CFG1_ADDR : integer range 0 to 31 := 9; - constant ESP_CSR_DDR_CFG1_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 32 + ESP_CSR_8_LSB; - constant ESP_CSR_DDR_CFG1_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 63 + ESP_CSR_8_LSB; + constant ESP_CSR_DDR_CFG1_ADDR : integer range 0 to 31 := 9; + constant ESP_CSR_DDR_CFG1_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 32 + ESP_CSR_8_LSB; + constant ESP_CSR_DDR_CFG1_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 63 + ESP_CSR_8_LSB; - constant ESP_CSR_DDR_CFG2_ADDR : integer range 0 to 31 := 10; - constant ESP_CSR_DDR_CFG2_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 64 + ESP_CSR_8_LSB; - constant ESP_CSR_DDR_CFG2_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 95 + ESP_CSR_8_LSB; + constant ESP_CSR_DDR_CFG2_ADDR : integer range 0 to 31 := 10; + constant ESP_CSR_DDR_CFG2_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 64 + ESP_CSR_8_LSB; + constant ESP_CSR_DDR_CFG2_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 95 + ESP_CSR_8_LSB; - constant ESP_CSR_ACC_COH_ADDR : integer range 0 to 31 := 11; - constant ESP_CSR_ACC_COH_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 96 + ESP_CSR_8_LSB; - constant ESP_CSR_ACC_COH_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 97 + ESP_CSR_8_LSB; + constant ESP_CSR_ACC_COH_ADDR : integer range 0 to 31 := 11; + constant ESP_CSR_ACC_COH_LSB : integer range 0 to ESP_CSR_WIDTH - 1 := 96 + ESP_CSR_8_LSB; + constant ESP_CSR_ACC_COH_MSB : integer range 0 to ESP_CSR_WIDTH - 1 := 97 + ESP_CSR_8_LSB; constant ESP_CSR_SRST_ADDR : integer range 0 to 31 := 31; -- reserved address constant DCO_CFG_LPDDR_CTRL_BITS : integer range 0 to 31 := 12; - component esp_tile_csr + component esp_tile_csr is generic ( - pindex : integer range 0 to NAPBSLV - 1; - dco_rst_cfg : std_logic_vector(30 downto 0) := (others => '0')); + pindex : integer range 0 to NAPBSLV - 1; + dco_rst_cfg : std_logic_vector(30 downto 0) := (others => '0') + ); port ( - clk : in std_logic; - rstn : in std_logic; - pconfig : in apb_config_type; - mon_ddr : in monitor_ddr_type; - mon_mem : in monitor_mem_type; - mon_noc : in monitor_noc_vector(1 to 6); - mon_l2 : in monitor_cache_type; - mon_llc : in monitor_cache_type; - mon_acc : in monitor_acc_type; - mon_dvfs : in monitor_dvfs_type; - tile_config : out std_logic_vector(ESP_CSR_WIDTH - 1 downto 0); - srst : out std_ulogic; - apbi : in apb_slv_in_type; - apbo : out apb_slv_out_type); + clk : in std_logic; + rstn : in std_logic; + pconfig : in apb_config_type; + mon_ddr : in monitor_ddr_type; + mon_mem : in monitor_mem_type; + mon_noc : in monitor_noc_vector(1 to 6); + mon_l2 : in monitor_cache_type; + mon_llc : in monitor_cache_type; + mon_acc : in monitor_acc_type; + mon_dvfs : in monitor_dvfs_type; + tile_config : out std_logic_vector(ESP_CSR_WIDTH - 1 downto 0); + srst : out std_ulogic; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type + ); end component; -end esp_csr_pkg; +end package esp_csr_pkg; diff --git a/rtl/sockets/dvfs/dvfs.vhd b/rtl/sockets/dvfs/dvfs.vhd index 3f83a6829d..1b1f8c0957 100644 --- a/rtl/sockets/dvfs/dvfs.vhd +++ b/rtl/sockets/dvfs/dvfs.vhd @@ -2,53 +2,51 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; - ---pragma translate_off -use STD.textio.all; -use ieee.std_logic_textio.all; ---pragma translate_on - -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; - -use work.gencomp.all; -use work.genacc.all; - -use work.nocpackage.all; - -use work.esp_acc_regmap.all; + use ieee.std_logic_1164.all; + + -- pragma translate_off + use std.textio.all; + use ieee.std_logic_textio.all; + -- pragma translate_on + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.genacc.all; + use work.nocpackage.all; + use work.esp_acc_regmap.all; package dvfs is function tech_v ( constant tech : integer; - constant vlevel : integer) + constant vlevel : integer + ) return std_logic_vector; function tech_f ( constant tech : integer; - constant vlevel : integer) + constant vlevel : integer + ) return std_logic_vector; - constant DVFS_CMD_REG : integer range 0 to MAXREGNUM-1 := 0; - constant DVFS_CMD_UPDATE_V_BIT : integer range 0 to 31 := 0; - constant DVFS_CMD_UPDATE_F_BIT : integer range 0 to 31 := 1; - constant DVFS_CMD_UPDATE_VF_BIT : integer range 0 to 31 := 2; - constant DVFS_CMD_REG_WIDTH : integer range 0 to 31 := 3; + constant DVFS_CMD_REG : integer range 0 to MAXREGNUM - 1 := 0; + constant DVFS_CMD_UPDATE_V_BIT : integer range 0 to 31 := 0; + constant DVFS_CMD_UPDATE_F_BIT : integer range 0 to 31 := 1; + constant DVFS_CMD_UPDATE_VF_BIT : integer range 0 to 31 := 2; + constant DVFS_CMD_REG_WIDTH : integer range 0 to 31 := 3; -- Current voltage: 1 hot encoding - constant VOLTAGE_STATUS_REG : integer range 0 to MAXREGNUM-1 := 1; + constant VOLTAGE_STATUS_REG : integer range 0 to MAXREGNUM - 1 := 1; -- Current frequency 1 hot encoding; - constant FREQUENCY_STATUS_REG : integer range 0 to MAXREGNUM-1 := 2; + constant FREQUENCY_STATUS_REG : integer range 0 to MAXREGNUM - 1 := 2; -- Set voltage when POLICY_NONE is selected: 1 hot encoding - constant VOLTAGE_SELECT_REG : integer range 0 to MAXREGNUM-1 := 3; + constant VOLTAGE_SELECT_REG : integer range 0 to MAXREGNUM - 1 := 3; -- Set frequency when POLICY_NONE is selected: 1 hot encoding; - constant FREQUENCY_SELECT_REG : integer range 0 to MAXREGNUM-1 := 4; + constant FREQUENCY_SELECT_REG : integer range 0 to MAXREGNUM - 1 := 4; - constant POLICY_REG : integer range 0 to MAXREGNUM-1 := 5; + constant POLICY_REG : integer range 0 to MAXREGNUM - 1 := 5; -- NONE: VF pair set by software -- AUTO_BUDGET: VF chosen depending on the power budget (requires current sensing) -- AUTO_ONDEMAND: VF chosen depending on the accelerator burstiness (used for NoC planes) @@ -61,72 +59,90 @@ package dvfs is constant POLICY_AUTO_BALANCE_BIT : integer range 0 to 31 := 4; -- Power budget: set the maximum allowd operation point - constant BUDGET_REG : integer range 0 to MAXREGNUM-1 := 6; + constant BUDGET_REG : integer range 0 to MAXREGNUM - 1 := 6; -- Power consumption per each VF pair - constant POWER_VF_0_REG : integer range 0 to MAXREGNUM-1 := 7; - constant POWER_VF_1_REG : integer range 0 to MAXREGNUM-1 := 8; - constant POWER_VF_2_REG : integer range 0 to MAXREGNUM-1 := 9; - constant POWER_VF_3_REG : integer range 0 to MAXREGNUM-1 := 10; + constant POWER_VF_0_REG : integer range 0 to MAXREGNUM - 1 := 7; + constant POWER_VF_1_REG : integer range 0 to MAXREGNUM - 1 := 8; + constant POWER_VF_2_REG : integer range 0 to MAXREGNUM - 1 := 9; + constant POWER_VF_3_REG : integer range 0 to MAXREGNUM - 1 := 10; -- Minimum period before next update in cycles - constant MIN_WAIT_REG : integer range 0 to MAXREGNUM-1 := 11; + constant MIN_WAIT_REG : integer range 0 to MAXREGNUM - 1 := 11; -- Feedback from IVR. Ideally information on current - constant QADC_REG : integer range 0 to MAXREGNUM-1 := 12; + constant QADC_REG : integer range 0 to MAXREGNUM - 1 := 12; -- PLL frequency change mode: DYNAMIC (default), RESET - constant PLL_MODE_REG : integer range 0 to MAXREGNUM-1 := 13; - constant PLL_MODE_DFS_BIT : integer range 0 to 31 := 0; - constant PLL_MODE_RST_BIT : integer range 0 to 31 := 1; + constant PLL_MODE_REG : integer range 0 to MAXREGNUM - 1 := 13; + constant PLL_MODE_DFS_BIT : integer range 0 to 31 := 0; + constant PLL_MODE_RST_BIT : integer range 0 to 31 := 1; -- PLICY_AUTO_WINDOW: take decision every WINDOW cycles -- POLICY_*_TH: slow down accelerator if below/above threshold - constant POLICY_AUTO_WINDOW_REG : integer range 0 to MAXREGNUM-1 := 14; - constant POLICY_ONDEMAND_TH_REG : integer range 0 to MAXREGNUM-1 := 15; - constant POLICY_TRAFFIC_TH_REG : integer range 0 to MAXREGNUM-1 := 16; - constant POLICY_BALANCE_TH_REG : integer range 0 to MAXREGNUM-1 := 17; + constant POLICY_AUTO_WINDOW_REG : integer range 0 to MAXREGNUM - 1 := 14; + constant POLICY_ONDEMAND_TH_REG : integer range 0 to MAXREGNUM - 1 := 15; + constant POLICY_TRAFFIC_TH_REG : integer range 0 to MAXREGNUM - 1 := 16; + constant POLICY_BALANCE_TH_REG : integer range 0 to MAXREGNUM - 1 := 17; -end dvfs; +end package dvfs; package body dvfs is function tech_v ( constant tech : integer; - constant vlevel : integer) + constant vlevel : integer + ) return std_logic_vector is + variable ddac : std_logic_vector(4 downto 0); + begin + ddac := (others => '0'); - if tech = virtex7 or tech = virtexup then + if (tech = virtex7 or tech = virtexup) then + for i in 0 to 4 loop - if vlevel = i then + + if (vlevel = i) then ddac(i) := '1'; end if; + end loop; -- i + end if; return ddac; - end tech_v; + + end function tech_v; function tech_f ( constant tech : integer; - constant vlevel : integer) + constant vlevel : integer + ) return std_logic_vector is + variable rangea : std_logic_vector(4 downto 0); + begin + rangea := (others => '0'); - if tech = virtex7 or tech = virtexup then + if (tech = virtex7 or tech = virtexup) then + for i in 0 to 4 loop - if vlevel = i then + + if (vlevel = i) then rangea(i) := '1'; end if; + end loop; -- i + end if; return rangea; - end tech_f; -end dvfs; + end function tech_f; + +end package body dvfs; diff --git a/rtl/sockets/jtag/apb2jtag.vhd b/rtl/sockets/jtag/apb2jtag.vhd index ceebe7846b..36d15540d5 100644 --- a/rtl/sockets/jtag/apb2jtag.vhd +++ b/rtl/sockets/jtag/apb2jtag.vhd @@ -2,82 +2,84 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.esp_global.all; -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; -use work.gencomp.all; -use work.leon3.all; -use work.ariane_esp_pkg.all; -use work.misc.all; --- pragma translate_off -use work.sim.all; -library unisim; -use unisim.all; --- pragma translate_on -use work.monitor_pkg.all; -use work.sldacc.all; -use work.nocpackage.all; -use work.tile.all; -use work.cachepackage.all; -use work.coretypes.all; -use work.grlib_config.all; -use work.socmap.all; -use work.jtag_pkg.all; - + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.esp_global.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.leon3.all; + use work.ariane_esp_pkg.all; + use work.misc.all; + -- pragma translate_off + use work.sim.all; +library unisim; + use unisim.all; + -- pragma translate_on + use work.monitor_pkg.all; + use work.sldacc.all; + use work.nocpackage.all; + use work.tile.all; + use work.cachepackage.all; + use work.coretypes.all; + use work.grlib_config.all; + use work.socmap.all; + use work.jtag_pkg.all; entity apb2jtag is port ( - rst : in std_ulogic; - tclk : in std_logic; - main_clk : in std_logic; - apbi : in apb_slv_in_type; - apbo : out apb_slv_out_type; - apbreq : in std_logic; - ack2apb : out std_logic; - req_flit : in std_logic_vector(5 downto 0); - empty_fifo : out std_logic_vector(5 downto 0); - piso_c : in std_logic; - piso_l : in std_logic; - piso_en : in std_logic; - load_invld : in std_logic; - tdi : out std_logic); -end apb2jtag; - + rst : in std_ulogic; + tclk : in std_logic; + main_clk : in std_logic; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type; + apbreq : in std_logic; + ack2apb : out std_logic; + req_flit : in std_logic_vector(5 downto 0); + empty_fifo : out std_logic_vector(5 downto 0); + piso_c : in std_logic; + piso_l : in std_logic; + piso_en : in std_logic; + load_invld : in std_logic; + tdi : out std_logic + ); +end entity apb2jtag; architecture rtl of apb2jtag is - constant reg_a2j_pindex : integer range 0 to NAPBSLV - 1 := 0; - constant reg_a2j_paddr : integer range 0 to 4095 := 16#100#; - constant reg_a2j_pmask : integer range 0 to 4095 := 16#FFF#; - constant invld_flit : std_logic_vector(MAX_NOC_FLIT_SIZE+8 downto 0) := conv_std_logic_vector(5, MAX_NOC_FLIT_SIZE+9); - signal this_paddr, this_pmask : integer range 0 to 4095; - signal this_pirq : integer range 0 to 15; + constant REG_A2J_PINDEX : integer range 0 to NAPBSLV - 1 := 0; + constant REG_A2J_PADDR : integer range 0 to 4095 := 16#100#; + constant REG_A2J_PMASK : integer range 0 to 4095 := 16#FFF#; + constant INVLD_FLIT : std_logic_vector(MAX_NOC_FLIT_SIZE + 8 downto 0) := conv_std_logic_vector(5, MAX_NOC_FLIT_SIZE + 9); + signal this_paddr, this_pmask : integer range 0 to 4095; + signal this_pirq : integer range 0 to 15; signal this_pconfig : apb_config_type; type tracein_t is array(0 to 5) of std_logic_vector(74 downto 0); - signal tracein, tracein1 : tracein_t; + signal tracein, tracein1 : tracein_t; signal tdi_in : std_logic; - signal full_fifo, en_fifo_in, ack : std_logic_vector(5 downto 0); - signal trace_in, fifo_out, piso_in : std_logic_vector(74 downto 0); + signal full_fifo : std_logic_vector(5 downto 0); + signal en_fifo_in : std_logic_vector(5 downto 0); + signal ack : std_logic_vector(5 downto 0); + signal trace_in : std_logic_vector(74 downto 0); + signal fifo_out : std_logic_vector(74 downto 0); + signal piso_in : std_logic_vector(74 downto 0); attribute mark_debug : string; - attribute mark_debug of trace_in : signal is "true"; + attribute mark_debug of trace_in : signal is "true"; attribute mark_debug of en_fifo_in : signal is "true"; attribute mark_debug of full_fifo : signal is "true"; - attribute mark_debug of tracein : signal is "true"; + attribute mark_debug of tracein : signal is "true"; attribute mark_debug of tracein1 : signal is "true"; attribute mark_debug of fifo_out : signal is "true"; @@ -85,8 +87,8 @@ architecture rtl of apb2jtag is begin - this_paddr <= reg_a2j_paddr; - this_pmask <= reg_a2j_pmask; + this_paddr <= REG_A2J_PADDR; + this_pmask <= REG_A2J_PMASK; this_pirq <= 0; this_pconfig(0) <= ahb_device_reg (VENDOR_SLD, 0, 0, 0, 0); @@ -95,9 +97,10 @@ begin ack <= not(full_fifo); - apb2jtag_reg_i : apb2jtag_reg + apb2jtag_reg_i : component apb2jtag_reg generic map ( - pindex => 0) + pindex => 0 + ) port map ( clk => main_clk, rstn => rst, @@ -109,11 +112,12 @@ begin apbreq => apbreq, valid => en_fifo_in, out_p => trace_in - ); + ); - demux_i : demux_1to6_vs + demux_i : component demux_1to6_vs generic map ( - SZ => MAX_NOC_FLIT_SIZE+9) + sz => MAX_NOC_FLIT_SIZE + 9 + ) port map ( data_in => trace_in, sel => en_fifo_in, @@ -123,18 +127,15 @@ begin out4 => tracein(3), out5 => tracein(4), out6 => tracein(5) - ); - - + ); + gen_fifos_apb2jtag : for i in 0 to 5 generate - - GEN_FIFOS_apb2jtag : for i in 0 to 5 generate - - async_fifo_01 : inferred_async_fifo + async_fifo_01 : component inferred_async_fifo generic map ( - g_data_width => MAX_NOC_FLIT_SIZE+9, - g_size => 200) + g_data_width => MAX_NOC_FLIT_SIZE + 9, + g_size => 200 + ) port map ( rst_wr_n_i => rst, clk_wr_i => main_clk, @@ -145,38 +146,45 @@ begin clk_rd_i => tclk, rd_i => req_flit(i), q_o => tracein1(i), - rd_empty_o => empty_fifo(i)); + rd_empty_o => empty_fifo(i) + ); - end generate GEN_FIFOS_apb2jtag; + end generate gen_fifos_apb2jtag; - mux_6to1_1 : mux_6to1 - generic map(sz => MAX_NOC_FLIT_SIZE+9) - port map( + mux_6to1_1 : component mux_6to1 + generic map ( + sz => MAX_NOC_FLIT_SIZE + 9 + ) + port map ( sel => req_flit, - A => tracein1(5), - B => tracein1(4), - C => tracein1(3), - D => tracein1(2), - E => tracein1(1), - F => tracein1(0), - X => fifo_out); - - piso_in <= fifo_out when load_invld = '0' else invld_flit; - - piso0 : piso_jtag - generic map(sz => MAX_NOC_FLIT_SIZE+9, - shift_dir => 1) - port map( + a => tracein1(5), + b => tracein1(4), + c => tracein1(3), + d => tracein1(2), + e => tracein1(1), + f => tracein1(0), + x => fifo_out + ); + + piso_in <= fifo_out when load_invld = '0' else + INVLD_FLIT; + + piso0 : component piso_jtag + generic map ( + sz => MAX_NOC_FLIT_SIZE + 9, + shift_dir => 1 + ) + port map ( rst => rst, clk => tclk, clear => piso_c, load => piso_l, - A => piso_in, + a => piso_in, shift_en => piso_en, - Y => tdi_in, - done => open); + y => tdi_in, + done => open + ); tdi <= tdi_in; - -end; +end architecture rtl; diff --git a/rtl/sockets/monitor/monitor.vhd b/rtl/sockets/monitor/monitor.vhd index a20d1104af..02c74b30f2 100644 --- a/rtl/sockets/monitor/monitor.vhd +++ b/rtl/sockets/monitor/monitor.vhd @@ -2,27 +2,25 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; + use ieee.std_logic_1164.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.allclkgen.all; -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; -use work.gencomp.all; -use work.allclkgen.all; + -- pragma translate off + use std.textio.all; ---pragma translate off -use std.textio.all; library unisim; -use unisim.vcomponents.all; ---pragma translate_on + use unisim.vcomponents.all; +-- pragma translate_on library profpga; - -use work.monitor_pkg.all; + use work.monitor_pkg.all; entity monitor is - generic ( memtech : integer; mmi64_width : integer; @@ -40,180 +38,192 @@ entity monitor is mon_mem_en : integer; mon_l2_en : integer; mon_llc_en : integer; - mon_dvfs_en : integer); + mon_dvfs_en : integer + ); port ( - profpga_clk0_p : in std_logic; -- 100 MHz clock - profpga_clk0_n : in std_logic; -- 100 MHz clock - profpga_sync0_p : in std_logic; - profpga_sync0_n : in std_logic; - dmbi_h2f : in std_logic_vector(19 downto 0); - dmbi_f2h : out std_logic_vector(19 downto 0); - user_rstn : in std_logic; - mon_ddr : in monitor_ddr_vector(0 to ddrs_num-1); - mon_noc : in monitor_noc_matrix(0 to nocs_num-1, 0 to tiles_num-1); - mon_acc : in monitor_acc_vector(0 to relu(accelerators_num-1)); - mon_mem : in monitor_mem_vector(0 to ddrs_num+slms_num-1); - mon_l2 : in monitor_cache_vector(0 to relu(l2_num-1)); - mon_llc : in monitor_cache_vector(0 to relu(llc_num-1)); - mon_dvfs : in monitor_dvfs_vector(0 to tiles_num-1) - ); - -end monitor; + profpga_clk0_p : in std_logic; -- 100 MHz clock + profpga_clk0_n : in std_logic; -- 100 MHz clock + profpga_sync0_p : in std_logic; + profpga_sync0_n : in std_logic; + dmbi_h2f : in std_logic_vector(19 downto 0); + dmbi_f2h : out std_logic_vector(19 downto 0); + user_rstn : in std_logic; + mon_ddr : in monitor_ddr_vector(0 to ddrs_num - 1); + mon_noc : in monitor_noc_matrix(0 to nocs_num - 1, 0 to tiles_num - 1); + mon_acc : in monitor_acc_vector(0 to relu(accelerators_num - 1)); + mon_mem : in monitor_mem_vector(0 to ddrs_num + slms_num - 1); + mon_l2 : in monitor_cache_vector(0 to relu(l2_num - 1)); + mon_llc : in monitor_cache_vector(0 to relu(llc_num - 1)); + mon_dvfs : in monitor_dvfs_vector(0 to tiles_num - 1) + ); +end entity monitor; architecture rtl of monitor is type syscom_dn_t is array (integer range 0 to 0) of std_logic_vector(67 downto 0); + type syscom_up_t is array (integer range 0 to 0) of std_logic_vector(68 downto 0); subtype profpga_tech_description is string(1 to 4); + type profpga_device_table_t is array (0 to NTECH) of profpga_tech_description; - constant profpga_device_table : profpga_device_table_t := ( - virtex7 => "XV7S", - virtexu => "XVUS", + + constant PROFPGA_DEVICE_TABLE : profpga_device_table_t := + ( + virtex7 => "XV7S", + virtexu => "XVUS", virtexup => "XVUP", - others => "NONE"); + others => "NONE" + ); component synchronizer is generic ( - DATA_WIDTH : integer - ); + data_width : integer + ); port ( - clk : in std_logic; - reset_n : in std_logic; - data_i : in std_logic_vector(DATA_WIDTH-1 downto 0); - data_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); - end component; + clk : in std_logic; + reset_n : in std_logic; + data_i : in std_logic_vector(DATA_WIDTH - 1 downto 0); + data_o : out std_logic_vector(DATA_WIDTH - 1 downto 0) + ); + end component; - component profpga_ctrl is + component profpga_ctrl is generic ( - DEVICE : string := "XV7S"); + device : string := "XV7S" + ); port ( -- access to FPGA pins - clk0_p : in std_logic; - clk0_n : in std_logic; - sync0_p : in std_logic; - sync0_n : in std_logic; - srcclk_p : out std_logic_vector(3 downto 0); - srcclk_n : out std_logic_vector(3 downto 0); - srcsync_p : out std_logic_vector(3 downto 0); - srcsync_n : out std_logic_vector(3 downto 0); - dmbi_h2f : in std_logic_vector(19 downto 0); - dmbi_f2h : out std_logic_vector(19 downto 0); - xdmbi_h2f : in std_logic_vector(3 downto 0); - xdmbi_f2h : out std_logic_vector(3 downto 0); + clk0_p : in std_logic; + clk0_n : in std_logic; + sync0_p : in std_logic; + sync0_n : in std_logic; + srcclk_p : out std_logic_vector(3 downto 0); + srcclk_n : out std_logic_vector(3 downto 0); + srcsync_p : out std_logic_vector(3 downto 0); + srcsync_n : out std_logic_vector(3 downto 0); + dmbi_h2f : in std_logic_vector(19 downto 0); + dmbi_f2h : out std_logic_vector(19 downto 0); + xdmbi_h2f : in std_logic_vector(3 downto 0); + xdmbi_f2h : out std_logic_vector(3 downto 0); -- 200 MHz clock (useful for IDELAYCTRL calibration) - clk_200mhz_o : out std_logic; + clk_200mhz_o : out std_logic; -- source clock/sync input - src_clk_i : in std_logic_vector(3 downto 0) := "0000"; + src_clk_i : in std_logic_vector(3 downto 0) := "0000"; -- the following signals are synchronous to the associated src_clk_i(i) - src_clk_locked_i : in std_logic_vector(3 downto 0) := "0000"; - src_event_id_i : in std_logic_vector(3*8+7 downto 0) := (others => '0'); - src_event_en_i : in std_logic_vector(3 downto 0) := "0000"; - src_event_busy_o : out std_logic_vector(3 downto 0); - src_event_reset_i : in std_logic_vector(3 downto 0) := "1111"; - src_event_strobe1_i : in std_logic_vector(3 downto 0) := "0000"; - src_event_strobe2_i : in std_logic_vector(3 downto 0) := "0000"; + src_clk_locked_i : in std_logic_vector(3 downto 0) := "0000"; + src_event_id_i : in std_logic_vector(3 * 8 + 7 downto 0) := (others => '0'); + src_event_en_i : in std_logic_vector(3 downto 0) := "0000"; + src_event_busy_o : out std_logic_vector(3 downto 0); + src_event_reset_i : in std_logic_vector(3 downto 0) := "1111"; + src_event_strobe1_i : in std_logic_vector(3 downto 0) := "0000"; + src_event_strobe2_i : in std_logic_vector(3 downto 0) := "0000"; -- clk0 sync events (synchronous to mmi64_clk) - clk0_event_id_o : out std_logic_vector(7 downto 0); - clk0_event_en_o : out std_logic; - clk0_event_strobe1_o : out std_logic; - clk0_event_strobe2_o : out std_logic; + clk0_event_id_o : out std_logic_vector(7 downto 0); + clk0_event_en_o : out std_logic; + clk0_event_strobe1_o : out std_logic; + clk0_event_strobe2_o : out std_logic; -- MMI-64 access (synchronous to mmi64_clk) - mmi64_present_i : in std_logic := '0'; - mmi64_clk_o : out std_logic; - mmi64_reset_o : out std_logic; - - mmi64_m_dn_d_o : out std_logic_vector(63 downto 0); - mmi64_m_dn_valid_o : out std_logic; - mmi64_m_dn_accept_i : in std_logic := '0'; - mmi64_m_dn_start_o : out std_logic; - mmi64_m_dn_stop_o : out std_logic; - mmi64_m_up_d_i : in std_logic_vector(63 downto 0); - mmi64_m_up_valid_i : in std_logic := '0'; - mmi64_m_up_accept_o : out std_logic; - mmi64_m_up_start_i : in std_logic := '0'; - mmi64_m_up_stop_i : in std_logic := '0'; + mmi64_present_i : in std_logic := '0'; + mmi64_clk_o : out std_logic; + mmi64_reset_o : out std_logic; + + mmi64_m_dn_d_o : out std_logic_vector(63 downto 0); + mmi64_m_dn_valid_o : out std_logic; + mmi64_m_dn_accept_i : in std_logic := '0'; + mmi64_m_dn_start_o : out std_logic; + mmi64_m_dn_stop_o : out std_logic; + mmi64_m_up_d_i : in std_logic_vector(63 downto 0); + mmi64_m_up_valid_i : in std_logic := '0'; + mmi64_m_up_accept_o : out std_logic; + mmi64_m_up_start_i : in std_logic := '0'; + mmi64_m_up_stop_i : in std_logic := '0'; -- clock configuration ports (synchronous to mmi64_clk) - clk1_cfg_dn_o : out std_logic_vector(19 downto 0); - clk1_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); - clk2_cfg_dn_o : out std_logic_vector(19 downto 0); - clk2_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); - clk3_cfg_dn_o : out std_logic_vector(19 downto 0); - clk3_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); - clk4_cfg_dn_o : out std_logic_vector(19 downto 0); - clk4_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); - clk5_cfg_dn_o : out std_logic_vector(19 downto 0); - clk5_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); - clk6_cfg_dn_o : out std_logic_vector(19 downto 0); - clk6_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); - clk7_cfg_dn_o : out std_logic_vector(19 downto 0); - clk7_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); + clk1_cfg_dn_o : out std_logic_vector(19 downto 0); + clk1_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); + clk2_cfg_dn_o : out std_logic_vector(19 downto 0); + clk2_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); + clk3_cfg_dn_o : out std_logic_vector(19 downto 0); + clk3_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); + clk4_cfg_dn_o : out std_logic_vector(19 downto 0); + clk4_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); + clk5_cfg_dn_o : out std_logic_vector(19 downto 0); + clk5_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); + clk6_cfg_dn_o : out std_logic_vector(19 downto 0); + clk6_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); + clk7_cfg_dn_o : out std_logic_vector(19 downto 0); + clk7_cfg_up_i : in std_logic_vector(19 downto 0) := (others => '0'); -- Stratix10 temperature monitor temp_mon_i2c_sda : inout std_logic := '0'; temp_mon_i2c_scl : inout std_logic := '0'; - syscom_dn_o : out syscom_dn_t; - syscom_up_i : in syscom_up_t + syscom_dn_o : out syscom_dn_t; + syscom_up_i : in syscom_up_t ); end component profpga_ctrl; - component mmi64_m_regif + component mmi64_m_regif is generic ( - MODULE_ID : integer := 16#00000000#; --! unique id of the module instance - REGISTER_COUNT : integer := 16; --! number of registers in register file - REGISTER_WIDTH : integer := 16; --! register data width in bit - READ_BUFFER_DEPTH : integer := 4 --! number of entries in read data buffer - ); + module_id : integer := 16#00000000#; + register_count : integer := 16; + register_width : integer := 16; + read_buffer_depth : integer := 4 + ); port ( -- clock and reset - mmi64_clk : in std_logic; --! clock of mmi64 domain - mmi64_reset : in std_logic; --! reset of mmi64 domain + mmi64_clk : in std_logic; + mmi64_reset : in std_logic; -- connections to mmi64 router - mmi64_h_dn_d_i : in std_logic_vector(63 downto 0); --! downstream data from router - mmi64_h_dn_valid_i : in std_logic; --! downstream data valid from router - mmi64_h_dn_accept_o : out std_logic; --! downstream data accept to router - mmi64_h_dn_start_i : in std_logic; --! downstream data start (first byte of transfer) from router - mmi64_h_dn_stop_i : in std_logic; --! downstream data end (last byte of transfer) from router - - mmi64_h_up_d_o : out std_logic_vector(63 downto 0); --! upstream data output to router - mmi64_h_up_valid_o : out std_logic; --! upstream data valid to router - mmi64_h_up_accept_i : in std_logic; --! upstream data accept from router - mmi64_h_up_start_o : out std_logic; --! upstream data start (first byte of transfer) to router - mmi64_h_up_stop_o : out std_logic; --! upstream data end (last byte of transfer) to router + mmi64_h_dn_d_i : in std_logic_vector(63 downto 0); + mmi64_h_dn_valid_i : in std_logic; + mmi64_h_dn_accept_o : out std_logic; + mmi64_h_dn_start_i : in std_logic; + mmi64_h_dn_stop_i : in std_logic; + + mmi64_h_up_d_o : out std_logic_vector(63 downto 0); + mmi64_h_up_valid_o : out std_logic; + mmi64_h_up_accept_i : in std_logic; + mmi64_h_up_start_o : out std_logic; + mmi64_h_up_stop_o : out std_logic; -- connections to register interface - reg_en_o : out std_logic; --! register access enable - reg_we_o : out std_logic; --! register write enable - reg_addr_o : out std_logic_vector(log2(REGISTER_COUNT)-1 downto 0); --! register read/write address - reg_wdata_o : out std_logic_vector(REGISTER_WIDTH-1 downto 0); --! register data output - reg_accept_i : in std_logic; --! register data command accepted - reg_rdata_i : in std_logic_vector(REGISTER_WIDTH-1 downto 0); --! register input data - reg_rvalid_i : in std_logic --! register input data valid - ); + reg_en_o : out std_logic; + reg_we_o : out std_logic; + reg_addr_o : out std_logic_vector(log2(REGISTER_COUNT) - 1 downto 0); + reg_wdata_o : out std_logic_vector(REGISTER_WIDTH - 1 downto 0); + reg_accept_i : in std_logic; + reg_rdata_i : in std_logic_vector(REGISTER_WIDTH - 1 downto 0); + reg_rvalid_i : in std_logic + ); end component; - -- X = ddrs_num -- -- r0 -- r1 -- ... -- rX + function ddr_offset ( - constant ddr : integer range 0 to ddrs_num) + constant ddr : integer range 0 to ddrs_num + ) return integer is + variable offset : integer; - begin -- ddr_offset + + begin -- ddr_offset + offset := ddr; return offset * mon_ddr_en; - end ddr_offset; + + end function ddr_offset; -- X = llc_num -- r = coh_req, coh_fwd, coh_rsp_rcv, coh_rsp_snd, dma_req, dma_rsp, coh_dma_req, coh_dma_rsp @@ -222,15 +232,22 @@ architecture rtl of monitor is -- ... -- ... -- coh_reqX, coh_fwdX, ... + function mem_offset ( constant mem : integer range -1 to ddrs_num + slms_num; - constant reg : integer range 0 to 8) + constant reg : integer range 0 to 8 + ) return integer is + variable offset : integer; + begin + offset := (mem * 8) + reg; return ddr_offset(ddrs_num) + (offset * mon_mem_en); - end mem_offset; + + end function mem_offset; + constant MEM_COH_REQ : integer range 0 to 7 := 0; constant MEM_COH_FWD : integer range 0 to 7 := 1; constant MEM_COH_RSP_RCV : integer range 0 to 7 := 2; @@ -247,15 +264,21 @@ architecture rtl of monitor is -- r10 ... ... ... -- ... ... ... ... -- rX0 ... ... rXY + function noc_tile_inject_offset ( constant plane : integer range -1 to nocs_num; - constant tile : integer range 0 to tiles_num) + constant tile : integer range 0 to tiles_num + ) return integer is + variable offset : integer; - begin -- noc_offset + + begin -- noc_offset + offset := (plane * tiles_num) + tile; return mem_offset(ddrs_num + slms_num - 1, 8) + (offset * mon_noc_tile_inject_en); - end noc_tile_inject_offset; + + end function noc_tile_inject_offset; -- X = nocs_num -- Y = tiles_num @@ -265,16 +288,23 @@ architecture rtl of monitor is -- ... ... ... ... -- ... ... ... ... -- nX0,sX0,wX0,eX0,lX0 ... ... nXY,sXY,wXY,eXY,lXY + function noc_queues_full_offset ( constant plane : integer range -1 to nocs_num; constant tile : integer range 0 to tiles_num; - constant direction : integer range 0 to 5) + constant direction : integer range 0 to 5 + ) return integer is + variable offset : integer; + begin + offset := (plane * tiles_num * 5) + (tile * 5) + direction; - return noc_tile_inject_offset(nocs_num-1, tiles_num) + (offset * mon_noc_queues_full_en); - end noc_queues_full_offset; + return noc_tile_inject_offset(nocs_num - 1, tiles_num) + (offset * mon_noc_queues_full_en); + + end function noc_queues_full_offset; + constant DIR_N : integer range 0 to 4 := 0; constant DIR_S : integer range 0 to 4 := 1; constant DIR_W : integer range 0 to 4 := 2; @@ -288,15 +318,22 @@ architecture rtl of monitor is -- ... -- ... -- tlbX,memX,totX + function acc_offset ( constant acc : integer range -1 to accelerators_num; - constant reg : integer range 0 to 5) + constant reg : integer range 0 to 5 + ) return integer is + variable offset : integer; + begin + offset := (acc * 5) + reg; - return noc_queues_full_offset(nocs_num-1, tiles_num-1, 5) + (offset * mon_acc_en); - end acc_offset; + return noc_queues_full_offset(nocs_num - 1, tiles_num - 1, 5) + (offset * mon_acc_en); + + end function acc_offset; + constant ACC_TLB : integer range 0 to 4 := 0; constant ACC_MEM_LO : integer range 0 to 4 := 1; constant ACC_MEM_HI : integer range 0 to 4 := 2; @@ -310,15 +347,22 @@ architecture rtl of monitor is -- ... -- ... -- hitX,missX, + function l2_offset ( constant l2 : integer range -1 to l2_num; - constant reg : integer range 0 to 2) + constant reg : integer range 0 to 2 + ) return integer is + variable offset : integer; + begin + offset := (l2 * 2) + reg; - return acc_offset(accelerators_num-1, 5) + (offset * mon_l2_en); - end l2_offset; + return acc_offset(accelerators_num - 1, 5) + (offset * mon_l2_en); + + end function l2_offset; + constant L2_HIT : integer range 0 to 1 := 0; constant L2_MISS : integer range 0 to 1 := 1; @@ -329,39 +373,58 @@ architecture rtl of monitor is -- ... -- ... -- hitX,missX, + function llc_offset ( constant llc : integer range -1 to llc_num; - constant reg : integer range 0 to 2) + constant reg : integer range 0 to 2 + ) return integer is + variable offset : integer; + begin + offset := (llc * 2) + reg; - return l2_offset(l2_num-1, 2) + (offset * mon_llc_en); - end llc_offset; + return l2_offset(l2_num - 1, 2) + (offset * mon_llc_en); + + end function llc_offset; + constant LLC_HIT : integer range 0 to 1 := 0; constant LLC_MISS : integer range 0 to 1 := 1; - constant VF_OP_POINTS : integer := 4; + function dvfs_offset ( constant tile : integer range 0 to tiles_num; - constant pair : integer range 0 to VF_OP_POINTS) + constant pair : integer range 0 to VF_OP_POINTS + ) return integer is + variable offset : integer; + begin + offset := (tile * VF_OP_POINTS) + pair; - return llc_offset(llc_num-1, 2) + (offset * mon_dvfs_en); - end dvfs_offset; + return llc_offset(llc_num - 1, 2) + (offset * mon_dvfs_en); + + end function dvfs_offset; + + constant CTRL_REG_COUNT : integer := 4; - constant CTRL_REG_COUNT : integer := 4; function ctrl_offset ( - constant ctrl : integer range 0 to CTRL_REG_COUNT) + constant ctrl : integer range 0 to CTRL_REG_COUNT + ) return integer is + variable offset : integer; - begin -- ctrl_offset + + begin -- ctrl_offset + offset := ctrl; - return dvfs_offset(tiles_num-1, VF_OP_POINTS) + offset; - end ctrl_offset; + return dvfs_offset(tiles_num - 1, VF_OP_POINTS) + offset; + + end function ctrl_offset; + constant CTRL_RESET : integer := 0; constant CTRL_WINDOW_SIZE : integer := 1; constant CTRL_WINDOW_COUNT_LO : integer := 2; @@ -371,89 +434,95 @@ architecture rtl of monitor is constant REGISTER_COUNT : integer := MONITOR_REG_COUNT + CTRL_REG_COUNT; constant REGISTER_WIDTH : integer := mmi64_width; -- Counters must be updated using user_clk. - constant DEFAULT_WINDOW : std_logic_vector(REGISTER_WIDTH-1 downto 0) := conv_std_logic_vector(65536, REGISTER_WIDTH); + constant DEFAULT_WINDOW : std_logic_vector(REGISTER_WIDTH - 1 downto 0) := conv_std_logic_vector(65536, REGISTER_WIDTH); - signal mmi64_clk : std_logic; - signal mmi64_reset : std_logic; - signal mmi64_resetn : std_logic; - signal mmi64_dn_d : std_logic_vector(63 downto 0); - signal mmi64_dn_valid : std_logic; + signal mmi64_clk : std_logic; + signal mmi64_reset : std_logic; + signal mmi64_resetn : std_logic; + signal mmi64_dn_d : std_logic_vector(63 downto 0); + signal mmi64_dn_valid : std_logic; signal mmi64_dn_accept : std_logic; - signal mmi64_dn_start : std_logic; - signal mmi64_dn_stop : std_logic; - signal mmi64_up_d : std_logic_vector(63 downto 0); - signal mmi64_up_valid : std_logic; + signal mmi64_dn_start : std_logic; + signal mmi64_dn_stop : std_logic; + signal mmi64_up_d : std_logic_vector(63 downto 0); + signal mmi64_up_valid : std_logic; signal mmi64_up_accept : std_logic; - signal mmi64_up_start : std_logic; - signal mmi64_up_stop : std_logic; + signal mmi64_up_start : std_logic; + signal mmi64_up_stop : std_logic; signal reg_en : std_logic; signal reg_we : std_logic; - signal reg_addr : std_logic_vector(log2(REGISTER_COUNT)-1 downto 0); - signal reg_wdata : std_logic_vector(REGISTER_WIDTH-1 downto 0); + signal reg_addr : std_logic_vector(log2(REGISTER_COUNT) - 1 downto 0); + signal reg_wdata : std_logic_vector(REGISTER_WIDTH - 1 downto 0); signal reg_accept : std_logic; - signal reg_rdata : std_logic_vector(REGISTER_WIDTH-1 downto 0); + signal reg_rdata : std_logic_vector(REGISTER_WIDTH - 1 downto 0); signal reg_rvalid : std_logic; - type counter_type is array (0 to MONITOR_REG_COUNT-1) of std_logic_vector(REGISTER_WIDTH-1 downto 0); - type counter_u_type is array (0 to MONITOR_REG_COUNT-1) of std_logic_vector(REGISTER_WIDTH-1 downto 0); - signal count : counter_type; + type counter_type is array (0 to MONITOR_REG_COUNT - 1) of std_logic_vector(REGISTER_WIDTH - 1 downto 0); + + type counter_u_type is array (0 to MONITOR_REG_COUNT - 1) of std_logic_vector(REGISTER_WIDTH - 1 downto 0); + + signal count : counter_type; signal count_value, count_value_sync : counter_type; - signal count_value_tmp : counter_u_type; - signal count_reset : std_logic_vector(0 to MONITOR_REG_COUNT-1); - - signal window_size : std_logic_vector(REGISTER_WIDTH-1 downto 0); - signal time_counter : std_logic_vector(REGISTER_WIDTH-1 downto 0); - signal window_reset : std_logic; - signal new_window : std_logic; - signal new_window_delayed : std_logic; - signal new_window_sync_ddr : std_logic_vector(0 to ddrs_num-1); - signal new_window_sync_mem : std_logic_vector(0 to ddrs_num+slms_num-1); - signal new_window_sync_noc : std_logic_vector(0 to nocs_num-1); - signal new_window_sync_acc : std_logic_vector(0 to accelerators_num-1); - signal new_window_sync_l2 : std_logic_vector(0 to l2_num-1); - signal new_window_sync_llc : std_logic_vector(0 to llc_num-1); - signal new_window_sync_dvfs : std_logic_vector(0 to tiles_num-1); - signal updated_ddr : std_logic_vector(0 to ddrs_num-1); - signal updated_mem : std_logic_vector(0 to ddrs_num+slms_num-1); - signal updated_noc : std_logic_vector(0 to nocs_num-1); - signal updated_acc : std_logic_vector(0 to accelerators_num-1); - signal updated_l2 : std_logic_vector(0 to l2_num-1); - signal updated_llc : std_logic_vector(0 to llc_num-1); - signal updated_dvfs : std_logic_vector(0 to tiles_num-1); + signal count_value_tmp : counter_u_type; + signal count_reset : std_logic_vector(0 to MONITOR_REG_COUNT - 1); + + signal window_size : std_logic_vector(REGISTER_WIDTH - 1 downto 0); + signal time_counter : std_logic_vector(REGISTER_WIDTH - 1 downto 0); + signal window_reset : std_logic; + signal new_window : std_logic; + signal new_window_delayed : std_logic; + signal new_window_sync_ddr : std_logic_vector(0 to ddrs_num - 1); + signal new_window_sync_mem : std_logic_vector(0 to ddrs_num + slms_num - 1); + signal new_window_sync_noc : std_logic_vector(0 to nocs_num - 1); + signal new_window_sync_acc : std_logic_vector(0 to accelerators_num - 1); + signal new_window_sync_l2 : std_logic_vector(0 to l2_num - 1); + signal new_window_sync_llc : std_logic_vector(0 to llc_num - 1); + signal new_window_sync_dvfs : std_logic_vector(0 to tiles_num - 1); + signal updated_ddr : std_logic_vector(0 to ddrs_num - 1); + signal updated_mem : std_logic_vector(0 to ddrs_num + slms_num - 1); + signal updated_noc : std_logic_vector(0 to nocs_num - 1); + signal updated_acc : std_logic_vector(0 to accelerators_num - 1); + signal updated_l2 : std_logic_vector(0 to l2_num - 1); + signal updated_llc : std_logic_vector(0 to llc_num - 1); + signal updated_dvfs : std_logic_vector(0 to tiles_num - 1); signal window_count : std_logic_vector(63 downto 0); - type accelerator_cycles_counter_type is array (0 to accelerators_num - 1) of std_logic_vector(2*REGISTER_WIDTH-1 downto 0); + type accelerator_cycles_counter_type is array (0 to accelerators_num - 1) of std_logic_vector(2 * REGISTER_WIDTH - 1 downto 0); + signal accelerator_mem_count : accelerator_cycles_counter_type; signal accelerator_tot_count : accelerator_cycles_counter_type; - type accelerator_cycles_small_counter_type is array (0 to accelerators_num - 1) of std_logic_vector(REGISTER_WIDTH-1 downto 0); + + type accelerator_cycles_small_counter_type is array (0 to accelerators_num - 1) of std_logic_vector(REGISTER_WIDTH - 1 downto 0); + signal accelerator_tlb_count : accelerator_cycles_small_counter_type; - signal temp_mon_sda : std_logic := '0'; - signal temp_mon_scl : std_logic := '0'; + signal temp_mon_sda : std_logic := '0'; + signal temp_mon_scl : std_logic := '0'; begin ----------------------------------------------------------------------------- -- MMI64 Interface (mmi64_clk domain) ----------------------------------------------------------------------------- - U_PROFPGA_CTRL : profpga_ctrl + u_profpga_ctrl : component profpga_ctrl generic map ( - DEVICE => profpga_device_table(memtech)) + device => profpga_device_table(memtech) + ) port map ( -- access to FPGA pins - clk0_p => profpga_clk0_p, - clk0_n => profpga_clk0_n, - sync0_p => profpga_sync0_p, - sync0_n => profpga_sync0_n, - srcclk_p => open, - srcclk_n => open, - srcsync_p => open, - srcsync_n => open, - dmbi_h2f => dmbi_h2f, - dmbi_f2h => dmbi_f2h, - xdmbi_h2f => (others => '0'), - xdmbi_f2h => open, + clk0_p => profpga_clk0_p, + clk0_n => profpga_clk0_n, + sync0_p => profpga_sync0_p, + sync0_n => profpga_sync0_n, + srcclk_p => open, + srcclk_n => open, + srcsync_p => open, + srcsync_n => open, + dmbi_h2f => dmbi_h2f, + dmbi_f2h => dmbi_f2h, + xdmbi_h2f => (others => '0'), + xdmbi_f2h => open, -- 200 MHz clock (useful for delay calibration) clk_200mhz_o => open, -- source clock/sync input, not used @@ -502,514 +571,568 @@ begin -- Stratix 10 temperature monitor temp_mon_i2c_sda => temp_mon_sda, temp_mon_i2c_scl => temp_mon_scl, - syscom_dn_o => open, - syscom_up_i => (others => (others => '0')) - ); + syscom_dn_o => open, + syscom_up_i => (others => (others => '0')) + ); mmi64_resetn <= not mmi64_reset; - USER_REGIF : mmi64_m_regif + user_regif : component mmi64_m_regif generic map ( - MODULE_ID => 16#00000E5F#, - REGISTER_COUNT => REGISTER_COUNT, - REGISTER_WIDTH => REGISTER_WIDTH, - READ_BUFFER_DEPTH => 4 --! number of entries in read data buffer - ) port map ( - -- clock and reset - mmi64_clk => mmi64_clk, - mmi64_reset => mmi64_reset, - mmi64_h_dn_d_i => mmi64_dn_d, - mmi64_h_dn_valid_i => mmi64_dn_valid, - mmi64_h_dn_accept_o => mmi64_dn_accept, - mmi64_h_dn_start_i => mmi64_dn_start, - mmi64_h_dn_stop_i => mmi64_dn_stop, - mmi64_h_up_d_o => mmi64_up_d, - mmi64_h_up_valid_o => mmi64_up_valid, - mmi64_h_up_accept_i => mmi64_up_accept, - mmi64_h_up_start_o => mmi64_up_start, - mmi64_h_up_stop_o => mmi64_up_stop, - reg_en_o => reg_en, - reg_we_o => reg_we, - reg_addr_o => reg_addr, - reg_wdata_o => reg_wdata, - reg_accept_i => reg_accept, - reg_rdata_i => reg_rdata, - reg_rvalid_i => reg_rvalid - ); + module_id => 16#00000E5F#, + register_count => REGISTER_COUNT, + register_width => REGISTER_WIDTH, + read_buffer_depth => 4 + ) + port map ( + -- clock and reset + mmi64_clk => mmi64_clk, + mmi64_reset => mmi64_reset, + mmi64_h_dn_d_i => mmi64_dn_d, + mmi64_h_dn_valid_i => mmi64_dn_valid, + mmi64_h_dn_accept_o => mmi64_dn_accept, + mmi64_h_dn_start_i => mmi64_dn_start, + mmi64_h_dn_stop_i => mmi64_dn_stop, + mmi64_h_up_d_o => mmi64_up_d, + mmi64_h_up_valid_o => mmi64_up_valid, + mmi64_h_up_accept_i => mmi64_up_accept, + mmi64_h_up_start_o => mmi64_up_start, + mmi64_h_up_stop_o => mmi64_up_stop, + reg_en_o => reg_en, + reg_we_o => reg_we, + reg_addr_o => reg_addr, + reg_wdata_o => reg_wdata, + reg_accept_i => reg_accept, + reg_rdata_i => reg_rdata, + reg_rvalid_i => reg_rvalid + ); + + synchronizer_input : for i in 0 to MONITOR_REG_COUNT - 1 generate - synchronizer_input: for i in 0 to MONITOR_REG_COUNT - 1 generate - synchronizer_1: synchronizer + synchronizer_1 : component synchronizer generic map ( - DATA_WIDTH => REGISTER_WIDTH) + data_width => REGISTER_WIDTH + ) port map ( - clk => mmi64_clk, + clk => mmi64_clk, reset_n => mmi64_resetn, - data_i => count_value(i), - data_o => count_value_tmp(i)); + data_i => count_value(i), + data_o => count_value_tmp(i) + ); + count_value_sync(i) <= count_value_tmp(i); end generate synchronizer_input; - reg_read_write: process (mmi64_clk, mmi64_resetn) - variable addr, wdata : integer; - variable counters_addr : integer range 0 to MONITOR_REG_COUNT - 1; + reg_read_write : process (mmi64_clk, mmi64_resetn) is + + variable addr, wdata : integer; + variable counters_addr : integer range 0 to MONITOR_REG_COUNT - 1; variable counters_wdata : integer range 0 to MONITOR_REG_COUNT - 1; - begin -- process reg_select - if mmi64_resetn = '0' then -- asynchronous reset (active low) - reg_rdata <= (others => '0'); - reg_rvalid <= '0'; - reg_accept <= '0'; - count_reset <= (others => '0'); - window_size <= DEFAULT_WINDOW; + + begin -- process reg_select + + if (mmi64_resetn = '0') then -- asynchronous reset (active low) + reg_rdata <= (others => '0'); + reg_rvalid <= '0'; + reg_accept <= '0'; + count_reset <= (others => '0'); + window_size <= DEFAULT_WINDOW; window_reset <= '0'; - addr := 0; - wdata := 0; - elsif mmi64_clk'event and mmi64_clk = '1' then -- rising clock edge - addr := conv_integer(reg_addr); + addr := 0; + wdata := 0; + elsif (mmi64_clk'event and mmi64_clk = '1') then -- rising clock edge + addr := conv_integer(reg_addr); wdata := conv_integer(reg_wdata); - if addr < MONITOR_REG_COUNT then + if (addr < MONITOR_REG_COUNT) then counters_addr := addr; else counters_addr := 0; end if; - if wdata < MONITOR_REG_COUNT then + if (wdata < MONITOR_REG_COUNT) then counters_wdata := wdata; else counters_wdata := 0; end if; - count_reset <= (others => '0'); - reg_accept <= '0'; - reg_rvalid <= '0'; + count_reset <= (others => '0'); + reg_accept <= '0'; + reg_rvalid <= '0'; window_reset <= '0'; - if reg_en = '1' then - if reg_we = '1' then + if (reg_en = '1') then + if (reg_we = '1') then -- write control registers at the beginning of a new window reg_accept <= new_window; - if addr = ctrl_offset(CTRL_RESET) then -- Reset counter + if (addr = ctrl_offset(CTRL_RESET)) then -- Reset counter count_reset(counters_wdata) <= '1'; - elsif addr = ctrl_offset(CTRL_WINDOW_SIZE) then -- Set window size + elsif (addr = ctrl_offset(CTRL_WINDOW_SIZE)) then -- Set window size window_reset <= '1'; - window_size <= reg_wdata; + window_size <= reg_wdata; end if; else - if addr = ctrl_offset(CTRL_WINDOW_COUNT_LO) then + if (addr = ctrl_offset(CTRL_WINDOW_COUNT_LO)) then -- read time stamp LO reg_rvalid <= '1'; reg_accept <= '1'; - reg_rdata <= window_count(REGISTER_WIDTH-1 downto 0); - elsif addr = ctrl_offset(CTRL_WINDOW_COUNT_HI) then + reg_rdata <= window_count(REGISTER_WIDTH - 1 downto 0); + elsif (addr = ctrl_offset(CTRL_WINDOW_COUNT_HI)) then -- read time stamp HI reg_rvalid <= '1'; reg_accept <= '1'; - reg_rdata <= window_count(2*REGISTER_WIDTH-1 downto REGISTER_WIDTH); - elsif addr = ctrl_offset(CTRL_WINDOW_SIZE) then + reg_rdata <= window_count(2 * REGISTER_WIDTH - 1 downto REGISTER_WIDTH); + elsif (addr = ctrl_offset(CTRL_WINDOW_SIZE)) then -- read current window size reg_rvalid <= '1'; reg_accept <= '1'; - reg_rdata <= window_size; + reg_rdata <= window_size; else -- read counters only on new window after hold time reg_rvalid <= new_window_delayed; reg_accept <= new_window_delayed; - reg_rdata <= count_value_sync(counters_addr); + reg_rdata <= count_value_sync(counters_addr); end if; end if; end if; end if; + end process reg_read_write; - time_stamp_update: process (mmi64_clk, mmi64_resetn) - variable new_window_setup : std_logic_vector(REGISTER_WIDTH-1 downto 0); - begin -- process time_stamp_update - if mmi64_resetn = '0' then -- asynchronous reset (active low) - new_window <= '0'; + time_stamp_update : process (mmi64_clk, mmi64_resetn) is + + variable new_window_setup : std_logic_vector(REGISTER_WIDTH - 1 downto 0); + + begin -- process time_stamp_update + + if (mmi64_resetn = '0') then -- asynchronous reset (active low) + new_window <= '0'; new_window_delayed <= '0'; - window_count <= (others => '0'); - time_counter <= (others => '0'); - new_window_setup := (others => '0'); - elsif mmi64_clk'event and mmi64_clk = '1' then -- rising clock edge + window_count <= (others => '0'); + time_counter <= (others => '0'); + new_window_setup := (others => '0'); + elsif (mmi64_clk'event and mmi64_clk = '1') then -- rising clock edge new_window_setup := window_size - conv_std_logic_vector(64, REGISTER_WIDTH); -- Advance time time_counter <= time_counter + 1; -- Advance window count - if time_counter = window_size or window_reset = '1' then - time_counter <= (others => '0'); - window_count <= window_count + 1; - new_window <= '1'; + if (time_counter = window_size or window_reset = '1') then + time_counter <= (others => '0'); + window_count <= window_count + 1; + new_window <= '1'; new_window_delayed <= '0'; end if; - if time_counter = conv_std_logic_vector(10, REGISTER_WIDTH) then + if (time_counter = conv_std_logic_vector(10, REGISTER_WIDTH)) then -- hold new_window for 10 cycles to make sure perf. counters get the reset. new_window <= '0'; end if; -- Prevent register read on window update - if time_counter = conv_std_logic_vector(64, REGISTER_WIDTH) then + if (time_counter = conv_std_logic_vector(64, REGISTER_WIDTH)) then -- 32 cycles are more than enough to make sure all counters are up to date! new_window_delayed <= '1'; end if; - if time_counter = new_window_setup then + if (time_counter = new_window_setup) then -- 32 cycles are more than enough to make sure all counters are up to date! new_window_delayed <= '0'; end if; - end if; - end process time_stamp_update; + end process time_stamp_update; ----------------------------------------------------------------------------- -- Monitor and counters (user clk domain) ----------------------------------------------------------------------------- - ddr_monitor_enabled_gen: if mon_ddr_en /= 0 generate - ddr_gen: for i in 0 to ddrs_num-1 generate - synchronizer_2: synchronizer + ddr_monitor_enabled_gen : if mon_ddr_en /= 0 generate + + ddr_gen : for i in 0 to ddrs_num - 1 generate + + synchronizer_2 : component synchronizer generic map ( - DATA_WIDTH => 1) + data_width => 1 + ) port map ( - clk => mon_ddr(i).clk, - reset_n => user_rstn, + clk => mon_ddr(i).clk, + reset_n => user_rstn, data_i(0) => new_window, - data_o(0) => new_window_sync_ddr(i)); + data_o(0) => new_window_sync_ddr(i) + ); + + process (mon_ddr(i).clk, user_rstn) is + begin -- process - process (mon_ddr(i).clk, user_rstn) - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) + if (user_rstn = '0') then -- asynchronous reset (active low) updated_ddr(i) <= '0'; - elsif mon_ddr(i).clk'event and mon_ddr(i).clk = '1' then -- rising clock edge - if new_window_sync_ddr(i) = '1' and updated_ddr(i) = '0' then + elsif (mon_ddr(i).clk'event and mon_ddr(i).clk = '1') then -- rising clock edge + if (new_window_sync_ddr(i) = '1' and updated_ddr(i) = '0') then updated_ddr(i) <= '1'; - elsif new_window_sync_ddr(i) = '0' then + elsif (new_window_sync_ddr(i) = '0') then updated_ddr(i) <= '0'; end if; end if; + end process; - ddr_counter: process (mon_ddr(i).clk, user_rstn) - constant index : integer := ddr_offset(i); - begin -- process ddr0_counter - if user_rstn = '0' then -- asynchronous reset (active low) + ddr_counter : process (mon_ddr(i).clk, user_rstn) is + + constant INDEX : integer := ddr_offset(i); + + begin -- process ddr0_counter + + if (user_rstn = '0') then -- asynchronous reset (active low) count_value(index) <= (others => '0'); - count(index) <= (others => '0'); - elsif mon_ddr(i).clk'event and mon_ddr(i).clk = '1' then -- rising clock edge - if mon_ddr(i).word_transfer = '1' then - count(index) <= count(index) + 1; + count(index) <= (others => '0'); + elsif (mon_ddr(i).clk'event and mon_ddr(i).clk = '1') then -- rising clock edge + if (mon_ddr(i).word_transfer = '1') then + count(index) <= count(INDEX) + 1; end if; - if new_window_sync_ddr(i) = '1' and updated_ddr(i) = '0' then - count(index) <= (others => '0'); - count_value(index) <= count(index); + if (new_window_sync_ddr(i) = '1' and updated_ddr(i) = '0') then + count(index) <= (others => '0'); + count_value(index) <= count(INDEX); end if; - if count_reset(index) = '1' then - count(index) <= (others => '0'); + if (count_reset(INDEX) = '1') then + count(index) <= (others => '0'); count_value(index) <= (others => '0'); end if; end if; + end process ddr_counter; end generate ddr_gen; end generate ddr_monitor_enabled_gen; - mem_monitor_enabled_gen: if mon_mem_en /= 0 generate - mem_gen: for i in 0 to ddrs_num+slms_num-1 generate - synchronizer_mem: synchronizer + mem_monitor_enabled_gen : if mon_mem_en /= 0 generate + + mem_gen : for i in 0 to ddrs_num + slms_num - 1 generate + + synchronizer_mem : component synchronizer generic map ( - DATA_WIDTH => 1) + data_width => 1 + ) port map ( - clk => mon_mem(i).clk, - reset_n => user_rstn, + clk => mon_mem(i).clk, + reset_n => user_rstn, data_i(0) => new_window, - data_o(0) => new_window_sync_mem(i)); + data_o(0) => new_window_sync_mem(i) + ); + + process (mon_mem(i).clk, user_rstn) is + begin -- process - process (mon_mem(i).clk, user_rstn) - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) + if (user_rstn = '0') then -- asynchronous reset (active low) updated_mem(i) <= '0'; - elsif mon_mem(i).clk'event and mon_mem(i).clk = '1' then -- rising clock edge - if new_window_sync_mem(i) = '1' and updated_mem(i) = '0' then + elsif (mon_mem(i).clk'event and mon_mem(i).clk = '1') then -- rising clock edge + if (new_window_sync_mem(i) = '1' and updated_mem(i) = '0') then updated_mem(i) <= '1'; - elsif new_window_sync_mem(i) = '0' then + elsif (new_window_sync_mem(i) = '0') then updated_mem(i) <= '0'; end if; end if; + end process; - mem_counter: process (mon_mem(i).clk, user_rstn) - constant coh_req_index : integer := mem_offset(i, MEM_COH_REQ); - constant coh_fwd_index : integer := mem_offset(i, MEM_COH_FWD); - constant coh_rsp_rcv_index : integer := mem_offset(i, MEM_COH_RSP_RCV); - constant coh_rsp_snd_index : integer := mem_offset(i, MEM_COH_RSP_SND); - constant dma_req_index : integer := mem_offset(i, MEM_DMA_REQ); - constant dma_rsp_index : integer := mem_offset(i, MEM_DMA_RSP); - constant coh_dma_req_index : integer := mem_offset(i, MEM_COH_DMA_REQ); - constant coh_dma_rsp_index : integer := mem_offset(i, MEM_COH_DMA_RSP); - begin -- process mem_counter - if user_rstn = '0' then -- asynchronous reset (active low) - count_value(coh_req_index) <= (others => '0'); - count_value(coh_fwd_index) <= (others => '0'); + mem_counter : process (mon_mem(i).clk, user_rstn) is + + constant COH_REQ_INDEX : integer := mem_offset(i, MEM_COH_REQ); + constant COH_FWD_INDEX : integer := mem_offset(i, MEM_COH_FWD); + constant COH_RSP_RCV_INDEX : integer := mem_offset(i, MEM_COH_RSP_RCV); + constant COH_RSP_SND_INDEX : integer := mem_offset(i, MEM_COH_RSP_SND); + constant DMA_REQ_INDEX : integer := mem_offset(i, MEM_DMA_REQ); + constant DMA_RSP_INDEX : integer := mem_offset(i, MEM_DMA_RSP); + constant COH_DMA_REQ_INDEX : integer := mem_offset(i, MEM_COH_DMA_REQ); + constant COH_DMA_RSP_INDEX : integer := mem_offset(i, MEM_COH_DMA_RSP); + + begin -- process mem_counter + + if (user_rstn = '0') then -- asynchronous reset (active low) + count_value(coh_req_index) <= (others => '0'); + count_value(coh_fwd_index) <= (others => '0'); count_value(coh_rsp_rcv_index) <= (others => '0'); count_value(coh_rsp_snd_index) <= (others => '0'); - count_value(dma_req_index) <= (others => '0'); - count_value(dma_rsp_index) <= (others => '0'); + count_value(dma_req_index) <= (others => '0'); + count_value(dma_rsp_index) <= (others => '0'); count_value(coh_dma_req_index) <= (others => '0'); count_value(coh_dma_rsp_index) <= (others => '0'); - count(coh_req_index) <= (others => '0'); - count(coh_fwd_index) <= (others => '0'); - count(coh_rsp_rcv_index) <= (others => '0'); - count(coh_rsp_snd_index) <= (others => '0'); - count(dma_req_index) <= (others => '0'); - count(dma_rsp_index) <= (others => '0'); - count(coh_dma_req_index) <= (others => '0'); - count(coh_dma_rsp_index) <= (others => '0'); - elsif mon_mem(i).clk'event and mon_mem(i).clk = '1' then -- rising clock edge - if mon_mem(i).coherent_req = '1' then - count(coh_req_index) <= count(coh_req_index) + 1; + count(coh_req_index) <= (others => '0'); + count(coh_fwd_index) <= (others => '0'); + count(coh_rsp_rcv_index) <= (others => '0'); + count(coh_rsp_snd_index) <= (others => '0'); + count(dma_req_index) <= (others => '0'); + count(dma_rsp_index) <= (others => '0'); + count(coh_dma_req_index) <= (others => '0'); + count(coh_dma_rsp_index) <= (others => '0'); + elsif (mon_mem(i).clk'event and mon_mem(i).clk = '1') then -- rising clock edge + if (mon_mem(i).coherent_req = '1') then + count(coh_req_index) <= count(COH_REQ_INDEX) + 1; end if; - if mon_mem(i).coherent_fwd = '1' then - count(coh_fwd_index) <= count(coh_fwd_index) + 1; + if (mon_mem(i).coherent_fwd = '1') then + count(coh_fwd_index) <= count(COH_FWD_INDEX) + 1; end if; - if mon_mem(i).coherent_rsp_rcv = '1' then - count(coh_rsp_rcv_index) <= count(coh_rsp_rcv_index) + 1; + if (mon_mem(i).coherent_rsp_rcv = '1') then + count(coh_rsp_rcv_index) <= count(COH_RSP_RCV_INDEX) + 1; end if; - if mon_mem(i).coherent_rsp_snd = '1' then - count(coh_rsp_snd_index) <= count(coh_rsp_snd_index) + 1; + if (mon_mem(i).coherent_rsp_snd = '1') then + count(coh_rsp_snd_index) <= count(COH_RSP_SND_INDEX) + 1; end if; - if mon_mem(i).dma_req = '1' then - count(dma_req_index) <= count(dma_req_index) + 1; + if (mon_mem(i).dma_req = '1') then + count(dma_req_index) <= count(DMA_REQ_INDEX) + 1; end if; - if mon_mem(i).dma_rsp = '1' then - count(dma_rsp_index) <= count(dma_rsp_index) + 1; + if (mon_mem(i).dma_rsp = '1') then + count(dma_rsp_index) <= count(DMA_RSP_INDEX) + 1; end if; - if mon_mem(i).coherent_dma_req = '1' then - count(coh_dma_req_index) <= count(coh_dma_req_index) + 1; + if (mon_mem(i).coherent_dma_req = '1') then + count(coh_dma_req_index) <= count(COH_DMA_REQ_INDEX) + 1; end if; - if mon_mem(i).coherent_dma_rsp = '1' then - count(coh_dma_rsp_index) <= count(coh_dma_rsp_index) + 1; + if (mon_mem(i).coherent_dma_rsp = '1') then + count(coh_dma_rsp_index) <= count(COH_DMA_RSP_INDEX) + 1; end if; - if new_window_sync_mem(i) = '1' and updated_mem(i) = '0' then - count(coh_req_index) <= (others => '0'); - count(coh_fwd_index) <= (others => '0'); + if (new_window_sync_mem(i) = '1' and updated_mem(i) = '0') then + count(coh_req_index) <= (others => '0'); + count(coh_fwd_index) <= (others => '0'); count(coh_rsp_rcv_index) <= (others => '0'); count(coh_rsp_snd_index) <= (others => '0'); - count(dma_req_index) <= (others => '0'); - count(dma_rsp_index) <= (others => '0'); + count(dma_req_index) <= (others => '0'); + count(dma_rsp_index) <= (others => '0'); count(coh_dma_req_index) <= (others => '0'); count(coh_dma_rsp_index) <= (others => '0'); - count_value(coh_req_index) <= count(coh_req_index); - count_value(coh_fwd_index) <= count(coh_fwd_index); - count_value(coh_rsp_rcv_index) <= count(coh_rsp_rcv_index); - count_value(coh_rsp_snd_index) <= count(coh_rsp_snd_index); - count_value(dma_req_index) <= count(dma_req_index); - count_value(dma_rsp_index) <= count(dma_rsp_index); - count_value(coh_dma_req_index) <= count(coh_dma_req_index); - count_value(coh_dma_rsp_index) <= count(coh_dma_rsp_index); + count_value(coh_req_index) <= count(COH_REQ_INDEX); + count_value(coh_fwd_index) <= count(COH_FWD_INDEX); + count_value(coh_rsp_rcv_index) <= count(COH_RSP_RCV_INDEX); + count_value(coh_rsp_snd_index) <= count(COH_RSP_SND_INDEX); + count_value(dma_req_index) <= count(DMA_REQ_INDEX); + count_value(dma_rsp_index) <= count(DMA_RSP_INDEX); + count_value(coh_dma_req_index) <= count(COH_DMA_REQ_INDEX); + count_value(coh_dma_rsp_index) <= count(COH_DMA_RSP_INDEX); end if; - if count_reset(coh_req_index) = '1' then - count(coh_req_index) <= (others => '0'); + if (count_reset(COH_REQ_INDEX) = '1') then + count(coh_req_index) <= (others => '0'); count_value(coh_req_index) <= (others => '0'); end if; - if count_reset(coh_fwd_index) = '1' then - count(coh_fwd_index) <= (others => '0'); + if (count_reset(COH_FWD_INDEX) = '1') then + count(coh_fwd_index) <= (others => '0'); count_value(coh_fwd_index) <= (others => '0'); end if; - if count_reset(coh_rsp_rcv_index) = '1' then - count(coh_rsp_rcv_index) <= (others => '0'); + if (count_reset(COH_RSP_RCV_INDEX) = '1') then + count(coh_rsp_rcv_index) <= (others => '0'); count_value(coh_rsp_rcv_index) <= (others => '0'); end if; - if count_reset(coh_rsp_snd_index) = '1' then - count(coh_rsp_snd_index) <= (others => '0'); + if (count_reset(COH_RSP_SND_INDEX) = '1') then + count(coh_rsp_snd_index) <= (others => '0'); count_value(coh_rsp_snd_index) <= (others => '0'); end if; - if count_reset(dma_req_index) = '1' then - count(dma_req_index) <= (others => '0'); + if (count_reset(DMA_REQ_INDEX) = '1') then + count(dma_req_index) <= (others => '0'); count_value(dma_req_index) <= (others => '0'); end if; - if count_reset(dma_rsp_index) = '1' then - count(dma_rsp_index) <= (others => '0'); + if (count_reset(DMA_RSP_INDEX) = '1') then + count(dma_rsp_index) <= (others => '0'); count_value(dma_rsp_index) <= (others => '0'); end if; - if count_reset(coh_dma_req_index) = '1' then - count(coh_dma_req_index) <= (others => '0'); + if (count_reset(COH_DMA_REQ_INDEX) = '1') then + count(coh_dma_req_index) <= (others => '0'); count_value(coh_dma_req_index) <= (others => '0'); end if; - if count_reset(coh_dma_rsp_index) = '1' then - count(coh_dma_rsp_index) <= (others => '0'); + if (count_reset(COH_DMA_RSP_INDEX) = '1') then + count(coh_dma_rsp_index) <= (others => '0'); count_value(coh_dma_rsp_index) <= (others => '0'); end if; - end if; + end process mem_counter; end generate mem_gen; end generate mem_monitor_enabled_gen; + noc_monitor_enabled_gen : if (mon_noc_tile_inject_en + mon_noc_queues_full_en) /= 0 generate - noc_monitor_enabled_gen: if (mon_noc_tile_inject_en + mon_noc_queues_full_en) /= 0 generate - noc_gen: for i in 0 to nocs_num-1 generate - synchronizer_4: synchronizer + noc_gen : for i in 0 to nocs_num - 1 generate + + synchronizer_4 : component synchronizer generic map ( - DATA_WIDTH => 1) + data_width => 1 + ) port map ( - clk => mon_noc(i,0).clk, -- NoC plane on single domain - reset_n => user_rstn, + clk => mon_noc(i,0).clk, + reset_n => user_rstn, data_i(0) => new_window, - data_o(0) => new_window_sync_noc(i)); + data_o(0) => new_window_sync_noc(i) + ); - process (mon_noc(i, 0).clk, user_rstn) - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) + process (mon_noc(i, 0).clk, user_rstn) is + begin -- process + + if (user_rstn = '0') then -- asynchronous reset (active low) updated_noc(i) <= '0'; - elsif mon_noc(i, 0).clk'event and mon_noc(i, 0).clk = '1' then -- rising clock edge - if new_window_sync_noc(i) = '1' and updated_noc(i) = '0' then + elsif (mon_noc(i, 0).clk'event and mon_noc(i, 0).clk = '1') then -- rising clock edge + if (new_window_sync_noc(i) = '1' and updated_noc(i) = '0') then updated_noc(i) <= '1'; - elsif new_window_sync_noc(i) = '0' then + elsif (new_window_sync_noc(i) = '0') then updated_noc(i) <= '0'; end if; end if; + end process; - inject_gen: if mon_noc_tile_inject_en /= 0 generate + inject_gen : if mon_noc_tile_inject_en /= 0 generate + + noc_inject_counters : for k in 0 to tiles_num - 1 generate + + process (mon_noc(i, k).clk, user_rstn) is + + constant INDEX : integer := noc_tile_inject_offset(i, k); + + begin -- process - noc_inject_counters: for k in 0 to tiles_num-1 generate - process (mon_noc(i,k).clk, user_rstn) - constant index : integer := noc_tile_inject_offset(i, k); - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) + if (user_rstn = '0') then -- asynchronous reset (active low) count_value(index) <= (others => '0'); - count(index) <= (others => '0'); - elsif mon_noc(i,k).clk'event and mon_noc(i,k).clk = '1' then -- rising clock edge - if mon_noc(i,k).tile_inject = '1' then - count(index) <= count(index) + 1; + count(index) <= (others => '0'); + elsif (mon_noc(i, k).clk'event and mon_noc(i, k).clk = '1') then -- rising clock edge + if (mon_noc(i, k).tile_inject = '1') then + count(index) <= count(INDEX) + 1; end if; - if new_window_sync_noc(i) = '1' and updated_noc(i) = '0' then - count(index) <= (others => '0'); - count_value(index) <= count(index); + if (new_window_sync_noc(i) = '1' and updated_noc(i) = '0') then + count(index) <= (others => '0'); + count_value(index) <= count(INDEX); end if; - if count_reset(index) = '1' then - count(index) <= (others => '0'); + if (count_reset(INDEX) = '1') then + count(index) <= (others => '0'); count_value(index) <= (others => '0'); end if; end if; + end process; + end generate noc_inject_counters; end generate inject_gen; + queues_full_gen : if mon_noc_queues_full_en /= 0 generate + + noc_queues_full_counters : for k in 0 to tiles_num - 1 generate + + noc_queue_dir_counters : for dir in 0 to 4 generate - queues_full_gen: if mon_noc_queues_full_en /= 0 generate + process (mon_noc(i, k).clk, user_rstn) is - noc_queues_full_counters: for k in 0 to tiles_num-1 generate - noc_queue_dir_counters: for dir in 0 to 4 generate - process (mon_noc(i,k).clk, user_rstn) - constant index : integer := noc_queues_full_offset(i, k, dir); - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) - count(index) <= (others => '0'); + constant INDEX : integer := noc_queues_full_offset(i, k, dir); + + begin -- process + + if (user_rstn = '0') then -- asynchronous reset (active low) + count(index) <= (others => '0'); count_value(index) <= (others => '0'); - elsif mon_noc(i,k).clk'event and mon_noc(i,k).clk = '1' then -- rising clock edge - if mon_noc(i,k).queue_full(dir) = '1' then - count(index) <= count(index) + 1; + elsif (mon_noc(i, k).clk'event and mon_noc(i, k).clk = '1') then -- rising clock edge + if (mon_noc(i, k).queue_full(dir) = '1') then + count(index) <= count(INDEX) + 1; end if; - if new_window_sync_noc(i) = '1' and updated_noc(i) = '0' then - count(index) <= (others => '0'); - count_value(index) <= count(index); + if (new_window_sync_noc(i) = '1' and updated_noc(i) = '0') then + count(index) <= (others => '0'); + count_value(index) <= count(INDEX); end if; - if count_reset(index) = '1' then - count(index) <= (others => '0'); + if (count_reset(INDEX) = '1') then + count(index) <= (others => '0'); count_value(index) <= (others => '0'); end if; end if; + end process; + end generate noc_queue_dir_counters; + end generate noc_queues_full_counters; end generate queues_full_gen; end generate noc_gen; + end generate noc_monitor_enabled_gen; + mon_acc_gen : if mon_acc_en /= 0 generate - mon_acc_gen: if mon_acc_en /= 0 generate + accelerators_new_window_sync : for i in accelerators_num - 1 downto 0 generate - accelerators_new_window_sync: for i in accelerators_num - 1 downto 0 generate - synchronizer_5: synchronizer + synchronizer_5 : component synchronizer generic map ( - DATA_WIDTH => 1) + data_width => 1 + ) port map ( - clk => mon_acc(i).clk, - reset_n => user_rstn, + clk => mon_acc(i).clk, + reset_n => user_rstn, data_i(0) => new_window, - data_o(0) => new_window_sync_acc(i)); + data_o(0) => new_window_sync_acc(i) + ); - process (mon_acc(i).clk, user_rstn) - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) + process (mon_acc(i).clk, user_rstn) is + begin -- process + + if (user_rstn = '0') then -- asynchronous reset (active low) updated_acc(i) <= '0'; - elsif mon_acc(i).clk'event and mon_acc(i).clk = '1' then -- rising clock edge - if new_window_sync_acc(i) = '1' and updated_acc(i) = '0' then + elsif (mon_acc(i).clk'event and mon_acc(i).clk = '1') then -- rising clock edge + if (new_window_sync_acc(i) = '1' and updated_acc(i) = '0') then updated_acc(i) <= '1'; - elsif new_window_sync_acc(i) = '0' then + elsif (new_window_sync_acc(i) = '0') then updated_acc(i) <= '0'; end if; end if; + end process; - end generate accelerators_new_window_sync; + end generate accelerators_new_window_sync; - accelerators_counters: for i in 0 to accelerators_num - 1 generate + accelerators_counters : for i in 0 to accelerators_num - 1 generate - process (mon_acc(i).clk, user_rstn) - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) - accelerator_tlb_count(i) <= (others => '0'); - accelerator_mem_count(i) <= (others => '0'); - accelerator_tot_count(i) <= (others => '0'); + process (mon_acc(i).clk, user_rstn) is + begin -- process + + if (user_rstn = '0') then -- asynchronous reset (active low) + accelerator_tlb_count(i) <= (others => '0'); + accelerator_mem_count(i) <= (others => '0'); + accelerator_tot_count(i) <= (others => '0'); count_value(acc_offset(i, ACC_TLB)) <= (others => '0'); count_value(acc_offset(i, ACC_MEM_LO)) <= (others => '0'); count_value(acc_offset(i, ACC_MEM_HI)) <= (others => '0'); count_value(acc_offset(i, ACC_TOT_LO)) <= (others => '0'); count_value(acc_offset(i, ACC_TOT_HI)) <= (others => '0'); - elsif mon_acc(i).clk'event and mon_acc(i).clk = '1' then -- rising clock edge - if mon_acc(i).done = '0' then - if mon_acc(i).go = '1' and mon_acc(i).run = '0' then + elsif (mon_acc(i).clk'event and mon_acc(i).clk = '1') then -- rising clock edge + if (mon_acc(i).done = '0') then + if (mon_acc(i).go = '1' and mon_acc(i).run = '0') then accelerator_tlb_count(i) <= accelerator_tlb_count(i) + 1; end if; - if mon_acc(i).run = '1' or mon_acc(i).go = '1' then + if (mon_acc(i).run = '1' or mon_acc(i).go = '1') then accelerator_tot_count(i) <= accelerator_tot_count(i) + 1; end if; - if mon_acc(i).run = '1' and mon_acc(i).burst = '1' then + if (mon_acc(i).run = '1' and mon_acc(i).burst = '1') then accelerator_mem_count(i) <= accelerator_mem_count(i) + 1; end if; end if; - if new_window_sync_acc(i) = '1' and updated_acc(i) = '0' then - accelerator_tlb_count(i) <= (others => '0'); - accelerator_mem_count(i) <= (others => '0'); - accelerator_tot_count(i) <= (others => '0'); + if (new_window_sync_acc(i) = '1' and updated_acc(i) = '0') then + accelerator_tlb_count(i) <= (others => '0'); + accelerator_mem_count(i) <= (others => '0'); + accelerator_tot_count(i) <= (others => '0'); count_value(acc_offset(i, ACC_TLB)) <= accelerator_tlb_count(i); - count_value(acc_offset(i, ACC_MEM_LO)) <= accelerator_mem_count(i)(REGISTER_WIDTH-1 downto 0); - count_value(acc_offset(i, ACC_MEM_HI)) <= accelerator_mem_count(i)(2*REGISTER_WIDTH-1 downto REGISTER_WIDTH); - count_value(acc_offset(i, ACC_TOT_LO)) <= accelerator_tot_count(i)(REGISTER_WIDTH-1 downto 0); - count_value(acc_offset(i, ACC_TOT_HI)) <= accelerator_tot_count(i)(2*REGISTER_WIDTH-1 downto REGISTER_WIDTH); + count_value(acc_offset(i, ACC_MEM_LO)) <= accelerator_mem_count(i)(REGISTER_WIDTH - 1 downto 0); + count_value(acc_offset(i, ACC_MEM_HI)) <= accelerator_mem_count(i)(2 * REGISTER_WIDTH - 1 downto REGISTER_WIDTH); + count_value(acc_offset(i, ACC_TOT_LO)) <= accelerator_tot_count(i)(REGISTER_WIDTH - 1 downto 0); + count_value(acc_offset(i, ACC_TOT_HI)) <= accelerator_tot_count(i)(2 * REGISTER_WIDTH - 1 downto REGISTER_WIDTH); end if; -- Reset all counters when tot_lo count is reset - if count_reset(acc_offset(i, ACC_TOT_LO)) = '1' then - accelerator_tlb_count(i) <= (others => '0'); - accelerator_mem_count(i) <= (others => '0'); - accelerator_tot_count(i) <= (others => '0'); + if (count_reset(acc_offset(i, ACC_TOT_LO)) = '1') then + accelerator_tlb_count(i) <= (others => '0'); + accelerator_mem_count(i) <= (others => '0'); + accelerator_tot_count(i) <= (others => '0'); count_value(acc_offset(i, ACC_TLB)) <= (others => '0'); count_value(acc_offset(i, ACC_MEM_LO)) <= (others => '0'); count_value(acc_offset(i, ACC_MEM_HI)) <= (others => '0'); @@ -1017,350 +1140,474 @@ begin count_value(acc_offset(i, ACC_TOT_HI)) <= (others => '0'); end if; end if; + end process; + end generate accelerators_counters; end generate mon_acc_gen; + l2_monitor_enabled_gen : if mon_l2_en /= 0 generate + + l2_gen : for i in 0 to l2_num - 1 generate - l2_monitor_enabled_gen: if mon_l2_en /= 0 generate - l2_gen: for i in 0 to l2_num-1 generate - synchronizer_2: synchronizer + synchronizer_2 : component synchronizer generic map ( - DATA_WIDTH => 1) + data_width => 1 + ) port map ( - clk => mon_l2(i).clk, - reset_n => user_rstn, + clk => mon_l2(i).clk, + reset_n => user_rstn, data_i(0) => new_window, - data_o(0) => new_window_sync_l2(i)); + data_o(0) => new_window_sync_l2(i) + ); + + process (mon_l2(i).clk, user_rstn) is + begin -- process - process (mon_l2(i).clk, user_rstn) - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) + if (user_rstn = '0') then -- asynchronous reset (active low) updated_l2(i) <= '0'; - elsif mon_l2(i).clk'event and mon_l2(i).clk = '1' then -- rising clock edge - if new_window_sync_l2(i) = '1' and updated_l2(i) = '0' then + elsif (mon_l2(i).clk'event and mon_l2(i).clk = '1') then -- rising clock edge + if (new_window_sync_l2(i) = '1' and updated_l2(i) = '0') then updated_l2(i) <= '1'; - elsif new_window_sync_l2(i) = '0' then + elsif (new_window_sync_l2(i) = '0') then updated_l2(i) <= '0'; end if; end if; + end process; - l2_counter: process (mon_l2(i).clk, user_rstn) - constant hit_index : integer := l2_offset(i, L2_HIT); - constant miss_index : integer := l2_offset(i, L2_MISS); - begin -- process l20_counter - if user_rstn = '0' then -- asynchronous reset (active low) + l2_counter : process (mon_l2(i).clk, user_rstn) is + + constant HIT_INDEX : integer := l2_offset(i, L2_HIT); + constant MISS_INDEX : integer := l2_offset(i, L2_MISS); + + begin -- process l20_counter + + if (user_rstn = '0') then -- asynchronous reset (active low) count_value(hit_index) <= (others => '0'); count_value(miss_index) <= (others => '0'); count(hit_index) <= (others => '0'); count(miss_index) <= (others => '0'); - elsif mon_l2(i).clk'event and mon_l2(i).clk = '1' then -- rising clock edge - if mon_l2(i).hit = '1' then - count(hit_index) <= count(hit_index) + 1; + elsif (mon_l2(i).clk'event and mon_l2(i).clk = '1') then -- rising clock edge + if (mon_l2(i).hit = '1') then + count(hit_index) <= count(HIT_INDEX) + 1; end if; - if mon_l2(i).miss = '1' then - count(miss_index) <= count(miss_index) + 1; + if (mon_l2(i).miss = '1') then + count(miss_index) <= count(MISS_INDEX) + 1; end if; - if new_window_sync_l2(i) = '1' and updated_l2(i) = '0' then + if (new_window_sync_l2(i) = '1' and updated_l2(i) = '0') then count(hit_index) <= (others => '0'); count(miss_index) <= (others => '0'); - count_value(hit_index) <= count(hit_index); - count_value(miss_index) <= count(miss_index); + count_value(hit_index) <= count(HIT_INDEX); + count_value(miss_index) <= count(MISS_INDEX); end if; - if count_reset(hit_index) = '1' then - count(hit_index) <= (others => '0'); - count_value(hit_index) <= (others => '0'); + if (count_reset(HIT_INDEX) = '1') then + count(hit_index) <= (others => '0'); + count_value(hit_index) <= (others => '0'); end if; - if count_reset(miss_index) = '1' then + if (count_reset(MISS_INDEX) = '1') then count(miss_index) <= (others => '0'); count_value(miss_index) <= (others => '0'); end if; end if; + end process l2_counter; end generate l2_gen; end generate l2_monitor_enabled_gen; + llc_monitor_enabled_gen : if mon_llc_en /= 0 generate - llc_monitor_enabled_gen: if mon_llc_en /= 0 generate - llc_gen: for i in 0 to llc_num-1 generate - synchronizer_2: synchronizer + llc_gen : for i in 0 to llc_num - 1 generate + + synchronizer_2 : component synchronizer generic map ( - DATA_WIDTH => 1) + data_width => 1 + ) port map ( - clk => mon_llc(i).clk, - reset_n => user_rstn, + clk => mon_llc(i).clk, + reset_n => user_rstn, data_i(0) => new_window, - data_o(0) => new_window_sync_llc(i)); + data_o(0) => new_window_sync_llc(i) + ); - process (mon_llc(i).clk, user_rstn) - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) + process (mon_llc(i).clk, user_rstn) is + begin -- process + + if (user_rstn = '0') then -- asynchronous reset (active low) updated_llc(i) <= '0'; - elsif mon_llc(i).clk'event and mon_llc(i).clk = '1' then -- rising clock edge - if new_window_sync_llc(i) = '1' and updated_llc(i) = '0' then + elsif (mon_llc(i).clk'event and mon_llc(i).clk = '1') then -- rising clock edge + if (new_window_sync_llc(i) = '1' and updated_llc(i) = '0') then updated_llc(i) <= '1'; - elsif new_window_sync_llc(i) = '0' then + elsif (new_window_sync_llc(i) = '0') then updated_llc(i) <= '0'; end if; end if; + end process; - llc_counter: process (mon_llc(i).clk, user_rstn) - constant hit_index : integer := llc_offset(i, LLC_HIT); - constant miss_index : integer := llc_offset(i, LLC_MISS); - begin -- process llc0_counter - if user_rstn = '0' then -- asynchronous reset (active low) + llc_counter : process (mon_llc(i).clk, user_rstn) is + + constant HIT_INDEX : integer := llc_offset(i, LLC_HIT); + constant MISS_INDEX : integer := llc_offset(i, LLC_MISS); + + begin -- process llc0_counter + + if (user_rstn = '0') then -- asynchronous reset (active low) count_value(hit_index) <= (others => '0'); count_value(miss_index) <= (others => '0'); count(hit_index) <= (others => '0'); count(miss_index) <= (others => '0'); - elsif mon_llc(i).clk'event and mon_llc(i).clk = '1' then -- rising clock edge - if mon_llc(i).hit = '1' then - count(hit_index) <= count(hit_index) + 1; + elsif (mon_llc(i).clk'event and mon_llc(i).clk = '1') then -- rising clock edge + if (mon_llc(i).hit = '1') then + count(hit_index) <= count(HIT_INDEX) + 1; end if; - if mon_llc(i).miss = '1' then - count(miss_index) <= count(miss_index) + 1; + if (mon_llc(i).miss = '1') then + count(miss_index) <= count(MISS_INDEX) + 1; end if; - if new_window_sync_llc(i) = '1' and updated_llc(i) = '0' then + if (new_window_sync_llc(i) = '1' and updated_llc(i) = '0') then count(hit_index) <= (others => '0'); count(miss_index) <= (others => '0'); - count_value(hit_index) <= count(hit_index); - count_value(miss_index) <= count(miss_index); + count_value(hit_index) <= count(HIT_INDEX); + count_value(miss_index) <= count(MISS_INDEX); end if; - if count_reset(hit_index) = '1' then - count(hit_index) <= (others => '0'); - count_value(hit_index) <= (others => '0'); + if (count_reset(HIT_INDEX) = '1') then + count(hit_index) <= (others => '0'); + count_value(hit_index) <= (others => '0'); end if; - if count_reset(miss_index) = '1' then + if (count_reset(MISS_INDEX) = '1') then count(miss_index) <= (others => '0'); count_value(miss_index) <= (others => '0'); end if; end if; + end process llc_counter; end generate llc_gen; end generate llc_monitor_enabled_gen; + mon_dvfs_gen : if mon_dvfs_en /= 0 generate + mon_dvfs_tiles_gen : for i in 0 to tiles_num - 1 generate - mon_dvfs_gen: if mon_dvfs_en /= 0 generate - - mon_dvfs_tiles_gen: for i in 0 to tiles_num-1 generate - synchronizer_6: synchronizer + synchronizer_6 : component synchronizer generic map ( - DATA_WIDTH => 1) + data_width => 1 + ) port map ( - clk => mon_dvfs(i).clk, - reset_n => user_rstn, + clk => mon_dvfs(i).clk, + reset_n => user_rstn, data_i(0) => new_window, - data_o(0) => new_window_sync_dvfs(i)); + data_o(0) => new_window_sync_dvfs(i) + ); + + process (mon_dvfs(i).clk, user_rstn) is + begin -- process - process (mon_dvfs(i).clk, user_rstn) - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) + if (user_rstn = '0') then -- asynchronous reset (active low) updated_dvfs(i) <= '0'; - elsif mon_dvfs(i).clk'event and mon_dvfs(i).clk = '1' then -- rising clock edge - if new_window_sync_dvfs(i) = '1' and updated_dvfs(i) = '0' then + elsif (mon_dvfs(i).clk'event and mon_dvfs(i).clk = '1') then -- rising clock edge + if (new_window_sync_dvfs(i) = '1' and updated_dvfs(i) = '0') then updated_dvfs(i) <= '1'; - elsif new_window_sync_dvfs(i) = '0' then + elsif (new_window_sync_dvfs(i) = '0') then updated_dvfs(i) <= '0'; end if; end if; + end process; - dvfs_op_counters: for k in 0 to VF_OP_POINTS-1 generate - process (mon_dvfs(i).clk, user_rstn) - constant index : integer := dvfs_offset(i, k); - begin -- process - if user_rstn = '0' then -- asynchronous reset (active low) - count(index) <= (others => '0'); + dvfs_op_counters : for k in 0 to VF_OP_POINTS - 1 generate + + process (mon_dvfs(i).clk, user_rstn) is + + constant INDEX : integer := dvfs_offset(i, k); + + begin -- process + + if (user_rstn = '0') then -- asynchronous reset (active low) + count(index) <= (others => '0'); count_value(index) <= (others => '0'); - elsif mon_dvfs(i).clk'event and mon_dvfs(i).clk = '1' then -- rising clock edge - if mon_dvfs(i).vf(k) = '1' then - count(index) <= count(index) + 1; + elsif (mon_dvfs(i).clk'event and mon_dvfs(i).clk = '1') then -- rising clock edge + if (mon_dvfs(i).vf(k) = '1') then + count(index) <= count(INDEX) + 1; end if; - if new_window_sync_dvfs(i) = '1' and updated_dvfs(i) = '0' then - count(index) <= (others => '0'); - count_value(index) <= count(index); + if (new_window_sync_dvfs(i) = '1' and updated_dvfs(i) = '0') then + count(index) <= (others => '0'); + count_value(index) <= count(INDEX); end if; - if count_reset(index) = '1' then - count(index) <= (others => '0'); + if (count_reset(INDEX) = '1') then + count(index) <= (others => '0'); count_value(index) <= (others => '0'); end if; end if; + end process; + end generate dvfs_op_counters; end generate mon_dvfs_tiles_gen; end generate mon_dvfs_gen; - --pragma translate_off - boot_message: process - variable s : line; + -- pragma translate_off + boot_message : process is + + variable s : line; variable dir : line; - begin -- process boot_message + + begin -- process boot_message + wait for 200 ns; write(s, "==========================" & LF); write(s, "MMI64 monitors address map" & LF); - writeline(output,s); - if mon_ddr_en /= 0 then - for i in 0 to ddrs_num-1 loop + writeline(output, s); + + if (mon_ddr_en /= 0) then + + for i in 0 to ddrs_num - 1 loop + write(s, "DDR" & integer'image(i) & ": " & integer'image(ddr_offset(i)) & LF); - writeline(output,s); - end loop; -- i + writeline(output, s); + + end loop; -- i + end if; - if mon_mem_en /= 0 then - for i in 0 to ddrs_num+slms_num-1 loop + if (mon_mem_en /= 0) then + + for i in 0 to ddrs_num + slms_num - 1 loop + write(s, "MEM-" & integer'image(i) & ".coh_req : " & integer'image(mem_offset(i, MEM_COH_REQ)) & LF); - writeline(output,s); + writeline(output, s); write(s, "MEM-" & integer'image(i) & ".coh_fwd : " & integer'image(mem_offset(i, MEM_COH_FWD)) & LF); - writeline(output,s); + writeline(output, s); write(s, "MEM-" & integer'image(i) & ".coh_rsp_rcv : " & integer'image(mem_offset(i, MEM_COH_RSP_RCV)) & LF); - writeline(output,s); + writeline(output, s); write(s, "MEM-" & integer'image(i) & ".coh_rsp_snd : " & integer'image(mem_offset(i, MEM_COH_RSP_SND)) & LF); - writeline(output,s); + writeline(output, s); write(s, "MEM-" & integer'image(i) & ".dma_req : " & integer'image(mem_offset(i, MEM_DMA_REQ)) & LF); - writeline(output,s); + writeline(output, s); write(s, "MEM-" & integer'image(i) & ".dma_rsp : " & integer'image(mem_offset(i, MEM_DMA_RSP)) & LF); - writeline(output,s); + writeline(output, s); write(s, "MEM-" & integer'image(i) & ".coh_dma_req : " & integer'image(mem_offset(i, MEM_COH_DMA_REQ)) & LF); - writeline(output,s); + writeline(output, s); write(s, "MEM-" & integer'image(i) & ".coh_dma_rsp : " & integer'image(mem_offset(i, MEM_COH_DMA_RSP)) & LF); - writeline(output,s); - end loop; -- i + writeline(output, s); + + end loop; -- i + end if; - if mon_noc_tile_inject_en /= 0 then - for i in 0 to nocs_num-1 loop - for k in 0 to tiles_num-1 loop + if (mon_noc_tile_inject_en /= 0) then + + for i in 0 to nocs_num - 1 loop + + for k in 0 to tiles_num - 1 loop + write(s, "NoC" & integer'image(i) & ".tile_inject" & integer'image(k) & ": " & integer'image(noc_tile_inject_offset(i,k)) & LF); writeline(output, s); - end loop; --k - end loop; -- i + + end loop; -- k + + end loop; -- i + end if; - if mon_noc_queues_full_en /= 0 then - for i in 0 to nocs_num-1 loop - for k in 0 to tiles_num-1 loop + if (mon_noc_queues_full_en /= 0) then + + for i in 0 to nocs_num - 1 loop + + for k in 0 to tiles_num - 1 loop + for z in 0 to 4 loop + case z is + when DIR_N => + write(s, "NoC" & integer'image(i) & ".queue_n_full" & integer'image(k) & ": " & integer'image(noc_queues_full_offset(i,k,z)) & LF); + when DIR_S => + write(s, "NoC" & integer'image(i) & ".queue_s_full" & integer'image(k) & ": " & integer'image(noc_queues_full_offset(i,k,z)) & LF); + when DIR_W => + write(s, "NoC" & integer'image(i) & ".queue_w_full" & integer'image(k) & ": " & integer'image(noc_queues_full_offset(i,k,z)) & LF); + when DIR_E => + write(s, "NoC" & integer'image(i) & ".queue_e_full" & integer'image(k) & ": " & integer'image(noc_queues_full_offset(i,k,z)) & LF); + when DIR_L => + write(s, "NoC" & integer'image(i) & ".queue_l_full" & integer'image(k) & ": " & integer'image(noc_queues_full_offset(i,k,z)) & LF); - when others => null; + + when others => + + null; + end case; + writeline(output, s); - end loop; -- z - end loop; --k - end loop; -- i + + end loop; -- z + + end loop; -- k + + end loop; -- i + end if; - if mon_acc_en /= 0 then - for k in 0 to accelerators_num-1 loop + if (mon_acc_en /= 0) then + + for k in 0 to accelerators_num - 1 loop + for z in 0 to 4 loop + case z is + when ACC_TLB => + write(s, "acc" & integer'image(k) & ".tlb " & ": " & integer'image(acc_offset(k,z)) & LF); + when ACC_MEM_LO => + write(s, "acc" & integer'image(k) & ".mem_lo" & ": " & integer'image(acc_offset(k,z)) & LF); + when ACC_MEM_HI => + write(s, "acc" & integer'image(k) & ".mem_hi" & ": " & integer'image(acc_offset(k,z)) & LF); + when ACC_TOT_LO => + write(s, "acc" & integer'image(k) & ".tot_lo" & ": " & integer'image(acc_offset(k,z)) & LF); + when ACC_TOT_HI => + write(s, "acc" & integer'image(k) & ".tot_hi" & ": " & integer'image(acc_offset(k,z)) & LF); - when others => null; + + when others => + + null; + end case; + writeline(output, s); - end loop; -- z - end loop; --k + + end loop; -- z + + end loop; -- k + end if; - if mon_l2_en /= 0 then - for i in 0 to l2_num-1 loop + if (mon_l2_en /= 0) then + + for i in 0 to l2_num - 1 loop + write(s, "L2-" & integer'image(i) & ".hit : " & integer'image(l2_offset(i, L2_HIT)) & LF); - writeline(output,s); + writeline(output, s); write(s, "L2-" & integer'image(i) & ".miss: " & integer'image(l2_offset(i, L2_MISS)) & LF); - writeline(output,s); - end loop; -- i + writeline(output, s); + + end loop; -- i + end if; - if mon_llc_en /= 0 then - for i in 0 to llc_num-1 loop + if (mon_llc_en /= 0) then + + for i in 0 to llc_num - 1 loop + write(s, "LLC-" & integer'image(i) & ".hit : " & integer'image(llc_offset(i, LLC_HIT)) & LF); - writeline(output,s); + writeline(output, s); write(s, "LLC-" & integer'image(i) & ".miss: " & integer'image(llc_offset(i, LLC_MISS)) & LF); - writeline(output,s); - end loop; -- i + writeline(output, s); + + end loop; -- i + end if; - if mon_dvfs_en /= 0 then - for k in 0 to tiles_num-1 loop - for z in 0 to VF_OP_POINTS-1 loop - write(s, "dvfs" & integer'image(k) & ".op" & integer'image(z) & ": " - & integer'image(dvfs_offset(k,z)) & LF); + if (mon_dvfs_en /= 0) then + + for k in 0 to tiles_num - 1 loop + + for z in 0 to VF_OP_POINTS - 1 loop + + write(s, "dvfs" & integer'image(k) & ".op" & integer'image(z) & ": " + & integer'image(dvfs_offset(k,z)) & LF); writeline(output, s); - end loop; -- z - end loop; --k + + end loop; -- z + + end loop; -- k + end if; write(s, "TOTAL MONITOR REGISTERS: " & integer'image(MONITOR_REG_COUNT) & LF); - writeline(output,s); - for z in 0 to CTRL_REG_COUNT-1 loop + writeline(output, s); + + for z in 0 to CTRL_REG_COUNT - 1 loop + case z is + when CTRL_RESET => + write(s, "CTRL" & ".reset " & ": " & integer'image(ctrl_offset(z)) & LF); + when CTRL_WINDOW_SIZE => + write(s, "CTRL" & ".win_sz" & ": " & integer'image(ctrl_offset(z)) & LF); + when CTRL_WINDOW_COUNT_LO => + write(s, "CTRL" & ".win_lo" & ": " & integer'image(ctrl_offset(z)) & LF); + when CTRL_WINDOW_COUNT_HI => + write(s, "CTRL" & ".win_hi" & ": " & integer'image(ctrl_offset(z)) & LF); - when others => null; + + when others => + + null; + end case; + writeline(output, s); - end loop; -- z + + end loop; -- z + write(s, "TOTAL CTRL MONITOR: " & integer'image(CTRL_REG_COUNT) & LF); - writeline(output,s); + writeline(output, s); write(s, "TOTAL MMI64 REG COUNT: " & integer'image(REGISTER_COUNT) & LF); - writeline(output,s); + writeline(output, s); write(s, "==========================" & LF); writeline(output, s); wait; + end process boot_message; - --pragma translate_on -end; +-- pragma translate_on + +end architecture rtl; diff --git a/rtl/sockets/proxy/ahbslv2iolink.vhd b/rtl/sockets/proxy/ahbslv2iolink.vhd index 840cdfa085..51139421b5 100644 --- a/rtl/sockets/proxy/ahbslv2iolink.vhd +++ b/rtl/sockets/proxy/ahbslv2iolink.vhd @@ -2,110 +2,117 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.esp_global.all; -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; -use work.gencomp.all; -use work.leon3.all; -use work.uart.all; -use work.misc.all; -use work.net.all; --- pragma translate_off -use work.sim.all; -library unisim; -use unisim.all; --- pragma translate_on -use work.sldacc.all; -use work.nocpackage.all; -use work.tile.all; -use work.coretypes.all; -use work.grlib_config.all; -use work.socmap.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.esp_global.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.leon3.all; + use work.uart.all; + use work.misc.all; + use work.net.all; + -- pragma translate_off + use work.sim.all; +library unisim; + use unisim.all; + -- pragma translate_on + use work.sldacc.all; + use work.nocpackage.all; + use work.tile.all; + use work.coretypes.all; + use work.grlib_config.all; + use work.socmap.all; entity ahbslv2iolink is generic ( hindex : integer range 0 to NAHBSLV - 1 := 0; hconfig : ahb_config_type; - io_bitwidth : integer range 1 to ARCH_BITS := 32; -- power of 2, <= word_bitwidth - word_bitwidth : integer range 1 to ARCH_BITS := 32; -- 32 or 64 - little_end : integer range 0 to 1 := 0); + io_bitwidth : integer range 1 to ARCH_BITS := 32; -- power of 2, <= word_bitwidth + word_bitwidth : integer range 1 to ARCH_BITS := 32; -- 32 or 64 + little_end : integer range 0 to 1 := 0 + ); port ( - clk : in std_ulogic; - rstn : in std_ulogic; - io_clk_in : in std_logic; - io_clk_out : out std_logic; - io_valid_in : in std_ulogic; - io_valid_out : out std_ulogic; - io_credit_in : in std_logic; - io_credit_out : out std_logic; - io_data_oen : out std_logic; - io_data_in : in std_logic_vector(io_bitwidth - 1 downto 0); - io_data_out : out std_logic_vector(io_bitwidth - 1 downto 0); - ahbsi : in ahb_slv_in_type; - ahbso : out ahb_slv_out_type); - + clk : in std_ulogic; + rstn : in std_ulogic; + io_clk_in : in std_logic; + io_clk_out : out std_logic; + io_valid_in : in std_ulogic; + io_valid_out : out std_ulogic; + io_credit_in : in std_logic; + io_credit_out : out std_logic; + io_data_oen : out std_logic; + io_data_in : in std_logic_vector(io_bitwidth - 1 downto 0); + io_data_out : out std_logic_vector(io_bitwidth - 1 downto 0); + ahbsi : in ahb_slv_in_type; + ahbso : out ahb_slv_out_type + ); end entity ahbslv2iolink; architecture rtl of ahbslv2iolink is ---------------------------------------------------------------------------- - --AHB slv + -- AHB slv + type attribute_vector is array (natural range <>) of integer; - --signal hconfig : ahb_config_type; - - constant ddr_haddr : integer := 16#400#; - constant hmask : integer := 16#C00#; + + -- signal hconfig : ahb_config_type; + + constant DDR_HADDR : integer := 16#400#; + constant HMASK : integer := 16#C00#; -- added for compatability with ahb ramsim - constant maccsz : integer := AHBDW; - constant dw : integer := maccsz; - constant kbytes : integer := 2 * 1024; - constant abits : integer := log2ext(kbytes) + 10 - log2(dw/8); -- understand value - - + constant MACCSZ : integer := AHBDW; + constant DW : integer := MACCSZ; + constant KBYTES : integer := 2 * 1024; + constant ABITS : integer := log2ext(KBYTES) + 10 - log2(DW / 8); -- understand value + ----------------------------------------------------------------------------- - --FSM: ahb rd/wr + -- FSM: ahb rd/wr ------------------------------------------------------------------------------ + type ahb_to_io_state is (recv_address, get_length, snd_data, rcv_data, early_burst_term); - + type ahb_slv_out_local_type is record - hready : std_ulogic; - hresp : std_logic_vector(1 downto 0); - hrdata : std_logic_vector(AHBDW-1 downto 0); - end record; + hready : std_ulogic; + hresp : std_logic_vector(1 downto 0); + hrdata : std_logic_vector(AHBDW - 1 downto 0); + end record ahb_slv_out_local_type; type reg_type is record - state : ahb_to_io_state; - ahbsout : ahb_slv_out_local_type; - cnt : integer; - burst_mode : std_ulogic; - load_first : std_ulogic; - end record; - + state : ahb_to_io_state; + ahbsout : ahb_slv_out_local_type; + cnt : integer; + burst_mode : std_ulogic; + load_first : std_ulogic; + end record reg_type; + constant QUEUE_DEPTH : integer := 8; - - constant ahbsout_reset : ahb_slv_out_local_type := ( - hready => '1', - hresp => HRESP_OKAY, - hrdata => (others => '0')); - - constant REG_DEF : reg_type := ( - state => recv_address, - ahbsout => ahbsout_reset, - cnt => 0, - burst_mode => '0', - load_first => '0' + + constant AHBSOUT_RESET : ahb_slv_out_local_type := + ( + hready => '1', + hresp => HRESP_OKAY, + hrdata => (others => '0') + ); + + constant REG_DEF : reg_type := + ( + state => recv_address, + ahbsout => AHBSOUT_RESET, + cnt => 0, + burst_mode => '0', + load_first => '0' ); - - constant zero_ahb_flags : std_logic_vector(0 to NAHBSLV - 1) := (others => '0'); - + + constant ZERO_AHB_FLAGS : std_logic_vector(0 to NAHBSLV - 1) := (others => '0'); + ------------------------------------------------------------------------------- -- FSM: I/O Send ------------------------------------------------------------------------------- + type io_snd_fsm_t is (idle, send); type io_snd_reg_type is record @@ -114,20 +121,23 @@ architecture rtl of ahbslv2iolink is cnt : integer range 0 to 64; end record io_snd_reg_type; - constant IO_SND_REG_DEFAULT : io_snd_reg_type := ( + constant IO_SND_REG_DEFAULT : io_snd_reg_type := + ( state => idle, word => (others => '0'), - cnt => 0); + cnt => 0 + ); - signal io_snd_reg, io_snd_reg_next : io_snd_reg_type; + signal io_snd_reg, io_snd_reg_next : io_snd_reg_type; + + constant DEFAULT_LEN : std_logic_vector := x"00000001"; + constant MAX_BURST_SIZE : integer := 27; -- 256; + constant IO_BEATS : natural range 1 to 64 := word_bitwidth / io_bitwidth; - constant default_len : std_logic_vector := x"00000001"; - constant MAX_BURST_SIZE : integer := 27; --256; - constant IO_BEATS : natural range 1 to 64 := word_bitwidth / io_bitwidth; - --------------------------------------------------- -- io_en sync delay -------------------------------------------------- + type snd_sync_type is record sync_clk : std_ulogic; async : std_ulogic; @@ -144,143 +154,147 @@ architecture rtl of ahbslv2iolink is signal receiving : rcv_sync_type; signal sending : snd_sync_type; - attribute ASYNC_REG : string; - attribute ASYNC_REG of receiving : signal is "TRUE"; + attribute async_reg : string; + attribute async_reg of receiving : signal is "TRUE"; -- attribute ASYNC_REG of sending : signal is "TRUE"; ------------------------------------------------------------------------------- -- FSM: Output enable ------------------------------------------------------------------------------- + type oen_fsm_t is (receive_address, receive_length, receive_data, send_data); type oen_reg_type is record - state : oen_fsm_t; - count : integer; - write : std_ulogic; + state : oen_fsm_t; + count : integer; + write : std_ulogic; end record oen_reg_type; - constant OEN_REG_DEFAULT : oen_reg_type := ( + constant OEN_REG_DEFAULT : oen_reg_type := + ( state => receive_address, count => 0, - write => '0'); + write => '0' + ); - signal oen_reg, oen_reg_next : oen_reg_type; + signal oen_reg, oen_reg_next : oen_reg_type; signal oen_fsm_idle, oen_fsm_idle_sync : std_logic; - - + ------------------------------------------------------------------------------- -- FSM: I/O Receive ------------------------------------------------------------------------------- + type io_rcv_reg_type is record word : std_logic_vector(word_bitwidth - 1 downto 0); cnt : integer range 0 to 64; end record io_rcv_reg_type; - constant IO_RCV_REG_DEFAULT : io_rcv_reg_type := ( + constant IO_RCV_REG_DEFAULT : io_rcv_reg_type := + ( word => (others => '0'), - cnt => 0); + cnt => 0 + ); - signal io_rcv_reg, io_rcv_reg_next : io_rcv_reg_type; + signal io_rcv_reg, io_rcv_reg_next : io_rcv_reg_type; - - signal ahb_rcv_wrreq : std_ulogic; - signal ahb_rcv_rdreq : std_ulogic; - signal ahb_rcv_data_in : std_logic_vector(word_bitwidth - 1 downto 0); - signal ahb_rcv_data_out : std_logic_vector(word_bitwidth - 1 downto 0); - signal ahb_rcv_full : std_ulogic; - signal ahb_rcv_empty : std_ulogic; + signal ahb_rcv_wrreq : std_ulogic; + signal ahb_rcv_rdreq : std_ulogic; + signal ahb_rcv_data_in : std_logic_vector(word_bitwidth - 1 downto 0); + signal ahb_rcv_data_out : std_logic_vector(word_bitwidth - 1 downto 0); + signal ahb_rcv_full : std_ulogic; + signal ahb_rcv_empty : std_ulogic; signal ahb_rcv_almost_full : std_ulogic; - + signal hsel_reg : std_logic_vector(0 to NAHBSLV - 1); - signal hwdata_reg : std_logic_vector (word_bitwidth - 1 downto 0); + signal hwdata_reg : std_logic_vector(word_bitwidth - 1 downto 0); signal hwrite_reg : std_ulogic; - signal hburst_reg : std_logic_vector (2 downto 0); - signal htrans_reg : std_logic_vector (1 downto 0); + signal hburst_reg : std_logic_vector(2 downto 0); + signal htrans_reg : std_logic_vector(1 downto 0); signal sample_bus : std_ulogic; - signal r, rin : reg_type; - signal ahb_clk_in : std_ulogic; - + signal r, rin : reg_type; + signal ahb_clk_in : std_ulogic; + signal credits : integer range 0 to QUEUE_DEPTH; signal credit_in : std_ulogic; signal credit_in_empty : std_ulogic; signal credit_received : std_ulogic; - signal io_snd_wrreq_in : std_logic; - signal io_snd_data_in : std_logic_vector (word_bitwidth - 1 downto 0); - signal io_snd_full_in : std_logic; - signal io_snd_clk_out : std_logic; - signal io_snd_rdreq_out : std_logic; - signal io_snd_data_out : std_logic_vector (word_bitwidth - 1 downto 0); - signal io_snd_empty : std_logic; - + signal io_snd_wrreq_in : std_logic; + signal io_snd_data_in : std_logic_vector(word_bitwidth - 1 downto 0); + signal io_snd_full_in : std_logic; + signal io_snd_clk_out : std_logic; + signal io_snd_rdreq_out : std_logic; + signal io_snd_data_out : std_logic_vector(word_bitwidth - 1 downto 0); + signal io_snd_empty : std_logic; + signal io_clk_out_int : std_logic; signal io_valid_out_int : std_ulogic; - signal rst :std_ulogic; - - signal ahb_snd_wrreq : std_ulogic; - signal ahb_snd_rdreq : std_ulogic; - signal ahb_snd_data_in : std_logic_vector(word_bitwidth - 1 downto 0); - signal ahb_snd_data_out : std_logic_vector(word_bitwidth - 1 downto 0); - signal ahb_snd_full : std_ulogic; - signal ahb_snd_almost_full : std_ulogic; - signal ahb_snd_empty : std_ulogic; - + signal rst : std_ulogic; + + signal ahb_snd_wrreq : std_ulogic; + signal ahb_snd_rdreq : std_ulogic; + signal ahb_snd_data_in : std_logic_vector(word_bitwidth - 1 downto 0); + signal ahb_snd_data_out : std_logic_vector(word_bitwidth - 1 downto 0); + signal ahb_snd_full : std_ulogic; + signal ahb_snd_almost_full : std_ulogic; + signal ahb_snd_empty : std_ulogic; + signal io_rcv_wrreq_in : std_logic; - signal io_rcv_data_in : std_logic_vector (word_bitwidth - 1 downto 0); + signal io_rcv_data_in : std_logic_vector(word_bitwidth - 1 downto 0); signal io_rcv_full_in : std_logic; signal io_rcv_clk_out : std_logic; signal io_rcv_rdreq_out : std_logic; - signal io_rcv_data_out : std_logic_vector (word_bitwidth - 1 downto 0); + signal io_rcv_data_out : std_logic_vector(word_bitwidth - 1 downto 0); signal io_rcv_almost_full : std_ulogic; signal io_rcv_empty : std_logic; - + attribute mark_debug : string; - --attribute keep : string; - - --attribute mark_debug of ahb_snd_wrreq : signal is "true"; - --attribute mark_debug of ahb_snd_rdreq : signal is "true"; - --attribute mark_debug of ahb_snd_data_in : signal is "true"; - --attribute mark_debug of ahb_snd_data_out : signal is "true"; - --attribute mark_debug of ahb_snd_full : signal is "true"; - --attribute mark_debug of ahb_snd_almost_full : signal is "true"; - --attribute mark_debug of ahb_snd_empty : signal is "true"; - --attribute mark_debug of io_rcv_wrreq_in : signal is "true"; - --attribute mark_debug of io_rcv_data_in : signal is "true"; - --attribute mark_debug of io_rcv_full_in : signal is "true"; - --attribute mark_debug of io_rcv_clk_out : signal is "true"; - --attribute mark_debug of io_rcv_rdreq_out : signal is "true"; - --attribute mark_debug of io_rcv_data_out : signal is "true"; - --attribute mark_debug of io_rcv_almost_full : signal is "true"; - --attribute mark_debug of io_rcv_empty : signal is "true"; - --attribute mark_debug of credits : signal is "true"; - --attribute mark_debug of credit_in : signal is "true"; - --attribute mark_debug of credit_in_empty : signal is "true"; - --attribute mark_debug of credit_received : signal is "true"; - --attribute mark_debug of r : signal is "true"; - --attribute mark_debug of ahb_rcv_wrreq : signal is "true"; - --attribute mark_debug of ahb_rcv_rdreq : signal is "true"; - --attribute mark_debug of ahb_rcv_data_in : signal is "true"; - --attribute mark_debug of ahb_rcv_data_out : signal is "true"; - --attribute mark_debug of ahb_rcv_full : signal is "true"; - --attribute mark_debug of ahb_rcv_empty : signal is "true"; - --attribute mark_debug of ahb_rcv_almost_full : signal is "true"; - --attribute mark_debug of io_snd_reg : signal is "true"; - --attribute mark_debug of receiving : signal is "true"; - --attribute mark_debug of sending : signal is "true"; - --attribute mark_debug of hsel_reg : signal is "true"; - --attribute mark_debug of hwdata_reg : signal is "true"; - --attribute mark_debug of hwrite_reg : signal is "true"; - --attribute mark_debug of hburst_reg : signal is "true"; - --attribute mark_debug of htrans_reg : signal is "true"; - --attribute mark_debug of io_rcv_reg : signal is "true"; - --attribute mark_debug of oen_reg : signal is "true"; - --attribute mark_debug of oen_fsm_idle : signal is "true"; - +-- attribute keep : string; + +-- attribute mark_debug of ahb_snd_wrreq : signal is "true"; +-- attribute mark_debug of ahb_snd_rdreq : signal is "true"; +-- attribute mark_debug of ahb_snd_data_in : signal is "true"; +-- attribute mark_debug of ahb_snd_data_out : signal is "true"; +-- attribute mark_debug of ahb_snd_full : signal is "true"; +-- attribute mark_debug of ahb_snd_almost_full : signal is "true"; +-- attribute mark_debug of ahb_snd_empty : signal is "true"; +-- attribute mark_debug of io_rcv_wrreq_in : signal is "true"; +-- attribute mark_debug of io_rcv_data_in : signal is "true"; +-- attribute mark_debug of io_rcv_full_in : signal is "true"; +-- attribute mark_debug of io_rcv_clk_out : signal is "true"; +-- attribute mark_debug of io_rcv_rdreq_out : signal is "true"; +-- attribute mark_debug of io_rcv_data_out : signal is "true"; +-- attribute mark_debug of io_rcv_almost_full : signal is "true"; +-- attribute mark_debug of io_rcv_empty : signal is "true"; +-- attribute mark_debug of credits : signal is "true"; +-- attribute mark_debug of credit_in : signal is "true"; +-- attribute mark_debug of credit_in_empty : signal is "true"; +-- attribute mark_debug of credit_received : signal is "true"; +-- attribute mark_debug of r : signal is "true"; +-- attribute mark_debug of ahb_rcv_wrreq : signal is "true"; +-- attribute mark_debug of ahb_rcv_rdreq : signal is "true"; +-- attribute mark_debug of ahb_rcv_data_in : signal is "true"; +-- attribute mark_debug of ahb_rcv_data_out : signal is "true"; +-- attribute mark_debug of ahb_rcv_full : signal is "true"; +-- attribute mark_debug of ahb_rcv_empty : signal is "true"; +-- attribute mark_debug of ahb_rcv_almost_full : signal is "true"; +-- attribute mark_debug of io_snd_reg : signal is "true"; +-- attribute mark_debug of receiving : signal is "true"; +-- attribute mark_debug of sending : signal is "true"; +-- attribute mark_debug of hsel_reg : signal is "true"; +-- attribute mark_debug of hwdata_reg : signal is "true"; +-- attribute mark_debug of hwrite_reg : signal is "true"; +-- attribute mark_debug of hburst_reg : signal is "true"; +-- attribute mark_debug of htrans_reg : signal is "true"; +-- attribute mark_debug of io_rcv_reg : signal is "true"; +-- attribute mark_debug of oen_reg : signal is "true"; +-- attribute mark_debug of oen_fsm_idle : signal is "true"; + begin - - rst <= not rstn; + + rst <= not rstn; io_data_oen <= sending.sync_clk_io or not receiving.sync_clk_io; ----------------------------------------------------------------------------- @@ -290,31 +304,38 @@ begin -- pads enables are never driven on both ends of the line at the same time. state_synchronizer : process (io_clk_in) is begin + if rising_edge(io_clk_in) then sending.async <= sending.sync_clk; sending.sync_clk_io <= sending.async; end if; + end process state_synchronizer; state_delay : process (io_clk_out_int) is begin + if rising_edge(io_clk_out_int) then - receiving.async <= receiving.sync_clk; - receiving.delay(0) <= receiving.async; - receiving.delay(1) <= receiving.delay(0); - receiving.delay(2) <= receiving.delay(1); - receiving.delay(3) <= receiving.delay(2); - --receiving.delay(4) <= receiving.delay(3); + receiving.async <= receiving.sync_clk; + receiving.delay(0) <= receiving.async; + receiving.delay(1) <= receiving.delay(0); + receiving.delay(2) <= receiving.delay(1); + receiving.delay(3) <= receiving.delay(2); + -- receiving.delay(4) <= receiving.delay(3); receiving.sync_clk_io <= receiving.delay(3) and not sending.sync_clk; end if; + end process state_delay; receiving.sync_clk <= not sending.sync_clk; - + -- oen fsm oen_fsm : process (oen_reg, ahb_rcv_wrreq, io_rcv_data_in, ahb_snd_rdreq, hburst_reg, ahbsi) is + variable reg : oen_reg_type; + begin + reg := oen_reg; sending.sync_clk <= '1'; @@ -322,20 +343,22 @@ begin case oen_reg.state is when receive_address => - if ahb_rcv_wrreq = '1' then + + if (ahb_rcv_wrreq = '1') then reg.state := receive_length; reg.write := ahb_rcv_data_in(0); end if; when receive_length => - if ahb_rcv_wrreq = '1' then + + if (ahb_rcv_wrreq = '1') then if (hburst_reg = "001" and ahbsi.htrans = HTRANS_SEQ) then reg.count := MAX_BURST_SIZE; else - reg.count := to_integer(unsigned(default_len)); + reg.count := to_integer(unsigned(DEFAULT_LEN)); end if; - --reg.count := conv_integer(io_rcv_data_in(31 downto 0)); - if reg.write = '1' then + -- reg.count := conv_integer(io_rcv_data_in(31 downto 0)); + if (reg.write = '1') then reg.state := send_data; else reg.state := receive_data; @@ -343,18 +366,21 @@ begin end if; when send_data => - if ahb_rcv_wrreq = '1' then + + if (ahb_rcv_wrreq = '1') then reg.count := reg.count - 1; - if reg.count = 0 then + if (reg.count = 0) then reg.state := receive_address; end if; end if; when receive_data => + sending.sync_clk <= '0'; - if ahb_snd_rdreq = '1' then + + if (ahb_snd_rdreq = '1') then reg.count := reg.count - 1; - if reg.count = 0 then + if (reg.count = 0) then reg.state := receive_address; end if; end if; @@ -362,67 +388,75 @@ begin end case; oen_reg_next <= reg; + end process oen_fsm; - oen_fsm_idle <= '1' when oen_reg.state = receive_address else '0'; - --oen_fsm_idle <= '1' when oen_reg.state = '0'; - + + oen_fsm_idle <= '1' when oen_reg.state = receive_address else + '0'; + -- oen_fsm_idle <= '1' when oen_reg.state = '0'; + -- Credits in - oen_reg_fifo : inferred_async_fifo + oen_reg_fifo : component inferred_async_fifo generic map ( g_data_width => 1, - g_size => 2) + g_size => 2 + ) port map ( - rst_wr_n_i => rstn, + rst_wr_n_i => rstn, clk_wr_i => io_clk_in, we_i => '1', d_i(0) => oen_fsm_idle, wr_full_o => open, - rst_rd_n_i => rstn, + rst_rd_n_i => rstn, clk_rd_i => clk, rd_i => '1', q_o(0) => oen_fsm_idle_sync, - rd_empty_o => open); - + rd_empty_o => open + ); -- ahb reqst receiving FIFO - ahb_in_fifo : fifo3 + ahb_in_fifo : component fifo3 generic map ( depth => QUEUE_DEPTH, - width => word_bitwidth) + width => word_bitwidth + ) port map ( - clk => clk, - rst => rstn, - wrreq => ahb_rcv_wrreq, - data_in => ahb_rcv_data_in, - full => ahb_rcv_full, - almost_full => ahb_rcv_almost_full, - rdreq => io_snd_rdreq_out, - data_out => io_snd_data_out, - empty => io_snd_empty); - --- ahb sending FIFO - ahb_out_fifo : inferred_async_fifo + clk => clk, + rst => rstn, + wrreq => ahb_rcv_wrreq, + data_in => ahb_rcv_data_in, + full => ahb_rcv_full, + almost_full => ahb_rcv_almost_full, + rdreq => io_snd_rdreq_out, + data_out => io_snd_data_out, + empty => io_snd_empty + ); + + -- ahb sending FIFO + ahb_out_fifo : component inferred_async_fifo generic map ( g_data_width => word_bitwidth, - g_size => QUEUE_DEPTH) + g_size => QUEUE_DEPTH + ) port map ( - rst_wr_n_i => rstn, + rst_wr_n_i => rstn, clk_wr_i => io_clk_in, - we_i => io_rcv_wrreq_in, + we_i => io_rcv_wrreq_in, d_i => io_rcv_data_in, wr_full_o => io_rcv_full_in, - rst_rd_n_i => rstn, + rst_rd_n_i => rstn, clk_rd_i => clk, rd_i => io_rcv_rdreq_out, q_o => io_rcv_data_out, - rd_empty_o => io_rcv_empty); - + rd_empty_o => io_rcv_empty + ); - io_out_fifo : fifo3 - generic map ( + io_out_fifo : component fifo3 + generic map ( depth => QUEUE_DEPTH, - width => word_bitwidth) - port map ( + width => word_bitwidth + ) + port map ( clk => clk, rst => rstn, wrreq => ahb_snd_wrreq, @@ -431,143 +465,153 @@ begin almost_full => ahb_snd_almost_full, rdreq => ahb_snd_rdreq, data_out => ahb_snd_data_out, - empty => ahb_snd_empty); - - ahb_snd_wrreq <= not io_rcv_empty and not ahb_snd_full; + empty => ahb_snd_empty + ); + + ahb_snd_wrreq <= not io_rcv_empty and not ahb_snd_full; io_rcv_rdreq_out <= not io_rcv_empty and not ahb_snd_full; - ahb_snd_data_in <= io_rcv_data_out; - - --io_data_out <= (others => '0'); - --io_valid_out <= '0'; - --io_clk_out <= '0'; - --io_credit_out <= '0'; - --ahbso.hresp <= "00"; - --ahbso.hsplit <= (others => '0'); - --ahbso.hirq <= (others => '0'); - --ahbso.hconfig <= hconfig; - --ahbso.hindex <= hindex; + ahb_snd_data_in <= io_rcv_data_out; + + -- io_data_out <= (others => '0'); + -- io_valid_out <= '0'; + -- io_clk_out <= '0'; + -- io_credit_out <= '0'; + -- ahbso.hresp <= "00"; + -- ahbso.hsplit <= (others => '0'); + -- ahbso.hirq <= (others => '0'); + -- ahbso.hconfig <= hconfig; + -- ahbso.hindex <= hindex; ----------------------------------------------------------------------------- -- Credits in - credits_in_fifo : inferred_async_fifo + credits_in_fifo : component inferred_async_fifo generic map ( g_data_width => 1, - g_size => 2 * QUEUE_DEPTH) + g_size => 2 * QUEUE_DEPTH + ) port map ( - rst_wr_n_i => rstn, + rst_wr_n_i => rstn, clk_wr_i => io_clk_in, we_i => io_credit_in, d_i => "0", wr_full_o => open, - rst_rd_n_i => rstn, + rst_rd_n_i => rstn, clk_rd_i => clk, rd_i => '1', q_o(0) => credit_in, - rd_empty_o => credit_in_empty); + rd_empty_o => credit_in_empty + ); credit_received <= credit_in nor credit_in_empty; - + ----------------------------------------------------------------------------- -- credits fsm credits_fsm : process (clk) is - begin -- process - if clk'event and clk = '1' then -- rising clock edge - if rstn = '0' then + begin -- process + + if (clk'event and clk = '1') then -- rising clock edge + if (rstn = '0') then credits <= QUEUE_DEPTH; else - if io_snd_rdreq_out = '1' and credit_received = '0' and credits /= 0 then + if (io_snd_rdreq_out = '1' and credit_received = '0' and credits /= 0) then credits <= credits - 1; - elsif io_snd_rdreq_out = '0' and credit_received = '1' and credits /= QUEUE_DEPTH then + elsif (io_snd_rdreq_out = '0' and credit_received = '1' and credits /= QUEUE_DEPTH) then credits <= credits + 1; end if; + end if; end if; - end if; + end process credits_fsm; ----------------------------------------------------------------------------- -- Credits out credits_out_reg : process (clk) is begin -- process io_credit_out_reg - if clk'event and clk = '1' then + + if (clk'event and clk = '1') then io_credit_out <= ahb_snd_rdreq; end if; + end process credits_out_reg; ----------------------------------------------------------------------------- - --FSM ahbslv rd/write - ahb_rdwr_reqsts_fsm : process (r, ahbsi, io_snd_empty, ahb_rcv_almost_full, ahb_rcv_full, ahb_snd_empty, ahb_snd_wrreq, ahb_snd_data_out, hwrite_reg, hburst_reg, hwdata_reg) - variable v : reg_type; - variable burst_mode : std_ulogic; - variable selected : std_ulogic; - + -- FSM ahbslv rd/write + ahb_rdwr_reqsts_fsm : process (r, ahbsi, io_snd_empty, ahb_rcv_almost_full, ahb_rcv_full, ahb_snd_empty, ahb_snd_wrreq, ahb_snd_data_out, hwrite_reg, hburst_reg, hwdata_reg) is + + variable v : reg_type; + variable burst_mode : std_ulogic; + variable selected : std_ulogic; + begin v := r; - - --burst_mode := '0'; - sample_bus <= '0'; - ahb_rcv_wrreq <= '0'; - ahb_rcv_data_in <= (others => '0'); - ahb_snd_rdreq <= '0'; + + -- burst_mode := '0'; + sample_bus <= '0'; + ahb_rcv_wrreq <= '0'; + ahb_rcv_data_in <= (others => '0'); + ahb_snd_rdreq <= '0'; v.ahbsout.hready := '1'; - --ahbso.hready <= '1'; - --ahbso.hrdata <= X"00000000"; - + -- ahbso.hready <= '1'; + -- ahbso.hrdata <= X"00000000"; + -- Default ahbso assignment - ahbso.hready <= '1'; - ahbso.hrdata <= (others => '0'); - ahbso.hresp <= HRESP_OKAY; - ahbso.hsplit <= (others => '0'); - ahbso.hirq <= (others => '0'); - ahbso.hrdata <= (others => '0'); + ahbso.hready <= '1'; + ahbso.hrdata <= (others => '0'); + ahbso.hresp <= HRESP_OKAY; + ahbso.hsplit <= (others => '0'); + ahbso.hirq <= (others => '0'); + ahbso.hrdata <= (others => '0'); ahbso.hconfig <= hconfig; - ahbso.hindex <= hindex; - + ahbso.hindex <= hindex; + selected := '0'; - --if (ahbsi.hsel and hindex) /= zero_ahb_flags then - if (ahbsi.hsel(hindex)) = '1' then + -- if (ahbsi.hsel and hindex) /= zero_ahb_flags then + if ((ahbsi.hsel(hindex)) = '1') then selected := '1'; end if; - + case r.state is when recv_address => - if (ahb_rcv_full or ahb_rcv_almost_full) = '0' then + + if ((ahb_rcv_full or ahb_rcv_almost_full) = '0') then v.burst_mode := '0'; v.load_first := '1'; - if (selected = '1' and ahbsi.hready = '1' and ahbsi.htrans = HTRANS_NONSEQ) then - sample_bus <= '1'; - ahb_rcv_data_in <= (others => '0'); - if (ahbsi.hwrite = '1') then - ahb_rcv_data_in(GLOB_PHYS_ADDR_BITS - 1 downto 0) <= ahbsi.haddr(31 downto 1) & '1'; - else - ahb_rcv_data_in(GLOB_PHYS_ADDR_BITS - 1 downto 0) <= ahbsi.haddr(31 downto 1) & '0'; - end if; - ahb_rcv_wrreq <= '1'; - v.state := get_length; + if (selected = '1' and ahbsi.hready = '1' and ahbsi.htrans = HTRANS_NONSEQ) then + sample_bus <= '1'; + ahb_rcv_data_in <= (others => '0'); + if (ahbsi.hwrite = '1') then + ahb_rcv_data_in(GLOB_PHYS_ADDR_BITS - 1 downto 0) <= ahbsi.haddr(31 downto 1) & '1'; + else + ahb_rcv_data_in(GLOB_PHYS_ADDR_BITS - 1 downto 0) <= ahbsi.haddr(31 downto 1) & '0'; end if; - --TODO: hanlde splitted burst transaction - --end if; + ahb_rcv_wrreq <= '1'; + v.state := get_length; + end if; + -- TODO: hanlde splitted burst transaction + -- end if; end if; - - -- TODO: add different burst lengths + + -- TODO: add different burst lengths when get_length => + v.ahbsout.hready := '0'; - --ahbso.hready <= '0'; - if(ahb_rcv_full or ahb_rcv_almost_full ) = '0' then - --undefined burst length + -- ahbso.hready <= '0'; + if ((ahb_rcv_full or ahb_rcv_almost_full) = '0') then + -- undefined burst length if (hburst_reg = "001" and ahbsi.htrans = HTRANS_SEQ) then ahb_rcv_data_in <= std_logic_vector(to_signed (MAX_BURST_SIZE, ahb_rcv_data_in'length)); - v.cnt := MAX_BURST_SIZE; - v.burst_mode := '1'; - else - ahb_rcv_data_in <= (others => '0'); + v.cnt := MAX_BURST_SIZE; + v.burst_mode := '1'; + else + ahb_rcv_data_in <= (others => '0'); ahb_rcv_data_in(0) <= '1'; - v.cnt := 1; - v.burst_mode := '0'; - end if; + v.cnt := 1; + v.burst_mode := '0'; + end if; ahb_rcv_wrreq <= '1'; - + if (hwrite_reg = '1') then v.state := snd_data; else @@ -576,101 +620,111 @@ begin end if; when snd_data => + v.ahbsout.hready := '0'; - if (ahb_rcv_almost_full or ahb_rcv_full) = '0' then + + if ((ahb_rcv_almost_full or ahb_rcv_full) = '0') then v.ahbsout.hready := '1'; if (v.burst_mode = '1') then -- burst mode - --check early termination of burst + -- check early termination of burst if (ahbsi.htrans = HTRANS_IDLE and r.cnt > 2) then v.state := early_burst_term; - --first word of the burst + -- first word of the burst elsif (v.load_first = '1') then ahb_rcv_data_in <= hwdata_reg; - ahb_rcv_wrreq <= '1'; - v.load_first := '0'; - v.cnt := r.cnt - 1; - --load remaining burst words + ahb_rcv_wrreq <= '1'; + v.load_first := '0'; + v.cnt := r.cnt - 1; + -- load remaining burst words elsif (r.cnt /= 0) then ahb_rcv_data_in <= ahbreadword(ahbsi.hwdata); - ahb_rcv_wrreq <= '1'; - v.load_first := '0'; - v.cnt := r.cnt - 1; + ahb_rcv_wrreq <= '1'; + v.load_first := '0'; + v.cnt := r.cnt - 1; else - v.state := recv_address; + v.state := recv_address; end if; -- single transaction mode elsif (v.burst_mode = '0') then ahb_rcv_data_in <= hwdata_reg; - ahb_rcv_wrreq <= '1'; - v.state := recv_address; + ahb_rcv_wrreq <= '1'; + v.state := recv_address; end if; end if; - --In case of early burst termination - --send 0s for the remaining burst beats + -- In case of early burst termination + -- send 0s for the remaining burst beats when early_burst_term => + v.ahbsout.hready := '0'; - if (ahb_rcv_almost_full or ahb_rcv_full) = '0' then + + if ((ahb_rcv_almost_full or ahb_rcv_full) = '0') then if (r.cnt /= 0) then ahb_rcv_data_in <= (others => '0'); - ahb_rcv_wrreq <= '1'; - v.load_first := '0'; - v.cnt := r.cnt - 1; + ahb_rcv_wrreq <= '1'; + v.load_first := '0'; + v.cnt := r.cnt - 1; else v.state := recv_address; end if; end if; - + when rcv_data => - if (v.cnt = 0) then + + if (v.cnt = 0) then v.state := recv_address; else v.ahbsout.hready := '0'; -- flush receieved data if burst is terminated early - --if (ahbsi.htrans = HTRANS_IDLE or ahbsi.htrans = HTRANS_NONSEQ) then + -- if (ahbsi.htrans = HTRANS_IDLE or ahbsi.htrans = HTRANS_NONSEQ) then -- if (ahb_snd_empty = '0') then -- ahb_snd_rdreq <= '1'; -- v.cnt := r.cnt - 1; - --ahbso.hready <= '0'; + -- ahbso.hready <= '0'; -- end if; if (ahb_snd_empty = '0') then v.ahbsout.hready := '1'; v.ahbsout.hrdata := ahbdrivedata(ahb_snd_data_out); - ahb_snd_rdreq <= '1'; - v.cnt := r.cnt - 1; + ahb_snd_rdreq <= '1'; + v.cnt := r.cnt - 1; + end if; end if; - end if; - end case; + + end case; + rin <= v; - - if hsel_reg(hindex) = '1' then - ahbso.hrdata <= v.ahbsout.hrdata; -- hrdata; - ahbso.hready <= v.ahbsout.hready; --hready; + + if (hsel_reg(hindex) = '1') then + ahbso.hrdata <= v.ahbsout.hrdata; -- hrdata; + ahbso.hready <= v.ahbsout.hready; -- hready; end if; end process ahb_rdwr_reqsts_fsm; send_to_chip_fsm : process (io_snd_reg, io_snd_empty, io_snd_data_out, credits) is - --io_snd_fsm : process (io_snd_reg, io_snd_empty, io_snd_data_out, credits, sending) is - variable reg : io_snd_reg_type; + + -- io_snd_fsm : process (io_snd_reg, io_snd_empty, io_snd_data_out, credits, sending) is + variable reg : io_snd_reg_type; + begin - - reg := io_snd_reg; + + reg := io_snd_reg; io_snd_rdreq_out <= '0'; io_valid_out_int <= '0'; - io_data_out <= (others => '0'); + io_data_out <= (others => '0'); case io_snd_reg.state is when idle => + reg.cnt := 0; - --if credits /= 0 and io_snd_empty = '0' and sending.sync_clk_io = '1' then - if credits /= 0 and io_snd_empty = '0' then - reg.word := io_snd_data_out; + -- if credits /= 0 and io_snd_empty = '0' and sending.sync_clk_io = '1' then + if (credits /= 0 and io_snd_empty = '0') then + reg.word := io_snd_data_out; io_valid_out_int <= '1'; - io_data_out <= io_snd_data_out((reg.cnt + 1) * io_bitwidth - 1 downto reg.cnt * io_bitwidth); - if IO_BEATS > 1 then + io_data_out <= io_snd_data_out((reg.cnt + 1) * io_bitwidth - 1 downto reg.cnt * io_bitwidth); + if (IO_BEATS > 1) then reg.state := send; reg.cnt := reg.cnt + 1; else @@ -679,13 +733,14 @@ begin end if; when send => - --if credits /= 0 and sending.sync_clk_io = '1' then - if credits /= 0 then + + -- if credits /= 0 and sending.sync_clk_io = '1' then + if (credits /= 0) then io_valid_out_int <= '1'; - io_data_out <= io_snd_data_out((reg.cnt + 1) * io_bitwidth - 1 downto reg.cnt * io_bitwidth); - reg.cnt := reg.cnt + 1; - if reg.cnt = IO_BEATS then - reg.state := idle; + io_data_out <= io_snd_data_out((reg.cnt + 1) * io_bitwidth - 1 downto reg.cnt * io_bitwidth); + reg.cnt := reg.cnt + 1; + if (reg.cnt = IO_BEATS) then + reg.state := idle; io_snd_rdreq_out <= '1'; end if; end if; @@ -697,86 +752,96 @@ begin end process send_to_chip_fsm; rcv_from_chip_fsm : process (io_rcv_reg, io_rcv_full_in, io_valid_in, io_data_in) is + variable reg : io_rcv_reg_type; + begin - reg := io_rcv_reg; + + reg := io_rcv_reg; io_rcv_wrreq_in <= '0'; - if io_valid_in = '1' and io_rcv_full_in = '0' then + if (io_valid_in = '1' and io_rcv_full_in = '0') then reg.word((reg.cnt + 1) * io_bitwidth - 1 downto reg.cnt * io_bitwidth) := io_data_in; reg.cnt := reg.cnt + 1; - if reg.cnt = IO_BEATS then - reg.cnt := 0; - io_rcv_wrreq_in <= '1'; - io_rcv_data_in <= reg.word; + if (reg.cnt = IO_BEATS) then + reg.cnt := 0; + io_rcv_wrreq_in <= '1'; + io_rcv_data_in <= reg.word; end if; end if; io_rcv_reg_next <= reg; + end process rcv_from_chip_fsm; - rcv_from_chip_state_update : process (clk, rstn) + rcv_from_chip_state_update : process (clk, rstn) is begin - if(rstn = '0') then + + if (rstn = '0') then io_rcv_reg <= IO_RCV_REG_DEFAULT; - elsif clk'event and clk = '1' then + elsif (clk'event and clk = '1') then io_rcv_reg <= io_rcv_reg_next; end if; + end process rcv_from_chip_state_update; - --io_snd state update - snd_to_chip_state_update : process (clk, rstn) + -- io_snd state update + snd_to_chip_state_update : process (clk, rstn) is begin - if rstn = '0' then + + if (rstn = '0') then io_snd_reg <= IO_SND_REG_DEFAULT; oen_reg <= OEN_REG_DEFAULT; - elsif clk'event and clk = '1' then + elsif (clk'event and clk = '1') then io_snd_reg <= io_snd_reg_next; oen_reg <= oen_reg_next; end if; + end process snd_to_chip_state_update; - --ahb_rd_wr state register - rd_wr_state_update : process (clk, rstn) + -- ahb_rd_wr state register + rd_wr_state_update : process (clk, rstn) is begin - if(rstn = '0') then - r <= REG_DEF; - --hsel_reg <= (others => '0'); - elsif clk'event and clk = '1' then + + if (rstn = '0') then + r <= REG_DEF; + -- hsel_reg <= (others => '0'); + elsif (clk'event and clk = '1') then r <= rin; - --hsel_reg <= ahbsi.hsel; + -- hsel_reg <= ahbsi.hsel; end if; + end process rd_wr_state_update; - sample_ahb_bus : process (clk, rstn) + sample_ahb_bus : process (clk, rstn) is begin - if (rstn = '0') then - hsel_reg <= (others => '0'); - hwdata_reg <= (others => '0'); - hwrite_reg <= '0'; - hburst_reg <= (others => '0'); - htrans_reg <= (others => '0'); - elsif clk'event and clk = '1' then + if (rstn = '0') then + hsel_reg <= (others => '0'); + hwdata_reg <= (others => '0'); + hwrite_reg <= '0'; + hburst_reg <= (others => '0'); + htrans_reg <= (others => '0'); + elsif (clk'event and clk = '1') then if (sample_bus = '1') then - hsel_reg <= ahbsi.hsel; + hsel_reg <= ahbsi.hsel; hwdata_reg <= ahbreadword(ahbsi.hwdata); hwrite_reg <= ahbsi.hwrite; hburst_reg <= ahbsi.hburst; htrans_reg <= ahbsi.htrans; end if; end if; - + end process sample_ahb_bus; - --ahbso.hready <= r.ahbsout.hready; - --ahbso.hrdata <= r.ahbsout.hrdata; - --ahbso.hresp <= "00"; -- r.ahbsout.hresp; - --ahbso.hirq <= (others => '0'); + -- ahbso.hready <= r.ahbsout.hready; + -- ahbso.hrdata <= r.ahbsout.hrdata; + -- ahbso.hresp <= "00"; -- r.ahbsout.hresp; + -- ahbso.hirq <= (others => '0'); io_valid_out <= io_valid_out_int; - + io_clk_out_int <= clk; - io_clk_out <= io_clk_out_int; - --io_data_oen <= '0'; + io_clk_out <= io_clk_out_int; +-- io_data_oen <= '0'; end architecture rtl; diff --git a/rtl/sockets/queues/acc_tile_q.vhd b/rtl/sockets/queues/acc_tile_q.vhd index f6cbdb3ded..3bd3956624 100644 --- a/rtl/sockets/queues/acc_tile_q.vhd +++ b/rtl/sockets/queues/acc_tile_q.vhd @@ -2,189 +2,196 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; - -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; - -use work.gencomp.all; -use work.genacc.all; - -use work.nocpackage.all; -use work.tile.all; + use ieee.std_logic_1164.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.genacc.all; + use work.nocpackage.all; + use work.tile.all; entity acc_tile_q is generic ( - tech : integer := virtex7); + tech : integer := virtex7 + ); port ( - rst : in std_ulogic; - clk : in std_ulogic; + rst : in std_ulogic; + clk : in std_ulogic; -- tile->NoC1 - coherence_req_wrreq : in std_ulogic; - coherence_req_data_in : in coh_noc_flit_type; - coherence_req_full : out std_ulogic; + coherence_req_wrreq : in std_ulogic; + coherence_req_data_in : in coh_noc_flit_type; + coherence_req_full : out std_ulogic; -- NoC2->tile - coherence_fwd_rdreq : in std_ulogic; - coherence_fwd_data_out : out coh_noc_flit_type; - coherence_fwd_empty : out std_ulogic; + coherence_fwd_rdreq : in std_ulogic; + coherence_fwd_data_out : out coh_noc_flit_type; + coherence_fwd_empty : out std_ulogic; -- Noc3->tile - coherence_rsp_rcv_rdreq : in std_ulogic; - coherence_rsp_rcv_data_out : out coh_noc_flit_type; - coherence_rsp_rcv_empty : out std_ulogic; + coherence_rsp_rcv_rdreq : in std_ulogic; + coherence_rsp_rcv_data_out : out coh_noc_flit_type; + coherence_rsp_rcv_empty : out std_ulogic; -- tile->Noc3 - coherence_rsp_snd_wrreq : in std_ulogic; - coherence_rsp_snd_data_in : in coh_noc_flit_type; - coherence_rsp_snd_full : out std_ulogic; + coherence_rsp_snd_wrreq : in std_ulogic; + coherence_rsp_snd_data_in : in coh_noc_flit_type; + coherence_rsp_snd_full : out std_ulogic; -- tile->Noc2 - coherence_fwd_snd_wrreq : in std_ulogic; - coherence_fwd_snd_data_in : in coh_noc_flit_type; - coherence_fwd_snd_full : out std_ulogic; + coherence_fwd_snd_wrreq : in std_ulogic; + coherence_fwd_snd_data_in : in coh_noc_flit_type; + coherence_fwd_snd_full : out std_ulogic; -- NoC4->tile - dma_rcv_rdreq : in std_ulogic; - dma_rcv_data_out : out dma_noc_flit_type; - dma_rcv_empty : out std_ulogic; + dma_rcv_rdreq : in std_ulogic; + dma_rcv_data_out : out dma_noc_flit_type; + dma_rcv_empty : out std_ulogic; -- tile->NoC4 - coherent_dma_snd_wrreq : in std_ulogic; - coherent_dma_snd_data_in : in dma_noc_flit_type; - coherent_dma_snd_full : out std_ulogic; + coherent_dma_snd_wrreq : in std_ulogic; + coherent_dma_snd_data_in : in dma_noc_flit_type; + coherent_dma_snd_full : out std_ulogic; -- tile->NoC6 - dma_snd_wrreq : in std_ulogic; - dma_snd_data_in : in dma_noc_flit_type; - dma_snd_full : out std_ulogic; + dma_snd_wrreq : in std_ulogic; + dma_snd_data_in : in dma_noc_flit_type; + dma_snd_full : out std_ulogic; -- NoC6->tile - coherent_dma_rcv_rdreq : in std_ulogic; - coherent_dma_rcv_data_out : out dma_noc_flit_type; - coherent_dma_rcv_empty : out std_ulogic; + coherent_dma_rcv_rdreq : in std_ulogic; + coherent_dma_rcv_data_out : out dma_noc_flit_type; + coherent_dma_rcv_empty : out std_ulogic; -- NoC5->tile - apb_rcv_rdreq : in std_ulogic; - apb_rcv_data_out : out misc_noc_flit_type; - apb_rcv_empty : out std_ulogic; + apb_rcv_rdreq : in std_ulogic; + apb_rcv_data_out : out misc_noc_flit_type; + apb_rcv_empty : out std_ulogic; -- tile->NoC5 - apb_snd_wrreq : in std_ulogic; - apb_snd_data_in : in misc_noc_flit_type; - apb_snd_full : out std_ulogic; + apb_snd_wrreq : in std_ulogic; + apb_snd_data_in : in misc_noc_flit_type; + apb_snd_full : out std_ulogic; -- tile->NoC5 - interrupt_wrreq : in std_ulogic; - interrupt_data_in : in misc_noc_flit_type; - interrupt_full : out std_ulogic; + interrupt_wrreq : in std_ulogic; + interrupt_data_in : in misc_noc_flit_type; + interrupt_full : out std_ulogic; -- NoC5->tile - interrupt_ack_rdreq : in std_ulogic; - interrupt_ack_data_out : out misc_noc_flit_type; - interrupt_ack_empty : out std_ulogic; + interrupt_ack_rdreq : in std_ulogic; + interrupt_ack_data_out : out misc_noc_flit_type; + interrupt_ack_empty : out std_ulogic; -- Cachable data plane 1 -> request messages - noc1_out_data : in coh_noc_flit_type; - noc1_out_void : in std_ulogic; - noc1_out_stop : out std_ulogic; - noc1_in_data : out coh_noc_flit_type; - noc1_in_void : out std_ulogic; - noc1_in_stop : in std_ulogic; + noc1_out_data : in coh_noc_flit_type; + noc1_out_void : in std_ulogic; + noc1_out_stop : out std_ulogic; + noc1_in_data : out coh_noc_flit_type; + noc1_in_void : out std_ulogic; + noc1_in_stop : in std_ulogic; -- Cachable data plane 2 -> forwarded messages - noc2_out_data : in coh_noc_flit_type; - noc2_out_void : in std_ulogic; - noc2_out_stop : out std_ulogic; - noc2_in_data : out coh_noc_flit_type; - noc2_in_void : out std_ulogic; - noc2_in_stop : in std_ulogic; + noc2_out_data : in coh_noc_flit_type; + noc2_out_void : in std_ulogic; + noc2_out_stop : out std_ulogic; + noc2_in_data : out coh_noc_flit_type; + noc2_in_void : out std_ulogic; + noc2_in_stop : in std_ulogic; -- Cachable data plane 3 -> response messages - noc3_out_data : in coh_noc_flit_type; - noc3_out_void : in std_ulogic; - noc3_out_stop : out std_ulogic; - noc3_in_data : out coh_noc_flit_type; - noc3_in_void : out std_ulogic; - noc3_in_stop : in std_ulogic; + noc3_out_data : in coh_noc_flit_type; + noc3_out_void : in std_ulogic; + noc3_out_stop : out std_ulogic; + noc3_in_data : out coh_noc_flit_type; + noc3_in_void : out std_ulogic; + noc3_in_stop : in std_ulogic; -- Non cachable data data plane 4 -> DMA transfers response - noc4_out_data : in dma_noc_flit_type; - noc4_out_void : in std_ulogic; - noc4_out_stop : out std_ulogic; - noc4_in_data : out dma_noc_flit_type; - noc4_in_void : out std_ulogic; - noc4_in_stop : in std_ulogic; + noc4_out_data : in dma_noc_flit_type; + noc4_out_void : in std_ulogic; + noc4_out_stop : out std_ulogic; + noc4_in_data : out dma_noc_flit_type; + noc4_in_void : out std_ulogic; + noc4_in_stop : in std_ulogic; -- Configuration plane 5 -> RD/WR registers - noc5_out_data : in misc_noc_flit_type; - noc5_out_void : in std_ulogic; - noc5_out_stop : out std_ulogic; - noc5_in_data : out misc_noc_flit_type; - noc5_in_void : out std_ulogic; - noc5_in_stop : in std_ulogic; + noc5_out_data : in misc_noc_flit_type; + noc5_out_void : in std_ulogic; + noc5_out_stop : out std_ulogic; + noc5_in_data : out misc_noc_flit_type; + noc5_in_void : out std_ulogic; + noc5_in_stop : in std_ulogic; -- Non cachable data data plane 6 -> DMA transfers requests - noc6_out_data : in dma_noc_flit_type; - noc6_out_void : in std_ulogic; - noc6_out_stop : out std_ulogic; - noc6_in_data : out dma_noc_flit_type; - noc6_in_void : out std_ulogic; - noc6_in_stop : in std_ulogic); - -end acc_tile_q; + noc6_out_data : in dma_noc_flit_type; + noc6_out_void : in std_ulogic; + noc6_out_stop : out std_ulogic; + noc6_in_data : out dma_noc_flit_type; + noc6_in_void : out std_ulogic; + noc6_in_stop : in std_ulogic + ); +end entity acc_tile_q; architecture rtl of acc_tile_q is signal fifo_rst : std_ulogic; -- tile->NoC1 - signal coherence_req_rdreq : std_ulogic; - signal coherence_req_data_out : coh_noc_flit_type; - signal coherence_req_empty : std_ulogic; + signal coherence_req_rdreq : std_ulogic; + signal coherence_req_data_out : coh_noc_flit_type; + signal coherence_req_empty : std_ulogic; -- NoC2->tile - signal coherence_fwd_wrreq : std_ulogic; - signal coherence_fwd_data_in : coh_noc_flit_type; - signal coherence_fwd_full : std_ulogic; + signal coherence_fwd_wrreq : std_ulogic; + signal coherence_fwd_data_in : coh_noc_flit_type; + signal coherence_fwd_full : std_ulogic; -- NoC3->tile - signal coherence_rsp_rcv_wrreq : std_ulogic; - signal coherence_rsp_rcv_data_in : coh_noc_flit_type; - signal coherence_rsp_rcv_full : std_ulogic; + signal coherence_rsp_rcv_wrreq : std_ulogic; + signal coherence_rsp_rcv_data_in : coh_noc_flit_type; + signal coherence_rsp_rcv_full : std_ulogic; -- tile->NoC3 - signal coherence_rsp_snd_rdreq : std_ulogic; - signal coherence_rsp_snd_data_out : coh_noc_flit_type; - signal coherence_rsp_snd_empty : std_ulogic; + signal coherence_rsp_snd_rdreq : std_ulogic; + signal coherence_rsp_snd_data_out : coh_noc_flit_type; + signal coherence_rsp_snd_empty : std_ulogic; -- tile->NoC2 signal coherence_fwd_snd_rdreq : std_ulogic; signal coherence_fwd_snd_data_out : coh_noc_flit_type; signal coherence_fwd_snd_empty : std_ulogic; -- NoC4->tile - signal dma_rcv_wrreq : std_ulogic; - signal dma_rcv_data_in : dma_noc_flit_type; - signal dma_rcv_full : std_ulogic; + signal dma_rcv_wrreq : std_ulogic; + signal dma_rcv_data_in : dma_noc_flit_type; + signal dma_rcv_full : std_ulogic; -- tile->NoC4 - signal coherent_dma_snd_rdreq : std_ulogic; - signal coherent_dma_snd_data_out : dma_noc_flit_type; - signal coherent_dma_snd_empty : std_ulogic; + signal coherent_dma_snd_rdreq : std_ulogic; + signal coherent_dma_snd_data_out : dma_noc_flit_type; + signal coherent_dma_snd_empty : std_ulogic; -- tile->NoC6 - signal dma_snd_rdreq : std_ulogic; - signal dma_snd_data_out : dma_noc_flit_type; - signal dma_snd_empty : std_ulogic; + signal dma_snd_rdreq : std_ulogic; + signal dma_snd_data_out : dma_noc_flit_type; + signal dma_snd_empty : std_ulogic; -- NoC6->tile - signal coherent_dma_rcv_wrreq : std_ulogic; - signal coherent_dma_rcv_data_in : dma_noc_flit_type; - signal coherent_dma_rcv_full : std_ulogic; + signal coherent_dma_rcv_wrreq : std_ulogic; + signal coherent_dma_rcv_data_in : dma_noc_flit_type; + signal coherent_dma_rcv_full : std_ulogic; -- NoC5->tile - signal apb_rcv_wrreq : std_ulogic; - signal apb_rcv_data_in : misc_noc_flit_type; - signal apb_rcv_full : std_ulogic; + signal apb_rcv_wrreq : std_ulogic; + signal apb_rcv_data_in : misc_noc_flit_type; + signal apb_rcv_full : std_ulogic; -- tile->NoC5 - signal apb_snd_rdreq : std_ulogic; - signal apb_snd_data_out : misc_noc_flit_type; - signal apb_snd_empty : std_ulogic; + signal apb_snd_rdreq : std_ulogic; + signal apb_snd_data_out : misc_noc_flit_type; + signal apb_snd_empty : std_ulogic; -- tile->Noc5 - signal interrupt_rdreq : std_ulogic; - signal interrupt_data_out : misc_noc_flit_type; - signal interrupt_empty : std_ulogic; + signal interrupt_rdreq : std_ulogic; + signal interrupt_data_out : misc_noc_flit_type; + signal interrupt_empty : std_ulogic; -- NoC5->tile - signal interrupt_ack_wrreq : std_ulogic; - signal interrupt_ack_data_in : misc_noc_flit_type; - signal interrupt_ack_full : std_ulogic; + signal interrupt_ack_wrreq : std_ulogic; + signal interrupt_ack_data_in : misc_noc_flit_type; + signal interrupt_ack_full : std_ulogic; type noc2_packet_fsm is (none, packet_inv); - signal noc2_fifos_current, noc2_fifos_next : noc2_packet_fsm; + + signal noc2_fifos_current, noc2_fifos_next : noc2_packet_fsm; + type noc3_packet_fsm is (none, packet_line); - signal noc3_fifos_current, noc3_fifos_next : noc3_packet_fsm; + + signal noc3_fifos_current, noc3_fifos_next : noc3_packet_fsm; + type to_noc3_packet_fsm is (none, packet_coherence_rsp_snd); + signal to_noc3_fifos_current, to_noc3_fifos_next : to_noc3_packet_fsm; + type noc5_packet_fsm is (none, packet_apb_rcv); - signal noc5_fifos_current, noc5_fifos_next : noc5_packet_fsm; + + signal noc5_fifos_current, noc5_fifos_next : noc5_packet_fsm; + type to_noc5_packet_fsm is (none, packet_apb_snd); + signal to_noc5_fifos_current, to_noc5_fifos_next : to_noc5_packet_fsm; signal noc3_msg_type : noc_msg_type; @@ -192,39 +199,41 @@ architecture rtl of acc_tile_q is signal noc5_msg_type : noc_msg_type; signal noc5_preamble : noc_preamble_type; - signal noc1_dummy_out_data : coh_noc_flit_type; - signal noc1_dummy_out_void : std_ulogic; - - -- attribute mark_debug : string; - - -- attribute mark_debug of interrupt_ack_wrreq : signal is "true"; - -- attribute mark_debug of interrupt_ack_data_in : signal is "true"; - -- attribute mark_debug of interrupt_ack_full : signal is "true"; - -- attribute mark_debug of interrupt_rdreq : signal is "true"; - -- attribute mark_debug of interrupt_data_out : signal is "true"; - -- attribute mark_debug of interrupt_empty : signal is "true"; - -- attribute mark_debug of noc5_msg_type : signal is "true"; - -- attribute mark_debug of noc5_preamble : signal is "true"; - -- attribute mark_debug of noc5_fifos_current : signal is "true"; - -- attribute mark_debug of noc5_fifos_next : signal is "true"; - -- attribute mark_debug of to_noc5_fifos_current : signal is "true"; - -- attribute mark_debug of to_noc5_fifos_next : signal is "true"; - + signal noc1_dummy_out_data : coh_noc_flit_type; + signal noc1_dummy_out_void : std_ulogic; + +-- attribute mark_debug : string; + +-- attribute mark_debug of interrupt_ack_wrreq : signal is "true"; +-- attribute mark_debug of interrupt_ack_data_in : signal is "true"; +-- attribute mark_debug of interrupt_ack_full : signal is "true"; +-- attribute mark_debug of interrupt_rdreq : signal is "true"; +-- attribute mark_debug of interrupt_data_out : signal is "true"; +-- attribute mark_debug of interrupt_empty : signal is "true"; +-- attribute mark_debug of noc5_msg_type : signal is "true"; +-- attribute mark_debug of noc5_preamble : signal is "true"; +-- attribute mark_debug of noc5_fifos_current : signal is "true"; +-- attribute mark_debug of noc5_fifos_next : signal is "true"; +-- attribute mark_debug of to_noc5_fifos_current : signal is "true"; +-- attribute mark_debug of to_noc5_fifos_next : signal is "true"; + begin -- rtl - fifo_rst <= rst; --FIFO rst active low + fifo_rst <= rst; -- FIFO rst active low -- To noc1: coherence requests from CPU to directory (GET/PUT) - noc1_out_stop <= '0'; + noc1_out_stop <= '0'; noc1_dummy_out_data <= noc1_out_data; noc1_dummy_out_void <= noc1_out_void; - noc1_in_data <= coherence_req_data_out; - noc1_in_void <= coherence_req_empty or noc1_in_stop; - coherence_req_rdreq <= (not coherence_req_empty) and (not noc1_in_stop); - fifo_1: fifo0 + noc1_in_data <= coherence_req_data_out; + noc1_in_void <= coherence_req_empty or noc1_in_stop; + coherence_req_rdreq <= (not coherence_req_empty) and (not noc1_in_stop); + + fifo_1 : component fifo0 generic map ( - depth => 6, --Header, address, [cache line] - width => COH_NOC_FLIT_SIZE) + depth => 6, + width => COH_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -233,18 +242,19 @@ begin -- rtl data_in => coherence_req_data_in, empty => coherence_req_empty, full => coherence_req_full, - data_out => coherence_req_data_out); - + data_out => coherence_req_data_out + ); -- From noc2: coherence forwarded messages to CPU (INV, GETS/M) - noc2_out_stop <= coherence_fwd_full and (not noc2_out_void); + noc2_out_stop <= coherence_fwd_full and (not noc2_out_void); coherence_fwd_data_in <= noc2_out_data; - coherence_fwd_wrreq <= (not noc2_out_void) and (not coherence_fwd_full); + coherence_fwd_wrreq <= (not noc2_out_void) and (not coherence_fwd_full); - fifo_2: fifo0 + fifo_2 : component fifo0 generic map ( - depth => 4, --Header, address (x2) - width => COH_NOC_FLIT_SIZE) + depth => 4, + width => COH_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -253,19 +263,20 @@ begin -- rtl data_in => coherence_fwd_data_in, empty => coherence_fwd_empty, full => coherence_fwd_full, - data_out => coherence_fwd_data_out); - + data_out => coherence_fwd_data_out + ); -- From noc3: coherence response messages to CPU (DATA, INVACK, PUTACK) - noc3_out_stop <= coherence_rsp_rcv_full and (not noc3_out_void); + noc3_out_stop <= coherence_rsp_rcv_full and (not noc3_out_void); coherence_rsp_rcv_data_in <= noc3_out_data; - coherence_rsp_rcv_wrreq <= (not noc3_out_void) and (not coherence_rsp_rcv_full); + coherence_rsp_rcv_wrreq <= (not noc3_out_void) and (not coherence_rsp_rcv_full); - fifo_3: fifo0 + fifo_3 : component fifo0 generic map ( - depth => 5, --Header (use RESERVED field to - --determine ACK number), cache line - width => COH_NOC_FLIT_SIZE) + depth => 5, + -- determine ACK number), cache line + width => COH_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -274,17 +285,19 @@ begin -- rtl data_in => coherence_rsp_rcv_data_in, empty => coherence_rsp_rcv_empty, full => coherence_rsp_rcv_full, - data_out => coherence_rsp_rcv_data_out); - + data_out => coherence_rsp_rcv_data_out + ); -- To noc3: coherence response messages from CPU (DATA, EDATA, INVACK) - noc3_in_data <= coherence_rsp_snd_data_out; - noc3_in_void <= coherence_rsp_snd_empty or noc3_in_stop; - coherence_rsp_snd_rdreq <= (not coherence_rsp_snd_empty) and (not noc3_in_stop); - fifo_4: fifo0 + noc3_in_data <= coherence_rsp_snd_data_out; + noc3_in_void <= coherence_rsp_snd_empty or noc3_in_stop; + coherence_rsp_snd_rdreq <= (not coherence_rsp_snd_empty) and (not noc3_in_stop); + + fifo_4 : component fifo0 generic map ( - depth => 5, --Header - width => COH_NOC_FLIT_SIZE) + depth => 5, + width => COH_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -293,16 +306,19 @@ begin -- rtl data_in => coherence_rsp_snd_data_in, empty => coherence_rsp_snd_empty, full => coherence_rsp_snd_full, - data_out => coherence_rsp_snd_data_out); + data_out => coherence_rsp_snd_data_out + ); -- To noc2: dcs l2_fwd_out - noc2_in_data <= coherence_fwd_snd_data_out; - noc2_in_void <= coherence_fwd_snd_empty or noc2_in_stop; - coherence_fwd_snd_rdreq <= (not coherence_fwd_snd_empty) and (not noc2_in_stop); - fifo_5: fifo0 + noc2_in_data <= coherence_fwd_snd_data_out; + noc2_in_void <= coherence_fwd_snd_empty or noc2_in_stop; + coherence_fwd_snd_rdreq <= (not coherence_fwd_snd_empty) and (not noc2_in_stop); + + fifo_5 : component fifo0 generic map ( - depth => 5, --Header - width => COH_NOC_FLIT_SIZE) + depth => 5, + width => COH_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -311,18 +327,19 @@ begin -- rtl data_in => coherence_fwd_snd_data_in, empty => coherence_fwd_snd_empty, full => coherence_fwd_snd_full, - data_out => coherence_fwd_snd_data_out); - - + data_out => coherence_fwd_snd_data_out + ); -- From noc4: DMA response to accelerators noc4_out_stop <= dma_rcv_full and (not noc4_out_void); dma_rcv_data_in <= noc4_out_data; dma_rcv_wrreq <= (not noc4_out_void) and (not dma_rcv_full); - fifo_14: fifo0 + + fifo_14 : component fifo0 generic map ( - depth => 18, --Header, [data] - width => DMA_NOC_FLIT_SIZE) + depth => 18, + width => DMA_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -331,16 +348,19 @@ begin -- rtl data_in => dma_rcv_data_in, empty => dma_rcv_empty, full => dma_rcv_full, - data_out => dma_rcv_data_out); + data_out => dma_rcv_data_out + ); -- From noc6: Coherent DMA response to accelerators - noc6_out_stop <= coherent_dma_rcv_full and (not noc6_out_void); + noc6_out_stop <= coherent_dma_rcv_full and (not noc6_out_void); coherent_dma_rcv_data_in <= noc6_out_data; coherent_dma_rcv_wrreq <= (not noc6_out_void) and (not coherent_dma_rcv_full); - fifo_14c: fifo0 + + fifo_14c : component fifo0 generic map ( - depth => 18, --Header, [data] - width => DMA_NOC_FLIT_SIZE) + depth => 18, + width => DMA_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -349,16 +369,19 @@ begin -- rtl data_in => coherent_dma_rcv_data_in, empty => coherent_dma_rcv_empty, full => coherent_dma_rcv_full, - data_out => coherent_dma_rcv_data_out); + data_out => coherent_dma_rcv_data_out + ); -- To noc6: DMA requests from accelerators - noc6_in_data <= dma_snd_data_out; - noc6_in_void <= dma_snd_empty or noc6_in_stop; + noc6_in_data <= dma_snd_data_out; + noc6_in_void <= dma_snd_empty or noc6_in_stop; dma_snd_rdreq <= (not dma_snd_empty) and (not noc6_in_stop); - fifo_13: fifo0 + + fifo_13 : component fifo0 generic map ( - depth => 18, --Header, address, length or data - width => DMA_NOC_FLIT_SIZE) + depth => 18, + width => DMA_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -367,16 +390,19 @@ begin -- rtl data_in => dma_snd_data_in, empty => dma_snd_empty, full => dma_snd_full, - data_out => dma_snd_data_out); + data_out => dma_snd_data_out + ); -- To noc4: Coherent DMA requests from accelerators - noc4_in_data <= coherent_dma_snd_data_out; - noc4_in_void <= coherent_dma_snd_empty or noc4_in_stop; + noc4_in_data <= coherent_dma_snd_data_out; + noc4_in_void <= coherent_dma_snd_empty or noc4_in_stop; coherent_dma_snd_rdreq <= (not coherent_dma_snd_empty) and (not noc4_in_stop); - fifo_13c: fifo0 + + fifo_13c : component fifo0 generic map ( - depth => 18, --Header, address, length or data - width => DMA_NOC_FLIT_SIZE) + depth => 18, + width => DMA_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -385,24 +411,30 @@ begin -- rtl data_in => coherent_dma_snd_data_in, empty => coherent_dma_snd_empty, full => coherent_dma_snd_full, - data_out => coherent_dma_snd_data_out); + data_out => coherent_dma_snd_data_out + ); -- From noc5: APB requests from cores noc5_msg_type <= get_msg_type(MISC_NOC_FLIT_SIZE, misc_noc_flit_pad & noc5_out_data); noc5_preamble <= get_preamble(MISC_NOC_FLIT_SIZE, misc_noc_flit_pad & noc5_out_data); - process (clk, rst) - begin -- process - if rst = '0' then -- asynchronous reset (active low) + + process (clk, rst) is + begin -- process + + if (rst = '0') then -- asynchronous reset (active low) noc5_fifos_current <= none; - elsif clk'event and clk = '1' then -- rising clock edge + elsif (clk'event and clk = '1') then -- rising clock edge noc5_fifos_current <= noc5_fifos_next; end if; + end process; + noc5_fifos_get_packet : process (noc5_out_data, noc5_out_void, noc5_msg_type, noc5_preamble, noc5_fifos_current, apb_rcv_full, - interrupt_ack_full) + interrupt_ack_full) is begin -- process noc5_get_packet + apb_rcv_wrreq <= '0'; interrupt_ack_wrreq <= '0'; @@ -410,11 +442,13 @@ begin -- rtl noc5_out_stop <= '0'; case noc5_fifos_current is + when none => - if noc5_out_void = '0' then + + if (noc5_out_void = '0') then if ((noc5_msg_type = REQ_REG_RD or noc5_msg_type = REQ_REG_WR) and noc5_preamble = PREAMBLE_HEADER) then - if apb_rcv_full = '0' then + if (apb_rcv_full = '0') then apb_rcv_wrreq <= '1'; noc5_fifos_next <= packet_apb_rcv; else @@ -422,29 +456,35 @@ begin -- rtl end if; elsif (noc5_msg_type = INTERRUPT and noc5_preamble = PREAMBLE_1FLIT) then interrupt_ack_wrreq <= not interrupt_ack_full; - noc5_out_stop <= interrupt_ack_full; + noc5_out_stop <= interrupt_ack_full; end if; end if; when packet_apb_rcv => + apb_rcv_wrreq <= not noc5_out_void and (not apb_rcv_full); noc5_out_stop <= apb_rcv_full and (not noc5_out_void); + if (noc5_preamble = PREAMBLE_TAIL and noc5_out_void = '0' and apb_rcv_full = '0') then noc5_fifos_next <= none; end if; when others => + noc5_fifos_next <= none; end case; + end process noc5_fifos_get_packet; apb_rcv_data_in <= noc5_out_data; - fifo_10 : fifo0 + + fifo_10 : component fifo0 generic map ( - depth => 3, --Header, address, data - width => MISC_NOC_FLIT_SIZE) + depth => 3, + width => MISC_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -453,13 +493,16 @@ begin -- rtl data_in => apb_rcv_data_in, empty => apb_rcv_empty, full => apb_rcv_full, - data_out => apb_rcv_data_out); - + data_out => apb_rcv_data_out + ); + interrupt_ack_data_in <= noc5_out_data; - fifo_16 : fifo0 + + fifo_16 : component fifo0 generic map ( - depth => 2, --Header x # accelerators - width => MISC_NOC_FLIT_SIZE) + depth => 2, + width => MISC_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -468,64 +511,82 @@ begin -- rtl data_in => interrupt_ack_data_in, empty => interrupt_ack_empty, full => interrupt_ack_full, - data_out => interrupt_ack_data_out); + data_out => interrupt_ack_data_out + ); -- To noc5: APB response from accelerators -- To noc5: interrupts from accelerators - process (clk, rst) - begin -- process - if rst = '0' then -- asynchronous reset (active low) + process (clk, rst) is + begin -- process + + if (rst = '0') then -- asynchronous reset (active low) to_noc5_fifos_current <= none; - elsif clk'event and clk = '1' then -- rising clock edge + elsif (clk'event and clk = '1') then -- rising clock edge to_noc5_fifos_current <= to_noc5_fifos_next; end if; + end process; - noc5_fifos_put_packet: process (noc5_in_stop, to_noc5_fifos_current, - apb_snd_data_out, apb_snd_empty, - interrupt_data_out, interrupt_empty) + + noc5_fifos_put_packet : process (noc5_in_stop, to_noc5_fifos_current, + apb_snd_data_out, apb_snd_empty, + interrupt_data_out, interrupt_empty) is + variable to_noc5_preamble : noc_preamble_type; + begin -- process noc5_get_packet - noc5_in_data <= (others => '0'); - noc5_in_void <= '1'; - apb_snd_rdreq <= '0'; - interrupt_rdreq <= '0'; + + noc5_in_data <= (others => '0'); + noc5_in_void <= '1'; + apb_snd_rdreq <= '0'; + interrupt_rdreq <= '0'; to_noc5_fifos_next <= to_noc5_fifos_current; - to_noc5_preamble := "00"; + to_noc5_preamble := "00"; case to_noc5_fifos_current is - when none => if apb_snd_empty = '0' then - if noc5_in_stop = '0' then - noc5_in_data <= apb_snd_data_out; - noc5_in_void <= apb_snd_empty; - apb_snd_rdreq <= '1'; - to_noc5_fifos_next <= packet_apb_snd; - end if; - elsif interrupt_empty = '0' then - if noc5_in_stop = '0' then - noc5_in_data <= interrupt_data_out; - noc5_in_void <= interrupt_empty; - interrupt_rdreq <= '1'; - end if; - end if; - - when packet_apb_snd => to_noc5_preamble := get_preamble(MISC_NOC_FLIT_SIZE, misc_noc_flit_pad & apb_snd_data_out); - if (noc5_in_stop = '0' and apb_snd_empty = '0') then - noc5_in_data <= apb_snd_data_out; - noc5_in_void <= apb_snd_empty; - apb_snd_rdreq <= not noc5_in_stop; - if to_noc5_preamble = PREAMBLE_TAIL then - to_noc5_fifos_next <= none; - end if; - end if; - - when others => to_noc5_fifos_next <= none; + + when none => + + if (apb_snd_empty = '0') then + if (noc5_in_stop = '0') then + noc5_in_data <= apb_snd_data_out; + noc5_in_void <= apb_snd_empty; + apb_snd_rdreq <= '1'; + to_noc5_fifos_next <= packet_apb_snd; + end if; + elsif (interrupt_empty = '0') then + if (noc5_in_stop = '0') then + noc5_in_data <= interrupt_data_out; + noc5_in_void <= interrupt_empty; + interrupt_rdreq <= '1'; + end if; + end if; + + when packet_apb_snd => + + to_noc5_preamble := get_preamble(MISC_NOC_FLIT_SIZE, misc_noc_flit_pad & apb_snd_data_out); + + if (noc5_in_stop = '0' and apb_snd_empty = '0') then + noc5_in_data <= apb_snd_data_out; + noc5_in_void <= apb_snd_empty; + apb_snd_rdreq <= not noc5_in_stop; + if (to_noc5_preamble = PREAMBLE_TAIL) then + to_noc5_fifos_next <= none; + end if; + end if; + + when others => + + to_noc5_fifos_next <= none; + end case; + end process noc5_fifos_put_packet; - fifo_7: fifo0 + fifo_7 : component fifo0 generic map ( - depth => 2, --Header, data (1 Word) - width => MISC_NOC_FLIT_SIZE) + depth => 2, + width => MISC_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -534,12 +595,14 @@ begin -- rtl data_in => apb_snd_data_in, empty => apb_snd_empty, full => apb_snd_full, - data_out => apb_snd_data_out); + data_out => apb_snd_data_out + ); - fifo_15: fifo0 + fifo_15 : component fifo0 generic map ( - depth => 2, --Header only x possible sharers - width => MISC_NOC_FLIT_SIZE) + depth => 2, + width => MISC_NOC_FLIT_SIZE + ) port map ( clk => clk, rst => fifo_rst, @@ -548,6 +611,7 @@ begin -- rtl data_in => interrupt_data_in, empty => interrupt_empty, full => interrupt_full, - data_out => interrupt_data_out); + data_out => interrupt_data_out + ); -end rtl; +end architecture rtl; diff --git a/rtl/techmap/asic/clkgen_gf12.vhd b/rtl/techmap/asic/clkgen_gf12.vhd index 76a03ce3e0..7b07011f38 100644 --- a/rtl/techmap/asic/clkgen_gf12.vhd +++ b/rtl/techmap/asic/clkgen_gf12.vhd @@ -2,96 +2,102 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; - + use ieee.std_logic_1164.all; entity gf12_dco is - generic ( - enable_div2 : integer range 0 to 1 := 0); + enable_div2 : integer range 0 to 1 := 0 + ); port ( - RSTN : in std_ulogic; - EXT_CLK : in std_logic; - EN : in std_ulogic; - CLK_SEL : in std_ulogic; - CC_SEL : in std_logic_vector(5 downto 0); - FC_SEL : in std_logic_vector(5 downto 0); - DIV_SEL : in std_logic_vector(2 downto 0); - FREQ_SEL : in std_logic_vector(1 downto 0); - CLK : out std_logic; - CLK_DIV2 : out std_logic; - CLK_DIV2_90 : out std_logic; - CLK_DIV : out std_logic); - + rstn : in std_ulogic; + ext_clk : in std_logic; + en : in std_ulogic; + clk_sel : in std_ulogic; + cc_sel : in std_logic_vector(5 downto 0); + fc_sel : in std_logic_vector(5 downto 0); + div_sel : in std_logic_vector(2 downto 0); + freq_sel : in std_logic_vector(1 downto 0); + clk : out std_logic; + clk_div2 : out std_logic; + clk_div2_90 : out std_logic; + clk_div : out std_logic + ); end entity gf12_dco; architecture rtl of gf12_dco is - component DCO_GF12_C14 is + component dco_gf12_c14 is port ( - RSTN : in std_ulogic; - EXT_CLK : in std_logic; - EN : in std_ulogic; - CLK_SEL : in std_ulogic; - CC_SEL : in std_logic_vector(5 downto 0); - FC_SEL : in std_logic_vector(5 downto 0); - DIV_SEL : in std_logic_vector(2 downto 0); - FREQ_SEL : in std_logic_vector(1 downto 0); - CLK : out std_logic; - CLK_DIV : out std_logic); - end component DCO_GF12_C14; + rstn : in std_ulogic; + ext_clk : in std_logic; + en : in std_ulogic; + clk_sel : in std_ulogic; + cc_sel : in std_logic_vector(5 downto 0); + fc_sel : in std_logic_vector(5 downto 0); + div_sel : in std_logic_vector(2 downto 0); + freq_sel : in std_logic_vector(1 downto 0); + clk : out std_logic; + clk_div : out std_logic + ); + end component dco_gf12_c14; - component DCO_LPDDR_GF12_C14 is + component dco_lpddr_gf12_c14 is port ( - RSTN : in std_ulogic; - EXT_CLK : in std_logic; - EN : in std_ulogic; - CLK_SEL : in std_ulogic; - CC_SEL : in std_logic_vector(5 downto 0); - FC_SEL : in std_logic_vector(5 downto 0); - DIV_SEL : in std_logic_vector(2 downto 0); - FREQ_SEL : in std_logic_vector(1 downto 0); - CLK : out std_logic; - CLK_DIV2 : out std_logic; - CLK_DIV2_90 : out std_logic; - CLK_DIV : out std_logic); - end component DCO_LPDDR_GF12_C14; + rstn : in std_ulogic; + ext_clk : in std_logic; + en : in std_ulogic; + clk_sel : in std_ulogic; + cc_sel : in std_logic_vector(5 downto 0); + fc_sel : in std_logic_vector(5 downto 0); + div_sel : in std_logic_vector(2 downto 0); + freq_sel : in std_logic_vector(1 downto 0); + clk : out std_logic; + clk_div2 : out std_logic; + clk_div2_90 : out std_logic; + clk_div : out std_logic + ); + end component dco_lpddr_gf12_c14; begin -- architecture rtl - no_div2: if enable_div2 = 0 generate - DCO_GF12_C14_1 : DCO_GF12_C14 + no_div2 : if enable_div2 = 0 generate + + dco_gf12_c14_1 : component dco_gf12_c14 port map ( - RSTN => RSTN, - EXT_CLK => EXT_CLK, - EN => EN, - CLK_SEL => CLK_SEL, - CC_SEL => CC_SEL, - FC_SEL => FC_SEL, - DIV_SEL => DIV_SEL, - FREQ_SEL => FREQ_SEL, - CLK => CLK, - CLK_DIV => CLK_DIV); + rstn => rstn, + ext_clk => ext_clk, + en => en, + clk_sel => clk_sel, + cc_sel => cc_sel, + fc_sel => fc_sel, + div_sel => div_sel, + freq_sel => freq_sel, + clk => clk, + clk_div => clk_div + ); - CLK_DIV2 <= '0'; - CLK_DIV2_90 <= '0'; + clk_div2 <= '0'; + clk_div2_90 <= '0'; end generate no_div2; - with_div2: if enable_div2 /= 0 generate - DCO_LPDDR_GF12_C14_1 : DCO_LPDDR_GF12_C14 + with_div2 : if enable_div2 /= 0 generate + + dco_lpddr_gf12_c14_1 : component dco_lpddr_gf12_c14 port map ( - RSTN => RSTN, - EXT_CLK => EXT_CLK, - EN => EN, - CLK_SEL => CLK_SEL, - CC_SEL => CC_SEL, - FC_SEL => FC_SEL, - DIV_SEL => DIV_SEL, - FREQ_SEL => FREQ_SEL, - CLK => CLK, - CLK_DIV2 => CLK_DIV2, - CLK_DIV2_90 => CLK_DIV2_90, - CLK_DIV => CLK_DIV); + rstn => rstn, + ext_clk => ext_clk, + en => en, + clk_sel => clk_sel, + cc_sel => cc_sel, + fc_sel => fc_sel, + div_sel => div_sel, + freq_sel => freq_sel, + clk => clk, + clk_div2 => clk_div2, + clk_div2_90 => clk_div2_90, + clk_div => clk_div + ); + end generate with_div2; end architecture rtl; diff --git a/rtl/techmap/inferred/SyncSpRamBeNx64.sv b/rtl/techmap/inferred/SyncSpRamBeNx64.sv index b316172d87..da6a6e365c 100644 --- a/rtl/techmap/inferred/SyncSpRamBeNx64.sv +++ b/rtl/techmap/inferred/SyncSpRamBeNx64.sv @@ -26,95 +26,94 @@ */ -module SyncSpRamBeNx64 - #( - parameter ADDR_WIDTH = 10, - parameter DATA_DEPTH = 1024, // usually 2**ADDR_WIDTH, but can be lower - parameter OUT_REGS = 0, // set to 1 to enable outregs - parameter SIM_INIT = 0 // for simulation only, will not be synthesized - // 0: no init, 1: zero init, 2: random init, 3: deadbeef init - // note: on verilator, 2 is not supported. define the VERILATOR macro to work around. - )( - input logic Clk_CI, - input logic Rst_RBI, - input logic CSel_SI, - input logic WrEn_SI, - input logic [7:0] BEn_SI, - input logic [63:0] WrData_DI, - input logic [ADDR_WIDTH-1:0] Addr_DI, - output logic [63:0] RdData_DO - ); - - //////////////////////////// +module SyncSpRamBeNx64 #( + parameter ADDR_WIDTH = 10, + parameter DATA_DEPTH = 1024, // usually 2**ADDR_WIDTH, but can be lower + parameter OUT_REGS = 0, // set to 1 to enable outregs + parameter SIM_INIT = 0 // for simulation only, will not be synthesized + // 0: no init, 1: zero init, 2: random init, 3: deadbeef init + // note: on verilator, 2 is not supported. define the VERILATOR macro to work around. +) ( + input logic Clk_CI, + input logic Rst_RBI, + input logic CSel_SI, + input logic WrEn_SI, + input logic [7:0] BEn_SI, + input logic [63:0] WrData_DI, + input logic [ADDR_WIDTH-1:0] Addr_DI, + output logic [63:0] RdData_DO +); + + //////////////////////////// // signals, localparams - //////////////////////////// - - // needs to be consistent with the Altera implemenation below - localparam DATA_BYTES = 8; - - logic [DATA_BYTES*8-1:0] RdData_DN; - logic [DATA_BYTES*8-1:0] RdData_DP; - - logic [DATA_BYTES*8-1:0] Mem_DP[DATA_DEPTH-1:0]; - - logic [DATA_BYTES*8-1:0] bitmask; - - assign bitmask[7:0] = {8{BEn_SI[0]}}; - assign bitmask[15:8] = {8{BEn_SI[1]}}; - assign bitmask[23:16] = {8{BEn_SI[2]}}; - assign bitmask[31:24] = {8{BEn_SI[3]}}; - assign bitmask[39:32] = {8{BEn_SI[4]}}; - assign bitmask[47:40] = {8{BEn_SI[5]}}; - assign bitmask[55:48] = {8{BEn_SI[6]}}; - assign bitmask[63:56] = {8{BEn_SI[7]}}; - - sram_behav #(.DATA_WIDTH(64), .NUM_WORDS(256)) i_sram( - .clk_i(Clk_CI), - .req_i(CSel_SI), - .we_i(WrEn_SI), - .addr_i(Addr_DI), - .wdata_i(WrData_DI), - .be_i(bitmask), - .rdata_o(RdData_DN) - ); - - //////////////////////////// - // optional output regs - //////////////////////////// - - // output regs - generate - if (OUT_REGS>0) begin : g_outreg - always_ff @(posedge Clk_CI or negedge Rst_RBI) begin - if(Rst_RBI == 1'b0) - begin - RdData_DP <= 0; - end - else - begin - RdData_DP <= RdData_DN; - end - end - end - endgenerate // g_outreg - - // output reg bypass - generate - if (OUT_REGS==0) begin : g_oureg_byp - assign RdData_DP = RdData_DN; - end - endgenerate// g_oureg_byp - - assign RdData_DO = RdData_DP; - - //////////////////////////// - // assertions - //////////////////////////// - - // pragma translate_off - assert property + //////////////////////////// + + // needs to be consistent with the Altera implemenation below + localparam DATA_BYTES = 8; + + logic [DATA_BYTES*8-1:0] RdData_DN; + logic [DATA_BYTES*8-1:0] RdData_DP; + + logic [DATA_BYTES*8-1:0] Mem_DP [DATA_DEPTH-1:0]; + + logic [DATA_BYTES*8-1:0] bitmask; + + assign bitmask[7:0] = {8{BEn_SI[0]}}; + assign bitmask[15:8] = {8{BEn_SI[1]}}; + assign bitmask[23:16] = {8{BEn_SI[2]}}; + assign bitmask[31:24] = {8{BEn_SI[3]}}; + assign bitmask[39:32] = {8{BEn_SI[4]}}; + assign bitmask[47:40] = {8{BEn_SI[5]}}; + assign bitmask[55:48] = {8{BEn_SI[6]}}; + assign bitmask[63:56] = {8{BEn_SI[7]}}; + + sram_behav #( + .DATA_WIDTH(64), + .NUM_WORDS (256) + ) i_sram ( + .clk_i(Clk_CI), + .req_i(CSel_SI), + .we_i(WrEn_SI), + .addr_i(Addr_DI), + .wdata_i(WrData_DI), + .be_i(bitmask), + .rdata_o(RdData_DN) + ); + + //////////////////////////// + // optional output regs + //////////////////////////// + + // output regs + generate + if (OUT_REGS > 0) begin : g_outreg + always_ff @(posedge Clk_CI or negedge Rst_RBI) begin + if (Rst_RBI == 1'b0) begin + RdData_DP <= 0; + end else begin + RdData_DP <= RdData_DN; + end + end + end + endgenerate // g_outreg + + // output reg bypass + generate + if (OUT_REGS == 0) begin : g_oureg_byp + assign RdData_DP = RdData_DN; + end + endgenerate // g_oureg_byp + + assign RdData_DO = RdData_DP; + + //////////////////////////// + // assertions + //////////////////////////// + + // pragma translate_off + assert property (@(posedge Clk_CI) (longint'(2)**longint'(ADDR_WIDTH) >= longint'(DATA_DEPTH))) - else $error("depth out of bounds"); - // pragma translate_on + else $error("depth out of bounds"); + // pragma translate_on -endmodule // SyncSpRamBeNx64 +endmodule // SyncSpRamBeNx64 diff --git a/rtl/techmap/inferred/ddr_inferred.vhd b/rtl/techmap/inferred/ddr_inferred.vhd index c37648ea54..41e0bdbbe7 100644 --- a/rtl/techmap/inferred/ddr_inferred.vhd +++ b/rtl/techmap/inferred/ddr_inferred.vhd @@ -16,7 +16,7 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------- -- Entity: gen_iddr_reg -- File: gen_iddr_reg.vhd @@ -25,83 +25,128 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; + use ieee.std_logic_1164.all; entity gen_iddr_reg is - generic (scantest: integer; noasync: integer); - port( - Q1 : out std_ulogic; - Q2 : out std_ulogic; - C1 : in std_ulogic; - C2 : in std_ulogic; - CE : in std_ulogic; - D : in std_ulogic; - R : in std_ulogic; - S : in std_ulogic; - testen: in std_ulogic; - testrst: in std_ulogic - ); -end; - + generic ( + scantest : integer; + noasync : integer + ); + port ( + q1 : out std_ulogic; + q2 : out std_ulogic; + c1 : in std_ulogic; + c2 : in std_ulogic; + ce : in std_ulogic; + d : in std_ulogic; + r : in std_ulogic; + s : in std_ulogic; + testen : in std_ulogic; + testrst : in std_ulogic + ); +end entity gen_iddr_reg; + architecture rtl of gen_iddr_reg is - signal preQ2 : std_ulogic; - signal RI: std_ulogic; + + signal preq2 : std_ulogic; + signal ri : std_ulogic; + begin - RI <= (not testrst) when (scantest/=0 and testen='1') else R; + ri <= (not testrst) when (scantest/=0 and testen='1') else + r; - ddrregp : process(RI,C1) + ddrregp : process (ri, c1) is begin - if RI = '1' and (noasync=0) then Q1 <= '0'; Q2 <= '0'; - elsif rising_edge(C1) then Q1 <= D; Q2 <= preQ2; end if; - end process; - ddrregn : process(RI,C2) + if (ri = '1' and (noasync=0)) then + q1 <= '0'; + q2 <= '0'; + elsif rising_edge(c1) then + q1 <= d; + q2 <= preq2; + end if; + + end process ddrregp; + + ddrregn : process (ri, c2) is begin - if RI = '1' and (noasync=0) then preQ2 <= '0'; --- elsif falling_edge(C1) then preQ2 <= D; end if; - elsif rising_edge(C2) then preQ2 <= D; end if; - end process; -end; + if (ri = '1' and (noasync=0)) then + preq2 <= '0'; + -- elsif falling_edge(C1) then preQ2 <= D; end if; + elsif rising_edge(c2) then + preq2 <= d; + end if; + + end process ddrregn; + +end architecture rtl; library ieee; -use ieee.std_logic_1164.all; + use ieee.std_logic_1164.all; entity gen_oddr_reg is - generic (scantest: integer; noasync: integer); + generic ( + scantest : integer; + noasync : integer + ); port ( - Q : out std_ulogic; - C1 : in std_ulogic; - C2 : in std_ulogic; - CE : in std_ulogic; - D1 : in std_ulogic; - D2 : in std_ulogic; - R : in std_ulogic; - S : in std_ulogic; - testen: in std_ulogic; - testrst: in std_ulogic); -end; + q : out std_ulogic; + c1 : in std_ulogic; + c2 : in std_ulogic; + ce : in std_ulogic; + d1 : in std_ulogic; + d2 : in std_ulogic; + r : in std_ulogic; + s : in std_ulogic; + testen : in std_ulogic; + testrst : in std_ulogic + ); +end entity gen_oddr_reg; architecture rtl of gen_oddr_reg is - signal Q1,Q2: std_ulogic; - signal SEL : std_ulogic := '1'; - signal RI,SI: std_ulogic; + + signal q1, q2 : std_ulogic; + signal sel : std_ulogic := '1'; + signal ri, si : std_ulogic; + begin - RI <= (not testrst) when (scantest/=0 and testen='1') else R; - SI <= '0' when (scantest/=0 and testen='1') else S; + ri <= (not testrst) when (scantest/=0 and testen='1') else + r; + si <= '0' when (scantest/=0 and testen='1') else + s; + + q <= q1 when sel = '1' else + q2; - Q <= Q1 when SEL = '1' else Q2; - - ddrregp: process(C1,RI,SI) + ddrregp : process (c1, ri, si) is begin - if rising_edge(C1) then Q1 <= D1; Q2 <= D2; end if; - if SI='1' and noasync=0 then Q1 <= '1'; Q2 <= '1'; end if; - if RI='1' and noasync=0 then Q1 <= '0'; Q2 <= '0'; end if; - if C1='1' and noasync=0 then SEL <= '1'; else SEL <= '0'; end if; - end process; - -end; - + + if rising_edge(c1) then + q1 <= d1; + q2 <= d2; + end if; + + if (si='1' and noasync=0) then + q1 <= '1'; + q2 <= '1'; + end if; + + if (ri='1' and noasync=0) then + q1 <= '0'; + q2 <= '0'; + end if; + + if (c1='1' and noasync=0) then + sel <= '1'; + else + sel <= '0'; + end if; + + end process ddrregp; + +end architecture rtl; + diff --git a/rtl/techmap/maps/allclkgen.vhd b/rtl/techmap/maps/allclkgen.vhd index d17bfa500f..596a95bd57 100644 --- a/rtl/techmap/maps/allclkgen.vhd +++ b/rtl/techmap/maps/allclkgen.vhd @@ -18,86 +18,90 @@ -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------- --- Package: allclkgen --- File: allclkgen.vhd --- Author: Jiri Gaisler - Gaisler Research --- Description: Clock generator interface package +-- Package: allclkgen +-- File: allclkgen.vhd +-- Author: Jiri Gaisler - Gaisler Research +-- Description: Clock generator interface package ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.gencomp.all; + use ieee.std_logic_1164.all; + use work.gencomp.all; package allclkgen is + component clkgen_virtex7 is + generic ( + clk_mul : integer := 1; + clk_div : integer := 1; + freq : integer := 25000 + ); + port ( + clkin : in std_logic; + clk : out std_logic; + clk90 : out std_ulogic; + clkio : out std_ulogic; + cgi : in clkgen_in_type; + cgo : out clkgen_out_type + ); + end component; -component clkgen_virtex7 - generic ( - clk_mul : integer := 1; - clk_div : integer := 1; - freq : integer := 25000); - port ( - clkin : in std_logic; - clk : out std_logic; -- main clock - clk90 : out std_ulogic; -- main clock 90deg - clkio : out std_ulogic; -- IO ref clock - cgi : in clkgen_in_type; - cgo : out clkgen_out_type); -end component; + component clkgen_virtexup is + generic ( + clk_mul : integer; + clk_div : integer; + freq : integer + ); + port ( + clkin : in std_ulogic; + clk : out std_ulogic; + clkn : out std_ulogic; + clkio : out std_ulogic; + cgi : in clkgen_in_type; + cgo : out clkgen_out_type + ); + end component clkgen_virtexup; -component clkgen_virtexup is - generic ( - clk_mul : integer; - clk_div : integer; - freq : integer); - port ( - clkin : in std_ulogic; - clk : out std_ulogic; - clkn : out std_ulogic; - clkio : out std_ulogic; - cgi : in clkgen_in_type; - cgo : out clkgen_out_type); -end component clkgen_virtexup; + component clkgen_virtexu is + generic ( + clk_mul : integer; + clk_div : integer; + freq : integer + ); + port ( + clkin : in std_ulogic; + clk : out std_ulogic; + clkn : out std_ulogic; + clkio : out std_ulogic; + cgi : in clkgen_in_type; + cgo : out clkgen_out_type + ); + end component clkgen_virtexu; -component clkgen_virtexu is - generic ( - clk_mul : integer; - clk_div : integer; - freq : integer); - port ( - clkin : in std_ulogic; - clk : out std_ulogic; - clkn : out std_ulogic; - clkio : out std_ulogic; - cgi : in clkgen_in_type; - cgo : out clkgen_out_type); -end component clkgen_virtexu; + component clkand_unisim is + port ( + i : in std_ulogic; + en : in std_ulogic; + o : out std_ulogic + ); + end component; + component clkmux_unisim is + port ( + i0 : in std_ulogic; + i1 : in std_ulogic; + sel : in std_ulogic; + o : out std_ulogic + ); + end component; -component clkand_unisim - port( - i : in std_ulogic; - en : in std_ulogic; - o : out std_ulogic - ); -end component; + component clkmuxctrl_unisim is + port ( + i0 : in std_ulogic; + i1 : in std_ulogic; + sel : in std_ulogic; + o : out std_ulogic + ); + end component; - -component clkmux_unisim - port( - i0, i1 : in std_ulogic; - sel : in std_ulogic; - o : out std_ulogic - ); -end component; - -component clkmuxctrl_unisim - port ( - i0 : in std_ulogic; - i1 : in std_ulogic; - sel : in std_ulogic; - o : out std_ulogic - ); -end component; - -end; +end package allclkgen; diff --git a/rtl/techmap/unisim/buffer_unisim.vhd b/rtl/techmap/unisim/buffer_unisim.vhd index 02621a92b3..9b5c1a28ee 100644 --- a/rtl/techmap/unisim/buffer_unisim.vhd +++ b/rtl/techmap/unisim/buffer_unisim.vhd @@ -16,71 +16,121 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ----------------------------------------------------------------------------- --- Entity: clkbuf_xilinx --- File: clkbuf_xilinx.vhd --- Author: Marko Isomaki, Jiri GAisler - Gaisler Research --- Description: Clock buffer generator for Xilinx devices +-- Entity: clkbuf_xilinx +-- File: clkbuf_xilinx.vhd +-- Author: Marko Isomaki, Jiri GAisler - Gaisler Research +-- Description: Clock buffer generator for Xilinx devices ------------------------------------------------------------------------------ + library ieee; -use ieee.std_logic_1164.all; + use ieee.std_logic_1164.all; -- pragma translate_off + library unisim; -use unisim.vcomponents.BUFGMUX; -use unisim.vcomponents.BUFG; + use unisim.vcomponents.bufgmux; + use unisim.vcomponents.bufg; -- pragma translate_on entity clkbuf_xilinx is - generic( - buftype : integer range 0 to 3 := 0); - port( - i : in std_ulogic; - o : out std_ulogic + generic ( + buftype : integer range 0 to 3 := 0 + ); + port ( + i : in std_ulogic; + o : out std_ulogic ); -end entity; +end entity clkbuf_xilinx; architecture rtl of clkbuf_xilinx is - component BUFGMUX port (O : out std_logic; I0, I1, S : in std_logic); end component; - component BUFG port (O : out std_logic; I : in std_logic); end component; - signal gnd : std_ulogic; - signal x : std_ulogic; + + component bufgmux is port ( + o : out std_logic; + i0 : in std_logic; + i1 : in std_logic; + s : in std_logic + ); end component; + + component bufg is port ( + o : out std_logic; + i : in std_logic + ); end component; + + signal gnd : std_ulogic; + signal x : std_ulogic; attribute syn_noclockbuf : boolean; attribute syn_noclockbuf of x : signal is true; + begin + gnd <= '0'; - buf0 : if (buftype = 0) or (buftype > 2) generate + + buf0 : if (buftype = 0) or (buftype > 2) generate x <= i; o <= x; - end generate; - buf1 : if buftype = 1 generate - buf : bufgmux port map(S => gnd, I0 => i, I1 => gnd, O => o); - end generate; - buf2 : if (buftype = 2) generate - buf : bufg port map(I => i, O => o); - end generate; - -end architecture; + end generate buf0; + + buf1 : if buftype = 1 generate + + buf : component bufgmux + port map ( + s => gnd, + i0 => i, + i1 => gnd, + o => o + ); + + end generate buf1; + + buf2 : if (buftype = 2) generate + + buf : component bufg + port map ( + i => i, + o => o + ); + + end generate buf2; + +end architecture rtl; library ieee; -use ieee.std_logic_1164.all; + use ieee.std_logic_1164.all; -- pragma translate_off + library unisim; -use unisim.vcomponents.BUFGMUX; + use unisim.vcomponents.bufgmux; -- pragma translate_on entity clkmux_xilinx is - port( - i0, i1 : in std_ulogic; - sel : in std_ulogic; - o : out std_ulogic + port ( + i0 : in std_ulogic; + i1 : in std_ulogic; + sel : in std_ulogic; + o : out std_ulogic ); -end entity; +end entity clkmux_xilinx; architecture rtl of clkmux_xilinx is - component BUFGMUX port (O : out std_logic; I0, I1, S : in std_logic); end component; + + component bufgmux is port ( + o : out std_logic; + i0 : in std_logic; + i1 : in std_logic; + s : in std_logic + ); end component; + begin - buf : bufgmux port map(S => sel, I0 => i0, I1 => i1, O => o); -end architecture; + + buf : component bufgmux + port map ( + s => sel, + i0 => i0, + i1 => i1, + o => o + ); + +end architecture rtl; diff --git a/rtl/techmap/unisim/mem/BRAM_1024x16.v b/rtl/techmap/unisim/mem/BRAM_1024x16.v index c18898d4ec..40849047ff 100644 --- a/rtl/techmap/unisim/mem/BRAM_1024x16.v +++ b/rtl/techmap/unisim/mem/BRAM_1024x16.v @@ -1,61 +1,75 @@ `timescale 1 ps / 1 ps // Copyright (c) 2014-2021, Columbia University -module BRAM_1024x16( CLK, A0, D0, Q0, WE0, WEM0, CE0, A1, D1, Q1, WE1, WEM1, CE1 ); - input CLK; - input [9:0] A0; - input [15:0] D0; - output [15:0] Q0; - input WE0; - input [15:0] WEM0; - input CE0; - input [9:0] A1; - input [15:0] D1; - output [15:0] Q1; - input WE1; - input [15:0] WEM1; - input CE1; +module BRAM_1024x16 ( + CLK, + A0, + D0, + Q0, + WE0, + WEM0, + CE0, + A1, + D1, + Q1, + WE1, + WEM1, + CE1 +); + input CLK; + input [9:0] A0; + input [15:0] D0; + output [15:0] Q0; + input WE0; + input [15:0] WEM0; + input CE0; + input [9:0] A1; + input [15:0] D1; + output [15:0] Q1; + input WE1; + input [15:0] WEM1; + input CE1; - reg CE0_tmp; - reg CE1_tmp; - reg [9:0] A0_tmp; - reg [9:0] A1_tmp; - reg WE0_tmp; - reg WE1_tmp; - reg [15:0] D0_tmp; - reg [15:0] D1_tmp; + reg CE0_tmp; + reg CE1_tmp; + reg [ 9:0] A0_tmp; + reg [ 9:0] A1_tmp; + reg WE0_tmp; + reg WE1_tmp; + reg [15:0] D0_tmp; + reg [15:0] D1_tmp; - always @(*) - begin - #5 A0_tmp = A0; - A1_tmp = A1; - CE0_tmp = CE0; - CE1_tmp = CE1; - WE0_tmp = WE0; - WE1_tmp = WE1; - D0_tmp = D0; - D1_tmp = D1; - end - - wire [1:0] DOPA_float; - wire [1:0] DOPB_float; + always @(*) begin + #5 A0_tmp = A0; + A1_tmp = A1; + CE0_tmp = CE0; + CE1_tmp = CE1; + WE0_tmp = WE0; + WE1_tmp = WE1; + D0_tmp = D0; + D1_tmp = D1; + end - RAMB16_S18_S18 bram ( - .DOA(Q0), - .DOB(Q1), - .DOPA(DOPA_float), - .DOPB(DOPB_float), - .ADDRA(A0_tmp), - .ADDRB(A1_tmp), - .CLKA(CLK), - .CLKB(CLK), - .DIA(D0_tmp), - .DIB(D1_tmp), - .DIPA(2'b0), - .DIPB(2'b0), - .ENA(CE0_tmp), - .ENB(CE1_tmp), - .SSRA(1'b0), - .SSRB(1'b0), - .WEA(WE0_tmp), - .WEB(WE1_tmp)); + wire [1:0] DOPA_float; + wire [1:0] DOPB_float; + + RAMB16_S18_S18 bram ( + .DOA (Q0), + .DOB (Q1), + .DOPA (DOPA_float), + .DOPB (DOPB_float), + .ADDRA(A0_tmp), + .ADDRB(A1_tmp), + .CLKA (CLK), + .CLKB (CLK), + .DIA (D0_tmp), + .DIB (D1_tmp), + .DIPA (2'b0), + .DIPB (2'b0), + .ENA (CE0_tmp), + .ENB (CE1_tmp), + .SSRA (1'b0), + .SSRB (1'b0), + .WEA (WE0_tmp), + .WEB (WE1_tmp) + ); endmodule diff --git a/rtl/techmap/unisim/sgmii_vcu118_reset_sync.v b/rtl/techmap/unisim/sgmii_vcu118_reset_sync.v index 74f4ef78fa..79ab204890 100644 --- a/rtl/techmap/unisim/sgmii_vcu118_reset_sync.v +++ b/rtl/techmap/unisim/sgmii_vcu118_reset_sync.v @@ -57,86 +57,85 @@ // //------------------------------------------------------------------------------ -`timescale 1ps/1ps +`timescale 1ps / 1ps module sgmii_vcu118_reset_sync #( - parameter INITIALISE = 2'b11 -) -( - input reset_in, - input clk, - output reset_out + parameter INITIALISE = 2'b11 +) ( + input reset_in, + input clk, + output reset_out ); - wire reset_stage1; - wire reset_stage2; - wire reset_stage3; - wire reset_stage4; - wire reset_stage5; - wire reset_stage6; + wire reset_stage1; + wire reset_stage2; + wire reset_stage3; + wire reset_stage4; + wire reset_stage5; + wire reset_stage6; - (* shreg_extract = "no", ASYNC_REG = "TRUE" *) - FDP #( - .INIT (INITIALISE[0]) - ) reset_sync1 ( - .C (clk), - .PRE(reset_in), - .D (1'b0), - .Q (reset_stage1) - ); + (* shreg_extract = "no", ASYNC_REG = "TRUE" *) + FDP #( + .INIT(INITIALISE[0]) + ) reset_sync1 ( + .C (clk), + .PRE(reset_in), + .D (1'b0), + .Q (reset_stage1) + ); - (* shreg_extract = "no", ASYNC_REG = "TRUE" *) - FDP #( - .INIT (INITIALISE[1]) - ) reset_sync2 ( - .C (clk), - .PRE(reset_in), - .D (reset_stage1), - .Q (reset_stage2) - ); + (* shreg_extract = "no", ASYNC_REG = "TRUE" *) + FDP #( + .INIT(INITIALISE[1]) + ) reset_sync2 ( + .C (clk), + .PRE(reset_in), + .D (reset_stage1), + .Q (reset_stage2) + ); - (* shreg_extract = "no", ASYNC_REG = "TRUE" *) - FDP #( - .INIT (INITIALISE[1]) - ) reset_sync3 ( - .C (clk), - .PRE(reset_in), - .D (reset_stage2), - .Q (reset_stage3) - ); + (* shreg_extract = "no", ASYNC_REG = "TRUE" *) + FDP #( + .INIT(INITIALISE[1]) + ) reset_sync3 ( + .C (clk), + .PRE(reset_in), + .D (reset_stage2), + .Q (reset_stage3) + ); - (* shreg_extract = "no", ASYNC_REG = "TRUE" *) - FDP #( - .INIT (INITIALISE[1]) - ) reset_sync4 ( - .C (clk), - .PRE(reset_in), - .D (reset_stage3), - .Q (reset_stage4) - ); + (* shreg_extract = "no", ASYNC_REG = "TRUE" *) + FDP #( + .INIT(INITIALISE[1]) + ) reset_sync4 ( + .C (clk), + .PRE(reset_in), + .D (reset_stage3), + .Q (reset_stage4) + ); - (* shreg_extract = "no", ASYNC_REG = "TRUE" *) - FDP #( - .INIT (INITIALISE[1]) - ) reset_sync5 ( - .C (clk), - .PRE(reset_in), - .D (reset_stage4), - .Q (reset_stage5) - ); + (* shreg_extract = "no", ASYNC_REG = "TRUE" *) + FDP #( + .INIT(INITIALISE[1]) + ) reset_sync5 ( + .C (clk), + .PRE(reset_in), + .D (reset_stage4), + .Q (reset_stage5) + ); - (* shreg_extract = "no", ASYNC_REG = "TRUE" *) - FDP #( - .INIT (INITIALISE[1]) - ) reset_sync6 ( - .C (clk), - .PRE(1'b0), - .D (reset_stage5), - .Q (reset_stage6) - ); + (* shreg_extract = "no", ASYNC_REG = "TRUE" *) + FDP #( + .INIT(INITIALISE[1]) + ) reset_sync6 ( + .C (clk), + .PRE(1'b0), + .D (reset_stage5), + .Q (reset_stage6) + ); -assign reset_out = reset_stage6; + assign reset_out = reset_stage6; diff --git a/rtl/techmap/unisim/sram_b/unisim_sram_b_10abits.v b/rtl/techmap/unisim/sram_b/unisim_sram_b_10abits.v index 8967d2f643..7a0a90abb3 100644 --- a/rtl/techmap/unisim/sram_b/unisim_sram_b_10abits.v +++ b/rtl/techmap/unisim/sram_b/unisim_sram_b_10abits.v @@ -7,9 +7,9 @@ // @author Paolo Mantovani // -`timescale 1 ps / 1 ps +`timescale 1 ps / 1 ps -module unisim_sram_b_10abits( +module unisim_sram_b_10abits ( CLK, CE0, A0, @@ -19,190 +19,191 @@ module unisim_sram_b_10abits( CE1, A1, Q1 - ); - input CLK; - input CE0; - input [9:0] A0; - input [7:0] D0; - input WE0; - input [7:0] WEM0; - input CE1; - input [9:0] A1; - output [7:0] Q1; - genvar d, h, v, hh; - - reg bank_CE [0:0][0:0][0:0][0:0][1:0]; - reg [10:0] bank_A [0:0][0:0][0:0][0:0][1:0]; - reg [7:0] bank_D [0:0][0:0][0:0][0:0][1:0]; - reg bank_WE [0:0][0:0][0:0][0:0][1:0]; - reg [7:0] bank_WEM [0:0][0:0][0:0][0:0][1:0]; - wire [7:0] bank_Q [0:0][0:0][0:0][0:0][1:0]; - wire [0:0] ctrld [1:1]; - wire [0:0] ctrlh [1:0]; - wire [0:0] ctrlv [1:0]; - reg [0:0] seld [1:1]; - reg [0:0] selh [1:1]; - reg [0:0] selv [1:1]; -// synthesis translate_off -// synopsys translate_off - integer check_bank_access [0:0][0:0][0:0][0:0][1:0]; - - task check_access; - input integer iface; - input integer d; - input integer h; - input integer v; - input integer hh; - input integer p; - begin - if ((check_bank_access[d][h][v][hh][p] != -1) && +); + input CLK; + input CE0; + input [9:0] A0; + input [7:0] D0; + input WE0; + input [7:0] WEM0; + input CE1; + input [9:0] A1; + output [7:0] Q1; + genvar d, h, v, hh; + + reg bank_CE [0:0] [0:0][0:0][0:0][1:0]; + reg [10:0] bank_A [0:0] [0:0][0:0][0:0][1:0]; + reg [ 7:0] bank_D [0:0] [0:0][0:0][0:0][1:0]; + reg bank_WE [0:0] [0:0][0:0][0:0][1:0]; + reg [ 7:0] bank_WEM [0:0] [0:0][0:0][0:0][1:0]; + wire [ 7:0] bank_Q [0:0] [0:0][0:0][0:0][1:0]; + wire [ 0:0] ctrld [1:1]; + wire [ 0:0] ctrlh [1:0]; + wire [ 0:0] ctrlv [1:0]; + reg [ 0:0] seld [1:1]; + reg [ 0:0] selh [1:1]; + reg [ 0:0] selv [1:1]; + // synthesis translate_off + // synopsys translate_off + integer check_bank_access[0:0] [0:0][0:0][0:0][1:0]; + + task check_access; + input integer iface; + input integer d; + input integer h; + input integer v; + input integer hh; + input integer p; + begin + if ((check_bank_access[d][h][v][hh][p] != -1) && (check_bank_access[d][h][v][hh][p] != iface)) begin - $display("ASSERTION FAILED in %m: port conflict on bank", h, "h", v, "v", hh, "hh", " for port", p, " involving interfaces", check_bank_access[d][h][v][hh][p], iface); - $finish; - end - else begin - check_bank_access[d][h][v][hh][p] = iface; + $display("ASSERTION FAILED in %m: port conflict on bank", h, "h", v, "v", hh, "hh", + " for port", p, " involving interfaces", + check_bank_access[d][h][v][hh][p], iface); + $finish; + end else begin + check_bank_access[d][h][v][hh][p] = iface; + end + end + endtask + // synopsys translate_on + // synthesis translate_on + + assign ctrld[1] = 0; + assign ctrlh[0] = 0; + assign ctrlh[1] = 0; + assign ctrlv[0] = 0; + assign ctrlv[1] = 0; + + always @(posedge CLK) begin + seld[1] <= ctrld[1]; + selh[1] <= ctrlh[1]; + selv[1] <= ctrlv[1]; end - end - endtask -// synopsys translate_on -// synthesis translate_on - - assign ctrld[1] = 0; - assign ctrlh[0] = 0; - assign ctrlh[1] = 0; - assign ctrlv[0] = 0; - assign ctrlv[1] = 0; - - always @(posedge CLK) begin - seld[1] <= ctrld[1]; - selh[1] <= ctrlh[1]; - selv[1] <= ctrlv[1]; - end - - generate - for (h = 0; h < 1; h = h + 1) begin : gen_ctrl_hbanks - for (v = 0; v < 1; v = v + 1) begin : gen_ctrl_vbanks - for (hh = 0; hh < 1; hh = hh + 1) begin : gen_ctrl_hhbanks - - always @(*) begin : handle_ops - -// synthesis translate_off -// synopsys translate_off - // Prevent assertions to trigger with false positive - # 1 -// synopsys translate_on -// synthesis translate_on - - /** Default **/ -// synthesis translate_off -// synopsys translate_off - check_bank_access[0][h][v][hh][0] = -1; -// synopsys translate_on -// synthesis translate_on - bank_CE[0][h][v][hh][0] = 0; - bank_A[0][h][v][hh][0] = 0; - bank_D[0][h][v][hh][0] = 0; - bank_WE[0][h][v][hh][0] = 0; - bank_WEM[0][h][v][hh][0] = 0; -// synthesis translate_off -// synopsys translate_off - check_bank_access[0][h][v][hh][1] = -1; -// synopsys translate_on -// synthesis translate_on - bank_CE[0][h][v][hh][1] = 0; - bank_A[0][h][v][hh][1] = 0; - bank_D[0][h][v][hh][1] = 0; - bank_WE[0][h][v][hh][1] = 0; - bank_WEM[0][h][v][hh][1] = 0; - - /** Handle 1w:1r **/ - // Duplicated bank set 0 - if (ctrlh[0] == h && ctrlv[0] == v && CE0 == 1'b1) begin -// synthesis translate_off -// synopsys translate_off - check_access(0, 0, h, v, hh, 0); -// synopsys translate_on -// synthesis translate_on - bank_CE[0][h][v][hh][0] = CE0; - bank_A[0][h][v][hh][0] = A0[9:0]; - if (hh != 0) begin - bank_D[0][h][v][hh][0] = D0[8 * (hh + 1) - 1:8 * hh]; - bank_WEM[0][h][v][hh][0] = WEM0[8 * (hh + 1) - 1:8 * hh]; - end - else begin - bank_D[0][h][v][hh][0] = D0[7 + 8 * hh:8 * hh]; - bank_WEM[0][h][v][hh][0] = WEM0[7 + 8 * hh:8 * hh]; - end - bank_WE[0][h][v][hh][0] = WE0; + + generate + for (h = 0; h < 1; h = h + 1) begin : gen_ctrl_hbanks + for (v = 0; v < 1; v = v + 1) begin : gen_ctrl_vbanks + for (hh = 0; hh < 1; hh = hh + 1) begin : gen_ctrl_hhbanks + + always @(*) begin : handle_ops + + // synthesis translate_off + // synopsys translate_off + // Prevent assertions to trigger with false positive + #1 + // synopsys translate_on + // synthesis translate_on + + /** Default **/ + // synthesis translate_off + // synopsys translate_off + check_bank_access[0][h][v][hh][0] = -1; + // synopsys translate_on + // synthesis translate_on + bank_CE[0][h][v][hh][0] = 0; + bank_A[0][h][v][hh][0] = 0; + bank_D[0][h][v][hh][0] = 0; + bank_WE[0][h][v][hh][0] = 0; + bank_WEM[0][h][v][hh][0] = 0; + // synthesis translate_off + // synopsys translate_off + check_bank_access[0][h][v][hh][1] = -1; + // synopsys translate_on + // synthesis translate_on + bank_CE[0][h][v][hh][1] = 0; + bank_A[0][h][v][hh][1] = 0; + bank_D[0][h][v][hh][1] = 0; + bank_WE[0][h][v][hh][1] = 0; + bank_WEM[0][h][v][hh][1] = 0; + + /** Handle 1w:1r **/ + // Duplicated bank set 0 + if (ctrlh[0] == h && ctrlv[0] == v && CE0 == 1'b1) begin + // synthesis translate_off + // synopsys translate_off + check_access(0, 0, h, v, hh, 0); + // synopsys translate_on + // synthesis translate_on + bank_CE[0][h][v][hh][0] = CE0; + bank_A[0][h][v][hh][0] = A0[9:0]; + if (hh != 0) begin + bank_D[0][h][v][hh][0] = D0[8*(hh+1)-1:8*hh]; + bank_WEM[0][h][v][hh][0] = WEM0[8*(hh+1)-1:8*hh]; + end else begin + bank_D[0][h][v][hh][0] = D0[7+8*hh:8*hh]; + bank_WEM[0][h][v][hh][0] = WEM0[7+8*hh:8*hh]; + end + bank_WE[0][h][v][hh][0] = WE0; + end + // Always choose duplicated bank set 0 + if (ctrlh[1] == h && ctrlv[1] == v && CE1 == 1'b1) begin + // synthesis translate_off + // synopsys translate_off + check_access(1, 0, h, v, hh, 1); + // synopsys translate_on + // synthesis translate_on + bank_CE[0][h][v][hh][1] = CE1; + bank_A[0][h][v][hh][1] = A1[9:0]; + end + + end + + end end - // Always choose duplicated bank set 0 - if (ctrlh[1] == h && ctrlv[1] == v && CE1 == 1'b1) begin -// synthesis translate_off -// synopsys translate_off - check_access(1, 0, h, v, hh, 1); -// synopsys translate_on -// synthesis translate_on - bank_CE[0][h][v][hh][1] = CE1; - bank_A[0][h][v][hh][1] = A1[9:0]; + end + endgenerate + + generate + for (hh = 0; hh < 1; hh = hh + 1) begin : gen_q_assign_hhbanks + if (hh == 0 && (hh + 1) * 8 > 8) begin : gen_q_assign_hhbanks_last_1 + assign Q1[7:8*hh] = bank_Q[seld[1]][selh[1]][selv[1]][hh][1][7:0]; + end else begin : gen_q_assign_hhbanks_others_1 + assign Q1[8*(hh+1)-1:8*hh] = bank_Q[seld[1]][selh[1]][selv[1]][hh][1]; end - end - - end - end - end - endgenerate - - generate - for (hh = 0; hh < 1; hh = hh + 1) begin : gen_q_assign_hhbanks - if (hh == 0 && (hh + 1) * 8 > 8) begin : gen_q_assign_hhbanks_last_1 - assign Q1[7:8 * hh] = bank_Q[seld[1]][selh[1]][selv[1]][hh][1][7:0]; - end else begin : gen_q_assign_hhbanks_others_1 - assign Q1[8 * (hh + 1) - 1:8 * hh] = bank_Q[seld[1]][selh[1]][selv[1]][hh][1]; - end - end - endgenerate - - generate - for (d = 0; d < 1; d = d + 1) begin : gen_wires_dbanks - for (h = 0; h < 1; h = h + 1) begin : gen_wires_hbanks - for (v = 0; v < 1; v = v + 1) begin : gen_wires_vbanks - for (hh = 0; hh < 1; hh = hh + 1) begin : gen_wires_hhbanks - - BRAM_2048x8 bank_i( - .CLK(CLK), - .CE0(bank_CE[d][h][v][hh][0]), - .A0(bank_A[d][h][v][hh][0]), - .D0(bank_D[d][h][v][hh][0]), - .WE0(bank_WE[d][h][v][hh][0]), - .WEM0(bank_WEM[d][h][v][hh][0]), - .Q0(bank_Q[d][h][v][hh][0]), - .CE1(bank_CE[d][h][v][hh][1]), - .A1(bank_A[d][h][v][hh][1]), - .D1(bank_D[d][h][v][hh][1]), - .WE1(bank_WE[d][h][v][hh][1]), - .WEM1(bank_WEM[d][h][v][hh][1]), - .Q1(bank_Q[d][h][v][hh][1]) - ); - -// synthesis translate_off -// synopsys translate_off - always @(posedge CLK) begin - if ((bank_CE[d][h][v][hh][0] & bank_CE[d][h][v][hh][1]) && + endgenerate + + generate + for (d = 0; d < 1; d = d + 1) begin : gen_wires_dbanks + for (h = 0; h < 1; h = h + 1) begin : gen_wires_hbanks + for (v = 0; v < 1; v = v + 1) begin : gen_wires_vbanks + for (hh = 0; hh < 1; hh = hh + 1) begin : gen_wires_hhbanks + + BRAM_2048x8 bank_i ( + .CLK (CLK), + .CE0 (bank_CE[d][h][v][hh][0]), + .A0 (bank_A[d][h][v][hh][0]), + .D0 (bank_D[d][h][v][hh][0]), + .WE0 (bank_WE[d][h][v][hh][0]), + .WEM0(bank_WEM[d][h][v][hh][0]), + .Q0 (bank_Q[d][h][v][hh][0]), + .CE1 (bank_CE[d][h][v][hh][1]), + .A1 (bank_A[d][h][v][hh][1]), + .D1 (bank_D[d][h][v][hh][1]), + .WE1 (bank_WE[d][h][v][hh][1]), + .WEM1(bank_WEM[d][h][v][hh][1]), + .Q1 (bank_Q[d][h][v][hh][1]) + ); + + // synthesis translate_off + // synopsys translate_off + always @(posedge CLK) begin + if ((bank_CE[d][h][v][hh][0] & bank_CE[d][h][v][hh][1]) && (bank_WE[d][h][v][hh][0] | bank_WE[d][h][v][hh][1]) && (bank_A[d][h][v][hh][0] == bank_A[d][h][v][hh][1])) begin - $display("ASSERTION FAILED in %m: address conflict on bank", h, "h", v, "v", hh, "hh"); - $finish; - end + $display("ASSERTION FAILED in %m: address conflict on bank", h, + "h", v, "v", hh, "hh"); + $finish; + end + end + // synopsys translate_on + // synthesis translate_on + + end + end end -// synopsys translate_on -// synthesis translate_on - end - end - end - end - endgenerate + endgenerate endmodule diff --git a/rtl/tiles/asic/asic_tile_acc.vhd b/rtl/tiles/asic/asic_tile_acc.vhd index cc06adffb6..108abd9662 100644 --- a/rtl/tiles/asic/asic_tile_acc.vhd +++ b/rtl/tiles/asic/asic_tile_acc.vhd @@ -6,143 +6,142 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.esp_global.all; -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; -use work.gencomp.all; -use work.monitor_pkg.all; -use work.esp_csr_pkg.all; -use work.jtag_pkg.all; -use work.sldacc.all; -use work.nocpackage.all; -use work.cachepackage.all; -use work.tile.all; -use work.misc.all; -use work.coretypes.all; -use work.esp_acc_regmap.all; -use work.socmap.all; -use work.grlib_config.all; -use work.tiles_pkg.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.esp_global.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.monitor_pkg.all; + use work.esp_csr_pkg.all; + use work.jtag_pkg.all; + use work.sldacc.all; + use work.nocpackage.all; + use work.cachepackage.all; + use work.tile.all; + use work.misc.all; + use work.coretypes.all; + use work.esp_acc_regmap.all; + use work.socmap.all; + use work.grlib_config.all; + use work.tiles_pkg.all; entity asic_tile_acc is generic ( - this_hls_conf : hlscfg_t := 0; - this_device : devid_t := 0; - this_irq_type : integer := 0; - this_has_l2 : integer range 0 to 1 := 0; - HAS_SYNC : integer range 0 to 1 := 1; - ROUTER_PORTS : ports_vec := "11111"; - this_has_dco : integer range 0 to 1 := 0); + this_hls_conf : hlscfg_t := 0; + this_device : devid_t := 0; + this_irq_type : integer := 0; + this_has_l2 : integer range 0 to 1 := 0; + has_sync : integer range 0 to 1 := 1; + router_ports : ports_vec := "11111"; + this_has_dco : integer range 0 to 1 := 0 + ); port ( - rst : in std_ulogic; - sys_clk : in std_ulogic; -- NoC clock - sys_clk_lock : in std_ulogic; -- sys_clk_lock - ext_clk : in std_ulogic; -- backup tile clock - clk_div : out std_ulogic; -- tile clock monitor for testing purposes + rst : in std_ulogic; + sys_clk : in std_ulogic; -- NoC clock + sys_clk_lock : in std_ulogic; -- sys_clk_lock + ext_clk : in std_ulogic; -- backup tile clock + clk_div : out std_ulogic; -- tile clock monitor for testing purposes -- Test interface - tdi : in std_logic; - tdo : out std_logic; - tms : in std_logic; - tclk : in std_logic; + tdi : in std_logic; + tdo : out std_logic; + tms : in std_logic; + tclk : in std_logic; -- Pad configuratio - pad_cfg : out std_logic_vector(ESP_CSR_PAD_CFG_MSB - ESP_CSR_PAD_CFG_LSB downto 0); + pad_cfg : out std_logic_vector(ESP_CSR_PAD_CFG_MSB - ESP_CSR_PAD_CFG_LSB downto 0); -- NOC - noc1_data_n_in : in coh_noc_flit_type; - noc1_data_s_in : in coh_noc_flit_type; - noc1_data_w_in : in coh_noc_flit_type; - noc1_data_e_in : in coh_noc_flit_type; - noc1_data_void_in : in std_logic_vector(3 downto 0); - noc1_stop_in : in std_logic_vector(3 downto 0); - noc1_data_n_out : out coh_noc_flit_type; - noc1_data_s_out : out coh_noc_flit_type; - noc1_data_w_out : out coh_noc_flit_type; - noc1_data_e_out : out coh_noc_flit_type; - noc1_data_void_out : out std_logic_vector(3 downto 0); - noc1_stop_out : out std_logic_vector(3 downto 0); - noc2_data_n_in : in coh_noc_flit_type; - noc2_data_s_in : in coh_noc_flit_type; - noc2_data_w_in : in coh_noc_flit_type; - noc2_data_e_in : in coh_noc_flit_type; - noc2_data_void_in : in std_logic_vector(3 downto 0); - noc2_stop_in : in std_logic_vector(3 downto 0); - noc2_data_n_out : out coh_noc_flit_type; - noc2_data_s_out : out coh_noc_flit_type; - noc2_data_w_out : out coh_noc_flit_type; - noc2_data_e_out : out coh_noc_flit_type; - noc2_data_void_out : out std_logic_vector(3 downto 0); - noc2_stop_out : out std_logic_vector(3 downto 0); - noc3_data_n_in : in coh_noc_flit_type; - noc3_data_s_in : in coh_noc_flit_type; - noc3_data_w_in : in coh_noc_flit_type; - noc3_data_e_in : in coh_noc_flit_type; - noc3_data_void_in : in std_logic_vector(3 downto 0); - noc3_stop_in : in std_logic_vector(3 downto 0); - noc3_data_n_out : out coh_noc_flit_type; - noc3_data_s_out : out coh_noc_flit_type; - noc3_data_w_out : out coh_noc_flit_type; - noc3_data_e_out : out coh_noc_flit_type; - noc3_data_void_out : out std_logic_vector(3 downto 0); - noc3_stop_out : out std_logic_vector(3 downto 0); - noc4_data_n_in : in dma_noc_flit_type; - noc4_data_s_in : in dma_noc_flit_type; - noc4_data_w_in : in dma_noc_flit_type; - noc4_data_e_in : in dma_noc_flit_type; - noc4_data_void_in : in std_logic_vector(3 downto 0); - noc4_stop_in : in std_logic_vector(3 downto 0); - noc4_data_n_out : out dma_noc_flit_type; - noc4_data_s_out : out dma_noc_flit_type; - noc4_data_w_out : out dma_noc_flit_type; - noc4_data_e_out : out dma_noc_flit_type; - noc4_data_void_out : out std_logic_vector(3 downto 0); - noc4_stop_out : out std_logic_vector(3 downto 0); - noc5_data_n_in : in misc_noc_flit_type; - noc5_data_s_in : in misc_noc_flit_type; - noc5_data_w_in : in misc_noc_flit_type; - noc5_data_e_in : in misc_noc_flit_type; - noc5_data_void_in : in std_logic_vector(3 downto 0); - noc5_stop_in : in std_logic_vector(3 downto 0); - noc5_data_n_out : out misc_noc_flit_type; - noc5_data_s_out : out misc_noc_flit_type; - noc5_data_w_out : out misc_noc_flit_type; - noc5_data_e_out : out misc_noc_flit_type; - noc5_data_void_out : out std_logic_vector(3 downto 0); - noc5_stop_out : out std_logic_vector(3 downto 0); - noc6_data_n_in : in dma_noc_flit_type; - noc6_data_s_in : in dma_noc_flit_type; - noc6_data_w_in : in dma_noc_flit_type; - noc6_data_e_in : in dma_noc_flit_type; - noc6_data_void_in : in std_logic_vector(3 downto 0); - noc6_stop_in : in std_logic_vector(3 downto 0); - noc6_data_n_out : out dma_noc_flit_type; - noc6_data_s_out : out dma_noc_flit_type; - noc6_data_w_out : out dma_noc_flit_type; - noc6_data_e_out : out dma_noc_flit_type; - noc6_data_void_out : out std_logic_vector(3 downto 0); - noc6_stop_out : out std_logic_vector(3 downto 0) - ); - -end; + noc1_data_n_in : in coh_noc_flit_type; + noc1_data_s_in : in coh_noc_flit_type; + noc1_data_w_in : in coh_noc_flit_type; + noc1_data_e_in : in coh_noc_flit_type; + noc1_data_void_in : in std_logic_vector(3 downto 0); + noc1_stop_in : in std_logic_vector(3 downto 0); + noc1_data_n_out : out coh_noc_flit_type; + noc1_data_s_out : out coh_noc_flit_type; + noc1_data_w_out : out coh_noc_flit_type; + noc1_data_e_out : out coh_noc_flit_type; + noc1_data_void_out : out std_logic_vector(3 downto 0); + noc1_stop_out : out std_logic_vector(3 downto 0); + noc2_data_n_in : in coh_noc_flit_type; + noc2_data_s_in : in coh_noc_flit_type; + noc2_data_w_in : in coh_noc_flit_type; + noc2_data_e_in : in coh_noc_flit_type; + noc2_data_void_in : in std_logic_vector(3 downto 0); + noc2_stop_in : in std_logic_vector(3 downto 0); + noc2_data_n_out : out coh_noc_flit_type; + noc2_data_s_out : out coh_noc_flit_type; + noc2_data_w_out : out coh_noc_flit_type; + noc2_data_e_out : out coh_noc_flit_type; + noc2_data_void_out : out std_logic_vector(3 downto 0); + noc2_stop_out : out std_logic_vector(3 downto 0); + noc3_data_n_in : in coh_noc_flit_type; + noc3_data_s_in : in coh_noc_flit_type; + noc3_data_w_in : in coh_noc_flit_type; + noc3_data_e_in : in coh_noc_flit_type; + noc3_data_void_in : in std_logic_vector(3 downto 0); + noc3_stop_in : in std_logic_vector(3 downto 0); + noc3_data_n_out : out coh_noc_flit_type; + noc3_data_s_out : out coh_noc_flit_type; + noc3_data_w_out : out coh_noc_flit_type; + noc3_data_e_out : out coh_noc_flit_type; + noc3_data_void_out : out std_logic_vector(3 downto 0); + noc3_stop_out : out std_logic_vector(3 downto 0); + noc4_data_n_in : in dma_noc_flit_type; + noc4_data_s_in : in dma_noc_flit_type; + noc4_data_w_in : in dma_noc_flit_type; + noc4_data_e_in : in dma_noc_flit_type; + noc4_data_void_in : in std_logic_vector(3 downto 0); + noc4_stop_in : in std_logic_vector(3 downto 0); + noc4_data_n_out : out dma_noc_flit_type; + noc4_data_s_out : out dma_noc_flit_type; + noc4_data_w_out : out dma_noc_flit_type; + noc4_data_e_out : out dma_noc_flit_type; + noc4_data_void_out : out std_logic_vector(3 downto 0); + noc4_stop_out : out std_logic_vector(3 downto 0); + noc5_data_n_in : in misc_noc_flit_type; + noc5_data_s_in : in misc_noc_flit_type; + noc5_data_w_in : in misc_noc_flit_type; + noc5_data_e_in : in misc_noc_flit_type; + noc5_data_void_in : in std_logic_vector(3 downto 0); + noc5_stop_in : in std_logic_vector(3 downto 0); + noc5_data_n_out : out misc_noc_flit_type; + noc5_data_s_out : out misc_noc_flit_type; + noc5_data_w_out : out misc_noc_flit_type; + noc5_data_e_out : out misc_noc_flit_type; + noc5_data_void_out : out std_logic_vector(3 downto 0); + noc5_stop_out : out std_logic_vector(3 downto 0); + noc6_data_n_in : in dma_noc_flit_type; + noc6_data_s_in : in dma_noc_flit_type; + noc6_data_w_in : in dma_noc_flit_type; + noc6_data_e_in : in dma_noc_flit_type; + noc6_data_void_in : in std_logic_vector(3 downto 0); + noc6_stop_in : in std_logic_vector(3 downto 0); + noc6_data_n_out : out dma_noc_flit_type; + noc6_data_s_out : out dma_noc_flit_type; + noc6_data_w_out : out dma_noc_flit_type; + noc6_data_e_out : out dma_noc_flit_type; + noc6_data_void_out : out std_logic_vector(3 downto 0); + noc6_stop_out : out std_logic_vector(3 downto 0) + ); +end entity asic_tile_acc; architecture rtl of asic_tile_acc is - constant ext_clk_sel_default : std_ulogic := '0'; + constant EXT_CLK_SEL_DEFAULT : std_ulogic := '0'; -- Tile clock and reset (only for I/O tile) - signal raw_rstn : std_ulogic; - signal dco_clk : std_ulogic; - signal dco_rstn : std_ulogic; - signal tile_rst : std_ulogic; + signal raw_rstn : std_ulogic; + signal dco_clk : std_ulogic; + signal dco_rstn : std_ulogic; + signal tile_rst : std_ulogic; -- signal dco_clk_lock : std_ulogic; -- Tile parameters signal this_local_y : local_yx; signal this_local_x : local_yx; - -- Tile interface signals signal test_rstn : std_ulogic; signal test1_output_port_s : coh_noc_flit_type; @@ -182,12 +181,12 @@ architecture rtl of asic_tile_acc is signal test6_data_void_in_s : std_ulogic; signal test6_stop_out_s : std_ulogic; - signal noc1_mon_noc_vec_int : monitor_noc_type; - signal noc2_mon_noc_vec_int : monitor_noc_type; - signal noc3_mon_noc_vec_int : monitor_noc_type; - signal noc4_mon_noc_vec_int : monitor_noc_type; - signal noc5_mon_noc_vec_int : monitor_noc_type; - signal noc6_mon_noc_vec_int : monitor_noc_type; + signal noc1_mon_noc_vec_int : monitor_noc_type; + signal noc2_mon_noc_vec_int : monitor_noc_type; + signal noc3_mon_noc_vec_int : monitor_noc_type; + signal noc4_mon_noc_vec_int : monitor_noc_type; + signal noc5_mon_noc_vec_int : monitor_noc_type; + signal noc6_mon_noc_vec_int : monitor_noc_type; -- Noc signals signal noc_rstn : std_ulogic; @@ -259,118 +258,134 @@ architecture rtl of asic_tile_acc is attribute keep of noc1_acc_data_void_out : signal is "true"; attribute keep of noc1_input_port : signal is "true"; attribute keep of noc1_output_port : signal is "true"; - attribute keep of noc1_data_n_in : signal is "true"; - attribute keep of noc1_data_s_in : signal is "true"; - attribute keep of noc1_data_w_in : signal is "true"; - attribute keep of noc1_data_e_in : signal is "true"; - attribute keep of noc1_data_void_in : signal is "true"; - attribute keep of noc1_stop_in : signal is "true"; - attribute keep of noc1_data_n_out : signal is "true"; - attribute keep of noc1_data_s_out : signal is "true"; - attribute keep of noc1_data_w_out : signal is "true"; - attribute keep of noc1_data_e_out : signal is "true"; - attribute keep of noc1_data_void_out : signal is "true"; - attribute keep of noc1_stop_out : signal is "true"; + attribute keep of noc1_data_n_in : signal is "true"; + attribute keep of noc1_data_s_in : signal is "true"; + attribute keep of noc1_data_w_in : signal is "true"; + attribute keep of noc1_data_e_in : signal is "true"; + attribute keep of noc1_data_void_in : signal is "true"; + attribute keep of noc1_stop_in : signal is "true"; + attribute keep of noc1_data_n_out : signal is "true"; + attribute keep of noc1_data_s_out : signal is "true"; + attribute keep of noc1_data_w_out : signal is "true"; + attribute keep of noc1_data_e_out : signal is "true"; + attribute keep of noc1_data_void_out : signal is "true"; + attribute keep of noc1_stop_out : signal is "true"; attribute keep of noc2_acc_stop_in : signal is "true"; attribute keep of noc2_acc_stop_out : signal is "true"; attribute keep of noc2_acc_data_void_in : signal is "true"; attribute keep of noc2_acc_data_void_out : signal is "true"; attribute keep of noc2_input_port : signal is "true"; attribute keep of noc2_output_port : signal is "true"; - attribute keep of noc2_data_n_in : signal is "true"; - attribute keep of noc2_data_s_in : signal is "true"; - attribute keep of noc2_data_w_in : signal is "true"; - attribute keep of noc2_data_e_in : signal is "true"; - attribute keep of noc2_data_void_in : signal is "true"; - attribute keep of noc2_stop_in : signal is "true"; - attribute keep of noc2_data_n_out : signal is "true"; - attribute keep of noc2_data_s_out : signal is "true"; - attribute keep of noc2_data_w_out : signal is "true"; - attribute keep of noc2_data_e_out : signal is "true"; - attribute keep of noc2_data_void_out : signal is "true"; - attribute keep of noc2_stop_out : signal is "true"; + attribute keep of noc2_data_n_in : signal is "true"; + attribute keep of noc2_data_s_in : signal is "true"; + attribute keep of noc2_data_w_in : signal is "true"; + attribute keep of noc2_data_e_in : signal is "true"; + attribute keep of noc2_data_void_in : signal is "true"; + attribute keep of noc2_stop_in : signal is "true"; + attribute keep of noc2_data_n_out : signal is "true"; + attribute keep of noc2_data_s_out : signal is "true"; + attribute keep of noc2_data_w_out : signal is "true"; + attribute keep of noc2_data_e_out : signal is "true"; + attribute keep of noc2_data_void_out : signal is "true"; + attribute keep of noc2_stop_out : signal is "true"; attribute keep of noc3_acc_stop_in : signal is "true"; attribute keep of noc3_acc_stop_out : signal is "true"; attribute keep of noc3_acc_data_void_in : signal is "true"; attribute keep of noc3_acc_data_void_out : signal is "true"; attribute keep of noc3_input_port : signal is "true"; attribute keep of noc3_output_port : signal is "true"; - attribute keep of noc3_data_n_in : signal is "true"; - attribute keep of noc3_data_s_in : signal is "true"; - attribute keep of noc3_data_w_in : signal is "true"; - attribute keep of noc3_data_e_in : signal is "true"; - attribute keep of noc3_data_void_in : signal is "true"; - attribute keep of noc3_stop_in : signal is "true"; - attribute keep of noc3_data_n_out : signal is "true"; - attribute keep of noc3_data_s_out : signal is "true"; - attribute keep of noc3_data_w_out : signal is "true"; - attribute keep of noc3_data_e_out : signal is "true"; - attribute keep of noc3_data_void_out : signal is "true"; - attribute keep of noc3_stop_out : signal is "true"; + attribute keep of noc3_data_n_in : signal is "true"; + attribute keep of noc3_data_s_in : signal is "true"; + attribute keep of noc3_data_w_in : signal is "true"; + attribute keep of noc3_data_e_in : signal is "true"; + attribute keep of noc3_data_void_in : signal is "true"; + attribute keep of noc3_stop_in : signal is "true"; + attribute keep of noc3_data_n_out : signal is "true"; + attribute keep of noc3_data_s_out : signal is "true"; + attribute keep of noc3_data_w_out : signal is "true"; + attribute keep of noc3_data_e_out : signal is "true"; + attribute keep of noc3_data_void_out : signal is "true"; + attribute keep of noc3_stop_out : signal is "true"; attribute keep of noc4_acc_stop_in : signal is "true"; attribute keep of noc4_acc_stop_out : signal is "true"; attribute keep of noc4_acc_data_void_in : signal is "true"; attribute keep of noc4_acc_data_void_out : signal is "true"; attribute keep of noc4_input_port : signal is "true"; attribute keep of noc4_output_port : signal is "true"; - attribute keep of noc4_data_n_in : signal is "true"; - attribute keep of noc4_data_s_in : signal is "true"; - attribute keep of noc4_data_w_in : signal is "true"; - attribute keep of noc4_data_e_in : signal is "true"; - attribute keep of noc4_data_void_in : signal is "true"; - attribute keep of noc4_stop_in : signal is "true"; - attribute keep of noc4_data_n_out : signal is "true"; - attribute keep of noc4_data_s_out : signal is "true"; - attribute keep of noc4_data_w_out : signal is "true"; - attribute keep of noc4_data_e_out : signal is "true"; - attribute keep of noc4_data_void_out : signal is "true"; - attribute keep of noc4_stop_out : signal is "true"; + attribute keep of noc4_data_n_in : signal is "true"; + attribute keep of noc4_data_s_in : signal is "true"; + attribute keep of noc4_data_w_in : signal is "true"; + attribute keep of noc4_data_e_in : signal is "true"; + attribute keep of noc4_data_void_in : signal is "true"; + attribute keep of noc4_stop_in : signal is "true"; + attribute keep of noc4_data_n_out : signal is "true"; + attribute keep of noc4_data_s_out : signal is "true"; + attribute keep of noc4_data_w_out : signal is "true"; + attribute keep of noc4_data_e_out : signal is "true"; + attribute keep of noc4_data_void_out : signal is "true"; + attribute keep of noc4_stop_out : signal is "true"; attribute keep of noc5_acc_stop_in : signal is "true"; attribute keep of noc5_acc_stop_out : signal is "true"; attribute keep of noc5_acc_data_void_in : signal is "true"; attribute keep of noc5_acc_data_void_out : signal is "true"; attribute keep of noc5_input_port : signal is "true"; attribute keep of noc5_output_port : signal is "true"; - attribute keep of noc5_data_n_in : signal is "true"; - attribute keep of noc5_data_s_in : signal is "true"; - attribute keep of noc5_data_w_in : signal is "true"; - attribute keep of noc5_data_e_in : signal is "true"; - attribute keep of noc5_data_void_in : signal is "true"; - attribute keep of noc5_stop_in : signal is "true"; - attribute keep of noc5_data_n_out : signal is "true"; - attribute keep of noc5_data_s_out : signal is "true"; - attribute keep of noc5_data_w_out : signal is "true"; - attribute keep of noc5_data_e_out : signal is "true"; - attribute keep of noc5_data_void_out : signal is "true"; - attribute keep of noc5_stop_out : signal is "true"; + attribute keep of noc5_data_n_in : signal is "true"; + attribute keep of noc5_data_s_in : signal is "true"; + attribute keep of noc5_data_w_in : signal is "true"; + attribute keep of noc5_data_e_in : signal is "true"; + attribute keep of noc5_data_void_in : signal is "true"; + attribute keep of noc5_stop_in : signal is "true"; + attribute keep of noc5_data_n_out : signal is "true"; + attribute keep of noc5_data_s_out : signal is "true"; + attribute keep of noc5_data_w_out : signal is "true"; + attribute keep of noc5_data_e_out : signal is "true"; + attribute keep of noc5_data_void_out : signal is "true"; + attribute keep of noc5_stop_out : signal is "true"; attribute keep of noc6_acc_stop_in : signal is "true"; attribute keep of noc6_acc_stop_out : signal is "true"; attribute keep of noc6_acc_data_void_in : signal is "true"; attribute keep of noc6_acc_data_void_out : signal is "true"; attribute keep of noc6_input_port : signal is "true"; attribute keep of noc6_output_port : signal is "true"; - attribute keep of noc6_data_n_in : signal is "true"; - attribute keep of noc6_data_s_in : signal is "true"; - attribute keep of noc6_data_w_in : signal is "true"; - attribute keep of noc6_data_e_in : signal is "true"; - attribute keep of noc6_data_void_in : signal is "true"; - attribute keep of noc6_stop_in : signal is "true"; - attribute keep of noc6_data_n_out : signal is "true"; - attribute keep of noc6_data_s_out : signal is "true"; - attribute keep of noc6_data_w_out : signal is "true"; - attribute keep of noc6_data_e_out : signal is "true"; - attribute keep of noc6_data_void_out : signal is "true"; - attribute keep of noc6_stop_out : signal is "true"; + attribute keep of noc6_data_n_in : signal is "true"; + attribute keep of noc6_data_s_in : signal is "true"; + attribute keep of noc6_data_w_in : signal is "true"; + attribute keep of noc6_data_e_in : signal is "true"; + attribute keep of noc6_data_void_in : signal is "true"; + attribute keep of noc6_stop_in : signal is "true"; + attribute keep of noc6_data_n_out : signal is "true"; + attribute keep of noc6_data_s_out : signal is "true"; + attribute keep of noc6_data_w_out : signal is "true"; + attribute keep of noc6_data_e_out : signal is "true"; + attribute keep of noc6_data_void_out : signal is "true"; + attribute keep of noc6_stop_out : signal is "true"; begin - rst_noc : rstgen -- reset generator - generic map (acthigh => 1, syncin => 0) - port map (rst, sys_clk, sys_clk_lock, noc_rstn, raw_rstn); + rst_noc : component rstgen + generic map ( + acthigh => 1, syncin => 0 + ) + port map ( +rst, + sys_clk, + sys_clk_lock, + noc_rstn, + raw_rstn + ); - rst_jtag : rstgen -- reset generator - generic map (acthigh => 1, syncin => 0) - port map (rst, tclk, '1', test_rstn, open); + rst_jtag : component rstgen + generic map ( + acthigh => 1, syncin => 0 + ) + port map ( +rst, + tclk, + '1', + test_rstn, + open + ); has_dco_rst : if this_has_dco = 1 generate tile_rst <= rst; @@ -383,9 +398,10 @@ begin ----------------------------------------------------------------------------- -- JTAG for single tile testing / bypass when test_if_en = 0 ----------------------------------------------------------------------------- - jtag_test_i : jtag_test + jtag_test_i : component jtag_test generic map ( - test_if_en => CFG_JTAG_EN) + test_if_en => CFG_JTAG_EN + ) port map ( rst => test_rstn, refclk => dco_clk, @@ -465,172 +481,175 @@ begin noc5_stop_out => noc5_acc_stop_out, noc6_input_port => noc6_input_port, noc6_data_void_in => noc6_acc_data_void_in, - noc6_stop_out => noc6_acc_stop_out); + noc6_stop_out => noc6_acc_stop_out + ); ----------------------------------------------------------------------------- -- NOC Connections ---------------------------------------------------------------------------- - noc1_stop_in_s <= noc1_acc_stop_in & noc1_stop_in; + noc1_stop_in_s <= noc1_acc_stop_in & noc1_stop_in; noc1_stop_out <= noc1_stop_out_s(3 downto 0); noc1_acc_stop_out <= noc1_stop_out_s(4); noc1_data_void_in_s <= noc1_acc_data_void_in & noc1_data_void_in; noc1_data_void_out <= noc1_data_void_out_s(3 downto 0); noc1_acc_data_void_out <= noc1_data_void_out_s(4); - noc2_stop_in_s <= noc2_acc_stop_in & noc2_stop_in; + noc2_stop_in_s <= noc2_acc_stop_in & noc2_stop_in; noc2_stop_out <= noc2_stop_out_s(3 downto 0); noc2_acc_stop_out <= noc2_stop_out_s(4); noc2_data_void_in_s <= noc2_acc_data_void_in & noc2_data_void_in; noc2_data_void_out <= noc2_data_void_out_s(3 downto 0); noc2_acc_data_void_out <= noc2_data_void_out_s(4); - noc3_stop_in_s <= noc3_acc_stop_in & noc3_stop_in; + noc3_stop_in_s <= noc3_acc_stop_in & noc3_stop_in; noc3_stop_out <= noc3_stop_out_s(3 downto 0); noc3_acc_stop_out <= noc3_stop_out_s(4); noc3_data_void_in_s <= noc3_acc_data_void_in & noc3_data_void_in; noc3_data_void_out <= noc3_data_void_out_s(3 downto 0); noc3_acc_data_void_out <= noc3_data_void_out_s(4); - noc4_stop_in_s <= noc4_acc_stop_in & noc4_stop_in; + noc4_stop_in_s <= noc4_acc_stop_in & noc4_stop_in; noc4_stop_out <= noc4_stop_out_s(3 downto 0); noc4_acc_stop_out <= noc4_stop_out_s(4); noc4_data_void_in_s <= noc4_acc_data_void_in & noc4_data_void_in; noc4_data_void_out <= noc4_data_void_out_s(3 downto 0); noc4_acc_data_void_out <= noc4_data_void_out_s(4); - noc5_stop_in_s <= noc5_acc_stop_in & noc5_stop_in; + noc5_stop_in_s <= noc5_acc_stop_in & noc5_stop_in; noc5_stop_out <= noc5_stop_out_s(3 downto 0); noc5_acc_stop_out <= noc5_stop_out_s(4); noc5_data_void_in_s <= noc5_acc_data_void_in & noc5_data_void_in; noc5_data_void_out <= noc5_data_void_out_s(3 downto 0); noc5_acc_data_void_out <= noc5_data_void_out_s(4); - noc6_stop_in_s <= noc6_acc_stop_in & noc6_stop_in; + noc6_stop_in_s <= noc6_acc_stop_in & noc6_stop_in; noc6_stop_out <= noc6_stop_out_s(3 downto 0); noc6_acc_stop_out <= noc6_stop_out_s(4); noc6_data_void_in_s <= noc6_acc_data_void_in & noc6_data_void_in; noc6_data_void_out <= noc6_data_void_out_s(3 downto 0); noc6_acc_data_void_out <= noc6_data_void_out_s(4); - sync_noc_set_acc: sync_noc_set - generic map ( - PORTS => ROUTER_PORTS, - HAS_SYNC => HAS_SYNC) - port map ( - clk => sys_clk, - clk_tile => dco_clk, - rst => noc_rstn, - rst_tile => dco_rstn, - CONST_local_x => this_local_x, - CONST_local_y => this_local_y, - noc1_data_n_in => noc1_data_n_in, - noc1_data_s_in => noc1_data_s_in, - noc1_data_w_in => noc1_data_w_in, - noc1_data_e_in => noc1_data_e_in, - noc1_input_port => noc1_input_port, - noc1_data_void_in => noc1_data_void_in_s, - noc1_stop_in => noc1_stop_in_s, - noc1_data_n_out => noc1_data_n_out, - noc1_data_s_out => noc1_data_s_out, - noc1_data_w_out => noc1_data_w_out, - noc1_data_e_out => noc1_data_e_out, - noc1_output_port => noc1_output_port, - noc1_data_void_out => noc1_data_void_out_s, - noc1_stop_out => noc1_stop_out_s, - noc2_data_n_in => noc2_data_n_in, - noc2_data_s_in => noc2_data_s_in, - noc2_data_w_in => noc2_data_w_in, - noc2_data_e_in => noc2_data_e_in, - noc2_input_port => noc2_input_port, - noc2_data_void_in => noc2_data_void_in_s, - noc2_stop_in => noc2_stop_in_s, - noc2_data_n_out => noc2_data_n_out, - noc2_data_s_out => noc2_data_s_out, - noc2_data_w_out => noc2_data_w_out, - noc2_data_e_out => noc2_data_e_out, - noc2_output_port => noc2_output_port, - noc2_data_void_out => noc2_data_void_out_s, - noc2_stop_out => noc2_stop_out_s, - noc3_data_n_in => noc3_data_n_in, - noc3_data_s_in => noc3_data_s_in, - noc3_data_w_in => noc3_data_w_in, - noc3_data_e_in => noc3_data_e_in, - noc3_input_port => noc3_input_port, - noc3_data_void_in => noc3_data_void_in_s, - noc3_stop_in => noc3_stop_in_s, - noc3_data_n_out => noc3_data_n_out, - noc3_data_s_out => noc3_data_s_out, - noc3_data_w_out => noc3_data_w_out, - noc3_data_e_out => noc3_data_e_out, - noc3_output_port => noc3_output_port, - noc3_data_void_out => noc3_data_void_out_s, - noc3_stop_out => noc3_stop_out_s, - noc4_data_n_in => noc4_data_n_in, - noc4_data_s_in => noc4_data_s_in, - noc4_data_w_in => noc4_data_w_in, - noc4_data_e_in => noc4_data_e_in, - noc4_input_port => noc4_input_port, - noc4_data_void_in => noc4_data_void_in_s, - noc4_stop_in => noc4_stop_in_s, - noc4_data_n_out => noc4_data_n_out, - noc4_data_s_out => noc4_data_s_out, - noc4_data_w_out => noc4_data_w_out, - noc4_data_e_out => noc4_data_e_out, - noc4_output_port => noc4_output_port, - noc4_data_void_out => noc4_data_void_out_s, - noc4_stop_out => noc4_stop_out_s, - noc5_data_n_in => noc5_data_n_in, - noc5_data_s_in => noc5_data_s_in, - noc5_data_w_in => noc5_data_w_in, - noc5_data_e_in => noc5_data_e_in, - noc5_input_port => noc5_input_port, - noc5_data_void_in => noc5_data_void_in_s, - noc5_stop_in => noc5_stop_in_s, - noc5_data_n_out => noc5_data_n_out, - noc5_data_s_out => noc5_data_s_out, - noc5_data_w_out => noc5_data_w_out, - noc5_data_e_out => noc5_data_e_out, - noc5_output_port => noc5_output_port, - noc5_data_void_out => noc5_data_void_out_s, - noc5_stop_out => noc5_stop_out_s, - noc6_data_n_in => noc6_data_n_in, - noc6_data_s_in => noc6_data_s_in, - noc6_data_w_in => noc6_data_w_in, - noc6_data_e_in => noc6_data_e_in, - noc6_input_port => noc6_input_port, - noc6_data_void_in => noc6_data_void_in_s, - noc6_stop_in => noc6_stop_in_s, - noc6_data_n_out => noc6_data_n_out, - noc6_data_s_out => noc6_data_s_out, - noc6_data_w_out => noc6_data_w_out, - noc6_data_e_out => noc6_data_e_out, - noc6_output_port => noc6_output_port, - noc6_data_void_out => noc6_data_void_out_s, - noc6_stop_out => noc6_stop_out_s, - noc1_mon_noc_vec => noc1_mon_noc_vec_int, - noc2_mon_noc_vec => noc2_mon_noc_vec_int, - noc3_mon_noc_vec => noc3_mon_noc_vec_int, - noc4_mon_noc_vec => noc4_mon_noc_vec_int, - noc5_mon_noc_vec => noc5_mon_noc_vec_int, - noc6_mon_noc_vec => noc6_mon_noc_vec_int - ); + sync_noc_set_acc : component sync_noc_set + generic map ( + ports => ROUTER_PORTS, + has_sync => HAS_SYNC + ) + port map ( + clk => sys_clk, + clk_tile => dco_clk, + rst => noc_rstn, + rst_tile => dco_rstn, + const_local_x => this_local_x, + const_local_y => this_local_y, + noc1_data_n_in => noc1_data_n_in, + noc1_data_s_in => noc1_data_s_in, + noc1_data_w_in => noc1_data_w_in, + noc1_data_e_in => noc1_data_e_in, + noc1_input_port => noc1_input_port, + noc1_data_void_in => noc1_data_void_in_s, + noc1_stop_in => noc1_stop_in_s, + noc1_data_n_out => noc1_data_n_out, + noc1_data_s_out => noc1_data_s_out, + noc1_data_w_out => noc1_data_w_out, + noc1_data_e_out => noc1_data_e_out, + noc1_output_port => noc1_output_port, + noc1_data_void_out => noc1_data_void_out_s, + noc1_stop_out => noc1_stop_out_s, + noc2_data_n_in => noc2_data_n_in, + noc2_data_s_in => noc2_data_s_in, + noc2_data_w_in => noc2_data_w_in, + noc2_data_e_in => noc2_data_e_in, + noc2_input_port => noc2_input_port, + noc2_data_void_in => noc2_data_void_in_s, + noc2_stop_in => noc2_stop_in_s, + noc2_data_n_out => noc2_data_n_out, + noc2_data_s_out => noc2_data_s_out, + noc2_data_w_out => noc2_data_w_out, + noc2_data_e_out => noc2_data_e_out, + noc2_output_port => noc2_output_port, + noc2_data_void_out => noc2_data_void_out_s, + noc2_stop_out => noc2_stop_out_s, + noc3_data_n_in => noc3_data_n_in, + noc3_data_s_in => noc3_data_s_in, + noc3_data_w_in => noc3_data_w_in, + noc3_data_e_in => noc3_data_e_in, + noc3_input_port => noc3_input_port, + noc3_data_void_in => noc3_data_void_in_s, + noc3_stop_in => noc3_stop_in_s, + noc3_data_n_out => noc3_data_n_out, + noc3_data_s_out => noc3_data_s_out, + noc3_data_w_out => noc3_data_w_out, + noc3_data_e_out => noc3_data_e_out, + noc3_output_port => noc3_output_port, + noc3_data_void_out => noc3_data_void_out_s, + noc3_stop_out => noc3_stop_out_s, + noc4_data_n_in => noc4_data_n_in, + noc4_data_s_in => noc4_data_s_in, + noc4_data_w_in => noc4_data_w_in, + noc4_data_e_in => noc4_data_e_in, + noc4_input_port => noc4_input_port, + noc4_data_void_in => noc4_data_void_in_s, + noc4_stop_in => noc4_stop_in_s, + noc4_data_n_out => noc4_data_n_out, + noc4_data_s_out => noc4_data_s_out, + noc4_data_w_out => noc4_data_w_out, + noc4_data_e_out => noc4_data_e_out, + noc4_output_port => noc4_output_port, + noc4_data_void_out => noc4_data_void_out_s, + noc4_stop_out => noc4_stop_out_s, + noc5_data_n_in => noc5_data_n_in, + noc5_data_s_in => noc5_data_s_in, + noc5_data_w_in => noc5_data_w_in, + noc5_data_e_in => noc5_data_e_in, + noc5_input_port => noc5_input_port, + noc5_data_void_in => noc5_data_void_in_s, + noc5_stop_in => noc5_stop_in_s, + noc5_data_n_out => noc5_data_n_out, + noc5_data_s_out => noc5_data_s_out, + noc5_data_w_out => noc5_data_w_out, + noc5_data_e_out => noc5_data_e_out, + noc5_output_port => noc5_output_port, + noc5_data_void_out => noc5_data_void_out_s, + noc5_stop_out => noc5_stop_out_s, + noc6_data_n_in => noc6_data_n_in, + noc6_data_s_in => noc6_data_s_in, + noc6_data_w_in => noc6_data_w_in, + noc6_data_e_in => noc6_data_e_in, + noc6_input_port => noc6_input_port, + noc6_data_void_in => noc6_data_void_in_s, + noc6_stop_in => noc6_stop_in_s, + noc6_data_n_out => noc6_data_n_out, + noc6_data_s_out => noc6_data_s_out, + noc6_data_w_out => noc6_data_w_out, + noc6_data_e_out => noc6_data_e_out, + noc6_output_port => noc6_output_port, + noc6_data_void_out => noc6_data_void_out_s, + noc6_stop_out => noc6_stop_out_s, + noc1_mon_noc_vec => noc1_mon_noc_vec_int, + noc2_mon_noc_vec => noc2_mon_noc_vec_int, + noc3_mon_noc_vec => noc3_mon_noc_vec_int, + noc4_mon_noc_vec => noc4_mon_noc_vec_int, + noc5_mon_noc_vec => noc5_mon_noc_vec_int, + noc6_mon_noc_vec => noc6_mon_noc_vec_int + ); - tile_acc_1: tile_acc + tile_acc_1 : component tile_acc generic map ( this_hls_conf => this_hls_conf, this_device => this_device, this_irq_type => this_irq_type, this_has_l2 => this_has_l2, - this_has_dvfs => 0, -- no DVFS controller + this_has_dvfs => 0, this_has_pll => 0, - this_has_dco => this_has_dco, -- use DCO - this_extra_clk_buf => 0) + this_has_dco => this_has_dco, + this_extra_clk_buf => 0 + ) port map ( - raw_rstn => raw_rstn, - tile_rst => tile_rst, - refclk => ext_clk, - pllbypass => ext_clk_sel_default, --ext_clk_sel, - pllclk => clk_div, - dco_clk => dco_clk, - dco_rstn => dco_rstn, - pad_cfg => pad_cfg, - local_x => this_local_x, - local_y => this_local_y, + raw_rstn => raw_rstn, + tile_rst => tile_rst, + refclk => ext_clk, + pllbypass => ext_clk_sel_default, + pllclk => clk_div, + dco_clk => dco_clk, + dco_rstn => dco_rstn, + pad_cfg => pad_cfg, + local_x => this_local_x, + local_y => this_local_y, test1_output_port => test1_output_port_s, test1_data_void_out => test1_data_void_out_s, test1_stop_in => test1_stop_out_s, @@ -667,15 +686,16 @@ begin test6_input_port => test6_input_port_s, test6_data_void_in => test6_data_void_in_s, test6_stop_out => test6_stop_in_s, - noc1_mon_noc_vec => noc1_mon_noc_vec_int, - noc2_mon_noc_vec => noc2_mon_noc_vec_int, - noc3_mon_noc_vec => noc3_mon_noc_vec_int, - noc4_mon_noc_vec => noc4_mon_noc_vec_int, - noc5_mon_noc_vec => noc5_mon_noc_vec_int, - noc6_mon_noc_vec => noc6_mon_noc_vec_int, - mon_dvfs_in => monitor_dvfs_none, - mon_acc => open, - mon_cache => open, - mon_dvfs => open - ); -end; + noc1_mon_noc_vec => noc1_mon_noc_vec_int, + noc2_mon_noc_vec => noc2_mon_noc_vec_int, + noc3_mon_noc_vec => noc3_mon_noc_vec_int, + noc4_mon_noc_vec => noc4_mon_noc_vec_int, + noc5_mon_noc_vec => noc5_mon_noc_vec_int, + noc6_mon_noc_vec => noc6_mon_noc_vec_int, + mon_dvfs_in => monitor_dvfs_none, + mon_acc => open, + mon_cache => open, + mon_dvfs => open + ); + +end architecture rtl; diff --git a/rtl/tiles/esp.vhd b/rtl/tiles/esp.vhd index 0f6acef4f4..e123a3a8b5 100644 --- a/rtl/tiles/esp.vhd +++ b/rtl/tiles/esp.vhd @@ -2,216 +2,230 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_misc.all; -use work.esp_global.all; -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; -use work.gencomp.all; -use work.leon3.all; -use work.net.all; --- pragma translate_off -use work.sim.all; + use ieee.std_logic_1164.all; + use ieee.std_logic_misc.all; + use work.esp_global.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.leon3.all; + use work.net.all; + -- pragma translate_off + use work.sim.all; + library unisim; -use unisim.all; --- pragma translate_on -use work.monitor_pkg.all; -use work.sldacc.all; -use work.tile.all; -use work.nocpackage.all; -use work.cachepackage.all; -use work.coretypes.all; -use work.grlib_config.all; -use work.socmap.all; -use work.tiles_pkg.all; -use work.tiles_fpga_pkg.all; + use unisim.all; + -- pragma translate_on + use work.monitor_pkg.all; + use work.sldacc.all; + use work.tile.all; + use work.nocpackage.all; + use work.cachepackage.all; + use work.coretypes.all; + use work.grlib_config.all; + use work.socmap.all; + use work.tiles_pkg.all; + use work.tiles_fpga_pkg.all; entity esp is generic ( - SIMULATION : boolean := false); + simulation : boolean := false + ); port ( - rst : in std_logic; - sys_clk : in std_logic_vector(0 to MEM_ID_RANGE_MSB); - refclk : in std_logic; - pllbypass : in std_logic_vector(CFG_TILES_NUM - 1 downto 0); - uart_rxd : in std_logic; -- UART1_RX (u1i.rxd) - uart_txd : out std_logic; -- UART1_TX (u1o.txd) - uart_ctsn : in std_logic; -- UART1_RTSN (u1i.ctsn) - uart_rtsn : out std_logic; -- UART1_RTSN (u1o.rtsn) - cpuerr : out std_logic; - ddr_ahbsi : out ahb_slv_in_vector_type(0 to MEM_ID_RANGE_MSB); - ddr_ahbso : in ahb_slv_out_vector_type(0 to MEM_ID_RANGE_MSB); - eth0_apbi : out apb_slv_in_type; - eth0_apbo : in apb_slv_out_type; - sgmii0_apbi : out apb_slv_in_type; - sgmii0_apbo : in apb_slv_out_type; - eth0_ahbmi : out ahb_mst_in_type; - eth0_ahbmo : in ahb_mst_out_type; - edcl_ahbmo : in ahb_mst_out_type; - dvi_apbi : out apb_slv_in_type; - dvi_apbo : in apb_slv_out_type; - dvi_ahbmi : out ahb_mst_in_type; - dvi_ahbmo : in ahb_mst_out_type; - mon_noc : out monitor_noc_matrix(1 to 6, 0 to CFG_TILES_NUM-1); - mon_acc : out monitor_acc_vector(0 to relu(accelerators_num-1)); - mon_mem : out monitor_mem_vector(0 to CFG_NMEM_TILE + CFG_NSLM_TILE + CFG_NSLMDDR_TILE - 1); - mon_l2 : out monitor_cache_vector(0 to relu(CFG_NL2 - 1)); - mon_llc : out monitor_cache_vector(0 to relu(CFG_NLLC - 1)); - mon_dvfs : out monitor_dvfs_vector(0 to CFG_TILES_NUM-1)); -end; - + rst : in std_logic; + sys_clk : in std_logic_vector(0 to MEM_ID_RANGE_MSB); + refclk : in std_logic; + pllbypass : in std_logic_vector(CFG_TILES_NUM - 1 downto 0); + uart_rxd : in std_logic; -- UART1_RX (u1i.rxd) + uart_txd : out std_logic; -- UART1_TX (u1o.txd) + uart_ctsn : in std_logic; -- UART1_RTSN (u1i.ctsn) + uart_rtsn : out std_logic; -- UART1_RTSN (u1o.rtsn) + cpuerr : out std_logic; + ddr_ahbsi : out ahb_slv_in_vector_type(0 to MEM_ID_RANGE_MSB); + ddr_ahbso : in ahb_slv_out_vector_type(0 to MEM_ID_RANGE_MSB); + eth0_apbi : out apb_slv_in_type; + eth0_apbo : in apb_slv_out_type; + sgmii0_apbi : out apb_slv_in_type; + sgmii0_apbo : in apb_slv_out_type; + eth0_ahbmi : out ahb_mst_in_type; + eth0_ahbmo : in ahb_mst_out_type; + edcl_ahbmo : in ahb_mst_out_type; + dvi_apbi : out apb_slv_in_type; + dvi_apbo : in apb_slv_out_type; + dvi_ahbmi : out ahb_mst_in_type; + dvi_ahbmo : in ahb_mst_out_type; + mon_noc : out monitor_noc_matrix(1 to 6, 0 to CFG_TILES_NUM - 1); + mon_acc : out monitor_acc_vector(0 to relu(accelerators_num - 1)); + mon_mem : out monitor_mem_vector(0 to CFG_NMEM_TILE + CFG_NSLM_TILE + CFG_NSLMDDR_TILE - 1); + mon_l2 : out monitor_cache_vector(0 to relu(CFG_NL2 - 1)); + mon_llc : out monitor_cache_vector(0 to relu(CFG_NLLC - 1)); + mon_dvfs : out monitor_dvfs_vector(0 to CFG_TILES_NUM - 1) + ); +end entity esp; architecture rtl of esp is + constant NOCS_NUM : integer := 6; + + signal clk_tile : std_logic_vector(CFG_TILES_NUM - 1 downto 0); + + type noc_ctrl_matrix is array (1 to NOCS_NUM) of std_logic_vector(CFG_TILES_NUM - 1 downto 0); + + type handshake_vec is array (CFG_TILES_NUM - 1 downto 0) of std_logic_vector(3 downto 0); + + signal rst_int : std_logic; + signal sys_clk_int : std_logic_vector(0 to MEM_ID_RANGE_MSB); + signal refclk_int : std_logic_vector(CFG_TILES_NUM - 1 downto 0); + signal pllbypass_int : std_logic_vector(CFG_TILES_NUM - 1 downto 0); + signal cpuerr_vec : std_logic_vector(0 to CFG_NCPU_TILE - 1); + + type monitor_noc_cast_vector is array (1 to NOCS_NUM) of monitor_noc_vector(0 to CFG_TILES_NUM - 1); + + signal mon_noc_vec : monitor_noc_cast_vector; + signal mon_dvfs_out : monitor_dvfs_vector(0 to CFG_TILES_NUM - 1); + signal mon_dvfs_domain : monitor_dvfs_vector(0 to CFG_TILES_NUM - 1); -constant nocs_num : integer := 6; - -signal clk_tile : std_logic_vector(CFG_TILES_NUM-1 downto 0); -type noc_ctrl_matrix is array (1 to nocs_num) of std_logic_vector(CFG_TILES_NUM-1 downto 0); -type handshake_vec is array (CFG_TILES_NUM-1 downto 0) of std_logic_vector(3 downto 0); - -signal rst_int : std_logic; -signal sys_clk_int : std_logic_vector(0 to MEM_ID_RANGE_MSB); -signal refclk_int : std_logic_vector(CFG_TILES_NUM -1 downto 0); -signal pllbypass_int : std_logic_vector(CFG_TILES_NUM - 1 downto 0); -signal cpuerr_vec : std_logic_vector(0 to CFG_NCPU_TILE-1); - -type monitor_noc_cast_vector is array (1 to nocs_num) of monitor_noc_vector(0 to CFG_TILES_NUM-1); -signal mon_noc_vec : monitor_noc_cast_vector; -signal mon_dvfs_out : monitor_dvfs_vector(0 to CFG_TILES_NUM-1); -signal mon_dvfs_domain : monitor_dvfs_vector(0 to CFG_TILES_NUM-1); - -signal mon_l2_int : monitor_cache_vector(0 to CFG_TILES_NUM-1); -signal mon_llc_int : monitor_cache_vector(0 to CFG_TILES_NUM-1); - --- NOC Signals -signal noc1_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc1_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc1_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc1_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc1_data_void_in : handshake_vec; -signal noc1_stop_in : handshake_vec; -signal noc1_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc1_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc1_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc1_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc1_data_void_out : handshake_vec; -signal noc1_stop_out : handshake_vec; -signal noc2_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc2_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc2_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc2_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc2_data_void_in : handshake_vec; -signal noc2_stop_in : handshake_vec; -signal noc2_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc2_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc2_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc2_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc2_data_void_out : handshake_vec; -signal noc2_stop_out : handshake_vec; -signal noc3_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc3_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc3_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc3_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc3_data_void_in : handshake_vec; -signal noc3_stop_in : handshake_vec; -signal noc3_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc3_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc3_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc3_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc3_data_void_out : handshake_vec; -signal noc3_stop_out : handshake_vec; -signal noc4_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc4_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc4_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc4_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc4_data_void_in : handshake_vec; -signal noc4_stop_in : handshake_vec; -signal noc4_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc4_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc4_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc4_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc4_data_void_out : handshake_vec; -signal noc4_stop_out : handshake_vec; -signal noc5_data_n_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc5_data_s_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc5_data_w_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc5_data_e_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc5_data_void_in : handshake_vec; -signal noc5_stop_in : handshake_vec; -signal noc5_data_n_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc5_data_s_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc5_data_w_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc5_data_e_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc5_data_void_out : handshake_vec; -signal noc5_stop_out : handshake_vec; -signal noc6_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc6_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc6_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc6_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc6_data_void_in : handshake_vec; -signal noc6_stop_in : handshake_vec; -signal noc6_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc6_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc6_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc6_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); -signal noc6_data_void_out : handshake_vec; -signal noc6_stop_out : handshake_vec; + signal mon_l2_int : monitor_cache_vector(0 to CFG_TILES_NUM - 1); + signal mon_llc_int : monitor_cache_vector(0 to CFG_TILES_NUM - 1); + -- NOC Signals + signal noc1_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_void_in : handshake_vec; + signal noc1_stop_in : handshake_vec; + signal noc1_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_void_out : handshake_vec; + signal noc1_stop_out : handshake_vec; + signal noc2_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_void_in : handshake_vec; + signal noc2_stop_in : handshake_vec; + signal noc2_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_void_out : handshake_vec; + signal noc2_stop_out : handshake_vec; + signal noc3_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_void_in : handshake_vec; + signal noc3_stop_in : handshake_vec; + signal noc3_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_void_out : handshake_vec; + signal noc3_stop_out : handshake_vec; + signal noc4_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_void_in : handshake_vec; + signal noc4_stop_in : handshake_vec; + signal noc4_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_void_out : handshake_vec; + signal noc4_stop_out : handshake_vec; + signal noc5_data_n_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_s_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_w_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_e_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_void_in : handshake_vec; + signal noc5_stop_in : handshake_vec; + signal noc5_data_n_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_s_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_w_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_e_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_void_out : handshake_vec; + signal noc5_stop_out : handshake_vec; + signal noc6_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_void_in : handshake_vec; + signal noc6_stop_in : handshake_vec; + signal noc6_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_void_out : handshake_vec; + signal noc6_stop_out : handshake_vec; begin rst_int <= rst; - clk_int_gen: for i in 0 to MEM_ID_RANGE_MSB generate + + clk_int_gen : for i in 0 to MEM_ID_RANGE_MSB generate sys_clk_int(i) <= sys_clk(i); end generate clk_int_gen; + pllbypass_int <= pllbypass; cpuerr <= cpuerr_vec(0); - ----------------------------------------------------------------------------- -- DVFS domain probes steering ----------------------------------------------------------------------------- - domain_in_gen: for i in 0 to CFG_TILES_NUM-1 generate - mon_dvfs_domain(i).clk <= '0'; + + domain_in_gen : for i in 0 to CFG_TILES_NUM - 1 generate + mon_dvfs_domain(i).clk <= '0'; mon_dvfs_domain(i).transient <= mon_dvfs_out(tile_domain_master(i)).transient; - mon_dvfs_domain(i).vf <= mon_dvfs_out(tile_domain_master(i)).vf; + mon_dvfs_domain(i).vf <= mon_dvfs_out(tile_domain_master(i)).vf; - no_domain_master: if tile_domain(i) /= 0 and tile_has_pll(i) = 0 generate + no_domain_master : if tile_domain(i) /= 0 and tile_has_pll(i) = 0 generate mon_dvfs_domain(i).acc_idle <= mon_dvfs_domain(tile_domain_master(i)).acc_idle; - mon_dvfs_domain(i).traffic <= mon_dvfs_domain(tile_domain_master(i)).traffic; - mon_dvfs_domain(i).burst <= mon_dvfs_domain(tile_domain_master(i)).burst; - refclk_int(i) <= clk_tile(tile_domain_master(i)); + mon_dvfs_domain(i).traffic <= mon_dvfs_domain(tile_domain_master(i)).traffic; + mon_dvfs_domain(i).burst <= mon_dvfs_domain(tile_domain_master(i)).burst; + refclk_int(i) <= clk_tile(tile_domain_master(i)); end generate no_domain_master; - domain_master_gen: if tile_domain(i) = 0 or tile_has_pll(i) /= 0 generate + domain_master_gen : if tile_domain(i) = 0 or tile_has_pll(i) /= 0 generate refclk_int(i) <= refclk; end generate domain_master_gen; end generate domain_in_gen; - domain_probes_gen: for k in 1 to domains_num-1 generate + domain_probes_gen : for k in 1 to domains_num - 1 generate -- DVFS masters need info from slave DVFS tiles - process (mon_dvfs_out) + process (mon_dvfs_out) is + variable mon_dvfs_or : monitor_dvfs_type; - begin -- process + + begin -- process + mon_dvfs_or.acc_idle := '1'; - mon_dvfs_or.traffic := '0'; - mon_dvfs_or.burst := '0'; - for i in 0 to CFG_TILES_NUM-1 loop - if tile_domain(i) = k then + mon_dvfs_or.traffic := '0'; + mon_dvfs_or.burst := '0'; + + for i in 0 to CFG_TILES_NUM - 1 loop + + if (tile_domain(i) = k) then mon_dvfs_or.acc_idle := mon_dvfs_or.acc_idle and mon_dvfs_out(i).acc_idle; - mon_dvfs_or.traffic := mon_dvfs_or.traffic or mon_dvfs_out(i).traffic; - mon_dvfs_or.burst := mon_dvfs_or.burst or mon_dvfs_out(i).burst; + mon_dvfs_or.traffic := mon_dvfs_or.traffic or mon_dvfs_out(i).traffic; + mon_dvfs_or.burst := mon_dvfs_or.burst or mon_dvfs_out(i).burst; end if; - end loop; -- i + + end loop; -- i + mon_dvfs_domain(domain_master_tile(k)).acc_idle <= mon_dvfs_or.acc_idle; - mon_dvfs_domain(domain_master_tile(k)).traffic <= mon_dvfs_or.traffic; - mon_dvfs_domain(domain_master_tile(k)).burst <= mon_dvfs_or.burst; + mon_dvfs_domain(domain_master_tile(k)).traffic <= mon_dvfs_or.traffic; + mon_dvfs_domain(domain_master_tile(k)).burst <= mon_dvfs_or.burst; + end process; + end generate domain_probes_gen; mon_dvfs <= mon_dvfs_out; @@ -220,809 +234,825 @@ begin -- NOC CONNECTIONS ----------------------------------------------------------------------------- + meshgen_y : for i in 0 to CFG_YLEN - 1 generate + meshgen_x : for j in 0 to CFG_XLEN - 1 generate - - - - meshgen_y: for i in 0 to CFG_YLEN-1 generate - meshgen_x: for j in 0 to CFG_XLEN-1 generate - - y_0: if (i=0) generate + y_0 : if (i=0) generate -- North port is unconnected - noc1_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc2_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc3_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc4_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc5_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc6_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(0) <= '0'; + noc1_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc2_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc3_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc4_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc5_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc6_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(0) <= '0'; end generate y_0; - y_non_0: if (i /= 0) generate + y_non_0 : if (i /= 0) generate -- North port is connected - noc1_data_n_in(i*CFG_XLEN + j) <= noc1_data_s_out((i-1)*CFG_XLEN + j); - noc1_data_void_in(i*CFG_XLEN + j)(0) <= noc1_data_void_out((i-1)*CFG_XLEN + j)(1); - noc1_stop_in(i*CFG_XLEN + j)(0) <= noc1_stop_out((i-1)*CFG_XLEN + j)(1); - noc2_data_n_in(i*CFG_XLEN + j) <= noc2_data_s_out((i-1)*CFG_XLEN + j); - noc2_data_void_in(i*CFG_XLEN + j)(0) <= noc2_data_void_out((i-1)*CFG_XLEN + j)(1); - noc2_stop_in(i*CFG_XLEN + j)(0) <= noc2_stop_out((i-1)*CFG_XLEN + j)(1); - noc3_data_n_in(i*CFG_XLEN + j) <= noc3_data_s_out((i-1)*CFG_XLEN + j); - noc3_data_void_in(i*CFG_XLEN + j)(0) <= noc3_data_void_out((i-1)*CFG_XLEN + j)(1); - noc3_stop_in(i*CFG_XLEN + j)(0) <= noc3_stop_out((i-1)*CFG_XLEN + j)(1); - noc4_data_n_in(i*CFG_XLEN + j) <= noc4_data_s_out((i-1)*CFG_XLEN + j); - noc4_data_void_in(i*CFG_XLEN + j)(0) <= noc4_data_void_out((i-1)*CFG_XLEN + j)(1); - noc4_stop_in(i*CFG_XLEN + j)(0) <= noc4_stop_out((i-1)*CFG_XLEN + j)(1); - noc5_data_n_in(i*CFG_XLEN + j) <= noc5_data_s_out((i-1)*CFG_XLEN + j); - noc5_data_void_in(i*CFG_XLEN + j)(0) <= noc5_data_void_out((i-1)*CFG_XLEN + j)(1); - noc5_stop_in(i*CFG_XLEN + j)(0) <= noc5_stop_out((i-1)*CFG_XLEN + j)(1); - noc6_data_n_in(i*CFG_XLEN + j) <= noc6_data_s_out((i-1)*CFG_XLEN + j); - noc6_data_void_in(i*CFG_XLEN + j)(0) <= noc6_data_void_out((i-1)*CFG_XLEN + j)(1); - noc6_stop_in(i*CFG_XLEN + j)(0) <= noc6_stop_out((i-1)*CFG_XLEN + j)(1); + noc1_data_n_in(i * CFG_XLEN + j) <= noc1_data_s_out((i - 1) * CFG_XLEN + j); + noc1_data_void_in(i * CFG_XLEN + j)(0) <= noc1_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc1_stop_in(i * CFG_XLEN + j)(0) <= noc1_stop_out((i - 1) * CFG_XLEN + j)(1); + noc2_data_n_in(i * CFG_XLEN + j) <= noc2_data_s_out((i - 1) * CFG_XLEN + j); + noc2_data_void_in(i * CFG_XLEN + j)(0) <= noc2_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc2_stop_in(i * CFG_XLEN + j)(0) <= noc2_stop_out((i - 1) * CFG_XLEN + j)(1); + noc3_data_n_in(i * CFG_XLEN + j) <= noc3_data_s_out((i - 1) * CFG_XLEN + j); + noc3_data_void_in(i * CFG_XLEN + j)(0) <= noc3_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc3_stop_in(i * CFG_XLEN + j)(0) <= noc3_stop_out((i - 1) * CFG_XLEN + j)(1); + noc4_data_n_in(i * CFG_XLEN + j) <= noc4_data_s_out((i - 1) * CFG_XLEN + j); + noc4_data_void_in(i * CFG_XLEN + j)(0) <= noc4_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc4_stop_in(i * CFG_XLEN + j)(0) <= noc4_stop_out((i - 1) * CFG_XLEN + j)(1); + noc5_data_n_in(i * CFG_XLEN + j) <= noc5_data_s_out((i - 1) * CFG_XLEN + j); + noc5_data_void_in(i * CFG_XLEN + j)(0) <= noc5_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc5_stop_in(i * CFG_XLEN + j)(0) <= noc5_stop_out((i - 1) * CFG_XLEN + j)(1); + noc6_data_n_in(i * CFG_XLEN + j) <= noc6_data_s_out((i - 1) * CFG_XLEN + j); + noc6_data_void_in(i * CFG_XLEN + j)(0) <= noc6_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc6_stop_in(i * CFG_XLEN + j)(0) <= noc6_stop_out((i - 1) * CFG_XLEN + j)(1); end generate y_non_0; - y_YLEN: if (i=CFG_YLEN-1) generate + y_ylen : if (i=CFG_YLEN - 1) generate -- South port is unconnected - noc1_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc2_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc3_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc4_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc5_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc6_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(1) <= '0'; - end generate y_YLEN; - - y_non_YLEN: if (i /= CFG_YLEN-1) generate + noc1_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc2_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc3_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc4_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc5_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc6_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(1) <= '0'; + end generate y_ylen; + + y_non_ylen : if (i /= CFG_YLEN - 1) generate -- south port is connected - noc1_data_s_in(i*CFG_XLEN + j) <= noc1_data_n_out((i+1)*CFG_XLEN + j); - noc1_data_void_in(i*CFG_XLEN + j)(1) <= noc1_data_void_out((i+1)*CFG_XLEN + j)(0); - noc1_stop_in(i*CFG_XLEN + j)(1) <= noc1_stop_out((i+1)*CFG_XLEN + j)(0); - noc2_data_s_in(i*CFG_XLEN + j) <= noc2_data_n_out((i+1)*CFG_XLEN + j); - noc2_data_void_in(i*CFG_XLEN + j)(1) <= noc2_data_void_out((i+1)*CFG_XLEN + j)(0); - noc2_stop_in(i*CFG_XLEN + j)(1) <= noc2_stop_out((i+1)*CFG_XLEN + j)(0); - noc3_data_s_in(i*CFG_XLEN + j) <= noc3_data_n_out((i+1)*CFG_XLEN + j); - noc3_data_void_in(i*CFG_XLEN + j)(1) <= noc3_data_void_out((i+1)*CFG_XLEN + j)(0); - noc3_stop_in(i*CFG_XLEN + j)(1) <= noc3_stop_out((i+1)*CFG_XLEN + j)(0); - noc4_data_s_in(i*CFG_XLEN + j) <= noc4_data_n_out((i+1)*CFG_XLEN + j); - noc4_data_void_in(i*CFG_XLEN + j)(1) <= noc4_data_void_out((i+1)*CFG_XLEN + j)(0); - noc4_stop_in(i*CFG_XLEN + j)(1) <= noc4_stop_out((i+1)*CFG_XLEN + j)(0); - noc5_data_s_in(i*CFG_XLEN + j) <= noc5_data_n_out((i+1)*CFG_XLEN + j); - noc5_data_void_in(i*CFG_XLEN + j)(1) <= noc5_data_void_out((i+1)*CFG_XLEN + j)(0); - noc5_stop_in(i*CFG_XLEN + j)(1) <= noc5_stop_out((i+1)*CFG_XLEN + j)(0); - noc6_data_s_in(i*CFG_XLEN + j) <= noc6_data_n_out((i+1)*CFG_XLEN + j); - noc6_data_void_in(i*CFG_XLEN + j)(1) <= noc6_data_void_out((i+1)*CFG_XLEN + j)(0); - noc6_stop_in(i*CFG_XLEN + j)(1) <= noc6_stop_out((i+1)*CFG_XLEN + j)(0); - end generate y_non_YLEN; - - x_0: if (j=0) generate + noc1_data_s_in(i * CFG_XLEN + j) <= noc1_data_n_out((i + 1) * CFG_XLEN + j); + noc1_data_void_in(i * CFG_XLEN + j)(1) <= noc1_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc1_stop_in(i * CFG_XLEN + j)(1) <= noc1_stop_out((i + 1) * CFG_XLEN + j)(0); + noc2_data_s_in(i * CFG_XLEN + j) <= noc2_data_n_out((i + 1) * CFG_XLEN + j); + noc2_data_void_in(i * CFG_XLEN + j)(1) <= noc2_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc2_stop_in(i * CFG_XLEN + j)(1) <= noc2_stop_out((i + 1) * CFG_XLEN + j)(0); + noc3_data_s_in(i * CFG_XLEN + j) <= noc3_data_n_out((i + 1) * CFG_XLEN + j); + noc3_data_void_in(i * CFG_XLEN + j)(1) <= noc3_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc3_stop_in(i * CFG_XLEN + j)(1) <= noc3_stop_out((i + 1) * CFG_XLEN + j)(0); + noc4_data_s_in(i * CFG_XLEN + j) <= noc4_data_n_out((i + 1) * CFG_XLEN + j); + noc4_data_void_in(i * CFG_XLEN + j)(1) <= noc4_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc4_stop_in(i * CFG_XLEN + j)(1) <= noc4_stop_out((i + 1) * CFG_XLEN + j)(0); + noc5_data_s_in(i * CFG_XLEN + j) <= noc5_data_n_out((i + 1) * CFG_XLEN + j); + noc5_data_void_in(i * CFG_XLEN + j)(1) <= noc5_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc5_stop_in(i * CFG_XLEN + j)(1) <= noc5_stop_out((i + 1) * CFG_XLEN + j)(0); + noc6_data_s_in(i * CFG_XLEN + j) <= noc6_data_n_out((i + 1) * CFG_XLEN + j); + noc6_data_void_in(i * CFG_XLEN + j)(1) <= noc6_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc6_stop_in(i * CFG_XLEN + j)(1) <= noc6_stop_out((i + 1) * CFG_XLEN + j)(0); + end generate y_non_ylen; + + x_0 : if (j=0) generate -- West port is unconnected - noc1_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc2_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc3_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc4_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc5_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc6_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(2) <= '0'; + noc1_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc2_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc3_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc4_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc5_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc6_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(2) <= '0'; end generate x_0; - x_non_0: if (j /= 0) generate + x_non_0 : if (j /= 0) generate -- West port is connected - noc1_data_w_in(i*CFG_XLEN + j) <= noc1_data_e_out(i*CFG_XLEN + j - 1); - noc1_data_void_in(i*CFG_XLEN + j)(2) <= noc1_data_void_out(i*CFG_XLEN + j - 1)(3); - noc1_stop_in(i*CFG_XLEN + j)(2) <= noc1_stop_out(i*CFG_XLEN + j - 1)(3); - noc2_data_w_in(i*CFG_XLEN + j) <= noc2_data_e_out(i*CFG_XLEN + j - 1); - noc2_data_void_in(i*CFG_XLEN + j)(2) <= noc2_data_void_out(i*CFG_XLEN + j - 1)(3); - noc2_stop_in(i*CFG_XLEN + j)(2) <= noc2_stop_out(i*CFG_XLEN + j - 1)(3); - noc3_data_w_in(i*CFG_XLEN + j) <= noc3_data_e_out(i*CFG_XLEN + j - 1); - noc3_data_void_in(i*CFG_XLEN + j)(2) <= noc3_data_void_out(i*CFG_XLEN + j - 1)(3); - noc3_stop_in(i*CFG_XLEN + j)(2) <= noc3_stop_out(i*CFG_XLEN + j - 1)(3); - noc4_data_w_in(i*CFG_XLEN + j) <= noc4_data_e_out(i*CFG_XLEN + j - 1); - noc4_data_void_in(i*CFG_XLEN + j)(2) <= noc4_data_void_out(i*CFG_XLEN + j - 1)(3); - noc4_stop_in(i*CFG_XLEN + j)(2) <= noc4_stop_out(i*CFG_XLEN + j - 1)(3); - noc5_data_w_in(i*CFG_XLEN + j) <= noc5_data_e_out(i*CFG_XLEN + j - 1); - noc5_data_void_in(i*CFG_XLEN + j)(2) <= noc5_data_void_out(i*CFG_XLEN + j - 1)(3); - noc5_stop_in(i*CFG_XLEN + j)(2) <= noc5_stop_out(i*CFG_XLEN + j - 1)(3); - noc6_data_w_in(i*CFG_XLEN + j) <= noc6_data_e_out(i*CFG_XLEN + j - 1); - noc6_data_void_in(i*CFG_XLEN + j)(2) <= noc6_data_void_out(i*CFG_XLEN + j - 1)(3); - noc6_stop_in(i*CFG_XLEN + j)(2) <= noc6_stop_out(i*CFG_XLEN + j - 1)(3); + noc1_data_w_in(i * CFG_XLEN + j) <= noc1_data_e_out(i * CFG_XLEN + j - 1); + noc1_data_void_in(i * CFG_XLEN + j)(2) <= noc1_data_void_out(i * CFG_XLEN + j - 1)(3); + noc1_stop_in(i * CFG_XLEN + j)(2) <= noc1_stop_out(i * CFG_XLEN + j - 1)(3); + noc2_data_w_in(i * CFG_XLEN + j) <= noc2_data_e_out(i * CFG_XLEN + j - 1); + noc2_data_void_in(i * CFG_XLEN + j)(2) <= noc2_data_void_out(i * CFG_XLEN + j - 1)(3); + noc2_stop_in(i * CFG_XLEN + j)(2) <= noc2_stop_out(i * CFG_XLEN + j - 1)(3); + noc3_data_w_in(i * CFG_XLEN + j) <= noc3_data_e_out(i * CFG_XLEN + j - 1); + noc3_data_void_in(i * CFG_XLEN + j)(2) <= noc3_data_void_out(i * CFG_XLEN + j - 1)(3); + noc3_stop_in(i * CFG_XLEN + j)(2) <= noc3_stop_out(i * CFG_XLEN + j - 1)(3); + noc4_data_w_in(i * CFG_XLEN + j) <= noc4_data_e_out(i * CFG_XLEN + j - 1); + noc4_data_void_in(i * CFG_XLEN + j)(2) <= noc4_data_void_out(i * CFG_XLEN + j - 1)(3); + noc4_stop_in(i * CFG_XLEN + j)(2) <= noc4_stop_out(i * CFG_XLEN + j - 1)(3); + noc5_data_w_in(i * CFG_XLEN + j) <= noc5_data_e_out(i * CFG_XLEN + j - 1); + noc5_data_void_in(i * CFG_XLEN + j)(2) <= noc5_data_void_out(i * CFG_XLEN + j - 1)(3); + noc5_stop_in(i * CFG_XLEN + j)(2) <= noc5_stop_out(i * CFG_XLEN + j - 1)(3); + noc6_data_w_in(i * CFG_XLEN + j) <= noc6_data_e_out(i * CFG_XLEN + j - 1); + noc6_data_void_in(i * CFG_XLEN + j)(2) <= noc6_data_void_out(i * CFG_XLEN + j - 1)(3); + noc6_stop_in(i * CFG_XLEN + j)(2) <= noc6_stop_out(i * CFG_XLEN + j - 1)(3); end generate x_non_0; - x_XLEN: if (j=CFG_XLEN-1) generate + x_xlen : if (j=CFG_XLEN - 1) generate -- East port is unconnected - noc1_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc2_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc3_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc4_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc5_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc6_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(3) <= '0'; - end generate x_XLEN; - - x_non_XLEN: if (j /= CFG_XLEN-1) generate + noc1_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc2_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc3_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc4_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc5_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc6_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(3) <= '0'; + end generate x_xlen; + + x_non_xlen : if (j /= CFG_XLEN - 1) generate -- East port is connected - noc1_data_e_in(i*CFG_XLEN + j) <= noc1_data_w_out(i*CFG_XLEN + j + 1); - noc1_data_void_in(i*CFG_XLEN + j)(3) <= noc1_data_void_out(i*CFG_XLEN + j + 1)(2); - noc1_stop_in(i*CFG_XLEN + j)(3) <= noc1_stop_out(i*CFG_XLEN + j + 1)(2); - noc2_data_e_in(i*CFG_XLEN + j) <= noc2_data_w_out(i*CFG_XLEN + j + 1); - noc2_data_void_in(i*CFG_XLEN + j)(3) <= noc2_data_void_out(i*CFG_XLEN + j + 1)(2); - noc2_stop_in(i*CFG_XLEN + j)(3) <= noc2_stop_out(i*CFG_XLEN + j + 1)(2); - noc3_data_e_in(i*CFG_XLEN + j) <= noc3_data_w_out(i*CFG_XLEN + j + 1); - noc3_data_void_in(i*CFG_XLEN + j)(3) <= noc3_data_void_out(i*CFG_XLEN + j + 1)(2); - noc3_stop_in(i*CFG_XLEN + j)(3) <= noc3_stop_out(i*CFG_XLEN + j + 1)(2); - noc4_data_e_in(i*CFG_XLEN + j) <= noc4_data_w_out(i*CFG_XLEN + j + 1); - noc4_data_void_in(i*CFG_XLEN + j)(3) <= noc4_data_void_out(i*CFG_XLEN + j + 1)(2); - noc4_stop_in(i*CFG_XLEN + j)(3) <= noc4_stop_out(i*CFG_XLEN + j + 1)(2); - noc5_data_e_in(i*CFG_XLEN + j) <= noc5_data_w_out(i*CFG_XLEN + j + 1); - noc5_data_void_in(i*CFG_XLEN + j)(3) <= noc5_data_void_out(i*CFG_XLEN + j + 1)(2); - noc5_stop_in(i*CFG_XLEN + j)(3) <= noc5_stop_out(i*CFG_XLEN + j + 1)(2); - noc6_data_e_in(i*CFG_XLEN + j) <= noc6_data_w_out(i*CFG_XLEN + j + 1); - noc6_data_void_in(i*CFG_XLEN + j)(3) <= noc6_data_void_out(i*CFG_XLEN + j + 1)(2); - noc6_stop_in(i*CFG_XLEN + j)(3) <= noc6_stop_out(i*CFG_XLEN + j + 1)(2); - end generate x_non_XLEN; + noc1_data_e_in(i * CFG_XLEN + j) <= noc1_data_w_out(i * CFG_XLEN + j + 1); + noc1_data_void_in(i * CFG_XLEN + j)(3) <= noc1_data_void_out(i * CFG_XLEN + j + 1)(2); + noc1_stop_in(i * CFG_XLEN + j)(3) <= noc1_stop_out(i * CFG_XLEN + j + 1)(2); + noc2_data_e_in(i * CFG_XLEN + j) <= noc2_data_w_out(i * CFG_XLEN + j + 1); + noc2_data_void_in(i * CFG_XLEN + j)(3) <= noc2_data_void_out(i * CFG_XLEN + j + 1)(2); + noc2_stop_in(i * CFG_XLEN + j)(3) <= noc2_stop_out(i * CFG_XLEN + j + 1)(2); + noc3_data_e_in(i * CFG_XLEN + j) <= noc3_data_w_out(i * CFG_XLEN + j + 1); + noc3_data_void_in(i * CFG_XLEN + j)(3) <= noc3_data_void_out(i * CFG_XLEN + j + 1)(2); + noc3_stop_in(i * CFG_XLEN + j)(3) <= noc3_stop_out(i * CFG_XLEN + j + 1)(2); + noc4_data_e_in(i * CFG_XLEN + j) <= noc4_data_w_out(i * CFG_XLEN + j + 1); + noc4_data_void_in(i * CFG_XLEN + j)(3) <= noc4_data_void_out(i * CFG_XLEN + j + 1)(2); + noc4_stop_in(i * CFG_XLEN + j)(3) <= noc4_stop_out(i * CFG_XLEN + j + 1)(2); + noc5_data_e_in(i * CFG_XLEN + j) <= noc5_data_w_out(i * CFG_XLEN + j + 1); + noc5_data_void_in(i * CFG_XLEN + j)(3) <= noc5_data_void_out(i * CFG_XLEN + j + 1)(2); + noc5_stop_in(i * CFG_XLEN + j)(3) <= noc5_stop_out(i * CFG_XLEN + j + 1)(2); + noc6_data_e_in(i * CFG_XLEN + j) <= noc6_data_w_out(i * CFG_XLEN + j + 1); + noc6_data_void_in(i * CFG_XLEN + j)(3) <= noc6_data_void_out(i * CFG_XLEN + j + 1)(2); + noc6_stop_in(i * CFG_XLEN + j)(3) <= noc6_stop_out(i * CFG_XLEN + j + 1)(2); + end generate x_non_xlen; end generate meshgen_x; - end generate meshgen_y; + end generate meshgen_y; ----------------------------------------------------------------------------- -- TILES ----------------------------------------------------------------------------- - tiles_gen: for i in 0 to CFG_TILES_NUM - 1 generate - - empty_tile: if tile_type(i) = 0 generate - tile_empty_i: fpga_tile_empty - generic map ( - SIMULATION => SIMULATION, - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - HAS_SYNC => CFG_HAS_SYNC) - port map ( - raw_rstn => '0', - rst => rst, - clk => sys_clk_int(0), - refclk => '0', - pllbypass => '0', - pllclk => open, - sys_clk_int => sys_clk_int(0), - dco_clk => open, - -- Test interface - tdi => '0', - tdo => open, - tms => '0', - tclk => '0', - -- NOC - noc1_data_n_in => noc1_data_n_in(i), - noc1_data_s_in => noc1_data_s_in(i), - noc1_data_w_in => noc1_data_w_in(i), - noc1_data_e_in => noc1_data_e_in(i), - noc1_data_void_in => noc1_data_void_in(i), - noc1_stop_in => noc1_stop_in(i), - noc1_data_n_out => noc1_data_n_out(i), - noc1_data_s_out => noc1_data_s_out(i), - noc1_data_w_out => noc1_data_w_out(i), - noc1_data_e_out => noc1_data_e_out(i), - noc1_data_void_out => noc1_data_void_out(i), - noc1_stop_out => noc1_stop_out(i), - noc2_data_n_in => noc2_data_n_in(i), - noc2_data_s_in => noc2_data_s_in (i), - noc2_data_w_in => noc2_data_w_in(i), - noc2_data_e_in => noc2_data_e_in(i), - noc2_data_void_in => noc2_data_void_in(i), - noc2_stop_in => noc2_stop_in(i), - noc2_data_n_out => noc2_data_n_out(i), - noc2_data_s_out => noc2_data_s_out(i), - noc2_data_w_out => noc2_data_w_out(i), - noc2_data_e_out => noc2_data_e_out(i), - noc2_data_void_out => noc2_data_void_out(i), - noc2_stop_out => noc2_stop_out(i), - noc3_data_n_in => noc3_data_n_in(i), - noc3_data_s_in => noc3_data_s_in(i), - noc3_data_w_in => noc3_data_w_in(i), - noc3_data_e_in => noc3_data_e_in(i), - noc3_data_void_in => noc3_data_void_in(i), - noc3_stop_in => noc3_stop_in(i), - noc3_data_n_out => noc3_data_n_out(i), - noc3_data_s_out => noc3_data_s_out(i), - noc3_data_w_out => noc3_data_w_out(i), - noc3_data_e_out => noc3_data_e_out(i), - noc3_data_void_out => noc3_data_void_out(i), - noc3_stop_out => noc3_stop_out(i), - noc4_data_n_in => noc4_data_n_in(i), - noc4_data_s_in => noc4_data_s_in(i), - noc4_data_w_in => noc4_data_w_in(i), - noc4_data_e_in => noc4_data_e_in(i), - noc4_data_void_in => noc4_data_void_in(i), - noc4_stop_in => noc4_stop_in(i), - noc4_data_n_out => noc4_data_n_out(i), - noc4_data_s_out => noc4_data_s_out(i), - noc4_data_w_out => noc4_data_w_out(i), - noc4_data_e_out => noc4_data_e_out(i), - noc4_data_void_out => noc4_data_void_out(i), - noc4_stop_out => noc4_stop_out(i), - noc5_data_n_in => noc5_data_n_in(i), - noc5_data_s_in => noc5_data_s_in(i), - noc5_data_w_in => noc5_data_w_in(i), - noc5_data_e_in => noc5_data_e_in(i), - noc5_data_void_in => noc5_data_void_in(i), - noc5_stop_in => noc5_stop_in(i), - noc5_data_n_out => noc5_data_n_out(i), - noc5_data_s_out => noc5_data_s_out(i), - noc5_data_w_out => noc5_data_w_out(i), - noc5_data_e_out => noc5_data_e_out(i), - noc5_data_void_out => noc5_data_void_out(i), - noc5_stop_out => noc5_stop_out(i), - noc6_data_n_in => noc6_data_n_in(i), - noc6_data_s_in => noc6_data_s_in(i), - noc6_data_w_in => noc6_data_w_in(i), - noc6_data_e_in => noc6_data_e_in(i), - noc6_data_void_in => noc6_data_void_in(i), - noc6_stop_in => noc6_stop_in(i), - noc6_data_n_out => noc6_data_n_out(i), - noc6_data_s_out => noc6_data_s_out(i), - noc6_data_w_out => noc6_data_w_out(i), - noc6_data_e_out => noc6_data_e_out(i), - noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i), - noc1_mon_noc_vec => mon_noc_vec(1)(i), - noc2_mon_noc_vec => mon_noc_vec(2)(i), - noc3_mon_noc_vec => mon_noc_vec(3)(i), - noc4_mon_noc_vec => mon_noc_vec(4)(i), - noc5_mon_noc_vec => mon_noc_vec(5)(i), - noc6_mon_noc_vec => mon_noc_vec(6)(i), - mon_dvfs_out => mon_dvfs_out(i)); - clk_tile(i) <= refclk_int(i); + + tiles_gen : for i in 0 to CFG_TILES_NUM - 1 generate + + empty_tile : if tile_type(i) = 0 generate + + tile_empty_i : component fpga_tile_empty + generic map ( + simulation => SIMULATION, + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + has_sync => CFG_HAS_SYNC + ) + port map ( + raw_rstn => '0', + rst => rst, + clk => sys_clk_int(0), + refclk => '0', + pllbypass => '0', + pllclk => open, + sys_clk_int => sys_clk_int(0), + dco_clk => open, + -- Test interface + tdi => '0', + tdo => open, + tms => '0', + tclk => '0', + -- NOC + noc1_data_n_in => noc1_data_n_in(i), + noc1_data_s_in => noc1_data_s_in(i), + noc1_data_w_in => noc1_data_w_in(i), + noc1_data_e_in => noc1_data_e_in(i), + noc1_data_void_in => noc1_data_void_in(i), + noc1_stop_in => noc1_stop_in(i), + noc1_data_n_out => noc1_data_n_out(i), + noc1_data_s_out => noc1_data_s_out(i), + noc1_data_w_out => noc1_data_w_out(i), + noc1_data_e_out => noc1_data_e_out(i), + noc1_data_void_out => noc1_data_void_out(i), + noc1_stop_out => noc1_stop_out(i), + noc2_data_n_in => noc2_data_n_in(i), + noc2_data_s_in => noc2_data_s_in (i), + noc2_data_w_in => noc2_data_w_in(i), + noc2_data_e_in => noc2_data_e_in(i), + noc2_data_void_in => noc2_data_void_in(i), + noc2_stop_in => noc2_stop_in(i), + noc2_data_n_out => noc2_data_n_out(i), + noc2_data_s_out => noc2_data_s_out(i), + noc2_data_w_out => noc2_data_w_out(i), + noc2_data_e_out => noc2_data_e_out(i), + noc2_data_void_out => noc2_data_void_out(i), + noc2_stop_out => noc2_stop_out(i), + noc3_data_n_in => noc3_data_n_in(i), + noc3_data_s_in => noc3_data_s_in(i), + noc3_data_w_in => noc3_data_w_in(i), + noc3_data_e_in => noc3_data_e_in(i), + noc3_data_void_in => noc3_data_void_in(i), + noc3_stop_in => noc3_stop_in(i), + noc3_data_n_out => noc3_data_n_out(i), + noc3_data_s_out => noc3_data_s_out(i), + noc3_data_w_out => noc3_data_w_out(i), + noc3_data_e_out => noc3_data_e_out(i), + noc3_data_void_out => noc3_data_void_out(i), + noc3_stop_out => noc3_stop_out(i), + noc4_data_n_in => noc4_data_n_in(i), + noc4_data_s_in => noc4_data_s_in(i), + noc4_data_w_in => noc4_data_w_in(i), + noc4_data_e_in => noc4_data_e_in(i), + noc4_data_void_in => noc4_data_void_in(i), + noc4_stop_in => noc4_stop_in(i), + noc4_data_n_out => noc4_data_n_out(i), + noc4_data_s_out => noc4_data_s_out(i), + noc4_data_w_out => noc4_data_w_out(i), + noc4_data_e_out => noc4_data_e_out(i), + noc4_data_void_out => noc4_data_void_out(i), + noc4_stop_out => noc4_stop_out(i), + noc5_data_n_in => noc5_data_n_in(i), + noc5_data_s_in => noc5_data_s_in(i), + noc5_data_w_in => noc5_data_w_in(i), + noc5_data_e_in => noc5_data_e_in(i), + noc5_data_void_in => noc5_data_void_in(i), + noc5_stop_in => noc5_stop_in(i), + noc5_data_n_out => noc5_data_n_out(i), + noc5_data_s_out => noc5_data_s_out(i), + noc5_data_w_out => noc5_data_w_out(i), + noc5_data_e_out => noc5_data_e_out(i), + noc5_data_void_out => noc5_data_void_out(i), + noc5_stop_out => noc5_stop_out(i), + noc6_data_n_in => noc6_data_n_in(i), + noc6_data_s_in => noc6_data_s_in(i), + noc6_data_w_in => noc6_data_w_in(i), + noc6_data_e_in => noc6_data_e_in(i), + noc6_data_void_in => noc6_data_void_in(i), + noc6_stop_in => noc6_stop_in(i), + noc6_data_n_out => noc6_data_n_out(i), + noc6_data_s_out => noc6_data_s_out(i), + noc6_data_w_out => noc6_data_w_out(i), + noc6_data_e_out => noc6_data_e_out(i), + noc6_data_void_out => noc6_data_void_out(i), + noc6_stop_out => noc6_stop_out(i), + noc1_mon_noc_vec => mon_noc_vec(1)(i), + noc2_mon_noc_vec => mon_noc_vec(2)(i), + noc3_mon_noc_vec => mon_noc_vec(3)(i), + noc4_mon_noc_vec => mon_noc_vec(4)(i), + noc5_mon_noc_vec => mon_noc_vec(5)(i), + noc6_mon_noc_vec => mon_noc_vec(6)(i), + mon_dvfs_out => mon_dvfs_out(i) + ); + + clk_tile(i) <= refclk_int(i); end generate empty_tile; + cpu_tile : if tile_type(i) = 1 generate + -- pragma translate_off + assert tile_cpu_id(i) /= -1 + report "Undefined CPU ID for CPU tile" + severity error; + -- pragma translate_on + tile_cpu_i : component fpga_tile_cpu - cpu_tile: if tile_type(i) = 1 generate --- pragma translate_off - assert tile_cpu_id(i) /= -1 report "Undefined CPU ID for CPU tile" severity error; --- pragma translate_on - tile_cpu_i: fpga_tile_cpu - - generic map ( - SIMULATION => SIMULATION, - this_has_dvfs => tile_has_dvfs(i), - this_has_pll => tile_has_pll(i), - this_extra_clk_buf => extra_clk_buf(i), - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - HAS_SYNC => CFG_HAS_SYNC) - port map ( - raw_rstn => '0', - rst => rst_int, - refclk => refclk_int(i), - pllbypass => pllbypass_int(i), - pllclk => clk_tile(i), - dco_clk => open, - cpuerr => cpuerr_vec(tile_cpu_id(i)), - -- Test interface - tdi => '0', - tdo => open, - tms => '0', - tclk => '0', - -- NOC - sys_clk_int => sys_clk_int(0), - noc1_data_n_in => noc1_data_n_in(i), - noc1_data_s_in => noc1_data_s_in(i), - noc1_data_w_in => noc1_data_w_in(i), - noc1_data_e_in => noc1_data_e_in(i), - noc1_data_void_in => noc1_data_void_in(i), - noc1_stop_in => noc1_stop_in(i), - noc1_data_n_out => noc1_data_n_out(i), - noc1_data_s_out => noc1_data_s_out(i), - noc1_data_w_out => noc1_data_w_out(i), - noc1_data_e_out => noc1_data_e_out(i), - noc1_data_void_out => noc1_data_void_out(i), - noc1_stop_out => noc1_stop_out(i), - noc2_data_n_in => noc2_data_n_in(i), - noc2_data_s_in => noc2_data_s_in (i), - noc2_data_w_in => noc2_data_w_in(i), - noc2_data_e_in => noc2_data_e_in(i), - noc2_data_void_in => noc2_data_void_in(i), - noc2_stop_in => noc2_stop_in(i), - noc2_data_n_out => noc2_data_n_out(i), - noc2_data_s_out => noc2_data_s_out(i), - noc2_data_w_out => noc2_data_w_out(i), - noc2_data_e_out => noc2_data_e_out(i), - noc2_data_void_out => noc2_data_void_out(i), - noc2_stop_out => noc2_stop_out(i), - noc3_data_n_in => noc3_data_n_in(i), - noc3_data_s_in => noc3_data_s_in(i), - noc3_data_w_in => noc3_data_w_in(i), - noc3_data_e_in => noc3_data_e_in(i), - noc3_data_void_in => noc3_data_void_in(i), - noc3_stop_in => noc3_stop_in(i), - noc3_data_n_out => noc3_data_n_out(i), - noc3_data_s_out => noc3_data_s_out(i), - noc3_data_w_out => noc3_data_w_out(i), - noc3_data_e_out => noc3_data_e_out(i), - noc3_data_void_out => noc3_data_void_out(i), - noc3_stop_out => noc3_stop_out(i), - noc4_data_n_in => noc4_data_n_in(i), - noc4_data_s_in => noc4_data_s_in(i), - noc4_data_w_in => noc4_data_w_in(i), - noc4_data_e_in => noc4_data_e_in(i), - noc4_data_void_in => noc4_data_void_in(i), - noc4_stop_in => noc4_stop_in(i), - noc4_data_n_out => noc4_data_n_out(i), - noc4_data_s_out => noc4_data_s_out(i), - noc4_data_w_out => noc4_data_w_out(i), - noc4_data_e_out => noc4_data_e_out(i), - noc4_data_void_out => noc4_data_void_out(i), - noc4_stop_out => noc4_stop_out(i), - noc5_data_n_in => noc5_data_n_in(i), - noc5_data_s_in => noc5_data_s_in(i), - noc5_data_w_in => noc5_data_w_in(i), - noc5_data_e_in => noc5_data_e_in(i), - noc5_data_void_in => noc5_data_void_in(i), - noc5_stop_in => noc5_stop_in(i), - noc5_data_n_out => noc5_data_n_out(i), - noc5_data_s_out => noc5_data_s_out(i), - noc5_data_w_out => noc5_data_w_out(i), - noc5_data_e_out => noc5_data_e_out(i), - noc5_data_void_out => noc5_data_void_out(i), - noc5_stop_out => noc5_stop_out(i), - noc6_data_n_in => noc6_data_n_in(i), - noc6_data_s_in => noc6_data_s_in(i), - noc6_data_w_in => noc6_data_w_in(i), - noc6_data_e_in => noc6_data_e_in(i), - noc6_data_void_in => noc6_data_void_in(i), - noc6_stop_in => noc6_stop_in(i), - noc6_data_n_out => noc6_data_n_out(i), - noc6_data_s_out => noc6_data_s_out(i), - noc6_data_w_out => noc6_data_w_out(i), - noc6_data_e_out => noc6_data_e_out(i), - noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i), - noc1_mon_noc_vec => mon_noc_vec(1)(i), - noc2_mon_noc_vec => mon_noc_vec(2)(i), - noc3_mon_noc_vec => mon_noc_vec(3)(i), - noc4_mon_noc_vec => mon_noc_vec(4)(i), - noc5_mon_noc_vec => mon_noc_vec(5)(i), - noc6_mon_noc_vec => mon_noc_vec(6)(i), - mon_cache => mon_l2_int(i), - mon_dvfs_in => mon_dvfs_domain(i), - mon_dvfs => mon_dvfs_out(i)); - end generate cpu_tile; + generic map ( + simulation => SIMULATION, + this_has_dvfs => tile_has_dvfs(i), + this_has_pll => tile_has_pll(i), + this_extra_clk_buf => extra_clk_buf(i), + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + has_sync => CFG_HAS_SYNC + ) + port map ( + raw_rstn => '0', + rst => rst_int, + refclk => refclk_int(i), + pllbypass => pllbypass_int(i), + pllclk => clk_tile(i), + dco_clk => open, + cpuerr => cpuerr_vec(tile_cpu_id(i)), + -- Test interface + tdi => '0', + tdo => open, + tms => '0', + tclk => '0', + -- NOC + sys_clk_int => sys_clk_int(0), + noc1_data_n_in => noc1_data_n_in(i), + noc1_data_s_in => noc1_data_s_in(i), + noc1_data_w_in => noc1_data_w_in(i), + noc1_data_e_in => noc1_data_e_in(i), + noc1_data_void_in => noc1_data_void_in(i), + noc1_stop_in => noc1_stop_in(i), + noc1_data_n_out => noc1_data_n_out(i), + noc1_data_s_out => noc1_data_s_out(i), + noc1_data_w_out => noc1_data_w_out(i), + noc1_data_e_out => noc1_data_e_out(i), + noc1_data_void_out => noc1_data_void_out(i), + noc1_stop_out => noc1_stop_out(i), + noc2_data_n_in => noc2_data_n_in(i), + noc2_data_s_in => noc2_data_s_in (i), + noc2_data_w_in => noc2_data_w_in(i), + noc2_data_e_in => noc2_data_e_in(i), + noc2_data_void_in => noc2_data_void_in(i), + noc2_stop_in => noc2_stop_in(i), + noc2_data_n_out => noc2_data_n_out(i), + noc2_data_s_out => noc2_data_s_out(i), + noc2_data_w_out => noc2_data_w_out(i), + noc2_data_e_out => noc2_data_e_out(i), + noc2_data_void_out => noc2_data_void_out(i), + noc2_stop_out => noc2_stop_out(i), + noc3_data_n_in => noc3_data_n_in(i), + noc3_data_s_in => noc3_data_s_in(i), + noc3_data_w_in => noc3_data_w_in(i), + noc3_data_e_in => noc3_data_e_in(i), + noc3_data_void_in => noc3_data_void_in(i), + noc3_stop_in => noc3_stop_in(i), + noc3_data_n_out => noc3_data_n_out(i), + noc3_data_s_out => noc3_data_s_out(i), + noc3_data_w_out => noc3_data_w_out(i), + noc3_data_e_out => noc3_data_e_out(i), + noc3_data_void_out => noc3_data_void_out(i), + noc3_stop_out => noc3_stop_out(i), + noc4_data_n_in => noc4_data_n_in(i), + noc4_data_s_in => noc4_data_s_in(i), + noc4_data_w_in => noc4_data_w_in(i), + noc4_data_e_in => noc4_data_e_in(i), + noc4_data_void_in => noc4_data_void_in(i), + noc4_stop_in => noc4_stop_in(i), + noc4_data_n_out => noc4_data_n_out(i), + noc4_data_s_out => noc4_data_s_out(i), + noc4_data_w_out => noc4_data_w_out(i), + noc4_data_e_out => noc4_data_e_out(i), + noc4_data_void_out => noc4_data_void_out(i), + noc4_stop_out => noc4_stop_out(i), + noc5_data_n_in => noc5_data_n_in(i), + noc5_data_s_in => noc5_data_s_in(i), + noc5_data_w_in => noc5_data_w_in(i), + noc5_data_e_in => noc5_data_e_in(i), + noc5_data_void_in => noc5_data_void_in(i), + noc5_stop_in => noc5_stop_in(i), + noc5_data_n_out => noc5_data_n_out(i), + noc5_data_s_out => noc5_data_s_out(i), + noc5_data_w_out => noc5_data_w_out(i), + noc5_data_e_out => noc5_data_e_out(i), + noc5_data_void_out => noc5_data_void_out(i), + noc5_stop_out => noc5_stop_out(i), + noc6_data_n_in => noc6_data_n_in(i), + noc6_data_s_in => noc6_data_s_in(i), + noc6_data_w_in => noc6_data_w_in(i), + noc6_data_e_in => noc6_data_e_in(i), + noc6_data_void_in => noc6_data_void_in(i), + noc6_stop_in => noc6_stop_in(i), + noc6_data_n_out => noc6_data_n_out(i), + noc6_data_s_out => noc6_data_s_out(i), + noc6_data_w_out => noc6_data_w_out(i), + noc6_data_e_out => noc6_data_e_out(i), + noc6_data_void_out => noc6_data_void_out(i), + noc6_stop_out => noc6_stop_out(i), + noc1_mon_noc_vec => mon_noc_vec(1)(i), + noc2_mon_noc_vec => mon_noc_vec(2)(i), + noc3_mon_noc_vec => mon_noc_vec(3)(i), + noc4_mon_noc_vec => mon_noc_vec(4)(i), + noc5_mon_noc_vec => mon_noc_vec(5)(i), + noc6_mon_noc_vec => mon_noc_vec(6)(i), + mon_cache => mon_l2_int(i), + mon_dvfs_in => mon_dvfs_domain(i), + mon_dvfs => mon_dvfs_out(i) + ); + end generate cpu_tile; - accelerator_tile: if tile_type(i) = 2 generate --- pragma translate_off - assert tile_device(i) /= 0 report "Undefined device ID for accelerator tile" severity error; --- pragma translate_on - tile_acc_i: fpga_tile_acc - generic map ( - this_hls_conf => tile_design_point(i), - this_device => tile_device(i), - this_irq_type => tile_irq_type(i), - this_has_l2 => tile_has_l2(i), - this_has_dvfs => tile_has_dvfs(i), - this_has_pll => tile_has_pll(i), - this_extra_clk_buf => extra_clk_buf(i), - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - HAS_SYNC => CFG_HAS_SYNC) - port map ( - raw_rstn => '0', - rst => rst_int, - refclk => refclk_int(i), - pllbypass => pllbypass_int(i), - pllclk => clk_tile(i), - dco_clk => open, - -- Test interface - tdi => '0', - tdo => open, - tms => '0', - tclk => '0', - -- NOC - sys_clk_int => sys_clk_int(0), - noc1_data_n_in => noc1_data_n_in(i), - noc1_data_s_in => noc1_data_s_in(i), - noc1_data_w_in => noc1_data_w_in(i), - noc1_data_e_in => noc1_data_e_in(i), - noc1_data_void_in => noc1_data_void_in(i), - noc1_stop_in => noc1_stop_in(i), - noc1_data_n_out => noc1_data_n_out(i), - noc1_data_s_out => noc1_data_s_out(i), - noc1_data_w_out => noc1_data_w_out(i), - noc1_data_e_out => noc1_data_e_out(i), - noc1_data_void_out => noc1_data_void_out(i), - noc1_stop_out => noc1_stop_out(i), - noc2_data_n_in => noc2_data_n_in(i), - noc2_data_s_in => noc2_data_s_in (i), - noc2_data_w_in => noc2_data_w_in(i), - noc2_data_e_in => noc2_data_e_in(i), - noc2_data_void_in => noc2_data_void_in(i), - noc2_stop_in => noc2_stop_in(i), - noc2_data_n_out => noc2_data_n_out(i), - noc2_data_s_out => noc2_data_s_out(i), - noc2_data_w_out => noc2_data_w_out(i), - noc2_data_e_out => noc2_data_e_out(i), - noc2_data_void_out => noc2_data_void_out(i), - noc2_stop_out => noc2_stop_out(i), - noc3_data_n_in => noc3_data_n_in(i), - noc3_data_s_in => noc3_data_s_in(i), - noc3_data_w_in => noc3_data_w_in(i), - noc3_data_e_in => noc3_data_e_in(i), - noc3_data_void_in => noc3_data_void_in(i), - noc3_stop_in => noc3_stop_in(i), - noc3_data_n_out => noc3_data_n_out(i), - noc3_data_s_out => noc3_data_s_out(i), - noc3_data_w_out => noc3_data_w_out(i), - noc3_data_e_out => noc3_data_e_out(i), - noc3_data_void_out => noc3_data_void_out(i), - noc3_stop_out => noc3_stop_out(i), - noc4_data_n_in => noc4_data_n_in(i), - noc4_data_s_in => noc4_data_s_in(i), - noc4_data_w_in => noc4_data_w_in(i), - noc4_data_e_in => noc4_data_e_in(i), - noc4_data_void_in => noc4_data_void_in(i), - noc4_stop_in => noc4_stop_in(i), - noc4_data_n_out => noc4_data_n_out(i), - noc4_data_s_out => noc4_data_s_out(i), - noc4_data_w_out => noc4_data_w_out(i), - noc4_data_e_out => noc4_data_e_out(i), - noc4_data_void_out => noc4_data_void_out(i), - noc4_stop_out => noc4_stop_out(i), - noc5_data_n_in => noc5_data_n_in(i), - noc5_data_s_in => noc5_data_s_in(i), - noc5_data_w_in => noc5_data_w_in(i), - noc5_data_e_in => noc5_data_e_in(i), - noc5_data_void_in => noc5_data_void_in(i), - noc5_stop_in => noc5_stop_in(i), - noc5_data_n_out => noc5_data_n_out(i), - noc5_data_s_out => noc5_data_s_out(i), - noc5_data_w_out => noc5_data_w_out(i), - noc5_data_e_out => noc5_data_e_out(i), - noc5_data_void_out => noc5_data_void_out(i), - noc5_stop_out => noc5_stop_out(i), - noc6_data_n_in => noc6_data_n_in(i), - noc6_data_s_in => noc6_data_s_in(i), - noc6_data_w_in => noc6_data_w_in(i), - noc6_data_e_in => noc6_data_e_in(i), - noc6_data_void_in => noc6_data_void_in(i), - noc6_stop_in => noc6_stop_in(i), - noc6_data_n_out => noc6_data_n_out(i), - noc6_data_s_out => noc6_data_s_out(i), - noc6_data_w_out => noc6_data_w_out(i), - noc6_data_e_out => noc6_data_e_out(i), - noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i), - noc1_mon_noc_vec => mon_noc_vec(1)(i), - noc2_mon_noc_vec => mon_noc_vec(2)(i), - noc3_mon_noc_vec => mon_noc_vec(3)(i), - noc4_mon_noc_vec => mon_noc_vec(4)(i), - noc5_mon_noc_vec => mon_noc_vec(5)(i), - noc6_mon_noc_vec => mon_noc_vec(6)(i), - mon_dvfs_in => mon_dvfs_domain(i), - --Monitor signals - mon_acc => mon_acc(tile_acc_id(i)), - mon_cache => mon_l2_int(i), - mon_dvfs => mon_dvfs_out(i) + accelerator_tile : if tile_type(i) = 2 generate + -- pragma translate_off + assert tile_device(i) /= 0 + report "Undefined device ID for accelerator tile" + severity error; + -- pragma translate_on + tile_acc_i : component fpga_tile_acc + generic map ( + this_hls_conf => tile_design_point(i), + this_device => tile_device(i), + this_irq_type => tile_irq_type(i), + this_has_l2 => tile_has_l2(i), + this_has_dvfs => tile_has_dvfs(i), + this_has_pll => tile_has_pll(i), + this_extra_clk_buf => extra_clk_buf(i), + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + has_sync => CFG_HAS_SYNC + ) + port map ( + raw_rstn => '0', + rst => rst_int, + refclk => refclk_int(i), + pllbypass => pllbypass_int(i), + pllclk => clk_tile(i), + dco_clk => open, + -- Test interface + tdi => '0', + tdo => open, + tms => '0', + tclk => '0', + -- NOC + sys_clk_int => sys_clk_int(0), + noc1_data_n_in => noc1_data_n_in(i), + noc1_data_s_in => noc1_data_s_in(i), + noc1_data_w_in => noc1_data_w_in(i), + noc1_data_e_in => noc1_data_e_in(i), + noc1_data_void_in => noc1_data_void_in(i), + noc1_stop_in => noc1_stop_in(i), + noc1_data_n_out => noc1_data_n_out(i), + noc1_data_s_out => noc1_data_s_out(i), + noc1_data_w_out => noc1_data_w_out(i), + noc1_data_e_out => noc1_data_e_out(i), + noc1_data_void_out => noc1_data_void_out(i), + noc1_stop_out => noc1_stop_out(i), + noc2_data_n_in => noc2_data_n_in(i), + noc2_data_s_in => noc2_data_s_in (i), + noc2_data_w_in => noc2_data_w_in(i), + noc2_data_e_in => noc2_data_e_in(i), + noc2_data_void_in => noc2_data_void_in(i), + noc2_stop_in => noc2_stop_in(i), + noc2_data_n_out => noc2_data_n_out(i), + noc2_data_s_out => noc2_data_s_out(i), + noc2_data_w_out => noc2_data_w_out(i), + noc2_data_e_out => noc2_data_e_out(i), + noc2_data_void_out => noc2_data_void_out(i), + noc2_stop_out => noc2_stop_out(i), + noc3_data_n_in => noc3_data_n_in(i), + noc3_data_s_in => noc3_data_s_in(i), + noc3_data_w_in => noc3_data_w_in(i), + noc3_data_e_in => noc3_data_e_in(i), + noc3_data_void_in => noc3_data_void_in(i), + noc3_stop_in => noc3_stop_in(i), + noc3_data_n_out => noc3_data_n_out(i), + noc3_data_s_out => noc3_data_s_out(i), + noc3_data_w_out => noc3_data_w_out(i), + noc3_data_e_out => noc3_data_e_out(i), + noc3_data_void_out => noc3_data_void_out(i), + noc3_stop_out => noc3_stop_out(i), + noc4_data_n_in => noc4_data_n_in(i), + noc4_data_s_in => noc4_data_s_in(i), + noc4_data_w_in => noc4_data_w_in(i), + noc4_data_e_in => noc4_data_e_in(i), + noc4_data_void_in => noc4_data_void_in(i), + noc4_stop_in => noc4_stop_in(i), + noc4_data_n_out => noc4_data_n_out(i), + noc4_data_s_out => noc4_data_s_out(i), + noc4_data_w_out => noc4_data_w_out(i), + noc4_data_e_out => noc4_data_e_out(i), + noc4_data_void_out => noc4_data_void_out(i), + noc4_stop_out => noc4_stop_out(i), + noc5_data_n_in => noc5_data_n_in(i), + noc5_data_s_in => noc5_data_s_in(i), + noc5_data_w_in => noc5_data_w_in(i), + noc5_data_e_in => noc5_data_e_in(i), + noc5_data_void_in => noc5_data_void_in(i), + noc5_stop_in => noc5_stop_in(i), + noc5_data_n_out => noc5_data_n_out(i), + noc5_data_s_out => noc5_data_s_out(i), + noc5_data_w_out => noc5_data_w_out(i), + noc5_data_e_out => noc5_data_e_out(i), + noc5_data_void_out => noc5_data_void_out(i), + noc5_stop_out => noc5_stop_out(i), + noc6_data_n_in => noc6_data_n_in(i), + noc6_data_s_in => noc6_data_s_in(i), + noc6_data_w_in => noc6_data_w_in(i), + noc6_data_e_in => noc6_data_e_in(i), + noc6_data_void_in => noc6_data_void_in(i), + noc6_stop_in => noc6_stop_in(i), + noc6_data_n_out => noc6_data_n_out(i), + noc6_data_s_out => noc6_data_s_out(i), + noc6_data_w_out => noc6_data_w_out(i), + noc6_data_e_out => noc6_data_e_out(i), + noc6_data_void_out => noc6_data_void_out(i), + noc6_stop_out => noc6_stop_out(i), + noc1_mon_noc_vec => mon_noc_vec(1)(i), + noc2_mon_noc_vec => mon_noc_vec(2)(i), + noc3_mon_noc_vec => mon_noc_vec(3)(i), + noc4_mon_noc_vec => mon_noc_vec(4)(i), + noc5_mon_noc_vec => mon_noc_vec(5)(i), + noc6_mon_noc_vec => mon_noc_vec(6)(i), + mon_dvfs_in => mon_dvfs_domain(i), + -- Monitor signals + mon_acc => mon_acc(tile_acc_id(i)), + mon_cache => mon_l2_int(i), + mon_dvfs => mon_dvfs_out(i) ); + end generate accelerator_tile; + io_tile : if tile_type(i) = 3 generate + + tile_io_i : component fpga_tile_io + generic map ( + simulation => SIMULATION, + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + has_sync => CFG_HAS_SYNC + ) + port map ( + raw_rstn => '0', + rst => rst_int, + clk => refclk_int(i), + refclk_noc => '0', + pllclk_noc => open, + refclk => '0', + pllbypass => '0', + pllclk => open, + dco_clk => open, + -- Test interface + tdi => '0', + tdo => open, + tms => '0', + tclk => '0', + -- Ethernet MDC Scaler configuration + mdcscaler => open, + -- I/O bus interfaces + eth0_apbi => eth0_apbi, + eth0_apbo => eth0_apbo, + sgmii0_apbi => sgmii0_apbi, + sgmii0_apbo => sgmii0_apbo, + eth0_ahbmi => eth0_ahbmi, + eth0_ahbmo => eth0_ahbmo, + edcl_ahbmo => edcl_ahbmo, + dvi_apbi => dvi_apbi, + dvi_apbo => dvi_apbo, + dvi_ahbmi => dvi_ahbmi, + dvi_ahbmo => dvi_ahbmo, + uart_rxd => uart_rxd, + uart_txd => uart_txd, + uart_ctsn => uart_ctsn, + uart_rtsn => uart_rtsn, + -- NOC + sys_clk_int => sys_clk_int(0), + sys_rstn => rst_int, + sys_clk_out => open, + sys_clk_lock => open, + noc1_data_n_in => noc1_data_n_in(i), + noc1_data_s_in => noc1_data_s_in(i), + noc1_data_w_in => noc1_data_w_in(i), + noc1_data_e_in => noc1_data_e_in(i), + noc1_data_void_in => noc1_data_void_in(i), + noc1_stop_in => noc1_stop_in(i), + noc1_data_n_out => noc1_data_n_out(i), + noc1_data_s_out => noc1_data_s_out(i), + noc1_data_w_out => noc1_data_w_out(i), + noc1_data_e_out => noc1_data_e_out(i), + noc1_data_void_out => noc1_data_void_out(i), + noc1_stop_out => noc1_stop_out(i), + noc2_data_n_in => noc2_data_n_in(i), + noc2_data_s_in => noc2_data_s_in (i), + noc2_data_w_in => noc2_data_w_in(i), + noc2_data_e_in => noc2_data_e_in(i), + noc2_data_void_in => noc2_data_void_in(i), + noc2_stop_in => noc2_stop_in(i), + noc2_data_n_out => noc2_data_n_out(i), + noc2_data_s_out => noc2_data_s_out(i), + noc2_data_w_out => noc2_data_w_out(i), + noc2_data_e_out => noc2_data_e_out(i), + noc2_data_void_out => noc2_data_void_out(i), + noc2_stop_out => noc2_stop_out(i), + noc3_data_n_in => noc3_data_n_in(i), + noc3_data_s_in => noc3_data_s_in(i), + noc3_data_w_in => noc3_data_w_in(i), + noc3_data_e_in => noc3_data_e_in(i), + noc3_data_void_in => noc3_data_void_in(i), + noc3_stop_in => noc3_stop_in(i), + noc3_data_n_out => noc3_data_n_out(i), + noc3_data_s_out => noc3_data_s_out(i), + noc3_data_w_out => noc3_data_w_out(i), + noc3_data_e_out => noc3_data_e_out(i), + noc3_data_void_out => noc3_data_void_out(i), + noc3_stop_out => noc3_stop_out(i), + noc4_data_n_in => noc4_data_n_in(i), + noc4_data_s_in => noc4_data_s_in(i), + noc4_data_w_in => noc4_data_w_in(i), + noc4_data_e_in => noc4_data_e_in(i), + noc4_data_void_in => noc4_data_void_in(i), + noc4_stop_in => noc4_stop_in(i), + noc4_data_n_out => noc4_data_n_out(i), + noc4_data_s_out => noc4_data_s_out(i), + noc4_data_w_out => noc4_data_w_out(i), + noc4_data_e_out => noc4_data_e_out(i), + noc4_data_void_out => noc4_data_void_out(i), + noc4_stop_out => noc4_stop_out(i), + noc5_data_n_in => noc5_data_n_in(i), + noc5_data_s_in => noc5_data_s_in(i), + noc5_data_w_in => noc5_data_w_in(i), + noc5_data_e_in => noc5_data_e_in(i), + noc5_data_void_in => noc5_data_void_in(i), + noc5_stop_in => noc5_stop_in(i), + noc5_data_n_out => noc5_data_n_out(i), + noc5_data_s_out => noc5_data_s_out(i), + noc5_data_w_out => noc5_data_w_out(i), + noc5_data_e_out => noc5_data_e_out(i), + noc5_data_void_out => noc5_data_void_out(i), + noc5_stop_out => noc5_stop_out(i), + noc6_data_n_in => noc6_data_n_in(i), + noc6_data_s_in => noc6_data_s_in(i), + noc6_data_w_in => noc6_data_w_in(i), + noc6_data_e_in => noc6_data_e_in(i), + noc6_data_void_in => noc6_data_void_in(i), + noc6_stop_in => noc6_stop_in(i), + noc6_data_n_out => noc6_data_n_out(i), + noc6_data_s_out => noc6_data_s_out(i), + noc6_data_w_out => noc6_data_w_out(i), + noc6_data_e_out => noc6_data_e_out(i), + noc6_data_void_out => noc6_data_void_out(i), + noc6_stop_out => noc6_stop_out(i), + noc1_mon_noc_vec => mon_noc_vec(1)(i), + noc2_mon_noc_vec => mon_noc_vec(2)(i), + noc3_mon_noc_vec => mon_noc_vec(3)(i), + noc4_mon_noc_vec => mon_noc_vec(4)(i), + noc5_mon_noc_vec => mon_noc_vec(5)(i), + noc6_mon_noc_vec => mon_noc_vec(6)(i), + mon_dvfs => mon_dvfs_out(i) + ); - io_tile: if tile_type(i) = 3 generate - tile_io_i : fpga_tile_io - generic map ( - SIMULATION => SIMULATION, - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - HAS_SYNC => CFG_HAS_SYNC) - port map ( - raw_rstn => '0', - rst => rst_int, - clk => refclk_int(i), - refclk_noc => '0', - pllclk_noc => open, - refclk => '0', - pllbypass => '0', - pllclk => open, - dco_clk => open, - -- Test interface - tdi => '0', - tdo => open, - tms => '0', - tclk => '0', - -- Ethernet MDC Scaler configuration - mdcscaler => open, - -- I/O bus interfaces - eth0_apbi => eth0_apbi, - eth0_apbo => eth0_apbo, - sgmii0_apbi => sgmii0_apbi, - sgmii0_apbo => sgmii0_apbo, - eth0_ahbmi => eth0_ahbmi, - eth0_ahbmo => eth0_ahbmo, - edcl_ahbmo => edcl_ahbmo, - dvi_apbi => dvi_apbi, - dvi_apbo => dvi_apbo, - dvi_ahbmi => dvi_ahbmi, - dvi_ahbmo => dvi_ahbmo, - uart_rxd => uart_rxd, - uart_txd => uart_txd, - uart_ctsn => uart_ctsn, - uart_rtsn => uart_rtsn, - -- NOC - sys_clk_int => sys_clk_int(0), - sys_rstn => rst_int, - sys_clk_out => open, - sys_clk_lock => open, - noc1_data_n_in => noc1_data_n_in(i), - noc1_data_s_in => noc1_data_s_in(i), - noc1_data_w_in => noc1_data_w_in(i), - noc1_data_e_in => noc1_data_e_in(i), - noc1_data_void_in => noc1_data_void_in(i), - noc1_stop_in => noc1_stop_in(i), - noc1_data_n_out => noc1_data_n_out(i), - noc1_data_s_out => noc1_data_s_out(i), - noc1_data_w_out => noc1_data_w_out(i), - noc1_data_e_out => noc1_data_e_out(i), - noc1_data_void_out => noc1_data_void_out(i), - noc1_stop_out => noc1_stop_out(i), - noc2_data_n_in => noc2_data_n_in(i), - noc2_data_s_in => noc2_data_s_in (i), - noc2_data_w_in => noc2_data_w_in(i), - noc2_data_e_in => noc2_data_e_in(i), - noc2_data_void_in => noc2_data_void_in(i), - noc2_stop_in => noc2_stop_in(i), - noc2_data_n_out => noc2_data_n_out(i), - noc2_data_s_out => noc2_data_s_out(i), - noc2_data_w_out => noc2_data_w_out(i), - noc2_data_e_out => noc2_data_e_out(i), - noc2_data_void_out => noc2_data_void_out(i), - noc2_stop_out => noc2_stop_out(i), - noc3_data_n_in => noc3_data_n_in(i), - noc3_data_s_in => noc3_data_s_in(i), - noc3_data_w_in => noc3_data_w_in(i), - noc3_data_e_in => noc3_data_e_in(i), - noc3_data_void_in => noc3_data_void_in(i), - noc3_stop_in => noc3_stop_in(i), - noc3_data_n_out => noc3_data_n_out(i), - noc3_data_s_out => noc3_data_s_out(i), - noc3_data_w_out => noc3_data_w_out(i), - noc3_data_e_out => noc3_data_e_out(i), - noc3_data_void_out => noc3_data_void_out(i), - noc3_stop_out => noc3_stop_out(i), - noc4_data_n_in => noc4_data_n_in(i), - noc4_data_s_in => noc4_data_s_in(i), - noc4_data_w_in => noc4_data_w_in(i), - noc4_data_e_in => noc4_data_e_in(i), - noc4_data_void_in => noc4_data_void_in(i), - noc4_stop_in => noc4_stop_in(i), - noc4_data_n_out => noc4_data_n_out(i), - noc4_data_s_out => noc4_data_s_out(i), - noc4_data_w_out => noc4_data_w_out(i), - noc4_data_e_out => noc4_data_e_out(i), - noc4_data_void_out => noc4_data_void_out(i), - noc4_stop_out => noc4_stop_out(i), - noc5_data_n_in => noc5_data_n_in(i), - noc5_data_s_in => noc5_data_s_in(i), - noc5_data_w_in => noc5_data_w_in(i), - noc5_data_e_in => noc5_data_e_in(i), - noc5_data_void_in => noc5_data_void_in(i), - noc5_stop_in => noc5_stop_in(i), - noc5_data_n_out => noc5_data_n_out(i), - noc5_data_s_out => noc5_data_s_out(i), - noc5_data_w_out => noc5_data_w_out(i), - noc5_data_e_out => noc5_data_e_out(i), - noc5_data_void_out => noc5_data_void_out(i), - noc5_stop_out => noc5_stop_out(i), - noc6_data_n_in => noc6_data_n_in(i), - noc6_data_s_in => noc6_data_s_in(i), - noc6_data_w_in => noc6_data_w_in(i), - noc6_data_e_in => noc6_data_e_in(i), - noc6_data_void_in => noc6_data_void_in(i), - noc6_stop_in => noc6_stop_in(i), - noc6_data_n_out => noc6_data_n_out(i), - noc6_data_s_out => noc6_data_s_out(i), - noc6_data_w_out => noc6_data_w_out(i), - noc6_data_e_out => noc6_data_e_out(i), - noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i), - noc1_mon_noc_vec => mon_noc_vec(1)(i), - noc2_mon_noc_vec => mon_noc_vec(2)(i), - noc3_mon_noc_vec => mon_noc_vec(3)(i), - noc4_mon_noc_vec => mon_noc_vec(4)(i), - noc5_mon_noc_vec => mon_noc_vec(5)(i), - noc6_mon_noc_vec => mon_noc_vec(6)(i), - mon_dvfs => mon_dvfs_out(i)); clk_tile(i) <= refclk_int(i); end generate io_tile; + mem_tile : if tile_type(i) = 4 generate + + tile_mem_i : component fpga_tile_mem + generic map ( + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + has_sync => CFG_HAS_SYNC + ) + port map ( + raw_rstn => '0', + rst => rst_int, + refclk => '0', + clk => sys_clk_int(tile_mem_id(i)), + pllbypass => '0', + pllclk => open, + dco_clk => open, + -- DDR controller ports (this_has_ddr -> 1) + dco_clk_div2 => open, + dco_clk_div2_90 => open, + ddr_ahbsi => ddr_ahbsi(tile_mem_id(i)), + ddr_ahbso => ddr_ahbso(tile_mem_id(i)), + ddr_cfg0 => open, + ddr_cfg1 => open, + ddr_cfg2 => open, + mem_id => open, + -- FPGA proxy memory link (this_has_ddr -> 0) + fpga_data_in => (others => '0'), + fpga_data_out => open, + fpga_oen => open, + fpga_valid_in => '0', + fpga_valid_out => open, + fpga_clk_in => '0', + fpga_clk_out => open, + fpga_credit_in => '0', + fpga_credit_out => open, + -- Test interface + tdi => '0', + tdo => open, + tms => '0', + tclk => '0', + -- NOC + sys_clk_int => sys_clk_int(0), + noc1_data_n_in => noc1_data_n_in(i), + noc1_data_s_in => noc1_data_s_in(i), + noc1_data_w_in => noc1_data_w_in(i), + noc1_data_e_in => noc1_data_e_in(i), + noc1_data_void_in => noc1_data_void_in(i), + noc1_stop_in => noc1_stop_in(i), + noc1_data_n_out => noc1_data_n_out(i), + noc1_data_s_out => noc1_data_s_out(i), + noc1_data_w_out => noc1_data_w_out(i), + noc1_data_e_out => noc1_data_e_out(i), + noc1_data_void_out => noc1_data_void_out(i), + noc1_stop_out => noc1_stop_out(i), + noc2_data_n_in => noc2_data_n_in(i), + noc2_data_s_in => noc2_data_s_in (i), + noc2_data_w_in => noc2_data_w_in(i), + noc2_data_e_in => noc2_data_e_in(i), + noc2_data_void_in => noc2_data_void_in(i), + noc2_stop_in => noc2_stop_in(i), + noc2_data_n_out => noc2_data_n_out(i), + noc2_data_s_out => noc2_data_s_out(i), + noc2_data_w_out => noc2_data_w_out(i), + noc2_data_e_out => noc2_data_e_out(i), + noc2_data_void_out => noc2_data_void_out(i), + noc2_stop_out => noc2_stop_out(i), + noc3_data_n_in => noc3_data_n_in(i), + noc3_data_s_in => noc3_data_s_in(i), + noc3_data_w_in => noc3_data_w_in(i), + noc3_data_e_in => noc3_data_e_in(i), + noc3_data_void_in => noc3_data_void_in(i), + noc3_stop_in => noc3_stop_in(i), + noc3_data_n_out => noc3_data_n_out(i), + noc3_data_s_out => noc3_data_s_out(i), + noc3_data_w_out => noc3_data_w_out(i), + noc3_data_e_out => noc3_data_e_out(i), + noc3_data_void_out => noc3_data_void_out(i), + noc3_stop_out => noc3_stop_out(i), + noc4_data_n_in => noc4_data_n_in(i), + noc4_data_s_in => noc4_data_s_in(i), + noc4_data_w_in => noc4_data_w_in(i), + noc4_data_e_in => noc4_data_e_in(i), + noc4_data_void_in => noc4_data_void_in(i), + noc4_stop_in => noc4_stop_in(i), + noc4_data_n_out => noc4_data_n_out(i), + noc4_data_s_out => noc4_data_s_out(i), + noc4_data_w_out => noc4_data_w_out(i), + noc4_data_e_out => noc4_data_e_out(i), + noc4_data_void_out => noc4_data_void_out(i), + noc4_stop_out => noc4_stop_out(i), + noc5_data_n_in => noc5_data_n_in(i), + noc5_data_s_in => noc5_data_s_in(i), + noc5_data_w_in => noc5_data_w_in(i), + noc5_data_e_in => noc5_data_e_in(i), + noc5_data_void_in => noc5_data_void_in(i), + noc5_stop_in => noc5_stop_in(i), + noc5_data_n_out => noc5_data_n_out(i), + noc5_data_s_out => noc5_data_s_out(i), + noc5_data_w_out => noc5_data_w_out(i), + noc5_data_e_out => noc5_data_e_out(i), + noc5_data_void_out => noc5_data_void_out(i), + noc5_stop_out => noc5_stop_out(i), + noc6_data_n_in => noc6_data_n_in(i), + noc6_data_s_in => noc6_data_s_in(i), + noc6_data_w_in => noc6_data_w_in(i), + noc6_data_e_in => noc6_data_e_in(i), + noc6_data_void_in => noc6_data_void_in(i), + noc6_stop_in => noc6_stop_in(i), + noc6_data_n_out => noc6_data_n_out(i), + noc6_data_s_out => noc6_data_s_out(i), + noc6_data_w_out => noc6_data_w_out(i), + noc6_data_e_out => noc6_data_e_out(i), + noc6_data_void_out => noc6_data_void_out(i), + noc6_stop_out => noc6_stop_out(i), + noc1_mon_noc_vec => mon_noc_vec(1)(i), + noc2_mon_noc_vec => mon_noc_vec(2)(i), + noc3_mon_noc_vec => mon_noc_vec(3)(i), + noc4_mon_noc_vec => mon_noc_vec(4)(i), + noc5_mon_noc_vec => mon_noc_vec(5)(i), + noc6_mon_noc_vec => mon_noc_vec(6)(i), + mon_mem => mon_mem(tile_mem_id(i)), + mon_cache => mon_llc_int(i), + mon_dvfs => mon_dvfs_out(i) + ); - mem_tile: if tile_type(i) = 4 generate - tile_mem_i: fpga_tile_mem - generic map ( - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - HAS_SYNC => CFG_HAS_SYNC) - port map ( - raw_rstn => '0', - rst => rst_int, - refclk => '0', - clk => sys_clk_int(tile_mem_id(i)), - pllbypass => '0', - pllclk => open, - dco_clk => open, - -- DDR controller ports (this_has_ddr -> 1) - dco_clk_div2 => open, - dco_clk_div2_90 => open, - ddr_ahbsi => ddr_ahbsi(tile_mem_id(i)), - ddr_ahbso => ddr_ahbso(tile_mem_id(i)), - ddr_cfg0 => open, - ddr_cfg1 => open, - ddr_cfg2 => open, - mem_id => open, - -- FPGA proxy memory link (this_has_ddr -> 0) - fpga_data_in => (others => '0'), - fpga_data_out => open, - fpga_oen => open, - fpga_valid_in => '0', - fpga_valid_out => open, - fpga_clk_in => '0', - fpga_clk_out => open, - fpga_credit_in => '0', - fpga_credit_out => open, - -- Test interface - tdi => '0', - tdo => open, - tms => '0', - tclk => '0', - -- NOC - sys_clk_int => sys_clk_int(0), - noc1_data_n_in => noc1_data_n_in(i), - noc1_data_s_in => noc1_data_s_in(i), - noc1_data_w_in => noc1_data_w_in(i), - noc1_data_e_in => noc1_data_e_in(i), - noc1_data_void_in => noc1_data_void_in(i), - noc1_stop_in => noc1_stop_in(i), - noc1_data_n_out => noc1_data_n_out(i), - noc1_data_s_out => noc1_data_s_out(i), - noc1_data_w_out => noc1_data_w_out(i), - noc1_data_e_out => noc1_data_e_out(i), - noc1_data_void_out => noc1_data_void_out(i), - noc1_stop_out => noc1_stop_out(i), - noc2_data_n_in => noc2_data_n_in(i), - noc2_data_s_in => noc2_data_s_in (i), - noc2_data_w_in => noc2_data_w_in(i), - noc2_data_e_in => noc2_data_e_in(i), - noc2_data_void_in => noc2_data_void_in(i), - noc2_stop_in => noc2_stop_in(i), - noc2_data_n_out => noc2_data_n_out(i), - noc2_data_s_out => noc2_data_s_out(i), - noc2_data_w_out => noc2_data_w_out(i), - noc2_data_e_out => noc2_data_e_out(i), - noc2_data_void_out => noc2_data_void_out(i), - noc2_stop_out => noc2_stop_out(i), - noc3_data_n_in => noc3_data_n_in(i), - noc3_data_s_in => noc3_data_s_in(i), - noc3_data_w_in => noc3_data_w_in(i), - noc3_data_e_in => noc3_data_e_in(i), - noc3_data_void_in => noc3_data_void_in(i), - noc3_stop_in => noc3_stop_in(i), - noc3_data_n_out => noc3_data_n_out(i), - noc3_data_s_out => noc3_data_s_out(i), - noc3_data_w_out => noc3_data_w_out(i), - noc3_data_e_out => noc3_data_e_out(i), - noc3_data_void_out => noc3_data_void_out(i), - noc3_stop_out => noc3_stop_out(i), - noc4_data_n_in => noc4_data_n_in(i), - noc4_data_s_in => noc4_data_s_in(i), - noc4_data_w_in => noc4_data_w_in(i), - noc4_data_e_in => noc4_data_e_in(i), - noc4_data_void_in => noc4_data_void_in(i), - noc4_stop_in => noc4_stop_in(i), - noc4_data_n_out => noc4_data_n_out(i), - noc4_data_s_out => noc4_data_s_out(i), - noc4_data_w_out => noc4_data_w_out(i), - noc4_data_e_out => noc4_data_e_out(i), - noc4_data_void_out => noc4_data_void_out(i), - noc4_stop_out => noc4_stop_out(i), - noc5_data_n_in => noc5_data_n_in(i), - noc5_data_s_in => noc5_data_s_in(i), - noc5_data_w_in => noc5_data_w_in(i), - noc5_data_e_in => noc5_data_e_in(i), - noc5_data_void_in => noc5_data_void_in(i), - noc5_stop_in => noc5_stop_in(i), - noc5_data_n_out => noc5_data_n_out(i), - noc5_data_s_out => noc5_data_s_out(i), - noc5_data_w_out => noc5_data_w_out(i), - noc5_data_e_out => noc5_data_e_out(i), - noc5_data_void_out => noc5_data_void_out(i), - noc5_stop_out => noc5_stop_out(i), - noc6_data_n_in => noc6_data_n_in(i), - noc6_data_s_in => noc6_data_s_in(i), - noc6_data_w_in => noc6_data_w_in(i), - noc6_data_e_in => noc6_data_e_in(i), - noc6_data_void_in => noc6_data_void_in(i), - noc6_stop_in => noc6_stop_in(i), - noc6_data_n_out => noc6_data_n_out(i), - noc6_data_s_out => noc6_data_s_out(i), - noc6_data_w_out => noc6_data_w_out(i), - noc6_data_e_out => noc6_data_e_out(i), - noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i), - noc1_mon_noc_vec => mon_noc_vec(1)(i), - noc2_mon_noc_vec => mon_noc_vec(2)(i), - noc3_mon_noc_vec => mon_noc_vec(3)(i), - noc4_mon_noc_vec => mon_noc_vec(4)(i), - noc5_mon_noc_vec => mon_noc_vec(5)(i), - noc6_mon_noc_vec => mon_noc_vec(6)(i), - mon_mem => mon_mem(tile_mem_id(i)), - mon_cache => mon_llc_int(i), - mon_dvfs => mon_dvfs_out(i)); clk_tile(i) <= sys_clk_int(tile_mem_id(i)); end generate mem_tile; - slm_tile: if tile_type(i) = 5 generate - tile_slm_i: fpga_tile_slm + slm_tile : if tile_type(i) = 5 generate + + tile_slm_i : component fpga_tile_slm generic map ( - SIMULATION => SIMULATION, - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - HAS_SYNC => CFG_HAS_SYNC) + simulation => SIMULATION, + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + has_sync => CFG_HAS_SYNC + ) port map ( - raw_rstn => '0', - rst => rst_int, - clk => refclk_int(i), - refclk => '0', - pllbypass => '0', - pllclk => open, - dco_clk => open, + raw_rstn => '0', + rst => rst_int, + clk => refclk_int(i), + refclk => '0', + pllbypass => '0', + pllclk => open, + dco_clk => open, -- DDR controller ports (disaled in generic ESP top) - dco_clk_div2 => open, - dco_clk_div2_90 => open, - ddr_ahbsi => open, - ddr_ahbso => ahbs_none, - ddr_cfg0 => open, - ddr_cfg1 => open, - ddr_cfg2 => open, - slmddr_id => open, + dco_clk_div2 => open, + dco_clk_div2_90 => open, + ddr_ahbsi => open, + ddr_ahbso => ahbs_none, + ddr_cfg0 => open, + ddr_cfg1 => open, + ddr_cfg2 => open, + slmddr_id => open, -- Test interface - tdi => '0', - tdo => open, - tms => '0', - tclk => '0', + tdi => '0', + tdo => open, + tms => '0', + tclk => '0', -- NOC sys_clk_int => sys_clk_int(0), noc1_data_n_in => noc1_data_n_in(i), @@ -1104,42 +1134,46 @@ begin noc5_mon_noc_vec => mon_noc_vec(5)(i), noc6_mon_noc_vec => mon_noc_vec(6)(i), mon_mem => mon_mem(CFG_NMEM_TILE + tile_slm_id(i)), - mon_dvfs => mon_dvfs_out(i)); + mon_dvfs => mon_dvfs_out(i) + ); + clk_tile(i) <= refclk_int(i); end generate slm_tile; end generate tiles_gen; - no_mem_tile_gen: if CFG_NMEM_TILE = 0 generate + no_mem_tile_gen : if CFG_NMEM_TILE = 0 generate ddr_ahbsi(0) <= ahbs_in_none; end generate no_mem_tile_gen; - monitor_noc_gen: for i in 1 to nocs_num generate - monitor_noc_tiles_gen: for j in 0 to CFG_TILES_NUM-1 generate + monitor_noc_gen : for i in 1 to NOCS_NUM generate + + monitor_noc_tiles_gen : for j in 0 to CFG_TILES_NUM - 1 generate mon_noc(i,j) <= mon_noc_vec(i)(j); end generate monitor_noc_tiles_gen; + end generate monitor_noc_gen; - monitor_l2_gen: for i in 0 to CFG_NL2 - 1 generate + monitor_l2_gen : for i in 0 to CFG_NL2 - 1 generate mon_l2(i) <= mon_l2_int(cache_tile_id(i)); end generate monitor_l2_gen; - monitor_llc_gen: for i in 0 to CFG_NLLC - 1 generate + monitor_llc_gen : for i in 0 to CFG_NLLC - 1 generate mon_llc(i) <= mon_llc_int(llc_tile_id(i)); end generate monitor_llc_gen; - -- Handle cases with no accelerators, no l2, no llc - mon_acc_noacc_gen: if accelerators_num = 0 generate + + mon_acc_noacc_gen : if accelerators_num = 0 generate mon_acc(0) <= monitor_acc_none; end generate mon_acc_noacc_gen; - mon_l2_nol2_gen: if CFG_NL2 = 0 generate + mon_l2_nol2_gen : if CFG_NL2 = 0 generate mon_l2(0) <= monitor_cache_none; end generate mon_l2_nol2_gen; - mon_llc_nollc_gen: if CFG_NLLC = 0 generate + mon_llc_nollc_gen : if CFG_NLLC = 0 generate mon_llc(0) <= monitor_cache_none; end generate mon_llc_nollc_gen; -end; +end architecture rtl; diff --git a/rtl/tiles/fpga/fpga_tile_acc.vhd b/rtl/tiles/fpga/fpga_tile_acc.vhd index b9b4be6729..aa1e17d451 100644 --- a/rtl/tiles/fpga/fpga_tile_acc.vhd +++ b/rtl/tiles/fpga/fpga_tile_acc.vhd @@ -6,27 +6,27 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.esp_global.all; -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; -use work.gencomp.all; -use work.monitor_pkg.all; -use work.esp_csr_pkg.all; -use work.jtag_pkg.all; -use work.sldacc.all; -use work.nocpackage.all; -use work.cachepackage.all; -use work.tile.all; -use work.misc.all; -use work.coretypes.all; -use work.esp_acc_regmap.all; -use work.socmap.all; -use work.grlib_config.all; -use work.tiles_pkg.all; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use work.esp_global.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.monitor_pkg.all; + use work.esp_csr_pkg.all; + use work.jtag_pkg.all; + use work.sldacc.all; + use work.nocpackage.all; + use work.cachepackage.all; + use work.tile.all; + use work.misc.all; + use work.coretypes.all; + use work.esp_acc_regmap.all; + use work.socmap.all; + use work.grlib_config.all; + use work.tiles_pkg.all; entity fpga_tile_acc is generic ( @@ -37,107 +37,107 @@ entity fpga_tile_acc is this_has_dvfs : integer range 0 to 1 := 0; this_has_pll : integer range 0 to 1 := 0; this_extra_clk_buf : integer range 0 to 1 := 0; - ROUTER_PORTS : ports_vec := "11111"; - HAS_SYNC : integer range 0 to 1 := 1); + router_ports : ports_vec := "11111"; + has_sync : integer range 0 to 1 := 1 + ); port ( - raw_rstn : in std_ulogic; - rst : in std_ulogic; - refclk : in std_ulogic; - pllbypass : in std_ulogic; - pllclk : out std_ulogic; - dco_clk : out std_ulogic; + raw_rstn : in std_ulogic; + rst : in std_ulogic; + refclk : in std_ulogic; + pllbypass : in std_ulogic; + pllclk : out std_ulogic; + dco_clk : out std_ulogic; -- Test interface - tdi : in std_logic; - tdo : out std_logic; - tms : in std_logic; - tclk : in std_logic; + tdi : in std_logic; + tdo : out std_logic; + tms : in std_logic; + tclk : in std_logic; -- NOC - sys_clk_int : in std_logic; - noc1_data_n_in : in coh_noc_flit_type; - noc1_data_s_in : in coh_noc_flit_type; - noc1_data_w_in : in coh_noc_flit_type; - noc1_data_e_in : in coh_noc_flit_type; - noc1_data_void_in : in std_logic_vector(3 downto 0); - noc1_stop_in : in std_logic_vector(3 downto 0); - noc1_data_n_out : out coh_noc_flit_type; - noc1_data_s_out : out coh_noc_flit_type; - noc1_data_w_out : out coh_noc_flit_type; - noc1_data_e_out : out coh_noc_flit_type; - noc1_data_void_out : out std_logic_vector(3 downto 0); - noc1_stop_out : out std_logic_vector(3 downto 0); - noc2_data_n_in : in coh_noc_flit_type; - noc2_data_s_in : in coh_noc_flit_type; - noc2_data_w_in : in coh_noc_flit_type; - noc2_data_e_in : in coh_noc_flit_type; - noc2_data_void_in : in std_logic_vector(3 downto 0); - noc2_stop_in : in std_logic_vector(3 downto 0); - noc2_data_n_out : out coh_noc_flit_type; - noc2_data_s_out : out coh_noc_flit_type; - noc2_data_w_out : out coh_noc_flit_type; - noc2_data_e_out : out coh_noc_flit_type; - noc2_data_void_out : out std_logic_vector(3 downto 0); - noc2_stop_out : out std_logic_vector(3 downto 0); - noc3_data_n_in : in coh_noc_flit_type; - noc3_data_s_in : in coh_noc_flit_type; - noc3_data_w_in : in coh_noc_flit_type; - noc3_data_e_in : in coh_noc_flit_type; - noc3_data_void_in : in std_logic_vector(3 downto 0); - noc3_stop_in : in std_logic_vector(3 downto 0); - noc3_data_n_out : out coh_noc_flit_type; - noc3_data_s_out : out coh_noc_flit_type; - noc3_data_w_out : out coh_noc_flit_type; - noc3_data_e_out : out coh_noc_flit_type; - noc3_data_void_out : out std_logic_vector(3 downto 0); - noc3_stop_out : out std_logic_vector(3 downto 0); - noc4_data_n_in : in dma_noc_flit_type; - noc4_data_s_in : in dma_noc_flit_type; - noc4_data_w_in : in dma_noc_flit_type; - noc4_data_e_in : in dma_noc_flit_type; - noc4_data_void_in : in std_logic_vector(3 downto 0); - noc4_stop_in : in std_logic_vector(3 downto 0); - noc4_data_n_out : out dma_noc_flit_type; - noc4_data_s_out : out dma_noc_flit_type; - noc4_data_w_out : out dma_noc_flit_type; - noc4_data_e_out : out dma_noc_flit_type; - noc4_data_void_out : out std_logic_vector(3 downto 0); - noc4_stop_out : out std_logic_vector(3 downto 0); - noc5_data_n_in : in misc_noc_flit_type; - noc5_data_s_in : in misc_noc_flit_type; - noc5_data_w_in : in misc_noc_flit_type; - noc5_data_e_in : in misc_noc_flit_type; - noc5_data_void_in : in std_logic_vector(3 downto 0); - noc5_stop_in : in std_logic_vector(3 downto 0); - noc5_data_n_out : out misc_noc_flit_type; - noc5_data_s_out : out misc_noc_flit_type; - noc5_data_w_out : out misc_noc_flit_type; - noc5_data_e_out : out misc_noc_flit_type; - noc5_data_void_out : out std_logic_vector(3 downto 0); - noc5_stop_out : out std_logic_vector(3 downto 0); - noc6_data_n_in : in dma_noc_flit_type; - noc6_data_s_in : in dma_noc_flit_type; - noc6_data_w_in : in dma_noc_flit_type; - noc6_data_e_in : in dma_noc_flit_type; - noc6_data_void_in : in std_logic_vector(3 downto 0); - noc6_stop_in : in std_logic_vector(3 downto 0); - noc6_data_n_out : out dma_noc_flit_type; - noc6_data_s_out : out dma_noc_flit_type; - noc6_data_w_out : out dma_noc_flit_type; - noc6_data_e_out : out dma_noc_flit_type; - noc6_data_void_out : out std_logic_vector(3 downto 0); - noc6_stop_out : out std_logic_vector(3 downto 0); - noc1_mon_noc_vec : out monitor_noc_type; - noc2_mon_noc_vec : out monitor_noc_type; - noc3_mon_noc_vec : out monitor_noc_type; - noc4_mon_noc_vec : out monitor_noc_type; - noc5_mon_noc_vec : out monitor_noc_type; - noc6_mon_noc_vec : out monitor_noc_type; - mon_dvfs_in : in monitor_dvfs_type; - mon_acc : out monitor_acc_type; - mon_cache : out monitor_cache_type; - mon_dvfs : out monitor_dvfs_type - ); - -end; + sys_clk_int : in std_logic; + noc1_data_n_in : in coh_noc_flit_type; + noc1_data_s_in : in coh_noc_flit_type; + noc1_data_w_in : in coh_noc_flit_type; + noc1_data_e_in : in coh_noc_flit_type; + noc1_data_void_in : in std_logic_vector(3 downto 0); + noc1_stop_in : in std_logic_vector(3 downto 0); + noc1_data_n_out : out coh_noc_flit_type; + noc1_data_s_out : out coh_noc_flit_type; + noc1_data_w_out : out coh_noc_flit_type; + noc1_data_e_out : out coh_noc_flit_type; + noc1_data_void_out : out std_logic_vector(3 downto 0); + noc1_stop_out : out std_logic_vector(3 downto 0); + noc2_data_n_in : in coh_noc_flit_type; + noc2_data_s_in : in coh_noc_flit_type; + noc2_data_w_in : in coh_noc_flit_type; + noc2_data_e_in : in coh_noc_flit_type; + noc2_data_void_in : in std_logic_vector(3 downto 0); + noc2_stop_in : in std_logic_vector(3 downto 0); + noc2_data_n_out : out coh_noc_flit_type; + noc2_data_s_out : out coh_noc_flit_type; + noc2_data_w_out : out coh_noc_flit_type; + noc2_data_e_out : out coh_noc_flit_type; + noc2_data_void_out : out std_logic_vector(3 downto 0); + noc2_stop_out : out std_logic_vector(3 downto 0); + noc3_data_n_in : in coh_noc_flit_type; + noc3_data_s_in : in coh_noc_flit_type; + noc3_data_w_in : in coh_noc_flit_type; + noc3_data_e_in : in coh_noc_flit_type; + noc3_data_void_in : in std_logic_vector(3 downto 0); + noc3_stop_in : in std_logic_vector(3 downto 0); + noc3_data_n_out : out coh_noc_flit_type; + noc3_data_s_out : out coh_noc_flit_type; + noc3_data_w_out : out coh_noc_flit_type; + noc3_data_e_out : out coh_noc_flit_type; + noc3_data_void_out : out std_logic_vector(3 downto 0); + noc3_stop_out : out std_logic_vector(3 downto 0); + noc4_data_n_in : in dma_noc_flit_type; + noc4_data_s_in : in dma_noc_flit_type; + noc4_data_w_in : in dma_noc_flit_type; + noc4_data_e_in : in dma_noc_flit_type; + noc4_data_void_in : in std_logic_vector(3 downto 0); + noc4_stop_in : in std_logic_vector(3 downto 0); + noc4_data_n_out : out dma_noc_flit_type; + noc4_data_s_out : out dma_noc_flit_type; + noc4_data_w_out : out dma_noc_flit_type; + noc4_data_e_out : out dma_noc_flit_type; + noc4_data_void_out : out std_logic_vector(3 downto 0); + noc4_stop_out : out std_logic_vector(3 downto 0); + noc5_data_n_in : in misc_noc_flit_type; + noc5_data_s_in : in misc_noc_flit_type; + noc5_data_w_in : in misc_noc_flit_type; + noc5_data_e_in : in misc_noc_flit_type; + noc5_data_void_in : in std_logic_vector(3 downto 0); + noc5_stop_in : in std_logic_vector(3 downto 0); + noc5_data_n_out : out misc_noc_flit_type; + noc5_data_s_out : out misc_noc_flit_type; + noc5_data_w_out : out misc_noc_flit_type; + noc5_data_e_out : out misc_noc_flit_type; + noc5_data_void_out : out std_logic_vector(3 downto 0); + noc5_stop_out : out std_logic_vector(3 downto 0); + noc6_data_n_in : in dma_noc_flit_type; + noc6_data_s_in : in dma_noc_flit_type; + noc6_data_w_in : in dma_noc_flit_type; + noc6_data_e_in : in dma_noc_flit_type; + noc6_data_void_in : in std_logic_vector(3 downto 0); + noc6_stop_in : in std_logic_vector(3 downto 0); + noc6_data_n_out : out dma_noc_flit_type; + noc6_data_s_out : out dma_noc_flit_type; + noc6_data_w_out : out dma_noc_flit_type; + noc6_data_e_out : out dma_noc_flit_type; + noc6_data_void_out : out std_logic_vector(3 downto 0); + noc6_stop_out : out std_logic_vector(3 downto 0); + noc1_mon_noc_vec : out monitor_noc_type; + noc2_mon_noc_vec : out monitor_noc_type; + noc3_mon_noc_vec : out monitor_noc_type; + noc4_mon_noc_vec : out monitor_noc_type; + noc5_mon_noc_vec : out monitor_noc_type; + noc6_mon_noc_vec : out monitor_noc_type; + mon_dvfs_in : in monitor_dvfs_type; + mon_acc : out monitor_acc_type; + mon_cache : out monitor_cache_type; + mon_dvfs : out monitor_dvfs_type + ); +end entity fpga_tile_acc; architecture rtl of fpga_tile_acc is @@ -186,12 +186,12 @@ architecture rtl of fpga_tile_acc is signal test6_data_void_in_s : std_ulogic; signal test6_stop_out_s : std_ulogic; - signal noc1_mon_noc_vec_int : monitor_noc_type; - signal noc2_mon_noc_vec_int : monitor_noc_type; - signal noc3_mon_noc_vec_int : monitor_noc_type; - signal noc4_mon_noc_vec_int : monitor_noc_type; - signal noc5_mon_noc_vec_int : monitor_noc_type; - signal noc6_mon_noc_vec_int : monitor_noc_type; + signal noc1_mon_noc_vec_int : monitor_noc_type; + signal noc2_mon_noc_vec_int : monitor_noc_type; + signal noc3_mon_noc_vec_int : monitor_noc_type; + signal noc4_mon_noc_vec_int : monitor_noc_type; + signal noc5_mon_noc_vec_int : monitor_noc_type; + signal noc6_mon_noc_vec_int : monitor_noc_type; -- Noc signals signal noc1_stop_in_s : std_logic_vector(4 downto 0); @@ -262,108 +262,108 @@ architecture rtl of fpga_tile_acc is attribute keep of noc1_acc_data_void_out : signal is "true"; attribute keep of noc1_input_port : signal is "true"; attribute keep of noc1_output_port : signal is "true"; - attribute keep of noc1_data_n_in : signal is "true"; - attribute keep of noc1_data_s_in : signal is "true"; - attribute keep of noc1_data_w_in : signal is "true"; - attribute keep of noc1_data_e_in : signal is "true"; - attribute keep of noc1_data_void_in : signal is "true"; - attribute keep of noc1_stop_in : signal is "true"; - attribute keep of noc1_data_n_out : signal is "true"; - attribute keep of noc1_data_s_out : signal is "true"; - attribute keep of noc1_data_w_out : signal is "true"; - attribute keep of noc1_data_e_out : signal is "true"; - attribute keep of noc1_data_void_out : signal is "true"; - attribute keep of noc1_stop_out : signal is "true"; + attribute keep of noc1_data_n_in : signal is "true"; + attribute keep of noc1_data_s_in : signal is "true"; + attribute keep of noc1_data_w_in : signal is "true"; + attribute keep of noc1_data_e_in : signal is "true"; + attribute keep of noc1_data_void_in : signal is "true"; + attribute keep of noc1_stop_in : signal is "true"; + attribute keep of noc1_data_n_out : signal is "true"; + attribute keep of noc1_data_s_out : signal is "true"; + attribute keep of noc1_data_w_out : signal is "true"; + attribute keep of noc1_data_e_out : signal is "true"; + attribute keep of noc1_data_void_out : signal is "true"; + attribute keep of noc1_stop_out : signal is "true"; attribute keep of noc2_acc_stop_in : signal is "true"; attribute keep of noc2_acc_stop_out : signal is "true"; attribute keep of noc2_acc_data_void_in : signal is "true"; attribute keep of noc2_acc_data_void_out : signal is "true"; attribute keep of noc2_input_port : signal is "true"; attribute keep of noc2_output_port : signal is "true"; - attribute keep of noc2_data_n_in : signal is "true"; - attribute keep of noc2_data_s_in : signal is "true"; - attribute keep of noc2_data_w_in : signal is "true"; - attribute keep of noc2_data_e_in : signal is "true"; - attribute keep of noc2_data_void_in : signal is "true"; - attribute keep of noc2_stop_in : signal is "true"; - attribute keep of noc2_data_n_out : signal is "true"; - attribute keep of noc2_data_s_out : signal is "true"; - attribute keep of noc2_data_w_out : signal is "true"; - attribute keep of noc2_data_e_out : signal is "true"; - attribute keep of noc2_data_void_out : signal is "true"; - attribute keep of noc2_stop_out : signal is "true"; + attribute keep of noc2_data_n_in : signal is "true"; + attribute keep of noc2_data_s_in : signal is "true"; + attribute keep of noc2_data_w_in : signal is "true"; + attribute keep of noc2_data_e_in : signal is "true"; + attribute keep of noc2_data_void_in : signal is "true"; + attribute keep of noc2_stop_in : signal is "true"; + attribute keep of noc2_data_n_out : signal is "true"; + attribute keep of noc2_data_s_out : signal is "true"; + attribute keep of noc2_data_w_out : signal is "true"; + attribute keep of noc2_data_e_out : signal is "true"; + attribute keep of noc2_data_void_out : signal is "true"; + attribute keep of noc2_stop_out : signal is "true"; attribute keep of noc3_acc_stop_in : signal is "true"; attribute keep of noc3_acc_stop_out : signal is "true"; attribute keep of noc3_acc_data_void_in : signal is "true"; attribute keep of noc3_acc_data_void_out : signal is "true"; attribute keep of noc3_input_port : signal is "true"; attribute keep of noc3_output_port : signal is "true"; - attribute keep of noc3_data_n_in : signal is "true"; - attribute keep of noc3_data_s_in : signal is "true"; - attribute keep of noc3_data_w_in : signal is "true"; - attribute keep of noc3_data_e_in : signal is "true"; - attribute keep of noc3_data_void_in : signal is "true"; - attribute keep of noc3_stop_in : signal is "true"; - attribute keep of noc3_data_n_out : signal is "true"; - attribute keep of noc3_data_s_out : signal is "true"; - attribute keep of noc3_data_w_out : signal is "true"; - attribute keep of noc3_data_e_out : signal is "true"; - attribute keep of noc3_data_void_out : signal is "true"; - attribute keep of noc3_stop_out : signal is "true"; + attribute keep of noc3_data_n_in : signal is "true"; + attribute keep of noc3_data_s_in : signal is "true"; + attribute keep of noc3_data_w_in : signal is "true"; + attribute keep of noc3_data_e_in : signal is "true"; + attribute keep of noc3_data_void_in : signal is "true"; + attribute keep of noc3_stop_in : signal is "true"; + attribute keep of noc3_data_n_out : signal is "true"; + attribute keep of noc3_data_s_out : signal is "true"; + attribute keep of noc3_data_w_out : signal is "true"; + attribute keep of noc3_data_e_out : signal is "true"; + attribute keep of noc3_data_void_out : signal is "true"; + attribute keep of noc3_stop_out : signal is "true"; attribute keep of noc4_acc_stop_in : signal is "true"; attribute keep of noc4_acc_stop_out : signal is "true"; attribute keep of noc4_acc_data_void_in : signal is "true"; attribute keep of noc4_acc_data_void_out : signal is "true"; attribute keep of noc4_input_port : signal is "true"; attribute keep of noc4_output_port : signal is "true"; - attribute keep of noc4_data_n_in : signal is "true"; - attribute keep of noc4_data_s_in : signal is "true"; - attribute keep of noc4_data_w_in : signal is "true"; - attribute keep of noc4_data_e_in : signal is "true"; - attribute keep of noc4_data_void_in : signal is "true"; - attribute keep of noc4_stop_in : signal is "true"; - attribute keep of noc4_data_n_out : signal is "true"; - attribute keep of noc4_data_s_out : signal is "true"; - attribute keep of noc4_data_w_out : signal is "true"; - attribute keep of noc4_data_e_out : signal is "true"; - attribute keep of noc4_data_void_out : signal is "true"; - attribute keep of noc4_stop_out : signal is "true"; + attribute keep of noc4_data_n_in : signal is "true"; + attribute keep of noc4_data_s_in : signal is "true"; + attribute keep of noc4_data_w_in : signal is "true"; + attribute keep of noc4_data_e_in : signal is "true"; + attribute keep of noc4_data_void_in : signal is "true"; + attribute keep of noc4_stop_in : signal is "true"; + attribute keep of noc4_data_n_out : signal is "true"; + attribute keep of noc4_data_s_out : signal is "true"; + attribute keep of noc4_data_w_out : signal is "true"; + attribute keep of noc4_data_e_out : signal is "true"; + attribute keep of noc4_data_void_out : signal is "true"; + attribute keep of noc4_stop_out : signal is "true"; attribute keep of noc5_acc_stop_in : signal is "true"; attribute keep of noc5_acc_stop_out : signal is "true"; attribute keep of noc5_acc_data_void_in : signal is "true"; attribute keep of noc5_acc_data_void_out : signal is "true"; attribute keep of noc5_input_port : signal is "true"; attribute keep of noc5_output_port : signal is "true"; - attribute keep of noc5_data_n_in : signal is "true"; - attribute keep of noc5_data_s_in : signal is "true"; - attribute keep of noc5_data_w_in : signal is "true"; - attribute keep of noc5_data_e_in : signal is "true"; - attribute keep of noc5_data_void_in : signal is "true"; - attribute keep of noc5_stop_in : signal is "true"; - attribute keep of noc5_data_n_out : signal is "true"; - attribute keep of noc5_data_s_out : signal is "true"; - attribute keep of noc5_data_w_out : signal is "true"; - attribute keep of noc5_data_e_out : signal is "true"; - attribute keep of noc5_data_void_out : signal is "true"; - attribute keep of noc5_stop_out : signal is "true"; + attribute keep of noc5_data_n_in : signal is "true"; + attribute keep of noc5_data_s_in : signal is "true"; + attribute keep of noc5_data_w_in : signal is "true"; + attribute keep of noc5_data_e_in : signal is "true"; + attribute keep of noc5_data_void_in : signal is "true"; + attribute keep of noc5_stop_in : signal is "true"; + attribute keep of noc5_data_n_out : signal is "true"; + attribute keep of noc5_data_s_out : signal is "true"; + attribute keep of noc5_data_w_out : signal is "true"; + attribute keep of noc5_data_e_out : signal is "true"; + attribute keep of noc5_data_void_out : signal is "true"; + attribute keep of noc5_stop_out : signal is "true"; attribute keep of noc6_acc_stop_in : signal is "true"; attribute keep of noc6_acc_stop_out : signal is "true"; attribute keep of noc6_acc_data_void_in : signal is "true"; attribute keep of noc6_acc_data_void_out : signal is "true"; attribute keep of noc6_input_port : signal is "true"; attribute keep of noc6_output_port : signal is "true"; - attribute keep of noc6_data_n_in : signal is "true"; - attribute keep of noc6_data_s_in : signal is "true"; - attribute keep of noc6_data_w_in : signal is "true"; - attribute keep of noc6_data_e_in : signal is "true"; - attribute keep of noc6_data_void_in : signal is "true"; - attribute keep of noc6_stop_in : signal is "true"; - attribute keep of noc6_data_n_out : signal is "true"; - attribute keep of noc6_data_s_out : signal is "true"; - attribute keep of noc6_data_w_out : signal is "true"; - attribute keep of noc6_data_e_out : signal is "true"; - attribute keep of noc6_data_void_out : signal is "true"; - attribute keep of noc6_stop_out : signal is "true"; + attribute keep of noc6_data_n_in : signal is "true"; + attribute keep of noc6_data_s_in : signal is "true"; + attribute keep of noc6_data_w_in : signal is "true"; + attribute keep of noc6_data_e_in : signal is "true"; + attribute keep of noc6_data_void_in : signal is "true"; + attribute keep of noc6_stop_in : signal is "true"; + attribute keep of noc6_data_n_out : signal is "true"; + attribute keep of noc6_data_s_out : signal is "true"; + attribute keep of noc6_data_w_out : signal is "true"; + attribute keep of noc6_data_e_out : signal is "true"; + attribute keep of noc6_data_void_out : signal is "true"; + attribute keep of noc6_stop_out : signal is "true"; begin @@ -377,9 +377,10 @@ begin ----------------------------------------------------------------------------- -- JTAG for single tile testing / bypass when test_if_en = 0 ----------------------------------------------------------------------------- - jtag_test_i : jtag_test + jtag_test_i : component jtag_test generic map ( - test_if_en => 0) + test_if_en => 0 + ) port map ( rst => rst, refclk => refclk, @@ -459,172 +460,175 @@ begin noc5_stop_out => noc5_acc_stop_out, noc6_input_port => noc6_input_port, noc6_data_void_in => noc6_acc_data_void_in, - noc6_stop_out => noc6_acc_stop_out); + noc6_stop_out => noc6_acc_stop_out + ); ----------------------------------------------------------------------------- -- NOC Connections ---------------------------------------------------------------------------- - noc1_stop_in_s <= noc1_acc_stop_in & noc1_stop_in; + noc1_stop_in_s <= noc1_acc_stop_in & noc1_stop_in; noc1_stop_out <= noc1_stop_out_s(3 downto 0); noc1_acc_stop_out <= noc1_stop_out_s(4); noc1_data_void_in_s <= noc1_acc_data_void_in & noc1_data_void_in; noc1_data_void_out <= noc1_data_void_out_s(3 downto 0); noc1_acc_data_void_out <= noc1_data_void_out_s(4); - noc2_stop_in_s <= noc2_acc_stop_in & noc2_stop_in; + noc2_stop_in_s <= noc2_acc_stop_in & noc2_stop_in; noc2_stop_out <= noc2_stop_out_s(3 downto 0); noc2_acc_stop_out <= noc2_stop_out_s(4); noc2_data_void_in_s <= noc2_acc_data_void_in & noc2_data_void_in; noc2_data_void_out <= noc2_data_void_out_s(3 downto 0); noc2_acc_data_void_out <= noc2_data_void_out_s(4); - noc3_stop_in_s <= noc3_acc_stop_in & noc3_stop_in; + noc3_stop_in_s <= noc3_acc_stop_in & noc3_stop_in; noc3_stop_out <= noc3_stop_out_s(3 downto 0); noc3_acc_stop_out <= noc3_stop_out_s(4); noc3_data_void_in_s <= noc3_acc_data_void_in & noc3_data_void_in; noc3_data_void_out <= noc3_data_void_out_s(3 downto 0); noc3_acc_data_void_out <= noc3_data_void_out_s(4); - noc4_stop_in_s <= noc4_acc_stop_in & noc4_stop_in; + noc4_stop_in_s <= noc4_acc_stop_in & noc4_stop_in; noc4_stop_out <= noc4_stop_out_s(3 downto 0); noc4_acc_stop_out <= noc4_stop_out_s(4); noc4_data_void_in_s <= noc4_acc_data_void_in & noc4_data_void_in; noc4_data_void_out <= noc4_data_void_out_s(3 downto 0); noc4_acc_data_void_out <= noc4_data_void_out_s(4); - noc5_stop_in_s <= noc5_acc_stop_in & noc5_stop_in; + noc5_stop_in_s <= noc5_acc_stop_in & noc5_stop_in; noc5_stop_out <= noc5_stop_out_s(3 downto 0); noc5_acc_stop_out <= noc5_stop_out_s(4); noc5_data_void_in_s <= noc5_acc_data_void_in & noc5_data_void_in; noc5_data_void_out <= noc5_data_void_out_s(3 downto 0); noc5_acc_data_void_out <= noc5_data_void_out_s(4); - noc6_stop_in_s <= noc6_acc_stop_in & noc6_stop_in; + noc6_stop_in_s <= noc6_acc_stop_in & noc6_stop_in; noc6_stop_out <= noc6_stop_out_s(3 downto 0); noc6_acc_stop_out <= noc6_stop_out_s(4); noc6_data_void_in_s <= noc6_acc_data_void_in & noc6_data_void_in; noc6_data_void_out <= noc6_data_void_out_s(3 downto 0); noc6_acc_data_void_out <= noc6_data_void_out_s(4); - sync_noc_set_acc: sync_noc_set - generic map ( - PORTS => ROUTER_PORTS, - HAS_SYNC => HAS_SYNC ) - port map ( - clk => sys_clk_int, - clk_tile => refclk, - rst => rst, - rst_tile => dco_rstn, - CONST_local_x => this_local_x, - CONST_local_y => this_local_y, - noc1_data_n_in => noc1_data_n_in, - noc1_data_s_in => noc1_data_s_in, - noc1_data_w_in => noc1_data_w_in, - noc1_data_e_in => noc1_data_e_in, - noc1_input_port => noc1_input_port, - noc1_data_void_in => noc1_data_void_in_s, - noc1_stop_in => noc1_stop_in_s, - noc1_data_n_out => noc1_data_n_out, - noc1_data_s_out => noc1_data_s_out, - noc1_data_w_out => noc1_data_w_out, - noc1_data_e_out => noc1_data_e_out, - noc1_output_port => noc1_output_port, - noc1_data_void_out => noc1_data_void_out_s, - noc1_stop_out => noc1_stop_out_s, - noc2_data_n_in => noc2_data_n_in, - noc2_data_s_in => noc2_data_s_in, - noc2_data_w_in => noc2_data_w_in, - noc2_data_e_in => noc2_data_e_in, - noc2_input_port => noc2_input_port, - noc2_data_void_in => noc2_data_void_in_s, - noc2_stop_in => noc2_stop_in_s, - noc2_data_n_out => noc2_data_n_out, - noc2_data_s_out => noc2_data_s_out, - noc2_data_w_out => noc2_data_w_out, - noc2_data_e_out => noc2_data_e_out, - noc2_output_port => noc2_output_port, - noc2_data_void_out => noc2_data_void_out_s, - noc2_stop_out => noc2_stop_out_s, - noc3_data_n_in => noc3_data_n_in, - noc3_data_s_in => noc3_data_s_in, - noc3_data_w_in => noc3_data_w_in, - noc3_data_e_in => noc3_data_e_in, - noc3_input_port => noc3_input_port, - noc3_data_void_in => noc3_data_void_in_s, - noc3_stop_in => noc3_stop_in_s, - noc3_data_n_out => noc3_data_n_out, - noc3_data_s_out => noc3_data_s_out, - noc3_data_w_out => noc3_data_w_out, - noc3_data_e_out => noc3_data_e_out, - noc3_output_port => noc3_output_port, - noc3_data_void_out => noc3_data_void_out_s, - noc3_stop_out => noc3_stop_out_s, - noc4_data_n_in => noc4_data_n_in, - noc4_data_s_in => noc4_data_s_in, - noc4_data_w_in => noc4_data_w_in, - noc4_data_e_in => noc4_data_e_in, - noc4_input_port => noc4_input_port, - noc4_data_void_in => noc4_data_void_in_s, - noc4_stop_in => noc4_stop_in_s, - noc4_data_n_out => noc4_data_n_out, - noc4_data_s_out => noc4_data_s_out, - noc4_data_w_out => noc4_data_w_out, - noc4_data_e_out => noc4_data_e_out, - noc4_output_port => noc4_output_port, - noc4_data_void_out => noc4_data_void_out_s, - noc4_stop_out => noc4_stop_out_s, - noc5_data_n_in => noc5_data_n_in, - noc5_data_s_in => noc5_data_s_in, - noc5_data_w_in => noc5_data_w_in, - noc5_data_e_in => noc5_data_e_in, - noc5_input_port => noc5_input_port, - noc5_data_void_in => noc5_data_void_in_s, - noc5_stop_in => noc5_stop_in_s, - noc5_data_n_out => noc5_data_n_out, - noc5_data_s_out => noc5_data_s_out, - noc5_data_w_out => noc5_data_w_out, - noc5_data_e_out => noc5_data_e_out, - noc5_output_port => noc5_output_port, - noc5_data_void_out => noc5_data_void_out_s, - noc5_stop_out => noc5_stop_out_s, - noc6_data_n_in => noc6_data_n_in, - noc6_data_s_in => noc6_data_s_in, - noc6_data_w_in => noc6_data_w_in, - noc6_data_e_in => noc6_data_e_in, - noc6_input_port => noc6_input_port, - noc6_data_void_in => noc6_data_void_in_s, - noc6_stop_in => noc6_stop_in_s, - noc6_data_n_out => noc6_data_n_out, - noc6_data_s_out => noc6_data_s_out, - noc6_data_w_out => noc6_data_w_out, - noc6_data_e_out => noc6_data_e_out, - noc6_output_port => noc6_output_port, - noc6_data_void_out => noc6_data_void_out_s, - noc6_stop_out => noc6_stop_out_s, - noc1_mon_noc_vec => noc1_mon_noc_vec_int, - noc2_mon_noc_vec => noc2_mon_noc_vec_int, - noc3_mon_noc_vec => noc3_mon_noc_vec_int, - noc4_mon_noc_vec => noc4_mon_noc_vec_int, - noc5_mon_noc_vec => noc5_mon_noc_vec_int, - noc6_mon_noc_vec => noc6_mon_noc_vec_int - ); + sync_noc_set_acc : component sync_noc_set + generic map ( + ports => ROUTER_PORTS, + has_sync => HAS_SYNC + ) + port map ( + clk => sys_clk_int, + clk_tile => refclk, + rst => rst, + rst_tile => dco_rstn, + const_local_x => this_local_x, + const_local_y => this_local_y, + noc1_data_n_in => noc1_data_n_in, + noc1_data_s_in => noc1_data_s_in, + noc1_data_w_in => noc1_data_w_in, + noc1_data_e_in => noc1_data_e_in, + noc1_input_port => noc1_input_port, + noc1_data_void_in => noc1_data_void_in_s, + noc1_stop_in => noc1_stop_in_s, + noc1_data_n_out => noc1_data_n_out, + noc1_data_s_out => noc1_data_s_out, + noc1_data_w_out => noc1_data_w_out, + noc1_data_e_out => noc1_data_e_out, + noc1_output_port => noc1_output_port, + noc1_data_void_out => noc1_data_void_out_s, + noc1_stop_out => noc1_stop_out_s, + noc2_data_n_in => noc2_data_n_in, + noc2_data_s_in => noc2_data_s_in, + noc2_data_w_in => noc2_data_w_in, + noc2_data_e_in => noc2_data_e_in, + noc2_input_port => noc2_input_port, + noc2_data_void_in => noc2_data_void_in_s, + noc2_stop_in => noc2_stop_in_s, + noc2_data_n_out => noc2_data_n_out, + noc2_data_s_out => noc2_data_s_out, + noc2_data_w_out => noc2_data_w_out, + noc2_data_e_out => noc2_data_e_out, + noc2_output_port => noc2_output_port, + noc2_data_void_out => noc2_data_void_out_s, + noc2_stop_out => noc2_stop_out_s, + noc3_data_n_in => noc3_data_n_in, + noc3_data_s_in => noc3_data_s_in, + noc3_data_w_in => noc3_data_w_in, + noc3_data_e_in => noc3_data_e_in, + noc3_input_port => noc3_input_port, + noc3_data_void_in => noc3_data_void_in_s, + noc3_stop_in => noc3_stop_in_s, + noc3_data_n_out => noc3_data_n_out, + noc3_data_s_out => noc3_data_s_out, + noc3_data_w_out => noc3_data_w_out, + noc3_data_e_out => noc3_data_e_out, + noc3_output_port => noc3_output_port, + noc3_data_void_out => noc3_data_void_out_s, + noc3_stop_out => noc3_stop_out_s, + noc4_data_n_in => noc4_data_n_in, + noc4_data_s_in => noc4_data_s_in, + noc4_data_w_in => noc4_data_w_in, + noc4_data_e_in => noc4_data_e_in, + noc4_input_port => noc4_input_port, + noc4_data_void_in => noc4_data_void_in_s, + noc4_stop_in => noc4_stop_in_s, + noc4_data_n_out => noc4_data_n_out, + noc4_data_s_out => noc4_data_s_out, + noc4_data_w_out => noc4_data_w_out, + noc4_data_e_out => noc4_data_e_out, + noc4_output_port => noc4_output_port, + noc4_data_void_out => noc4_data_void_out_s, + noc4_stop_out => noc4_stop_out_s, + noc5_data_n_in => noc5_data_n_in, + noc5_data_s_in => noc5_data_s_in, + noc5_data_w_in => noc5_data_w_in, + noc5_data_e_in => noc5_data_e_in, + noc5_input_port => noc5_input_port, + noc5_data_void_in => noc5_data_void_in_s, + noc5_stop_in => noc5_stop_in_s, + noc5_data_n_out => noc5_data_n_out, + noc5_data_s_out => noc5_data_s_out, + noc5_data_w_out => noc5_data_w_out, + noc5_data_e_out => noc5_data_e_out, + noc5_output_port => noc5_output_port, + noc5_data_void_out => noc5_data_void_out_s, + noc5_stop_out => noc5_stop_out_s, + noc6_data_n_in => noc6_data_n_in, + noc6_data_s_in => noc6_data_s_in, + noc6_data_w_in => noc6_data_w_in, + noc6_data_e_in => noc6_data_e_in, + noc6_input_port => noc6_input_port, + noc6_data_void_in => noc6_data_void_in_s, + noc6_stop_in => noc6_stop_in_s, + noc6_data_n_out => noc6_data_n_out, + noc6_data_s_out => noc6_data_s_out, + noc6_data_w_out => noc6_data_w_out, + noc6_data_e_out => noc6_data_e_out, + noc6_output_port => noc6_output_port, + noc6_data_void_out => noc6_data_void_out_s, + noc6_stop_out => noc6_stop_out_s, + noc1_mon_noc_vec => noc1_mon_noc_vec_int, + noc2_mon_noc_vec => noc2_mon_noc_vec_int, + noc3_mon_noc_vec => noc3_mon_noc_vec_int, + noc4_mon_noc_vec => noc4_mon_noc_vec_int, + noc5_mon_noc_vec => noc5_mon_noc_vec_int, + noc6_mon_noc_vec => noc6_mon_noc_vec_int + ); - tile_acc_1: tile_acc + tile_acc_1 : component tile_acc generic map ( this_hls_conf => this_hls_conf, this_device => this_device, this_irq_type => this_irq_type, this_has_l2 => this_has_l2, - this_has_dvfs => this_has_dvfs, -- no DVFS controller + this_has_dvfs => this_has_dvfs, this_has_pll => this_has_pll, - this_has_dco => 0, - this_extra_clk_buf => this_extra_clk_buf) + this_has_dco => 0, + this_extra_clk_buf => this_extra_clk_buf + ) port map ( - raw_rstn => raw_rstn, - tile_rst => rst, - refclk => refclk, - pllbypass => pllbypass, - pllclk => pllclk, - dco_clk => dco_clk, - dco_rstn => dco_rstn, - pad_cfg => open, - local_x => this_local_x, - local_y => this_local_y, + raw_rstn => raw_rstn, + tile_rst => rst, + refclk => refclk, + pllbypass => pllbypass, + pllclk => pllclk, + dco_clk => dco_clk, + dco_rstn => dco_rstn, + pad_cfg => open, + local_x => this_local_x, + local_y => this_local_y, test1_output_port => test1_output_port_s, test1_data_void_out => test1_data_void_out_s, test1_stop_in => test1_stop_out_s, @@ -671,5 +675,6 @@ begin mon_acc => mon_acc, mon_cache => mon_cache, mon_dvfs => mon_dvfs - ); -end; + ); + +end architecture rtl; diff --git a/socs/epochs0-gf12/EPOCHS0_TOP.vhd b/socs/epochs0-gf12/EPOCHS0_TOP.vhd index cce0784c3b..775c243d59 100644 --- a/socs/epochs0-gf12/EPOCHS0_TOP.vhd +++ b/socs/epochs0-gf12/EPOCHS0_TOP.vhd @@ -2,52 +2,53 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_misc.all; -use work.esp_global.all; -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; -use work.gencomp.all; -use work.leon3.all; -use work.net.all; --- pragma translate_off -use work.sim.all; + use ieee.std_logic_1164.all; + use ieee.std_logic_misc.all; + use work.esp_global.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.leon3.all; + use work.net.all; + -- pragma translate_off + use work.sim.all; + library unisim; -use unisim.all; --- pragma translate_on -use work.monitor_pkg.all; -use work.esp_csr_pkg.all; -use work.sldacc.all; -use work.tile.all; -use work.nocpackage.all; -use work.coretypes.all; -use work.grlib_config.all; -use work.socmap.all; -use work.tiles_asic_pkg.all; -use work.pads_loc.all; - - -entity EPOCHS0_TOP is + use unisim.all; + -- pragma translate_on + use work.monitor_pkg.all; + use work.esp_csr_pkg.all; + use work.sldacc.all; + use work.tile.all; + use work.nocpackage.all; + use work.coretypes.all; + use work.grlib_config.all; + use work.socmap.all; + use work.tiles_asic_pkg.all; + use work.pads_loc.all; + +entity epochs0_top is generic ( - SIMULATION : boolean := false); + simulation : boolean := false + ); port ( - reset : in std_logic; + reset : in std_logic; -- Backup external clocks for selected tiles and NoC - ext_clk_noc : in std_logic; - ext_clk_io : in std_logic; - ext_clk_cpu : in std_logic; - ext_clk_mem : in std_logic; - ext_clk_acc0 : in std_logic; - ext_clk_acc1 : in std_logic; + ext_clk_noc : in std_logic; + ext_clk_io : in std_logic; + ext_clk_cpu : in std_logic; + ext_clk_mem : in std_logic; + ext_clk_acc0 : in std_logic; + ext_clk_acc1 : in std_logic; -- Test clock output (DCO divided clock) for selected tiles and NoC - clk_div_noc : out std_logic; - clk_div_io : out std_logic; - clk_div_cpu : out std_logic; - clk_div_mem : out std_logic; - clk_div_acc0 : out std_logic; - clk_div_acc1 : out std_logic; + clk_div_noc : out std_logic; + clk_div_io : out std_logic; + clk_div_cpu : out std_logic; + clk_div_mem : out std_logic; + clk_div_acc0 : out std_logic; + clk_div_acc1 : out std_logic; -- FPGA proxy memory link fpga_data : inout std_logic_vector(4 * CFG_MEM_LINK_BITS - 1 downto 0); fpga_valid_in : in std_logic_vector(3 downto 0); @@ -57,44 +58,44 @@ entity EPOCHS0_TOP is fpga_credit_in : in std_logic_vector(3 downto 0); fpga_credit_out : out std_logic_vector(3 downto 0); -- Test interface - tdi_cpu : in std_logic; - tdi_io : in std_logic; - tdi_mem : in std_logic; - tdi_acc0 : in std_logic; - tdi_acc1 : in std_logic; - tdi_acc2 : in std_logic; - tdi_acc3 : in std_logic; - tdi_acc4 : in std_logic; - tdi_acc5 : in std_logic; - tdi_acc6 : in std_logic; - tdi_acc7 : in std_logic; - tdo_cpu : out std_logic; - tdo_io : out std_logic; - tdo_mem : out std_logic; - tdo_acc0 : out std_logic; - tdo_acc1 : out std_logic; - tdo_acc2 : out std_logic; - tdo_acc3 : out std_logic; - tdo_acc4 : out std_logic; - tdo_acc5 : out std_logic; - tdo_acc6 : out std_logic; - tdo_acc7 : out std_logic; - tms : in std_logic; - tclk : in std_logic; + tdi_cpu : in std_logic; + tdi_io : in std_logic; + tdi_mem : in std_logic; + tdi_acc0 : in std_logic; + tdi_acc1 : in std_logic; + tdi_acc2 : in std_logic; + tdi_acc3 : in std_logic; + tdi_acc4 : in std_logic; + tdi_acc5 : in std_logic; + tdi_acc6 : in std_logic; + tdi_acc7 : in std_logic; + tdo_cpu : out std_logic; + tdo_io : out std_logic; + tdo_mem : out std_logic; + tdo_acc0 : out std_logic; + tdo_acc1 : out std_logic; + tdo_acc2 : out std_logic; + tdo_acc3 : out std_logic; + tdo_acc4 : out std_logic; + tdo_acc5 : out std_logic; + tdo_acc6 : out std_logic; + tdo_acc7 : out std_logic; + tms : in std_logic; + tclk : in std_logic; -- Ethernet signals - reset_o2 : out std_ulogic; - etx_clk : in std_ulogic; - erx_clk : in std_ulogic; - erxd : in std_logic_vector(3 downto 0); - erx_dv : in std_ulogic; - erx_er : in std_ulogic; - erx_col : in std_ulogic; - erx_crs : in std_ulogic; - etxd : out std_logic_vector(3 downto 0); - etx_en : out std_ulogic; - etx_er : out std_ulogic; - emdc : out std_ulogic; - emdio : inout std_logic; + reset_o2 : out std_ulogic; + etx_clk : in std_ulogic; + erx_clk : in std_ulogic; + erxd : in std_logic_vector(3 downto 0); + erx_dv : in std_ulogic; + erx_er : in std_ulogic; + erx_col : in std_ulogic; + erx_crs : in std_ulogic; + etxd : out std_logic_vector(3 downto 0); + etx_en : out std_ulogic; + etx_er : out std_ulogic; + emdc : out std_ulogic; + emdio : inout std_logic; -- -- DVI -- tft_nhpd : in std_ulogic; -- Hot plug -- tft_clk_p : out std_ulogic; @@ -113,153 +114,153 @@ entity EPOCHS0_TOP is -- tft_edge : out std_ulogic; -- tft_npd : out std_ulogic; -- LPDDR0 - lpddr0_ck_p : out std_logic; - lpddr0_ck_n : out std_logic; - lpddr0_cke : out std_logic; - lpddr0_ba : out std_logic_vector(2 downto 0); - lpddr0_addr : out std_logic_vector(15 downto 0); - lpddr0_cs_n : out std_logic; - lpddr0_ras_n : out std_logic; - lpddr0_cas_n : out std_logic; - lpddr0_we_n : out std_logic; - lpddr0_reset_n : out std_logic; - lpddr0_odt : out std_logic; - lpddr0_dm : out std_logic_vector(3 downto 0); - lpddr0_dqs_p : inout std_logic_vector(3 downto 0); - lpddr0_dqs_n : inout std_logic_vector(3 downto 0); - lpddr0_dq : inout std_logic_vector(31 downto 0); + lpddr0_ck_p : out std_logic; + lpddr0_ck_n : out std_logic; + lpddr0_cke : out std_logic; + lpddr0_ba : out std_logic_vector(2 downto 0); + lpddr0_addr : out std_logic_vector(15 downto 0); + lpddr0_cs_n : out std_logic; + lpddr0_ras_n : out std_logic; + lpddr0_cas_n : out std_logic; + lpddr0_we_n : out std_logic; + lpddr0_reset_n : out std_logic; + lpddr0_odt : out std_logic; + lpddr0_dm : out std_logic_vector(3 downto 0); + lpddr0_dqs_p : inout std_logic_vector(3 downto 0); + lpddr0_dqs_n : inout std_logic_vector(3 downto 0); + lpddr0_dq : inout std_logic_vector(31 downto 0); -- LPDDR1 - lpddr1_ck_p : out std_logic; - lpddr1_ck_n : out std_logic; - lpddr1_cke : out std_logic; - lpddr1_ba : out std_logic_vector(2 downto 0); - lpddr1_addr : out std_logic_vector(15 downto 0); - lpddr1_cs_n : out std_logic; - lpddr1_ras_n : out std_logic; - lpddr1_cas_n : out std_logic; - lpddr1_we_n : out std_logic; - lpddr1_reset_n : out std_logic; - lpddr1_odt : out std_logic; - lpddr1_dm : out std_logic_vector(3 downto 0); - lpddr1_dqs_p : inout std_logic_vector(3 downto 0); - lpddr1_dqs_n : inout std_logic_vector(3 downto 0); - lpddr1_dq : inout std_logic_vector(31 downto 0); + lpddr1_ck_p : out std_logic; + lpddr1_ck_n : out std_logic; + lpddr1_cke : out std_logic; + lpddr1_ba : out std_logic_vector(2 downto 0); + lpddr1_addr : out std_logic_vector(15 downto 0); + lpddr1_cs_n : out std_logic; + lpddr1_ras_n : out std_logic; + lpddr1_cas_n : out std_logic; + lpddr1_we_n : out std_logic; + lpddr1_reset_n : out std_logic; + lpddr1_odt : out std_logic; + lpddr1_dm : out std_logic_vector(3 downto 0); + lpddr1_dqs_p : inout std_logic_vector(3 downto 0); + lpddr1_dqs_n : inout std_logic_vector(3 downto 0); + lpddr1_dq : inout std_logic_vector(31 downto 0); -- UART - uart_rxd : in std_logic; -- UART1_RX (u1i.rxd) - uart_txd : out std_logic; -- UART1_TX (u1o.txd) - uart_ctsn : in std_logic; -- UART1_RTSN (u1i.ctsn) - uart_rtsn : out std_logic; -- UART1_RTSN (u1o.rtsn) + uart_rxd : in std_logic; -- UART1_RX (u1i.rxd) + uart_txd : out std_logic; -- UART1_TX (u1o.txd) + uart_ctsn : in std_logic; -- UART1_RTSN (u1i.ctsn) + uart_rtsn : out std_logic; -- UART1_RTSN (u1o.rtsn) -- IVR - ivr_pmb_dat : in std_ulogic; - ivr_pmb_clk : in std_ulogic; - ivr_avs_clk : in std_ulogic; - ivr_avs_dat : in std_ulogic; - ivr_avs_sdat : in std_ulogic; - ivr_control : in std_ulogic; - ivr_gpio : in std_logic_vector(3 downto 0); + ivr_pmb_dat : in std_ulogic; + ivr_pmb_clk : in std_ulogic; + ivr_avs_clk : in std_ulogic; + ivr_avs_dat : in std_ulogic; + ivr_avs_sdat : in std_ulogic; + ivr_control : in std_ulogic; + ivr_gpio : in std_logic_vector(3 downto 0); -- Unused - unused : in std_ulogic - ); -end; - - + unused : in std_ulogic + ); +end entity epochs0_top; -architecture rtl of EPOCHS0_TOP is +architecture rtl of epochs0_top is - - type handshake_vec is array (CFG_TILES_NUM-1 downto 0) of std_logic_vector(3 downto 0); + type handshake_vec is array (CFG_TILES_NUM - 1 downto 0) of std_logic_vector(3 downto 0); -- NOC Signals - signal noc1_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc1_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc1_data_void_in : handshake_vec; signal noc1_stop_in : handshake_vec; - signal noc1_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc1_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc1_data_void_out : handshake_vec; signal noc1_stop_out : handshake_vec; - signal noc2_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc2_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc2_data_void_in : handshake_vec; signal noc2_stop_in : handshake_vec; - signal noc2_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc2_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc2_data_void_out : handshake_vec; signal noc2_stop_out : handshake_vec; - signal noc3_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc3_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc3_data_void_in : handshake_vec; signal noc3_stop_in : handshake_vec; - signal noc3_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc3_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc3_data_void_out : handshake_vec; signal noc3_stop_out : handshake_vec; - signal noc4_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc4_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc4_data_void_in : handshake_vec; signal noc4_stop_in : handshake_vec; - signal noc4_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc4_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc4_data_void_out : handshake_vec; signal noc4_stop_out : handshake_vec; - signal noc5_data_n_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_s_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_w_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_e_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc5_data_n_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_s_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_w_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_e_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc5_data_void_in : handshake_vec; signal noc5_stop_in : handshake_vec; - signal noc5_data_n_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_s_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_w_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_e_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc5_data_n_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_s_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_w_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_e_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc5_data_void_out : handshake_vec; signal noc5_stop_out : handshake_vec; - signal noc6_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc6_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc6_data_void_in : handshake_vec; signal noc6_stop_in : handshake_vec; - signal noc6_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc6_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc6_data_void_out : handshake_vec; signal noc6_stop_out : handshake_vec; -- Global NoC reset and clock - signal sys_clk : std_ulogic; - signal sys_rstn : std_ulogic; + signal sys_clk : std_ulogic; + signal sys_rstn : std_ulogic; signal sys_clk_lock : std_ulogic; -- I/O for PADS - constant pad_fixed_cfg : std_logic_vector(19 - (ESP_CSR_PAD_CFG_MSB - ESP_CSR_PAD_CFG_LSB + 1) downto 0) := (others => '0'); + constant PAD_FIXED_CFG : std_logic_vector(19 - (ESP_CSR_PAD_CFG_MSB - ESP_CSR_PAD_CFG_LSB + 1) downto 0) := (others => '0'); + type pad_cfg_full_array is array (0 to CFG_TILES_NUM - 1) of std_logic_vector(19 downto 0); + type pad_cfg_array is array (0 to CFG_TILES_NUM - 1) of std_logic_vector(ESP_CSR_PAD_CFG_MSB - ESP_CSR_PAD_CFG_LSB downto 0); + -- Current default configuration is SR=0, DS1=1, DS0=1 - signal pad_cfg : pad_cfg_array; + signal pad_cfg : pad_cfg_array; signal full_pad_cfg : pad_cfg_full_array; -- External clocks and reset - signal reset_int : std_logic; - signal ext_clk_int : std_logic_vector(0 to CFG_TILES_NUM - 1); -- backup tile clock - signal clk_div_int : std_logic_vector(0 to CFG_TILES_NUM - 1); -- tile clock monitor for testing purposes + signal reset_int : std_logic; + signal ext_clk_int : std_logic_vector(0 to CFG_TILES_NUM - 1); -- backup tile clock + signal clk_div_int : std_logic_vector(0 to CFG_TILES_NUM - 1); -- tile clock monitor for testing purposes signal ext_clk_noc_int : std_logic; signal clk_div_noc_int : std_logic; @@ -294,21 +295,21 @@ architecture rtl of EPOCHS0_TOP is signal fpga_c_pad_cfg : std_logic_vector(4 * 20 - 1 downto 0); -- Ethernet signals - signal reset_o2_int : std_ulogic; - signal etx_clk_int : std_ulogic; - signal erx_clk_int : std_ulogic; - signal erxd_int : std_logic_vector(3 downto 0); - signal erx_dv_int : std_ulogic; - signal erx_er_int : std_ulogic; - signal erx_col_int : std_ulogic; - signal erx_crs_int : std_ulogic; - signal etxd_int : std_logic_vector(3 downto 0); - signal etx_en_int : std_ulogic; - signal etx_er_int : std_ulogic; - signal emdc_int : std_ulogic; - signal emdio_i : std_logic; - signal emdio_o : std_logic; - signal emdio_oe : std_logic; + signal reset_o2_int : std_ulogic; + signal etx_clk_int : std_ulogic; + signal erx_clk_int : std_ulogic; + signal erxd_int : std_logic_vector(3 downto 0); + signal erx_dv_int : std_ulogic; + signal erx_er_int : std_ulogic; + signal erx_col_int : std_ulogic; + signal erx_crs_int : std_ulogic; + signal etxd_int : std_logic_vector(3 downto 0); + signal etx_en_int : std_ulogic; + signal etx_er_int : std_ulogic; + signal emdc_int : std_ulogic; + signal emdio_i : std_logic; + signal emdio_o : std_logic; + signal emdio_oe : std_logic; -- -- DVI -- signal dvi_nhpd : std_ulogic; -- signal dvi_data : std_logic_vector(23 downto 0); @@ -327,10 +328,10 @@ architecture rtl of EPOCHS0_TOP is -- signal clkvga_p : std_ulogic; -- signal clkvga_n : std_ulogic; -- UART - signal uart_rxd_int : std_logic; -- UART1_RX (u1i.rxd) - signal uart_txd_int : std_logic; -- UART1_TX (u1o.txd) - signal uart_ctsn_int : std_logic; -- UART1_RTSN (u1i.ctsn) - signal uart_rtsn_int : std_logic; -- UART1_RTSN (u1o.rtsn) + signal uart_rxd_int : std_logic; -- UART1_RX (u1i.rxd) + signal uart_txd_int : std_logic; -- UART1_TX (u1o.txd) + signal uart_ctsn_int : std_logic; -- UART1_RTSN (u1i.ctsn) + signal uart_rtsn_int : std_logic; -- UART1_RTSN (u1o.rtsn) begin @@ -339,113 +340,521 @@ begin ----------------------------------------------------------------------------- pad_cfg_gen : for i in 0 to CFG_TILES_NUM - 1 generate - full_pad_cfg(i) <= pad_fixed_cfg & pad_cfg(i); + full_pad_cfg(i) <= PAD_FIXED_CFG & pad_cfg(i); end generate pad_cfg_gen; -- External clocks and reset and test interface - reset_pad : inpad generic map (loc => reset_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (reset, reset_int); + reset_pad : component inpad + generic map ( + loc => reset_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +reset, + reset_int + ); -- ext_clk and div_clk for NoC (DCO located in the I/O tile) - ext_clk_noc_pad : inpad generic map (loc => ext_clk_noc_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ext_clk_noc, ext_clk_noc_int); - clk_div_noc_pad : outpad generic map (loc => clk_div_noc_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (clk_div_noc, clk_div_noc_int, full_pad_cfg(io_tile_id)); + ext_clk_noc_pad : component inpad + generic map ( + loc => ext_clk_noc_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ext_clk_noc, + ext_clk_noc_int + ); + + clk_div_noc_pad : component outpad + generic map ( + loc => clk_div_noc_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +clk_div_noc, + clk_div_noc_int, + full_pad_cfg(io_tile_id) + ); ----------------------------------------------------------------------------- -- chip-specific pads mapping (based on pin availability and selected tiles) -- TODO: add selection for this mapping to ESP GUI -- ext_clk and div_clk for I/O tile - ext_clk_io_pad : inpad generic map (loc => ext_clk_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ext_clk_io, ext_clk_int(io_tile_id)); - clk_div_io_pad : outpad generic map (loc => clk_div_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (clk_div_io, clk_div_int(io_tile_id), full_pad_cfg(io_tile_id)); + ext_clk_io_pad : component inpad + generic map ( + loc => ext_clk_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ext_clk_io, + ext_clk_int(io_tile_id) + ); + + clk_div_io_pad : component outpad + generic map ( + loc => clk_div_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +clk_div_io, + clk_div_int(io_tile_id), + full_pad_cfg(io_tile_id) + ); + -- ext_clk and div_clk for CPU are close to CPU0 - ext_clk_cpu_pad : inpad generic map (loc => ext_clk_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ext_clk_cpu, ext_clk_int(cpu_tile_id(0))); - clk_div_cpu_pad : outpad generic map (loc => clk_div_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (clk_div_cpu, clk_div_int(cpu_tile_id(0)), full_pad_cfg(cpu_tile_id(0))); + ext_clk_cpu_pad : component inpad + generic map ( + loc => ext_clk_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ext_clk_cpu, + ext_clk_int(cpu_tile_id(0)) + ); + + clk_div_cpu_pad : component outpad + generic map ( + loc => clk_div_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +clk_div_cpu, + clk_div_int(cpu_tile_id(0)), + full_pad_cfg(cpu_tile_id(0)) + ); + -- ext_clk and div_clk for memory tile are close to MEM0 - ext_clk_mem_pad : inpad generic map (loc => ext_clk_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ext_clk_mem, ext_clk_int(mem_tile_id(0))); - clk_div_mem_pad : outpad generic map (loc => clk_div_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (clk_div_mem, clk_div_int(mem_tile_id(0)), full_pad_cfg(mem_tile_id(0))); + ext_clk_mem_pad : component inpad + generic map ( + loc => ext_clk_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ext_clk_mem, + ext_clk_int(mem_tile_id(0)) + ); + + clk_div_mem_pad : component outpad + generic map ( + loc => clk_div_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +clk_div_mem, + clk_div_int(mem_tile_id(0)), + full_pad_cfg(mem_tile_id(0)) + ); + -- ext_clk and div_clk for accelerator0 are close to tile 1 - ext_clk_acc0_pad : inpad generic map (loc => ext_clk_acc0_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ext_clk_acc0, ext_clk_int(1)); - clk_div_acc0_pad : outpad generic map (loc => clk_div_acc0_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (clk_div_acc0, clk_div_int(1), full_pad_cfg(1)); + ext_clk_acc0_pad : component inpad + generic map ( + loc => ext_clk_acc0_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ext_clk_acc0, + ext_clk_int(1) + ); + + clk_div_acc0_pad : component outpad + generic map ( + loc => clk_div_acc0_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +clk_div_acc0, + clk_div_int(1), + full_pad_cfg(1) + ); + -- ext_clk and div_clk for accelerator1 are close to tile 12 - ext_clk_acc1_pad : inpad generic map (loc => ext_clk_acc1_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ext_clk_acc1, ext_clk_int(12)); - clk_div_acc1_pad : outpad generic map (loc => clk_div_acc1_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (clk_div_acc1, clk_div_int(12), full_pad_cfg(12)); + ext_clk_acc1_pad : component inpad + generic map ( + loc => ext_clk_acc1_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ext_clk_acc1, + ext_clk_int(12) + ); + + clk_div_acc1_pad : component outpad + generic map ( + loc => clk_div_acc1_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +clk_div_acc1, + clk_div_int(12), + full_pad_cfg(12) + ); + -- tdi/o_cpu - tdi_cpu_pad : inpad generic map (loc => tdi_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_cpu, tdi_int(cpu_tile_id(0))); - tdo_cpu_pad : outpad generic map (loc => tdo_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_cpu, tdo_int(cpu_tile_id(0)), full_pad_cfg(cpu_tile_id(0))); + tdi_cpu_pad : component inpad + generic map ( + loc => tdi_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_cpu, + tdi_int(cpu_tile_id(0)) + ); + + tdo_cpu_pad : component outpad + generic map ( + loc => tdo_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_cpu, + tdo_int(cpu_tile_id(0)), + full_pad_cfg(cpu_tile_id(0)) + ); + -- tdi/o_io - tdi_io_pad : inpad generic map (loc => tdi_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_io, tdi_int(io_tile_id)); - tdo_io_pad : outpad generic map (loc => tdo_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_io, tdo_int(io_tile_id), full_pad_cfg(io_tile_id)); + tdi_io_pad : component inpad + generic map ( + loc => tdi_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_io, + tdi_int(io_tile_id) + ); + + tdo_io_pad : component outpad + generic map ( + loc => tdo_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_io, + tdo_int(io_tile_id), + full_pad_cfg(io_tile_id) + ); + -- tdi/o_mem pad is close to memory tile 0 - tdi_mem_pad : inpad generic map (loc => tdi_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_mem, tdi_int(mem_tile_id(0))); - tdo_mem_pad : outpad generic map (loc => tdo_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_mem, tdo_int(mem_tile_id(0)), full_pad_cfg(mem_tile_id(0))); + tdi_mem_pad : component inpad + generic map ( + loc => tdi_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_mem, + tdi_int(mem_tile_id(0)) + ); + + tdo_mem_pad : component outpad + generic map ( + loc => tdo_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_mem, + tdo_int(mem_tile_id(0)), + full_pad_cfg(mem_tile_id(0)) + ); + -- tdi/o_acc0 - tdi_acc0_pad : inpad generic map (loc => tdi_acc0_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_acc0, tdi_int(8)); - tdo_acc0_pad : outpad generic map (loc => tdo_acc0_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_acc0, tdo_int(8), full_pad_cfg(8)); + tdi_acc0_pad : component inpad + generic map ( + loc => tdi_acc0_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_acc0, + tdi_int(8) + ); + + tdo_acc0_pad : component outpad + generic map ( + loc => tdo_acc0_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_acc0, + tdo_int(8), + full_pad_cfg(8) + ); + -- tdi/o_acc1 - tdi_acc1_pad : inpad generic map (loc => tdi_acc1_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_acc1, tdi_int(4)); - tdo_acc1_pad : outpad generic map (loc => tdo_acc1_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_acc1, tdo_int(4), full_pad_cfg(4)); + tdi_acc1_pad : component inpad + generic map ( + loc => tdi_acc1_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_acc1, + tdi_int(4) + ); + + tdo_acc1_pad : component outpad + generic map ( + loc => tdo_acc1_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_acc1, + tdo_int(4), + full_pad_cfg(4) + ); + -- tdi/o_acc2 - tdi_acc2_pad : inpad generic map (loc => tdi_acc2_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_acc2, tdi_int(1)); - tdo_acc2_pad : outpad generic map (loc => tdo_acc2_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_acc2, tdo_int(1), full_pad_cfg(1)); + tdi_acc2_pad : component inpad + generic map ( + loc => tdi_acc2_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_acc2, + tdi_int(1) + ); + + tdo_acc2_pad : component outpad + generic map ( + loc => tdo_acc2_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_acc2, + tdo_int(1), + full_pad_cfg(1) + ); + -- tdi/o_acc3 - tdi_acc3_pad : inpad generic map (loc => tdi_acc3_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_acc3, tdi_int(2)); - tdo_acc3_pad : outpad generic map (loc => tdo_acc3_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_acc3, tdo_int(2), full_pad_cfg(2)); + tdi_acc3_pad : component inpad + generic map ( + loc => tdi_acc3_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_acc3, + tdi_int(2) + ); + + tdo_acc3_pad : component outpad + generic map ( + loc => tdo_acc3_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_acc3, + tdo_int(2), + full_pad_cfg(2) + ); + -- tdi/o_acc4 pad is close to memory tile 1 - tdi_acc4_pad : inpad generic map (loc => tdi_acc4_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_acc4, tdi_int(mem_tile_id(1))); - tdo_acc4_pad : outpad generic map (loc => tdo_acc4_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_acc4, tdo_int(mem_tile_id(1)), full_pad_cfg(mem_tile_id(1))); + tdi_acc4_pad : component inpad + generic map ( + loc => tdi_acc4_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_acc4, + tdi_int(mem_tile_id(1)) + ); + + tdo_acc4_pad : component outpad + generic map ( + loc => tdo_acc4_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_acc4, + tdo_int(mem_tile_id(1)), + full_pad_cfg(mem_tile_id(1)) + ); + -- tdi/o_acc5 - tdi_acc5_pad : inpad generic map (loc => tdi_acc5_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_acc5, tdi_int(15)); - tdo_acc5_pad : outpad generic map (loc => tdo_acc5_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_acc5, tdo_int(15), full_pad_cfg(15)); + tdi_acc5_pad : component inpad + generic map ( + loc => tdi_acc5_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_acc5, + tdi_int(15) + ); + + tdo_acc5_pad : component outpad + generic map ( + loc => tdo_acc5_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_acc5, + tdo_int(15), + full_pad_cfg(15) + ); + -- tdi/o_acc6 is close to memory tile 3 - tdi_acc6_pad : inpad generic map (loc => tdi_acc6_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_acc6, tdi_int(mem_tile_id(3))); - tdo_acc6_pad : outpad generic map (loc => tdo_acc6_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_acc6, tdo_int(mem_tile_id(3)), full_pad_cfg(mem_tile_id(3))); + tdi_acc6_pad : component inpad + generic map ( + loc => tdi_acc6_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_acc6, + tdi_int(mem_tile_id(3)) + ); + + tdo_acc6_pad : component outpad + generic map ( + loc => tdo_acc6_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_acc6, + tdo_int(mem_tile_id(3)), + full_pad_cfg(mem_tile_id(3)) + ); + -- tdi/o_acc7 is close to memory tile 2 - tdi_acc7_pad : inpad generic map (loc => tdi_acc7_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_acc7, tdi_int(mem_tile_id(2))); - tdo_acc7_pad : outpad generic map (loc => tdo_acc7_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_acc7, tdo_int(mem_tile_id(2)), full_pad_cfg(mem_tile_id(2))); + tdi_acc7_pad : component inpad + generic map ( + loc => tdi_acc7_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_acc7, + tdi_int(mem_tile_id(2)) + ); + + tdo_acc7_pad : component outpad + generic map ( + loc => tdo_acc7_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_acc7, + tdo_int(mem_tile_id(2)), + full_pad_cfg(mem_tile_id(2)) + ); unused_interface_gen : for i in 0 to CFG_TILES_NUM - 1 generate - unused_ext_clk_io_gen: if i /= cpu_tile_id(0) and i /= io_tile_id and i /= 1 and i /= 12 and i /= mem_tile_id(0) generate + + unused_ext_clk_io_gen : if i /= cpu_tile_id(0) and i /= io_tile_id and i /= 1 and i /= 12 and i /= mem_tile_id(0) generate ext_clk_int(i) <= ext_clk_noc_int; end generate unused_ext_clk_io_gen; - unused_td_io_gen: if i /= cpu_tile_id(0) and i /= io_tile_id and i /= mem_tile_id(0) and i /= mem_tile_id(1) and i /= mem_tile_id(2) and i /= mem_tile_id(3) + + unused_td_io_gen : if i /= cpu_tile_id(0) and i /= io_tile_id and i /= mem_tile_id(0) and i /= mem_tile_id(1) and i /= mem_tile_id(2) and i /= mem_tile_id(3) and i /= 8 and i /= 4 and i /= 1 and i /= 2 and i /= 15 generate tdi_int(i) <= '0'; end generate unused_td_io_gen; + end generate unused_interface_gen; + -- end chip-specific pads mapping ----------------------------------------------------------------------------- - tms_pad : inpad generic map (loc => tms_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tms, tms_int); - tclk_pad : inpad generic map (loc => tclk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tclk, tclk_int); + tms_pad : component inpad + generic map ( + loc => tms_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tms, + tms_int + ); + + tclk_pad : component inpad + generic map ( + loc => tclk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tclk, + tclk_int + ); -- Ethernet - reset_o2_pad : outpad generic map (tech => CFG_FABTECH, loc => reset_o2_pad_loc, level => cmos, voltage => x18v) - port map (reset_o2, reset_o2_int, full_pad_cfg(io_tile_id)); - - etx_clk_pad : inpad generic map (tech => CFG_FABTECH, loc => etx_clk_pad_loc, level => cmos, voltage => x18v) - port map (etx_clk, etx_clk_int); - erx_clk_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_clk_pad_loc, level => cmos, voltage => x18v) - port map (erx_clk, erx_clk_int); - erxd_pad : inpadv generic map (tech => CFG_FABTECH, loc => erxd_pad_loc, level => cmos, voltage => x18v, width => 4) - port map (erxd, erxd_int); - erx_dv_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_dv_pad_loc, level => cmos, voltage => x18v) - port map (erx_dv, erx_dv_int); - erx_er_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_er_pad_loc, level => cmos, voltage => x18v) - port map (erx_er, erx_er_int); - erx_col_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_col_pad_loc, level => cmos, voltage => x18v) - port map (erx_col, erx_col_int); - erx_crs_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_crs_pad_loc, level => cmos, voltage => x18v) - port map (erx_crs, erx_crs_int); - - emdio_pad : iopad generic map (tech => CFG_FABTECH, loc => emdio_pad_loc, level => cmos, voltage => x18v, oepol => 1) - port map (emdio, emdio_o, emdio_oe, emdio_i, full_pad_cfg(io_tile_id)); - - etxd_pad : outpadv generic map (tech => CFG_FABTECH, loc => etxd_pad_loc, level => cmos, voltage => x18v, width => 4) - port map (etxd, etxd_int, full_pad_cfg(io_tile_id)); - etx_en_pad : outpad generic map (tech => CFG_FABTECH, loc => etx_en_pad_loc, level => cmos, voltage => x18v) - port map (etx_en, etx_en_int, full_pad_cfg(io_tile_id)); - etx_er_pad : outpad generic map (tech => CFG_FABTECH, loc => etx_er_pad_loc, level => cmos, voltage => x18v) - port map (etx_er, etx_er_int, full_pad_cfg(io_tile_id)); - emdc_pad : outpad generic map (tech => CFG_FABTECH, loc => emdc_pad_loc, level => cmos, voltage => x18v) - port map (emdc, emdc_int, full_pad_cfg(io_tile_id)); + reset_o2_pad : component outpad + generic map ( + tech => CFG_FABTECH, loc => reset_o2_pad_loc, level => cmos, voltage => x18v + ) + port map ( +reset_o2, + reset_o2_int, + full_pad_cfg(io_tile_id) + ); + + etx_clk_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => etx_clk_pad_loc, level => cmos, voltage => x18v + ) + port map ( +etx_clk, + etx_clk_int + ); + + erx_clk_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_clk_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_clk, + erx_clk_int + ); + + erxd_pad : component inpadv + generic map ( + tech => CFG_FABTECH, loc => erxd_pad_loc, level => cmos, voltage => x18v, width => 4 + ) + port map ( +erxd, + erxd_int + ); + + erx_dv_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_dv_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_dv, + erx_dv_int + ); + + erx_er_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_er_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_er, + erx_er_int + ); + + erx_col_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_col_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_col, + erx_col_int + ); + + erx_crs_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_crs_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_crs, + erx_crs_int + ); + + emdio_pad : component iopad + generic map ( + tech => CFG_FABTECH, loc => emdio_pad_loc, level => cmos, voltage => x18v, oepol => 1 + ) + port map ( +emdio, + emdio_o, + emdio_oe, + emdio_i, + full_pad_cfg(io_tile_id) + ); + + etxd_pad : component outpadv + generic map ( + tech => CFG_FABTECH, loc => etxd_pad_loc, level => cmos, voltage => x18v, width => 4 + ) + port map ( +etxd, + etxd_int, + full_pad_cfg(io_tile_id) + ); + + etx_en_pad : component outpad + generic map ( + tech => CFG_FABTECH, loc => etx_en_pad_loc, level => cmos, voltage => x18v + ) + port map ( +etx_en, + etx_en_int, + full_pad_cfg(io_tile_id) + ); + + etx_er_pad : component outpad + generic map ( + tech => CFG_FABTECH, loc => etx_er_pad_loc, level => cmos, voltage => x18v + ) + port map ( +etx_er, + etx_er_int, + full_pad_cfg(io_tile_id) + ); + + emdc_pad : component outpad + generic map ( + tech => CFG_FABTECH, loc => emdc_pad_loc, level => cmos, voltage => x18v + ) + port map ( +emdc, + emdc_int, + full_pad_cfg(io_tile_id) + ); -- DVI -- tft_nhpd_pad : inpad generic map (tech => CFG_FABTECH, loc => tft_nhpd_pad_loc, level => cmos, voltage => x18v) @@ -486,59 +895,441 @@ begin -- port map (tft_npd, dvi_npd, full_pad_cfg(io_tile_id)); -- LPDDR - lpddr0_ck_p_pad : outpad generic map (loc => lpddr0_ck_p_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr0_ck_p, '0', X"00003"); - lpddr0_ck_n_pad : outpad generic map (loc => lpddr0_ck_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr0_ck_n, '0', X"00003"); - lpddr0_cke_pad : outpad generic map (loc => lpddr0_cke_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr0_cke, '0', X"00003"); - lpddr0_ba_pad : outpadv generic map (loc => lpddr0_ba_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 3) port map (lpddr0_ba, "000", X"00003"); - lpddr0_addr_pad : outpadv generic map (loc => lpddr0_addr_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 16) port map (lpddr0_addr, X"0000", X"00003"); - lpddr0_cs_n_pad : outpad generic map (loc => lpddr0_cs_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr0_cs_n, '0', X"00003"); - lpddr0_ras_n_pad : outpad generic map (loc => lpddr0_ras_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr0_ras_n, '0', X"00003"); - lpddr0_cas_n_pad : outpad generic map (loc => lpddr0_cas_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr0_cas_n, '0', X"00003"); - lpddr0_we_n_pad : outpad generic map (loc => lpddr0_we_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr0_we_n, '0', X"00003"); - lpddr0_reset_n_pad : outpad generic map (loc => lpddr0_reset_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr0_reset_n, '0', X"00003"); - lpddr0_odt_pad : outpad generic map (loc => lpddr0_odt_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr0_odt, '0', X"00003"); - lpddr0_dm_pad : outpadv generic map (loc => lpddr0_dm_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4) port map (lpddr0_dm, "0000", X"00003"); - lpddr0_dqs_p_pad : iopadv generic map (tech => CFG_FABTECH, loc => lpddr0_dqs_p_pad_loc, level => cmos, voltage => x18v, width => 4, oepol => 1) port map (lpddr0_dqs_p, "0000", '0', open, X"00003"); - lpddr0_dqs_n_pad : iopadv generic map (tech => CFG_FABTECH, loc => lpddr0_dqs_n_pad_loc, level => cmos, voltage => x18v, width => 4, oepol => 1) port map (lpddr0_dqs_n, "0000", '0', open, X"00003"); - lpddr0_dq_pad : iopadv generic map (tech => CFG_FABTECH, loc => lpddr0_dq_pad_loc, level => cmos, voltage => x18v, width => 32, oepol => 1) port map (lpddr0_dq, X"00000000", '0', open, X"00003"); - - lpddr1_ck_p_pad : outpad generic map (loc => lpddr1_ck_p_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr1_ck_p, '0', X"00003"); - lpddr1_ck_n_pad : outpad generic map (loc => lpddr1_ck_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr1_ck_n, '0', X"00003"); - lpddr1_cke_pad : outpad generic map (loc => lpddr1_cke_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr1_cke, '0', X"00003"); - lpddr1_ba_pad : outpadv generic map (loc => lpddr1_ba_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 3) port map (lpddr1_ba, "000", X"00003"); - lpddr1_addr_pad : outpadv generic map (loc => lpddr1_addr_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 16) port map (lpddr1_addr, X"0000", X"00003"); - lpddr1_cs_n_pad : outpad generic map (loc => lpddr1_cs_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr1_cs_n, '0', X"00003"); - lpddr1_ras_n_pad : outpad generic map (loc => lpddr1_ras_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr1_ras_n, '0', X"00003"); - lpddr1_cas_n_pad : outpad generic map (loc => lpddr1_cas_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr1_cas_n, '0', X"00003"); - lpddr1_we_n_pad : outpad generic map (loc => lpddr1_we_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr1_we_n, '0', X"00003"); - lpddr1_reset_n_pad : outpad generic map (loc => lpddr1_reset_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr1_reset_n, '0', X"00003"); - lpddr1_odt_pad : outpad generic map (loc => lpddr1_odt_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (lpddr1_odt, '0', X"00003"); - lpddr1_dm_pad : outpadv generic map (loc => lpddr1_dm_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4) port map (lpddr1_dm, "0000", X"00003"); - lpddr1_dqs_p_pad : iopadv generic map (tech => CFG_FABTECH, loc => lpddr1_dqs_p_pad_loc, level => cmos, voltage => x18v, width => 4, oepol => 1) port map (lpddr1_dqs_p, "0000", '0', open, X"00003"); - lpddr1_dqs_n_pad : iopadv generic map (tech => CFG_FABTECH, loc => lpddr1_dqs_n_pad_loc, level => cmos, voltage => x18v, width => 4, oepol => 1) port map (lpddr1_dqs_n, "0000", '0', open, X"00003"); - lpddr1_dq_pad : iopadv generic map (tech => CFG_FABTECH, loc => lpddr1_dq_pad_loc, level => cmos, voltage => x18v, width => 32, oepol => 1) port map (lpddr1_dq, X"00000000", '0', open, X"00003"); + lpddr0_ck_p_pad : component outpad + generic map ( + loc => lpddr0_ck_p_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr0_ck_p, + '0', + X"00003" + ); + + lpddr0_ck_n_pad : component outpad + generic map ( + loc => lpddr0_ck_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr0_ck_n, + '0', + X"00003" + ); + + lpddr0_cke_pad : component outpad + generic map ( + loc => lpddr0_cke_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr0_cke, + '0', + X"00003" + ); + + lpddr0_ba_pad : component outpadv + generic map ( + loc => lpddr0_ba_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 3 + ) + port map ( +lpddr0_ba, + "000", + X"00003" + ); + + lpddr0_addr_pad : component outpadv + generic map ( + loc => lpddr0_addr_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 16 + ) + port map ( +lpddr0_addr, + X"0000", + X"00003" + ); + + lpddr0_cs_n_pad : component outpad + generic map ( + loc => lpddr0_cs_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr0_cs_n, + '0', + X"00003" + ); + + lpddr0_ras_n_pad : component outpad + generic map ( + loc => lpddr0_ras_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr0_ras_n, + '0', + X"00003" + ); + + lpddr0_cas_n_pad : component outpad + generic map ( + loc => lpddr0_cas_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr0_cas_n, + '0', + X"00003" + ); + + lpddr0_we_n_pad : component outpad + generic map ( + loc => lpddr0_we_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr0_we_n, + '0', + X"00003" + ); + + lpddr0_reset_n_pad : component outpad + generic map ( + loc => lpddr0_reset_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr0_reset_n, + '0', + X"00003" + ); + + lpddr0_odt_pad : component outpad + generic map ( + loc => lpddr0_odt_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr0_odt, + '0', + X"00003" + ); + + lpddr0_dm_pad : component outpadv + generic map ( + loc => lpddr0_dm_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4 + ) + port map ( +lpddr0_dm, + "0000", + X"00003" + ); + + lpddr0_dqs_p_pad : component iopadv + generic map ( + tech => CFG_FABTECH, loc => lpddr0_dqs_p_pad_loc, level => cmos, voltage => x18v, width => 4, oepol => 1 + ) + port map ( +lpddr0_dqs_p, + "0000", + '0', + open, + X"00003" + ); + + lpddr0_dqs_n_pad : component iopadv + generic map ( + tech => CFG_FABTECH, loc => lpddr0_dqs_n_pad_loc, level => cmos, voltage => x18v, width => 4, oepol => 1 + ) + port map ( +lpddr0_dqs_n, + "0000", + '0', + open, + X"00003" + ); + + lpddr0_dq_pad : component iopadv + generic map ( + tech => CFG_FABTECH, loc => lpddr0_dq_pad_loc, level => cmos, voltage => x18v, width => 32, oepol => 1 + ) + port map ( +lpddr0_dq, + X"00000000", + '0', + open, + X"00003" + ); + + lpddr1_ck_p_pad : component outpad + generic map ( + loc => lpddr1_ck_p_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr1_ck_p, + '0', + X"00003" + ); + + lpddr1_ck_n_pad : component outpad + generic map ( + loc => lpddr1_ck_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr1_ck_n, + '0', + X"00003" + ); + + lpddr1_cke_pad : component outpad + generic map ( + loc => lpddr1_cke_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr1_cke, + '0', + X"00003" + ); + + lpddr1_ba_pad : component outpadv + generic map ( + loc => lpddr1_ba_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 3 + ) + port map ( +lpddr1_ba, + "000", + X"00003" + ); + + lpddr1_addr_pad : component outpadv + generic map ( + loc => lpddr1_addr_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 16 + ) + port map ( +lpddr1_addr, + X"0000", + X"00003" + ); + + lpddr1_cs_n_pad : component outpad + generic map ( + loc => lpddr1_cs_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr1_cs_n, + '0', + X"00003" + ); + + lpddr1_ras_n_pad : component outpad + generic map ( + loc => lpddr1_ras_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr1_ras_n, + '0', + X"00003" + ); + + lpddr1_cas_n_pad : component outpad + generic map ( + loc => lpddr1_cas_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr1_cas_n, + '0', + X"00003" + ); + + lpddr1_we_n_pad : component outpad + generic map ( + loc => lpddr1_we_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr1_we_n, + '0', + X"00003" + ); + + lpddr1_reset_n_pad : component outpad + generic map ( + loc => lpddr1_reset_n_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr1_reset_n, + '0', + X"00003" + ); + + lpddr1_odt_pad : component outpad + generic map ( + loc => lpddr1_odt_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +lpddr1_odt, + '0', + X"00003" + ); + + lpddr1_dm_pad : component outpadv + generic map ( + loc => lpddr1_dm_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4 + ) + port map ( +lpddr1_dm, + "0000", + X"00003" + ); + + lpddr1_dqs_p_pad : component iopadv + generic map ( + tech => CFG_FABTECH, loc => lpddr1_dqs_p_pad_loc, level => cmos, voltage => x18v, width => 4, oepol => 1 + ) + port map ( +lpddr1_dqs_p, + "0000", + '0', + open, + X"00003" + ); + + lpddr1_dqs_n_pad : component iopadv + generic map ( + tech => CFG_FABTECH, loc => lpddr1_dqs_n_pad_loc, level => cmos, voltage => x18v, width => 4, oepol => 1 + ) + port map ( +lpddr1_dqs_n, + "0000", + '0', + open, + X"00003" + ); + + lpddr1_dq_pad : component iopadv + generic map ( + tech => CFG_FABTECH, loc => lpddr1_dq_pad_loc, level => cmos, voltage => x18v, width => 32, oepol => 1 + ) + port map ( +lpddr1_dq, + X"00000000", + '0', + open, + X"00003" + ); -- UART - uart_rxd_pad : inpad generic map (loc => uart_rxd_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (uart_rxd, uart_rxd_int); - uart_txd_pad : outpad generic map (loc => uart_txd_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (uart_txd, uart_txd_int, full_pad_cfg(io_tile_id)); - uart_ctsn_pad : inpad generic map (loc => uart_ctsn_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (uart_ctsn, uart_ctsn_int); - uart_rtsn_pad : outpad generic map (loc => uart_rtsn_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (uart_rtsn, uart_rtsn_int, full_pad_cfg(io_tile_id)); + uart_rxd_pad : component inpad + generic map ( + loc => uart_rxd_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +uart_rxd, + uart_rxd_int + ); + + uart_txd_pad : component outpad + generic map ( + loc => uart_txd_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +uart_txd, + uart_txd_int, + full_pad_cfg(io_tile_id) + ); + + uart_ctsn_pad : component inpad + generic map ( + loc => uart_ctsn_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +uart_ctsn, + uart_ctsn_int + ); + + uart_rtsn_pad : component outpad + generic map ( + loc => uart_rtsn_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +uart_rtsn, + uart_rtsn_int, + full_pad_cfg(io_tile_id) + ); -- IVR (set to inputs; unused for now) - ivr_pmb_dat_pad : inpad generic map (loc => ivr_pmb_dat_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ivr_pmb_dat, open); - ivr_pmb_clk_pad : inpad generic map (loc => ivr_pmb_clk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ivr_pmb_clk, open); - ivr_avs_clk_pad : inpad generic map (loc => ivr_avs_clk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ivr_avs_clk, open); - ivr_avs_dat_pad : inpad generic map (loc => ivr_avs_dat_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ivr_avs_dat, open); - ivr_avs_sdat_pad : inpad generic map (loc => ivr_avs_sdat_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ivr_avs_sdat, open); - ivr_control_pad : inpad generic map (loc => ivr_control_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ivr_control, open); + ivr_pmb_dat_pad : component inpad + generic map ( + loc => ivr_pmb_dat_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ivr_pmb_dat, + open + ); + + ivr_pmb_clk_pad : component inpad + generic map ( + loc => ivr_pmb_clk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ivr_pmb_clk, + open + ); + + ivr_avs_clk_pad : component inpad + generic map ( + loc => ivr_avs_clk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ivr_avs_clk, + open + ); - ivr_gpio_pad : inpadv generic map (loc => ivr_gpio_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4) port map (ivr_gpio, open); + ivr_avs_dat_pad : component inpad + generic map ( + loc => ivr_avs_dat_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ivr_avs_dat, + open + ); + + ivr_avs_sdat_pad : component inpad + generic map ( + loc => ivr_avs_sdat_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ivr_avs_sdat, + open + ); + + ivr_control_pad : component inpad + generic map ( + loc => ivr_control_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ivr_control, + open + ); + + ivr_gpio_pad : component inpadv + generic map ( + loc => ivr_gpio_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4 + ) + port map ( +ivr_gpio, + open + ); -- UNUSED - unused_pad : inpad generic map (loc => unused_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (unused, open); + unused_pad : component inpad + generic map ( + loc => unused_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +unused, + open + ); -- DUMMY - dummy_pad : outpad generic map (loc => dummy_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (open, '0', X"00003"); + dummy_pad : component outpad + generic map ( + loc => dummy_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +open, + '0', + X"00003" + ); ----------------------------------------------------------------------------- -- chip-specific mapping of memory tile pins to package pins @@ -548,277 +1339,338 @@ begin -- Memory tile 2 - FPGA link 3 -- Memory tile 3 - FPGA link 2 -- data_out - fpga_data_out_swap(63 downto 0) <= fpga_data_out(63 downto 0); -- 0 - fpga_data_out_swap(127 downto 64) <= fpga_data_out(127 downto 64); -- 1 - fpga_data_out_swap(255 downto 192) <= fpga_data_out(191 downto 128); -- 2 - fpga_data_out_swap(191 downto 128) <= fpga_data_out(255 downto 192); -- 3 + fpga_data_out_swap(63 downto 0) <= fpga_data_out(63 downto 0); -- 0 + fpga_data_out_swap(127 downto 64) <= fpga_data_out(127 downto 64); -- 1 + fpga_data_out_swap(255 downto 192) <= fpga_data_out(191 downto 128); -- 2 + fpga_data_out_swap(191 downto 128) <= fpga_data_out(255 downto 192); -- 3 -- data in - fpga_data_in(63 downto 0) <= fpga_data_in_swap(63 downto 0); -- 0 - fpga_data_in(127 downto 64) <= fpga_data_in_swap(127 downto 64); -- 1 - fpga_data_in(191 downto 128) <= fpga_data_in_swap(255 downto 192); -- 2 - fpga_data_in(255 downto 192) <= fpga_data_in_swap(191 downto 128); -- 3 + fpga_data_in(63 downto 0) <= fpga_data_in_swap(63 downto 0); -- 0 + fpga_data_in(127 downto 64) <= fpga_data_in_swap(127 downto 64); -- 1 + fpga_data_in(191 downto 128) <= fpga_data_in_swap(255 downto 192); -- 2 + fpga_data_in(255 downto 192) <= fpga_data_in_swap(191 downto 128); -- 3 -- valid out - fpga_valid_out_swap(0) <= fpga_valid_out_int(0); -- 0 - fpga_valid_out_swap(1) <= fpga_valid_out_int(1); -- 1 - fpga_valid_out_swap(3) <= fpga_valid_out_int(2); -- 2 - fpga_valid_out_swap(2) <= fpga_valid_out_int(3); -- 3 + fpga_valid_out_swap(0) <= fpga_valid_out_int(0); -- 0 + fpga_valid_out_swap(1) <= fpga_valid_out_int(1); -- 1 + fpga_valid_out_swap(3) <= fpga_valid_out_int(2); -- 2 + fpga_valid_out_swap(2) <= fpga_valid_out_int(3); -- 3 -- valid in - fpga_valid_in_int(0) <= fpga_valid_in_swap(0); -- 0 - fpga_valid_in_int(1) <= fpga_valid_in_swap(1); -- 1 - fpga_valid_in_int(2) <= fpga_valid_in_swap(3); -- 2 - fpga_valid_in_int(3) <= fpga_valid_in_swap(2); -- 3 + fpga_valid_in_int(0) <= fpga_valid_in_swap(0); -- 0 + fpga_valid_in_int(1) <= fpga_valid_in_swap(1); -- 1 + fpga_valid_in_int(2) <= fpga_valid_in_swap(3); -- 2 + fpga_valid_in_int(3) <= fpga_valid_in_swap(2); -- 3 -- clk out - fpga_clk_out_swap(0) <= fpga_clk_out_int(0); -- 0 - fpga_clk_out_swap(1) <= fpga_clk_out_int(1); -- 1 - fpga_clk_out_swap(3) <= fpga_clk_out_int(2); -- 2 - fpga_clk_out_swap(2) <= fpga_clk_out_int(3); -- 3 + fpga_clk_out_swap(0) <= fpga_clk_out_int(0); -- 0 + fpga_clk_out_swap(1) <= fpga_clk_out_int(1); -- 1 + fpga_clk_out_swap(3) <= fpga_clk_out_int(2); -- 2 + fpga_clk_out_swap(2) <= fpga_clk_out_int(3); -- 3 -- clk in - fpga_clk_in_int(0) <= fpga_clk_in_swap(0); -- 0 - fpga_clk_in_int(1) <= fpga_clk_in_swap(1); -- 1 - fpga_clk_in_int(2) <= fpga_clk_in_swap(3); -- 2 - fpga_clk_in_int(3) <= fpga_clk_in_swap(2); -- 3 + fpga_clk_in_int(0) <= fpga_clk_in_swap(0); -- 0 + fpga_clk_in_int(1) <= fpga_clk_in_swap(1); -- 1 + fpga_clk_in_int(2) <= fpga_clk_in_swap(3); -- 2 + fpga_clk_in_int(3) <= fpga_clk_in_swap(2); -- 3 -- credit out - fpga_credit_out_swap(0) <= fpga_credit_out_int(0); -- 0 - fpga_credit_out_swap(1) <= fpga_credit_out_int(1); -- 1 - fpga_credit_out_swap(3) <= fpga_credit_out_int(2); -- 2 - fpga_credit_out_swap(2) <= fpga_credit_out_int(3); -- 3 + fpga_credit_out_swap(0) <= fpga_credit_out_int(0); -- 0 + fpga_credit_out_swap(1) <= fpga_credit_out_int(1); -- 1 + fpga_credit_out_swap(3) <= fpga_credit_out_int(2); -- 2 + fpga_credit_out_swap(2) <= fpga_credit_out_int(3); -- 3 -- credit in - fpga_credit_in_int(0) <= fpga_credit_in_swap(0); -- 0 - fpga_credit_in_int(1) <= fpga_credit_in_swap(1); -- 1 - fpga_credit_in_int(2) <= fpga_credit_in_swap(3); -- 2 - fpga_credit_in_int(3) <= fpga_credit_in_swap(2); -- 3 + fpga_credit_in_int(0) <= fpga_credit_in_swap(0); -- 0 + fpga_credit_in_int(1) <= fpga_credit_in_swap(1); -- 1 + fpga_credit_in_int(2) <= fpga_credit_in_swap(3); -- 2 + fpga_credit_in_int(3) <= fpga_credit_in_swap(2); -- 3 + fpga_pad_wires_gen : for i in 0 to 63 generate -- oen - fpga_oen_swap(0 + i) <= fpga_oen(0); -- 0 - fpga_oen_swap(64 + i) <= fpga_oen(1); -- 1 - fpga_oen_swap(192 + i) <= fpga_oen(2); -- 2 - fpga_oen_swap(128 + i) <= fpga_oen(3); -- 3 + fpga_oen_swap(0 + i) <= fpga_oen(0); -- 0 + fpga_oen_swap(64 + i) <= fpga_oen(1); -- 1 + fpga_oen_swap(192 + i) <= fpga_oen(2); -- 2 + fpga_oen_swap(128 + i) <= fpga_oen(3); -- 3 -- data pad cfg - fpga_data_pad_cfg(0 * CFG_MEM_LINK_BITS * 20 + (i+1) * 20 - 1 downto 0 * CFG_MEM_LINK_BITS * 20 + i * 20) <= full_pad_cfg(mem_tile_id(0)); -- 0 - fpga_data_pad_cfg(1 * CFG_MEM_LINK_BITS * 20 + (i+1) * 20 - 1 downto 1 * CFG_MEM_LINK_BITS * 20 + i * 20) <= full_pad_cfg(mem_tile_id(1)); -- 1 - fpga_data_pad_cfg(3 * CFG_MEM_LINK_BITS * 20 + (i+1) * 20 - 1 downto 3 * CFG_MEM_LINK_BITS * 20 + i * 20) <= full_pad_cfg(mem_tile_id(2)); -- 2 - fpga_data_pad_cfg(2 * CFG_MEM_LINK_BITS * 20 + (i+1) * 20 - 1 downto 2 * CFG_MEM_LINK_BITS * 20 + i * 20) <= full_pad_cfg(mem_tile_id(3)); -- 3 + fpga_data_pad_cfg(0 * CFG_MEM_LINK_BITS * 20 + (i + 1) * 20 - 1 downto 0 * CFG_MEM_LINK_BITS * 20 + i * 20) <= full_pad_cfg(mem_tile_id(0)); -- 0 + fpga_data_pad_cfg(1 * CFG_MEM_LINK_BITS * 20 + (i + 1) * 20 - 1 downto 1 * CFG_MEM_LINK_BITS * 20 + i * 20) <= full_pad_cfg(mem_tile_id(1)); -- 1 + fpga_data_pad_cfg(3 * CFG_MEM_LINK_BITS * 20 + (i + 1) * 20 - 1 downto 3 * CFG_MEM_LINK_BITS * 20 + i * 20) <= full_pad_cfg(mem_tile_id(2)); -- 2 + fpga_data_pad_cfg(2 * CFG_MEM_LINK_BITS * 20 + (i + 1) * 20 - 1 downto 2 * CFG_MEM_LINK_BITS * 20 + i * 20) <= full_pad_cfg(mem_tile_id(3)); -- 3 end generate fpga_pad_wires_gen; + -- clock and credit pad cfg - fpga_c_pad_cfg(19 downto 0) <= full_pad_cfg(mem_tile_id(0)); -- 0 - fpga_c_pad_cfg(39 downto 20) <= full_pad_cfg(mem_tile_id(1)); -- 1 - fpga_c_pad_cfg(79 downto 60) <= full_pad_cfg(mem_tile_id(2)); -- 2 - fpga_c_pad_cfg(59 downto 40) <= full_pad_cfg(mem_tile_id(3)); -- 3 + fpga_c_pad_cfg(19 downto 0) <= full_pad_cfg(mem_tile_id(0)); -- 0 + fpga_c_pad_cfg(39 downto 20) <= full_pad_cfg(mem_tile_id(1)); -- 1 + fpga_c_pad_cfg(79 downto 60) <= full_pad_cfg(mem_tile_id(2)); -- 2 + fpga_c_pad_cfg(59 downto 40) <= full_pad_cfg(mem_tile_id(3)); -- 3 -- End of chip-specific pad mapping ----------------------------------------------------------------------------- - fpga_data_pad : iopadvvv generic map (tech => CFG_FABTECH, loc => fpga_data_pad_loc, level => cmos, voltage => x18v, width => 4*CFG_MEM_LINK_BITS, oepol => 1) - port map (fpga_data, fpga_data_out_swap, fpga_oen_swap, fpga_data_in_swap, fpga_data_pad_cfg); - fpga_valid_in_pad : inpadv generic map (loc => fpga_valid_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4) - port map (fpga_valid_in, fpga_valid_in_swap); - fpga_valid_out_pad : outpadvvv generic map (loc => fpga_valid_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4) - port map (fpga_valid_out, fpga_valid_out_swap, fpga_c_pad_cfg); - fpga_clk_in_pad : inpadv generic map (loc => fpga_clk_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4) - port map (fpga_clk_in, fpga_clk_in_swap); - fpga_clk_out_pad : outpadvvv generic map (loc => fpga_clk_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4) - port map (fpga_clk_out, fpga_clk_out_swap, fpga_c_pad_cfg); - fpga_credit_in_pad : inpadv generic map (loc => fpga_credit_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4) - port map (fpga_credit_in, fpga_credit_in_swap); - fpga_credit_out_pad : outpadvvv generic map (loc => fpga_credit_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4) - port map (fpga_credit_out, fpga_credit_out_swap, fpga_c_pad_cfg); + fpga_data_pad : component iopadvvv + generic map ( + tech => CFG_FABTECH, loc => fpga_data_pad_loc, level => cmos, voltage => x18v, width => 4 * CFG_MEM_LINK_BITS, oepol => 1 + ) + port map ( +fpga_data, + fpga_data_out_swap, + fpga_oen_swap, + fpga_data_in_swap, + fpga_data_pad_cfg + ); + + fpga_valid_in_pad : component inpadv + generic map ( + loc => fpga_valid_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4 + ) + port map ( +fpga_valid_in, + fpga_valid_in_swap + ); + + fpga_valid_out_pad : component outpadvvv + generic map ( + loc => fpga_valid_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4 + ) + port map ( +fpga_valid_out, + fpga_valid_out_swap, + fpga_c_pad_cfg + ); + + fpga_clk_in_pad : component inpadv + generic map ( + loc => fpga_clk_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4 + ) + port map ( +fpga_clk_in, + fpga_clk_in_swap + ); + + fpga_clk_out_pad : component outpadvvv + generic map ( + loc => fpga_clk_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4 + ) + port map ( +fpga_clk_out, + fpga_clk_out_swap, + fpga_c_pad_cfg + ); + + fpga_credit_in_pad : component inpadv + generic map ( + loc => fpga_credit_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4 + ) + port map ( +fpga_credit_in, + fpga_credit_in_swap + ); + + fpga_credit_out_pad : component outpadvvv + generic map ( + loc => fpga_credit_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH, width => 4 + ) + port map ( +fpga_credit_out, + fpga_credit_out_swap, + fpga_c_pad_cfg + ); ----------------------------------------------------------------------------- -- NOC CONNECTIONS ----------------------------------------------------------------------------- - meshgen_y : for i in 0 to CFG_YLEN-1 generate - meshgen_x : for j in 0 to CFG_XLEN-1 generate + + meshgen_y : for i in 0 to CFG_YLEN - 1 generate + + meshgen_x : for j in 0 to CFG_XLEN - 1 generate y_0 : if (i = 0) generate -- North port is unconnected - noc1_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc2_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc3_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc4_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc5_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc6_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(0) <= '0'; + noc1_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc2_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc3_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc4_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc5_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc6_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(0) <= '0'; end generate y_0; y_non_0 : if (i /= 0) generate -- North port is connected - noc1_data_n_in(i*CFG_XLEN + j) <= noc1_data_s_out((i-1)*CFG_XLEN + j); - noc1_data_void_in(i*CFG_XLEN + j)(0) <= noc1_data_void_out((i-1)*CFG_XLEN + j)(1); - noc1_stop_in(i*CFG_XLEN + j)(0) <= noc1_stop_out((i-1)*CFG_XLEN + j)(1); - noc2_data_n_in(i*CFG_XLEN + j) <= noc2_data_s_out((i-1)*CFG_XLEN + j); - noc2_data_void_in(i*CFG_XLEN + j)(0) <= noc2_data_void_out((i-1)*CFG_XLEN + j)(1); - noc2_stop_in(i*CFG_XLEN + j)(0) <= noc2_stop_out((i-1)*CFG_XLEN + j)(1); - noc3_data_n_in(i*CFG_XLEN + j) <= noc3_data_s_out((i-1)*CFG_XLEN + j); - noc3_data_void_in(i*CFG_XLEN + j)(0) <= noc3_data_void_out((i-1)*CFG_XLEN + j)(1); - noc3_stop_in(i*CFG_XLEN + j)(0) <= noc3_stop_out((i-1)*CFG_XLEN + j)(1); - noc4_data_n_in(i*CFG_XLEN + j) <= noc4_data_s_out((i-1)*CFG_XLEN + j); - noc4_data_void_in(i*CFG_XLEN + j)(0) <= noc4_data_void_out((i-1)*CFG_XLEN + j)(1); - noc4_stop_in(i*CFG_XLEN + j)(0) <= noc4_stop_out((i-1)*CFG_XLEN + j)(1); - noc5_data_n_in(i*CFG_XLEN + j) <= noc5_data_s_out((i-1)*CFG_XLEN + j); - noc5_data_void_in(i*CFG_XLEN + j)(0) <= noc5_data_void_out((i-1)*CFG_XLEN + j)(1); - noc5_stop_in(i*CFG_XLEN + j)(0) <= noc5_stop_out((i-1)*CFG_XLEN + j)(1); - noc6_data_n_in(i*CFG_XLEN + j) <= noc6_data_s_out((i-1)*CFG_XLEN + j); - noc6_data_void_in(i*CFG_XLEN + j)(0) <= noc6_data_void_out((i-1)*CFG_XLEN + j)(1); - noc6_stop_in(i*CFG_XLEN + j)(0) <= noc6_stop_out((i-1)*CFG_XLEN + j)(1); + noc1_data_n_in(i * CFG_XLEN + j) <= noc1_data_s_out((i - 1) * CFG_XLEN + j); + noc1_data_void_in(i * CFG_XLEN + j)(0) <= noc1_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc1_stop_in(i * CFG_XLEN + j)(0) <= noc1_stop_out((i - 1) * CFG_XLEN + j)(1); + noc2_data_n_in(i * CFG_XLEN + j) <= noc2_data_s_out((i - 1) * CFG_XLEN + j); + noc2_data_void_in(i * CFG_XLEN + j)(0) <= noc2_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc2_stop_in(i * CFG_XLEN + j)(0) <= noc2_stop_out((i - 1) * CFG_XLEN + j)(1); + noc3_data_n_in(i * CFG_XLEN + j) <= noc3_data_s_out((i - 1) * CFG_XLEN + j); + noc3_data_void_in(i * CFG_XLEN + j)(0) <= noc3_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc3_stop_in(i * CFG_XLEN + j)(0) <= noc3_stop_out((i - 1) * CFG_XLEN + j)(1); + noc4_data_n_in(i * CFG_XLEN + j) <= noc4_data_s_out((i - 1) * CFG_XLEN + j); + noc4_data_void_in(i * CFG_XLEN + j)(0) <= noc4_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc4_stop_in(i * CFG_XLEN + j)(0) <= noc4_stop_out((i - 1) * CFG_XLEN + j)(1); + noc5_data_n_in(i * CFG_XLEN + j) <= noc5_data_s_out((i - 1) * CFG_XLEN + j); + noc5_data_void_in(i * CFG_XLEN + j)(0) <= noc5_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc5_stop_in(i * CFG_XLEN + j)(0) <= noc5_stop_out((i - 1) * CFG_XLEN + j)(1); + noc6_data_n_in(i * CFG_XLEN + j) <= noc6_data_s_out((i - 1) * CFG_XLEN + j); + noc6_data_void_in(i * CFG_XLEN + j)(0) <= noc6_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc6_stop_in(i * CFG_XLEN + j)(0) <= noc6_stop_out((i - 1) * CFG_XLEN + j)(1); end generate y_non_0; - y_YLEN : if (i = CFG_YLEN-1) generate + y_ylen : if (i = CFG_YLEN - 1) generate -- South port is unconnected - noc1_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc2_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc3_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc4_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc5_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc6_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(1) <= '0'; - end generate y_YLEN; - - y_non_YLEN : if (i /= CFG_YLEN-1) generate + noc1_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc2_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc3_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc4_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc5_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc6_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(1) <= '0'; + end generate y_ylen; + + y_non_ylen : if (i /= CFG_YLEN - 1) generate -- south port is connected - noc1_data_s_in(i*CFG_XLEN + j) <= noc1_data_n_out((i+1)*CFG_XLEN + j); - noc1_data_void_in(i*CFG_XLEN + j)(1) <= noc1_data_void_out((i+1)*CFG_XLEN + j)(0); - noc1_stop_in(i*CFG_XLEN + j)(1) <= noc1_stop_out((i+1)*CFG_XLEN + j)(0); - noc2_data_s_in(i*CFG_XLEN + j) <= noc2_data_n_out((i+1)*CFG_XLEN + j); - noc2_data_void_in(i*CFG_XLEN + j)(1) <= noc2_data_void_out((i+1)*CFG_XLEN + j)(0); - noc2_stop_in(i*CFG_XLEN + j)(1) <= noc2_stop_out((i+1)*CFG_XLEN + j)(0); - noc3_data_s_in(i*CFG_XLEN + j) <= noc3_data_n_out((i+1)*CFG_XLEN + j); - noc3_data_void_in(i*CFG_XLEN + j)(1) <= noc3_data_void_out((i+1)*CFG_XLEN + j)(0); - noc3_stop_in(i*CFG_XLEN + j)(1) <= noc3_stop_out((i+1)*CFG_XLEN + j)(0); - noc4_data_s_in(i*CFG_XLEN + j) <= noc4_data_n_out((i+1)*CFG_XLEN + j); - noc4_data_void_in(i*CFG_XLEN + j)(1) <= noc4_data_void_out((i+1)*CFG_XLEN + j)(0); - noc4_stop_in(i*CFG_XLEN + j)(1) <= noc4_stop_out((i+1)*CFG_XLEN + j)(0); - noc5_data_s_in(i*CFG_XLEN + j) <= noc5_data_n_out((i+1)*CFG_XLEN + j); - noc5_data_void_in(i*CFG_XLEN + j)(1) <= noc5_data_void_out((i+1)*CFG_XLEN + j)(0); - noc5_stop_in(i*CFG_XLEN + j)(1) <= noc5_stop_out((i+1)*CFG_XLEN + j)(0); - noc6_data_s_in(i*CFG_XLEN + j) <= noc6_data_n_out((i+1)*CFG_XLEN + j); - noc6_data_void_in(i*CFG_XLEN + j)(1) <= noc6_data_void_out((i+1)*CFG_XLEN + j)(0); - noc6_stop_in(i*CFG_XLEN + j)(1) <= noc6_stop_out((i+1)*CFG_XLEN + j)(0); - end generate y_non_YLEN; + noc1_data_s_in(i * CFG_XLEN + j) <= noc1_data_n_out((i + 1) * CFG_XLEN + j); + noc1_data_void_in(i * CFG_XLEN + j)(1) <= noc1_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc1_stop_in(i * CFG_XLEN + j)(1) <= noc1_stop_out((i + 1) * CFG_XLEN + j)(0); + noc2_data_s_in(i * CFG_XLEN + j) <= noc2_data_n_out((i + 1) * CFG_XLEN + j); + noc2_data_void_in(i * CFG_XLEN + j)(1) <= noc2_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc2_stop_in(i * CFG_XLEN + j)(1) <= noc2_stop_out((i + 1) * CFG_XLEN + j)(0); + noc3_data_s_in(i * CFG_XLEN + j) <= noc3_data_n_out((i + 1) * CFG_XLEN + j); + noc3_data_void_in(i * CFG_XLEN + j)(1) <= noc3_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc3_stop_in(i * CFG_XLEN + j)(1) <= noc3_stop_out((i + 1) * CFG_XLEN + j)(0); + noc4_data_s_in(i * CFG_XLEN + j) <= noc4_data_n_out((i + 1) * CFG_XLEN + j); + noc4_data_void_in(i * CFG_XLEN + j)(1) <= noc4_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc4_stop_in(i * CFG_XLEN + j)(1) <= noc4_stop_out((i + 1) * CFG_XLEN + j)(0); + noc5_data_s_in(i * CFG_XLEN + j) <= noc5_data_n_out((i + 1) * CFG_XLEN + j); + noc5_data_void_in(i * CFG_XLEN + j)(1) <= noc5_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc5_stop_in(i * CFG_XLEN + j)(1) <= noc5_stop_out((i + 1) * CFG_XLEN + j)(0); + noc6_data_s_in(i * CFG_XLEN + j) <= noc6_data_n_out((i + 1) * CFG_XLEN + j); + noc6_data_void_in(i * CFG_XLEN + j)(1) <= noc6_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc6_stop_in(i * CFG_XLEN + j)(1) <= noc6_stop_out((i + 1) * CFG_XLEN + j)(0); + end generate y_non_ylen; x_0 : if (j = 0) generate -- West port is unconnected - noc1_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc2_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc3_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc4_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc5_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc6_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(2) <= '0'; + noc1_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc2_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc3_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc4_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc5_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc6_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(2) <= '0'; end generate x_0; x_non_0 : if (j /= 0) generate -- West port is connected - noc1_data_w_in(i*CFG_XLEN + j) <= noc1_data_e_out(i*CFG_XLEN + j - 1); - noc1_data_void_in(i*CFG_XLEN + j)(2) <= noc1_data_void_out(i*CFG_XLEN + j - 1)(3); - noc1_stop_in(i*CFG_XLEN + j)(2) <= noc1_stop_out(i*CFG_XLEN + j - 1)(3); - noc2_data_w_in(i*CFG_XLEN + j) <= noc2_data_e_out(i*CFG_XLEN + j - 1); - noc2_data_void_in(i*CFG_XLEN + j)(2) <= noc2_data_void_out(i*CFG_XLEN + j - 1)(3); - noc2_stop_in(i*CFG_XLEN + j)(2) <= noc2_stop_out(i*CFG_XLEN + j - 1)(3); - noc3_data_w_in(i*CFG_XLEN + j) <= noc3_data_e_out(i*CFG_XLEN + j - 1); - noc3_data_void_in(i*CFG_XLEN + j)(2) <= noc3_data_void_out(i*CFG_XLEN + j - 1)(3); - noc3_stop_in(i*CFG_XLEN + j)(2) <= noc3_stop_out(i*CFG_XLEN + j - 1)(3); - noc4_data_w_in(i*CFG_XLEN + j) <= noc4_data_e_out(i*CFG_XLEN + j - 1); - noc4_data_void_in(i*CFG_XLEN + j)(2) <= noc4_data_void_out(i*CFG_XLEN + j - 1)(3); - noc4_stop_in(i*CFG_XLEN + j)(2) <= noc4_stop_out(i*CFG_XLEN + j - 1)(3); - noc5_data_w_in(i*CFG_XLEN + j) <= noc5_data_e_out(i*CFG_XLEN + j - 1); - noc5_data_void_in(i*CFG_XLEN + j)(2) <= noc5_data_void_out(i*CFG_XLEN + j - 1)(3); - noc5_stop_in(i*CFG_XLEN + j)(2) <= noc5_stop_out(i*CFG_XLEN + j - 1)(3); - noc6_data_w_in(i*CFG_XLEN + j) <= noc6_data_e_out(i*CFG_XLEN + j - 1); - noc6_data_void_in(i*CFG_XLEN + j)(2) <= noc6_data_void_out(i*CFG_XLEN + j - 1)(3); - noc6_stop_in(i*CFG_XLEN + j)(2) <= noc6_stop_out(i*CFG_XLEN + j - 1)(3); + noc1_data_w_in(i * CFG_XLEN + j) <= noc1_data_e_out(i * CFG_XLEN + j - 1); + noc1_data_void_in(i * CFG_XLEN + j)(2) <= noc1_data_void_out(i * CFG_XLEN + j - 1)(3); + noc1_stop_in(i * CFG_XLEN + j)(2) <= noc1_stop_out(i * CFG_XLEN + j - 1)(3); + noc2_data_w_in(i * CFG_XLEN + j) <= noc2_data_e_out(i * CFG_XLEN + j - 1); + noc2_data_void_in(i * CFG_XLEN + j)(2) <= noc2_data_void_out(i * CFG_XLEN + j - 1)(3); + noc2_stop_in(i * CFG_XLEN + j)(2) <= noc2_stop_out(i * CFG_XLEN + j - 1)(3); + noc3_data_w_in(i * CFG_XLEN + j) <= noc3_data_e_out(i * CFG_XLEN + j - 1); + noc3_data_void_in(i * CFG_XLEN + j)(2) <= noc3_data_void_out(i * CFG_XLEN + j - 1)(3); + noc3_stop_in(i * CFG_XLEN + j)(2) <= noc3_stop_out(i * CFG_XLEN + j - 1)(3); + noc4_data_w_in(i * CFG_XLEN + j) <= noc4_data_e_out(i * CFG_XLEN + j - 1); + noc4_data_void_in(i * CFG_XLEN + j)(2) <= noc4_data_void_out(i * CFG_XLEN + j - 1)(3); + noc4_stop_in(i * CFG_XLEN + j)(2) <= noc4_stop_out(i * CFG_XLEN + j - 1)(3); + noc5_data_w_in(i * CFG_XLEN + j) <= noc5_data_e_out(i * CFG_XLEN + j - 1); + noc5_data_void_in(i * CFG_XLEN + j)(2) <= noc5_data_void_out(i * CFG_XLEN + j - 1)(3); + noc5_stop_in(i * CFG_XLEN + j)(2) <= noc5_stop_out(i * CFG_XLEN + j - 1)(3); + noc6_data_w_in(i * CFG_XLEN + j) <= noc6_data_e_out(i * CFG_XLEN + j - 1); + noc6_data_void_in(i * CFG_XLEN + j)(2) <= noc6_data_void_out(i * CFG_XLEN + j - 1)(3); + noc6_stop_in(i * CFG_XLEN + j)(2) <= noc6_stop_out(i * CFG_XLEN + j - 1)(3); end generate x_non_0; - x_XLEN : if (j = CFG_XLEN-1) generate + x_xlen : if (j = CFG_XLEN - 1) generate -- East port is unconnected - noc1_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc2_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc3_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc4_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc5_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc6_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(3) <= '0'; - end generate x_XLEN; - - x_non_XLEN : if (j /= CFG_XLEN-1) generate + noc1_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc2_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc3_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc4_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc5_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc6_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(3) <= '0'; + end generate x_xlen; + + x_non_xlen : if (j /= CFG_XLEN - 1) generate -- East port is connected - noc1_data_e_in(i*CFG_XLEN + j) <= noc1_data_w_out(i*CFG_XLEN + j + 1); - noc1_data_void_in(i*CFG_XLEN + j)(3) <= noc1_data_void_out(i*CFG_XLEN + j + 1)(2); - noc1_stop_in(i*CFG_XLEN + j)(3) <= noc1_stop_out(i*CFG_XLEN + j + 1)(2); - noc2_data_e_in(i*CFG_XLEN + j) <= noc2_data_w_out(i*CFG_XLEN + j + 1); - noc2_data_void_in(i*CFG_XLEN + j)(3) <= noc2_data_void_out(i*CFG_XLEN + j + 1)(2); - noc2_stop_in(i*CFG_XLEN + j)(3) <= noc2_stop_out(i*CFG_XLEN + j + 1)(2); - noc3_data_e_in(i*CFG_XLEN + j) <= noc3_data_w_out(i*CFG_XLEN + j + 1); - noc3_data_void_in(i*CFG_XLEN + j)(3) <= noc3_data_void_out(i*CFG_XLEN + j + 1)(2); - noc3_stop_in(i*CFG_XLEN + j)(3) <= noc3_stop_out(i*CFG_XLEN + j + 1)(2); - noc4_data_e_in(i*CFG_XLEN + j) <= noc4_data_w_out(i*CFG_XLEN + j + 1); - noc4_data_void_in(i*CFG_XLEN + j)(3) <= noc4_data_void_out(i*CFG_XLEN + j + 1)(2); - noc4_stop_in(i*CFG_XLEN + j)(3) <= noc4_stop_out(i*CFG_XLEN + j + 1)(2); - noc5_data_e_in(i*CFG_XLEN + j) <= noc5_data_w_out(i*CFG_XLEN + j + 1); - noc5_data_void_in(i*CFG_XLEN + j)(3) <= noc5_data_void_out(i*CFG_XLEN + j + 1)(2); - noc5_stop_in(i*CFG_XLEN + j)(3) <= noc5_stop_out(i*CFG_XLEN + j + 1)(2); - noc6_data_e_in(i*CFG_XLEN + j) <= noc6_data_w_out(i*CFG_XLEN + j + 1); - noc6_data_void_in(i*CFG_XLEN + j)(3) <= noc6_data_void_out(i*CFG_XLEN + j + 1)(2); - noc6_stop_in(i*CFG_XLEN + j)(3) <= noc6_stop_out(i*CFG_XLEN + j + 1)(2); - end generate x_non_XLEN; + noc1_data_e_in(i * CFG_XLEN + j) <= noc1_data_w_out(i * CFG_XLEN + j + 1); + noc1_data_void_in(i * CFG_XLEN + j)(3) <= noc1_data_void_out(i * CFG_XLEN + j + 1)(2); + noc1_stop_in(i * CFG_XLEN + j)(3) <= noc1_stop_out(i * CFG_XLEN + j + 1)(2); + noc2_data_e_in(i * CFG_XLEN + j) <= noc2_data_w_out(i * CFG_XLEN + j + 1); + noc2_data_void_in(i * CFG_XLEN + j)(3) <= noc2_data_void_out(i * CFG_XLEN + j + 1)(2); + noc2_stop_in(i * CFG_XLEN + j)(3) <= noc2_stop_out(i * CFG_XLEN + j + 1)(2); + noc3_data_e_in(i * CFG_XLEN + j) <= noc3_data_w_out(i * CFG_XLEN + j + 1); + noc3_data_void_in(i * CFG_XLEN + j)(3) <= noc3_data_void_out(i * CFG_XLEN + j + 1)(2); + noc3_stop_in(i * CFG_XLEN + j)(3) <= noc3_stop_out(i * CFG_XLEN + j + 1)(2); + noc4_data_e_in(i * CFG_XLEN + j) <= noc4_data_w_out(i * CFG_XLEN + j + 1); + noc4_data_void_in(i * CFG_XLEN + j)(3) <= noc4_data_void_out(i * CFG_XLEN + j + 1)(2); + noc4_stop_in(i * CFG_XLEN + j)(3) <= noc4_stop_out(i * CFG_XLEN + j + 1)(2); + noc5_data_e_in(i * CFG_XLEN + j) <= noc5_data_w_out(i * CFG_XLEN + j + 1); + noc5_data_void_in(i * CFG_XLEN + j)(3) <= noc5_data_void_out(i * CFG_XLEN + j + 1)(2); + noc5_stop_in(i * CFG_XLEN + j)(3) <= noc5_stop_out(i * CFG_XLEN + j + 1)(2); + noc6_data_e_in(i * CFG_XLEN + j) <= noc6_data_w_out(i * CFG_XLEN + j + 1); + noc6_data_void_in(i * CFG_XLEN + j)(3) <= noc6_data_void_out(i * CFG_XLEN + j + 1)(2); + noc6_stop_in(i * CFG_XLEN + j)(3) <= noc6_stop_out(i * CFG_XLEN + j + 1)(2); + end generate x_non_xlen; end generate meshgen_x; - end generate meshgen_y; + end generate meshgen_y; ----------------------------------------------------------------------------- -- TILES ----------------------------------------------------------------------------- + tiles_gen : for i in 0 to CFG_TILES_NUM - 1 generate empty_tile : if tile_type(i) = 0 generate - tile_empty_i : asic_tile_empty + + tile_empty_i : component asic_tile_empty generic map ( - SIMULATION => SIMULATION, - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - this_has_dco => 1 - ESP_EMU) + simulation => SIMULATION, + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + this_has_dco => 1 - ESP_EMU + ) port map ( rst => reset_int, sys_clk => sys_clk, @@ -901,19 +1753,23 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); - end generate empty_tile; + noc6_stop_out => noc6_stop_out(i) + ); + end generate empty_tile; cpu_tile : if tile_type(i) = 1 generate --- pragma translate_off - assert tile_cpu_id(i) /= -1 report "Undefined CPU ID for CPU tile" severity error; --- pragma translate_on - tile_cpu_i : asic_tile_cpu + -- pragma translate_off + assert tile_cpu_id(i) /= -1 + report "Undefined CPU ID for CPU tile" + severity error; + -- pragma translate_on + tile_cpu_i : component asic_tile_cpu generic map ( - SIMULATION => SIMULATION, - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - this_has_dco => 1 - ESP_EMU) + simulation => SIMULATION, + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + this_has_dco => 1 - ESP_EMU + ) port map ( rst => reset_int, sys_clk => sys_clk, @@ -996,22 +1852,26 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); - end generate cpu_tile; + noc6_stop_out => noc6_stop_out(i) + ); + end generate cpu_tile; accelerator_tile : if tile_type(i) = 2 generate --- pragma translate_off - assert tile_device(i) /= 0 report "Undefined device ID for accelerator tile" severity error; --- pragma translate_on - tile_acc_i : asic_tile_acc + -- pragma translate_off + assert tile_device(i) /= 0 + report "Undefined device ID for accelerator tile" + severity error; + -- pragma translate_on + tile_acc_i : component asic_tile_acc generic map ( this_hls_conf => tile_design_point(i), this_device => tile_device(i), this_irq_type => tile_irq_type(i), this_has_l2 => tile_has_l2(i), - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - this_has_dco => 1 - ESP_EMU) + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + this_has_dco => 1 - ESP_EMU + ) port map ( rst => reset_int, sys_clk => sys_clk, @@ -1095,51 +1955,53 @@ begin noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), noc6_stop_out => noc6_stop_out(i) - ); - end generate accelerator_tile; + ); + end generate accelerator_tile; io_tile : if tile_type(i) = 3 generate - tile_io_i : asic_tile_io + + tile_io_i : component asic_tile_io generic map ( - SIMULATION => SIMULATION, - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - this_has_dco => 1 - ESP_EMU) + simulation => SIMULATION, + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + this_has_dco => 1 - ESP_EMU + ) port map ( - rst => reset_int, -- from I/O PAD reset - sys_rstn_out => sys_rstn, -- NoC reset out (unused; connect other tiles directly to reset PAD) - sys_clk_out => sys_clk, -- NoC clock out - sys_clk => sys_clk, -- NoC clock in - sys_clk_lock_out => sys_clk_lock, -- NoC DCO lock - ext_clk_noc => ext_clk_noc_int, -- backup NoC clock - clk_div_noc => clk_div_noc_int, - ext_clk => ext_clk_int(i), -- backup clock (fixed) - clk_div => clk_div_int(i), - reset_o2 => reset_o2_int, - etx_clk => etx_clk_int, - erx_clk => erx_clk_int, - erxd => erxd_int, - erx_dv => erx_dv_int, - erx_er => erx_er_int, - erx_col => erx_col_int, - erx_crs => erx_crs_int, - etxd => etxd_int, - etx_en => etx_en_int, - etx_er => etx_er_int, - emdc => emdc_int, - emdio_i => emdio_i, - emdio_o => emdio_o, - emdio_oe => emdio_oe, - -- I/O link - iolink_data_oen => open, - iolink_data_in => (others => '0'), - iolink_data_out => open, - iolink_valid_in => '0', - iolink_valid_out => open, - iolink_clk_in => '0', - iolink_clk_out => open, - iolink_credit_in => '0', - iolink_credit_out => open, + rst => reset_int, + sys_rstn_out => sys_rstn, + sys_clk_out => sys_clk, + sys_clk => sys_clk, + sys_clk_lock_out => sys_clk_lock, + ext_clk_noc => ext_clk_noc_int, + clk_div_noc => clk_div_noc_int, + ext_clk => ext_clk_int(i), + clk_div => clk_div_int(i), + reset_o2 => reset_o2_int, + etx_clk => etx_clk_int, + erx_clk => erx_clk_int, + erxd => erxd_int, + erx_dv => erx_dv_int, + erx_er => erx_er_int, + erx_col => erx_col_int, + erx_crs => erx_crs_int, + etxd => etxd_int, + etx_en => etx_en_int, + etx_er => etx_er_int, + emdc => emdc_int, + emdio_i => emdio_i, + emdio_o => emdio_o, + emdio_oe => emdio_oe, + -- I/O link + iolink_data_oen => open, + iolink_data_in => (others => '0'), + iolink_data_out => open, + iolink_valid_in => '0', + iolink_valid_out => open, + iolink_clk_in => '0', + iolink_clk_out => open, + iolink_credit_in => '0', + iolink_credit_out => open, -- dvi_nhpd => dvi_nhpd, -- clkvga_p => clkvga_p, -- clkvga_n => clkvga_n, @@ -1236,15 +2098,18 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); - end generate io_tile; + noc6_stop_out => noc6_stop_out(i) + ); + end generate io_tile; mem_tile : if tile_type(i) = 4 generate - tile_mem_i : asic_tile_mem + + tile_mem_i : component asic_tile_mem generic map ( - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - this_has_dco => 1 - ESP_EMU) + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + this_has_dco => 1 - ESP_EMU + ) port map ( rst => reset_int, sys_clk => sys_clk, @@ -1336,14 +2201,18 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); + noc6_stop_out => noc6_stop_out(i) + ); + end generate mem_tile; slm_tile : if tile_type(i) = 5 generate - tile_slm_i : asic_tile_slm + + tile_slm_i : component asic_tile_slm generic map ( - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - this_has_dco => 1 - ESP_EMU) + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + this_has_dco => 1 - ESP_EMU + ) port map ( rst => reset_int, sys_clk => sys_clk, @@ -1426,9 +2295,11 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); + noc6_stop_out => noc6_stop_out(i) + ); + end generate slm_tile; end generate tiles_gen; -end; +end architecture rtl; diff --git a/socs/epochs0-gf12/systest.c b/socs/epochs0-gf12/systest.c index 08f2d177f4..df58d1dee6 100644 --- a/socs/epochs0-gf12/systest.c +++ b/socs/epochs0-gf12/systest.c @@ -3,7 +3,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/esp_asic_generic/ESP_ASIC_TOP.vhd b/socs/esp_asic_generic/ESP_ASIC_TOP.vhd index b2f3a9ab26..b46bd5dfa8 100644 --- a/socs/esp_asic_generic/ESP_ASIC_TOP.vhd +++ b/socs/esp_asic_generic/ESP_ASIC_TOP.vhd @@ -2,40 +2,42 @@ -- SPDX-License-Identifier: Apache-2.0 library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_misc.all; -use work.esp_global.all; -use work.amba.all; -use work.stdlib.all; -use work.sld_devices.all; -use work.devices.all; -use work.gencomp.all; -use work.leon3.all; -use work.net.all; --- pragma translate_off -use work.sim.all; + use ieee.std_logic_1164.all; + use ieee.std_logic_misc.all; + use work.esp_global.all; + use work.amba.all; + use work.stdlib.all; + use work.sld_devices.all; + use work.devices.all; + use work.gencomp.all; + use work.leon3.all; + use work.net.all; + -- pragma translate_off + use work.sim.all; + library unisim; -use unisim.all; --- pragma translate_on -use work.monitor_pkg.all; -use work.esp_csr_pkg.all; -use work.sldacc.all; -use work.tile.all; -use work.nocpackage.all; -use work.coretypes.all; -use work.grlib_config.all; -use work.socmap.all; -use work.tiles_asic_pkg.all; -use work.pads_loc.all; - -entity ESP_ASIC_TOP is + use unisim.all; + -- pragma translate_on + use work.monitor_pkg.all; + use work.esp_csr_pkg.all; + use work.sldacc.all; + use work.tile.all; + use work.nocpackage.all; + use work.coretypes.all; + use work.grlib_config.all; + use work.socmap.all; + use work.tiles_asic_pkg.all; + use work.pads_loc.all; + +entity esp_asic_top is generic ( - SIMULATION : boolean := false); + simulation : boolean := false + ); port ( - reset : in std_logic; + reset : in std_logic; -- Backup external clocks for selected tiles and NoC - ext_clk : in std_logic; - clk_div : out std_logic; + ext_clk : in std_logic; + clk_div : out std_logic; -- FPGA proxy memory link fpga_data : inout std_logic_vector(CFG_NMEM_TILE * CFG_MEM_LINK_BITS - 1 downto 0); fpga_valid_in : in std_logic_vector(CFG_NMEM_TILE - 1 downto 0); @@ -53,136 +55,136 @@ entity ESP_ASIC_TOP is iolink_credit_in : in std_ulogic; iolink_credit_out : out std_ulogic; -- Ethernet signals - reset_o2 : out std_ulogic; - etx_clk : in std_ulogic; - erx_clk : in std_ulogic; - erxd : in std_logic_vector(3 downto 0); - erx_dv : in std_ulogic; - erx_er : in std_ulogic; - erx_col : in std_ulogic; - erx_crs : in std_ulogic; - etxd : out std_logic_vector(3 downto 0); - etx_en : out std_ulogic; - etx_er : out std_ulogic; - emdc : out std_ulogic; - emdio : inout std_logic; + reset_o2 : out std_ulogic; + etx_clk : in std_ulogic; + erx_clk : in std_ulogic; + erxd : in std_logic_vector(3 downto 0); + erx_dv : in std_ulogic; + erx_er : in std_ulogic; + erx_col : in std_ulogic; + erx_crs : in std_ulogic; + etxd : out std_logic_vector(3 downto 0); + etx_en : out std_ulogic; + etx_er : out std_ulogic; + emdc : out std_ulogic; + emdio : inout std_logic; -- UART - uart_rxd : in std_logic; -- UART1_RX (u1i.rxd) - uart_txd : out std_logic; -- UART1_TX (u1o.txd) - uart_ctsn : in std_logic; -- UART1_RTSN (u1i.ctsn) - uart_rtsn : out std_logic; -- UART1_RTSN (u1o.rtsn) - --JTAG - tclk : in std_logic; - tms : in std_logic; - tdi_io : in std_logic; - tdi_cpu : in std_logic; - tdi_mem : in std_logic; - tdi_acc : in std_logic; - tdo_io : out std_logic; - tdo_cpu : out std_logic; - tdo_mem : out std_logic; - tdo_acc : out std_logic - ); -end; - - - -architecture rtl of ESP_ASIC_TOP is + uart_rxd : in std_logic; -- UART1_RX (u1i.rxd) + uart_txd : out std_logic; -- UART1_TX (u1o.txd) + uart_ctsn : in std_logic; -- UART1_RTSN (u1i.ctsn) + uart_rtsn : out std_logic; -- UART1_RTSN (u1o.rtsn) + -- JTAG + tclk : in std_logic; + tms : in std_logic; + tdi_io : in std_logic; + tdi_cpu : in std_logic; + tdi_mem : in std_logic; + tdi_acc : in std_logic; + tdo_io : out std_logic; + tdo_cpu : out std_logic; + tdo_mem : out std_logic; + tdo_acc : out std_logic + ); +end entity esp_asic_top; +architecture rtl of esp_asic_top is - type handshake_vec is array (CFG_TILES_NUM-1 downto 0) of std_logic_vector(3 downto 0); + type handshake_vec is array (CFG_TILES_NUM - 1 downto 0) of std_logic_vector(3 downto 0); -- NOC Signals - signal noc1_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc1_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc1_data_void_in : handshake_vec; signal noc1_stop_in : handshake_vec; - signal noc1_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc1_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc1_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc1_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc1_data_void_out : handshake_vec; signal noc1_stop_out : handshake_vec; - signal noc2_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc2_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc2_data_void_in : handshake_vec; signal noc2_stop_in : handshake_vec; - signal noc2_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc2_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc2_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc2_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc2_data_void_out : handshake_vec; signal noc2_stop_out : handshake_vec; - signal noc3_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc3_data_n_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_s_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_w_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_e_in : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc3_data_void_in : handshake_vec; signal noc3_stop_in : handshake_vec; - signal noc3_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc3_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc3_data_n_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_s_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_w_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc3_data_e_out : coh_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc3_data_void_out : handshake_vec; signal noc3_stop_out : handshake_vec; - signal noc4_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc4_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc4_data_void_in : handshake_vec; signal noc4_stop_in : handshake_vec; - signal noc4_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc4_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc4_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc4_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc4_data_void_out : handshake_vec; signal noc4_stop_out : handshake_vec; - signal noc5_data_n_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_s_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_w_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_e_in : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc5_data_n_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_s_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_w_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_e_in : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc5_data_void_in : handshake_vec; signal noc5_stop_in : handshake_vec; - signal noc5_data_n_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_s_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_w_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc5_data_e_out : misc_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc5_data_n_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_s_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_w_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc5_data_e_out : misc_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc5_data_void_out : handshake_vec; signal noc5_stop_out : handshake_vec; - signal noc6_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc6_data_n_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_s_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_w_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_e_in : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc6_data_void_in : handshake_vec; signal noc6_stop_in : handshake_vec; - signal noc6_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); - signal noc6_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM-1 downto 0); + signal noc6_data_n_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_s_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_w_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); + signal noc6_data_e_out : dma_noc_flit_vector(CFG_TILES_NUM - 1 downto 0); signal noc6_data_void_out : handshake_vec; signal noc6_stop_out : handshake_vec; -- Global NoC reset and clock - signal sys_clk : std_ulogic; - signal sys_rstn : std_ulogic; - signal sys_clk_lock : std_ulogic; + signal sys_clk : std_ulogic; + signal sys_rstn : std_ulogic; + signal sys_clk_lock : std_ulogic; -- I/O for PADS - constant pad_fixed_cfg : std_logic_vector(19 - (ESP_CSR_PAD_CFG_MSB - ESP_CSR_PAD_CFG_LSB + 1) downto 0) := (others => '0'); + constant PAD_FIXED_CFG : std_logic_vector(19 - (ESP_CSR_PAD_CFG_MSB - ESP_CSR_PAD_CFG_LSB + 1) downto 0) := (others => '0'); + type pad_cfg_full_array is array (0 to CFG_TILES_NUM - 1) of std_logic_vector(19 downto 0); + type pad_cfg_array is array (0 to CFG_TILES_NUM - 1) of std_logic_vector(ESP_CSR_PAD_CFG_MSB - ESP_CSR_PAD_CFG_LSB downto 0); + -- Current default configuration is SR=0, DS1=1, DS0=1 - signal pad_cfg : pad_cfg_array; + signal pad_cfg : pad_cfg_array; signal full_pad_cfg : pad_cfg_full_array; -- External clocks and reset - signal reset_int : std_logic; - signal ext_clk_int : std_logic; -- backup tile clock - signal clk_div_int : std_logic_vector(0 to CFG_TILES_NUM - 1); -- tile clock monitor for testing purposes + signal reset_int : std_logic; + signal ext_clk_int : std_logic; -- backup tile clock + signal clk_div_int : std_logic_vector(0 to CFG_TILES_NUM - 1); -- tile clock monitor for testing purposes signal ext_clk_noc_int : std_logic; signal clk_div_noc_int : std_logic; @@ -209,34 +211,34 @@ architecture rtl of ESP_ASIC_TOP is signal iolink_data_in_int : std_logic_vector(CFG_IOLINK_BITS - 1 downto 0); signal iolink_data_out_int : std_logic_vector(CFG_IOLINK_BITS - 1 downto 0); signal iolink_valid_in_int : std_ulogic; - signal iolink_valid_out_int, iolink_valid_out_io : std_ulogic; + signal iolink_valid_out_int, iolink_valid_out_io : std_ulogic; signal iolink_clk_in_int : std_ulogic; - signal iolink_clk_out_int, iolink_clk_out_io : std_ulogic; + signal iolink_clk_out_int, iolink_clk_out_io : std_ulogic; signal iolink_credit_in_int : std_ulogic; signal iolink_credit_out_int, iolink_credit_out_io : std_ulogic; -- Ethernet signals - signal reset_o2_int : std_ulogic; - signal etx_clk_int : std_ulogic; - signal erx_clk_int : std_ulogic; - signal erxd_int : std_logic_vector(3 downto 0); - signal erx_dv_int : std_ulogic; - signal erx_er_int : std_ulogic; - signal erx_col_int : std_ulogic; - signal erx_crs_int : std_ulogic; - signal etxd_int : std_logic_vector(3 downto 0); - signal etx_en_int : std_ulogic; - signal etx_er_int : std_ulogic; - signal emdc_int : std_ulogic; - signal emdio_i : std_logic; - signal emdio_o : std_logic; - signal emdio_oe : std_logic; + signal reset_o2_int : std_ulogic; + signal etx_clk_int : std_ulogic; + signal erx_clk_int : std_ulogic; + signal erxd_int : std_logic_vector(3 downto 0); + signal erx_dv_int : std_ulogic; + signal erx_er_int : std_ulogic; + signal erx_col_int : std_ulogic; + signal erx_crs_int : std_ulogic; + signal etxd_int : std_logic_vector(3 downto 0); + signal etx_en_int : std_ulogic; + signal etx_er_int : std_ulogic; + signal emdc_int : std_ulogic; + signal emdio_i : std_logic; + signal emdio_o : std_logic; + signal emdio_oe : std_logic; -- UART - signal uart_rxd_int : std_logic; -- UART1_RX (u1i.rxd) - signal uart_txd_int : std_logic; -- UART1_TX (u1o.txd) - signal uart_ctsn_int : std_logic; -- UART1_RTSN (u1i.ctsn) - signal uart_rtsn_int : std_logic; -- UART1_RTSN (u1o.rtsn) + signal uart_rxd_int : std_logic; -- UART1_RX (u1i.rxd) + signal uart_txd_int : std_logic; -- UART1_TX (u1o.txd) + signal uart_ctsn_int : std_logic; -- UART1_RTSN (u1i.ctsn) + signal uart_rtsn_int : std_logic; -- UART1_RTSN (u1o.rtsn) begin @@ -245,296 +247,643 @@ begin ----------------------------------------------------------------------------- pad_cfg_gen : for i in 0 to CFG_TILES_NUM - 1 generate - full_pad_cfg(i) <= pad_fixed_cfg & pad_cfg(i); + full_pad_cfg(i) <= PAD_FIXED_CFG & pad_cfg(i); end generate pad_cfg_gen; - reset_pad : inpad generic map (loc => reset_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (reset, reset_int); + reset_pad : component inpad + generic map ( + loc => reset_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +reset, + reset_int + ); + -- ext_clk and div_clk for NoC (DCO located in the I/O tile) - ext_clk_pad : inpad generic map (loc => ext_clk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (ext_clk, ext_clk_int); - clk_div_pad : outpad generic map (loc => clk_div_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (clk_div, clk_div_noc_int, full_pad_cfg(io_tile_id)); + ext_clk_pad : component inpad + generic map ( + loc => ext_clk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +ext_clk, + ext_clk_int + ); + + clk_div_pad : component outpad + generic map ( + loc => clk_div_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +clk_div, + clk_div_noc_int, + full_pad_cfg(io_tile_id) + ); + -- tdi/o_cpu - tdi_cpu_pad : inpad generic map (loc => tdi_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_cpu, tdi_int(cpu_tile_id(0))); - tdo_cpu_pad : outpad generic map (loc => tdo_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_cpu, tdo_int(cpu_tile_id(0)), full_pad_cfg(cpu_tile_id(0))); + tdi_cpu_pad : component inpad + generic map ( + loc => tdi_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_cpu, + tdi_int(cpu_tile_id(0)) + ); + + tdo_cpu_pad : component outpad + generic map ( + loc => tdo_cpu_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_cpu, + tdo_int(cpu_tile_id(0)), + full_pad_cfg(cpu_tile_id(0)) + ); + -- tdi/o_io - tdi_io_pad : inpad generic map (loc => tdi_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_io, tdi_int(io_tile_id)); - tdo_io_pad : outpad generic map (loc => tdo_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_io, tdo_int(io_tile_id), full_pad_cfg(io_tile_id)); + tdi_io_pad : component inpad + generic map ( + loc => tdi_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_io, + tdi_int(io_tile_id) + ); + + tdo_io_pad : component outpad + generic map ( + loc => tdo_io_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_io, + tdo_int(io_tile_id), + full_pad_cfg(io_tile_id) + ); + -- tdi/o_mem pad is close to memory tile 0 - tdi_mem_pad : inpad generic map (loc => tdi_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_mem, tdi_int(mem_tile_id(0))); - tdo_mem_pad : outpad generic map (loc => tdo_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_mem, tdo_int(mem_tile_id(0)), full_pad_cfg(mem_tile_id(0))); + tdi_mem_pad : component inpad + generic map ( + loc => tdi_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_mem, + tdi_int(mem_tile_id(0)) + ); + + tdo_mem_pad : component outpad + generic map ( + loc => tdo_mem_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_mem, + tdo_int(mem_tile_id(0)), + full_pad_cfg(mem_tile_id(0)) + ); + -- tdi/o_acc - tdi_acc_pad : inpad generic map (loc => tdi_acc_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdi_acc, tdi_int(2)); - tdo_acc_pad : outpad generic map (loc => tdo_acc_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tdo_acc, tdo_int(2), full_pad_cfg(2)); + tdi_acc_pad : component inpad + generic map ( + loc => tdi_acc_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdi_acc, + tdi_int(2) + ); + + tdo_acc_pad : component outpad + generic map ( + loc => tdo_acc_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tdo_acc, + tdo_int(2), + full_pad_cfg(2) + ); - tms_pad : inpad generic map (loc => tms_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tms, tms_int); - tclk_pad : inpad generic map (loc => tclk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (tclk, tclk_int); + tms_pad : component inpad + generic map ( + loc => tms_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tms, + tms_int + ); + + tclk_pad : component inpad + generic map ( + loc => tclk_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +tclk, + tclk_int + ); -- Ethernet - reset_o2_pad : outpad generic map (tech => CFG_FABTECH, loc => reset_o2_pad_loc, level => cmos, voltage => x18v) - port map (reset_o2, reset_o2_int, full_pad_cfg(io_tile_id)); - - etx_clk_pad : inpad generic map (tech => CFG_FABTECH, loc => etx_clk_pad_loc, level => cmos, voltage => x18v) - port map (etx_clk, etx_clk_int); - erx_clk_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_clk_pad_loc, level => cmos, voltage => x18v) - port map (erx_clk, erx_clk_int); - erxd_pad : inpadv generic map (tech => CFG_FABTECH, loc => erxd_pad_loc, level => cmos, voltage => x18v, width => 4) - port map (erxd, erxd_int); - erx_dv_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_dv_pad_loc, level => cmos, voltage => x18v) - port map (erx_dv, erx_dv_int); - erx_er_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_er_pad_loc, level => cmos, voltage => x18v) - port map (erx_er, erx_er_int); - erx_col_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_col_pad_loc, level => cmos, voltage => x18v) - port map (erx_col, erx_col_int); - erx_crs_pad : inpad generic map (tech => CFG_FABTECH, loc => erx_crs_pad_loc, level => cmos, voltage => x18v) - port map (erx_crs, erx_crs_int); - - emdio_pad : iopad generic map (tech => CFG_FABTECH, loc => emdio_pad_loc, level => cmos, voltage => x18v, oepol => 1) - port map (emdio, emdio_o, emdio_oe, emdio_i, full_pad_cfg(io_tile_id)); - - etxd_pad : outpadv generic map (tech => CFG_FABTECH, loc => etxd_pad_loc, level => cmos, voltage => x18v, width => 4) - port map (etxd, etxd_int, full_pad_cfg(io_tile_id)); - etx_en_pad : outpad generic map (tech => CFG_FABTECH, loc => etx_en_pad_loc, level => cmos, voltage => x18v) - port map (etx_en, etx_en_int, full_pad_cfg(io_tile_id)); - etx_er_pad : outpad generic map (tech => CFG_FABTECH, loc => etx_er_pad_loc, level => cmos, voltage => x18v) - port map (etx_er, etx_er_int, full_pad_cfg(io_tile_id)); - emdc_pad : outpad generic map (tech => CFG_FABTECH, loc => emdc_pad_loc, level => cmos, voltage => x18v) - port map (emdc, emdc_int, full_pad_cfg(io_tile_id)); - - fpga_data_pad : iopadv generic map (tech => CFG_FABTECH, loc => fpga_data_pad_loc, level => cmos, voltage => x18v, width => CFG_MEM_LINK_BITS, oepol => 1) - port map (fpga_data, fpga_data_out, fpga_oen(0), fpga_data_in, full_pad_cfg(mem_tile_id(0))); - fpga_valid_in_pad : inpad generic map (loc => fpga_valid_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (fpga_valid_in(0), fpga_valid_in_int(0)); - fpga_valid_out_pad : outpad generic map (loc => fpga_valid_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (fpga_valid_out(0), fpga_valid_out_int(0), full_pad_cfg(mem_tile_id(0))); - fpga_clk_in_pad : inpad generic map (loc => fpga_clk_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (fpga_clk_in(0), fpga_clk_in_int(0)); - fpga_clk_out_pad : outpad generic map (loc => fpga_clk_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (fpga_clk_out(0), fpga_clk_out_int(0), full_pad_cfg(mem_tile_id(0))); - fpga_credit_in_pad : inpad generic map (loc => fpga_credit_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (fpga_credit_in(0), fpga_credit_in_int(0)); - fpga_credit_out_pad : outpad generic map (loc => fpga_credit_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (fpga_credit_out(0), fpga_credit_out_int(0), full_pad_cfg(mem_tile_id(0))); - - --IO Link - iolink_data_pad : iopadv generic map (tech => CFG_FABTECH, loc => iolink_data_pad_loc, level => cmos, voltage => x18v, width => CFG_IOLINK_BITS, oepol => 1) - port map (iolink_data, iolink_data_out_int, iolink_data_oen, iolink_data_in_int, full_pad_cfg(io_tile_id)); - iolink_valid_in_pad : inpad generic map (loc => iolink_valid_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (iolink_valid_in, iolink_valid_in_int); - iolink_valid_out_pad : outpad generic map (loc => iolink_valid_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (iolink_valid_out, iolink_valid_out_int, full_pad_cfg(io_tile_id)); - iolink_clk_in_pad : inpad generic map (loc => iolink_clk_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (iolink_clk_in, iolink_clk_in_int); - iolink_clk_out_pad : outpad generic map (loc => iolink_clk_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (iolink_clk_out, iolink_clk_out_int, full_pad_cfg(io_tile_id)); - iolink_credit_in_pad : inpad generic map (loc => iolink_credit_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (iolink_credit_in, iolink_credit_in_int); - iolink_credit_out_pad : outpad generic map (loc => iolink_credit_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) - port map (iolink_credit_out, iolink_credit_out_int, full_pad_cfg(io_tile_id)); + reset_o2_pad : component outpad + generic map ( + tech => CFG_FABTECH, loc => reset_o2_pad_loc, level => cmos, voltage => x18v + ) + port map ( +reset_o2, + reset_o2_int, + full_pad_cfg(io_tile_id) + ); + + etx_clk_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => etx_clk_pad_loc, level => cmos, voltage => x18v + ) + port map ( +etx_clk, + etx_clk_int + ); + + erx_clk_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_clk_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_clk, + erx_clk_int + ); + + erxd_pad : component inpadv + generic map ( + tech => CFG_FABTECH, loc => erxd_pad_loc, level => cmos, voltage => x18v, width => 4 + ) + port map ( +erxd, + erxd_int + ); + + erx_dv_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_dv_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_dv, + erx_dv_int + ); + + erx_er_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_er_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_er, + erx_er_int + ); + + erx_col_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_col_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_col, + erx_col_int + ); + + erx_crs_pad : component inpad + generic map ( + tech => CFG_FABTECH, loc => erx_crs_pad_loc, level => cmos, voltage => x18v + ) + port map ( +erx_crs, + erx_crs_int + ); + + emdio_pad : component iopad + generic map ( + tech => CFG_FABTECH, loc => emdio_pad_loc, level => cmos, voltage => x18v, oepol => 1 + ) + port map ( +emdio, + emdio_o, + emdio_oe, + emdio_i, + full_pad_cfg(io_tile_id) + ); + + etxd_pad : component outpadv + generic map ( + tech => CFG_FABTECH, loc => etxd_pad_loc, level => cmos, voltage => x18v, width => 4 + ) + port map ( +etxd, + etxd_int, + full_pad_cfg(io_tile_id) + ); + + etx_en_pad : component outpad + generic map ( + tech => CFG_FABTECH, loc => etx_en_pad_loc, level => cmos, voltage => x18v + ) + port map ( +etx_en, + etx_en_int, + full_pad_cfg(io_tile_id) + ); + + etx_er_pad : component outpad + generic map ( + tech => CFG_FABTECH, loc => etx_er_pad_loc, level => cmos, voltage => x18v + ) + port map ( +etx_er, + etx_er_int, + full_pad_cfg(io_tile_id) + ); + + emdc_pad : component outpad + generic map ( + tech => CFG_FABTECH, loc => emdc_pad_loc, level => cmos, voltage => x18v + ) + port map ( +emdc, + emdc_int, + full_pad_cfg(io_tile_id) + ); + + fpga_data_pad : component iopadv + generic map ( + tech => CFG_FABTECH, loc => fpga_data_pad_loc, level => cmos, voltage => x18v, width => CFG_MEM_LINK_BITS, oepol => 1 + ) + port map ( +fpga_data, + fpga_data_out, + fpga_oen(0), + fpga_data_in, + full_pad_cfg(mem_tile_id(0)) + ); + + fpga_valid_in_pad : component inpad + generic map ( + loc => fpga_valid_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +fpga_valid_in(0), + fpga_valid_in_int(0) + ); + + fpga_valid_out_pad : component outpad + generic map ( + loc => fpga_valid_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +fpga_valid_out(0), + fpga_valid_out_int(0), + full_pad_cfg(mem_tile_id(0)) + ); + + fpga_clk_in_pad : component inpad + generic map ( + loc => fpga_clk_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +fpga_clk_in(0), + fpga_clk_in_int(0) + ); + + fpga_clk_out_pad : component outpad + generic map ( + loc => fpga_clk_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +fpga_clk_out(0), + fpga_clk_out_int(0), + full_pad_cfg(mem_tile_id(0)) + ); + + fpga_credit_in_pad : component inpad + generic map ( + loc => fpga_credit_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +fpga_credit_in(0), + fpga_credit_in_int(0) + ); + + fpga_credit_out_pad : component outpad + generic map ( + loc => fpga_credit_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +fpga_credit_out(0), + fpga_credit_out_int(0), + full_pad_cfg(mem_tile_id(0)) + ); + + -- IO Link + iolink_data_pad : component iopadv + generic map ( + tech => CFG_FABTECH, loc => iolink_data_pad_loc, level => cmos, voltage => x18v, width => CFG_IOLINK_BITS, oepol => 1 + ) + port map ( +iolink_data, + iolink_data_out_int, + iolink_data_oen, + iolink_data_in_int, + full_pad_cfg(io_tile_id) + ); + + iolink_valid_in_pad : component inpad + generic map ( + loc => iolink_valid_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +iolink_valid_in, + iolink_valid_in_int + ); + + iolink_valid_out_pad : component outpad + generic map ( + loc => iolink_valid_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +iolink_valid_out, + iolink_valid_out_int, + full_pad_cfg(io_tile_id) + ); + + iolink_clk_in_pad : component inpad + generic map ( + loc => iolink_clk_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +iolink_clk_in, + iolink_clk_in_int + ); + + iolink_clk_out_pad : component outpad + generic map ( + loc => iolink_clk_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +iolink_clk_out, + iolink_clk_out_int, + full_pad_cfg(io_tile_id) + ); + + iolink_credit_in_pad : component inpad + generic map ( + loc => iolink_credit_in_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +iolink_credit_in, + iolink_credit_in_int + ); + + iolink_credit_out_pad : component outpad + generic map ( + loc => iolink_credit_out_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +iolink_credit_out, + iolink_credit_out_int, + full_pad_cfg(io_tile_id) + ); -- UART - uart_rxd_pad : inpad generic map (loc => uart_rxd_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (uart_rxd, uart_rxd_int); - uart_txd_pad : outpad generic map (loc => uart_txd_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (uart_txd, uart_txd_int, full_pad_cfg(io_tile_id)); - uart_ctsn_pad : inpad generic map (loc => uart_ctsn_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (uart_ctsn, uart_ctsn_int); - uart_rtsn_pad : outpad generic map (loc => uart_rtsn_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH) port map (uart_rtsn, uart_rtsn_int, full_pad_cfg(io_tile_id)); + uart_rxd_pad : component inpad + generic map ( + loc => uart_rxd_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +uart_rxd, + uart_rxd_int + ); + + uart_txd_pad : component outpad + generic map ( + loc => uart_txd_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +uart_txd, + uart_txd_int, + full_pad_cfg(io_tile_id) + ); + + uart_ctsn_pad : component inpad + generic map ( + loc => uart_ctsn_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +uart_ctsn, + uart_ctsn_int + ); + uart_rtsn_pad : component outpad + generic map ( + loc => uart_rtsn_pad_loc, level => cmos, voltage => x18v, tech => CFG_FABTECH + ) + port map ( +uart_rtsn, + uart_rtsn_int, + full_pad_cfg(io_tile_id) + ); ----------------------------------------------------------------------------- -- NOC CONNECTIONS ----------------------------------------------------------------------------- - meshgen_y : for i in 0 to CFG_YLEN-1 generate - meshgen_x : for j in 0 to CFG_XLEN-1 generate + + meshgen_y : for i in 0 to CFG_YLEN - 1 generate + + meshgen_x : for j in 0 to CFG_XLEN - 1 generate y_0 : if (i = 0) generate -- North port is unconnected - noc1_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc2_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc3_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc4_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc5_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(0) <= '0'; - noc6_data_n_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(0) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(0) <= '0'; + noc1_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc2_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc3_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc4_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc5_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(0) <= '0'; + noc6_data_n_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(0) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(0) <= '0'; end generate y_0; y_non_0 : if (i /= 0) generate -- North port is connected - noc1_data_n_in(i*CFG_XLEN + j) <= noc1_data_s_out((i-1)*CFG_XLEN + j); - noc1_data_void_in(i*CFG_XLEN + j)(0) <= noc1_data_void_out((i-1)*CFG_XLEN + j)(1); - noc1_stop_in(i*CFG_XLEN + j)(0) <= noc1_stop_out((i-1)*CFG_XLEN + j)(1); - noc2_data_n_in(i*CFG_XLEN + j) <= noc2_data_s_out((i-1)*CFG_XLEN + j); - noc2_data_void_in(i*CFG_XLEN + j)(0) <= noc2_data_void_out((i-1)*CFG_XLEN + j)(1); - noc2_stop_in(i*CFG_XLEN + j)(0) <= noc2_stop_out((i-1)*CFG_XLEN + j)(1); - noc3_data_n_in(i*CFG_XLEN + j) <= noc3_data_s_out((i-1)*CFG_XLEN + j); - noc3_data_void_in(i*CFG_XLEN + j)(0) <= noc3_data_void_out((i-1)*CFG_XLEN + j)(1); - noc3_stop_in(i*CFG_XLEN + j)(0) <= noc3_stop_out((i-1)*CFG_XLEN + j)(1); - noc4_data_n_in(i*CFG_XLEN + j) <= noc4_data_s_out((i-1)*CFG_XLEN + j); - noc4_data_void_in(i*CFG_XLEN + j)(0) <= noc4_data_void_out((i-1)*CFG_XLEN + j)(1); - noc4_stop_in(i*CFG_XLEN + j)(0) <= noc4_stop_out((i-1)*CFG_XLEN + j)(1); - noc5_data_n_in(i*CFG_XLEN + j) <= noc5_data_s_out((i-1)*CFG_XLEN + j); - noc5_data_void_in(i*CFG_XLEN + j)(0) <= noc5_data_void_out((i-1)*CFG_XLEN + j)(1); - noc5_stop_in(i*CFG_XLEN + j)(0) <= noc5_stop_out((i-1)*CFG_XLEN + j)(1); - noc6_data_n_in(i*CFG_XLEN + j) <= noc6_data_s_out((i-1)*CFG_XLEN + j); - noc6_data_void_in(i*CFG_XLEN + j)(0) <= noc6_data_void_out((i-1)*CFG_XLEN + j)(1); - noc6_stop_in(i*CFG_XLEN + j)(0) <= noc6_stop_out((i-1)*CFG_XLEN + j)(1); + noc1_data_n_in(i * CFG_XLEN + j) <= noc1_data_s_out((i - 1) * CFG_XLEN + j); + noc1_data_void_in(i * CFG_XLEN + j)(0) <= noc1_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc1_stop_in(i * CFG_XLEN + j)(0) <= noc1_stop_out((i - 1) * CFG_XLEN + j)(1); + noc2_data_n_in(i * CFG_XLEN + j) <= noc2_data_s_out((i - 1) * CFG_XLEN + j); + noc2_data_void_in(i * CFG_XLEN + j)(0) <= noc2_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc2_stop_in(i * CFG_XLEN + j)(0) <= noc2_stop_out((i - 1) * CFG_XLEN + j)(1); + noc3_data_n_in(i * CFG_XLEN + j) <= noc3_data_s_out((i - 1) * CFG_XLEN + j); + noc3_data_void_in(i * CFG_XLEN + j)(0) <= noc3_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc3_stop_in(i * CFG_XLEN + j)(0) <= noc3_stop_out((i - 1) * CFG_XLEN + j)(1); + noc4_data_n_in(i * CFG_XLEN + j) <= noc4_data_s_out((i - 1) * CFG_XLEN + j); + noc4_data_void_in(i * CFG_XLEN + j)(0) <= noc4_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc4_stop_in(i * CFG_XLEN + j)(0) <= noc4_stop_out((i - 1) * CFG_XLEN + j)(1); + noc5_data_n_in(i * CFG_XLEN + j) <= noc5_data_s_out((i - 1) * CFG_XLEN + j); + noc5_data_void_in(i * CFG_XLEN + j)(0) <= noc5_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc5_stop_in(i * CFG_XLEN + j)(0) <= noc5_stop_out((i - 1) * CFG_XLEN + j)(1); + noc6_data_n_in(i * CFG_XLEN + j) <= noc6_data_s_out((i - 1) * CFG_XLEN + j); + noc6_data_void_in(i * CFG_XLEN + j)(0) <= noc6_data_void_out((i - 1) * CFG_XLEN + j)(1); + noc6_stop_in(i * CFG_XLEN + j)(0) <= noc6_stop_out((i - 1) * CFG_XLEN + j)(1); end generate y_non_0; - y_YLEN : if (i = CFG_YLEN-1) generate + y_ylen : if (i = CFG_YLEN - 1) generate -- South port is unconnected - noc1_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc2_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc3_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc4_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc5_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(1) <= '0'; - noc6_data_s_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(1) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(1) <= '0'; - end generate y_YLEN; - - y_non_YLEN : if (i /= CFG_YLEN-1) generate + noc1_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc2_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc3_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc4_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc5_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(1) <= '0'; + noc6_data_s_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(1) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(1) <= '0'; + end generate y_ylen; + + y_non_ylen : if (i /= CFG_YLEN - 1) generate -- south port is connected - noc1_data_s_in(i*CFG_XLEN + j) <= noc1_data_n_out((i+1)*CFG_XLEN + j); - noc1_data_void_in(i*CFG_XLEN + j)(1) <= noc1_data_void_out((i+1)*CFG_XLEN + j)(0); - noc1_stop_in(i*CFG_XLEN + j)(1) <= noc1_stop_out((i+1)*CFG_XLEN + j)(0); - noc2_data_s_in(i*CFG_XLEN + j) <= noc2_data_n_out((i+1)*CFG_XLEN + j); - noc2_data_void_in(i*CFG_XLEN + j)(1) <= noc2_data_void_out((i+1)*CFG_XLEN + j)(0); - noc2_stop_in(i*CFG_XLEN + j)(1) <= noc2_stop_out((i+1)*CFG_XLEN + j)(0); - noc3_data_s_in(i*CFG_XLEN + j) <= noc3_data_n_out((i+1)*CFG_XLEN + j); - noc3_data_void_in(i*CFG_XLEN + j)(1) <= noc3_data_void_out((i+1)*CFG_XLEN + j)(0); - noc3_stop_in(i*CFG_XLEN + j)(1) <= noc3_stop_out((i+1)*CFG_XLEN + j)(0); - noc4_data_s_in(i*CFG_XLEN + j) <= noc4_data_n_out((i+1)*CFG_XLEN + j); - noc4_data_void_in(i*CFG_XLEN + j)(1) <= noc4_data_void_out((i+1)*CFG_XLEN + j)(0); - noc4_stop_in(i*CFG_XLEN + j)(1) <= noc4_stop_out((i+1)*CFG_XLEN + j)(0); - noc5_data_s_in(i*CFG_XLEN + j) <= noc5_data_n_out((i+1)*CFG_XLEN + j); - noc5_data_void_in(i*CFG_XLEN + j)(1) <= noc5_data_void_out((i+1)*CFG_XLEN + j)(0); - noc5_stop_in(i*CFG_XLEN + j)(1) <= noc5_stop_out((i+1)*CFG_XLEN + j)(0); - noc6_data_s_in(i*CFG_XLEN + j) <= noc6_data_n_out((i+1)*CFG_XLEN + j); - noc6_data_void_in(i*CFG_XLEN + j)(1) <= noc6_data_void_out((i+1)*CFG_XLEN + j)(0); - noc6_stop_in(i*CFG_XLEN + j)(1) <= noc6_stop_out((i+1)*CFG_XLEN + j)(0); - end generate y_non_YLEN; + noc1_data_s_in(i * CFG_XLEN + j) <= noc1_data_n_out((i + 1) * CFG_XLEN + j); + noc1_data_void_in(i * CFG_XLEN + j)(1) <= noc1_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc1_stop_in(i * CFG_XLEN + j)(1) <= noc1_stop_out((i + 1) * CFG_XLEN + j)(0); + noc2_data_s_in(i * CFG_XLEN + j) <= noc2_data_n_out((i + 1) * CFG_XLEN + j); + noc2_data_void_in(i * CFG_XLEN + j)(1) <= noc2_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc2_stop_in(i * CFG_XLEN + j)(1) <= noc2_stop_out((i + 1) * CFG_XLEN + j)(0); + noc3_data_s_in(i * CFG_XLEN + j) <= noc3_data_n_out((i + 1) * CFG_XLEN + j); + noc3_data_void_in(i * CFG_XLEN + j)(1) <= noc3_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc3_stop_in(i * CFG_XLEN + j)(1) <= noc3_stop_out((i + 1) * CFG_XLEN + j)(0); + noc4_data_s_in(i * CFG_XLEN + j) <= noc4_data_n_out((i + 1) * CFG_XLEN + j); + noc4_data_void_in(i * CFG_XLEN + j)(1) <= noc4_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc4_stop_in(i * CFG_XLEN + j)(1) <= noc4_stop_out((i + 1) * CFG_XLEN + j)(0); + noc5_data_s_in(i * CFG_XLEN + j) <= noc5_data_n_out((i + 1) * CFG_XLEN + j); + noc5_data_void_in(i * CFG_XLEN + j)(1) <= noc5_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc5_stop_in(i * CFG_XLEN + j)(1) <= noc5_stop_out((i + 1) * CFG_XLEN + j)(0); + noc6_data_s_in(i * CFG_XLEN + j) <= noc6_data_n_out((i + 1) * CFG_XLEN + j); + noc6_data_void_in(i * CFG_XLEN + j)(1) <= noc6_data_void_out((i + 1) * CFG_XLEN + j)(0); + noc6_stop_in(i * CFG_XLEN + j)(1) <= noc6_stop_out((i + 1) * CFG_XLEN + j)(0); + end generate y_non_ylen; x_0 : if (j = 0) generate -- West port is unconnected - noc1_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc2_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc3_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc4_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc5_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(2) <= '0'; - noc6_data_w_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(2) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(2) <= '0'; + noc1_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc2_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc3_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc4_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc5_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(2) <= '0'; + noc6_data_w_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(2) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(2) <= '0'; end generate x_0; x_non_0 : if (j /= 0) generate -- West port is connected - noc1_data_w_in(i*CFG_XLEN + j) <= noc1_data_e_out(i*CFG_XLEN + j - 1); - noc1_data_void_in(i*CFG_XLEN + j)(2) <= noc1_data_void_out(i*CFG_XLEN + j - 1)(3); - noc1_stop_in(i*CFG_XLEN + j)(2) <= noc1_stop_out(i*CFG_XLEN + j - 1)(3); - noc2_data_w_in(i*CFG_XLEN + j) <= noc2_data_e_out(i*CFG_XLEN + j - 1); - noc2_data_void_in(i*CFG_XLEN + j)(2) <= noc2_data_void_out(i*CFG_XLEN + j - 1)(3); - noc2_stop_in(i*CFG_XLEN + j)(2) <= noc2_stop_out(i*CFG_XLEN + j - 1)(3); - noc3_data_w_in(i*CFG_XLEN + j) <= noc3_data_e_out(i*CFG_XLEN + j - 1); - noc3_data_void_in(i*CFG_XLEN + j)(2) <= noc3_data_void_out(i*CFG_XLEN + j - 1)(3); - noc3_stop_in(i*CFG_XLEN + j)(2) <= noc3_stop_out(i*CFG_XLEN + j - 1)(3); - noc4_data_w_in(i*CFG_XLEN + j) <= noc4_data_e_out(i*CFG_XLEN + j - 1); - noc4_data_void_in(i*CFG_XLEN + j)(2) <= noc4_data_void_out(i*CFG_XLEN + j - 1)(3); - noc4_stop_in(i*CFG_XLEN + j)(2) <= noc4_stop_out(i*CFG_XLEN + j - 1)(3); - noc5_data_w_in(i*CFG_XLEN + j) <= noc5_data_e_out(i*CFG_XLEN + j - 1); - noc5_data_void_in(i*CFG_XLEN + j)(2) <= noc5_data_void_out(i*CFG_XLEN + j - 1)(3); - noc5_stop_in(i*CFG_XLEN + j)(2) <= noc5_stop_out(i*CFG_XLEN + j - 1)(3); - noc6_data_w_in(i*CFG_XLEN + j) <= noc6_data_e_out(i*CFG_XLEN + j - 1); - noc6_data_void_in(i*CFG_XLEN + j)(2) <= noc6_data_void_out(i*CFG_XLEN + j - 1)(3); - noc6_stop_in(i*CFG_XLEN + j)(2) <= noc6_stop_out(i*CFG_XLEN + j - 1)(3); + noc1_data_w_in(i * CFG_XLEN + j) <= noc1_data_e_out(i * CFG_XLEN + j - 1); + noc1_data_void_in(i * CFG_XLEN + j)(2) <= noc1_data_void_out(i * CFG_XLEN + j - 1)(3); + noc1_stop_in(i * CFG_XLEN + j)(2) <= noc1_stop_out(i * CFG_XLEN + j - 1)(3); + noc2_data_w_in(i * CFG_XLEN + j) <= noc2_data_e_out(i * CFG_XLEN + j - 1); + noc2_data_void_in(i * CFG_XLEN + j)(2) <= noc2_data_void_out(i * CFG_XLEN + j - 1)(3); + noc2_stop_in(i * CFG_XLEN + j)(2) <= noc2_stop_out(i * CFG_XLEN + j - 1)(3); + noc3_data_w_in(i * CFG_XLEN + j) <= noc3_data_e_out(i * CFG_XLEN + j - 1); + noc3_data_void_in(i * CFG_XLEN + j)(2) <= noc3_data_void_out(i * CFG_XLEN + j - 1)(3); + noc3_stop_in(i * CFG_XLEN + j)(2) <= noc3_stop_out(i * CFG_XLEN + j - 1)(3); + noc4_data_w_in(i * CFG_XLEN + j) <= noc4_data_e_out(i * CFG_XLEN + j - 1); + noc4_data_void_in(i * CFG_XLEN + j)(2) <= noc4_data_void_out(i * CFG_XLEN + j - 1)(3); + noc4_stop_in(i * CFG_XLEN + j)(2) <= noc4_stop_out(i * CFG_XLEN + j - 1)(3); + noc5_data_w_in(i * CFG_XLEN + j) <= noc5_data_e_out(i * CFG_XLEN + j - 1); + noc5_data_void_in(i * CFG_XLEN + j)(2) <= noc5_data_void_out(i * CFG_XLEN + j - 1)(3); + noc5_stop_in(i * CFG_XLEN + j)(2) <= noc5_stop_out(i * CFG_XLEN + j - 1)(3); + noc6_data_w_in(i * CFG_XLEN + j) <= noc6_data_e_out(i * CFG_XLEN + j - 1); + noc6_data_void_in(i * CFG_XLEN + j)(2) <= noc6_data_void_out(i * CFG_XLEN + j - 1)(3); + noc6_stop_in(i * CFG_XLEN + j)(2) <= noc6_stop_out(i * CFG_XLEN + j - 1)(3); end generate x_non_0; - x_XLEN : if (j = CFG_XLEN-1) generate + x_xlen : if (j = CFG_XLEN - 1) generate -- East port is unconnected - noc1_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc1_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc1_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc2_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc2_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc2_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc3_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc3_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc3_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc4_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc4_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc4_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc5_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc5_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc5_stop_in(i*CFG_XLEN + j)(3) <= '0'; - noc6_data_e_in(i*CFG_XLEN + j) <= (others => '0'); - noc6_data_void_in(i*CFG_XLEN + j)(3) <= '1'; - noc6_stop_in(i*CFG_XLEN + j)(3) <= '0'; - end generate x_XLEN; - - x_non_XLEN : if (j /= CFG_XLEN-1) generate + noc1_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc1_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc1_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc2_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc2_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc2_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc3_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc3_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc3_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc4_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc4_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc4_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc5_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc5_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc5_stop_in(i * CFG_XLEN + j)(3) <= '0'; + noc6_data_e_in(i * CFG_XLEN + j) <= (others => '0'); + noc6_data_void_in(i * CFG_XLEN + j)(3) <= '1'; + noc6_stop_in(i * CFG_XLEN + j)(3) <= '0'; + end generate x_xlen; + + x_non_xlen : if (j /= CFG_XLEN - 1) generate -- East port is connected - noc1_data_e_in(i*CFG_XLEN + j) <= noc1_data_w_out(i*CFG_XLEN + j + 1); - noc1_data_void_in(i*CFG_XLEN + j)(3) <= noc1_data_void_out(i*CFG_XLEN + j + 1)(2); - noc1_stop_in(i*CFG_XLEN + j)(3) <= noc1_stop_out(i*CFG_XLEN + j + 1)(2); - noc2_data_e_in(i*CFG_XLEN + j) <= noc2_data_w_out(i*CFG_XLEN + j + 1); - noc2_data_void_in(i*CFG_XLEN + j)(3) <= noc2_data_void_out(i*CFG_XLEN + j + 1)(2); - noc2_stop_in(i*CFG_XLEN + j)(3) <= noc2_stop_out(i*CFG_XLEN + j + 1)(2); - noc3_data_e_in(i*CFG_XLEN + j) <= noc3_data_w_out(i*CFG_XLEN + j + 1); - noc3_data_void_in(i*CFG_XLEN + j)(3) <= noc3_data_void_out(i*CFG_XLEN + j + 1)(2); - noc3_stop_in(i*CFG_XLEN + j)(3) <= noc3_stop_out(i*CFG_XLEN + j + 1)(2); - noc4_data_e_in(i*CFG_XLEN + j) <= noc4_data_w_out(i*CFG_XLEN + j + 1); - noc4_data_void_in(i*CFG_XLEN + j)(3) <= noc4_data_void_out(i*CFG_XLEN + j + 1)(2); - noc4_stop_in(i*CFG_XLEN + j)(3) <= noc4_stop_out(i*CFG_XLEN + j + 1)(2); - noc5_data_e_in(i*CFG_XLEN + j) <= noc5_data_w_out(i*CFG_XLEN + j + 1); - noc5_data_void_in(i*CFG_XLEN + j)(3) <= noc5_data_void_out(i*CFG_XLEN + j + 1)(2); - noc5_stop_in(i*CFG_XLEN + j)(3) <= noc5_stop_out(i*CFG_XLEN + j + 1)(2); - noc6_data_e_in(i*CFG_XLEN + j) <= noc6_data_w_out(i*CFG_XLEN + j + 1); - noc6_data_void_in(i*CFG_XLEN + j)(3) <= noc6_data_void_out(i*CFG_XLEN + j + 1)(2); - noc6_stop_in(i*CFG_XLEN + j)(3) <= noc6_stop_out(i*CFG_XLEN + j + 1)(2); - end generate x_non_XLEN; + noc1_data_e_in(i * CFG_XLEN + j) <= noc1_data_w_out(i * CFG_XLEN + j + 1); + noc1_data_void_in(i * CFG_XLEN + j)(3) <= noc1_data_void_out(i * CFG_XLEN + j + 1)(2); + noc1_stop_in(i * CFG_XLEN + j)(3) <= noc1_stop_out(i * CFG_XLEN + j + 1)(2); + noc2_data_e_in(i * CFG_XLEN + j) <= noc2_data_w_out(i * CFG_XLEN + j + 1); + noc2_data_void_in(i * CFG_XLEN + j)(3) <= noc2_data_void_out(i * CFG_XLEN + j + 1)(2); + noc2_stop_in(i * CFG_XLEN + j)(3) <= noc2_stop_out(i * CFG_XLEN + j + 1)(2); + noc3_data_e_in(i * CFG_XLEN + j) <= noc3_data_w_out(i * CFG_XLEN + j + 1); + noc3_data_void_in(i * CFG_XLEN + j)(3) <= noc3_data_void_out(i * CFG_XLEN + j + 1)(2); + noc3_stop_in(i * CFG_XLEN + j)(3) <= noc3_stop_out(i * CFG_XLEN + j + 1)(2); + noc4_data_e_in(i * CFG_XLEN + j) <= noc4_data_w_out(i * CFG_XLEN + j + 1); + noc4_data_void_in(i * CFG_XLEN + j)(3) <= noc4_data_void_out(i * CFG_XLEN + j + 1)(2); + noc4_stop_in(i * CFG_XLEN + j)(3) <= noc4_stop_out(i * CFG_XLEN + j + 1)(2); + noc5_data_e_in(i * CFG_XLEN + j) <= noc5_data_w_out(i * CFG_XLEN + j + 1); + noc5_data_void_in(i * CFG_XLEN + j)(3) <= noc5_data_void_out(i * CFG_XLEN + j + 1)(2); + noc5_stop_in(i * CFG_XLEN + j)(3) <= noc5_stop_out(i * CFG_XLEN + j + 1)(2); + noc6_data_e_in(i * CFG_XLEN + j) <= noc6_data_w_out(i * CFG_XLEN + j + 1); + noc6_data_void_in(i * CFG_XLEN + j)(3) <= noc6_data_void_out(i * CFG_XLEN + j + 1)(2); + noc6_stop_in(i * CFG_XLEN + j)(3) <= noc6_stop_out(i * CFG_XLEN + j + 1)(2); + end generate x_non_xlen; end generate meshgen_x; - end generate meshgen_y; + end generate meshgen_y; ----------------------------------------------------------------------------- -- TILES ----------------------------------------------------------------------------- + tiles_gen : for i in 0 to CFG_TILES_NUM - 1 generate empty_tile : if tile_type(i) = 0 generate - tile_empty_i : asic_tile_empty + + tile_empty_i : component asic_tile_empty generic map ( - SIMULATION => SIMULATION, - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + simulation => SIMULATION, + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), this_has_dco => 0, - HAS_SYNC => 0) + has_sync => 0 + ) port map ( rst => reset, sys_clk => sys_clk, @@ -617,20 +966,24 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); - end generate empty_tile; + noc6_stop_out => noc6_stop_out(i) + ); + end generate empty_tile; cpu_tile : if tile_type(i) = 1 generate --- pragma translate_off - assert tile_cpu_id(i) /= -1 report "Undefined CPU ID for CPU tile" severity error; --- pragma translate_on - tile_cpu_i : asic_tile_cpu + -- pragma translate_off + assert tile_cpu_id(i) /= -1 + report "Undefined CPU ID for CPU tile" + severity error; + -- pragma translate_on + tile_cpu_i : component asic_tile_cpu generic map ( - SIMULATION => SIMULATION, - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + simulation => SIMULATION, + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), this_has_dco => 0, - HAS_SYNC => 0) + has_sync => 0 + ) port map ( rst => reset, sys_clk => sys_clk, @@ -713,23 +1066,27 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); - end generate cpu_tile; + noc6_stop_out => noc6_stop_out(i) + ); + end generate cpu_tile; accelerator_tile : if tile_type(i) = 2 generate --- pragma translate_off - assert tile_device(i) /= 0 report "Undefined device ID for accelerator tile" severity error; --- pragma translate_on - tile_acc_i : asic_tile_acc + -- pragma translate_off + assert tile_device(i) /= 0 + report "Undefined device ID for accelerator tile" + severity error; + -- pragma translate_on + tile_acc_i : component asic_tile_acc generic map ( this_hls_conf => tile_design_point(i), this_device => tile_device(i), this_irq_type => tile_irq_type(i), this_has_l2 => tile_has_l2(i), - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), - this_has_dco => 0, - HAS_SYNC => 0) + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + this_has_dco => 0, + has_sync => 0 + ) port map ( rst => reset, sys_clk => sys_clk, @@ -813,26 +1170,28 @@ begin noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), noc6_stop_out => noc6_stop_out(i) - ); - end generate accelerator_tile; + ); + end generate accelerator_tile; io_tile : if tile_type(i) = 3 generate - tile_io_i : asic_tile_io + + tile_io_i : component asic_tile_io generic map ( - SIMULATION => SIMULATION, - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + simulation => SIMULATION, + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), this_has_dco => 0, - HAS_SYNC => 0) + has_sync => 0 + ) port map ( - rst => reset, -- from I/O PAD reset - sys_rstn_out => sys_rstn, -- NoC reset out (unused; connect other tiles directly to reset PAD) - sys_clk_out => sys_clk, -- NoC clock out - sys_clk => sys_clk, -- NoC clock in + rst => reset, + sys_rstn_out => sys_rstn, + sys_clk_out => sys_clk, + sys_clk => sys_clk, sys_clk_lock_out => sys_clk_lock, - ext_clk_noc => ext_clk_int, -- backup NoC clock + ext_clk_noc => ext_clk_int, clk_div_noc => clk_div_noc_int, - ext_clk => sys_clk, -- backup clock (fixed) + ext_clk => sys_clk, clk_div => clk_div_int(i), reset_o2 => reset_o2_int, etx_clk => etx_clk_int, @@ -938,16 +1297,19 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); - end generate io_tile; + noc6_stop_out => noc6_stop_out(i) + ); + end generate io_tile; mem_tile : if tile_type(i) = 4 generate - tile_mem_i : asic_tile_mem + + tile_mem_i : component asic_tile_mem generic map ( - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), this_has_dco => 0, - HAS_SYNC => 0) + has_sync => 0 + ) port map ( rst => reset, sys_clk => sys_clk, @@ -1039,15 +1401,19 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); + noc6_stop_out => noc6_stop_out(i) + ); + end generate mem_tile; slm_tile : if tile_type(i) = 5 generate - tile_slm_i : asic_tile_slm + + tile_slm_i : component asic_tile_slm generic map ( - ROUTER_PORTS => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), + router_ports => set_router_ports(CFG_FABTECH, CFG_XLEN, CFG_YLEN, tile_x(i), tile_y(i)), this_has_dco => 0, - HAS_SYNC => 0) + has_sync => 0 + ) port map ( rst => reset, sys_clk => sys_clk, @@ -1130,9 +1496,11 @@ begin noc6_data_w_out => noc6_data_w_out(i), noc6_data_e_out => noc6_data_e_out(i), noc6_data_void_out => noc6_data_void_out(i), - noc6_stop_out => noc6_stop_out(i)); + noc6_stop_out => noc6_stop_out(i) + ); + end generate slm_tile; end generate tiles_gen; -end; +end architecture rtl; diff --git a/socs/esp_asic_generic/systest.c b/socs/esp_asic_generic/systest.c index 08f2d177f4..df58d1dee6 100644 --- a/socs/esp_asic_generic/systest.c +++ b/socs/esp_asic_generic/systest.c @@ -3,7 +3,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/profpga-xc7v2000t/systest.c b/socs/profpga-xc7v2000t/systest.c index 1819d28446..6d6e7c094c 100644 --- a/socs/profpga-xc7v2000t/systest.c +++ b/socs/profpga-xc7v2000t/systest.c @@ -5,7 +5,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/profpga-xc7v2000t/testbench.vhd b/socs/profpga-xc7v2000t/testbench.vhd index 686dcbd313..e572d1bbff 100644 --- a/socs/profpga-xc7v2000t/testbench.vhd +++ b/socs/profpga-xc7v2000t/testbench.vhd @@ -4,25 +4,22 @@ -- Testbench for ESP on proFPGA xc7v2000t with dual DDR3, Ethernet and DVI ------------------------------------------------------------------------------ - library ieee; -use ieee.std_logic_1164.all; -use work.libdcom.all; -use work.sim.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gencomp.all; - -use work.grlib_config.all; + use ieee.std_logic_1164.all; + use work.libdcom.all; + use work.sim.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gencomp.all; + use work.grlib_config.all; entity testbench is -end; +end entity testbench; architecture behav of testbench is - constant SIMULATION : boolean := true; - + constant SIMULATION : boolean := true; -- Ethernet signals signal reset_o2 : std_ulogic; @@ -66,8 +63,7 @@ architecture behav of testbench is signal clk_ref_p : std_ulogic := '0'; signal clk_ref_n : std_ulogic := '1'; - --- DDR3 memory + -- DDR3 memory signal c0_ddr3_dq : std_logic_vector(63 downto 0); signal c0_ddr3_dqs_p : std_logic_vector(7 downto 0); signal c0_ddr3_dqs_n : std_logic_vector(7 downto 0); @@ -83,7 +79,7 @@ architecture behav of testbench is signal c0_ddr3_cs_n : std_logic_vector(0 downto 0); signal c0_ddr3_dm : std_logic_vector(7 downto 0); signal c0_ddr3_odt : std_logic_vector(0 downto 0); --- DDR3 memory + -- DDR3 memory signal c1_ddr3_dq : std_logic_vector(63 downto 0); signal c1_ddr3_dqs_p : std_logic_vector(7 downto 0); signal c1_ddr3_dqs_n : std_logic_vector(7 downto 0); @@ -100,41 +96,40 @@ architecture behav of testbench is signal c1_ddr3_dm : std_logic_vector(7 downto 0); signal c1_ddr3_odt : std_logic_vector(0 downto 0); - -- UART signal uart_rxd : std_ulogic; signal uart_txd : std_ulogic; signal uart_ctsn : std_ulogic; signal uart_rtsn : std_ulogic; - --- MMI64 - signal profpga_clk0_p : std_ulogic := '0'; -- 100 MHz clock - signal profpga_clk0_n : std_ulogic := '1'; -- 100 MHz clock + -- MMI64 + signal profpga_clk0_p : std_ulogic := '0'; -- 100 MHz clock + signal profpga_clk0_n : std_ulogic := '1'; -- 100 MHz clock signal profpga_sync0_p : std_ulogic; signal profpga_sync0_n : std_ulogic; signal dmbi_h2f : std_logic_vector(19 downto 0); signal dmbi_f2h : std_logic_vector(19 downto 0); - component top + component top is generic ( - SIMULATION : boolean); + simulation : boolean + ); port ( -- MMI64 interface: - profpga_clk0_p : in std_ulogic; -- 100 MHz clock - profpga_clk0_n : in std_ulogic; -- 100 MHz clock - profpga_sync0_p : in std_ulogic; - profpga_sync0_n : in std_ulogic; - dmbi_h2f : in std_logic_vector(19 downto 0); - dmbi_f2h : out std_logic_vector(19 downto 0); + profpga_clk0_p : in std_ulogic; + profpga_clk0_n : in std_ulogic; + profpga_sync0_p : in std_ulogic; + profpga_sync0_n : in std_ulogic; + dmbi_h2f : in std_logic_vector(19 downto 0); + dmbi_f2h : out std_logic_vector(19 downto 0); -- reset : in std_ulogic; - c0_main_clk_p : in std_ulogic; -- 160 MHz clock - c0_main_clk_n : in std_ulogic; -- 160 MHz clock - c1_main_clk_p : in std_ulogic; -- 160 MHz clock - c1_main_clk_n : in std_ulogic; -- 160 MHz clock - clk_ref_p : in std_ulogic; -- 200 MHz clock - clk_ref_n : in std_ulogic; -- 200 MHz clock + c0_main_clk_p : in std_ulogic; + c0_main_clk_n : in std_ulogic; + c1_main_clk_p : in std_ulogic; + c1_main_clk_n : in std_ulogic; + clk_ref_p : in std_ulogic; + clk_ref_n : in std_ulogic; c0_ddr3_dq : inout std_logic_vector(63 downto 0); c0_ddr3_dqs_p : inout std_logic_vector(7 downto 0); c0_ddr3_dqs_n : inout std_logic_vector(7 downto 0); @@ -172,49 +167,49 @@ architecture behav of testbench is uart_ctsn : in std_ulogic; uart_rtsn : out std_ulogic; -- Ethernet signals - reset_o2 : out std_ulogic; - etx_clk : in std_ulogic; - erx_clk : in std_ulogic; - erxd : in std_logic_vector(3 downto 0); - erx_dv : in std_ulogic; - erx_er : in std_ulogic; - erx_col : in std_ulogic; - erx_crs : in std_ulogic; - etxd : out std_logic_vector(3 downto 0); - etx_en : out std_ulogic; - etx_er : out std_ulogic; - emdc : out std_ulogic; - emdio : inout std_logic; + reset_o2 : out std_ulogic; + etx_clk : in std_ulogic; + erx_clk : in std_ulogic; + erxd : in std_logic_vector(3 downto 0); + erx_dv : in std_ulogic; + erx_er : in std_ulogic; + erx_col : in std_ulogic; + erx_crs : in std_ulogic; + etxd : out std_logic_vector(3 downto 0); + etx_en : out std_ulogic; + etx_er : out std_ulogic; + emdc : out std_ulogic; + emdio : inout std_logic; -- DVI - tft_nhpd : in std_ulogic; -- Hot plug - tft_clk_p : out std_ulogic; - tft_clk_n : out std_ulogic; - tft_data : out std_logic_vector(23 downto 0); - tft_hsync : out std_ulogic; - tft_vsync : out std_ulogic; - tft_de : out std_ulogic; - tft_dken : out std_ulogic; - tft_ctl1_a1_dk1 : out std_ulogic; - tft_ctl2_a2_dk2 : out std_ulogic; - tft_a3_dk3 : out std_ulogic; - tft_isel : out std_ulogic; - tft_bsel : out std_logic; - tft_dsel : out std_logic; - tft_edge : out std_ulogic; - tft_npd : out std_ulogic; - - LED_RED : out std_ulogic; - LED_GREEN : out std_ulogic; - LED_BLUE : out std_ulogic; - LED_YELLOW : out std_ulogic; - c0_diagnostic_led : out std_ulogic; - c1_diagnostic_led : out std_ulogic); + tft_nhpd : in std_ulogic; + tft_clk_p : out std_ulogic; + tft_clk_n : out std_ulogic; + tft_data : out std_logic_vector(23 downto 0); + tft_hsync : out std_ulogic; + tft_vsync : out std_ulogic; + tft_de : out std_ulogic; + tft_dken : out std_ulogic; + tft_ctl1_a1_dk1 : out std_ulogic; + tft_ctl2_a2_dk2 : out std_ulogic; + tft_a3_dk3 : out std_ulogic; + tft_isel : out std_ulogic; + tft_bsel : out std_logic; + tft_dsel : out std_logic; + tft_edge : out std_ulogic; + tft_npd : out std_ulogic; + led_red : out std_ulogic; + led_green : out std_ulogic; + led_blue : out std_ulogic; + led_yellow : out std_ulogic; + c0_diagnostic_led : out std_ulogic; + c1_diagnostic_led : out std_ulogic + ); end component; begin - --MMI 64 + -- MMI 64 profpga_clk0_p <= not profpga_clk0_p after 5 ns; profpga_clk0_n <= not profpga_clk0_n after 5 ns; profpga_sync0_p <= '0'; @@ -242,11 +237,10 @@ begin c1_ddr3_dqs_p <= (others => 'Z'); c1_ddr3_dqs_n <= (others => 'Z'); - - top_1 : top + top_1 : component top generic map ( - SIMULATION => SIMULATION - ) + simulation => SIMULATION + ) port map ( -- MMI64 profpga_clk0_p => profpga_clk0_p, @@ -328,13 +322,13 @@ begin tft_edge => tft_edge, tft_npd => tft_npd, - LED_RED => open, - LED_GREEN => open, - LED_BLUE => open, - LED_YELLOW => open, + led_red => open, + led_green => open, + led_blue => open, + led_yellow => open, c0_diagnostic_led => open, c1_diagnostic_led => open - ); + ); -end; +end architecture behav; diff --git a/socs/profpga-xcvu19p/systest.c b/socs/profpga-xcvu19p/systest.c index 1819d28446..6d6e7c094c 100644 --- a/socs/profpga-xcvu19p/systest.c +++ b/socs/profpga-xcvu19p/systest.c @@ -5,7 +5,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/profpga-xcvu19p/testbench.vhd b/socs/profpga-xcvu19p/testbench.vhd index c988fcf516..1648432a14 100644 --- a/socs/profpga-xcvu19p/testbench.vhd +++ b/socs/profpga-xcvu19p/testbench.vhd @@ -5,20 +5,18 @@ -- Testbench for ESP on proFPGA xcvu440 with DDR4, Ethernet and DVI ------------------------------------------------------------------------------ - library ieee; -use ieee.std_logic_1164.all; -use work.libdcom.all; -use work.sim.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gencomp.all; - -use work.grlib_config.all; + use ieee.std_logic_1164.all; + use work.libdcom.all; + use work.sim.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gencomp.all; + use work.grlib_config.all; entity testbench is -end; +end entity testbench; architecture behav of testbench is @@ -40,22 +38,22 @@ architecture behav of testbench is signal emdio : std_logic; -- DVI --- signal tft_nhpd : std_ulogic; --- signal tft_clk_p : std_ulogic; --- signal tft_clk_n : std_ulogic; --- signal tft_data : std_logic_vector(23 downto 0); --- signal tft_hsync : std_ulogic; --- signal tft_vsync : std_ulogic; --- signal tft_de : std_ulogic; --- signal tft_dken : std_ulogic; --- signal tft_ctl1_a1_dk1 : std_ulogic; --- signal tft_ctl2_a2_dk2 : std_ulogic; --- signal tft_a3_dk3 : std_ulogic; --- signal tft_isel : std_ulogic; --- signal tft_bsel : std_logic; --- signal tft_dsel : std_logic; --- signal tft_edge : std_ulogic; --- signal tft_npd : std_ulogic; + -- signal tft_nhpd : std_ulogic; + -- signal tft_clk_p : std_ulogic; + -- signal tft_clk_n : std_ulogic; + -- signal tft_data : std_logic_vector(23 downto 0); + -- signal tft_hsync : std_ulogic; + -- signal tft_vsync : std_ulogic; + -- signal tft_de : std_ulogic; + -- signal tft_dken : std_ulogic; + -- signal tft_ctl1_a1_dk1 : std_ulogic; + -- signal tft_ctl2_a2_dk2 : std_ulogic; + -- signal tft_a3_dk3 : std_ulogic; + -- signal tft_isel : std_ulogic; + -- signal tft_bsel : std_logic; + -- signal tft_dsel : std_logic; + -- signal tft_edge : std_ulogic; + -- signal tft_npd : std_ulogic; -- Clock and reset signal reset : std_ulogic := '1'; @@ -70,75 +68,74 @@ architecture behav of testbench is signal esp_clk_p : std_ulogic := '0'; signal esp_clk_n : std_ulogic := '1'; - -- DDR4 memory - signal c0_ddr4_act_n : std_logic; - signal c0_ddr4_adr : std_logic_vector(16 downto 0); - signal c0_ddr4_ba : std_logic_vector(1 downto 0); - signal c0_ddr4_bg : std_logic_vector(1 downto 0); - signal c0_ddr4_cke : std_logic_vector(1 downto 0); - signal c0_ddr4_odt : std_logic_vector(1 downto 0); - signal c0_ddr4_cs_n : std_logic_vector(1 downto 0); - signal c0_ddr4_ck_t : std_logic_vector(0 downto 0); - signal c0_ddr4_ck_c : std_logic_vector(0 downto 0); - signal c0_ddr4_reset_n : std_logic; - signal c0_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); - signal c0_ddr4_dq : std_logic_vector(71 downto 0); - signal c0_ddr4_dqs_c : std_logic_vector(8 downto 0); - signal c0_ddr4_dqs_t : std_logic_vector(8 downto 0); + signal c0_ddr4_act_n : std_logic; + signal c0_ddr4_adr : std_logic_vector(16 downto 0); + signal c0_ddr4_ba : std_logic_vector(1 downto 0); + signal c0_ddr4_bg : std_logic_vector(1 downto 0); + signal c0_ddr4_cke : std_logic_vector(1 downto 0); + signal c0_ddr4_odt : std_logic_vector(1 downto 0); + signal c0_ddr4_cs_n : std_logic_vector(1 downto 0); + signal c0_ddr4_ck_t : std_logic_vector(0 downto 0); + signal c0_ddr4_ck_c : std_logic_vector(0 downto 0); + signal c0_ddr4_reset_n : std_logic; + signal c0_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); + signal c0_ddr4_dq : std_logic_vector(71 downto 0); + signal c0_ddr4_dqs_c : std_logic_vector(8 downto 0); + signal c0_ddr4_dqs_t : std_logic_vector(8 downto 0); signal c0_calib_complete : std_logic; - signal c0_diagnostic_led : std_ulogic; - - signal c1_ddr4_act_n : std_logic; - signal c1_ddr4_adr : std_logic_vector(16 downto 0); - signal c1_ddr4_ba : std_logic_vector(1 downto 0); - signal c1_ddr4_bg : std_logic_vector(1 downto 0); - signal c1_ddr4_cke : std_logic_vector(1 downto 0); - signal c1_ddr4_odt : std_logic_vector(1 downto 0); - signal c1_ddr4_cs_n : std_logic_vector(1 downto 0); - signal c1_ddr4_ck_t : std_logic_vector(0 downto 0); - signal c1_ddr4_ck_c : std_logic_vector(0 downto 0); - signal c1_ddr4_reset_n : std_logic; - signal c1_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); - signal c1_ddr4_dq : std_logic_vector(71 downto 0); - signal c1_ddr4_dqs_c : std_logic_vector(8 downto 0); - signal c1_ddr4_dqs_t : std_logic_vector(8 downto 0); + signal c0_diagnostic_led : std_ulogic; + + signal c1_ddr4_act_n : std_logic; + signal c1_ddr4_adr : std_logic_vector(16 downto 0); + signal c1_ddr4_ba : std_logic_vector(1 downto 0); + signal c1_ddr4_bg : std_logic_vector(1 downto 0); + signal c1_ddr4_cke : std_logic_vector(1 downto 0); + signal c1_ddr4_odt : std_logic_vector(1 downto 0); + signal c1_ddr4_cs_n : std_logic_vector(1 downto 0); + signal c1_ddr4_ck_t : std_logic_vector(0 downto 0); + signal c1_ddr4_ck_c : std_logic_vector(0 downto 0); + signal c1_ddr4_reset_n : std_logic; + signal c1_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); + signal c1_ddr4_dq : std_logic_vector(71 downto 0); + signal c1_ddr4_dqs_c : std_logic_vector(8 downto 0); + signal c1_ddr4_dqs_t : std_logic_vector(8 downto 0); signal c1_calib_complete : std_logic; - signal c1_diagnostic_led : std_ulogic; - - signal c2_ddr4_act_n : std_logic; - signal c2_ddr4_adr : std_logic_vector(16 downto 0); - signal c2_ddr4_ba : std_logic_vector(1 downto 0); - signal c2_ddr4_bg : std_logic_vector(1 downto 0); - signal c2_ddr4_cke : std_logic_vector(1 downto 0); - signal c2_ddr4_odt : std_logic_vector(1 downto 0); - signal c2_ddr4_cs_n : std_logic_vector(1 downto 0); - signal c2_ddr4_ck_t : std_logic_vector(0 downto 0); - signal c2_ddr4_ck_c : std_logic_vector(0 downto 0); - signal c2_ddr4_reset_n : std_logic; - signal c2_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); - signal c2_ddr4_dq : std_logic_vector(71 downto 0); - signal c2_ddr4_dqs_c : std_logic_vector(8 downto 0); - signal c2_ddr4_dqs_t : std_logic_vector(8 downto 0); + signal c1_diagnostic_led : std_ulogic; + + signal c2_ddr4_act_n : std_logic; + signal c2_ddr4_adr : std_logic_vector(16 downto 0); + signal c2_ddr4_ba : std_logic_vector(1 downto 0); + signal c2_ddr4_bg : std_logic_vector(1 downto 0); + signal c2_ddr4_cke : std_logic_vector(1 downto 0); + signal c2_ddr4_odt : std_logic_vector(1 downto 0); + signal c2_ddr4_cs_n : std_logic_vector(1 downto 0); + signal c2_ddr4_ck_t : std_logic_vector(0 downto 0); + signal c2_ddr4_ck_c : std_logic_vector(0 downto 0); + signal c2_ddr4_reset_n : std_logic; + signal c2_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); + signal c2_ddr4_dq : std_logic_vector(71 downto 0); + signal c2_ddr4_dqs_c : std_logic_vector(8 downto 0); + signal c2_ddr4_dqs_t : std_logic_vector(8 downto 0); signal c2_calib_complete : std_logic; - signal c2_diagnostic_led : std_ulogic; - - signal c3_ddr4_act_n : std_logic; - signal c3_ddr4_adr : std_logic_vector(16 downto 0); - signal c3_ddr4_ba : std_logic_vector(1 downto 0); - signal c3_ddr4_bg : std_logic_vector(1 downto 0); - signal c3_ddr4_cke : std_logic_vector(1 downto 0); - signal c3_ddr4_odt : std_logic_vector(1 downto 0); - signal c3_ddr4_cs_n : std_logic_vector(1 downto 0); - signal c3_ddr4_ck_t : std_logic_vector(0 downto 0); - signal c3_ddr4_ck_c : std_logic_vector(0 downto 0); - signal c3_ddr4_reset_n : std_logic; - signal c3_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); - signal c3_ddr4_dq : std_logic_vector(71 downto 0); - signal c3_ddr4_dqs_c : std_logic_vector(8 downto 0); - signal c3_ddr4_dqs_t : std_logic_vector(8 downto 0); + signal c2_diagnostic_led : std_ulogic; + + signal c3_ddr4_act_n : std_logic; + signal c3_ddr4_adr : std_logic_vector(16 downto 0); + signal c3_ddr4_ba : std_logic_vector(1 downto 0); + signal c3_ddr4_bg : std_logic_vector(1 downto 0); + signal c3_ddr4_cke : std_logic_vector(1 downto 0); + signal c3_ddr4_odt : std_logic_vector(1 downto 0); + signal c3_ddr4_cs_n : std_logic_vector(1 downto 0); + signal c3_ddr4_ck_t : std_logic_vector(0 downto 0); + signal c3_ddr4_ck_c : std_logic_vector(0 downto 0); + signal c3_ddr4_reset_n : std_logic; + signal c3_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); + signal c3_ddr4_dq : std_logic_vector(71 downto 0); + signal c3_ddr4_dqs_c : std_logic_vector(8 downto 0); + signal c3_ddr4_dqs_t : std_logic_vector(8 downto 0); signal c3_calib_complete : std_logic; - signal c3_diagnostic_led : std_ulogic; + signal c3_diagnostic_led : std_ulogic; -- UART signal uart_rxd : std_ulogic; @@ -146,30 +143,30 @@ architecture behav of testbench is signal uart_ctsn : std_ulogic; signal uart_rtsn : std_ulogic; - -- MMI64 - signal profpga_clk0_p : std_ulogic := '0'; -- 100 MHz clock - signal profpga_clk0_n : std_ulogic := '1'; -- 100 MHz clock + signal profpga_clk0_p : std_ulogic := '0'; -- 100 MHz clock + signal profpga_clk0_n : std_ulogic := '1'; -- 100 MHz clock signal profpga_sync0_p : std_ulogic; signal profpga_sync0_n : std_ulogic; signal dmbi_h2f : std_logic_vector(19 downto 0); signal dmbi_f2h : std_logic_vector(19 downto 0); - component top + component top is generic ( - SIMULATION : boolean); + simulation : boolean + ); port ( -- MMI64 interface: - profpga_clk0_p : in std_ulogic; -- 100 MHz clock - profpga_clk0_n : in std_ulogic; -- 100 MHz clock - profpga_sync0_p : in std_ulogic; - profpga_sync0_n : in std_ulogic; - dmbi_h2f : in std_logic_vector(19 downto 0); - dmbi_f2h : out std_logic_vector(19 downto 0); + profpga_clk0_p : in std_ulogic; + profpga_clk0_n : in std_ulogic; + profpga_sync0_p : in std_ulogic; + profpga_sync0_n : in std_ulogic; + dmbi_h2f : in std_logic_vector(19 downto 0); + dmbi_f2h : out std_logic_vector(19 downto 0); -- Main ESP clock - esp_clk_p : in std_ulogic; -- 78.125 MHz clock - esp_clk_n : in std_ulogic; -- 78.125 MHz clock - reset : in std_ulogic; + esp_clk_p : in std_ulogic; + esp_clk_n : in std_ulogic; + reset : in std_ulogic; -- DDR4 c0_sys_clk_p : in std_logic; c0_sys_clk_n : in std_logic; @@ -243,53 +240,53 @@ architecture behav of testbench is c3_ddr4_dqs_t : inout std_logic_vector(8 downto 0); c3_calib_complete : out std_logic; c3_diagnostic_led : out std_ulogic; --- UART - uart_rxd : in std_ulogic; - uart_txd : out std_ulogic; - uart_ctsn : in std_ulogic; - uart_rtsn : out std_ulogic; + -- UART + uart_rxd : in std_ulogic; + uart_txd : out std_ulogic; + uart_ctsn : in std_ulogic; + uart_rtsn : out std_ulogic; -- Ethernet signals - reset_o2 : out std_ulogic; - etx_clk : in std_ulogic; - erx_clk : in std_ulogic; - erxd : in std_logic_vector(3 downto 0); - erx_dv : in std_ulogic; - erx_er : in std_ulogic; - erx_col : in std_ulogic; - erx_crs : in std_ulogic; - etxd : out std_logic_vector(3 downto 0); - etx_en : out std_ulogic; - etx_er : out std_ulogic; - emdc : out std_ulogic; - emdio : inout std_logic; + reset_o2 : out std_ulogic; + etx_clk : in std_ulogic; + erx_clk : in std_ulogic; + erxd : in std_logic_vector(3 downto 0); + erx_dv : in std_ulogic; + erx_er : in std_ulogic; + erx_col : in std_ulogic; + erx_crs : in std_ulogic; + etxd : out std_logic_vector(3 downto 0); + etx_en : out std_ulogic; + etx_er : out std_ulogic; + emdc : out std_ulogic; + emdio : inout std_logic; -- DVI --- tft_nhpd : in std_ulogic; -- Hot plug --- tft_clk_p : out std_ulogic; --- tft_clk_n : out std_ulogic; --- tft_data : out std_logic_vector(23 downto 0); --- tft_hsync : out std_ulogic; --- tft_vsync : out std_ulogic; --- tft_de : out std_ulogic; --- tft_dken : out std_ulogic; --- tft_ctl1_a1_dk1 : out std_ulogic; --- tft_ctl2_a2_dk2 : out std_ulogic; --- tft_a3_dk3 : out std_ulogic; --- tft_isel : out std_ulogic; --- tft_bsel : out std_logic; --- tft_dsel : out std_logic; --- tft_edge : out std_ulogic; --- tft_npd : out std_ulogic; + -- tft_nhpd : in std_ulogic; -- Hot plug + -- tft_clk_p : out std_ulogic; + -- tft_clk_n : out std_ulogic; + -- tft_data : out std_logic_vector(23 downto 0); + -- tft_hsync : out std_ulogic; + -- tft_vsync : out std_ulogic; + -- tft_de : out std_ulogic; + -- tft_dken : out std_ulogic; + -- tft_ctl1_a1_dk1 : out std_ulogic; + -- tft_ctl2_a2_dk2 : out std_ulogic; + -- tft_a3_dk3 : out std_ulogic; + -- tft_isel : out std_ulogic; + -- tft_bsel : out std_logic; + -- tft_dsel : out std_logic; + -- tft_edge : out std_ulogic; + -- tft_npd : out std_ulogic; -- LEDs - LED_RED : out std_ulogic; - LED_GREEN : out std_ulogic; - LED_BLUE : out std_ulogic; - LED_YELLOW : out std_ulogic); - + led_red : out std_ulogic; + led_green : out std_ulogic; + led_blue : out std_ulogic; + led_yellow : out std_ulogic + ); end component; begin - --MMI64 + -- MMI64 profpga_clk0_p <= not profpga_clk0_p after 5 ns; profpga_clk0_n <= not profpga_clk0_n after 5 ns; profpga_sync0_p <= '0'; @@ -331,10 +328,10 @@ begin c3_ddr4_dqs_c <= (others => 'Z'); c3_ddr4_dqs_t <= (others => 'Z'); - top_1 : top + top_1 : component top generic map ( - SIMULATION => SIMULATION - ) + simulation => SIMULATION + ) port map ( -- MMI64 profpga_clk0_p => profpga_clk0_p, @@ -435,27 +432,27 @@ begin etx_er => etx_er, emdc => emdc, emdio => emdio, --- tft_nhpd => '0', --- tft_clk_p => tft_clk_p, --- tft_clk_n => tft_clk_n, --- tft_data => tft_data, --- tft_hsync => tft_hsync, --- tft_vsync => tft_vsync, --- tft_de => tft_de, --- tft_dken => tft_dken, --- tft_ctl1_a1_dk1 => tft_ctl1_a1_dk1, --- tft_ctl2_a2_dk2 => tft_ctl2_a2_dk2, --- tft_a3_dk3 => tft_a3_dk3, --- tft_isel => tft_isel, --- tft_bsel => tft_bsel, --- tft_dsel => tft_dsel, --- tft_edge => tft_edge, --- tft_npd => tft_npd, - LED_RED => open, - LED_GREEN => open, - LED_BLUE => open, - LED_YELLOW => open - ); + -- tft_nhpd => '0', + -- tft_clk_p => tft_clk_p, + -- tft_clk_n => tft_clk_n, + -- tft_data => tft_data, + -- tft_hsync => tft_hsync, + -- tft_vsync => tft_vsync, + -- tft_de => tft_de, + -- tft_dken => tft_dken, + -- tft_ctl1_a1_dk1 => tft_ctl1_a1_dk1, + -- tft_ctl2_a2_dk2 => tft_ctl2_a2_dk2, + -- tft_a3_dk3 => tft_a3_dk3, + -- tft_isel => tft_isel, + -- tft_bsel => tft_bsel, + -- tft_dsel => tft_dsel, + -- tft_edge => tft_edge, + -- tft_npd => tft_npd, + led_red => open, + led_green => open, + led_blue => open, + led_yellow => open + ); -end; +end architecture behav; diff --git a/socs/profpga-xcvu440/systest.c b/socs/profpga-xcvu440/systest.c index 1819d28446..6d6e7c094c 100644 --- a/socs/profpga-xcvu440/systest.c +++ b/socs/profpga-xcvu440/systest.c @@ -5,7 +5,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/profpga-xcvu440/testbench.vhd b/socs/profpga-xcvu440/testbench.vhd index afd9d47f8a..218f8ffbf0 100644 --- a/socs/profpga-xcvu440/testbench.vhd +++ b/socs/profpga-xcvu440/testbench.vhd @@ -5,20 +5,18 @@ -- Testbench for ESP on proFPGA xcvu440 with DDR4, Ethernet and DVI ------------------------------------------------------------------------------ - library ieee; -use ieee.std_logic_1164.all; -use work.libdcom.all; -use work.sim.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gencomp.all; - -use work.grlib_config.all; + use ieee.std_logic_1164.all; + use work.libdcom.all; + use work.sim.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gencomp.all; + use work.grlib_config.all; entity testbench is -end; +end entity testbench; architecture behav of testbench is @@ -70,75 +68,74 @@ architecture behav of testbench is signal esp_clk_p : std_ulogic := '0'; signal esp_clk_n : std_ulogic := '1'; - -- DDR4 memory - signal c0_ddr4_act_n : std_logic; - signal c0_ddr4_adr : std_logic_vector(16 downto 0); - signal c0_ddr4_ba : std_logic_vector(1 downto 0); - signal c0_ddr4_bg : std_logic_vector(1 downto 0); - signal c0_ddr4_cke : std_logic_vector(1 downto 0); - signal c0_ddr4_odt : std_logic_vector(1 downto 0); - signal c0_ddr4_cs_n : std_logic_vector(1 downto 0); - signal c0_ddr4_ck_t : std_logic_vector(0 downto 0); - signal c0_ddr4_ck_c : std_logic_vector(0 downto 0); - signal c0_ddr4_reset_n : std_logic; - signal c0_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); - signal c0_ddr4_dq : std_logic_vector(71 downto 0); - signal c0_ddr4_dqs_c : std_logic_vector(8 downto 0); - signal c0_ddr4_dqs_t : std_logic_vector(8 downto 0); + signal c0_ddr4_act_n : std_logic; + signal c0_ddr4_adr : std_logic_vector(16 downto 0); + signal c0_ddr4_ba : std_logic_vector(1 downto 0); + signal c0_ddr4_bg : std_logic_vector(1 downto 0); + signal c0_ddr4_cke : std_logic_vector(1 downto 0); + signal c0_ddr4_odt : std_logic_vector(1 downto 0); + signal c0_ddr4_cs_n : std_logic_vector(1 downto 0); + signal c0_ddr4_ck_t : std_logic_vector(0 downto 0); + signal c0_ddr4_ck_c : std_logic_vector(0 downto 0); + signal c0_ddr4_reset_n : std_logic; + signal c0_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); + signal c0_ddr4_dq : std_logic_vector(71 downto 0); + signal c0_ddr4_dqs_c : std_logic_vector(8 downto 0); + signal c0_ddr4_dqs_t : std_logic_vector(8 downto 0); signal c0_calib_complete : std_logic; - signal c0_diagnostic_led : std_ulogic; - - signal c1_ddr4_act_n : std_logic; - signal c1_ddr4_adr : std_logic_vector(16 downto 0); - signal c1_ddr4_ba : std_logic_vector(1 downto 0); - signal c1_ddr4_bg : std_logic_vector(1 downto 0); - signal c1_ddr4_cke : std_logic_vector(1 downto 0); - signal c1_ddr4_odt : std_logic_vector(1 downto 0); - signal c1_ddr4_cs_n : std_logic_vector(1 downto 0); - signal c1_ddr4_ck_t : std_logic_vector(0 downto 0); - signal c1_ddr4_ck_c : std_logic_vector(0 downto 0); - signal c1_ddr4_reset_n : std_logic; - signal c1_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); - signal c1_ddr4_dq : std_logic_vector(71 downto 0); - signal c1_ddr4_dqs_c : std_logic_vector(8 downto 0); - signal c1_ddr4_dqs_t : std_logic_vector(8 downto 0); + signal c0_diagnostic_led : std_ulogic; + + signal c1_ddr4_act_n : std_logic; + signal c1_ddr4_adr : std_logic_vector(16 downto 0); + signal c1_ddr4_ba : std_logic_vector(1 downto 0); + signal c1_ddr4_bg : std_logic_vector(1 downto 0); + signal c1_ddr4_cke : std_logic_vector(1 downto 0); + signal c1_ddr4_odt : std_logic_vector(1 downto 0); + signal c1_ddr4_cs_n : std_logic_vector(1 downto 0); + signal c1_ddr4_ck_t : std_logic_vector(0 downto 0); + signal c1_ddr4_ck_c : std_logic_vector(0 downto 0); + signal c1_ddr4_reset_n : std_logic; + signal c1_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); + signal c1_ddr4_dq : std_logic_vector(71 downto 0); + signal c1_ddr4_dqs_c : std_logic_vector(8 downto 0); + signal c1_ddr4_dqs_t : std_logic_vector(8 downto 0); signal c1_calib_complete : std_logic; - signal c1_diagnostic_led : std_ulogic; - - signal c2_ddr4_act_n : std_logic; - signal c2_ddr4_adr : std_logic_vector(16 downto 0); - signal c2_ddr4_ba : std_logic_vector(1 downto 0); - signal c2_ddr4_bg : std_logic_vector(1 downto 0); - signal c2_ddr4_cke : std_logic_vector(1 downto 0); - signal c2_ddr4_odt : std_logic_vector(1 downto 0); - signal c2_ddr4_cs_n : std_logic_vector(1 downto 0); - signal c2_ddr4_ck_t : std_logic_vector(0 downto 0); - signal c2_ddr4_ck_c : std_logic_vector(0 downto 0); - signal c2_ddr4_reset_n : std_logic; - signal c2_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); - signal c2_ddr4_dq : std_logic_vector(71 downto 0); - signal c2_ddr4_dqs_c : std_logic_vector(8 downto 0); - signal c2_ddr4_dqs_t : std_logic_vector(8 downto 0); + signal c1_diagnostic_led : std_ulogic; + + signal c2_ddr4_act_n : std_logic; + signal c2_ddr4_adr : std_logic_vector(16 downto 0); + signal c2_ddr4_ba : std_logic_vector(1 downto 0); + signal c2_ddr4_bg : std_logic_vector(1 downto 0); + signal c2_ddr4_cke : std_logic_vector(1 downto 0); + signal c2_ddr4_odt : std_logic_vector(1 downto 0); + signal c2_ddr4_cs_n : std_logic_vector(1 downto 0); + signal c2_ddr4_ck_t : std_logic_vector(0 downto 0); + signal c2_ddr4_ck_c : std_logic_vector(0 downto 0); + signal c2_ddr4_reset_n : std_logic; + signal c2_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); + signal c2_ddr4_dq : std_logic_vector(71 downto 0); + signal c2_ddr4_dqs_c : std_logic_vector(8 downto 0); + signal c2_ddr4_dqs_t : std_logic_vector(8 downto 0); signal c2_calib_complete : std_logic; - signal c2_diagnostic_led : std_ulogic; - - signal c3_ddr4_act_n : std_logic; - signal c3_ddr4_adr : std_logic_vector(16 downto 0); - signal c3_ddr4_ba : std_logic_vector(1 downto 0); - signal c3_ddr4_bg : std_logic_vector(1 downto 0); - signal c3_ddr4_cke : std_logic_vector(1 downto 0); - signal c3_ddr4_odt : std_logic_vector(1 downto 0); - signal c3_ddr4_cs_n : std_logic_vector(1 downto 0); - signal c3_ddr4_ck_t : std_logic_vector(0 downto 0); - signal c3_ddr4_ck_c : std_logic_vector(0 downto 0); - signal c3_ddr4_reset_n : std_logic; - signal c3_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); - signal c3_ddr4_dq : std_logic_vector(71 downto 0); - signal c3_ddr4_dqs_c : std_logic_vector(8 downto 0); - signal c3_ddr4_dqs_t : std_logic_vector(8 downto 0); + signal c2_diagnostic_led : std_ulogic; + + signal c3_ddr4_act_n : std_logic; + signal c3_ddr4_adr : std_logic_vector(16 downto 0); + signal c3_ddr4_ba : std_logic_vector(1 downto 0); + signal c3_ddr4_bg : std_logic_vector(1 downto 0); + signal c3_ddr4_cke : std_logic_vector(1 downto 0); + signal c3_ddr4_odt : std_logic_vector(1 downto 0); + signal c3_ddr4_cs_n : std_logic_vector(1 downto 0); + signal c3_ddr4_ck_t : std_logic_vector(0 downto 0); + signal c3_ddr4_ck_c : std_logic_vector(0 downto 0); + signal c3_ddr4_reset_n : std_logic; + signal c3_ddr4_dm_dbi_n : std_logic_vector(8 downto 0); + signal c3_ddr4_dq : std_logic_vector(71 downto 0); + signal c3_ddr4_dqs_c : std_logic_vector(8 downto 0); + signal c3_ddr4_dqs_t : std_logic_vector(8 downto 0); signal c3_calib_complete : std_logic; - signal c3_diagnostic_led : std_ulogic; + signal c3_diagnostic_led : std_ulogic; -- UART signal uart_rxd : std_ulogic; @@ -146,30 +143,30 @@ architecture behav of testbench is signal uart_ctsn : std_ulogic; signal uart_rtsn : std_ulogic; - -- MMI64 - signal profpga_clk0_p : std_ulogic := '0'; -- 100 MHz clock - signal profpga_clk0_n : std_ulogic := '1'; -- 100 MHz clock + signal profpga_clk0_p : std_ulogic := '0'; -- 100 MHz clock + signal profpga_clk0_n : std_ulogic := '1'; -- 100 MHz clock signal profpga_sync0_p : std_ulogic; signal profpga_sync0_n : std_ulogic; signal dmbi_h2f : std_logic_vector(19 downto 0); signal dmbi_f2h : std_logic_vector(19 downto 0); - component top + component top is generic ( - SIMULATION : boolean); + simulation : boolean + ); port ( -- MMI64 interface: - profpga_clk0_p : in std_ulogic; -- 100 MHz clock - profpga_clk0_n : in std_ulogic; -- 100 MHz clock - profpga_sync0_p : in std_ulogic; - profpga_sync0_n : in std_ulogic; - dmbi_h2f : in std_logic_vector(19 downto 0); - dmbi_f2h : out std_logic_vector(19 downto 0); + profpga_clk0_p : in std_ulogic; + profpga_clk0_n : in std_ulogic; + profpga_sync0_p : in std_ulogic; + profpga_sync0_n : in std_ulogic; + dmbi_h2f : in std_logic_vector(19 downto 0); + dmbi_f2h : out std_logic_vector(19 downto 0); -- Main ESP clock - esp_clk_p : in std_ulogic; -- 78.125 MHz clock - esp_clk_n : in std_ulogic; -- 78.125 MHz clock - reset : in std_ulogic; + esp_clk_p : in std_ulogic; + esp_clk_n : in std_ulogic; + reset : in std_ulogic; -- DDR4 c0_sys_clk_p : in std_logic; c0_sys_clk_n : in std_logic; @@ -243,53 +240,53 @@ architecture behav of testbench is c3_ddr4_dqs_t : inout std_logic_vector(8 downto 0); c3_calib_complete : out std_logic; c3_diagnostic_led : out std_ulogic; --- UART - uart_rxd : in std_ulogic; - uart_txd : out std_ulogic; - uart_ctsn : in std_ulogic; - uart_rtsn : out std_ulogic; + -- UART + uart_rxd : in std_ulogic; + uart_txd : out std_ulogic; + uart_ctsn : in std_ulogic; + uart_rtsn : out std_ulogic; -- Ethernet signals - reset_o2 : out std_ulogic; - etx_clk : in std_ulogic; - erx_clk : in std_ulogic; - erxd : in std_logic_vector(3 downto 0); - erx_dv : in std_ulogic; - erx_er : in std_ulogic; - erx_col : in std_ulogic; - erx_crs : in std_ulogic; - etxd : out std_logic_vector(3 downto 0); - etx_en : out std_ulogic; - etx_er : out std_ulogic; - emdc : out std_ulogic; - emdio : inout std_logic; + reset_o2 : out std_ulogic; + etx_clk : in std_ulogic; + erx_clk : in std_ulogic; + erxd : in std_logic_vector(3 downto 0); + erx_dv : in std_ulogic; + erx_er : in std_ulogic; + erx_col : in std_ulogic; + erx_crs : in std_ulogic; + etxd : out std_logic_vector(3 downto 0); + etx_en : out std_ulogic; + etx_er : out std_ulogic; + emdc : out std_ulogic; + emdio : inout std_logic; -- DVI - tft_nhpd : in std_ulogic; -- Hot plug - tft_clk_p : out std_ulogic; - tft_clk_n : out std_ulogic; - tft_data : out std_logic_vector(23 downto 0); - tft_hsync : out std_ulogic; - tft_vsync : out std_ulogic; - tft_de : out std_ulogic; - tft_dken : out std_ulogic; - tft_ctl1_a1_dk1 : out std_ulogic; - tft_ctl2_a2_dk2 : out std_ulogic; - tft_a3_dk3 : out std_ulogic; - tft_isel : out std_ulogic; - tft_bsel : out std_logic; - tft_dsel : out std_logic; - tft_edge : out std_ulogic; - tft_npd : out std_ulogic; + tft_nhpd : in std_ulogic; + tft_clk_p : out std_ulogic; + tft_clk_n : out std_ulogic; + tft_data : out std_logic_vector(23 downto 0); + tft_hsync : out std_ulogic; + tft_vsync : out std_ulogic; + tft_de : out std_ulogic; + tft_dken : out std_ulogic; + tft_ctl1_a1_dk1 : out std_ulogic; + tft_ctl2_a2_dk2 : out std_ulogic; + tft_a3_dk3 : out std_ulogic; + tft_isel : out std_ulogic; + tft_bsel : out std_logic; + tft_dsel : out std_logic; + tft_edge : out std_ulogic; + tft_npd : out std_ulogic; -- LEDs - LED_RED : out std_ulogic; - LED_GREEN : out std_ulogic; - LED_BLUE : out std_ulogic; - LED_YELLOW : out std_ulogic); - + led_red : out std_ulogic; + led_green : out std_ulogic; + led_blue : out std_ulogic; + led_yellow : out std_ulogic + ); end component; begin - --MMI64 + -- MMI64 profpga_clk0_p <= not profpga_clk0_p after 5 ns; profpga_clk0_n <= not profpga_clk0_n after 5 ns; profpga_sync0_p <= '0'; @@ -331,10 +328,10 @@ begin c3_ddr4_dqs_c <= (others => 'Z'); c3_ddr4_dqs_t <= (others => 'Z'); - top_1 : top + top_1 : component top generic map ( - SIMULATION => SIMULATION - ) + simulation => SIMULATION + ) port map ( -- MMI64 profpga_clk0_p => profpga_clk0_p, @@ -451,11 +448,11 @@ begin tft_dsel => tft_dsel, tft_edge => tft_edge, tft_npd => tft_npd, - LED_RED => open, - LED_GREEN => open, - LED_BLUE => open, - LED_YELLOW => open - ); + led_red => open, + led_green => open, + led_blue => open, + led_yellow => open + ); -end; +end architecture behav; diff --git a/socs/xilinx-vc707-xc7vx485t/systest.c b/socs/xilinx-vc707-xc7vx485t/systest.c index 1819d28446..6d6e7c094c 100644 --- a/socs/xilinx-vc707-xc7vx485t/systest.c +++ b/socs/xilinx-vc707-xc7vx485t/systest.c @@ -5,7 +5,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/xilinx-vc707-xc7vx485t/testbench.vhd b/socs/xilinx-vc707-xc7vx485t/testbench.vhd index c53668880b..d54ef3f3df 100644 --- a/socs/xilinx-vc707-xc7vx485t/testbench.vhd +++ b/socs/xilinx-vc707-xc7vx485t/testbench.vhd @@ -5,26 +5,26 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.libdcom.all; -use work.sim.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gencomp.all; - -use work.grlib_config.all; + use ieee.std_logic_1164.all; + use work.libdcom.all; + use work.sim.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gencomp.all; + use work.grlib_config.all; entity testbench is -end; +end entity testbench; architecture behav of testbench is - constant SIMULATION : boolean := true; + constant SIMULATION : boolean := true; component top is generic ( - SIMULATION : boolean); + simulation : boolean + ); port ( reset : in std_ulogic; sys_clk_p : in std_ulogic; @@ -60,13 +60,12 @@ architecture behav of testbench is uart_rtsn : out std_ulogic; button : in std_logic_vector(3 downto 0); switch : inout std_logic_vector(4 downto 0); - led : out std_logic_vector(6 downto 0)); + led : out std_logic_vector(6 downto 0) + ); end component top; - -- Bein TOP-level interface -- - -- Reset and clocl signal reset : std_ulogic := '1'; signal sys_clk_p : std_ulogic := '0'; @@ -112,7 +111,7 @@ architecture behav of testbench is signal switch : std_logic_vector(4 downto 0); signal led : std_logic_vector(6 downto 0); - -- End TOP-level interface -- +-- End TOP-level interface -- begin @@ -126,7 +125,6 @@ begin ddr3_dqs_p <= (others => 'Z'); ddr3_dqs_n <= (others => 'Z'); - -- Ethernet (There is no behavioral testbench for the SGMII PHY) gtrefclk_p <= not gtrefclk_p after 4 ns; gtrefclk_n <= not gtrefclk_n after 4 ns; @@ -143,10 +141,10 @@ begin button <= (others => '0'); switch <= (others => '0'); - top_1 : entity work.top generic map ( - SIMULATION => SIMULATION) + simulation => SIMULATION + ) port map ( reset => reset, sys_clk_p => sys_clk_p, @@ -182,7 +180,8 @@ begin uart_rtsn => uart_rtsn, button => button, switch => switch, - led => led); + led => led + ); -end; +end architecture behav; diff --git a/socs/xilinx-vcu118-xcvu9p/systest.c b/socs/xilinx-vcu118-xcvu9p/systest.c index 1819d28446..6d6e7c094c 100644 --- a/socs/xilinx-vcu118-xcvu9p/systest.c +++ b/socs/xilinx-vcu118-xcvu9p/systest.c @@ -5,7 +5,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/xilinx-vcu118-xcvu9p/testbench.vhd b/socs/xilinx-vcu118-xcvu9p/testbench.vhd index a0d58e49d1..edd5350e39 100644 --- a/socs/xilinx-vcu118-xcvu9p/testbench.vhd +++ b/socs/xilinx-vcu118-xcvu9p/testbench.vhd @@ -5,29 +5,29 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.libdcom.all; -use work.sim.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gencomp.all; - -use work.grlib_config.all; + use ieee.std_logic_1164.all; + use work.libdcom.all; + use work.sim.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gencomp.all; + use work.grlib_config.all; entity testbench is -end; +end entity testbench; architecture behav of testbench is - constant SIMULATION : boolean := true; + constant SIMULATION : boolean := true; - constant promfile : string := "prom.srec"; -- rom contents - constant ramfile : string := "ram.srec"; -- ram contents + constant PROMFILE : string := "prom.srec"; -- rom contents + constant RAMFILE : string := "ram.srec"; -- ram contents component top is generic ( - SIMULATION : boolean); + simulation : boolean + ); port ( reset : in std_ulogic; c0_sys_clk_p : in std_logic; @@ -62,17 +62,18 @@ architecture behav of testbench is uart_rtsn : out std_ulogic; button : in std_logic_vector(3 downto 0); switch : inout std_logic_vector(3 downto 0); - led : out std_logic_vector(6 downto 0)); + led : out std_logic_vector(6 downto 0) + ); end component top; --- Bein TOP-level interface -- + -- Bein TOP-level interface -- --- Reset and clock + -- Reset and clock signal reset : std_ulogic := '1'; signal c0_sys_clk_p : std_logic := '0'; signal c0_sys_clk_n : std_logic := '1'; --- DDR4 + -- DDR4 signal c0_ddr4_act_n : std_logic; signal c0_ddr4_adr : std_logic_vector(16 downto 0); signal c0_ddr4_ba : std_logic_vector(1 downto 0); @@ -88,7 +89,7 @@ architecture behav of testbench is signal c0_ddr4_dqs_c : std_logic_vector(7 downto 0); signal c0_ddr4_dqs_t : std_logic_vector(7 downto 0); --- SGMII Ethernet + -- SGMII Ethernet signal gtrefclk_p : std_logic := '0'; signal gtrefclk_n : std_logic := '1'; signal txp : std_logic; @@ -100,13 +101,13 @@ architecture behav of testbench is signal eint : std_ulogic; signal erst : std_ulogic; --- UART + -- UART signal uart_rxd : std_ulogic; signal uart_txd : std_ulogic; signal uart_ctsn : std_ulogic; signal uart_rtsn : std_ulogic; --- GPIO + -- GPIO signal button : std_logic_vector(3 downto 0); signal switch : std_logic_vector(3 downto 0); signal led : std_logic_vector(6 downto 0); @@ -142,9 +143,10 @@ begin button <= (others => '0'); switch <= (others => '0'); - cpu : top + cpu : component top generic map ( - SIMULATION => SIMULATION) + simulation => SIMULATION + ) port map ( reset => reset, c0_sys_clk_p => c0_sys_clk_p, @@ -179,7 +181,7 @@ begin uart_rtsn => uart_rtsn, button => button, switch => switch, - led => led); - + led => led + ); -end; +end architecture behav; diff --git a/socs/xilinx-vcu128-xcvu37p/systest.c b/socs/xilinx-vcu128-xcvu37p/systest.c index 1819d28446..6d6e7c094c 100644 --- a/socs/xilinx-vcu128-xcvu37p/systest.c +++ b/socs/xilinx-vcu128-xcvu37p/systest.c @@ -5,7 +5,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/xilinx-vcu128-xcvu37p/testbench.vhd b/socs/xilinx-vcu128-xcvu37p/testbench.vhd index 75ae0ad241..62f1d7e54d 100644 --- a/socs/xilinx-vcu128-xcvu37p/testbench.vhd +++ b/socs/xilinx-vcu128-xcvu37p/testbench.vhd @@ -5,29 +5,29 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.libdcom.all; -use work.sim.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gencomp.all; - -use work.grlib_config.all; + use ieee.std_logic_1164.all; + use work.libdcom.all; + use work.sim.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gencomp.all; + use work.grlib_config.all; entity testbench is -end; +end entity testbench; architecture behav of testbench is - constant SIMULATION : boolean := true; + constant SIMULATION : boolean := true; - constant promfile : string := "prom.srec"; -- rom contents - constant ramfile : string := "ram.srec"; -- ram contents + constant PROMFILE : string := "prom.srec"; -- rom contents + constant RAMFILE : string := "ram.srec"; -- ram contents component top is generic ( - SIMULATION : boolean); + simulation : boolean + ); port ( reset : in std_ulogic; c0_sys_clk_p : in std_logic; @@ -60,17 +60,18 @@ architecture behav of testbench is uart_txd : out std_ulogic; uart_ctsn : in std_ulogic; uart_rtsn : out std_ulogic; - led : out std_logic_vector(6 downto 0)); + led : out std_logic_vector(6 downto 0) + ); end component top; --- Bein TOP-level interface -- + -- Bein TOP-level interface -- --- Reset and clock + -- Reset and clock signal reset : std_ulogic := '1'; signal c0_sys_clk_p : std_logic := '0'; signal c0_sys_clk_n : std_logic := '1'; --- DDR4 + -- DDR4 signal c0_ddr4_act_n : std_logic; signal c0_ddr4_adr : std_logic_vector(16 downto 0); signal c0_ddr4_ba : std_logic_vector(1 downto 0); @@ -86,7 +87,7 @@ architecture behav of testbench is signal c0_ddr4_dqs_c : std_logic_vector(7 downto 0); signal c0_ddr4_dqs_t : std_logic_vector(7 downto 0); --- SGMII Ethernet + -- SGMII Ethernet signal gtrefclk_p : std_logic := '0'; signal gtrefclk_n : std_logic := '1'; signal txp : std_logic; @@ -98,14 +99,14 @@ architecture behav of testbench is signal eint : std_ulogic; signal edummy : std_ulogic; --- UART + -- UART signal uart_rxd : std_ulogic; signal uart_txd : std_ulogic; signal uart_ctsn : std_ulogic; signal uart_rtsn : std_ulogic; --- GPIO - signal led : std_logic_vector(6 downto 0); + -- GPIO + signal led : std_logic_vector(6 downto 0); -- End TOP-level interface -- @@ -135,9 +136,10 @@ begin uart_rxd <= '0'; uart_ctsn <= '0'; - cpu : top + cpu : component top generic map ( - SIMULATION => SIMULATION) + simulation => SIMULATION + ) port map ( reset => reset, c0_sys_clk_p => c0_sys_clk_p, @@ -170,7 +172,7 @@ begin uart_txd => uart_txd, uart_ctsn => uart_ctsn, uart_rtsn => uart_rtsn, - led => led); - + led => led + ); -end; +end architecture behav; diff --git a/socs/xilinx-zcu102-xczu9eg/systest.c b/socs/xilinx-zcu102-xczu9eg/systest.c index 1819d28446..6d6e7c094c 100644 --- a/socs/xilinx-zcu102-xczu9eg/systest.c +++ b/socs/xilinx-zcu102-xczu9eg/systest.c @@ -5,7 +5,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/xilinx-zcu102-xczu9eg/testbench.vhd b/socs/xilinx-zcu102-xczu9eg/testbench.vhd index 678aa06d70..d16c43f02c 100644 --- a/socs/xilinx-zcu102-xczu9eg/testbench.vhd +++ b/socs/xilinx-zcu102-xczu9eg/testbench.vhd @@ -5,79 +5,81 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.libdcom.all; -use work.sim.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gencomp.all; -use work.grlib_config.all; -use work.sim.all; -use work.esp_global.all; -use work.socmap.all; + use ieee.std_logic_1164.all; + use work.libdcom.all; + use work.sim.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gencomp.all; + use work.grlib_config.all; + use work.sim.all; + use work.esp_global.all; + use work.socmap.all; entity testbench is -end; +end entity testbench; architecture behav of testbench is - constant SIMULATION : boolean := true; + constant SIMULATION : boolean := true; - constant promfile : string := "prom.srec"; -- rom contents - constant ramfile : string := "ram.srec"; -- ram contents + constant PROMFILE : string := "prom.srec"; -- rom contents + constant RAMFILE : string := "ram.srec"; -- ram contents component top is generic ( - SIMULATION : boolean); + simulation : boolean + ); port ( - reset : in std_ulogic; - chip_refclk : in std_ulogic; - uart_rxd : in std_ulogic; - uart_txd : out std_ulogic; - uart_ctsn : in std_ulogic; - uart_rtsn : out std_ulogic; - led : out std_logic_vector(6 downto 0); - so_hready : in std_ulogic; - so_hresp : in std_logic_vector(1 downto 0); - so_hrdata : in std_logic_vector(AHBDW - 1 downto 0); - si_htrans : out std_logic_vector(1 downto 0); - si_haddr : out std_logic_vector(31 downto 0); - si_hwrite : out std_ulogic; - si_hsize : out std_logic_vector(2 downto 0); - si_hburst : out std_logic_vector(2 downto 0); - si_hprot : out std_logic_vector(3 downto 0); - si_hwdata : out std_logic_vector(AHBDW - 1 downto 0); - si_hsel : out std_ulogic; - si_hready : out std_ulogic; - mi_hready : out std_ulogic; - mi_hresp : out std_logic_vector(1 downto 0); - mi_hrdata : out std_logic_vector(31 downto 0); - mo_hlock : in std_ulogic; - mo_htrans : in std_logic_vector(1 downto 0); - mo_haddr : in std_logic_vector(31 downto 0); - mo_hwrite : in std_ulogic; - mo_hsize : in std_logic_vector(2 downto 0); - mo_hburst : in std_logic_vector(2 downto 0); - mo_hprot : in std_logic_vector(3 downto 0); - mo_hwdata : in std_logic_vector(31 downto 0)); + reset : in std_ulogic; + chip_refclk : in std_ulogic; + uart_rxd : in std_ulogic; + uart_txd : out std_ulogic; + uart_ctsn : in std_ulogic; + uart_rtsn : out std_ulogic; + led : out std_logic_vector(6 downto 0); + so_hready : in std_ulogic; + so_hresp : in std_logic_vector(1 downto 0); + so_hrdata : in std_logic_vector(AHBDW - 1 downto 0); + si_htrans : out std_logic_vector(1 downto 0); + si_haddr : out std_logic_vector(31 downto 0); + si_hwrite : out std_ulogic; + si_hsize : out std_logic_vector(2 downto 0); + si_hburst : out std_logic_vector(2 downto 0); + si_hprot : out std_logic_vector(3 downto 0); + si_hwdata : out std_logic_vector(AHBDW - 1 downto 0); + si_hsel : out std_ulogic; + si_hready : out std_ulogic; + mi_hready : out std_ulogic; + mi_hresp : out std_logic_vector(1 downto 0); + mi_hrdata : out std_logic_vector(31 downto 0); + mo_hlock : in std_ulogic; + mo_htrans : in std_logic_vector(1 downto 0); + mo_haddr : in std_logic_vector(31 downto 0); + mo_hwrite : in std_ulogic; + mo_hsize : in std_logic_vector(2 downto 0); + mo_hburst : in std_logic_vector(2 downto 0); + mo_hprot : in std_logic_vector(3 downto 0); + mo_hwdata : in std_logic_vector(31 downto 0) + ); end component top; -- ESP top - signal so_hready : std_ulogic; - signal so_hresp : std_logic_vector(1 downto 0); - signal so_hrdata : std_logic_vector(AHBDW - 1 downto 0); - signal si_htrans : std_logic_vector(1 downto 0); - signal si_haddr : std_logic_vector(31 downto 0); - signal si_hwrite : std_ulogic; - signal si_hsize : std_logic_vector(2 downto 0); - signal si_hburst : std_logic_vector(2 downto 0); - signal si_hprot : std_logic_vector(3 downto 0); - signal si_hwdata : std_logic_vector(AHBDW - 1 downto 0); - signal mi_hready : std_ulogic; - signal mi_hresp : std_logic_vector(1 downto 0); - signal si_hsel : std_ulogic; - signal si_hready : std_ulogic; + signal so_hready : std_ulogic; + signal so_hresp : std_logic_vector(1 downto 0); + signal so_hrdata : std_logic_vector(AHBDW - 1 downto 0); + signal si_htrans : std_logic_vector(1 downto 0); + signal si_haddr : std_logic_vector(31 downto 0); + signal si_hwrite : std_ulogic; + signal si_hsize : std_logic_vector(2 downto 0); + signal si_hburst : std_logic_vector(2 downto 0); + signal si_hprot : std_logic_vector(3 downto 0); + signal si_hwdata : std_logic_vector(AHBDW - 1 downto 0); + signal mi_hready : std_ulogic; + signal mi_hresp : std_logic_vector(1 downto 0); + signal si_hsel : std_ulogic; + signal si_hready : std_ulogic; -- PS-side memory model signal ddr_ahbsi : ahb_slv_in_type; @@ -96,7 +98,7 @@ architecture behav of testbench is signal uart_rtsn : std_ulogic; -- GPIO - signal led : std_logic_vector(6 downto 0); + signal led : std_logic_vector(6 downto 0); begin @@ -113,13 +115,17 @@ begin rstn <= not reset; ddr_ahbsi.hready <= si_hready; + hsel_gen : process (si_hsel) is begin -- process hsel_gen + ddr_ahbsi.hsel <= (others => '0'); ddr_ahbsi.hsel(0) <= si_hsel; ddr_ahbsi.hmaster <= (others => '0'); ddr_ahbsi.hmaster(CFG_DEFMST) <= '1'; + end process hsel_gen; + ddr_ahbsi.htrans <= si_htrans; ddr_ahbsi.haddr <= si_haddr; ddr_ahbsi.hwrite <= si_hwrite; @@ -136,10 +142,10 @@ begin ddr_ahbsi.testin <= (others => '0'); so_hready <= ddr_ahbso.hready; - so_hresp <= ddr_ahbso.hresp; + so_hresp <= ddr_ahbso.hresp; so_hrdata <= ddr_ahbso.hrdata; - ddr_model : ahbram_sim + ddr_model : component ahbram_sim generic map ( hindex => 0, tech => 0, @@ -147,21 +153,21 @@ begin pipe => 0, maccsz => AHBDW, fname => "ram.srec" - ) - port map( + ) + port map ( rst => rstn, clk => chip_refclk, - haddr => 16#400#, -- ZCU102 has fixed address mapping! + haddr => 16#400#, hmask => ddr_hmask(0), ahbsi => ddr_ahbsi, ahbso => ddr_ahbso - ); - + ); -- ESP top - cpu : top + cpu : component top generic map ( - SIMULATION => SIMULATION) + simulation => SIMULATION + ) port map ( reset => reset, chip_refclk => chip_refclk, @@ -193,7 +199,6 @@ begin mo_hburst => (others => '0'), mo_hprot => (others => '0'), mo_hwdata => (others => '0') - ); - + ); -end; +end architecture behav; diff --git a/socs/xilinx-zcu106-xczu7ev/systest.c b/socs/xilinx-zcu106-xczu7ev/systest.c index 1819d28446..6d6e7c094c 100644 --- a/socs/xilinx-zcu106-xczu7ev/systest.c +++ b/socs/xilinx-zcu106-xczu7ev/systest.c @@ -5,7 +5,7 @@ int main(int argc, char **argv) { - printf("Hello from ESP!\n"); + printf("Hello from ESP!\n"); - return 0; + return 0; } diff --git a/socs/xilinx-zcu106-xczu7ev/testbench.vhd b/socs/xilinx-zcu106-xczu7ev/testbench.vhd index 678aa06d70..d16c43f02c 100644 --- a/socs/xilinx-zcu106-xczu7ev/testbench.vhd +++ b/socs/xilinx-zcu106-xczu7ev/testbench.vhd @@ -5,79 +5,81 @@ ------------------------------------------------------------------------------ library ieee; -use ieee.std_logic_1164.all; -use work.libdcom.all; -use work.sim.all; -use work.amba.all; -use work.stdlib.all; -use work.devices.all; -use work.gencomp.all; -use work.grlib_config.all; -use work.sim.all; -use work.esp_global.all; -use work.socmap.all; + use ieee.std_logic_1164.all; + use work.libdcom.all; + use work.sim.all; + use work.amba.all; + use work.stdlib.all; + use work.devices.all; + use work.gencomp.all; + use work.grlib_config.all; + use work.sim.all; + use work.esp_global.all; + use work.socmap.all; entity testbench is -end; +end entity testbench; architecture behav of testbench is - constant SIMULATION : boolean := true; + constant SIMULATION : boolean := true; - constant promfile : string := "prom.srec"; -- rom contents - constant ramfile : string := "ram.srec"; -- ram contents + constant PROMFILE : string := "prom.srec"; -- rom contents + constant RAMFILE : string := "ram.srec"; -- ram contents component top is generic ( - SIMULATION : boolean); + simulation : boolean + ); port ( - reset : in std_ulogic; - chip_refclk : in std_ulogic; - uart_rxd : in std_ulogic; - uart_txd : out std_ulogic; - uart_ctsn : in std_ulogic; - uart_rtsn : out std_ulogic; - led : out std_logic_vector(6 downto 0); - so_hready : in std_ulogic; - so_hresp : in std_logic_vector(1 downto 0); - so_hrdata : in std_logic_vector(AHBDW - 1 downto 0); - si_htrans : out std_logic_vector(1 downto 0); - si_haddr : out std_logic_vector(31 downto 0); - si_hwrite : out std_ulogic; - si_hsize : out std_logic_vector(2 downto 0); - si_hburst : out std_logic_vector(2 downto 0); - si_hprot : out std_logic_vector(3 downto 0); - si_hwdata : out std_logic_vector(AHBDW - 1 downto 0); - si_hsel : out std_ulogic; - si_hready : out std_ulogic; - mi_hready : out std_ulogic; - mi_hresp : out std_logic_vector(1 downto 0); - mi_hrdata : out std_logic_vector(31 downto 0); - mo_hlock : in std_ulogic; - mo_htrans : in std_logic_vector(1 downto 0); - mo_haddr : in std_logic_vector(31 downto 0); - mo_hwrite : in std_ulogic; - mo_hsize : in std_logic_vector(2 downto 0); - mo_hburst : in std_logic_vector(2 downto 0); - mo_hprot : in std_logic_vector(3 downto 0); - mo_hwdata : in std_logic_vector(31 downto 0)); + reset : in std_ulogic; + chip_refclk : in std_ulogic; + uart_rxd : in std_ulogic; + uart_txd : out std_ulogic; + uart_ctsn : in std_ulogic; + uart_rtsn : out std_ulogic; + led : out std_logic_vector(6 downto 0); + so_hready : in std_ulogic; + so_hresp : in std_logic_vector(1 downto 0); + so_hrdata : in std_logic_vector(AHBDW - 1 downto 0); + si_htrans : out std_logic_vector(1 downto 0); + si_haddr : out std_logic_vector(31 downto 0); + si_hwrite : out std_ulogic; + si_hsize : out std_logic_vector(2 downto 0); + si_hburst : out std_logic_vector(2 downto 0); + si_hprot : out std_logic_vector(3 downto 0); + si_hwdata : out std_logic_vector(AHBDW - 1 downto 0); + si_hsel : out std_ulogic; + si_hready : out std_ulogic; + mi_hready : out std_ulogic; + mi_hresp : out std_logic_vector(1 downto 0); + mi_hrdata : out std_logic_vector(31 downto 0); + mo_hlock : in std_ulogic; + mo_htrans : in std_logic_vector(1 downto 0); + mo_haddr : in std_logic_vector(31 downto 0); + mo_hwrite : in std_ulogic; + mo_hsize : in std_logic_vector(2 downto 0); + mo_hburst : in std_logic_vector(2 downto 0); + mo_hprot : in std_logic_vector(3 downto 0); + mo_hwdata : in std_logic_vector(31 downto 0) + ); end component top; -- ESP top - signal so_hready : std_ulogic; - signal so_hresp : std_logic_vector(1 downto 0); - signal so_hrdata : std_logic_vector(AHBDW - 1 downto 0); - signal si_htrans : std_logic_vector(1 downto 0); - signal si_haddr : std_logic_vector(31 downto 0); - signal si_hwrite : std_ulogic; - signal si_hsize : std_logic_vector(2 downto 0); - signal si_hburst : std_logic_vector(2 downto 0); - signal si_hprot : std_logic_vector(3 downto 0); - signal si_hwdata : std_logic_vector(AHBDW - 1 downto 0); - signal mi_hready : std_ulogic; - signal mi_hresp : std_logic_vector(1 downto 0); - signal si_hsel : std_ulogic; - signal si_hready : std_ulogic; + signal so_hready : std_ulogic; + signal so_hresp : std_logic_vector(1 downto 0); + signal so_hrdata : std_logic_vector(AHBDW - 1 downto 0); + signal si_htrans : std_logic_vector(1 downto 0); + signal si_haddr : std_logic_vector(31 downto 0); + signal si_hwrite : std_ulogic; + signal si_hsize : std_logic_vector(2 downto 0); + signal si_hburst : std_logic_vector(2 downto 0); + signal si_hprot : std_logic_vector(3 downto 0); + signal si_hwdata : std_logic_vector(AHBDW - 1 downto 0); + signal mi_hready : std_ulogic; + signal mi_hresp : std_logic_vector(1 downto 0); + signal si_hsel : std_ulogic; + signal si_hready : std_ulogic; -- PS-side memory model signal ddr_ahbsi : ahb_slv_in_type; @@ -96,7 +98,7 @@ architecture behav of testbench is signal uart_rtsn : std_ulogic; -- GPIO - signal led : std_logic_vector(6 downto 0); + signal led : std_logic_vector(6 downto 0); begin @@ -113,13 +115,17 @@ begin rstn <= not reset; ddr_ahbsi.hready <= si_hready; + hsel_gen : process (si_hsel) is begin -- process hsel_gen + ddr_ahbsi.hsel <= (others => '0'); ddr_ahbsi.hsel(0) <= si_hsel; ddr_ahbsi.hmaster <= (others => '0'); ddr_ahbsi.hmaster(CFG_DEFMST) <= '1'; + end process hsel_gen; + ddr_ahbsi.htrans <= si_htrans; ddr_ahbsi.haddr <= si_haddr; ddr_ahbsi.hwrite <= si_hwrite; @@ -136,10 +142,10 @@ begin ddr_ahbsi.testin <= (others => '0'); so_hready <= ddr_ahbso.hready; - so_hresp <= ddr_ahbso.hresp; + so_hresp <= ddr_ahbso.hresp; so_hrdata <= ddr_ahbso.hrdata; - ddr_model : ahbram_sim + ddr_model : component ahbram_sim generic map ( hindex => 0, tech => 0, @@ -147,21 +153,21 @@ begin pipe => 0, maccsz => AHBDW, fname => "ram.srec" - ) - port map( + ) + port map ( rst => rstn, clk => chip_refclk, - haddr => 16#400#, -- ZCU102 has fixed address mapping! + haddr => 16#400#, hmask => ddr_hmask(0), ahbsi => ddr_ahbsi, ahbso => ddr_ahbso - ); - + ); -- ESP top - cpu : top + cpu : component top generic map ( - SIMULATION => SIMULATION) + simulation => SIMULATION + ) port map ( reset => reset, chip_refclk => chip_refclk, @@ -193,7 +199,6 @@ begin mo_hburst => (others => '0'), mo_hprot => (others => '0'), mo_hwdata => (others => '0') - ); - + ); -end; +end architecture behav; diff --git a/soft/ariane/bootrom/main.c b/soft/ariane/bootrom/main.c index b5c001b184..b5b4a64dc9 100644 --- a/soft/ariane/bootrom/main.c +++ b/soft/ariane/bootrom/main.c @@ -2,26 +2,20 @@ int main() { - __asm__ volatile( - "csrr a0, mhartid;" - "bne a0, x0, 1f"); + __asm__ volatile("csrr a0, mhartid;" + "bne a0, x0, 1f"); - init_uart(); + init_uart(); - // jump to the address - __asm__ volatile( - "1:" - "li s0, 0x80000000;" - "la a1, _dtb;" - "jr s0"); + // jump to the address + __asm__ volatile("1:" + "li s0, 0x80000000;" + "la a1, _dtb;" + "jr s0"); - while (1) - { - // do nothing - } + while (1) { + // do nothing + } } -void handle_trap(void) -{ - -} +void handle_trap(void) {} diff --git a/soft/ariane/common/syscalls.c b/soft/ariane/common/syscalls.c index c00f89ef85..7468767dac 100644 --- a/soft/ariane/common/syscalls.c +++ b/soft/ariane/common/syscalls.c @@ -1,13 +1,13 @@ // See LICENSE for license details. -#include -#include +#include "uart.h" +#include "util.h" +#include #include +#include #include -#include +#include #include -#include "util.h" -#include "uart.h" #undef strcmp @@ -16,437 +16,410 @@ extern volatile uint64_t fromhost; #define NUM_COUNTERS 2 static uintptr_t counters[NUM_COUNTERS]; -static char* counter_names[NUM_COUNTERS]; +static char *counter_names[NUM_COUNTERS]; void setStats(int enable) { - int i = 0; -#define READ_CTR(name) do { \ - while (i >= NUM_COUNTERS) ; \ - uintptr_t csr = read_csr(name); \ - if (!enable) { csr -= counters[i]; counter_names[i] = #name; } \ - counters[i++] = csr; \ - } while (0) - - READ_CTR(mcycle); - READ_CTR(minstret); + int i = 0; +#define READ_CTR(name) \ + do { \ + while (i >= NUM_COUNTERS) \ + ; \ + uintptr_t csr = read_csr(name); \ + if (!enable) { \ + csr -= counters[i]; \ + counter_names[i] = #name; \ + } \ + counters[i++] = csr; \ + } while (0) + + READ_CTR(mcycle); + READ_CTR(minstret); #undef READ_CTR } void __attribute__((noreturn)) tohost_exit(uintptr_t code) { - tohost = (code << 1) | 1; - while (1); + tohost = (code << 1) | 1; + while (1) + ; } uintptr_t __attribute__((weak)) handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) { - tohost_exit(1337); + tohost_exit(1337); } -void exit(int code) -{ - tohost_exit(code); -} +void exit(int code) { tohost_exit(code); } -void abort() -{ - exit(128 + SIGABRT); -} +void abort() { exit(128 + SIGABRT); } -void printstr(const char* s) -{ - print_uart(s); -} +void printstr(const char *s) { print_uart(s); } void __attribute__((weak)) thread_entry(int cid, int nc) { - // multi-threaded programs override this function. - // for the case of single-threaded programs, only let core 0 proceed. - while (cid != 0); + // multi-threaded programs override this function. + // for the case of single-threaded programs, only let core 0 proceed. + while (cid != 0) + ; } -int __attribute__((weak)) main(int argc, char** argv) +int __attribute__((weak)) main(int argc, char **argv) { - // single-threaded programs override this function. - printstr("Implement main(), foo!\n"); - return -1; + // single-threaded programs override this function. + printstr("Implement main(), foo!\n"); + return -1; } static void init_tls() { - register void* thread_pointer asm("tp"); - extern char _tls_data; - extern __thread char _tdata_begin, _tdata_end, _tbss_end; - size_t tdata_size = &_tdata_end - &_tdata_begin; - memcpy(thread_pointer, &_tls_data, tdata_size); - size_t tbss_size = &_tbss_end - &_tdata_end; - memset(thread_pointer + tdata_size, 0, tbss_size); + register void *thread_pointer asm("tp"); + extern char _tls_data; + extern __thread char _tdata_begin, _tdata_end, _tbss_end; + size_t tdata_size = &_tdata_end - &_tdata_begin; + memcpy(thread_pointer, &_tls_data, tdata_size); + size_t tbss_size = &_tbss_end - &_tdata_end; + memset(thread_pointer + tdata_size, 0, tbss_size); } void _init(int cid, int nc) { - init_tls(); - thread_entry(cid, nc); + init_tls(); + thread_entry(cid, nc); - // only single-threaded programs should ever get here. - int ret = main(0, 0); + // only single-threaded programs should ever get here. + int ret = main(0, 0); - char buf[NUM_COUNTERS * 32] __attribute__((aligned(64))); - char* pbuf = buf; - for (int i = 0; i < NUM_COUNTERS; i++) - if (counters[i]) - pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]); - if (pbuf != buf) - printstr(buf); + char buf[NUM_COUNTERS * 32] __attribute__((aligned(64))); + char *pbuf = buf; + for (int i = 0; i < NUM_COUNTERS; i++) + if (counters[i]) pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]); + if (pbuf != buf) printstr(buf); - exit(ret); + exit(ret); } #undef putchar int putchar(int ch) { - static __thread char buf[64] __attribute__((aligned(64))); - static __thread int buflen = 0; + static __thread char buf[64] __attribute__((aligned(64))); + static __thread int buflen = 0; - buf[buflen++] = ch; + buf[buflen++] = ch; - if (ch == '\n' || buflen == (sizeof(buf) - 1)) - { - buf[buflen] = '\0'; - print_uart(buf); - buflen = 0; - } + if (ch == '\n' || buflen == (sizeof(buf) - 1)) { + buf[buflen] = '\0'; + print_uart(buf); + buflen = 0; + } - return 0; + return 0; } void printhex(uint64_t x) { - char str[17]; - int i; - for (i = 0; i < 16; i++) - { - str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10); - x >>= 4; - } - str[16] = 0; - - printstr(str); + char str[17]; + int i; + for (i = 0; i < 16; i++) { + str[15 - i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a' - 10); + x >>= 4; + } + str[16] = 0; + + printstr(str); } -static inline void printnum(void (*putch)(int, void**), void **putdat, - unsigned long long num, unsigned base, int width, int padc) +static inline void printnum(void (*putch)(int, void **), void **putdat, unsigned long long num, + unsigned base, int width, int padc) { - unsigned digs[sizeof(num)*CHAR_BIT]; - int pos = 0; - - while (1) - { - digs[pos++] = num % base; - if (num < base) - break; - num /= base; - } - - while (width-- > pos) - putch(padc, putdat); - - while (pos-- > 0) - putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat); + unsigned digs[sizeof(num) * CHAR_BIT]; + int pos = 0; + + while (1) { + digs[pos++] = num % base; + if (num < base) break; + num /= base; + } + + while (width-- > pos) + putch(padc, putdat); + + while (pos-- > 0) + putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat); } static unsigned long long getuint(va_list *ap, int lflag) { - if (lflag >= 2) - return va_arg(*ap, unsigned long long); - else if (lflag) - return va_arg(*ap, unsigned long); - else - return va_arg(*ap, unsigned int); + if (lflag >= 2) return va_arg(*ap, unsigned long long); + else if (lflag) + return va_arg(*ap, unsigned long); + else + return va_arg(*ap, unsigned int); } static long long getint(va_list *ap, int lflag) { - if (lflag >= 2) - return va_arg(*ap, long long); - else if (lflag) - return va_arg(*ap, long); - else - return va_arg(*ap, int); + if (lflag >= 2) return va_arg(*ap, long long); + else if (lflag) + return va_arg(*ap, long); + else + return va_arg(*ap, int); } -static void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap) +static void vprintfmt(void (*putch)(int, void **), void **putdat, const char *fmt, va_list ap) { - register const char* p; - const char* last_fmt; - register int ch, err; - unsigned long long num; - int base, lflag, width, precision, altflag; - char padc; - - while (1) { - while ((ch = *(unsigned char *) fmt) != '%') { - if (ch == '\0') - return; - fmt++; - putch(ch, putdat); - } - fmt++; - - // Process a %-escape sequence - last_fmt = fmt; - padc = ' '; - width = -1; - precision = -1; - lflag = 0; - altflag = 0; - reswitch: - switch (ch = *(unsigned char *) fmt++) { - - // flag to pad on the right - case '-': - padc = '-'; - goto reswitch; - - // flag to pad with 0's instead of spaces - case '0': - padc = '0'; - goto reswitch; - - // width field - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - for (precision = 0; ; ++fmt) { - precision = precision * 10 + ch - '0'; - ch = *fmt; - if (ch < '0' || ch > '9') - break; - } - goto process_precision; - - case '*': - precision = va_arg(ap, int); - goto process_precision; - - case '.': - if (width < 0) - width = 0; - goto reswitch; - - case '#': - altflag = 1; - goto reswitch; - - process_precision: - if (width < 0) - width = precision, precision = -1; - goto reswitch; - - // long flag (doubled for long long) - case 'l': - lflag++; - goto reswitch; - - // character - case 'c': - putch(va_arg(ap, int), putdat); - break; - - // string - case 's': - if ((p = va_arg(ap, char *)) == NULL) - p = "(null)"; - if (width > 0 && padc != '-') - for (width -= strnlen(p, precision); width > 0; width--) - putch(padc, putdat); - for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) { - putch(ch, putdat); - p++; - } - for (; width > 0; width--) - putch(' ', putdat); - break; - - // (signed) decimal - case 'd': - num = getint(&ap, lflag); - if ((long long) num < 0) { - putch('-', putdat); - num = -(long long) num; - } - base = 10; - goto signed_number; - - // unsigned decimal - case 'u': - base = 10; - goto unsigned_number; - - // (unsigned) octal - case 'o': - // should do something with padding so it's always 3 octits - base = 8; - goto unsigned_number; - - // pointer - case 'p': - static_assert(sizeof(long) == sizeof(void*)); - lflag = 1; - putch('0', putdat); - putch('x', putdat); - /* fall through to 'x' */ - - // (unsigned) hexadecimal - case 'x': - base = 16; - unsigned_number: - num = getuint(&ap, lflag); - signed_number: - printnum(putch, putdat, num, base, width, padc); - break; - - // escaped '%' character - case '%': - putch(ch, putdat); - break; - - // unrecognized escape sequence - just print it literally - default: - putch('%', putdat); - fmt = last_fmt; - break; + register const char *p; + const char *last_fmt; + register int ch, err; + unsigned long long num; + int base, lflag, width, precision, altflag; + char padc; + + while (1) { + while ((ch = *(unsigned char *)fmt) != '%') { + if (ch == '\0') return; + fmt++; + putch(ch, putdat); + } + fmt++; + + // Process a %-escape sequence + last_fmt = fmt; + padc = ' '; + width = -1; + precision = -1; + lflag = 0; + altflag = 0; +reswitch: + switch (ch = *(unsigned char *)fmt++) { + + // flag to pad on the right + case '-': padc = '-'; goto reswitch; + + // flag to pad with 0's instead of spaces + case '0': padc = '0'; goto reswitch; + + // width field + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + for (precision = 0;; ++fmt) { + precision = precision * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') break; + } + goto process_precision; + + case '*': precision = va_arg(ap, int); goto process_precision; + + case '.': + if (width < 0) width = 0; + goto reswitch; + + case '#': + altflag = 1; + goto reswitch; + +process_precision: + if (width < 0) width = precision, precision = -1; + goto reswitch; + + // long flag (doubled for long long) + case 'l': lflag++; goto reswitch; + + // character + case 'c': putch(va_arg(ap, int), putdat); break; + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) p = "(null)"; + if (width > 0 && padc != '-') + for (width -= strnlen(p, precision); width > 0; width--) + putch(padc, putdat); + for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) { + putch(ch, putdat); + p++; + } + for (; width > 0; width--) + putch(' ', putdat); + break; + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + if ((long long)num < 0) { + putch('-', putdat); + num = -(long long)num; + } + base = 10; + goto signed_number; + + // unsigned decimal + case 'u': base = 10; goto unsigned_number; + + // (unsigned) octal + case 'o': + // should do something with padding so it's always 3 octits + base = 8; + goto unsigned_number; + + // pointer + case 'p': + static_assert(sizeof(long) == sizeof(void *)); + lflag = 1; + putch('0', putdat); + putch('x', putdat); + /* fall through to 'x' */ + + // (unsigned) hexadecimal + case 'x': + base = 16; +unsigned_number: + num = getuint(&ap, lflag); +signed_number: + printnum(putch, putdat, num, base, width, padc); + break; + + // escaped '%' character + case '%': putch(ch, putdat); break; + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + fmt = last_fmt; + break; + } } - } } -int printf(const char* fmt, ...) +int printf(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); + va_list ap; + va_start(ap, fmt); - vprintfmt((void*)putchar, 0, fmt, ap); + vprintfmt((void *)putchar, 0, fmt, ap); - va_end(ap); - return 0; // incorrect return value, but who cares, anyway? + va_end(ap); + return 0; // incorrect return value, but who cares, anyway? } -int sprintf(char* str, const char* fmt, ...) +int sprintf(char *str, const char *fmt, ...) { - va_list ap; - char* str0 = str; - va_start(ap, fmt); - - void sprintf_putch(int ch, void** data) - { - char** pstr = (char**)data; - **pstr = ch; - (*pstr)++; - } - - vprintfmt(sprintf_putch, (void**)&str, fmt, ap); - *str = 0; - - va_end(ap); - return str - str0; + va_list ap; + char *str0 = str; + va_start(ap, fmt); + + void sprintf_putch(int ch, void **data) + { + char **pstr = (char **)data; + **pstr = ch; + (*pstr)++; + } + + vprintfmt(sprintf_putch, (void **)&str, fmt, ap); + *str = 0; + + va_end(ap); + return str - str0; } -void* memcpy(void* dest, const void* src, size_t len) +void *memcpy(void *dest, const void *src, size_t len) { - if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) { - const uintptr_t* s = src; - uintptr_t *d = dest; - while (d < (uintptr_t*)(dest + len)) - *d++ = *s++; - } else { - const char* s = src; - char *d = dest; - while (d < (char*)(dest + len)) - *d++ = *s++; - } - return dest; + if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t) - 1)) == 0) { + const uintptr_t *s = src; + uintptr_t *d = dest; + while (d < (uintptr_t *)(dest + len)) + *d++ = *s++; + } + else { + const char *s = src; + char *d = dest; + while (d < (char *)(dest + len)) + *d++ = *s++; + } + return dest; } -void* memset(void* dest, int byte, size_t len) +void *memset(void *dest, int byte, size_t len) { - if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) { - uintptr_t word = byte & 0xFF; - word |= word << 8; - word |= word << 16; - word |= word << 16 << 16; - - uintptr_t *d = dest; - while (d < (uintptr_t*)(dest + len)) - *d++ = word; - } else { - char *d = dest; - while (d < (char*)(dest + len)) - *d++ = byte; - } - return dest; + if ((((uintptr_t)dest | len) & (sizeof(uintptr_t) - 1)) == 0) { + uintptr_t word = byte & 0xFF; + word |= word << 8; + word |= word << 16; + word |= word << 16 << 16; + + uintptr_t *d = dest; + while (d < (uintptr_t *)(dest + len)) + *d++ = word; + } + else { + char *d = dest; + while (d < (char *)(dest + len)) + *d++ = byte; + } + return dest; } size_t strlen(const char *s) { - const char *p = s; - while (*p) - p++; - return p - s; + const char *p = s; + while (*p) + p++; + return p - s; } size_t strnlen(const char *s, size_t n) { - const char *p = s; - while (n-- && *p) - p++; - return p - s; + const char *p = s; + while (n-- && *p) + p++; + return p - s; } -int strcmp(const char* s1, const char* s2) +int strcmp(const char *s1, const char *s2) { - unsigned char c1, c2; + unsigned char c1, c2; - do { - c1 = *s1++; - c2 = *s2++; - } while (c1 != 0 && c1 == c2); + do { + c1 = *s1++; + c2 = *s2++; + } while (c1 != 0 && c1 == c2); - return c1 - c2; + return c1 - c2; } -char* strcpy(char* dest, const char* src) +char *strcpy(char *dest, const char *src) { - char* d = dest; - while ((*d++ = *src++)) - ; - return dest; + char *d = dest; + while ((*d++ = *src++)) + ; + return dest; } -long atol(const char* str) +long atol(const char *str) { - long res = 0; - int sign = 0; + long res = 0; + int sign = 0; - while (*str == ' ') - str++; + while (*str == ' ') + str++; - if (*str == '-' || *str == '+') { - sign = *str == '-'; - str++; - } + if (*str == '-' || *str == '+') { + sign = *str == '-'; + str++; + } - while (*str) { - res *= 10; - res += *str++ - '0'; - } + while (*str) { + res *= 10; + res += *str++ - '0'; + } - return sign ? -res : res; + return sign ? -res : res; } diff --git a/soft/common/apps/baremetal/fft_monitors/fft_monitors.c b/soft/common/apps/baremetal/fft_monitors/fft_monitors.c index f266316887..4576b6922c 100644 --- a/soft/common/apps/baremetal/fft_monitors/fft_monitors.c +++ b/soft/common/apps/baremetal/fft_monitors/fft_monitors.c @@ -3,37 +3,33 @@ #include #ifndef __riscv -#include + #include #endif +#include "monitors.h" +#include "utils/fft_utils.h" #include #include -#include "utils/fft_utils.h" -#include "monitors.h" #if (FFT_FX_WIDTH == 64) typedef long long token_t; typedef double native_t; -#define fx2float fixed64_to_double -#define float2fx double_to_fixed64 -#define FX_IL 42 + #define fx2float fixed64_to_double + #define float2fx double_to_fixed64 + #define FX_IL 42 #else // (FFT_FX_WIDTH == 32) typedef int token_t; typedef float native_t; -#define fx2float fixed32_to_float -#define float2fx float_to_fixed32 -#define FX_IL 12 + #define fx2float fixed32_to_float + #define float2fx float_to_fixed32 + #define FX_IL 12 #endif /* FFT_FX_WIDTH */ const float ERR_TH = 0.05; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } - -#define SLD_FFT 0x059 +#define SLD_FFT 0x059 #define DEV_NAME "sld,fft_stratus" /* <<--params-->> */ @@ -52,204 +48,195 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ -#define FFT_DO_PEAK_REG 0x48 +#define FFT_DO_PEAK_REG 0x48 #define FFT_DO_BITREV_REG 0x44 -#define FFT_LOG_LEN_REG 0x40 - +#define FFT_LOG_LEN_REG 0x40 static int validate_buf(token_t *out, float *gold) { - int j; - unsigned errors = 0; + int j; + unsigned errors = 0; - for (j = 0; j < 2 * len; j++) { - native_t val = fx2float(out[j], FX_IL); - if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) - errors++; - } + for (j = 0; j < 2 * len; j++) { + native_t val = fx2float(out[j], FX_IL); + if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) errors++; + } - //printf(" %u errors\n", errors); - return errors; + // printf(" %u errors\n", errors); + return errors; } - static void init_buf(token_t *in, float *gold) { - int j; - const float LO = -10.0; - const float HI = 10.0; + int j; + const float LO = -10.0; + const float HI = 10.0; - /* srand((unsigned int) time(NULL)); */ + /* srand((unsigned int) time(NULL)); */ - for (j = 0; j < 2 * len; j++) { - float scaling_factor = (float) rand () / (float) RAND_MAX; - gold[j] = LO + scaling_factor * (HI - LO); - } + for (j = 0; j < 2 * len; j++) { + float scaling_factor = (float)rand() / (float)RAND_MAX; + gold[j] = LO + scaling_factor * (HI - LO); + } - // preprocess with bitreverse (fast in software anyway) - if (!do_bitrev) - fft_bit_reverse(gold, len, log_len); + // preprocess with bitreverse (fast in software anyway) + if (!do_bitrev) fft_bit_reverse(gold, len, log_len); - // convert input to fixed point - for (j = 0; j < 2 * len; j++) - in[j] = float2fx((native_t) gold[j], FX_IL); + // convert input to fixed point + for (j = 0; j < 2 * len; j++) + in[j] = float2fx((native_t)gold[j], FX_IL); - - // Compute golden output - fft_comp(gold, len, log_len, -1, do_bitrev); + // Compute golden output + fft_comp(gold, len, log_len, -1, do_bitrev); } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable = NULL; - token_t *mem; - float *gold; - unsigned errors = 0; - unsigned coherence; - const int ERROR_COUNT_TH = 0.001; - - len = 1 << log_len; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * len; - out_words_adj = 2 * len; - } else { - in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = 0; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_FFT, DEV_NAME); - if (ndev == 0) { - printf("fft not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - printf("**************** %s.%d ****************\n", DEV_NAME, n); - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_len * sizeof(float)); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - - // Allocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable = NULL; + token_t *mem; + float *gold; + unsigned errors = 0; + unsigned coherence; + const int ERROR_COUNT_TH = 0.001; + + len = 1 << log_len; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * len; + out_words_adj = 2 * len; + } + else { + in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = 0; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_FFT, DEV_NAME); + if (ndev == 0) { + printf("fft not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + printf("**************** %s.%d ****************\n", DEV_NAME, n); + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_len * sizeof(float)); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); + + // Allocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_FULL; coherence++) { #else - { - coherence = ACC_COH_NONE; + { + coherence = ACC_COH_NONE; #endif - printf(" --------------------\n"); - printf(" Generate input...\n"); - init_buf(mem, gold); - - // Pass common configuration parameters - - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); - - iowrite32(dev, PT_ADDRESS_REG, (unsigned long) ptable); - - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - iowrite32(dev, FFT_DO_PEAK_REG, 0); - iowrite32(dev, FFT_DO_BITREV_REG, do_bitrev); - iowrite32(dev, FFT_LOG_LEN_REG, log_len); - - esp_monitor_args_t mon_args; - mon_args.read_mode = ESP_MON_READ_ALL; - - //declare monitor structures and capture start values - esp_monitor_vals_t vals_start, vals_end, vals_diff; - esp_monitor(mon_args, &vals_start); - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - //capture end values and compute difference - esp_monitor(mon_args, &vals_end); - vals_diff = esp_monitor_diff(vals_start, vals_end); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - if ((errors / len) > ERROR_COUNT_TH) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - - //dump monitor statistics - esp_monitor_print(mon_args, vals_diff); - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + printf(" --------------------\n"); + printf(" Generate input...\n"); + init_buf(mem, gold); + + // Pass common configuration parameters + + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); + + iowrite32(dev, PT_ADDRESS_REG, (unsigned long)ptable); + + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + iowrite32(dev, FFT_DO_PEAK_REG, 0); + iowrite32(dev, FFT_DO_BITREV_REG, do_bitrev); + iowrite32(dev, FFT_LOG_LEN_REG, log_len); + + esp_monitor_args_t mon_args; + mon_args.read_mode = ESP_MON_READ_ALL; + + // declare monitor structures and capture start values + esp_monitor_vals_t vals_start, vals_end, vals_diff; + esp_monitor(mon_args, &vals_start); + + // Flush (customize coherence model here) + esp_flush(coherence); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + // capture end values and compute difference + esp_monitor(mon_args, &vals_end); + vals_diff = esp_monitor_diff(vals_start, vals_end); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + if ((errors / len) > ERROR_COUNT_TH) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + + // dump monitor statistics + esp_monitor_print(mon_args, vals_diff); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/soft/common/apps/baremetal/jtag_reg_rw/jtag_reg_rw.c b/soft/common/apps/baremetal/jtag_reg_rw/jtag_reg_rw.c index 0093d497fa..ad10bf7b13 100644 --- a/soft/common/apps/baremetal/jtag_reg_rw/jtag_reg_rw.c +++ b/soft/common/apps/baremetal/jtag_reg_rw/jtag_reg_rw.c @@ -21,40 +21,39 @@ * not all registers are readable, and that you may be overwriting important * configuration parameters. Make sure you consult the tile CSRs source code * in `rtl/sockets/crs`. - * - Ser CSR_VAL to the expected value in the read-only mode, and to the value + * - Ser CSR_VAL to the expected value in the read-only mode, and to the value * to be written in the write&read mode. */ #include #ifndef __riscv -#include + #include #endif +#include "jtag_reg_rw.h" #include #include -#include "jtag_reg_rw.h" - // CSR offset -#define CSR_BASE_ADDR 0x60090180 +#define CSR_BASE_ADDR 0x60090180 #define CSR_TILE_OFFSET 0x200 -#define TILE_ID 0 +#define TILE_ID 0 // example 1: 1 for read-only (value: TILE_ID), 1 for write&read (any value, e.g. 3) // example 2: 8 for read-only (value: 0x2af13ff4), 8 for write&read (any value, 0x2bf13ff4) #define CSR_REG_OFFSET 8 -#define CSR_TILE_ADDR (CSR_BASE_ADDR + CSR_TILE_OFFSET * TILE_ID) +#define CSR_TILE_ADDR (CSR_BASE_ADDR + CSR_TILE_OFFSET * TILE_ID) // CSR value #define CSR_VAL 0x2bf13ff4 // Accelerator registers offset -#define ACCREG_BASE_ADDR 0x60010000 +#define ACCREG_BASE_ADDR 0x60010000 #define ACCREG_TILE_OFFSET 0x100 -#define ACC_ID 0 +#define ACC_ID 0 // example: 7 for read-only (value: data_size in xml of accelerator, e.g. 4 for FFT2) // 16 for write&read (any value, e.g. 12345678) #define ACCREG_REG_OFFSET 7 -#define ACCREG_TILE_ADDR (ACCREG_BASE_ADDR + ACCREG_TILE_OFFSET * ACC_ID) +#define ACCREG_TILE_ADDR (ACCREG_BASE_ADDR + ACCREG_TILE_OFFSET * ACC_ID) // Accelerator register value #define ACCREG_VAL 4 @@ -63,7 +62,7 @@ const int test_type = 1; // 0 = CSR read only, 1 = CSR write&read // 2 = acc reg read only, 3 = acc reg write&read -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { int i; unsigned offset, val, csr_val; @@ -71,26 +70,24 @@ int main(int argc, char * argv[]) // Set test configuration either for CSR or for accelerator registers if (test_type <= 1) { - dev.addr = CSR_TILE_ADDR; - offset = CSR_REG_OFFSET; - val = CSR_VAL; - } else { - dev.addr = ACCREG_TILE_ADDR; - offset = ACCREG_REG_OFFSET; - val = ACCREG_VAL; + dev.addr = CSR_TILE_ADDR; + offset = CSR_REG_OFFSET; + val = CSR_VAL; + } + else { + dev.addr = ACCREG_TILE_ADDR; + offset = ACCREG_REG_OFFSET; + val = ACCREG_VAL; } // Write - if (test_type == 1 || test_type == 3) { - iowrite32(&dev, offset * 4, val); - } + if (test_type == 1 || test_type == 3) { iowrite32(&dev, offset * 4, val); } // Read - csr_val = ioread32(&dev, offset * 4); - if (csr_val != val) - printf("[ERROR] Expected : %u, read : %u.\n", val, csr_val); + csr_val = ioread32(&dev, offset * 4); + if (csr_val != val) printf("[ERROR] Expected : %u, read : %u.\n", val, csr_val); else - printf("Test PASSED!\n"); + printf("Test PASSED!\n"); return 0; } diff --git a/soft/common/apps/baremetal/nv_nvdla_coh/nv_nvdla_coh.c b/soft/common/apps/baremetal/nv_nvdla_coh/nv_nvdla_coh.c index cce772277b..1d3a98d0cb 100644 --- a/soft/common/apps/baremetal/nv_nvdla_coh/nv_nvdla_coh.c +++ b/soft/common/apps/baremetal/nv_nvdla_coh/nv_nvdla_coh.c @@ -3,26 +3,21 @@ #include #ifndef __riscv -#include + #include #endif #include #include #include - typedef unsigned long long int token_t; typedef unsigned long long int native_t; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } #define MAX_PRINTED_ERRORS 10 - -#define NV_NVDLA 0x100 +#define NV_NVDLA 0x100 #define DEV_NAME "nvidia,nv_small" #define CSR_TILE_SIZE 0x200 @@ -40,308 +35,294 @@ static unsigned out_offset; static int validate_buf(token_t *out, native_t *gold) { - int j; - native_t val; - unsigned errors = 0; - - for (j = 0; j < out_len; j++) { - val = out[j]; - - if (gold[j] != val) { - errors++; - if (errors <= MAX_PRINTED_ERRORS) { - printf("%d : %llu : %llu\n", j, val, gold[j]); - } - } - } - - return errors; + int j; + native_t val; + unsigned errors = 0; + + for (j = 0; j < out_len; j++) { + val = out[j]; + + if (gold[j] != val) { + errors++; + if (errors <= MAX_PRINTED_ERRORS) { printf("%d : %llu : %llu\n", j, val, gold[j]); } + } + } + + return errors; } -static void init_buf (token_t *in, native_t * gold) +static void init_buf(token_t *in, native_t *gold) { -#include "input.h" #include "gold.h" +#include "input.h" } -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - token_t *mem; - native_t *gold; - unsigned errors = 0; - unsigned coherence; - unsigned error_id; - unsigned read_val; - unsigned int coh; - unsigned int tile_offset; - unsigned int* coh_reg_addr; - - //change this depending on the SoC layout and number of NVDLA instances - unsigned int nvdla_tile_numbers[1] = {2}; - i_base = 0x200; - w_base = 0x000; - b_base = 0x280; - o_base = 0x400; - mem_size = 0x500; - - out_len = 12; - out_size = 12 * sizeof(native_t); - out_offset = o_base / sizeof(native_t); - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, NV_NVDLA, DEV_NAME); - if (ndev == 0) { - printf("nv_nvdla not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - dev = &espdevs[n]; - - // Allocation of the accelerator data array (mem) and of the expected output array (gold) - mem = aligned_malloc(mem_size); - gold = aligned_malloc(out_size); - printf(" memory buffer base-address = %p\n", mem); - printf(" memory buffer base-address for gold = %p\n", gold); - - printf(" Generate input...\n"); - - init_buf(mem, gold); - - // Write coherence mode and flush (customize coherence model here) - tile_offset = (CSR_TILE_SIZE / sizeof(unsigned int)) * nvdla_tile_numbers[n]; - coh_reg_addr = ((unsigned int*) CSR_BASE_ADDR) + tile_offset + COH_REG_INDEX; - coh = ACC_COH_RECALL; - *coh_reg_addr = coh; - esp_flush(coh); - - // Write the accelerator configuration registers - - error_id = 0; - - //read_val = ioread32(dev, 28676); - //if (read_val != 1 && read_val != 65536) - // printf("error %u\n", error_id); - //error_id++; - - iowrite32(dev, 28676, 0); - iowrite32(dev, 20484, 0); - iowrite32(dev, 24580, 0); - iowrite32(dev, 16388, 0); - iowrite32(dev, 12292, 0); - - read_val = ioread32(dev, 28672); - if (read_val != 0) - printf("error %u\n", error_id); - error_id++; - - read_val = ioread32(dev, 20480); - if (read_val != 0) - printf("error %u\n", error_id); - error_id++; - - read_val = ioread32(dev, 24576); - if (read_val != 0) - printf("error %u\n", error_id); - error_id++; - - read_val = ioread32(dev, 16384); - if (read_val != 0) - printf("error %u\n", error_id); - error_id++; - - read_val = ioread32(dev, 12288); - if (read_val != 0) - printf("error %u\n", error_id); - error_id++; - - iowrite32(dev, 28684, 0); - iowrite32(dev, 28688, 65537); - iowrite32(dev, 28692, 19); - iowrite32(dev, 28696, 0); - iowrite32(dev, 28700, 0); - iowrite32(dev, 28704, 16); - iowrite32(dev, 28708, 32); - iowrite32(dev, 28712, 0); - iowrite32(dev, 28716, 0); - iowrite32(dev, 20492, 0); - iowrite32(dev, 24588, 0); - iowrite32(dev, 16396, 0); - iowrite32(dev, 16400, 0); - iowrite32(dev, 16404, 327685); - iowrite32(dev, 16408, 0); - iowrite32(dev, 16412, 0); - iowrite32(dev, 16416, 0); - iowrite32(dev, 16420, 5); - iowrite32(dev, 16424, 0); - iowrite32(dev, 16428, 262148); - iowrite32(dev, 16432, 1245184); - iowrite32(dev, 16436, 504); - iowrite32(dev, 16440, 0); - iowrite32(dev, 16444, 65537); - iowrite32(dev, 16448, 19); - iowrite32(dev, 16452, 3); - iowrite32(dev, 16456, 5); - iowrite32(dev, 16460, 0); - iowrite32(dev, 16464, 0); - iowrite32(dev, 16468, 0); - iowrite32(dev, 16472, 0); - iowrite32(dev, 16476, 0); - iowrite32(dev, 16480, 0); - iowrite32(dev, 12308, 0); - iowrite32(dev, 12312, 1048576); - iowrite32(dev, 12316, 327685); - iowrite32(dev, 12320, 0); - iowrite32(dev, 12324, 327685); - iowrite32(dev, 12332, 1); - iowrite32(dev, 12336, 0); - iowrite32(dev, 12340, ((uint64_t) mem) + b_base); // 2686488576 - iowrite32(dev, 12344, 0); - iowrite32(dev, 12348, ((uint64_t) mem) + b_base); // 2686488576 - iowrite32(dev, 12352, 48); - iowrite32(dev, 12360, 288); - iowrite32(dev, 12356, 0); - iowrite32(dev, 12364, 65537); - iowrite32(dev, 12376, 0); - iowrite32(dev, 12380, 0); - iowrite32(dev, 12384, 5); - iowrite32(dev, 12388, 0); - iowrite32(dev, 12392, 0); - iowrite32(dev, 12396, 24); - iowrite32(dev, 12400, 19); - iowrite32(dev, 12404, 1); - iowrite32(dev, 12408, 0); - iowrite32(dev, 12412, ((uint64_t) mem) + w_base); // 2686459904 - iowrite32(dev, 12416, 504); - iowrite32(dev, 12440, 0); - iowrite32(dev, 12452, 1); - iowrite32(dev, 12456, 0); - iowrite32(dev, 12460, 1); - iowrite32(dev, 12464, 0); - iowrite32(dev, 12468, 0); - iowrite32(dev, 12472, 0); - iowrite32(dev, 12476, 0); - - //read_val = ioread32(dev, 36868); - //if (read_val != 1 && read_val != 65536) - // printf("error %u\n", error_id); - //error_id++; - - //read_val = ioread32(dev, 32772); - //if (read_val != 1 && read_val != 65536) - // printf("error %u\n", error_id); - //error_id++; - - iowrite32(dev, 36868, 0); - iowrite32(dev, 32772, 0); - - read_val = ioread32(dev, 4100); - if (read_val != 0) - printf("error %u\n", error_id); - error_id++; - - iowrite32(dev, 4100, 0); - iowrite32(dev, 32880, 0); - iowrite32(dev, 32808, 0); - iowrite32(dev, 32832, 0); - iowrite32(dev, 32856, 0); - iowrite32(dev, 32880, 1); - iowrite32(dev, 32780, 1); - iowrite32(dev, 32784, 1); - iowrite32(dev, 32788, 19); - iowrite32(dev, 32808, 44); - iowrite32(dev, 32812, ((uint64_t) mem) + i_base); // 2686464000 - iowrite32(dev, 32816, 0); - iowrite32(dev, 32820, 32); - iowrite32(dev, 32824, 32); - iowrite32(dev, 32832, 49); - iowrite32(dev, 32856, 49); - iowrite32(dev, 36924, 1); - iowrite32(dev, 36928, 1); - iowrite32(dev, 36932, 19); - iowrite32(dev, 36940, 0); - iowrite32(dev, 36936, ((uint64_t) mem) + o_base); // 2686492672 - iowrite32(dev, 36944, 16); - iowrite32(dev, 36948, 32); - iowrite32(dev, 36952, 72); - iowrite32(dev, 36956, 1); - iowrite32(dev, 36964, 6145); - iowrite32(dev, 36972, 83); - iowrite32(dev, 36992, 83); - iowrite32(dev, 37040, 1); - iowrite32(dev, 37044, 1); - iowrite32(dev, 37052, 0); - iowrite32(dev, 37056, 0); - iowrite32(dev, 37060, 1); - iowrite32(dev, 37064, 0); - iowrite32(dev, 36868, 0); - iowrite32(dev, 32772, 0); - iowrite32(dev, 32776, 1); - iowrite32(dev, 36920, 1); - iowrite32(dev, 28676, 0); - iowrite32(dev, 20484, 0); - iowrite32(dev, 24580, 0); - iowrite32(dev, 16388, 0); - iowrite32(dev, 12292, 0); - - read_val = ioread32(dev, 12300); - if (read_val != 1) - printf("error %u\n", error_id); - error_id++; - - iowrite32(dev, 28680, 1); - iowrite32(dev, 20488, 1); - iowrite32(dev, 24584, 1); - iowrite32(dev, 16392, 1); - iowrite32(dev, 12304, 1); - - for (i = 0; i < 10; ++i) - printf("wait...\n"); - - read_val = ioread32(dev, 4100); - if (read_val != 0) - printf("error %u\n", error_id); - error_id++; - - read_val = ioread32(dev, 4108); - if (read_val != 1376257 && read_val != 2752514) - printf("error %u\n", error_id); - error_id++; - iowrite32(dev, 4108, read_val); - - read_val = ioread32(dev, 4100); - if (read_val != 0) - printf("error %u\n", error_id); - error_id++; - - read_val = ioread32(dev, 4108); - if (read_val != 0) - printf("error %u\n", error_id); - error_id++; - - printf(" Done\n"); - - /* Validation */ - printf(" validating...\n"); - errors = validate_buf(&mem[out_offset], gold); - - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - - aligned_free(mem); - aligned_free(gold); - } - - return 0; + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + token_t *mem; + native_t *gold; + unsigned errors = 0; + unsigned coherence; + unsigned error_id; + unsigned read_val; + unsigned int coh; + unsigned int tile_offset; + unsigned int *coh_reg_addr; + + // change this depending on the SoC layout and number of NVDLA instances + unsigned int nvdla_tile_numbers[1] = {2}; + i_base = 0x200; + w_base = 0x000; + b_base = 0x280; + o_base = 0x400; + mem_size = 0x500; + + out_len = 12; + out_size = 12 * sizeof(native_t); + out_offset = o_base / sizeof(native_t); + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, NV_NVDLA, DEV_NAME); + if (ndev == 0) { + printf("nv_nvdla not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + dev = &espdevs[n]; + + // Allocation of the accelerator data array (mem) and of the expected output array (gold) + mem = aligned_malloc(mem_size); + gold = aligned_malloc(out_size); + printf(" memory buffer base-address = %p\n", mem); + printf(" memory buffer base-address for gold = %p\n", gold); + + printf(" Generate input...\n"); + + init_buf(mem, gold); + + // Write coherence mode and flush (customize coherence model here) + tile_offset = (CSR_TILE_SIZE / sizeof(unsigned int)) * nvdla_tile_numbers[n]; + coh_reg_addr = ((unsigned int *)CSR_BASE_ADDR) + tile_offset + COH_REG_INDEX; + coh = ACC_COH_RECALL; + *coh_reg_addr = coh; + esp_flush(coh); + + // Write the accelerator configuration registers + + error_id = 0; + + // read_val = ioread32(dev, 28676); + // if (read_val != 1 && read_val != 65536) + // printf("error %u\n", error_id); + // error_id++; + + iowrite32(dev, 28676, 0); + iowrite32(dev, 20484, 0); + iowrite32(dev, 24580, 0); + iowrite32(dev, 16388, 0); + iowrite32(dev, 12292, 0); + + read_val = ioread32(dev, 28672); + if (read_val != 0) printf("error %u\n", error_id); + error_id++; + + read_val = ioread32(dev, 20480); + if (read_val != 0) printf("error %u\n", error_id); + error_id++; + + read_val = ioread32(dev, 24576); + if (read_val != 0) printf("error %u\n", error_id); + error_id++; + + read_val = ioread32(dev, 16384); + if (read_val != 0) printf("error %u\n", error_id); + error_id++; + + read_val = ioread32(dev, 12288); + if (read_val != 0) printf("error %u\n", error_id); + error_id++; + + iowrite32(dev, 28684, 0); + iowrite32(dev, 28688, 65537); + iowrite32(dev, 28692, 19); + iowrite32(dev, 28696, 0); + iowrite32(dev, 28700, 0); + iowrite32(dev, 28704, 16); + iowrite32(dev, 28708, 32); + iowrite32(dev, 28712, 0); + iowrite32(dev, 28716, 0); + iowrite32(dev, 20492, 0); + iowrite32(dev, 24588, 0); + iowrite32(dev, 16396, 0); + iowrite32(dev, 16400, 0); + iowrite32(dev, 16404, 327685); + iowrite32(dev, 16408, 0); + iowrite32(dev, 16412, 0); + iowrite32(dev, 16416, 0); + iowrite32(dev, 16420, 5); + iowrite32(dev, 16424, 0); + iowrite32(dev, 16428, 262148); + iowrite32(dev, 16432, 1245184); + iowrite32(dev, 16436, 504); + iowrite32(dev, 16440, 0); + iowrite32(dev, 16444, 65537); + iowrite32(dev, 16448, 19); + iowrite32(dev, 16452, 3); + iowrite32(dev, 16456, 5); + iowrite32(dev, 16460, 0); + iowrite32(dev, 16464, 0); + iowrite32(dev, 16468, 0); + iowrite32(dev, 16472, 0); + iowrite32(dev, 16476, 0); + iowrite32(dev, 16480, 0); + iowrite32(dev, 12308, 0); + iowrite32(dev, 12312, 1048576); + iowrite32(dev, 12316, 327685); + iowrite32(dev, 12320, 0); + iowrite32(dev, 12324, 327685); + iowrite32(dev, 12332, 1); + iowrite32(dev, 12336, 0); + iowrite32(dev, 12340, ((uint64_t)mem) + b_base); // 2686488576 + iowrite32(dev, 12344, 0); + iowrite32(dev, 12348, ((uint64_t)mem) + b_base); // 2686488576 + iowrite32(dev, 12352, 48); + iowrite32(dev, 12360, 288); + iowrite32(dev, 12356, 0); + iowrite32(dev, 12364, 65537); + iowrite32(dev, 12376, 0); + iowrite32(dev, 12380, 0); + iowrite32(dev, 12384, 5); + iowrite32(dev, 12388, 0); + iowrite32(dev, 12392, 0); + iowrite32(dev, 12396, 24); + iowrite32(dev, 12400, 19); + iowrite32(dev, 12404, 1); + iowrite32(dev, 12408, 0); + iowrite32(dev, 12412, ((uint64_t)mem) + w_base); // 2686459904 + iowrite32(dev, 12416, 504); + iowrite32(dev, 12440, 0); + iowrite32(dev, 12452, 1); + iowrite32(dev, 12456, 0); + iowrite32(dev, 12460, 1); + iowrite32(dev, 12464, 0); + iowrite32(dev, 12468, 0); + iowrite32(dev, 12472, 0); + iowrite32(dev, 12476, 0); + + // read_val = ioread32(dev, 36868); + // if (read_val != 1 && read_val != 65536) + // printf("error %u\n", error_id); + // error_id++; + + // read_val = ioread32(dev, 32772); + // if (read_val != 1 && read_val != 65536) + // printf("error %u\n", error_id); + // error_id++; + + iowrite32(dev, 36868, 0); + iowrite32(dev, 32772, 0); + + read_val = ioread32(dev, 4100); + if (read_val != 0) printf("error %u\n", error_id); + error_id++; + + iowrite32(dev, 4100, 0); + iowrite32(dev, 32880, 0); + iowrite32(dev, 32808, 0); + iowrite32(dev, 32832, 0); + iowrite32(dev, 32856, 0); + iowrite32(dev, 32880, 1); + iowrite32(dev, 32780, 1); + iowrite32(dev, 32784, 1); + iowrite32(dev, 32788, 19); + iowrite32(dev, 32808, 44); + iowrite32(dev, 32812, ((uint64_t)mem) + i_base); // 2686464000 + iowrite32(dev, 32816, 0); + iowrite32(dev, 32820, 32); + iowrite32(dev, 32824, 32); + iowrite32(dev, 32832, 49); + iowrite32(dev, 32856, 49); + iowrite32(dev, 36924, 1); + iowrite32(dev, 36928, 1); + iowrite32(dev, 36932, 19); + iowrite32(dev, 36940, 0); + iowrite32(dev, 36936, ((uint64_t)mem) + o_base); // 2686492672 + iowrite32(dev, 36944, 16); + iowrite32(dev, 36948, 32); + iowrite32(dev, 36952, 72); + iowrite32(dev, 36956, 1); + iowrite32(dev, 36964, 6145); + iowrite32(dev, 36972, 83); + iowrite32(dev, 36992, 83); + iowrite32(dev, 37040, 1); + iowrite32(dev, 37044, 1); + iowrite32(dev, 37052, 0); + iowrite32(dev, 37056, 0); + iowrite32(dev, 37060, 1); + iowrite32(dev, 37064, 0); + iowrite32(dev, 36868, 0); + iowrite32(dev, 32772, 0); + iowrite32(dev, 32776, 1); + iowrite32(dev, 36920, 1); + iowrite32(dev, 28676, 0); + iowrite32(dev, 20484, 0); + iowrite32(dev, 24580, 0); + iowrite32(dev, 16388, 0); + iowrite32(dev, 12292, 0); + + read_val = ioread32(dev, 12300); + if (read_val != 1) printf("error %u\n", error_id); + error_id++; + + iowrite32(dev, 28680, 1); + iowrite32(dev, 20488, 1); + iowrite32(dev, 24584, 1); + iowrite32(dev, 16392, 1); + iowrite32(dev, 12304, 1); + + for (i = 0; i < 10; ++i) + printf("wait...\n"); + + read_val = ioread32(dev, 4100); + if (read_val != 0) printf("error %u\n", error_id); + error_id++; + + read_val = ioread32(dev, 4108); + if (read_val != 1376257 && read_val != 2752514) printf("error %u\n", error_id); + error_id++; + iowrite32(dev, 4108, read_val); + + read_val = ioread32(dev, 4100); + if (read_val != 0) printf("error %u\n", error_id); + error_id++; + + read_val = ioread32(dev, 4108); + if (read_val != 0) printf("error %u\n", error_id); + error_id++; + + printf(" Done\n"); + + /* Validation */ + printf(" validating...\n"); + errors = validate_buf(&mem[out_offset], gold); + + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/soft/common/apps/baremetal/slm_rw_test/slm_rw_test.c b/soft/common/apps/baremetal/slm_rw_test/slm_rw_test.c index 13e5d48eda..854eb3ccb1 100644 --- a/soft/common/apps/baremetal/slm_rw_test/slm_rw_test.c +++ b/soft/common/apps/baremetal/slm_rw_test/slm_rw_test.c @@ -8,56 +8,48 @@ int main(int argc, char **argv) { printf("Testing SLM tile with CPU writes/reads...\n\n"); - char* slm_base_0 = (char *) 0x04000000; - for (int i = 0; i < SIZE; i++) - slm_base_0[i] = i; + char *slm_base_0 = (char *)0x04000000; + for (int i = 0; i < SIZE; i++) + slm_base_0[i] = i; int tot_errors = 0; - int errors = 0; - for (int i = 0; i < SIZE; i++) - if (slm_base_0[i] != i) - errors++; - tot_errors += errors; - if (errors) - printf("char errors: %d\n", errors); - - short* slm_base_1 = (short *) 0x04001000; - for (int i = 0; i < SIZE; i++) - slm_base_1[i] = i; - - errors = 0; - for (int i = 0; i < SIZE; i++) - if (slm_base_1[i] != i) - errors++; - tot_errors += errors; - if (errors) - printf("short errors: %d\n", errors); - - int* slm_base_2 = (int *) 0x04002000; - for (int i = 0; i < SIZE; i++) - slm_base_2[i] = i; - - errors = 0; - for (int i = 0; i < SIZE; i++) - if (slm_base_2[i] != i) - errors++; - tot_errors += errors; - if (errors) - printf("int errors: %d\n", errors); - - long long* slm_base_3 = (long long *) 0x04003000; - for (int i = 0; i < SIZE; i++) - slm_base_3[i] = i; - - errors = 0; - for (int i = 0; i < SIZE; i++) - if (slm_base_3[i] != i) - errors++; - tot_errors += errors; - if (errors) - printf("ll errors: %d\n", errors); - - printf("Completed with %d errors\n", tot_errors); + int errors = 0; + for (int i = 0; i < SIZE; i++) + if (slm_base_0[i] != i) errors++; + tot_errors += errors; + if (errors) printf("char errors: %d\n", errors); + + short *slm_base_1 = (short *)0x04001000; + for (int i = 0; i < SIZE; i++) + slm_base_1[i] = i; + + errors = 0; + for (int i = 0; i < SIZE; i++) + if (slm_base_1[i] != i) errors++; + tot_errors += errors; + if (errors) printf("short errors: %d\n", errors); + + int *slm_base_2 = (int *)0x04002000; + for (int i = 0; i < SIZE; i++) + slm_base_2[i] = i; + + errors = 0; + for (int i = 0; i < SIZE; i++) + if (slm_base_2[i] != i) errors++; + tot_errors += errors; + if (errors) printf("int errors: %d\n", errors); + + long long *slm_base_3 = (long long *)0x04003000; + for (int i = 0; i < SIZE; i++) + slm_base_3[i] = i; + + errors = 0; + for (int i = 0; i < SIZE; i++) + if (slm_base_3[i] != i) errors++; + tot_errors += errors; + if (errors) printf("ll errors: %d\n", errors); + + printf("Completed with %d errors\n", tot_errors); return 0; } diff --git a/soft/common/apps/examples/multifft/multifft.c b/soft/common/apps/examples/multifft/multifft.c index 52e4a4fced..36f994dc88 100644 --- a/soft/common/apps/examples/multifft/multifft.c +++ b/soft/common/apps/examples/multifft/multifft.c @@ -18,232 +18,224 @@ const float ERR_TH = 0.05; /* User-defined code */ static int validate_buffer(token_t *out, float *gold) { - int j; - unsigned errors = 0; - int total; + int j; + unsigned errors = 0; + int total; - total = 2 * len; + total = 2 * len; - for (j = 0; j < total; j++) { - native_t val = fx2float(out[j], FX_IL); - if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) - errors++; - } + for (j = 0; j < total; j++) { + native_t val = fx2float(out[j], FX_IL); + if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) errors++; + } - printf(" + Relative error > %.02f for %d output values out of %d\n", ERR_TH, errors, total); + printf(" + Relative error > %.02f for %d output values out of %d\n", ERR_TH, errors, total); - return errors; + return errors; } - /* User-defined code */ static void init_buffer(token_t *in, float *gold, bool p2p) { - int j, p, iters; - const float LO = -1.0; - const float HI = 1.0; - - srand((unsigned int) time(NULL)); - - /* Repeat FFT for NACC times on the same memory region */ - if (p2p) - iters = NACC; - else - iters = 1; - - for (j = 0; j < 2 * len; j++) { - float scaling_factor = (float) rand () / (float) RAND_MAX; - gold[j] = LO + scaling_factor * (HI - LO); - } - - // convert input to fixed point - for (j = 0; j < 2 * len; j++) - in[j] = float2fx((native_t) gold[j], FX_IL); - - for (p = 0; p < iters; p++) { - // Compute golden output - fft_comp(gold, len, log_len, -1, DO_BITREV); - } + int j, p, iters; + const float LO = -1.0; + const float HI = 1.0; + + srand((unsigned int)time(NULL)); + + /* Repeat FFT for NACC times on the same memory region */ + if (p2p) iters = NACC; + else + iters = 1; + + for (j = 0; j < 2 * len; j++) { + float scaling_factor = (float)rand() / (float)RAND_MAX; + gold[j] = LO + scaling_factor * (HI - LO); + } + + // convert input to fixed point + for (j = 0; j < 2 * len; j++) + in[j] = float2fx((native_t)gold[j], FX_IL); + + for (p = 0; p < iters; p++) { + // Compute golden output + fft_comp(gold, len, log_len, -1, DO_BITREV); + } } - /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * len; - out_words_adj = 2 * len; - } else { - in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = 0; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * len; + out_words_adj = 2 * len; + } + else { + in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = 0; + size = (out_offset * sizeof(token_t)) + out_size; } - int main(int argc, char **argv) { - int errors; - char key; - - float *gold[3]; - token_t *buf[3]; - - const float ERROR_COUNT_TH = 0.01; - - int k; - - init_parameters(); + int errors; + char key; - for (k = 0; k < NACC; k++) { - buf[k] = (token_t *) esp_alloc(NACC * size); - gold[k] = malloc(NACC * out_len * sizeof(float)); - } + float *gold[3]; + token_t *buf[3]; - init_buffer(buf[0], gold[0], false); + const float ERROR_COUNT_TH = 0.01; - printf("\n====== Non coherent DMA ======\n\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + int k; - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + init_parameters(); - cfg_nc[0].hw_buf = buf[0]; - esp_run(cfg_nc, 1); + for (k = 0; k < NACC; k++) { + buf[k] = (token_t *)esp_alloc(NACC * size); + gold[k] = malloc(NACC * out_len * sizeof(float)); + } - printf("\n ** DONE **\n"); + init_buffer(buf[0], gold[0], false); - errors = validate_buffer(&buf[0][out_offset], gold[0]); + printf("\n====== Non coherent DMA ======\n\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - if (((float) errors / (float) len) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - printf("\n============\n\n"); + cfg_nc[0].hw_buf = buf[0]; + esp_run(cfg_nc, 1); + printf("\n ** DONE **\n"); - /* LLC-Coherent test */ - init_buffer(buf[0], gold[0], false); + errors = validate_buffer(&buf[0][out_offset], gold[0]); - printf("\n====== LLC-coherent DMA ======\n\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + if (((float)errors / (float)len) > ERROR_COUNT_TH) + printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + printf("\n============\n\n"); - cfg_llc[0].hw_buf = buf[0]; - esp_run(cfg_llc, 1); + /* LLC-Coherent test */ + init_buffer(buf[0], gold[0], false); - printf("\n ** DONE **\n"); + printf("\n====== LLC-coherent DMA ======\n\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - errors = validate_buffer(&buf[0][out_offset], gold[0]); + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - if (((float) errors / (float) len) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + cfg_llc[0].hw_buf = buf[0]; + esp_run(cfg_llc, 1); - printf("\n============\n\n"); + printf("\n ** DONE **\n"); + errors = validate_buffer(&buf[0][out_offset], gold[0]); - /* Fully-Coherent test */ - init_buffer(buf[0], gold[0], false); + if (((float)errors / (float)len) > ERROR_COUNT_TH) + printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - printf("\n====== Fully-coherent DMA ======\n\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + printf("\n============\n\n"); - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + /* Fully-Coherent test */ + init_buffer(buf[0], gold[0], false); - cfg_fc[0].hw_buf = buf[0]; - esp_run(cfg_fc, 1); + printf("\n====== Fully-coherent DMA ======\n\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - printf("\n ** DONE **\n"); + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - errors = validate_buffer(&buf[0][out_offset], gold[0]); + cfg_fc[0].hw_buf = buf[0]; + esp_run(cfg_fc, 1); - if (((float) errors / (float) len) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + printf("\n ** DONE **\n"); - printf("\n============\n\n"); + errors = validate_buffer(&buf[0][out_offset], gold[0]); + if (((float)errors / (float)len) > ERROR_COUNT_TH) + printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - /* Parallel test */ - for (k = 0; k < NACC; k++) { - init_buffer(buf[k], gold[k], false); - } + printf("\n============\n\n"); - printf("\n====== Concurrent execution ======\n\n"); - printf(" fft.0 -> fully coherent\n"); - printf(" fft.1 -> LLC-coherent DMA\n"); - printf(" fft.2 -> non-coherent DMA\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + /* Parallel test */ + for (k = 0; k < NACC; k++) { + init_buffer(buf[k], gold[k], false); + } - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + printf("\n====== Concurrent execution ======\n\n"); + printf(" fft.0 -> fully coherent\n"); + printf(" fft.1 -> LLC-coherent DMA\n"); + printf(" fft.2 -> non-coherent DMA\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - for (k = 0; k < NACC; k++) - cfg_parallel[k].hw_buf = buf[k]; + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - esp_run(cfg_parallel, NACC); + for (k = 0; k < NACC; k++) + cfg_parallel[k].hw_buf = buf[k]; - printf("\n ** DONE **\n"); + esp_run(cfg_parallel, NACC); - for (k = 0; k < NACC; k++) { - errors = validate_buffer(&buf[k][out_offset], gold[k]); + printf("\n ** DONE **\n"); - if (((float) errors / (float) (len * NACC)) > ERROR_COUNT_TH) - printf(" + TEST FAIL fft.%d: exceeding error count threshold\n", k); - else - printf(" + TEST PASS fft.%d: not exceeding error count threshold\n", k); - } + for (k = 0; k < NACC; k++) { + errors = validate_buffer(&buf[k][out_offset], gold[k]); - printf("\n============\n\n"); + if (((float)errors / (float)(len * NACC)) > ERROR_COUNT_TH) + printf(" + TEST FAIL fft.%d: exceeding error count threshold\n", k); + else + printf(" + TEST PASS fft.%d: not exceeding error count threshold\n", k); + } + printf("\n============\n\n"); - /* P2P test */ - init_buffer(buf[0], gold[0], true); + /* P2P test */ + init_buffer(buf[0], gold[0], true); - printf("\n====== Point-to-point Test ======\n\n"); - printf(" fft.0 (NC DMA) -> fft.1 -> fft.2 (NC DMA)\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + printf("\n====== Point-to-point Test ======\n\n"); + printf(" fft.0 (NC DMA) -> fft.1 -> fft.2 (NC DMA)\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - for (k = 0; k < NACC; k++) - cfg_p2p[k].hw_buf = buf[0]; + for (k = 0; k < NACC; k++) + cfg_p2p[k].hw_buf = buf[0]; - esp_run(cfg_p2p, NACC); + esp_run(cfg_p2p, NACC); - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - errors = validate_buffer(&buf[0][out_offset], gold[0]); + errors = validate_buffer(&buf[0][out_offset], gold[0]); - if (((float) errors / (float) (len * NACC)) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + if (((float)errors / (float)(len * NACC)) > ERROR_COUNT_TH) + printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - printf("\n============\n\n"); + printf("\n============\n\n"); - for (k = 0; k < NACC; k++) { - free(gold[k]); - esp_free(buf[k]); - } + for (k = 0; k < NACC; k++) { + free(gold[k]); + esp_free(buf[k]); + } - return errors; + return errors; } diff --git a/soft/common/apps/examples/multifft_mon/multifft_mon.c b/soft/common/apps/examples/multifft_mon/multifft_mon.c index baac1825bc..87b3b0759a 100644 --- a/soft/common/apps/examples/multifft_mon/multifft_mon.c +++ b/soft/common/apps/examples/multifft_mon/multifft_mon.c @@ -1,7 +1,7 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include "monitors.h" #include "libesp.h" +#include "monitors.h" #include "multifft_mon_cfg.h" #include "utils/fft_utils.h" @@ -19,323 +19,316 @@ const float ERR_TH = 0.05; /* User-defined code */ static int validate_buffer(token_t *out, float *gold) { - int j; - unsigned errors = 0; - int total; + int j; + unsigned errors = 0; + int total; - total = 2 * len; + total = 2 * len; - for (j = 0; j < total; j++) { - native_t val = fx2float(out[j], FX_IL); - if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) - errors++; - } + for (j = 0; j < total; j++) { + native_t val = fx2float(out[j], FX_IL); + if ((fabs(gold[j] - val) / fabs(gold[j])) > ERR_TH) errors++; + } - printf(" + Relative error > %.02f for %d output values out of %d\n", ERR_TH, errors, total); + printf(" + Relative error > %.02f for %d output values out of %d\n", ERR_TH, errors, total); - return errors; + return errors; } - /* User-defined code */ static void init_buffer(token_t *in, float *gold, bool p2p) { - int j, p, iters; - const float LO = -1.0; - const float HI = 1.0; - - srand((unsigned int) time(NULL)); - - /* Repeat FFT for NACC times on the same memory region */ - if (p2p) - iters = NACC; - else - iters = 1; - - for (j = 0; j < 2 * len; j++) { - float scaling_factor = (float) rand () / (float) RAND_MAX; - gold[j] = LO + scaling_factor * (HI - LO); - } - - // convert input to fixed point - for (j = 0; j < 2 * len; j++) - in[j] = float2fx((native_t) gold[j], FX_IL); - - for (p = 0; p < iters; p++) { - // Compute golden output - fft_comp(gold, len, log_len, -1, DO_BITREV); - } + int j, p, iters; + const float LO = -1.0; + const float HI = 1.0; + + srand((unsigned int)time(NULL)); + + /* Repeat FFT for NACC times on the same memory region */ + if (p2p) iters = NACC; + else + iters = 1; + + for (j = 0; j < 2 * len; j++) { + float scaling_factor = (float)rand() / (float)RAND_MAX; + gold[j] = LO + scaling_factor * (HI - LO); + } + + // convert input to fixed point + for (j = 0; j < 2 * len; j++) + in[j] = float2fx((native_t)gold[j], FX_IL); + + for (p = 0; p < iters; p++) { + // Compute golden output + fft_comp(gold, len, log_len, -1, DO_BITREV); + } } - /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = 2 * len; - out_words_adj = 2 * len; - } else { - in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj; - out_len = out_words_adj; - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = 0; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = 2 * len; + out_words_adj = 2 * len; + } + else { + in_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(2 * len, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj; + out_len = out_words_adj; + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = 0; + size = (out_offset * sizeof(token_t)) + out_size; } - int main(int argc, char **argv) { - int errors; - char key; - - float *gold[3]; - token_t *buf[3]; - - const float ERROR_COUNT_TH = 0.01; - int k; - - init_parameters(); + int errors; + char key; - for (k = 0; k < NACC; k++) { - buf[k] = (token_t *) esp_alloc(NACC * size); - gold[k] = malloc(NACC * out_len * sizeof(float)); - } + float *gold[3]; + token_t *buf[3]; - init_buffer(buf[0], gold[0], false); + const float ERROR_COUNT_TH = 0.01; + int k; - printf("\n====== Non coherent DMA ======\n\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + init_parameters(); - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + for (k = 0; k < NACC; k++) { + buf[k] = (token_t *)esp_alloc(NACC * size); + gold[k] = malloc(NACC * out_len * sizeof(float)); + } - cfg_nc[0].hw_buf = buf[0]; + init_buffer(buf[0], gold[0], false); - //ESP MONITORS: EXAMPLE #1 - //read a single monitor from the tile number and monitor offset + printf("\n====== Non coherent DMA ======\n\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - //statically declare monitor arg structure - esp_monitor_args_t mon_args; + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - //set up argument structure using READ_SINGLE mode - //the off-chip memory accesses are read from the memory tile at the DDR_WORD_TRANSFER monitor - const int MEM_TILE_IDX = 0; - mon_args.read_mode = ESP_MON_READ_SINGLE; - mon_args.tile_index = MEM_TILE_IDX; - mon_args.mon_index = MON_DDR_WORD_TRANSFER_INDEX; + cfg_nc[0].hw_buf = buf[0]; - //in the READ_SINGLE mode, the monitor value is returned directly - //read before and after - unsigned int ddr_accesses_start, ddr_accesses_end; - ddr_accesses_start = esp_monitor(mon_args, NULL); - esp_run(cfg_nc, 1); - ddr_accesses_end = esp_monitor(mon_args, NULL); + // ESP MONITORS: EXAMPLE #1 + // read a single monitor from the tile number and monitor offset - printf("\n ** DONE **\n"); + // statically declare monitor arg structure + esp_monitor_args_t mon_args; - //calculate differnce, accounting for overflow - unsigned int ddr_accesses_diff; - ddr_accesses_diff = sub_monitor_vals(ddr_accesses_start, ddr_accesses_end); - printf("\tOff-chip memory accesses: %d\n", ddr_accesses_diff); + // set up argument structure using READ_SINGLE mode + // the off-chip memory accesses are read from the memory tile at the DDR_WORD_TRANSFER monitor + const int MEM_TILE_IDX = 0; + mon_args.read_mode = ESP_MON_READ_SINGLE; + mon_args.tile_index = MEM_TILE_IDX; + mon_args.mon_index = MON_DDR_WORD_TRANSFER_INDEX; - errors = validate_buffer(&buf[0][out_offset], gold[0]); + // in the READ_SINGLE mode, the monitor value is returned directly + // read before and after + unsigned int ddr_accesses_start, ddr_accesses_end; + ddr_accesses_start = esp_monitor(mon_args, NULL); + esp_run(cfg_nc, 1); + ddr_accesses_end = esp_monitor(mon_args, NULL); - if (((float) errors / (float) len) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + printf("\n ** DONE **\n"); - printf("\n============\n\n"); + // calculate differnce, accounting for overflow + unsigned int ddr_accesses_diff; + ddr_accesses_diff = sub_monitor_vals(ddr_accesses_start, ddr_accesses_end); + printf("\tOff-chip memory accesses: %d\n", ddr_accesses_diff); + errors = validate_buffer(&buf[0][out_offset], gold[0]); - /* LLC-Coherent test */ - init_buffer(buf[0], gold[0], false); + if (((float)errors / (float)len) > ERROR_COUNT_TH) + printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - printf("\n====== LLC-coherent DMA ======\n\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + printf("\n============\n\n"); - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + /* LLC-Coherent test */ + init_buffer(buf[0], gold[0], false); - //ESP MONITORS: EXAMPLE #2 - //read all monitors on the SoC + printf("\n====== LLC-coherent DMA ======\n\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - //statically declare monitor vals structures - esp_monitor_vals_t vals_start, vals_end; + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - //set read_mode to ALL - mon_args.read_mode = ESP_MON_READ_ALL; + // ESP MONITORS: EXAMPLE #2 + // read all monitors on the SoC - cfg_llc[0].hw_buf = buf[0]; + // statically declare monitor vals structures + esp_monitor_vals_t vals_start, vals_end; - printf("\n ** DONE **\n"); + // set read_mode to ALL + mon_args.read_mode = ESP_MON_READ_ALL; - //values written into vals struct argument - esp_monitor(mon_args, &vals_start); - esp_run(cfg_llc, 1); - esp_monitor(mon_args, &vals_end); + cfg_llc[0].hw_buf = buf[0]; - //calculate difference of all values - esp_monitor_vals_t vals_diff; - vals_diff = esp_monitor_diff(vals_start, vals_end); + printf("\n ** DONE **\n"); - FILE *fp = fopen("multifft_esp_mon_all.txt", "w"); - esp_monitor_print(mon_args, vals_diff, fp); - fclose(fp); + // values written into vals struct argument + esp_monitor(mon_args, &vals_start); + esp_run(cfg_llc, 1); + esp_monitor(mon_args, &vals_end); - errors = validate_buffer(&buf[0][out_offset], gold[0]); + // calculate difference of all values + esp_monitor_vals_t vals_diff; + vals_diff = esp_monitor_diff(vals_start, vals_end); - if (((float) errors / (float) len) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + FILE *fp = fopen("multifft_esp_mon_all.txt", "w"); + esp_monitor_print(mon_args, vals_diff, fp); + fclose(fp); + errors = validate_buffer(&buf[0][out_offset], gold[0]); - printf("\n============\n\n"); + if (((float)errors / (float)len) > ERROR_COUNT_TH) + printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - /* Fully-Coherent test */ - init_buffer(buf[0], gold[0], false); + printf("\n============\n\n"); - printf("\n====== Fully-coherent DMA ======\n\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + /* Fully-Coherent test */ + init_buffer(buf[0], gold[0], false); - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + printf("\n====== Fully-coherent DMA ======\n\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - //ESP MONITORS: EXAMPLE #3 - //read a specified subset of the monitors on the SoC + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - //dynamically allocate monitor arg structure - esp_monitor_vals_t *vals_start_ptr = esp_monitor_vals_alloc(); - esp_monitor_vals_t *vals_end_ptr = esp_monitor_vals_alloc(); + // ESP MONITORS: EXAMPLE #3 + // read a specified subset of the monitors on the SoC - //set read_mode to MANY - mon_args.read_mode = ESP_MON_READ_MANY; - mon_args.read_mask = 0; + // dynamically allocate monitor arg structure + esp_monitor_vals_t *vals_start_ptr = esp_monitor_vals_alloc(); + esp_monitor_vals_t *vals_end_ptr = esp_monitor_vals_alloc(); - //enable reading memory accesses - mon_args.read_mask |= 1 << ESP_MON_READ_DDR_ACCESSES; + // set read_mode to MANY + mon_args.read_mode = ESP_MON_READ_MANY; + mon_args.read_mask = 0; - //enable reading L2 statistics - mon_args.read_mask |= 1 << ESP_MON_READ_L2_STATS; + // enable reading memory accesses + mon_args.read_mask |= 1 << ESP_MON_READ_DDR_ACCESSES; - //enable reading LLC statistics - mon_args.read_mask |= 1 << ESP_MON_READ_LLC_STATS; + // enable reading L2 statistics + mon_args.read_mask |= 1 << ESP_MON_READ_L2_STATS; - //enable reading acc statistics - requires the index of the accelerator - mon_args.acc_index = 0; - mon_args.read_mask |= 1 << ESP_MON_READ_ACC_STATS; + // enable reading LLC statistics + mon_args.read_mask |= 1 << ESP_MON_READ_LLC_STATS; - //enable reading noc injections - requires the index of the tile - const int ACC_TILE_INDEX = 0; - mon_args.tile_index = ACC_TILE_INDEX; - mon_args.read_mask |= 1 << ESP_MON_READ_NOC_INJECTS; + // enable reading acc statistics - requires the index of the accelerator + mon_args.acc_index = 0; + mon_args.read_mask |= 1 << ESP_MON_READ_ACC_STATS; - //enable reading noc backpressure on a plane - requires the index of the noc plane - const int NOC_PLANE = 0; - mon_args.noc_index = NOC_PLANE; - mon_args.read_mask |= 1 << ESP_MON_READ_NOC_QUEUE_FULL_PLANE; + // enable reading noc injections - requires the index of the tile + const int ACC_TILE_INDEX = 0; + mon_args.tile_index = ACC_TILE_INDEX; + mon_args.read_mask |= 1 << ESP_MON_READ_NOC_INJECTS; - cfg_fc[0].hw_buf = buf[0]; + // enable reading noc backpressure on a plane - requires the index of the noc plane + const int NOC_PLANE = 0; + mon_args.noc_index = NOC_PLANE; + mon_args.read_mask |= 1 << ESP_MON_READ_NOC_QUEUE_FULL_PLANE; - //values written into vals struct argument - esp_monitor(mon_args, vals_start_ptr); - esp_run(cfg_fc, 1); - esp_monitor(mon_args, vals_end_ptr); + cfg_fc[0].hw_buf = buf[0]; - printf("\n ** DONE **\n"); + // values written into vals struct argument + esp_monitor(mon_args, vals_start_ptr); + esp_run(cfg_fc, 1); + esp_monitor(mon_args, vals_end_ptr); - //calculate difference of all values - vals_diff = esp_monitor_diff(*vals_start_ptr, *vals_end_ptr); + printf("\n ** DONE **\n"); - //write results to file - fp = fopen("multifft_esp_mon_many.txt", "w"); - esp_monitor_print(mon_args, vals_diff, fp); - fclose(fp); + // calculate difference of all values + vals_diff = esp_monitor_diff(*vals_start_ptr, *vals_end_ptr); - //when done with monitors, free all allocated structures, and unmap the address space - esp_monitor_free(); + // write results to file + fp = fopen("multifft_esp_mon_many.txt", "w"); + esp_monitor_print(mon_args, vals_diff, fp); + fclose(fp); - errors = validate_buffer(&buf[0][out_offset], gold[0]); + // when done with monitors, free all allocated structures, and unmap the address space + esp_monitor_free(); - if (((float) errors / (float) len) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + errors = validate_buffer(&buf[0][out_offset], gold[0]); - printf("\n============\n\n"); + if (((float)errors / (float)len) > ERROR_COUNT_TH) + printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - /* Parallel test */ - for (k = 0; k < NACC; k++) { - init_buffer(buf[k], gold[k], false); - } + printf("\n============\n\n"); - printf("\n====== Concurrent execution ======\n\n"); - printf(" fft.0 -> fully coherent\n"); - printf(" fft.1 -> LLC-coherent DMA\n"); - printf(" fft.2 -> non-coherent DMA\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + /* Parallel test */ + for (k = 0; k < NACC; k++) { + init_buffer(buf[k], gold[k], false); + } - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + printf("\n====== Concurrent execution ======\n\n"); + printf(" fft.0 -> fully coherent\n"); + printf(" fft.1 -> LLC-coherent DMA\n"); + printf(" fft.2 -> non-coherent DMA\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - for (k = 0; k < NACC; k++) - cfg_parallel[k].hw_buf = buf[k]; + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - esp_run(cfg_parallel, NACC); + for (k = 0; k < NACC; k++) + cfg_parallel[k].hw_buf = buf[k]; - printf("\n ** DONE **\n"); + esp_run(cfg_parallel, NACC); - for (k = 0; k < NACC; k++) { - errors = validate_buffer(&buf[k][out_offset], gold[k]); - if (( (float) errors / (float) (len * NACC)) > ERROR_COUNT_TH) - printf(" + TEST FAIL fft.%d: exceeding error count threshold\n", k); - else - printf(" + TEST PASS fft.%d: not exceeding error count threshold\n", k); - } + printf("\n ** DONE **\n"); - printf("\n============\n\n"); + for (k = 0; k < NACC; k++) { + errors = validate_buffer(&buf[k][out_offset], gold[k]); + if (((float)errors / (float)(len * NACC)) > ERROR_COUNT_TH) + printf(" + TEST FAIL fft.%d: exceeding error count threshold\n", k); + else + printf(" + TEST PASS fft.%d: not exceeding error count threshold\n", k); + } + printf("\n============\n\n"); - /* P2P test */ - init_buffer(buf[0], gold[0], true); + /* P2P test */ + init_buffer(buf[0], gold[0], true); - printf("\n====== Point-to-point Test ======\n\n"); - printf(" fft.0 (NC DMA) -> fft.1 -> fft.2 (NC DMA)\n"); - printf(" .len = %d\n", len); - printf(" .log_len = %d\n", log_len); + printf("\n====== Point-to-point Test ======\n\n"); + printf(" fft.0 (NC DMA) -> fft.1 -> fft.2 (NC DMA)\n"); + printf(" .len = %d\n", len); + printf(" .log_len = %d\n", log_len); - printf(" ** Press ENTER to START ** "); - scanf("%c", &key); + printf(" ** Press ENTER to START ** "); + scanf("%c", &key); - for (k = 0; k < NACC; k++) - cfg_p2p[k].hw_buf = buf[0]; + for (k = 0; k < NACC; k++) + cfg_p2p[k].hw_buf = buf[0]; - esp_run(cfg_p2p, NACC); + esp_run(cfg_p2p, NACC); - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - errors = validate_buffer(&buf[0][out_offset], gold[0]); + errors = validate_buffer(&buf[0][out_offset], gold[0]); - if (((float) errors / (float) (len * NACC)) > ERROR_COUNT_TH) - printf(" + TEST FAIL: exceeding error count threshold\n"); - else - printf(" + TEST PASS: not exceeding error count threshold\n"); + if (((float)errors / (float)(len * NACC)) > ERROR_COUNT_TH) + printf(" + TEST FAIL: exceeding error count threshold\n"); + else + printf(" + TEST PASS: not exceeding error count threshold\n"); - printf("\n============\n\n"); + printf("\n============\n\n"); - for (k = 0; k < NACC; k++) { - free(gold[k]); - esp_free(buf[k]); - } + for (k = 0; k < NACC; k++) { + free(gold[k]); + esp_free(buf[k]); + } - return errors; + return errors; } diff --git a/soft/common/drivers/baremetal/dvi/draw.c b/soft/common/drivers/baremetal/dvi/draw.c index 5a02da9d44..498483c7b7 100644 --- a/soft/common/drivers/baremetal/dvi/draw.c +++ b/soft/common/drivers/baremetal/dvi/draw.c @@ -8,24 +8,22 @@ int main(int argc, char **argv) { - int i, j; - volatile unsigned *mem = (unsigned *) 0x80000614; + int i, j; + volatile unsigned *mem = (unsigned *)0x80000614; - i = 0; - for (i = 0; i < 600; i++) - for (j = 0; j < 200; j++) - mem[i * 200 + j] = 0; + i = 0; + for (i = 0; i < 600; i++) + for (j = 0; j < 200; j++) + mem[i * 200 + j] = 0; - for (i = 0; i < 600; i++) - for (j = 0; j < 200; j++) { - if (j*4 > 600) - mem[i * 200 + j] = 0x0; - else if (i < (j*4 - 4) || i > (j*4 + 4)) - mem[i * 200 + j] = 0x0c0c0c0c; - else - mem[i * 200 + j] = 0xc4c4c4c4; - } + for (i = 0; i < 600; i++) + for (j = 0; j < 200; j++) { + if (j * 4 > 600) mem[i * 200 + j] = 0x0; + else if (i < (j * 4 - 4) || i > (j * 4 + 4)) + mem[i * 200 + j] = 0x0c0c0c0c; + else + mem[i * 200 + j] = 0xc4c4c4c4; + } - - return 0; + return 0; } diff --git a/soft/common/drivers/baremetal/include/esp_probe.h b/soft/common/drivers/baremetal/include/esp_probe.h index cb32f438bd..ef900516d2 100644 --- a/soft/common/drivers/baremetal/include/esp_probe.h +++ b/soft/common/drivers/baremetal/include/esp_probe.h @@ -3,89 +3,85 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include +#include #ifdef __riscv -#include -#include -#include + #include + #include + #include #endif #include "esplink.h" #ifndef __ESP_PROBE_H__ -#define __ESP_PROBE_H__ - -#ifdef __sparc -#define APB_BASE_ADDR 0x80000000 -#define APB_PLUGNPLAY (APB_BASE_ADDR + 0xff000) -#elif __riscv -#define DTB_ADDRESS RODATA_START_ADDR -#else -#error Unsupported ISA -#endif - -/* - * The number of accelerators depends on how many I/O devices can be addressed. - * This can be changed by updating the constant NAPBS as explained above, as well - * as the corresponding constant in - * /rtl/include/sld/noc/nocpackage.vhd - * The following indices are reserved: - * 0 - BOOT ROM memory controller - * 1 - UART - * 2 - Interrupt controller - * 3 - Timer - * 4 - Reserved - * 5-8 - DVFS controller - * 9-12 - Processors' private cache controller (must change with NCPU_MAX) - * 13 - SVGA controller - * 14 - Ethernet MAC controller - * 15 - Ethernet SGMII PHY controller - * 16-19 - LLC cache controller (must change with NMEM_MAX) - * 84-(NAPBS-1) - Accelerators - */ -#define NAPBSLV 128 -#define NACC_MAX 44 - - -#define VENDOR_SLD 0xEB - -#define SLD_L2_CACHE 0x020 -#define SLD_LLC_CACHE 0x021 - - -#define VENDOR_UIUC 0xEE - -#define UIUC_SPANDEX_L2 0x020 -#define UIUC_SPANDEX_LLC 0x021 - - -#ifdef USE_SPANDEX -#define VENDOR_CACHE VENDOR_UIUC -#define DEVID_L2_CACHE UIUC_SPANDEX_L2 -#define DEVID_LLC_CACHE UIUC_SPANDEX_LLC -#define DEVNAME_L2_CACHE "uiuc,spandex_l2" -#define DEVNAME_LLC_CACHE "uiuc,spandex_llc" -#else -#define VENDOR_CACHE VENDOR_SLD -#define DEVID_L2_CACHE SLD_L2_CACHE -#define DEVID_LLC_CACHE SLD_LLC_CACHE -#define DEVNAME_L2_CACHE "sld,l2_cache" -#define DEVNAME_LLC_CACHE "sld,llc_cache" -#endif - - -#define DEVNAME_MAX_LEN 32 + #define __ESP_PROBE_H__ + + #ifdef __sparc + #define APB_BASE_ADDR 0x80000000 + #define APB_PLUGNPLAY (APB_BASE_ADDR + 0xff000) + #elif __riscv + #define DTB_ADDRESS RODATA_START_ADDR + #else + #error Unsupported ISA + #endif + + /* + * The number of accelerators depends on how many I/O devices can be addressed. + * This can be changed by updating the constant NAPBS as explained above, as well + * as the corresponding constant in + * /rtl/include/sld/noc/nocpackage.vhd + * The following indices are reserved: + * 0 - BOOT ROM memory controller + * 1 - UART + * 2 - Interrupt controller + * 3 - Timer + * 4 - Reserved + * 5-8 - DVFS controller + * 9-12 - Processors' private cache controller (must change with NCPU_MAX) + * 13 - SVGA controller + * 14 - Ethernet MAC controller + * 15 - Ethernet SGMII PHY controller + * 16-19 - LLC cache controller (must change with NMEM_MAX) + * 84-(NAPBS-1) - Accelerators + */ + #define NAPBSLV 128 + #define NACC_MAX 44 + + #define VENDOR_SLD 0xEB + + #define SLD_L2_CACHE 0x020 + #define SLD_LLC_CACHE 0x021 + + #define VENDOR_UIUC 0xEE + + #define UIUC_SPANDEX_L2 0x020 + #define UIUC_SPANDEX_LLC 0x021 + + #ifdef USE_SPANDEX + #define VENDOR_CACHE VENDOR_UIUC + #define DEVID_L2_CACHE UIUC_SPANDEX_L2 + #define DEVID_LLC_CACHE UIUC_SPANDEX_LLC + #define DEVNAME_L2_CACHE "uiuc,spandex_l2" + #define DEVNAME_LLC_CACHE "uiuc,spandex_llc" + #else + #define VENDOR_CACHE VENDOR_SLD + #define DEVID_L2_CACHE SLD_L2_CACHE + #define DEVID_LLC_CACHE SLD_LLC_CACHE + #define DEVNAME_L2_CACHE "sld,l2_cache" + #define DEVNAME_LLC_CACHE "sld,llc_cache" + #endif + + #define DEVNAME_MAX_LEN 32 struct esp_device { - unsigned vendor; - unsigned id; - unsigned number; - unsigned irq; - long long unsigned addr; - unsigned compat; - char name[DEVNAME_MAX_LEN]; + unsigned vendor; + unsigned id; + unsigned number; + unsigned irq; + long long unsigned addr; + unsigned compat; + char name[DEVNAME_MAX_LEN]; }; extern const char *const coherence_label[5]; @@ -99,13 +95,20 @@ void iowrite32(struct esp_device *dev, unsigned offset, unsigned payload); void esp_flush(int coherence); void esp_p2p_init(struct esp_device *dev, struct esp_device **srcs, unsigned nsrcs); -#define esp_get_y(_dev) (YX_MASK_YX & (ioread32(_dev, YX_REG) >> YX_SHIFT_Y)) -#define esp_get_x(_dev) (YX_MASK_YX & (ioread32(_dev, YX_REG) >> YX_SHIFT_X)) -#define esp_p2p_reset(_dev) iowrite32(_dev, P2P_REG, 0) -#define esp_p2p_enable_dst(_dev) iowrite32(_dev, P2P_REG, ioread32(_dev, P2P_REG) | P2P_MASK_DST_IS_P2P) -#define esp_p2p_enable_src(_dev) iowrite32(_dev, P2P_REG, ioread32(_dev, P2P_REG) | P2P_MASK_SRC_IS_P2P) -#define esp_p2p_set_nsrcs(_dev, _n) iowrite32(_dev, P2P_REG, ioread32(_dev, P2P_REG) | (P2P_MASK_NSRCS & (_n - 1))) -#define esp_p2p_set_y(_dev, _n, _y) iowrite32(_dev, P2P_REG, ioread32(_dev, P2P_REG) | ((P2P_MASK_SRCS_YX & _y) << P2P_SHIFT_SRCS_Y(_n))) -#define esp_p2p_set_x(_dev, _n, _x) iowrite32(_dev, P2P_REG, ioread32(_dev, P2P_REG) | ((P2P_MASK_SRCS_YX & _x) << P2P_SHIFT_SRCS_X(_n))) + #define esp_get_y(_dev) (YX_MASK_YX & (ioread32(_dev, YX_REG) >> YX_SHIFT_Y)) + #define esp_get_x(_dev) (YX_MASK_YX & (ioread32(_dev, YX_REG) >> YX_SHIFT_X)) + #define esp_p2p_reset(_dev) iowrite32(_dev, P2P_REG, 0) + #define esp_p2p_enable_dst(_dev) \ + iowrite32(_dev, P2P_REG, ioread32(_dev, P2P_REG) | P2P_MASK_DST_IS_P2P) + #define esp_p2p_enable_src(_dev) \ + iowrite32(_dev, P2P_REG, ioread32(_dev, P2P_REG) | P2P_MASK_SRC_IS_P2P) + #define esp_p2p_set_nsrcs(_dev, _n) \ + iowrite32(_dev, P2P_REG, ioread32(_dev, P2P_REG) | (P2P_MASK_NSRCS & (_n - 1))) + #define esp_p2p_set_y(_dev, _n, _y) \ + iowrite32(_dev, P2P_REG, \ + ioread32(_dev, P2P_REG) | ((P2P_MASK_SRCS_YX & _y) << P2P_SHIFT_SRCS_Y(_n))) + #define esp_p2p_set_x(_dev, _n, _x) \ + iowrite32(_dev, P2P_REG, \ + ioread32(_dev, P2P_REG) | ((P2P_MASK_SRCS_YX & _x) << P2P_SHIFT_SRCS_X(_n))) #endif /* __ESP_PROBE_H__ */ diff --git a/soft/common/drivers/baremetal/probe/fdt.c b/soft/common/drivers/baremetal/probe/fdt.c index 96b32a5d05..cb3e0fd2c4 100644 --- a/soft/common/drivers/baremetal/probe/fdt.c +++ b/soft/common/drivers/baremetal/probe/fdt.c @@ -27,149 +27,143 @@ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ - +#include "fdt.h" #include #include -#include "fdt.h" static inline uint32_t bswap(uint32_t x) { -// #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - uint32_t y = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8; - uint32_t z = (y & 0x0000FFFF) << 16 | (y & 0xFFFF0000) >> 16; - return z; -// #else -// /* No need to swap on big endian */ -// return x; -// #endif + // #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint32_t y = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8; + uint32_t z = (y & 0x0000FFFF) << 16 | (y & 0xFFFF0000) >> 16; + return z; + // #else + // /* No need to swap on big endian */ + // return x; + // #endif } static inline int isstring(char c) { - if (c >= 'A' && c <= 'Z') - return 1; - if (c >= 'a' && c <= 'z') - return 1; - if (c >= '0' && c <= '9') - return 1; - if (c == '\0' || c == ' ' || c == ',' || c == '-') - return 1; - return 0; + if (c >= 'A' && c <= 'Z') return 1; + if (c >= 'a' && c <= 'z') return 1; + if (c >= '0' && c <= '9') return 1; + if (c == '\0' || c == ' ' || c == ',' || c == '-') return 1; + return 0; } -static uint32_t *fdt_scan_helper( - uint32_t *lex, - const char *strings, - struct fdt_scan_node *node, - const struct fdt_cb *cb) +static uint32_t *fdt_scan_helper(uint32_t *lex, const char *strings, struct fdt_scan_node *node, + const struct fdt_cb *cb) { - struct fdt_scan_node child; - struct fdt_scan_prop prop; - int last = 0; - - child.parent = node; - // these are the default cell counts, as per the FDT spec - child.address_cells = 2; - child.size_cells = 1; - prop.node = node; - - while (1) { - switch (bswap(lex[0])) { - case FDT_NOP: { - lex += 1; - break; - } - case FDT_PROP: { - // assert (!last); - prop.name = strings + bswap(lex[2]); - prop.len = bswap(lex[1]); - prop.value = lex + 3; - if (node && !strcmp(prop.name, "#address-cells")) { node->address_cells = bswap(lex[3]); } - if (node && !strcmp(prop.name, "#size-cells")) { node->size_cells = bswap(lex[3]); } - lex += 3 + (prop.len+3)/4; - cb->prop(&prop, cb->extra); - break; - } - case FDT_BEGIN_NODE: { - uint32_t *lex_next; - if (!last && node && cb->done) cb->done(node, cb->extra); - last = 1; - child.name = (const char *)(lex+1); - if (cb->open) cb->open(&child, cb->extra); - lex_next = fdt_scan_helper( - lex + 2 + strlen(child.name)/4, - strings, &child, cb); - if (cb->close && cb->close(&child, cb->extra) == -1) - while (lex != lex_next) *lex++ = bswap(FDT_NOP); - lex = lex_next; - break; - } - case FDT_END_NODE: { - if (!last && node && cb->done) cb->done(node, cb->extra); - return lex + 1; - } - default: { // FDT_END - if (!last && node && cb->done) cb->done(node, cb->extra); - return lex; - } + struct fdt_scan_node child; + struct fdt_scan_prop prop; + int last = 0; + + child.parent = node; + // these are the default cell counts, as per the FDT spec + child.address_cells = 2; + child.size_cells = 1; + prop.node = node; + + while (1) { + switch (bswap(lex[0])) { + case FDT_NOP: { + lex += 1; + break; + } + case FDT_PROP: { + // assert (!last); + prop.name = strings + bswap(lex[2]); + prop.len = bswap(lex[1]); + prop.value = lex + 3; + if (node && !strcmp(prop.name, "#address-cells")) { + node->address_cells = bswap(lex[3]); + } + if (node && !strcmp(prop.name, "#size-cells")) { node->size_cells = bswap(lex[3]); } + lex += 3 + (prop.len + 3) / 4; + cb->prop(&prop, cb->extra); + break; + } + case FDT_BEGIN_NODE: { + uint32_t *lex_next; + if (!last && node && cb->done) cb->done(node, cb->extra); + last = 1; + child.name = (const char *)(lex + 1); + if (cb->open) cb->open(&child, cb->extra); + lex_next = fdt_scan_helper(lex + 2 + strlen(child.name) / 4, strings, &child, cb); + if (cb->close && cb->close(&child, cb->extra) == -1) + while (lex != lex_next) + *lex++ = bswap(FDT_NOP); + lex = lex_next; + break; + } + case FDT_END_NODE: { + if (!last && node && cb->done) cb->done(node, cb->extra); + return lex + 1; + } + default: { // FDT_END + if (!last && node && cb->done) cb->done(node, cb->extra); + return lex; + } + } } - } } void fdt_scan(uintptr_t fdt, const struct fdt_cb *cb) { - struct fdt_header *header = (struct fdt_header *)fdt; + struct fdt_header *header = (struct fdt_header *)fdt; - // Only process FDT that we understand - if (bswap(header->magic) != FDT_MAGIC || - bswap(header->last_comp_version) > FDT_VERSION) return; + // Only process FDT that we understand + if (bswap(header->magic) != FDT_MAGIC || bswap(header->last_comp_version) > FDT_VERSION) return; - const char *strings = (const char *)(fdt + bswap(header->off_dt_strings)); - uint32_t *lex = (uint32_t *)(fdt + bswap(header->off_dt_struct)); + const char *strings = (const char *)(fdt + bswap(header->off_dt_strings)); + uint32_t *lex = (uint32_t *)(fdt + bswap(header->off_dt_struct)); - fdt_scan_helper(lex, strings, 0, cb); + fdt_scan_helper(lex, strings, 0, cb); } uint32_t fdt_size(uintptr_t fdt) { - struct fdt_header *header = (struct fdt_header *)fdt; + struct fdt_header *header = (struct fdt_header *)fdt; - // Only process FDT that we understand - if (bswap(header->magic) != FDT_MAGIC || - bswap(header->last_comp_version) > FDT_VERSION) return 0; - return bswap(header->totalsize); + // Only process FDT that we understand + if (bswap(header->magic) != FDT_MAGIC || bswap(header->last_comp_version) > FDT_VERSION) + return 0; + return bswap(header->totalsize); } -const uint32_t *fdt_get_address(const struct fdt_scan_node *node, const uint32_t *value, uint64_t *result) +const uint32_t *fdt_get_address(const struct fdt_scan_node *node, const uint32_t *value, + uint64_t *result) { - *result = 0; - for (int cells = node->address_cells; cells > 0; --cells) - *result = (*result << 32) + bswap(*value++); - return value; + *result = 0; + for (int cells = node->address_cells; cells > 0; --cells) + *result = (*result << 32) + bswap(*value++); + return value; } -const uint32_t *fdt_get_size(const struct fdt_scan_node *node, const uint32_t *value, uint64_t *result) +const uint32_t *fdt_get_size(const struct fdt_scan_node *node, const uint32_t *value, + uint64_t *result) { - *result = 0; - for (int cells = node->size_cells; cells > 0; --cells) - *result = (*result << 32) + bswap(*value++); - return value; + *result = 0; + for (int cells = node->size_cells; cells > 0; --cells) + *result = (*result << 32) + bswap(*value++); + return value; } uint32_t fdt_get_value(const struct fdt_scan_prop *prop, uint32_t index) { - return bswap(prop->value[index]); + return bswap(prop->value[index]); } int fdt_string_list_index(const struct fdt_scan_prop *prop, const char *str) { - const char *list = (const char *)prop->value; - const char *end = list + prop->len; - int index = 0; - while (end - list > 0) { - if (!strcmp(list, str)) return index; - ++index; - list += strlen(list) + 1; - } - return -1; + const char *list = (const char *)prop->value; + const char *end = list + prop->len; + int index = 0; + while (end - list > 0) { + if (!strcmp(list, str)) return index; + ++index; + list += strlen(list) + 1; + } + return -1; } diff --git a/soft/common/drivers/common/include/esp_accelerator.h b/soft/common/drivers/common/include/esp_accelerator.h index 42d8000aa7..e721697b41 100644 --- a/soft/common/drivers/common/include/esp_accelerator.h +++ b/soft/common/drivers/common/include/esp_accelerator.h @@ -6,24 +6,23 @@ #ifndef __ESP_ACCELERATOR_H__ #define __ESP_ACCELERATOR_H__ -#define BIT(nr) (1UL << (nr)) +#define BIT(nr) (1UL << (nr)) #ifndef __KERNEL__ -#define __round_mask(x, y) ((y)-1) -#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) + #define __round_mask(x, y) ((y)-1) + #define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1) #endif - /*** * ESP accelerator common definitions and registers offset ***/ /* bank(0): CMD (reset if cleared) */ -#define CMD_REG 0x00 +#define CMD_REG 0x00 #define CMD_MASK_START BIT(0) /* bank(1): STATUS (idle when cleared) - Read only */ -#define STATUS_REG 0x04 +#define STATUS_REG 0x04 #define STATUS_MASK_RUN BIT(0) #define STATUS_MASK_DONE BIT(1) #define STATUS_MASK_ERR BIT(2) @@ -51,19 +50,25 @@ /* bank(9) : Type of coherence (None, LLC, Full) - Read only */ #define COHERENCE_REG 0x24 -enum accelerator_coherence {ACC_COH_NONE = 0, ACC_COH_LLC, ACC_COH_RECALL, ACC_COH_FULL, ACC_COH_AUTO}; +enum accelerator_coherence { + ACC_COH_NONE = 0, + ACC_COH_LLC, + ACC_COH_RECALL, + ACC_COH_FULL, + ACC_COH_AUTO +}; /* bank(10) : Point-to-point configuration */ -#define P2P_REG 0x28 -#define P2P_MASK_NSRCS 0x3 -#define P2P_MASK_SRC_IS_P2P BIT(2) -#define P2P_MASK_DST_IS_P2P BIT(3) -#define P2P_MASK_SRCS_YX 0x7 +#define P2P_REG 0x28 +#define P2P_MASK_NSRCS 0x3 +#define P2P_MASK_SRC_IS_P2P BIT(2) +#define P2P_MASK_DST_IS_P2P BIT(3) +#define P2P_MASK_SRCS_YX 0x7 #define P2P_SHIFT_SRCS_Y(_n) (7 + _n * 6) #define P2P_SHIFT_SRCS_X(_n) (4 + _n * 6) /* bank(11) : RESERVED */ -#define YX_REG 0x2c +#define YX_REG 0x2c #define YX_SHIFT_X 0 #define YX_SHIFT_Y 16 #define YX_MASK_YX 0x7 diff --git a/soft/common/drivers/common/include/utils/fft2_utils.h b/soft/common/drivers/common/include/utils/fft2_utils.h index 16d834b55a..c52e28a00c 100644 --- a/soft/common/drivers/common/include/utils/fft2_utils.h +++ b/soft/common/drivers/common/include/utils/fft2_utils.h @@ -6,23 +6,24 @@ #ifndef FFT2_UTILS_H #define FFT2_UTILS_H -#include #include #include +#include #include void fft2_do_shift(float *A0, unsigned int offset, unsigned int num_samples, unsigned int bits); unsigned int fft2_rev(unsigned int v); void fft2_bit_reverse(float *w, unsigned int offset, unsigned int n, unsigned int bits); -int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, int do_inverse, int do_shift); +int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, int do_inverse, + int do_shift); #ifndef __linux__ double sin(double x); -#ifdef __riscv + #ifdef __riscv float rand(void); -#define RAND_MAX 32768.0 -#endif + #define RAND_MAX 32768.0 + #endif #endif #endif /* FFT2_UTILS_H */ diff --git a/soft/common/drivers/common/monitors/libmonitors.c b/soft/common/drivers/common/monitors/libmonitors.c index 92c554ac9c..964bd2c351 100644 --- a/soft/common/drivers/common/monitors/libmonitors.c +++ b/soft/common/drivers/common/monitors/libmonitors.c @@ -3,383 +3,382 @@ void mem_barrier() { #ifdef __riscv - __asm__ __volatile__("fence\n"); + __asm__ __volatile__("fence\n"); #else - __asm__ __volatile__("stbar\n"); + __asm__ __volatile__("stbar\n"); #endif - } #ifdef LINUX -void *mon_alloc_head = NULL; +void *mon_alloc_head = NULL; void *monitor_base_ptr = NULL; -int mapped = 0; +int mapped = 0; void mmap_monitors() { - int fd = open("/dev/mem", O_RDWR); - monitor_base_ptr = mmap(NULL, SOC_ROWS * SOC_COLS * MONITOR_TILE_SIZE - , PROT_READ | PROT_WRITE, MAP_SHARED, fd, MONITOR_BASE_ADDR); - close(fd); + int fd = open("/dev/mem", O_RDWR); + monitor_base_ptr = mmap(NULL, SOC_ROWS * SOC_COLS * MONITOR_TILE_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, MONITOR_BASE_ADDR); + close(fd); } -void munmap_monitors() -{ - munmap(monitor_base_ptr, SOC_ROWS * SOC_COLS * MONITOR_TILE_SIZE); -} +void munmap_monitors() { munmap(monitor_base_ptr, SOC_ROWS * SOC_COLS * MONITOR_TILE_SIZE); } #endif unsigned int read_monitor(int tile_no, int mon_no) { - unsigned int offset = (MONITOR_TILE_SIZE / sizeof(unsigned int)) * tile_no; + unsigned int offset = (MONITOR_TILE_SIZE / sizeof(unsigned int)) * tile_no; #ifdef LINUX - unsigned int *addr = ((unsigned int *) monitor_base_ptr) + offset + mon_no + 1; + unsigned int *addr = ((unsigned int *)monitor_base_ptr) + offset + mon_no + 1; #else - unsigned int *addr = ((unsigned int *) MONITOR_BASE_ADDR) + offset + mon_no + 1; + unsigned int *addr = ((unsigned int *)MONITOR_BASE_ADDR) + offset + mon_no + 1; #endif - return *addr; + return *addr; } void write_burst_reg(int tile_no, int val) { - unsigned int offset = (MONITOR_TILE_SIZE / sizeof(unsigned int)) * tile_no; + unsigned int offset = (MONITOR_TILE_SIZE / sizeof(unsigned int)) * tile_no; #ifdef LINUX - unsigned int *addr = ((unsigned int *) monitor_base_ptr) + offset; + unsigned int *addr = ((unsigned int *)monitor_base_ptr) + offset; #else - unsigned int *addr = ((unsigned int *) MONITOR_BASE_ADDR) + offset; + unsigned int *addr = ((unsigned int *)MONITOR_BASE_ADDR) + offset; #endif - *addr = val; + *addr = val; } unsigned int esp_monitor(esp_monitor_args_t args, esp_monitor_vals_t *vals) { #include "soc_locs.h" - int tile, t, p, q; + int tile, t, p, q; #ifdef LINUX - if (!mapped) { - mmap_monitors(); - mapped = 1; - } + if (!mapped) { + mmap_monitors(); + mapped = 1; + } #endif - if (args.read_mode == ESP_MON_READ_SINGLE){ - - return read_monitor(args.tile_index, args.mon_index); - - } else if (args.read_mode == ESP_MON_READ_ALL){ - - for (t = 0; t < SOC_NTILES; t++) - write_burst_reg(t, 1); - - mem_barrier(); - - //ddr accesses - for (t = 0; t < SOC_NMEM; t++) - vals->ddr_accesses[t] = - read_monitor(mem_locs[t].row * SOC_COLS + mem_locs[t].col, MON_DDR_WORD_TRANSFER_INDEX); - - //mem_reqs - for (t = 0; t < SOC_NMEM; t++){ - tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; - vals->mem_reqs[t].coh_reqs = read_monitor(tile, MON_MEM_COH_REQ_INDEX); - vals->mem_reqs[t].coh_fwds = read_monitor(tile, MON_MEM_COH_FWD_INDEX); - vals->mem_reqs[t].coh_rsps_rcv = read_monitor(tile, MON_MEM_COH_RSP_RCV_INDEX); - vals->mem_reqs[t].coh_rsps_snd = read_monitor(tile, MON_MEM_COH_RSP_SND_INDEX); - vals->mem_reqs[t].dma_reqs = read_monitor(tile, MON_MEM_DMA_REQ_INDEX); - vals->mem_reqs[t].dma_rsps = read_monitor(tile, MON_MEM_DMA_RSP_INDEX); - vals->mem_reqs[t].coh_dma_reqs = read_monitor(tile, MON_MEM_COH_DMA_REQ_INDEX); - vals->mem_reqs[t].coh_dma_rsps = read_monitor(tile, MON_MEM_COH_DMA_RSP_INDEX); - } - - //l2 stats - for (t = 0; t < SOC_NCPU; t++) { - tile = cpu_locs[t].row * SOC_COLS + cpu_locs[t].col; - vals->l2_stats[tile].hits = read_monitor(tile, MON_L2_HIT_INDEX); - vals->l2_stats[tile].misses = read_monitor(tile, MON_L2_MISS_INDEX); - } + if (args.read_mode == ESP_MON_READ_SINGLE) { + + return read_monitor(args.tile_index, args.mon_index); + } + else if (args.read_mode == ESP_MON_READ_ALL) { + + for (t = 0; t < SOC_NTILES; t++) + write_burst_reg(t, 1); + + mem_barrier(); + + // ddr accesses + for (t = 0; t < SOC_NMEM; t++) + vals->ddr_accesses[t] = read_monitor(mem_locs[t].row * SOC_COLS + mem_locs[t].col, + MON_DDR_WORD_TRANSFER_INDEX); + + // mem_reqs + for (t = 0; t < SOC_NMEM; t++) { + tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; + vals->mem_reqs[t].coh_reqs = read_monitor(tile, MON_MEM_COH_REQ_INDEX); + vals->mem_reqs[t].coh_fwds = read_monitor(tile, MON_MEM_COH_FWD_INDEX); + vals->mem_reqs[t].coh_rsps_rcv = read_monitor(tile, MON_MEM_COH_RSP_RCV_INDEX); + vals->mem_reqs[t].coh_rsps_snd = read_monitor(tile, MON_MEM_COH_RSP_SND_INDEX); + vals->mem_reqs[t].dma_reqs = read_monitor(tile, MON_MEM_DMA_REQ_INDEX); + vals->mem_reqs[t].dma_rsps = read_monitor(tile, MON_MEM_DMA_RSP_INDEX); + vals->mem_reqs[t].coh_dma_reqs = read_monitor(tile, MON_MEM_COH_DMA_REQ_INDEX); + vals->mem_reqs[t].coh_dma_rsps = read_monitor(tile, MON_MEM_COH_DMA_RSP_INDEX); + } + + // l2 stats + for (t = 0; t < SOC_NCPU; t++) { + tile = cpu_locs[t].row * SOC_COLS + cpu_locs[t].col; + vals->l2_stats[tile].hits = read_monitor(tile, MON_L2_HIT_INDEX); + vals->l2_stats[tile].misses = read_monitor(tile, MON_L2_MISS_INDEX); + } #ifdef ACCS_PRESENT - for (t = 0; t < SOC_NACC; t++) { - if (acc_has_l2[t]) { - tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; - vals->l2_stats[tile].hits = read_monitor(tile, MON_L2_HIT_INDEX); - vals->l2_stats[tile].misses = read_monitor(tile, MON_L2_MISS_INDEX); - } - } + for (t = 0; t < SOC_NACC; t++) { + if (acc_has_l2[t]) { + tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; + vals->l2_stats[tile].hits = read_monitor(tile, MON_L2_HIT_INDEX); + vals->l2_stats[tile].misses = read_monitor(tile, MON_L2_MISS_INDEX); + } + } #endif - //llc stats - for (t = 0; t < SOC_NMEM; t++) { - tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; - vals->l2_stats[tile].hits = read_monitor(tile, MON_LLC_HIT_INDEX); - vals->l2_stats[tile].misses = read_monitor(tile, MON_LLC_MISS_INDEX); - } + // llc stats + for (t = 0; t < SOC_NMEM; t++) { + tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; + vals->l2_stats[tile].hits = read_monitor(tile, MON_LLC_HIT_INDEX); + vals->l2_stats[tile].misses = read_monitor(tile, MON_LLC_MISS_INDEX); + } - //acc stats + // acc stats #ifdef ACCS_PRESENT - for (t = 0; t < SOC_NACC; t++) { - tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; - vals->acc_stats[t].acc_tlb = read_monitor(tile, MON_ACC_TLB_INDEX); - vals->acc_stats[t].acc_mem_lo = read_monitor(tile, MON_ACC_MEM_LO_INDEX); - vals->acc_stats[t].acc_mem_hi = read_monitor(tile, MON_ACC_MEM_HI_INDEX); - vals->acc_stats[t].acc_tot_lo = read_monitor(tile, MON_ACC_TOT_LO_INDEX); - vals->acc_stats[t].acc_tot_hi = read_monitor(tile, MON_ACC_TOT_HI_INDEX); - vals->acc_stats[t].acc_invocations = read_monitor(tile, MON_ACC_INVOCATIONS); - } + for (t = 0; t < SOC_NACC; t++) { + tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; + vals->acc_stats[t].acc_tlb = read_monitor(tile, MON_ACC_TLB_INDEX); + vals->acc_stats[t].acc_mem_lo = read_monitor(tile, MON_ACC_MEM_LO_INDEX); + vals->acc_stats[t].acc_mem_hi = read_monitor(tile, MON_ACC_MEM_HI_INDEX); + vals->acc_stats[t].acc_tot_lo = read_monitor(tile, MON_ACC_TOT_LO_INDEX); + vals->acc_stats[t].acc_tot_hi = read_monitor(tile, MON_ACC_TOT_HI_INDEX); + vals->acc_stats[t].acc_invocations = read_monitor(tile, MON_ACC_INVOCATIONS); + } #endif - //dvfs - for (p = 0; p < DVFS_OP_POINTS; p++) - for (t = 0; t < SOC_NTILES; t++) - vals->dvfs_op[t][p] = read_monitor(t, MON_DVFS_BASE_INDEX + p); - - //noc inject - for (p = 0; p < NOC_PLANES; p++) - for (t = 0; t < SOC_NTILES; t++) - vals->noc_injects[t][p] = read_monitor(t, MON_NOC_TILE_INJECT_BASE_INDEX + p); - - //noc queue full tile - for (p = 0; p < NOC_PLANES; p++) - for (q = 0; q < NOC_QUEUES; q++) - for (t = 0; t < SOC_NTILES; t++) - vals->noc_queue_full[t][p][q] = - read_monitor(t, MON_NOC_QUEUES_FULL_BASE_INDEX + p * NOC_QUEUES + q); - - mem_barrier(); - - for (t = 0; t < SOC_NTILES; t++) - write_burst_reg(t, 0); - - return 0; - - } else { - - memset(vals, 0, sizeof(esp_monitor_vals_t)); - for (t = 0; t < SOC_NTILES; t++) - write_burst_reg(t, 1); - - mem_barrier(); - - //ddr accesses - if (args.read_mask & (1 << ESP_MON_READ_DDR_ACCESSES)) - for (t = 0; t < SOC_NMEM; t++) - vals->ddr_accesses[t] = - read_monitor(mem_locs[t].row * SOC_COLS + mem_locs[t].col, MON_DDR_WORD_TRANSFER_INDEX); - - //mem_reqs - if (args.read_mask & (1 << ESP_MON_READ_MEM_REQS)) - for (t = 0; t < SOC_NMEM; t++){ - tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; - vals->mem_reqs[t].coh_reqs = read_monitor(tile, MON_MEM_COH_REQ_INDEX); - vals->mem_reqs[t].coh_fwds = read_monitor(tile, MON_MEM_COH_FWD_INDEX); - vals->mem_reqs[t].coh_rsps_rcv = read_monitor(tile, MON_MEM_COH_RSP_RCV_INDEX); - vals->mem_reqs[t].coh_rsps_snd = read_monitor(tile, MON_MEM_COH_RSP_SND_INDEX); - vals->mem_reqs[t].dma_reqs = read_monitor(tile, MON_MEM_DMA_REQ_INDEX); - vals->mem_reqs[t].dma_rsps = read_monitor(tile, MON_MEM_DMA_RSP_INDEX); - vals->mem_reqs[t].coh_dma_reqs = read_monitor(tile, MON_MEM_COH_DMA_REQ_INDEX); - vals->mem_reqs[t].coh_dma_rsps = read_monitor(tile, MON_MEM_COH_DMA_RSP_INDEX); - } - - //l2 stats - if (args.read_mask & (1 << ESP_MON_READ_L2_STATS)) { - for (t = 0; t < SOC_NCPU; t++) { - tile = cpu_locs[t].row * SOC_COLS + cpu_locs[t].col; - vals->l2_stats[tile].hits = read_monitor(tile, MON_L2_HIT_INDEX); - vals->l2_stats[tile].misses = read_monitor(tile, MON_L2_MISS_INDEX); - } + // dvfs + for (p = 0; p < DVFS_OP_POINTS; p++) + for (t = 0; t < SOC_NTILES; t++) + vals->dvfs_op[t][p] = read_monitor(t, MON_DVFS_BASE_INDEX + p); + + // noc inject + for (p = 0; p < NOC_PLANES; p++) + for (t = 0; t < SOC_NTILES; t++) + vals->noc_injects[t][p] = read_monitor(t, MON_NOC_TILE_INJECT_BASE_INDEX + p); + + // noc queue full tile + for (p = 0; p < NOC_PLANES; p++) + for (q = 0; q < NOC_QUEUES; q++) + for (t = 0; t < SOC_NTILES; t++) + vals->noc_queue_full[t][p][q] = + read_monitor(t, MON_NOC_QUEUES_FULL_BASE_INDEX + p * NOC_QUEUES + q); + + mem_barrier(); + + for (t = 0; t < SOC_NTILES; t++) + write_burst_reg(t, 0); + + return 0; + } + else { + + memset(vals, 0, sizeof(esp_monitor_vals_t)); + for (t = 0; t < SOC_NTILES; t++) + write_burst_reg(t, 1); + + mem_barrier(); + + // ddr accesses + if (args.read_mask & (1 << ESP_MON_READ_DDR_ACCESSES)) + for (t = 0; t < SOC_NMEM; t++) + vals->ddr_accesses[t] = read_monitor(mem_locs[t].row * SOC_COLS + mem_locs[t].col, + MON_DDR_WORD_TRANSFER_INDEX); + + // mem_reqs + if (args.read_mask & (1 << ESP_MON_READ_MEM_REQS)) + for (t = 0; t < SOC_NMEM; t++) { + tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; + vals->mem_reqs[t].coh_reqs = read_monitor(tile, MON_MEM_COH_REQ_INDEX); + vals->mem_reqs[t].coh_fwds = read_monitor(tile, MON_MEM_COH_FWD_INDEX); + vals->mem_reqs[t].coh_rsps_rcv = read_monitor(tile, MON_MEM_COH_RSP_RCV_INDEX); + vals->mem_reqs[t].coh_rsps_snd = read_monitor(tile, MON_MEM_COH_RSP_SND_INDEX); + vals->mem_reqs[t].dma_reqs = read_monitor(tile, MON_MEM_DMA_REQ_INDEX); + vals->mem_reqs[t].dma_rsps = read_monitor(tile, MON_MEM_DMA_RSP_INDEX); + vals->mem_reqs[t].coh_dma_reqs = read_monitor(tile, MON_MEM_COH_DMA_REQ_INDEX); + vals->mem_reqs[t].coh_dma_rsps = read_monitor(tile, MON_MEM_COH_DMA_RSP_INDEX); + } + + // l2 stats + if (args.read_mask & (1 << ESP_MON_READ_L2_STATS)) { + for (t = 0; t < SOC_NCPU; t++) { + tile = cpu_locs[t].row * SOC_COLS + cpu_locs[t].col; + vals->l2_stats[tile].hits = read_monitor(tile, MON_L2_HIT_INDEX); + vals->l2_stats[tile].misses = read_monitor(tile, MON_L2_MISS_INDEX); + } #ifdef ACCS_PRESENT - for (t = 0; t < SOC_NACC; t++) { - if (acc_has_l2[t]) { - tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; - vals->l2_stats[tile].hits = read_monitor(tile, MON_L2_HIT_INDEX); - vals->l2_stats[tile].misses = read_monitor(tile, MON_L2_MISS_INDEX); - } - } + for (t = 0; t < SOC_NACC; t++) { + if (acc_has_l2[t]) { + tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; + vals->l2_stats[tile].hits = read_monitor(tile, MON_L2_HIT_INDEX); + vals->l2_stats[tile].misses = read_monitor(tile, MON_L2_MISS_INDEX); + } + } #endif - } + } - //llc stats - if (args.read_mask & (1 << ESP_MON_READ_LLC_STATS)) - for (t = 0; t < SOC_NMEM; t++) { - tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; - vals->l2_stats[tile].hits = read_monitor(tile, MON_LLC_HIT_INDEX); - vals->l2_stats[tile].misses = read_monitor(tile, MON_LLC_MISS_INDEX); - } + // llc stats + if (args.read_mask & (1 << ESP_MON_READ_LLC_STATS)) + for (t = 0; t < SOC_NMEM; t++) { + tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; + vals->l2_stats[tile].hits = read_monitor(tile, MON_LLC_HIT_INDEX); + vals->l2_stats[tile].misses = read_monitor(tile, MON_LLC_MISS_INDEX); + } - //acc stats + // acc stats #ifdef ACCS_PRESENT - if (args.read_mask & (1 << ESP_MON_READ_ACC_STATS)) { - tile = acc_locs[args.acc_index].row * SOC_COLS + acc_locs[args.acc_index].col; - vals->acc_stats[args.acc_index].acc_tlb = read_monitor(tile, MON_ACC_TLB_INDEX); - vals->acc_stats[args.acc_index].acc_mem_lo = read_monitor(tile, MON_ACC_MEM_LO_INDEX); - vals->acc_stats[args.acc_index].acc_mem_hi = read_monitor(tile, MON_ACC_MEM_HI_INDEX); - vals->acc_stats[args.acc_index].acc_tot_lo = read_monitor(tile, MON_ACC_TOT_LO_INDEX); - vals->acc_stats[args.acc_index].acc_tot_hi = read_monitor(tile, MON_ACC_TOT_HI_INDEX); - vals->acc_stats[args.acc_index].acc_invocations = read_monitor(tile, MON_ACC_INVOCATIONS); - } + if (args.read_mask & (1 << ESP_MON_READ_ACC_STATS)) { + tile = acc_locs[args.acc_index].row * SOC_COLS + acc_locs[args.acc_index].col; + vals->acc_stats[args.acc_index].acc_tlb = read_monitor(tile, MON_ACC_TLB_INDEX); + vals->acc_stats[args.acc_index].acc_mem_lo = read_monitor(tile, MON_ACC_MEM_LO_INDEX); + vals->acc_stats[args.acc_index].acc_mem_hi = read_monitor(tile, MON_ACC_MEM_HI_INDEX); + vals->acc_stats[args.acc_index].acc_tot_lo = read_monitor(tile, MON_ACC_TOT_LO_INDEX); + vals->acc_stats[args.acc_index].acc_tot_hi = read_monitor(tile, MON_ACC_TOT_HI_INDEX); + vals->acc_stats[args.acc_index].acc_invocations = + read_monitor(tile, MON_ACC_INVOCATIONS); + } #endif - //dvfs - if (args.read_mask & (1 << ESP_MON_READ_DVFS_OP)) - for (p = 0; p < DVFS_OP_POINTS; p++) - vals->dvfs_op[args.tile_index][p] = read_monitor(args.tile_index, MON_DVFS_BASE_INDEX + p); - - //noc inject - if (args.read_mask & (1 << ESP_MON_READ_NOC_INJECTS)) - for (p = 0; p < NOC_PLANES; p++) - vals->noc_injects[args.tile_index][p] = - read_monitor(args.tile_index, MON_NOC_TILE_INJECT_BASE_INDEX + p); - - //noc queue full tile - if (args.read_mask & (1 << ESP_MON_READ_NOC_QUEUE_FULL_TILE)) - for (p = 0; p < NOC_PLANES; p++) - for (q = 0; q < NOC_QUEUES; q++) - vals->noc_queue_full[args.tile_index][p][q] = - read_monitor(args.tile_index, MON_NOC_QUEUES_FULL_BASE_INDEX + p * NOC_QUEUES + q); - - if (args.read_mask & (1 << ESP_MON_READ_NOC_QUEUE_FULL_PLANE)) - for (q = 0; q < NOC_QUEUES; q++) - for (t = 0; t < SOC_NTILES; t++) - vals->noc_queue_full[t][args.noc_index][q] = - read_monitor(t, MON_NOC_QUEUES_FULL_BASE_INDEX + args.noc_index * NOC_QUEUES + q); - - mem_barrier(); - - for (t = 0; t < SOC_NTILES; t++) - write_burst_reg(t, 0); - - return 0; - - } + // dvfs + if (args.read_mask & (1 << ESP_MON_READ_DVFS_OP)) + for (p = 0; p < DVFS_OP_POINTS; p++) + vals->dvfs_op[args.tile_index][p] = + read_monitor(args.tile_index, MON_DVFS_BASE_INDEX + p); + + // noc inject + if (args.read_mask & (1 << ESP_MON_READ_NOC_INJECTS)) + for (p = 0; p < NOC_PLANES; p++) + vals->noc_injects[args.tile_index][p] = + read_monitor(args.tile_index, MON_NOC_TILE_INJECT_BASE_INDEX + p); + + // noc queue full tile + if (args.read_mask & (1 << ESP_MON_READ_NOC_QUEUE_FULL_TILE)) + for (p = 0; p < NOC_PLANES; p++) + for (q = 0; q < NOC_QUEUES; q++) + vals->noc_queue_full[args.tile_index][p][q] = read_monitor( + args.tile_index, MON_NOC_QUEUES_FULL_BASE_INDEX + p * NOC_QUEUES + q); + + if (args.read_mask & (1 << ESP_MON_READ_NOC_QUEUE_FULL_PLANE)) + for (q = 0; q < NOC_QUEUES; q++) + for (t = 0; t < SOC_NTILES; t++) + vals->noc_queue_full[t][args.noc_index][q] = read_monitor( + t, MON_NOC_QUEUES_FULL_BASE_INDEX + args.noc_index * NOC_QUEUES + q); + + mem_barrier(); + + for (t = 0; t < SOC_NTILES; t++) + write_burst_reg(t, 0); + + return 0; + } } -uint32_t sub_monitor_vals (uint32_t val_start, uint32_t val_end) +uint32_t sub_monitor_vals(uint32_t val_start, uint32_t val_end) { - if (val_end >= val_start) - return val_end - val_start; - else - return (0xFFFFFFFF - val_start + val_end); + if (val_end >= val_start) return val_end - val_start; + else + return (0xFFFFFFFF - val_start + val_end); } -uint64_t sub_monitor_vals64 (uint64_t val_start, uint64_t val_end) +uint64_t sub_monitor_vals64(uint64_t val_start, uint64_t val_end) { - if (val_end >= val_start) - return val_end - val_start; - else - return (0xFFFFFFFFFFFFFFFFll - val_start + val_end); + if (val_end >= val_start) return val_end - val_start; + else + return (0xFFFFFFFFFFFFFFFFll - val_start + val_end); } esp_monitor_vals_t esp_monitor_diff(esp_monitor_vals_t vals_start, esp_monitor_vals_t vals_end) { #include "soc_locs.h" - esp_monitor_vals_t vals_diff; - int t, p, q, tile; - - for (t = 0; t < SOC_NMEM; t++) - vals_diff.ddr_accesses[t] = sub_monitor_vals(vals_start.ddr_accesses[t], vals_end.ddr_accesses[t]); - - //mem_reqs - for (t = 0; t < SOC_NMEM; t++){ - tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; - vals_diff.mem_reqs[t].coh_reqs = - sub_monitor_vals(vals_start.mem_reqs[t].coh_reqs, vals_end.mem_reqs[t].coh_reqs); - vals_diff.mem_reqs[t].coh_fwds = - sub_monitor_vals(vals_start.mem_reqs[t].coh_fwds, vals_end.mem_reqs[t].coh_fwds); - vals_diff.mem_reqs[t].coh_rsps_rcv = - sub_monitor_vals(vals_start.mem_reqs[t].coh_rsps_rcv, vals_end.mem_reqs[t].coh_rsps_rcv); - vals_diff.mem_reqs[t].coh_rsps_snd = - sub_monitor_vals(vals_start.mem_reqs[t].coh_rsps_snd, vals_end.mem_reqs[t].coh_rsps_snd); - vals_diff.mem_reqs[t].dma_reqs = - sub_monitor_vals(vals_start.mem_reqs[t].dma_reqs, vals_end.mem_reqs[t].dma_reqs); - vals_diff.mem_reqs[t].dma_rsps = - sub_monitor_vals(vals_start.mem_reqs[t].dma_rsps, vals_end.mem_reqs[t].dma_rsps); - vals_diff.mem_reqs[t].coh_dma_reqs = - sub_monitor_vals(vals_start.mem_reqs[t].coh_dma_reqs, vals_end.mem_reqs[t].coh_dma_reqs); - vals_diff.mem_reqs[t].coh_dma_rsps = - sub_monitor_vals(vals_start.mem_reqs[t].coh_dma_rsps, vals_end.mem_reqs[t].coh_dma_rsps); - } - - //l2 stats - for (t = 0; t < SOC_NCPU; t++) { - tile = cpu_locs[t].row * SOC_COLS + cpu_locs[t].col; - vals_diff.l2_stats[tile].hits = - sub_monitor_vals(vals_start.l2_stats[tile].hits, vals_end.l2_stats[tile].hits); - vals_diff.l2_stats[tile].misses = - sub_monitor_vals(vals_start.l2_stats[tile].misses, vals_end.l2_stats[tile].misses); - } + esp_monitor_vals_t vals_diff; + int t, p, q, tile; + + for (t = 0; t < SOC_NMEM; t++) + vals_diff.ddr_accesses[t] = + sub_monitor_vals(vals_start.ddr_accesses[t], vals_end.ddr_accesses[t]); + + // mem_reqs + for (t = 0; t < SOC_NMEM; t++) { + tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; + vals_diff.mem_reqs[t].coh_reqs = + sub_monitor_vals(vals_start.mem_reqs[t].coh_reqs, vals_end.mem_reqs[t].coh_reqs); + vals_diff.mem_reqs[t].coh_fwds = + sub_monitor_vals(vals_start.mem_reqs[t].coh_fwds, vals_end.mem_reqs[t].coh_fwds); + vals_diff.mem_reqs[t].coh_rsps_rcv = sub_monitor_vals(vals_start.mem_reqs[t].coh_rsps_rcv, + vals_end.mem_reqs[t].coh_rsps_rcv); + vals_diff.mem_reqs[t].coh_rsps_snd = sub_monitor_vals(vals_start.mem_reqs[t].coh_rsps_snd, + vals_end.mem_reqs[t].coh_rsps_snd); + vals_diff.mem_reqs[t].dma_reqs = + sub_monitor_vals(vals_start.mem_reqs[t].dma_reqs, vals_end.mem_reqs[t].dma_reqs); + vals_diff.mem_reqs[t].dma_rsps = + sub_monitor_vals(vals_start.mem_reqs[t].dma_rsps, vals_end.mem_reqs[t].dma_rsps); + vals_diff.mem_reqs[t].coh_dma_reqs = sub_monitor_vals(vals_start.mem_reqs[t].coh_dma_reqs, + vals_end.mem_reqs[t].coh_dma_reqs); + vals_diff.mem_reqs[t].coh_dma_rsps = sub_monitor_vals(vals_start.mem_reqs[t].coh_dma_rsps, + vals_end.mem_reqs[t].coh_dma_rsps); + } + + // l2 stats + for (t = 0; t < SOC_NCPU; t++) { + tile = cpu_locs[t].row * SOC_COLS + cpu_locs[t].col; + vals_diff.l2_stats[tile].hits = + sub_monitor_vals(vals_start.l2_stats[tile].hits, vals_end.l2_stats[tile].hits); + vals_diff.l2_stats[tile].misses = + sub_monitor_vals(vals_start.l2_stats[tile].misses, vals_end.l2_stats[tile].misses); + } #ifdef ACCS_PRESENT - for (t = 0; t < SOC_NACC; t++) { - if (acc_has_l2[t]) { - tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; - vals_diff.l2_stats[tile].hits = - sub_monitor_vals(vals_start.l2_stats[tile].hits, vals_end.l2_stats[tile].hits); - vals_diff.l2_stats[tile].misses = - sub_monitor_vals(vals_start.l2_stats[tile].misses, vals_end.l2_stats[tile].misses); - } - } + for (t = 0; t < SOC_NACC; t++) { + if (acc_has_l2[t]) { + tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; + vals_diff.l2_stats[tile].hits = + sub_monitor_vals(vals_start.l2_stats[tile].hits, vals_end.l2_stats[tile].hits); + vals_diff.l2_stats[tile].misses = + sub_monitor_vals(vals_start.l2_stats[tile].misses, vals_end.l2_stats[tile].misses); + } + } #endif - //llc stats - for (t = 0; t < SOC_NMEM; t++) { - tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; - vals_diff.l2_stats[tile].hits = - sub_monitor_vals(vals_start.l2_stats[tile].hits, vals_end.l2_stats[tile].hits); - vals_diff.l2_stats[tile].misses = - sub_monitor_vals(vals_start.l2_stats[tile].misses, vals_end.l2_stats[tile].misses); - } + // llc stats + for (t = 0; t < SOC_NMEM; t++) { + tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; + vals_diff.l2_stats[tile].hits = + sub_monitor_vals(vals_start.l2_stats[tile].hits, vals_end.l2_stats[tile].hits); + vals_diff.l2_stats[tile].misses = + sub_monitor_vals(vals_start.l2_stats[tile].misses, vals_end.l2_stats[tile].misses); + } - //acc stats + // acc stats #ifdef ACCS_PRESENT - for (t = 0; t < SOC_NACC; t++) { - tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; - //accelerator counters are cleared at the start of an invocation, so merely report the final count - uint64_t acc_mem_start, acc_mem_end, acc_mem_diff; - uint64_t acc_tot_start, acc_tot_end, acc_tot_diff; - acc_mem_start = ((uint64_t) vals_start.acc_stats[t].acc_mem_lo) - | (((uint64_t) vals_start.acc_stats[t].acc_mem_hi) << 32); - acc_mem_end = ((uint64_t) vals_end.acc_stats[t].acc_mem_lo) - | (((uint64_t) vals_end.acc_stats[t].acc_mem_hi) << 32); - acc_tot_start = ((uint64_t) vals_start.acc_stats[t].acc_tot_lo) - | (((uint64_t) vals_start.acc_stats[t].acc_tot_hi) << 32); - acc_tot_end = ((uint64_t) vals_end.acc_stats[t].acc_tot_lo) - | (((uint64_t) vals_end.acc_stats[t].acc_tot_hi) << 32); - - acc_mem_diff = sub_monitor_vals64(acc_mem_start, acc_mem_end); - acc_tot_diff = sub_monitor_vals64(acc_tot_start, acc_tot_end); - - vals_diff.acc_stats[t].acc_tlb = sub_monitor_vals(vals_start.acc_stats[t].acc_tlb, vals_end.acc_stats[t].acc_tlb); - vals_diff.acc_stats[t].acc_mem_lo = acc_mem_diff & 0xFFFFFFFF; - vals_diff.acc_stats[t].acc_mem_hi = (acc_mem_diff >> 32) & 0xFFFFFFFF; - vals_diff.acc_stats[t].acc_tot_lo = acc_tot_diff & 0xFFFFFFFF; - vals_diff.acc_stats[t].acc_tot_hi = (acc_tot_diff >> 32) & 0xFFFFFFFF; - vals_diff.acc_stats[t].acc_invocations = sub_monitor_vals(vals_start.acc_stats[t].acc_invocations, vals_end.acc_stats[t].acc_invocations); - } + for (t = 0; t < SOC_NACC; t++) { + tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; + // accelerator counters are cleared at the start of an invocation, so merely report the + // final count + uint64_t acc_mem_start, acc_mem_end, acc_mem_diff; + uint64_t acc_tot_start, acc_tot_end, acc_tot_diff; + acc_mem_start = ((uint64_t)vals_start.acc_stats[t].acc_mem_lo) | + (((uint64_t)vals_start.acc_stats[t].acc_mem_hi) << 32); + acc_mem_end = ((uint64_t)vals_end.acc_stats[t].acc_mem_lo) | + (((uint64_t)vals_end.acc_stats[t].acc_mem_hi) << 32); + acc_tot_start = ((uint64_t)vals_start.acc_stats[t].acc_tot_lo) | + (((uint64_t)vals_start.acc_stats[t].acc_tot_hi) << 32); + acc_tot_end = ((uint64_t)vals_end.acc_stats[t].acc_tot_lo) | + (((uint64_t)vals_end.acc_stats[t].acc_tot_hi) << 32); + + acc_mem_diff = sub_monitor_vals64(acc_mem_start, acc_mem_end); + acc_tot_diff = sub_monitor_vals64(acc_tot_start, acc_tot_end); + + vals_diff.acc_stats[t].acc_tlb = + sub_monitor_vals(vals_start.acc_stats[t].acc_tlb, vals_end.acc_stats[t].acc_tlb); + vals_diff.acc_stats[t].acc_mem_lo = acc_mem_diff & 0xFFFFFFFF; + vals_diff.acc_stats[t].acc_mem_hi = (acc_mem_diff >> 32) & 0xFFFFFFFF; + vals_diff.acc_stats[t].acc_tot_lo = acc_tot_diff & 0xFFFFFFFF; + vals_diff.acc_stats[t].acc_tot_hi = (acc_tot_diff >> 32) & 0xFFFFFFFF; + vals_diff.acc_stats[t].acc_invocations = sub_monitor_vals( + vals_start.acc_stats[t].acc_invocations, vals_end.acc_stats[t].acc_invocations); + } #endif - //dvfs - for (p = 0; p < DVFS_OP_POINTS; p++) - for (t = 0; t < SOC_NTILES; t++) - vals_diff.dvfs_op[t][p] = - sub_monitor_vals(vals_start.dvfs_op[t][p], vals_end.dvfs_op[t][p]); - - //noc inject - for (p = 0; p < NOC_PLANES; p++) - for (t = 0; t < SOC_NTILES; t++) - vals_diff.noc_injects[t][p] = - sub_monitor_vals(vals_start.noc_injects[t][p], vals_end.noc_injects[t][p]); - - //noc queue full tile - for (p = 0; p < NOC_PLANES; p++) - for (q = 0; q < NOC_QUEUES; q++) - for (t = 0; t < SOC_NTILES; t++) - vals_diff.noc_queue_full[t][p][q] = - sub_monitor_vals(vals_start.noc_queue_full[t][p][q], vals_end.noc_queue_full[t][p][q]); - - return vals_diff; + // dvfs + for (p = 0; p < DVFS_OP_POINTS; p++) + for (t = 0; t < SOC_NTILES; t++) + vals_diff.dvfs_op[t][p] = + sub_monitor_vals(vals_start.dvfs_op[t][p], vals_end.dvfs_op[t][p]); + + // noc inject + for (p = 0; p < NOC_PLANES; p++) + for (t = 0; t < SOC_NTILES; t++) + vals_diff.noc_injects[t][p] = + sub_monitor_vals(vals_start.noc_injects[t][p], vals_end.noc_injects[t][p]); + + // noc queue full tile + for (p = 0; p < NOC_PLANES; p++) + for (q = 0; q < NOC_QUEUES; q++) + for (t = 0; t < SOC_NTILES; t++) + vals_diff.noc_queue_full[t][p][q] = sub_monitor_vals( + vals_start.noc_queue_full[t][p][q], vals_end.noc_queue_full[t][p][q]); + + return vals_diff; } #ifdef LINUX @@ -390,156 +389,164 @@ void esp_monitor_print(esp_monitor_args_t args, esp_monitor_vals_t vals) { #include "soc_locs.h" - int t, p, q, tile; + int t, p, q, tile; #ifdef LINUX - printf("\tWriting esp_monitor stats to specified file...\n"); + printf("\tWriting esp_monitor stats to specified file...\n"); #endif - print_mon( "\n***************************************************\n"); - print_mon( "******************ESP MONITOR STATS****************\n"); - print_mon( "***************************************************\n"); - - print_mon( "\n********************MEMORY STATS*******************\n"); - if (args.read_mode == ESP_MON_READ_ALL || (args.read_mask & (1 << ESP_MON_READ_DDR_ACCESSES))) - for (t = 0; t < SOC_NMEM; t++) - print_mon( "Off-chip memory accesses at mem tile %d: %d\n", t, vals.ddr_accesses[t]); - - //mem_reqs - if (args.read_mode == ESP_MON_READ_ALL || (args.read_mask & (1 << ESP_MON_READ_MEM_REQS))) - for (t = 0; t < SOC_NMEM; t++){ - tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; - print_mon( "Coherence requests to LLC %d: %d\n", t, vals.mem_reqs[t].coh_reqs); - print_mon( "Coherence forwards from LLC %d: %d\n", t, vals.mem_reqs[t].coh_fwds); - print_mon( "Coherence responses received by LLC %d: %d\n", t, vals.mem_reqs[t].coh_rsps_rcv); - print_mon( "Coherence responses sent by LLC %d: %d\n", t, vals.mem_reqs[t].coh_rsps_snd); - print_mon( "DMA requests to mem tile %d: %d\n", t, vals.mem_reqs[t].dma_reqs); - print_mon( "DMA responses from mem tile %d: %d\n", t, vals.mem_reqs[t].dma_rsps); - print_mon( "Coherent DMA requests to LLC %d: %d\n", t, vals.mem_reqs[t].coh_dma_reqs); - print_mon( "Coherent DMA responses from LLC %d: %d\n", t, vals.mem_reqs[t].coh_dma_rsps); - } - - print_mon( "\n********************CACHE STATS********************\n"); - //l2 stats - if (args.read_mode == ESP_MON_READ_ALL || (args.read_mask & (1 << ESP_MON_READ_L2_STATS))){ - for (t = 0; t < SOC_NCPU; t++) { - tile = cpu_locs[t].row * SOC_COLS + cpu_locs[t].col; - print_mon( "L2 hits for CPU %d: %d\n", t, vals.l2_stats[tile].hits); - print_mon( "L2 misses for CPU %d: %d\n", t, vals.l2_stats[tile].misses); - } + print_mon("\n***************************************************\n"); + print_mon("******************ESP MONITOR STATS****************\n"); + print_mon("***************************************************\n"); + + print_mon("\n********************MEMORY STATS*******************\n"); + if (args.read_mode == ESP_MON_READ_ALL || (args.read_mask & (1 << ESP_MON_READ_DDR_ACCESSES))) + for (t = 0; t < SOC_NMEM; t++) + print_mon("Off-chip memory accesses at mem tile %d: %d\n", t, vals.ddr_accesses[t]); + + // mem_reqs + if (args.read_mode == ESP_MON_READ_ALL || (args.read_mask & (1 << ESP_MON_READ_MEM_REQS))) + for (t = 0; t < SOC_NMEM; t++) { + tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; + print_mon("Coherence requests to LLC %d: %d\n", t, vals.mem_reqs[t].coh_reqs); + print_mon("Coherence forwards from LLC %d: %d\n", t, vals.mem_reqs[t].coh_fwds); + print_mon("Coherence responses received by LLC %d: %d\n", t, + vals.mem_reqs[t].coh_rsps_rcv); + print_mon("Coherence responses sent by LLC %d: %d\n", t, vals.mem_reqs[t].coh_rsps_snd); + print_mon("DMA requests to mem tile %d: %d\n", t, vals.mem_reqs[t].dma_reqs); + print_mon("DMA responses from mem tile %d: %d\n", t, vals.mem_reqs[t].dma_rsps); + print_mon("Coherent DMA requests to LLC %d: %d\n", t, vals.mem_reqs[t].coh_dma_reqs); + print_mon("Coherent DMA responses from LLC %d: %d\n", t, vals.mem_reqs[t].coh_dma_rsps); + } + + print_mon("\n********************CACHE STATS********************\n"); + // l2 stats + if (args.read_mode == ESP_MON_READ_ALL || (args.read_mask & (1 << ESP_MON_READ_L2_STATS))) { + for (t = 0; t < SOC_NCPU; t++) { + tile = cpu_locs[t].row * SOC_COLS + cpu_locs[t].col; + print_mon("L2 hits for CPU %d: %d\n", t, vals.l2_stats[tile].hits); + print_mon("L2 misses for CPU %d: %d\n", t, vals.l2_stats[tile].misses); + } #ifdef ACCS_PRESENT - for (t = 0; t < SOC_NACC; t++) { - if (acc_has_l2[t]) { - tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; - print_mon( "L2 hits for acc %d: %d\n", t, vals.l2_stats[tile].hits); - print_mon( "L2 misses for acc %d: %d\n", t, vals.l2_stats[tile].misses); - } - } + for (t = 0; t < SOC_NACC; t++) { + if (acc_has_l2[t]) { + tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; + print_mon("L2 hits for acc %d: %d\n", t, vals.l2_stats[tile].hits); + print_mon("L2 misses for acc %d: %d\n", t, vals.l2_stats[tile].misses); + } + } #endif - } - - //llc stats - if (args.read_mode == ESP_MON_READ_ALL || (args.read_mask & (1 << ESP_MON_READ_LLC_STATS))) - for (t = 0; t < SOC_NMEM; t++) { - tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; - print_mon( "Hits at LLC %d: %d\n", t, vals.l2_stats[tile].hits); - print_mon( "Misses at LLC %d: %d\n", t, vals.l2_stats[tile].misses); - } - - print_mon( "\n****************ACCELERATOR STATS******************\n"); - //acc stats + } + + // llc stats + if (args.read_mode == ESP_MON_READ_ALL || (args.read_mask & (1 << ESP_MON_READ_LLC_STATS))) + for (t = 0; t < SOC_NMEM; t++) { + tile = mem_locs[t].row * SOC_COLS + mem_locs[t].col; + print_mon("Hits at LLC %d: %d\n", t, vals.l2_stats[tile].hits); + print_mon("Misses at LLC %d: %d\n", t, vals.l2_stats[tile].misses); + } + + print_mon("\n****************ACCELERATOR STATS******************\n"); + // acc stats #ifdef ACCS_PRESENT - if (args.read_mode == ESP_MON_READ_ALL){ - for (t = 0; t < SOC_NACC; t++) { - tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; - print_mon( "Accelerator %d TLB-loading cycles: %d\n", t, vals.acc_stats[t].acc_tlb); - print_mon( "Accelerator %d mem cycles: %llu\n", t - , ((long long unsigned int) vals.acc_stats[t].acc_mem_lo) - | (((long long unsigned int) vals.acc_stats[t].acc_mem_hi) << 32)); - print_mon( "Accelerator %d total cycles: %llu\n", t - , ((long long unsigned int) vals.acc_stats[t].acc_tot_lo) - | (((long long unsigned int) vals.acc_stats[t].acc_tot_hi) << 32)); - print_mon( "Accelerator %d invocations: %d\n", t, vals.acc_stats[t].acc_invocations); - } - } else if (args.read_mask & (1 << ESP_MON_READ_ACC_STATS)) { - print_mon( "Accelerator %d TLB-loading cycles: %d\n", args.acc_index, vals.acc_stats[args.acc_index].acc_tlb); - print_mon( "Accelerator %d mem cycles: %llu\n", args.acc_index - , ((long long unsigned int) vals.acc_stats[args.acc_index].acc_mem_lo) - | (((long long unsigned int) vals.acc_stats[args.acc_index].acc_mem_hi) << 32)); - print_mon( "Accelerator %d total cycles: %llu\n", args.acc_index - , ((long long unsigned int) vals.acc_stats[args.acc_index].acc_tot_lo) - | (((long long unsigned int) vals.acc_stats[args.acc_index].acc_tot_hi) << 32)); - print_mon( "Accelerator %d invocations: %d\n", args.acc_index, vals.acc_stats[args.acc_index].acc_invocations); - } + if (args.read_mode == ESP_MON_READ_ALL) { + for (t = 0; t < SOC_NACC; t++) { + tile = acc_locs[t].row * SOC_COLS + acc_locs[t].col; + print_mon("Accelerator %d TLB-loading cycles: %d\n", t, vals.acc_stats[t].acc_tlb); + print_mon("Accelerator %d mem cycles: %llu\n", t, + ((long long unsigned int)vals.acc_stats[t].acc_mem_lo) | + (((long long unsigned int)vals.acc_stats[t].acc_mem_hi) << 32)); + print_mon("Accelerator %d total cycles: %llu\n", t, + ((long long unsigned int)vals.acc_stats[t].acc_tot_lo) | + (((long long unsigned int)vals.acc_stats[t].acc_tot_hi) << 32)); + print_mon("Accelerator %d invocations: %d\n", t, vals.acc_stats[t].acc_invocations); + } + } + else if (args.read_mask & (1 << ESP_MON_READ_ACC_STATS)) { + print_mon("Accelerator %d TLB-loading cycles: %d\n", args.acc_index, + vals.acc_stats[args.acc_index].acc_tlb); + print_mon("Accelerator %d mem cycles: %llu\n", args.acc_index, + ((long long unsigned int)vals.acc_stats[args.acc_index].acc_mem_lo) | + (((long long unsigned int)vals.acc_stats[args.acc_index].acc_mem_hi) << 32)); + print_mon("Accelerator %d total cycles: %llu\n", args.acc_index, + ((long long unsigned int)vals.acc_stats[args.acc_index].acc_tot_lo) | + (((long long unsigned int)vals.acc_stats[args.acc_index].acc_tot_hi) << 32)); + print_mon("Accelerator %d invocations: %d\n", args.acc_index, + vals.acc_stats[args.acc_index].acc_invocations); + } #endif - print_mon( "\n*********************DVFS STATS********************\n"); - //dvfs - if (args.read_mode == ESP_MON_READ_ALL) { - for (t = 0; t < SOC_NTILES; t++) - for (p = 0; p < DVFS_OP_POINTS; p++) - print_mon( "DVFS Cycles for tile %d at operating point %d: %d\n" - , t, p, vals.dvfs_op[t][p]); - } else if (args.read_mask & (1 << ESP_MON_READ_DVFS_OP)) { - for (p = 0; p < DVFS_OP_POINTS; p++) - print_mon( "DVFS Cycles for tile %d at operating point %d: %d\n" - , args.tile_index, p, vals.dvfs_op[args.tile_index][p]); - } - - print_mon( "\n*********************NOC STATS*********************\n"); - //noc inject - if (args.read_mode == ESP_MON_READ_ALL) { - for (t = 0; t < SOC_NTILES; t++) - for (p = 0; p < NOC_PLANES; p++) - print_mon( "NoC packets injected at tile %d on plane %d: %d\n" - , t, p, vals.noc_injects[t][p]); - } else if (args.read_mask & (1 << ESP_MON_READ_NOC_INJECTS)) { - for (p = 0; p < NOC_PLANES; p++) - print_mon( "NoC packets injected at tile %d on plane %d: %d\n" - , args.tile_index, p, vals.noc_injects[args.tile_index][p]); - } - //noc queue full tile - if (args.read_mode == ESP_MON_READ_ALL) { - for (t = 0; t < SOC_NTILES; t++) - for (p = 0; p < NOC_PLANES; p++) - for (q = 0; q < NOC_QUEUES; q++) - print_mon( "NoC backpressure cycles at tile %d on plane %d for queue %d: %d\n" - , t, p, q, vals.noc_queue_full[t][p][q]); - } else if (args.read_mask & (1 << ESP_MON_READ_NOC_QUEUE_FULL_TILE)) { - for (p = 0; p < NOC_PLANES; p++) - for (q = 0; q < NOC_QUEUES; q++) - print_mon( "NoC backpressure cycles at tile %d on plane %d for queue %d: %d\n" - , args.tile_index, p, q, vals.noc_queue_full[args.tile_index][p][q]); - } else if (args.read_mask & (1 << ESP_MON_READ_NOC_QUEUE_FULL_PLANE)) { - for (t = 0; t < SOC_NTILES; t++) - for (q = 0; q < NOC_QUEUES; q++) - print_mon( "NoC backpressure cycles at tile %d on plane %d for queue %d: %d\n" - , t, args.noc_index, q, vals.noc_queue_full[t][args.noc_index][q]); - } + print_mon("\n*********************DVFS STATS********************\n"); + // dvfs + if (args.read_mode == ESP_MON_READ_ALL) { + for (t = 0; t < SOC_NTILES; t++) + for (p = 0; p < DVFS_OP_POINTS; p++) + print_mon("DVFS Cycles for tile %d at operating point %d: %d\n", t, p, + vals.dvfs_op[t][p]); + } + else if (args.read_mask & (1 << ESP_MON_READ_DVFS_OP)) { + for (p = 0; p < DVFS_OP_POINTS; p++) + print_mon("DVFS Cycles for tile %d at operating point %d: %d\n", args.tile_index, p, + vals.dvfs_op[args.tile_index][p]); + } + + print_mon("\n*********************NOC STATS*********************\n"); + // noc inject + if (args.read_mode == ESP_MON_READ_ALL) { + for (t = 0; t < SOC_NTILES; t++) + for (p = 0; p < NOC_PLANES; p++) + print_mon("NoC packets injected at tile %d on plane %d: %d\n", t, p, + vals.noc_injects[t][p]); + } + else if (args.read_mask & (1 << ESP_MON_READ_NOC_INJECTS)) { + for (p = 0; p < NOC_PLANES; p++) + print_mon("NoC packets injected at tile %d on plane %d: %d\n", args.tile_index, p, + vals.noc_injects[args.tile_index][p]); + } + // noc queue full tile + if (args.read_mode == ESP_MON_READ_ALL) { + for (t = 0; t < SOC_NTILES; t++) + for (p = 0; p < NOC_PLANES; p++) + for (q = 0; q < NOC_QUEUES; q++) + print_mon("NoC backpressure cycles at tile %d on plane %d for queue %d: %d\n", + t, p, q, vals.noc_queue_full[t][p][q]); + } + else if (args.read_mask & (1 << ESP_MON_READ_NOC_QUEUE_FULL_TILE)) { + for (p = 0; p < NOC_PLANES; p++) + for (q = 0; q < NOC_QUEUES; q++) + print_mon("NoC backpressure cycles at tile %d on plane %d for queue %d: %d\n", + args.tile_index, p, q, vals.noc_queue_full[args.tile_index][p][q]); + } + else if (args.read_mask & (1 << ESP_MON_READ_NOC_QUEUE_FULL_PLANE)) { + for (t = 0; t < SOC_NTILES; t++) + for (q = 0; q < NOC_QUEUES; q++) + print_mon("NoC backpressure cycles at tile %d on plane %d for queue %d: %d\n", t, + args.noc_index, q, vals.noc_queue_full[t][args.noc_index][q]); + } } #ifdef LINUX -esp_monitor_vals_t* esp_monitor_vals_alloc() +esp_monitor_vals_t *esp_monitor_vals_alloc() { - esp_monitor_vals_t *ptr = malloc(sizeof(esp_monitor_vals_t)); - esp_mon_alloc_node_t *node = malloc(sizeof(esp_mon_alloc_node_t)); - node->vals = ptr; - node->next = mon_alloc_head; - mon_alloc_head = node; - return ptr; + esp_monitor_vals_t *ptr = malloc(sizeof(esp_monitor_vals_t)); + esp_mon_alloc_node_t *node = malloc(sizeof(esp_mon_alloc_node_t)); + node->vals = ptr; + node->next = mon_alloc_head; + mon_alloc_head = node; + return ptr; } void esp_monitor_free() { - munmap_monitors(); - - esp_mon_alloc_node_t *cur = mon_alloc_head; - esp_mon_alloc_node_t *next; - while (cur) { - next = cur->next; - free(cur->vals); - free(cur); - cur = next; - } + munmap_monitors(); + + esp_mon_alloc_node_t *cur = mon_alloc_head; + esp_mon_alloc_node_t *next; + while (cur) { + next = cur->next; + free(cur->vals); + free(cur); + cur = next; + } } #endif diff --git a/soft/common/drivers/common/utils/fft2_utils.c b/soft/common/drivers/common/utils/fft2_utils.c index cdb5188f24..da2afde68e 100644 --- a/soft/common/drivers/common/utils/fft2_utils.c +++ b/soft/common/drivers/common/utils/fft2_utils.c @@ -1,9 +1,8 @@ -#include #include +#include #include - /* * This determines the maximum admissible relative error between the accelerated * FFT2 and the software one. @@ -22,7 +21,7 @@ unsigned int fft2_rev(unsigned int v) { unsigned int r = v; - int s = sizeof(v) * CHAR_BIT - 1; + int s = sizeof(v) * CHAR_BIT - 1; for (v >>= 1; v; v >>= 1) { r <<= 1; @@ -37,7 +36,7 @@ void fft2_bit_reverse(float *w, unsigned int offset, unsigned int n, unsigned in { unsigned int i, s, shift; - s = sizeof(i) * CHAR_BIT - 1; + s = sizeof(i) * CHAR_BIT - 1; shift = s - bits + 1; for (i = 0; i < n; i++) { @@ -48,31 +47,30 @@ void fft2_bit_reverse(float *w, unsigned int offset, unsigned int n, unsigned in r >>= shift; if (i < r) { - t_real = w[2 * (offset + i)]; - t_imag = w[2 * (offset + i) + 1]; - w[2 * (offset + i)] = w[2 * (offset + r)]; + t_real = w[2 * (offset + i)]; + t_imag = w[2 * (offset + i) + 1]; + w[2 * (offset + i)] = w[2 * (offset + r)]; w[2 * (offset + i) + 1] = w[2 * (offset + r) + 1]; - w[2 * (offset + r)] = t_real; + w[2 * (offset + r)] = t_real; w[2 * (offset + r) + 1] = t_imag; } } - } - void fft2_do_shift(float *A0, unsigned int offset, unsigned int num_samples, unsigned int bits) { - int md = (num_samples/2); + int md = (num_samples / 2); unsigned oi; /* shift: */ - for(oi = 0; oi < md; oi++) { - unsigned int iidx = 2*(offset + oi); - unsigned int midx = 2*(offset + md + oi); - //printf("TEST: DO_SHIFT: offset %u : iidx %u %u midx %u %u\n", offset, iidx, (iidx+1), midx, (midx+1)); + for (oi = 0; oi < md; oi++) { + unsigned int iidx = 2 * (offset + oi); + unsigned int midx = 2 * (offset + md + oi); + // printf("TEST: DO_SHIFT: offset %u : iidx %u %u midx %u %u\n", offset, iidx, (iidx+1), + // midx, (midx+1)); float swap_rl, swap_im; - swap_rl = A0[iidx]; - swap_im = A0[iidx + 1]; + swap_rl = A0[iidx]; + swap_im = A0[iidx + 1]; A0[iidx] = A0[midx]; A0[iidx + 1] = A0[midx + 1]; A0[midx] = swap_rl; @@ -80,42 +78,44 @@ void fft2_do_shift(float *A0, unsigned int offset, unsigned int num_samples, uns } } - -int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, int do_inverse, int do_shift) +int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, int do_inverse, + int do_shift) { int nf; for (nf = 0; nf < nffts; nf++) { - unsigned int transform_length; - unsigned int a, b, i, j, bit; - float theta, t_real, t_imag, w_real, w_imag, s, t, s2, z_real, z_imag; + unsigned int transform_length; + unsigned int a, b, i, j, bit; + float theta, t_real, t_imag, w_real, w_imag, s, t, s2, z_real, z_imag; - unsigned int offset = nf * n; // This is the offset for start of nf=th FFT + unsigned int offset = nf * n; // This is the offset for start of nf=th FFT int sign; - //printf("TEST : Doing computation of FFT %u : data[%u] = %.15g\n", nf, 2*offset, data[2*offset]); + // printf("TEST : Doing computation of FFT %u : data[%u] = %.15g\n", nf, 2*offset, + // data[2*offset]); if (do_inverse) { sign = 1; if (do_shift) { - //printf("TEST: Calling Inverse-Do-Shift\n"); + // printf("TEST: Calling Inverse-Do-Shift\n"); fft2_do_shift(data, offset, n, logn); } - } else { + } + else { sign = -1; } - transform_length = 1; + transform_length = 1; // Do the bit-reverse fft2_bit_reverse(data, offset, n, logn); - /* calculation */ - for (bit = 0; bit < logn; bit++) { + /* calculation */ + for (bit = 0; bit < logn; bit++) { w_real = 1.0; w_imag = 0.0; - theta = 1.0 * sign * M_PI / (float) transform_length; + theta = 1.0 * sign * M_PI / (float)transform_length; - s = sin(theta); - t = sin(0.5 * theta); + s = sin(theta); + t = sin(0.5 * theta); s2 = 2.0 * t * t; for (a = 0; a < transform_length; a++) { @@ -130,10 +130,10 @@ int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, in t_imag = w_real * z_imag + w_imag * z_real; /* write the result */ - data[2*j] = data[2*i] - t_real; - data[2*j + 1] = data[2*i + 1] - t_imag; - data[2*i] += t_real; - data[2*i + 1] += t_imag; + data[2 * j] = data[2 * i] - t_real; + data[2 * j + 1] = data[2 * i + 1] - t_imag; + data[2 * i] += t_real; + data[2 * i + 1] += t_imag; } // for (b = 0 .. n by 2*transform_length /* adjust w */ @@ -144,10 +144,10 @@ int fft2_comp(float *data, unsigned nffts, unsigned int n, unsigned int logn, in } // for (a = 0 .. transform_length) transform_length *= 2; - } // for (bit = 0 .. logn ) + } // for (bit = 0 .. logn ) if ((!do_inverse) && do_shift) { - //printf("TEST: Calling Non-Inverse Do-Shift\n"); + // printf("TEST: Calling Non-Inverse Do-Shift\n"); fft2_do_shift(data, offset, n, logn); } diff --git a/soft/common/drivers/linux/contig_alloc/contig_alloc.c b/soft/common/drivers/linux/contig_alloc/contig_alloc.c index aeacdd80f3..dd7dd5fbc7 100644 --- a/soft/common/drivers/linux/contig_alloc/contig_alloc.c +++ b/soft/common/drivers/linux/contig_alloc/contig_alloc.c @@ -17,31 +17,31 @@ * - chunk_log: log2 of the size of each memory chunk. Default: 20 (i.e. 1MB). */ //#include -#include -#include #include #include +#include +#include #include +#include +#include #include +#include #include -#include #include #include -#include -#include #include #include struct contig_chunk { - unsigned long paddr; - int ddr_node; - struct list_head node; /* head: inactive_chunks or desc->alloc_list */ + unsigned long paddr; + int ddr_node; + struct list_head node; /* head: inactive_chunks or desc->alloc_list */ }; struct contig_file { - struct list_head desc_list; + struct list_head desc_list; }; #define PFX "contig_alloc: " @@ -72,297 +72,289 @@ static long contig_ioctl(struct file *, unsigned int, unsigned long); static int contig_mmap(struct file *, struct vm_area_struct *); static const struct file_operations contig_fops = { - .owner = THIS_MODULE, - .open = contig_open, - .release = contig_release, - .unlocked_ioctl = contig_ioctl, - .mmap = contig_mmap, + .owner = THIS_MODULE, + .open = contig_open, + .release = contig_release, + .unlocked_ioctl = contig_ioctl, + .mmap = contig_mmap, }; static struct contig_desc *contig_alloc_descriptor(unsigned int n_chunks) { - struct contig_desc *desc; + struct contig_desc *desc; - desc = kmalloc(sizeof(*desc), GFP_KERNEL); - if (unlikely(desc == NULL)) - return ERR_PTR(-ENOMEM); + desc = kmalloc(sizeof(*desc), GFP_KERNEL); + if (unlikely(desc == NULL)) return ERR_PTR(-ENOMEM); - desc->arr = kmalloc_array(n_chunks, sizeof(unsigned long), GFP_KERNEL); - if (unlikely(desc->arr == NULL)) - goto err_arr; + desc->arr = kmalloc_array(n_chunks, sizeof(unsigned long), GFP_KERNEL); + if (unlikely(desc->arr == NULL)) goto err_arr; #ifndef __riscv - desc->arr_dma_addr = dma_map_single(NULL, desc->arr, n_chunks * sizeof(dma_addr_t), DMA_TO_DEVICE); + desc->arr_dma_addr = + dma_map_single(NULL, desc->arr, n_chunks * sizeof(dma_addr_t), DMA_TO_DEVICE); #else - desc->arr_dma_addr = virt_to_phys(desc->arr); + desc->arr_dma_addr = virt_to_phys(desc->arr); #endif - if (unlikely(dma_mapping_error(NULL, desc->arr_dma_addr))) - goto err_dma; + if (unlikely(dma_mapping_error(NULL, desc->arr_dma_addr))) goto err_dma; - desc->n = n_chunks; - INIT_LIST_HEAD(&desc->alloc_list); - return desc; + desc->n = n_chunks; + INIT_LIST_HEAD(&desc->alloc_list); + return desc; - err_dma: - kfree(desc->arr); - err_arr: - kfree(desc); - return ERR_PTR(-ENOMEM); +err_dma: + kfree(desc->arr); +err_arr: + kfree(desc); + return ERR_PTR(-ENOMEM); } static void contig_free_descriptor(struct contig_desc *desc) { #ifndef __riscv - dma_unmap_single(NULL, desc->arr_dma_addr, desc->n * sizeof(dma_addr_t), DMA_TO_DEVICE); + dma_unmap_single(NULL, desc->arr_dma_addr, desc->n * sizeof(dma_addr_t), DMA_TO_DEVICE); #endif - kfree(desc->arr); - kfree(desc); + kfree(desc->arr); + kfree(desc); } static int get_next_ddr_node(int ddr_node, int first_ddr_node) { - BUG_ON(mem_allocated[ddr_node] > mem_size[ddr_node]); - while (mem_allocated[ddr_node] == mem_size[ddr_node]) { - ddr_node = (ddr_node + 1) % nddr; - BUG_ON(ddr_node == first_ddr_node); - } - return ddr_node; + BUG_ON(mem_allocated[ddr_node] > mem_size[ddr_node]); + while (mem_allocated[ddr_node] == mem_size[ddr_node]) { + ddr_node = (ddr_node + 1) % nddr; + BUG_ON(ddr_node == first_ddr_node); + } + return ddr_node; } static void allocate_chunk(struct contig_desc **desc, int ddr_node, int chunk_index) { - struct contig_chunk *ch; + struct contig_chunk *ch; - BUG_ON(list_empty(&inactive_chunks[ddr_node])); - ch = list_first_entry(&inactive_chunks[ddr_node], struct contig_chunk, node); - /* pr_info("Allocating chunk %d @ address 0x%08lx\n", chunk_index, ch->paddr); */ - list_del(&ch->node); - list_add(&ch->node, &(*desc)->alloc_list); - (*desc)->arr[chunk_index] = ch->paddr; - mem_allocated[ddr_node] += chunk_size; + BUG_ON(list_empty(&inactive_chunks[ddr_node])); + ch = list_first_entry(&inactive_chunks[ddr_node], struct contig_chunk, node); + /* pr_info("Allocating chunk %d @ address 0x%08lx\n", chunk_index, ch->paddr); */ + list_del(&ch->node); + list_add(&ch->node, &(*desc)->alloc_list); + (*desc)->arr[chunk_index] = ch->paddr; + mem_allocated[ddr_node] += chunk_size; } -static int contig_alloc_preferred(struct contig_desc *desc, const struct contig_alloc_params *params) +static int contig_alloc_preferred(struct contig_desc *desc, + const struct contig_alloc_params *params) { - unsigned long allocated = 0; - int ddr_node; - int i; + unsigned long allocated = 0; + int ddr_node; + int i; - unsigned int n_per_node_max; - unsigned int n_per_node[MAX_DDR_NODES]; - for (i = 0; i < nddr; i++) - n_per_node[i] = 0; + unsigned int n_per_node_max; + unsigned int n_per_node[MAX_DDR_NODES]; + for (i = 0; i < nddr; i++) + n_per_node[i] = 0; - ddr_node = params->pol.first.ddr_node; - for (i = 0; i < desc->n; i++) { - ddr_node = get_next_ddr_node(ddr_node, params->pol.first.ddr_node); - allocate_chunk(&desc, ddr_node, i); - allocated += chunk_size; - n_per_node[ddr_node]++; - } - BUG_ON(allocated != desc->n * chunk_size); + ddr_node = params->pol.first.ddr_node; + for (i = 0; i < desc->n; i++) { + ddr_node = get_next_ddr_node(ddr_node, params->pol.first.ddr_node); + allocate_chunk(&desc, ddr_node, i); + allocated += chunk_size; + n_per_node[ddr_node]++; + } + BUG_ON(allocated != desc->n * chunk_size); - /* Compute which DDR holds most of the data */ - ddr_node = 0; - n_per_node_max = n_per_node[0]; + /* Compute which DDR holds most of the data */ + ddr_node = 0; + n_per_node_max = n_per_node[0]; - for (i = 1; i < nddr; i++) - if (n_per_node[i] > n_per_node_max) { - ddr_node = i; - n_per_node_max = n_per_node[i]; - } - desc->most_allocated = ddr_node; + for (i = 1; i < nddr; i++) + if (n_per_node[i] > n_per_node_max) { + ddr_node = i; + n_per_node_max = n_per_node[i]; + } + desc->most_allocated = ddr_node; - return 0; + return 0; } static bool least_loaded_alloc_ok(unsigned int n_chunks) { - int i; - for (i = 0; i < nddr; i++) - if (mem_size[i] - mem_allocated[i] >= n_chunks * chunk_size) - return true; - return false; + int i; + for (i = 0; i < nddr; i++) + if (mem_size[i] - mem_allocated[i] >= n_chunks * chunk_size) return true; + return false; } static int get_least_loaded_ddr_node(unsigned int n_chunks, unsigned int threshold) { - int i; - unsigned long min_allocated = mem_size[1]; - int least_loaded = 0; - unsigned long tba = n_chunks * chunk_size; - unsigned long th = threshold * chunk_size; + int i; + unsigned long min_allocated = mem_size[1]; + int least_loaded = 0; + unsigned long tba = n_chunks * chunk_size; + unsigned long th = threshold * chunk_size; - for (i = 1; i < nddr; i++) - if (mem_allocated[i] <= min_allocated && mem_size[i] - mem_allocated[i] >= tba) { - min_allocated = mem_allocated[i]; - least_loaded = i; - } + for (i = 1; i < nddr; i++) + if (mem_allocated[i] <= min_allocated && mem_size[i] - mem_allocated[i] >= tba) { + min_allocated = mem_allocated[i]; + least_loaded = i; + } - if (mem_allocated[0] + th < min_allocated && mem_size[0] - mem_allocated[0] >= tba) - return 0; - else - return least_loaded; + if (mem_allocated[0] + th < min_allocated && mem_size[0] - mem_allocated[0] >= tba) return 0; + else + return least_loaded; } -static int contig_alloc_least_loaded(struct contig_desc *desc, const struct contig_alloc_params *params) +static int contig_alloc_least_loaded(struct contig_desc *desc, + const struct contig_alloc_params *params) { - unsigned long allocated = 0; - int ddr_node; - int i; + unsigned long allocated = 0; + int ddr_node; + int i; - if (unlikely(!least_loaded_alloc_ok(desc->n))) - return -ENOMEM; + if (unlikely(!least_loaded_alloc_ok(desc->n))) return -ENOMEM; - ddr_node = get_least_loaded_ddr_node(desc->n, params->pol.lloaded.threshold); - for (i = 0; i < desc->n; i++) { - allocate_chunk(&desc, ddr_node, i); - allocated += chunk_size; - } - BUG_ON(allocated != desc->n * chunk_size); + ddr_node = get_least_loaded_ddr_node(desc->n, params->pol.lloaded.threshold); + for (i = 0; i < desc->n; i++) { + allocate_chunk(&desc, ddr_node, i); + allocated += chunk_size; + } + BUG_ON(allocated != desc->n * chunk_size); - desc->most_allocated = ddr_node; + desc->most_allocated = ddr_node; - return 0; + return 0; } static int contig_alloc_balanced(struct contig_desc *desc, const struct contig_alloc_params *params) { - unsigned long allocated = 0; - int next_ddr_node; - int cluster_chunk; - int ddr_node; - int i; + unsigned long allocated = 0; + int next_ddr_node; + int cluster_chunk; + int ddr_node; + int i; - unsigned int n_per_node_max; - unsigned int n_per_node[MAX_DDR_NODES]; - for (i = 0; i < nddr; i++) - n_per_node[i] = 0; + unsigned int n_per_node_max; + unsigned int n_per_node[MAX_DDR_NODES]; + for (i = 0; i < nddr; i++) + n_per_node[i] = 0; - ddr_node = get_least_loaded_ddr_node(1, params->pol.balanced.threshold); + ddr_node = get_least_loaded_ddr_node(1, params->pol.balanced.threshold); - cluster_chunk = 0; - for (i = 0; i < desc->n; i++) { - if (cluster_chunk == params->pol.balanced.cluster_size) { - next_ddr_node = (ddr_node + 1) % nddr; - next_ddr_node = get_next_ddr_node(next_ddr_node, next_ddr_node); - } else { - next_ddr_node = get_next_ddr_node(ddr_node, ddr_node); - } + cluster_chunk = 0; + for (i = 0; i < desc->n; i++) { + if (cluster_chunk == params->pol.balanced.cluster_size) { + next_ddr_node = (ddr_node + 1) % nddr; + next_ddr_node = get_next_ddr_node(next_ddr_node, next_ddr_node); + } + else { + next_ddr_node = get_next_ddr_node(ddr_node, ddr_node); + } - if (ddr_node != next_ddr_node) { - ddr_node = next_ddr_node; - cluster_chunk = 1; - } else { - cluster_chunk++; - } + if (ddr_node != next_ddr_node) { + ddr_node = next_ddr_node; + cluster_chunk = 1; + } + else { + cluster_chunk++; + } - allocate_chunk(&desc, ddr_node, i); - allocated += chunk_size; + allocate_chunk(&desc, ddr_node, i); + allocated += chunk_size; - n_per_node[ddr_node]++; - } - BUG_ON(allocated != desc->n * chunk_size); + n_per_node[ddr_node]++; + } + BUG_ON(allocated != desc->n * chunk_size); - /* Compute which DDR holds most of the data */ - ddr_node = 0; - n_per_node_max = n_per_node[0]; + /* Compute which DDR holds most of the data */ + ddr_node = 0; + n_per_node_max = n_per_node[0]; - for (i = 1; i < nddr; i++) - if (n_per_node[i] > n_per_node_max) { - ddr_node = i; - n_per_node_max = n_per_node[i]; - } - desc->most_allocated = ddr_node; + for (i = 1; i < nddr; i++) + if (n_per_node[i] > n_per_node_max) { + ddr_node = i; + n_per_node_max = n_per_node[i]; + } + desc->most_allocated = ddr_node; - return 0; + return 0; } -static struct contig_desc *__contig_alloc_chunks(const struct contig_alloc_params *params, unsigned int n_chunks) +static struct contig_desc *__contig_alloc_chunks(const struct contig_alloc_params *params, + unsigned int n_chunks) { - struct contig_desc *desc; - int rc; + struct contig_desc *desc; + int rc; - desc = contig_alloc_descriptor(n_chunks); - if (unlikely(IS_ERR(desc))) - return desc; + desc = contig_alloc_descriptor(n_chunks); + if (unlikely(IS_ERR(desc))) return desc; - switch (params->policy) { - case CONTIG_ALLOC_PREFERRED: - rc = contig_alloc_preferred(desc, params); - break; - case CONTIG_ALLOC_LEAST_LOADED: - rc = contig_alloc_least_loaded(desc, params); - break; - case CONTIG_ALLOC_BALANCED: - rc = contig_alloc_balanced(desc, params); - break; - default: - BUG(); - } + switch (params->policy) { + case CONTIG_ALLOC_PREFERRED: rc = contig_alloc_preferred(desc, params); break; + case CONTIG_ALLOC_LEAST_LOADED: rc = contig_alloc_least_loaded(desc, params); break; + case CONTIG_ALLOC_BALANCED: rc = contig_alloc_balanced(desc, params); break; + default: BUG(); + } - if (rc) { - contig_free_descriptor(desc); - return ERR_PTR(rc); - } + if (rc) { + contig_free_descriptor(desc); + return ERR_PTR(rc); + } - list_add(&desc->desc_node, &desc_list); - return desc; + list_add(&desc->desc_node, &desc_list); + return desc; } -static struct contig_desc *__contig_alloc(const struct contig_alloc_params *params, unsigned long size) +static struct contig_desc *__contig_alloc(const struct contig_alloc_params *params, + unsigned long size) { - unsigned long mem_free = 0; - unsigned int n_chunks; - int i; + unsigned long mem_free = 0; + unsigned int n_chunks; + int i; - for (i = 0; i < nddr; i++) - mem_free += mem_size[i] - mem_allocated[i]; + for (i = 0; i < nddr; i++) + mem_free += mem_size[i] - mem_allocated[i]; - if (size > mem_free) - return ERR_PTR(-ENOMEM); + if (size > mem_free) return ERR_PTR(-ENOMEM); - n_chunks = DIV_ROUND_UP(size, chunk_size); - BUG_ON(n_chunks > mem_free / chunk_size); - return __contig_alloc_chunks(params, n_chunks); + n_chunks = DIV_ROUND_UP(size, chunk_size); + BUG_ON(n_chunks > mem_free / chunk_size); + return __contig_alloc_chunks(params, n_chunks); } struct contig_desc *contig_alloc(const struct contig_alloc_params *params, unsigned long size) { - struct contig_desc *ret; + struct contig_desc *ret; - if (unlikely(size == 0)) - return ERR_PTR(-EINVAL); + if (unlikely(size == 0)) return ERR_PTR(-EINVAL); - mutex_lock(&contig_lock); - ret = __contig_alloc(params, size); - mutex_unlock(&contig_lock); + mutex_lock(&contig_lock); + ret = __contig_alloc(params, size); + mutex_unlock(&contig_lock); - return ret; + return ret; } EXPORT_SYMBOL_GPL(contig_alloc); void __contig_free(struct contig_desc *desc) { - struct contig_chunk *ch, *nxt; - unsigned int deallocated = 0; + struct contig_chunk *ch, *nxt; + unsigned int deallocated = 0; - list_for_each_entry_safe(ch, nxt, &desc->alloc_list, node) { - list_del(&ch->node); - list_add(&ch->node, &inactive_chunks[ch->ddr_node]); - deallocated += chunk_size; - mem_allocated[ch->ddr_node] -= chunk_size; - } - BUG_ON(deallocated != desc->n * chunk_size); - list_del(&desc->desc_node); - contig_free_descriptor(desc); + list_for_each_entry_safe(ch, nxt, &desc->alloc_list, node) + { + list_del(&ch->node); + list_add(&ch->node, &inactive_chunks[ch->ddr_node]); + deallocated += chunk_size; + mem_allocated[ch->ddr_node] -= chunk_size; + } + BUG_ON(deallocated != desc->n * chunk_size); + list_del(&desc->desc_node); + contig_free_descriptor(desc); } void contig_free(struct contig_desc *desc) { - mutex_lock(&contig_lock); - __contig_free(desc); - mutex_unlock(&contig_lock); + mutex_lock(&contig_lock); + __contig_free(desc); + mutex_unlock(&contig_lock); } EXPORT_SYMBOL_GPL(contig_free); @@ -372,364 +364,333 @@ EXPORT_SYMBOL_GPL(contig_free); */ struct contig_desc *contig_khandle_to_desc(contig_khandle_t khandle) { - struct contig_desc *handle = (struct contig_desc *)khandle; - struct contig_desc *desc; + struct contig_desc *handle = (struct contig_desc *)khandle; + struct contig_desc *desc; - mutex_lock(&contig_lock); - list_for_each_entry(desc, &desc_list, desc_node) { - if (desc == handle) - break; - } - mutex_unlock(&contig_lock); + mutex_lock(&contig_lock); + list_for_each_entry(desc, &desc_list, desc_node) + { + if (desc == handle) break; + } + mutex_unlock(&contig_lock); - return desc == handle ? desc : NULL; + return desc == handle ? desc : NULL; } EXPORT_SYMBOL_GPL(contig_khandle_to_desc); static void __contig_chunks_remove(void) { - struct contig_chunk *ch, *nxt; - int i; + struct contig_chunk *ch, *nxt; + int i; - for (i = 0; i < nddr; i++) - list_for_each_entry_safe(ch, nxt, &inactive_chunks[i], node) { - list_del(&ch->node); - kfree(ch); - } + for (i = 0; i < nddr; i++) + list_for_each_entry_safe(ch, nxt, &inactive_chunks[i], node) + { + list_del(&ch->node); + kfree(ch); + } } #ifdef CONFIG_BIGPHYS_AREA static unsigned long __init contig_chunk_paddr(struct contig_chunk *ch, int n_chunk) { - return virt_to_phys(bp_buf) + chunk_size * n_chunk; + return virt_to_phys(bp_buf) + chunk_size * n_chunk; } static int __init contig_phys_alloc(int n_chunks) { - bp_buf = bigphysarea_alloc(n_chunks * chunk_size); - if (bp_buf == NULL) - return -ENOMEM; - return 0; + bp_buf = bigphysarea_alloc(n_chunks * chunk_size); + if (bp_buf == NULL) return -ENOMEM; + return 0; } -static void contig_phys_free(void) -{ - bigphysarea_free(bp_buf, mem_size); -} +static void contig_phys_free(void) { bigphysarea_free(bp_buf, mem_size); } #else static unsigned long __init contig_chunk_paddr(int ddr_node, struct contig_chunk *ch, int n_chunk) { - return mem_start[ddr_node] + chunk_size * n_chunk; + return mem_start[ddr_node] + chunk_size * n_chunk; } -static int __init contig_phys_alloc(int n_chunks) -{ - return 0; -} +static int __init contig_phys_alloc(int n_chunks) { return 0; } -static void contig_phys_free(void) -{ } +static void contig_phys_free(void) {} #endif /* CONFIG_BIGPHYS_AREA */ static int __init contig_chunks_create(int ddr_node, int n_chunks) { - int i; + int i; - if (contig_phys_alloc(n_chunks)) - return -ENOMEM; + if (contig_phys_alloc(n_chunks)) return -ENOMEM; - for (i = 0; i < n_chunks; i++) { - struct contig_chunk *ch; + for (i = 0; i < n_chunks; i++) { + struct contig_chunk *ch; - ch = kmalloc(sizeof(*ch), GFP_KERNEL); - if (ch == NULL) - goto err; + ch = kmalloc(sizeof(*ch), GFP_KERNEL); + if (ch == NULL) goto err; - ch->paddr = contig_chunk_paddr(ddr_node, ch, i); - ch->ddr_node = ddr_node; - list_add_tail(&ch->node, &inactive_chunks[ddr_node]); - } - return 0; - err: - __contig_chunks_remove(); - contig_phys_free(); - return -ENOMEM; + ch->paddr = contig_chunk_paddr(ddr_node, ch, i); + ch->ddr_node = ddr_node; + list_add_tail(&ch->node, &inactive_chunks[ddr_node]); + } + return 0; +err: + __contig_chunks_remove(); + contig_phys_free(); + return -ENOMEM; } static int contig_open(struct inode *inode, struct file *file) { - struct contig_file *priv; + struct contig_file *priv; - priv = kmalloc(sizeof(*priv), GFP_KERNEL); - if (priv == NULL) - return -ENOMEM; - INIT_LIST_HEAD(&priv->desc_list); - file->private_data = priv; - return 0; + priv = kmalloc(sizeof(*priv), GFP_KERNEL); + if (priv == NULL) return -ENOMEM; + INIT_LIST_HEAD(&priv->desc_list); + file->private_data = priv; + return 0; } static int contig_release(struct inode *inode, struct file *file) { - struct contig_file *priv = file->private_data; - struct contig_desc *desc, *nxt; + struct contig_file *priv = file->private_data; + struct contig_desc *desc, *nxt; - list_for_each_entry_safe(desc, nxt, &priv->desc_list, file_node) { - list_del(&desc->file_node); - contig_free(desc); - } - kfree(priv); - return 0; + list_for_each_entry_safe(desc, nxt, &priv->desc_list, file_node) + { + list_del(&desc->file_node); + contig_free(desc); + } + kfree(priv); + return 0; } static bool contig_alloc_ok(const struct contig_alloc_params *params) { - switch (params->policy) { - case CONTIG_ALLOC_PREFERRED: - if (params->pol.first.ddr_node < 0 || params->pol.first.ddr_node > nddr) - return false; - break; - case CONTIG_ALLOC_LEAST_LOADED: - if (params->pol.lloaded.threshold < 0 || params->pol.lloaded.threshold > mem_size[0] / chunk_size) - return false; - break; - case CONTIG_ALLOC_BALANCED: - if (params->pol.balanced.threshold < 0 || params->pol.balanced.threshold > mem_size[0] / chunk_size) - return false; - if (params->pol.balanced.cluster_size < 1) - return false; - break; - default: - return false; - } - return true; + switch (params->policy) { + case CONTIG_ALLOC_PREFERRED: + if (params->pol.first.ddr_node < 0 || params->pol.first.ddr_node > nddr) return false; + break; + case CONTIG_ALLOC_LEAST_LOADED: + if (params->pol.lloaded.threshold < 0 || + params->pol.lloaded.threshold > mem_size[0] / chunk_size) + return false; + break; + case CONTIG_ALLOC_BALANCED: + if (params->pol.balanced.threshold < 0 || + params->pol.balanced.threshold > mem_size[0] / chunk_size) + return false; + if (params->pol.balanced.cluster_size < 1) return false; + break; + default: return false; + } + return true; } static long contig_alloc_ioctl(struct file *file, void __user *arg) { - struct contig_file *priv = file->private_data; - struct contig_alloc_req req; - struct contig_desc *desc; - - if (copy_from_user(&req, arg, sizeof(req))) - return -EFAULT; - if (req.arr == NULL) - return -EFAULT; - - if (!contig_alloc_ok(&req.params)) - return -EINVAL; - - desc = contig_alloc(&req.params, req.size); - if (IS_ERR(desc)) - return PTR_ERR(desc); - - if (desc->n > req.n_max) { - contig_free(desc); - return -EINVAL; - } - - if (copy_to_user(req.arr, desc->arr, sizeof(*desc->arr) * desc->n)) { - contig_free(desc); - return -EFAULT; - } - req.n = desc->n; - req.khandle = (contig_khandle_t)desc; - req.most_allocated = desc->most_allocated; - if (copy_to_user(arg, &req, sizeof(req))) { - contig_free(desc); - return -EFAULT; - } - list_add(&desc->file_node, &priv->desc_list); - return 0; + struct contig_file *priv = file->private_data; + struct contig_alloc_req req; + struct contig_desc *desc; + + if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; + if (req.arr == NULL) return -EFAULT; + + if (!contig_alloc_ok(&req.params)) return -EINVAL; + + desc = contig_alloc(&req.params, req.size); + if (IS_ERR(desc)) return PTR_ERR(desc); + + if (desc->n > req.n_max) { + contig_free(desc); + return -EINVAL; + } + + if (copy_to_user(req.arr, desc->arr, sizeof(*desc->arr) * desc->n)) { + contig_free(desc); + return -EFAULT; + } + req.n = desc->n; + req.khandle = (contig_khandle_t)desc; + req.most_allocated = desc->most_allocated; + if (copy_to_user(arg, &req, sizeof(req))) { + contig_free(desc); + return -EFAULT; + } + list_add(&desc->file_node, &priv->desc_list); + return 0; } static long contig_free_ioctl(struct file *file, contig_khandle_t __user *arg) { - struct contig_file *priv = file->private_data; - struct contig_desc *del, *desc, *next; - contig_khandle_t del_addr; - bool found = false; - - if (get_user(del_addr, arg)) - return -EFAULT; - del = (struct contig_desc *)del_addr; - - /* is it a valid descriptor for this file? */ - list_for_each_entry_safe(desc, next, &priv->desc_list, file_node) { - if (desc == del) { - list_del(&del->file_node); - found = true; - break; - } - } - if (!found) - return -EFAULT; - contig_free(del); - return 0; + struct contig_file *priv = file->private_data; + struct contig_desc *del, *desc, *next; + contig_khandle_t del_addr; + bool found = false; + + if (get_user(del_addr, arg)) return -EFAULT; + del = (struct contig_desc *)del_addr; + + /* is it a valid descriptor for this file? */ + list_for_each_entry_safe(desc, next, &priv->desc_list, file_node) + { + if (desc == del) { + list_del(&del->file_node); + found = true; + break; + } + } + if (!found) return -EFAULT; + contig_free(del); + return 0; } static long contig_chunk_size_ioctl(struct file *file, void __user *arg) { - if (put_user(contig_chunk_size_log, (unsigned long __user *)arg)) - return -EFAULT; - return 0; + if (put_user(contig_chunk_size_log, (unsigned long __user *)arg)) return -EFAULT; + return 0; } static long contig_do_ioctl(struct file *file, unsigned int cm, void __user *arg) { - switch (cm) { - case CONTIG_IOC_ALLOC: - return contig_alloc_ioctl(file, arg); - case CONTIG_IOC_FREE: - return contig_free_ioctl(file, arg); - case CONTIG_IOC_CHUNK_LOG: - return contig_chunk_size_ioctl(file, arg); - default: - return -ENOTTY; - } + switch (cm) { + case CONTIG_IOC_ALLOC: return contig_alloc_ioctl(file, arg); + case CONTIG_IOC_FREE: return contig_free_ioctl(file, arg); + case CONTIG_IOC_CHUNK_LOG: return contig_chunk_size_ioctl(file, arg); + default: return -ENOTTY; + } } static long contig_ioctl(struct file *file, unsigned int cm, unsigned long arg) { - return contig_do_ioctl(file, cm, (void __user *)arg); + return contig_do_ioctl(file, cm, (void __user *)arg); } static int contig_mmap(struct file *file, struct vm_area_struct *vma) { - int i, rc; - struct contig_desc *desc, *itr; - struct contig_file *priv = file->private_data; - long unsigned paddr = PFN_PHYS(vma->vm_pgoff); - bool found = false; - - mutex_lock(&contig_lock); - list_for_each_entry(itr, &priv->desc_list, file_node) { - if (itr->arr[0] == paddr) { - found = true; - desc = itr; - break; - } - } - mutex_unlock(&contig_lock); + int i, rc; + struct contig_desc *desc, *itr; + struct contig_file *priv = file->private_data; + long unsigned paddr = PFN_PHYS(vma->vm_pgoff); + bool found = false; - if (!found) { - pr_info("contig_alloc: descriptor for addres %08lX not found", paddr); - return -EFAULT; - } + mutex_lock(&contig_lock); + list_for_each_entry(itr, &priv->desc_list, file_node) + { + if (itr->arr[0] == paddr) { + found = true; + desc = itr; + break; + } + } + mutex_unlock(&contig_lock); + if (!found) { + pr_info("contig_alloc: descriptor for addres %08lX not found", paddr); + return -EFAULT; + } - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - for (i = 0; i < desc->n; i++) { - /* pr_info("contig_mmap: paddr[%d] = %08lX\n", i, desc->arr[i]); */ - rc = remap_pfn_range(vma, vma->vm_start + i * chunk_size, PHYS_PFN(desc->arr[i]), - chunk_size, vma->vm_page_prot); + for (i = 0; i < desc->n; i++) { + /* pr_info("contig_mmap: paddr[%d] = %08lX\n", i, desc->arr[i]); */ + rc = remap_pfn_range(vma, vma->vm_start + i * chunk_size, PHYS_PFN(desc->arr[i]), + chunk_size, vma->vm_page_prot); - if (rc) - return rc; - } + if (rc) return rc; + } - return 0; + return 0; } static int __init contig_create_file(void) { - contig_class = class_create(THIS_MODULE, "contig_alloc"); - if (IS_ERR(contig_class)) - return PTR_ERR(contig_class); + contig_class = class_create(THIS_MODULE, "contig_alloc"); + if (IS_ERR(contig_class)) return PTR_ERR(contig_class); - if (register_chrdev(CONTIG_MAJOR, "contig_alloc", &contig_fops)) - goto err_chrdev; + if (register_chrdev(CONTIG_MAJOR, "contig_alloc", &contig_fops)) goto err_chrdev; - if (IS_ERR(device_create(contig_class, NULL, MKDEV(CONTIG_MAJOR, CONTIG_MINOR), NULL, "contig_alloc"))) - goto err_device_create; + if (IS_ERR(device_create(contig_class, NULL, MKDEV(CONTIG_MAJOR, CONTIG_MINOR), NULL, + "contig_alloc"))) + goto err_device_create; - return 0; + return 0; - err_device_create: - unregister_chrdev(CONTIG_MAJOR, "contig_alloc"); - err_chrdev: - class_destroy(contig_class); - return -ENODEV; +err_device_create: + unregister_chrdev(CONTIG_MAJOR, "contig_alloc"); +err_chrdev: + class_destroy(contig_class); + return -ENODEV; } static void contig_remove_file(void) { - device_destroy(contig_class, MKDEV(CONTIG_MAJOR, CONTIG_MINOR)); - unregister_chrdev(CONTIG_MAJOR, "contig_alloc"); - class_destroy(contig_class); + device_destroy(contig_class, MKDEV(CONTIG_MAJOR, CONTIG_MINOR)); + unregister_chrdev(CONTIG_MAJOR, "contig_alloc"); + class_destroy(contig_class); } static int __init contig_init(void) { - int rc; - int i; + int rc; + int i; - if (contig_chunk_size_log >= 32) - return -EINVAL; - chunk_size = BIT(contig_chunk_size_log); + if (contig_chunk_size_log >= 32) return -EINVAL; + chunk_size = BIT(contig_chunk_size_log); #ifndef CONFIG_BIGPHYS_AREA - if (!mem_start[0]) - return -EINVAL; + if (!mem_start[0]) return -EINVAL; #endif - if (chunk_size < PAGE_SIZE) { - pr_err(PFX "chunk_size (0x%lx) < PAGE_SIZE (0x%lx)\n", - chunk_size, PAGE_SIZE); - return -EINVAL; - } - - for (i = 0; i < nddr; i++) { - INIT_LIST_HEAD(&inactive_chunks[i]); - if (mem_size[i] % chunk_size) { - pr_warn(PFX "chunk_size (0x%lx) does not divide evenly mem_size[%d] (0x%lx); discarding %ld bytes\n", - chunk_size, i, mem_size[i], mem_size[i] % chunk_size); - mem_size[i] -= mem_size[i] % chunk_size; - } - if (!mem_size[i] || !chunk_size) - return -EINVAL; - if (chunk_size > mem_size[i]) { - pr_err(PFX "chunk_size (0x%lx) > mem_size[%d] (0x%lx)\n", - chunk_size, i, mem_size[i]); - return -EINVAL; - } - } - - rc = contig_create_file(); - if (rc) - return rc; - - for (i = 0; i < nddr; i++) { - rc = contig_chunks_create(i, mem_size[i] / chunk_size); - if (rc) - goto err_chunks; - } - - return 0; - - err_chunks: - contig_remove_file(); - return rc; + if (chunk_size < PAGE_SIZE) { + pr_err(PFX "chunk_size (0x%lx) < PAGE_SIZE (0x%lx)\n", chunk_size, PAGE_SIZE); + return -EINVAL; + } + + for (i = 0; i < nddr; i++) { + INIT_LIST_HEAD(&inactive_chunks[i]); + if (mem_size[i] % chunk_size) { + pr_warn(PFX "chunk_size (0x%lx) does not divide evenly mem_size[%d] (0x%lx); " + "discarding %ld bytes\n", + chunk_size, i, mem_size[i], mem_size[i] % chunk_size); + mem_size[i] -= mem_size[i] % chunk_size; + } + if (!mem_size[i] || !chunk_size) return -EINVAL; + if (chunk_size > mem_size[i]) { + pr_err(PFX "chunk_size (0x%lx) > mem_size[%d] (0x%lx)\n", chunk_size, i, mem_size[i]); + return -EINVAL; + } + } + + rc = contig_create_file(); + if (rc) return rc; + + for (i = 0; i < nddr; i++) { + rc = contig_chunks_create(i, mem_size[i] / chunk_size); + if (rc) goto err_chunks; + } + + return 0; + +err_chunks: + contig_remove_file(); + return rc; } static void contig_exit(void) { - struct contig_desc *desc, *nxt; + struct contig_desc *desc, *nxt; - list_for_each_entry_safe(desc, nxt, &desc_list, desc_node) { - __contig_free(desc); - } - __contig_chunks_remove(); - contig_phys_free(); - contig_remove_file(); + list_for_each_entry_safe(desc, nxt, &desc_list, desc_node) { __contig_free(desc); } + __contig_chunks_remove(); + contig_phys_free(); + contig_remove_file(); } -module_init(contig_init) -module_exit(contig_exit) +module_init(contig_init) module_exit(contig_exit) -MODULE_AUTHOR("Emilio G. Cota "); + MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("allocator for memory beyond the system's physical memory"); diff --git a/soft/common/drivers/linux/dvi/app/dvitest.c b/soft/common/drivers/linux/dvi/app/dvitest.c index 2cc6f3342c..cd555e235e 100644 --- a/soft/common/drivers/linux/dvi/app/dvitest.c +++ b/soft/common/drivers/linux/dvi/app/dvitest.c @@ -1,75 +1,74 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include -#include -#include #include #include -#include +#include +#include #include +#include +#include int main() { - int fbfd = 0; - struct fb_var_screeninfo vinfo; - struct fb_fix_screeninfo finfo; - long int screensize = 0; - char *fbpc = 0; - unsigned *fbp = 0; - int x = 0, y = 0; - long int location = 0; - - // Open the file for reading and writing - fbfd = open("/dev/fb0", O_RDWR); - if (fbfd == -1) { - perror("Error: cannot open framebuffer device"); - exit(1); - } - printf("The framebuffer device was opened successfully.\n"); + int fbfd = 0; + struct fb_var_screeninfo vinfo; + struct fb_fix_screeninfo finfo; + long int screensize = 0; + char *fbpc = 0; + unsigned *fbp = 0; + int x = 0, y = 0; + long int location = 0; - // Get fixed screen information - if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) { - perror("Error reading fixed information"); - exit(2); - } + // Open the file for reading and writing + fbfd = open("/dev/fb0", O_RDWR); + if (fbfd == -1) { + perror("Error: cannot open framebuffer device"); + exit(1); + } + printf("The framebuffer device was opened successfully.\n"); - // Get variable screen information - if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) { - perror("Error reading variable information"); - exit(3); - } + // Get fixed screen information + if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) { + perror("Error reading fixed information"); + exit(2); + } - printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); + // Get variable screen information + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) { + perror("Error reading variable information"); + exit(3); + } - // Figure out the size of the screen in bytes - screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; + printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); - // Map the device to memory - fbpc = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); - if (fbpc == MAP_FAILED) { - perror("Error: failed to map framebuffer device to memory"); - exit(4); - } - fbp = (unsigned *) fbpc; - printf("The framebuffer device was mapped to memory successfully.\n"); + // Figure out the size of the screen in bytes + screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; - // Figure out where in memory to put the pixel - printf("xoffset: %d\n", vinfo.xoffset); - printf("bits_per_pixel: %d\n", vinfo.bits_per_pixel); - printf("yoffset: %d\n", vinfo.yoffset); - printf("line_length: %d\n", finfo.line_length); + // Map the device to memory + fbpc = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); + if (fbpc == MAP_FAILED) { + perror("Error: failed to map framebuffer device to memory"); + exit(4); + } + fbp = (unsigned *)fbpc; + printf("The framebuffer device was mapped to memory successfully.\n"); - for (y = 100; y < 150; y++) - for (x = 100; x < 150; x++) { + // Figure out where in memory to put the pixel + printf("xoffset: %d\n", vinfo.xoffset); + printf("bits_per_pixel: %d\n", vinfo.bits_per_pixel); + printf("yoffset: %d\n", vinfo.yoffset); + printf("line_length: %d\n", finfo.line_length); - location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + - (y+vinfo.yoffset) * finfo.line_length / 4; + for (y = 100; y < 150; y++) + for (x = 100; x < 150; x++) { - /* Writing for pixels at a time; each 1-byts (2 hex digits) */ - *(fbp + location) = 0xc4c4c4c4; + location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8) + + (y + vinfo.yoffset) * finfo.line_length / 4; - } - munmap(fbp, screensize); - close(fbfd); - return 0; + /* Writing for pixels at a time; each 1-byts (2 hex digits) */ + *(fbp + location) = 0xc4c4c4c4; + } + munmap(fbp, screensize); + close(fbfd); + return 0; } diff --git a/soft/common/drivers/linux/esp/esp.c b/soft/common/drivers/linux/esp/esp.c index 2cec2152f6..bc8d087007 100644 --- a/soft/common/drivers/linux/esp/esp.c +++ b/soft/common/drivers/linux/esp/esp.c @@ -15,24 +15,24 @@ * - llc_banks */ -#include -#include -#include -#include #include -#include -#include #include -#include +#include #include +#include +#include +#include +#include +#include +#include #include #include #include -#define PFX "esp: " -#define ESP_MAX_DEVICES 64 +#define PFX "esp: " +#define ESP_MAX_DEVICES 64 static DEFINE_SPINLOCK(esp_devices_lock); static LIST_HEAD(esp_devices); @@ -54,344 +54,344 @@ static unsigned long rtl_cache = 1; module_param(rtl_cache, ulong, S_IRUGO); /* These are overwritten when the module initializes based on input flags */ -static size_t cache_l2_size = 32768; +static size_t cache_l2_size = 32768; static size_t cache_llc_bank_size = 262144; -static size_t cache_llc_size = 262144; +static size_t cache_llc_size = 262144; struct esp_status esp_status; static irqreturn_t esp_irq(int irq, void *dev) { - struct esp_device *esp = dev_get_drvdata(dev); - u32 status, error, done; - - status = ioread32be(esp->iomem + STATUS_REG); - error = status & STATUS_MASK_ERR; - done = status & STATUS_MASK_DONE; - - /* printk(KERN_INFO "IRQ: %08x\n", status); */ - - if (error) { - iowrite32be(0, esp->iomem + CMD_REG); - esp->err = -1; - complete_all(&esp->completion); - return IRQ_HANDLED; - } - if (done) { - iowrite32be(0, esp->iomem + CMD_REG); - complete_all(&esp->completion); - return IRQ_HANDLED; - } - return IRQ_NONE; + struct esp_device *esp = dev_get_drvdata(dev); + u32 status, error, done; + + status = ioread32be(esp->iomem + STATUS_REG); + error = status & STATUS_MASK_ERR; + done = status & STATUS_MASK_DONE; + + /* printk(KERN_INFO "IRQ: %08x\n", status); */ + + if (error) { + iowrite32be(0, esp->iomem + CMD_REG); + esp->err = -1; + complete_all(&esp->completion); + return IRQ_HANDLED; + } + if (done) { + iowrite32be(0, esp->iomem + CMD_REG); + complete_all(&esp->completion); + return IRQ_HANDLED; + } + return IRQ_NONE; } static int esp_flush(struct esp_device *esp) { - int rc = 0; - if (esp->coherence < ACC_COH_RECALL) - rc |= esp_private_cache_flush(); + int rc = 0; + if (esp->coherence < ACC_COH_RECALL) rc |= esp_private_cache_flush(); - if (esp->coherence < ACC_COH_LLC) - rc |= esp_cache_flush(); + if (esp->coherence < ACC_COH_LLC) rc |= esp_cache_flush(); - return rc; + return rc; } static int esp_open(struct inode *inode, struct file *file) { - struct esp_device *esp; + struct esp_device *esp; - esp = container_of(inode->i_cdev, struct esp_device, cdev); - file->private_data = esp; - if (!try_module_get(esp->module)) - return -ENODEV; - return 0; + esp = container_of(inode->i_cdev, struct esp_device, cdev); + file->private_data = esp; + if (!try_module_get(esp->module)) return -ENODEV; + return 0; } static int esp_release(struct inode *inode, struct file *file) { - struct esp_device *esp; + struct esp_device *esp; - esp = file->private_data; - module_put(esp->module); - return 0; + esp = file->private_data; + module_put(esp->module); + return 0; } -void esp_status_init(void) { +void esp_status_init(void) +{ + + int i; - int i; + cache_l2_size = cache_l2_sets * cache_l2_ways * cache_line_bytes; - cache_l2_size = cache_l2_sets * cache_l2_ways * cache_line_bytes; - if (rtl_cache) { - cache_llc_size = cache_llc_sets * cache_llc_ways * cache_line_bytes; + cache_llc_size = cache_llc_sets * cache_llc_ways * cache_line_bytes; cache_llc_bank_size = cache_llc_sets * cache_llc_ways * cache_line_bytes / cache_llc_banks; - } else { - cache_llc_size = cache_llc_sets * cache_llc_ways * cache_line_bytes * cache_llc_banks; + } + else { + cache_llc_size = cache_llc_sets * cache_llc_ways * cache_line_bytes * cache_llc_banks; cache_llc_bank_size = cache_llc_sets * cache_llc_ways * cache_line_bytes; } - mutex_init(&esp_status.lock); - esp_status.active_acc_cnt = 0; - esp_status.active_footprint = 0; - for (i = 0; i < cache_llc_banks; i++) - esp_status.active_footprint_split[i] = 0; + mutex_init(&esp_status.lock); + esp_status.active_acc_cnt = 0; + esp_status.active_footprint = 0; + for (i = 0; i < cache_llc_banks; i++) + esp_status.active_footprint_split[i] = 0; } static void esp_runtime_config(struct esp_device *esp) { - unsigned int footprint, footprint_llc_threshold; - // Update number of active accelerators - esp_status.active_acc_cnt += 1; + unsigned int footprint, footprint_llc_threshold; + // Update number of active accelerators + esp_status.active_acc_cnt += 1; - if (esp->coherence == ACC_COH_FULL) { + if (esp->coherence == ACC_COH_FULL) { - esp_status.active_acc_cnt_full++; + esp_status.active_acc_cnt_full++; - return; - } + return; + } - if (esp->coherence == ACC_COH_AUTO){ + if (esp->coherence == ACC_COH_AUTO) { // Evaluate footprint if (esp->alloc_policy == CONTIG_ALLOC_PREFERRED || esp->alloc_policy == CONTIG_ALLOC_LEAST_LOADED) { - footprint = esp_status.active_footprint_split[esp->ddr_node] - + esp->footprint; + footprint = esp_status.active_footprint_split[esp->ddr_node] + esp->footprint; footprint_llc_threshold = cache_llc_bank_size; + } + else { // CONTIG_ALLOC_BALANCED - } else { // CONTIG_ALLOC_BALANCED - - footprint = esp_status.active_footprint + esp->footprint;; + footprint = esp_status.active_footprint + esp->footprint; + ; footprint_llc_threshold = cache_llc_size; } // Cache coherence choice if (esp->footprint < cache_l2_size) { - if (esp->reuse_factor > 1){ - esp->coherence = ACC_COH_FULL; + if (esp->reuse_factor > 1) { + esp->coherence = ACC_COH_FULL; esp_status.active_acc_cnt_full++; - } else { + } + else { esp->coherence = ACC_COH_RECALL; } - } else if (esp->footprint < cache_llc_bank_size) { + } + else if (esp->footprint < cache_llc_bank_size) { esp->coherence = ACC_COH_RECALL; - - } else { + } + else { esp->coherence = ACC_COH_NONE; } } - // Update footprint - if (esp->coherence != ACC_COH_NONE) { - - esp_status.active_footprint += esp->footprint; + // Update footprint + if (esp->coherence != ACC_COH_NONE) { - if (esp->alloc_policy == CONTIG_ALLOC_PREFERRED || - esp->alloc_policy == CONTIG_ALLOC_LEAST_LOADED) { + esp_status.active_footprint += esp->footprint; - esp_status.active_footprint_split[esp->ddr_node] += - esp->footprint; + if (esp->alloc_policy == CONTIG_ALLOC_PREFERRED || + esp->alloc_policy == CONTIG_ALLOC_LEAST_LOADED) { - } else { // CONTIG_ALLOC_BALANCED + esp_status.active_footprint_split[esp->ddr_node] += esp->footprint; + } + else { // CONTIG_ALLOC_BALANCED - int i; - for (i = 0; i < cache_llc_banks; i++) { - esp_status.active_footprint_split[i] += - (esp->footprint / cache_llc_banks); - } - } - } + int i; + for (i = 0; i < cache_llc_banks; i++) { + esp_status.active_footprint_split[i] += (esp->footprint / cache_llc_banks); + } + } + } - return; + return; } static void esp_transfer(struct esp_device *esp, const struct contig_desc *contig) { - esp->err = 0; - reinit_completion(&esp->completion); - - iowrite32be(contig->arr_dma_addr, esp->iomem + PT_ADDRESS_REG); - iowrite32be(contig_chunk_size_log, esp->iomem + PT_SHIFT_REG); - iowrite32be(contig->n, esp->iomem + PT_NCHUNK_REG); - iowrite32be(esp->coherence, esp->iomem + COHERENCE_REG); - iowrite32be(0x0, esp->iomem + SRC_OFFSET_REG); - iowrite32be(0x0, esp->iomem + DST_OFFSET_REG); + esp->err = 0; + reinit_completion(&esp->completion); + + iowrite32be(contig->arr_dma_addr, esp->iomem + PT_ADDRESS_REG); + iowrite32be(contig_chunk_size_log, esp->iomem + PT_SHIFT_REG); + iowrite32be(contig->n, esp->iomem + PT_NCHUNK_REG); + iowrite32be(esp->coherence, esp->iomem + COHERENCE_REG); + iowrite32be(0x0, esp->iomem + SRC_OFFSET_REG); + iowrite32be(0x0, esp->iomem + DST_OFFSET_REG); } -static void esp_run(struct esp_device *esp) -{ - iowrite32be(0x1, esp->iomem + CMD_REG); -} +static void esp_run(struct esp_device *esp) { iowrite32be(0x1, esp->iomem + CMD_REG); } static int esp_wait(struct esp_device *esp) { - /* Interrupt */ - int wait; - - wait = wait_for_completion_interruptible(&esp->completion); - if (wait < 0) - return -EINTR; - if (esp->err) { - pr_info(PFX "Error occured\n"); - return -1; - } - - return 0; + /* Interrupt */ + int wait; + + wait = wait_for_completion_interruptible(&esp->completion); + if (wait < 0) return -EINTR; + if (esp->err) { + pr_info(PFX "Error occured\n"); + return -1; + } + + return 0; } static void esp_update_status(struct esp_device *esp) { - if (esp->coherence == ACC_COH_FULL) - esp_status.active_acc_cnt_full--; - - // Update number of active accelerators - esp_status.active_acc_cnt -= 1; + if (esp->coherence == ACC_COH_FULL) esp_status.active_acc_cnt_full--; - // Update footprints - if (esp->coherence != ACC_COH_NONE) { + // Update number of active accelerators + esp_status.active_acc_cnt -= 1; - esp_status.active_footprint -= esp->footprint; + // Update footprints + if (esp->coherence != ACC_COH_NONE) { - if (esp->alloc_policy == CONTIG_ALLOC_PREFERRED || - esp->alloc_policy == CONTIG_ALLOC_LEAST_LOADED) { + esp_status.active_footprint -= esp->footprint; - esp_status.active_footprint_split[esp->ddr_node] -= esp->footprint; + if (esp->alloc_policy == CONTIG_ALLOC_PREFERRED || + esp->alloc_policy == CONTIG_ALLOC_LEAST_LOADED) { - } else { + esp_status.active_footprint_split[esp->ddr_node] -= esp->footprint; + } + else { - int i; - for (i = 0; i < cache_llc_banks; i++) { - esp_status.active_footprint_split[i] -= (esp->footprint / cache_llc_banks); - } - } - } + int i; + for (i = 0; i < cache_llc_banks; i++) { + esp_status.active_footprint_split[i] -= (esp->footprint / cache_llc_banks); + } + } + } } static bool esp_xfer_input_ok(struct esp_device *esp, const struct contig_desc *contig) { - unsigned nchunk_max = ioread32be(esp->iomem + PT_NCHUNK_MAX_REG); + unsigned nchunk_max = ioread32be(esp->iomem + PT_NCHUNK_MAX_REG); - /* No check needed if memory is not accessed (PT_NCHUNK_MAX == 0) */ - if (!nchunk_max) - return true; + /* No check needed if memory is not accessed (PT_NCHUNK_MAX == 0) */ + if (!nchunk_max) return true; - if (!contig->n || contig->n > nchunk_max) - return false; - return true; + if (!contig->n || contig->n > nchunk_max) return false; + return true; } -#define esp_get_y(_dev) (YX_MASK_YX & (ioread32be(_dev->iomem + YX_REG) >> YX_SHIFT_Y)) -#define esp_get_x(_dev) (YX_MASK_YX & (ioread32be(_dev->iomem + YX_REG) >> YX_SHIFT_X)) +#define esp_get_y(_dev) (YX_MASK_YX & (ioread32be(_dev->iomem + YX_REG) >> YX_SHIFT_Y)) +#define esp_get_x(_dev) (YX_MASK_YX & (ioread32be(_dev->iomem + YX_REG) >> YX_SHIFT_X)) #define esp_p2p_reset(_dev) iowrite32be(0, _dev->iomem + P2P_REG) -#define esp_p2p_enable_dst(_dev) iowrite32be(ioread32be(_dev->iomem + P2P_REG) | P2P_MASK_DST_IS_P2P, _dev->iomem + P2P_REG) -#define esp_p2p_enable_src(_dev) iowrite32be(ioread32be(_dev->iomem + P2P_REG) | P2P_MASK_SRC_IS_P2P, _dev->iomem + P2P_REG) -#define esp_p2p_set_nsrcs(_dev, _n) iowrite32be(ioread32be(_dev->iomem + P2P_REG) | (P2P_MASK_NSRCS & (_n - 1)), _dev->iomem + P2P_REG) -#define esp_p2p_set_y(_dev, _n, _y) iowrite32be(ioread32be(_dev->iomem + P2P_REG) | ((P2P_MASK_SRCS_YX & _y) << P2P_SHIFT_SRCS_Y(_n)), _dev->iomem + P2P_REG) -#define esp_p2p_set_x(_dev, _n, _x) iowrite32be(ioread32be(_dev->iomem + P2P_REG) | ((P2P_MASK_SRCS_YX & _x) << P2P_SHIFT_SRCS_X(_n)), _dev->iomem + P2P_REG) +#define esp_p2p_enable_dst(_dev) \ + iowrite32be(ioread32be(_dev->iomem + P2P_REG) | P2P_MASK_DST_IS_P2P, _dev->iomem + P2P_REG) +#define esp_p2p_enable_src(_dev) \ + iowrite32be(ioread32be(_dev->iomem + P2P_REG) | P2P_MASK_SRC_IS_P2P, _dev->iomem + P2P_REG) +#define esp_p2p_set_nsrcs(_dev, _n) \ + iowrite32be(ioread32be(_dev->iomem + P2P_REG) | (P2P_MASK_NSRCS & (_n - 1)), \ + _dev->iomem + P2P_REG) +#define esp_p2p_set_y(_dev, _n, _y) \ + iowrite32be(ioread32be(_dev->iomem + P2P_REG) | \ + ((P2P_MASK_SRCS_YX & _y) << P2P_SHIFT_SRCS_Y(_n)), \ + _dev->iomem + P2P_REG) +#define esp_p2p_set_x(_dev, _n, _x) \ + iowrite32be(ioread32be(_dev->iomem + P2P_REG) | \ + ((P2P_MASK_SRCS_YX & _x) << P2P_SHIFT_SRCS_X(_n)), \ + _dev->iomem + P2P_REG) static long esp_p2p_set_src(struct esp_device *esp, char *src_name, int src_index) { - struct list_head *ele; - struct esp_device *dev; - - dev_dbg(esp->pdev, "searching P2P source %s\n", src_name); - spin_lock(&esp_devices_lock); - list_for_each(ele, &esp_devices) { - dev = list_entry(ele, struct esp_device, list); - if (!strncmp(src_name, dev->dev->kobj.name, strlen(dev->dev->kobj.name))) { - unsigned y = esp_get_y(dev); - unsigned x = esp_get_x(dev); - esp_p2p_set_y(esp, src_index, y); - esp_p2p_set_x(esp, src_index, x); - spin_unlock(&esp_devices_lock); - dev_dbg(esp->pdev, "P2P source %s on tile %d,%d\n", dev->dev->kobj.name, y, x); - return true; - } - } - spin_unlock(&esp_devices_lock); - - dev_info(esp->pdev, "ESP device %s not found\n", src_name); - return false; + struct list_head *ele; + struct esp_device *dev; + + dev_dbg(esp->pdev, "searching P2P source %s\n", src_name); + spin_lock(&esp_devices_lock); + list_for_each(ele, &esp_devices) + { + dev = list_entry(ele, struct esp_device, list); + if (!strncmp(src_name, dev->dev->kobj.name, strlen(dev->dev->kobj.name))) { + unsigned y = esp_get_y(dev); + unsigned x = esp_get_x(dev); + esp_p2p_set_y(esp, src_index, y); + esp_p2p_set_x(esp, src_index, x); + spin_unlock(&esp_devices_lock); + dev_dbg(esp->pdev, "P2P source %s on tile %d,%d\n", dev->dev->kobj.name, y, x); + return true; + } + } + spin_unlock(&esp_devices_lock); + + dev_info(esp->pdev, "ESP device %s not found\n", src_name); + return false; } static long esp_p2p_init(struct esp_device *esp, struct esp_access *access) { - int i = 0; + int i = 0; - esp_p2p_reset(esp); + esp_p2p_reset(esp); - for (i = 0; i < access->p2p_nsrcs; i++) - if (!esp_p2p_set_src(esp, access->p2p_srcs[i], i)) - return -ENODEV; + for (i = 0; i < access->p2p_nsrcs; i++) + if (!esp_p2p_set_src(esp, access->p2p_srcs[i], i)) return -ENODEV; - if (access->p2p_store) { - dev_dbg(esp->pdev, "P2P store enabled\n"); - esp_p2p_enable_dst(esp); - } + if (access->p2p_store) { + dev_dbg(esp->pdev, "P2P store enabled\n"); + esp_p2p_enable_dst(esp); + } - if (access->p2p_nsrcs != 0) { - esp_p2p_enable_src(esp); - esp_p2p_set_nsrcs(esp, access->p2p_nsrcs); - } + if (access->p2p_nsrcs != 0) { + esp_p2p_enable_src(esp); + esp_p2p_set_nsrcs(esp, access->p2p_nsrcs); + } - return 0; + return 0; } static int esp_access_ioctl(struct esp_device *esp, void __user *argp) { - struct contig_desc *contig; - struct esp_access *access; - void *arg; - int rc = 0; - - arg = kmalloc(esp->driver->arg_size, GFP_KERNEL); - if (arg == NULL) - return -ENOMEM; - - if (copy_from_user(arg, argp, esp->driver->arg_size)) { - rc = -EFAULT; - goto out; - } - - access = arg; - contig = contig_khandle_to_desc(access->contig); - if (contig == NULL) { - rc = -EFAULT; - goto out; - } - - if (access->p2p_nsrcs > 4) { - rc = -EINVAL; - goto out; - } - - if (!esp_xfer_input_ok(esp, contig)) { - rc = -EINVAL; - goto out; - } - - if (esp->driver->xfer_input_ok && !esp->driver->xfer_input_ok(esp, arg)) { - rc = -EINVAL; - goto out; - } - - if (mutex_lock_interruptible(&esp->lock)) { - rc = -EINTR; - goto out; - } - - rc = esp_p2p_init(esp, access); - if (rc) - goto out; - - esp->coherence = access->coherence; - esp->footprint = access->footprint; - esp->alloc_policy = access->alloc_policy; - esp->ddr_node = access->ddr_node; - esp->in_place = access->in_place; - esp->reuse_factor = access->reuse_factor; + struct contig_desc *contig; + struct esp_access *access; + void *arg; + int rc = 0; + + arg = kmalloc(esp->driver->arg_size, GFP_KERNEL); + if (arg == NULL) return -ENOMEM; + + if (copy_from_user(arg, argp, esp->driver->arg_size)) { + rc = -EFAULT; + goto out; + } + + access = arg; + contig = contig_khandle_to_desc(access->contig); + if (contig == NULL) { + rc = -EFAULT; + goto out; + } + + if (access->p2p_nsrcs > 4) { + rc = -EINVAL; + goto out; + } + + if (!esp_xfer_input_ok(esp, contig)) { + rc = -EINVAL; + goto out; + } + + if (esp->driver->xfer_input_ok && !esp->driver->xfer_input_ok(esp, arg)) { + rc = -EINVAL; + goto out; + } + + if (mutex_lock_interruptible(&esp->lock)) { + rc = -EINTR; + goto out; + } + + rc = esp_p2p_init(esp, access); + if (rc) goto out; + + esp->coherence = access->coherence; + esp->footprint = access->footprint; + esp->alloc_policy = access->alloc_policy; + esp->ddr_node = access->ddr_node; + esp->in_place = access->in_place; + esp->reuse_factor = access->reuse_factor; if (mutex_lock_interruptible(&esp_status.lock)) { rc = -EINTR; @@ -402,19 +402,17 @@ static int esp_access_ioctl(struct esp_device *esp, void __user *argp) mutex_unlock(&esp_status.lock); - rc = esp_flush(esp); - if (rc) - goto out; + rc = esp_flush(esp); + if (rc) goto out; - esp_transfer(esp, contig); + esp_transfer(esp, contig); - if (esp->driver->prep_xfer) - esp->driver->prep_xfer(esp, arg); + if (esp->driver->prep_xfer) esp->driver->prep_xfer(esp, arg); - if (access->run) { - esp_run(esp); - rc = esp_wait(esp); - } + if (access->run) { + esp_run(esp); + rc = esp_wait(esp); + } if (mutex_lock_interruptible(&esp_status.lock)) { rc = -EINTR; @@ -425,252 +423,243 @@ static int esp_access_ioctl(struct esp_device *esp, void __user *argp) mutex_unlock(&esp_status.lock); - mutex_unlock(&esp->lock); + mutex_unlock(&esp->lock); out: - kfree(arg); - return rc; + kfree(arg); + return rc; } static int esp_run_ioctl(struct esp_device *esp) { - esp_run(esp); - return 0; + esp_run(esp); + return 0; } static long esp_flush_ioctl(struct esp_device *esp, void __user *argp) { - struct esp_access *access; - void *arg; - int rc = 0; - - arg = kmalloc(esp->driver->arg_size, GFP_KERNEL); - if (arg == NULL) - return -ENOMEM; - - if (copy_from_user(arg, argp, esp->driver->arg_size)) { - rc = -EFAULT; - goto out; - } - - access = arg; - esp->coherence = access->coherence; - rc = esp_flush(esp); + struct esp_access *access; + void *arg; + int rc = 0; + + arg = kmalloc(esp->driver->arg_size, GFP_KERNEL); + if (arg == NULL) return -ENOMEM; + + if (copy_from_user(arg, argp, esp->driver->arg_size)) { + rc = -EFAULT; + goto out; + } + + access = arg; + esp->coherence = access->coherence; + rc = esp_flush(esp); out: - kfree(arg); - return rc; + kfree(arg); + return rc; } static long esp_do_ioctl(struct file *file, unsigned int cm, void __user *arg) { - struct esp_device *esp = file->private_data; - - switch (cm) { - case ESP_IOC_RUN: - return esp_run_ioctl(esp); - case ESP_IOC_FLUSH: - return esp_flush_ioctl(esp, arg); - default: - if (cm == esp->driver->ioctl_cm) - return esp_access_ioctl(esp, arg); - return -ENOTTY; - } + struct esp_device *esp = file->private_data; + + switch (cm) { + case ESP_IOC_RUN: return esp_run_ioctl(esp); + case ESP_IOC_FLUSH: return esp_flush_ioctl(esp, arg); + default: + if (cm == esp->driver->ioctl_cm) return esp_access_ioctl(esp, arg); + return -ENOTTY; + } } static long esp_ioctl(struct file *file, unsigned int cm, unsigned long arg) { - return esp_do_ioctl(file, cm, (void __user *)arg); + return esp_do_ioctl(file, cm, (void __user *)arg); } static const struct file_operations esp_fops = { - .owner = THIS_MODULE, - .open = esp_open, - .release = esp_release, - .unlocked_ioctl = esp_ioctl, + .owner = THIS_MODULE, + .open = esp_open, + .release = esp_release, + .unlocked_ioctl = esp_ioctl, }; static int esp_create_cdev(struct esp_device *esp, int ndev) { - dev_t devno = MKDEV(MAJOR(esp->driver->devno), ndev); - const char *name = esp->driver->plat.driver.name; - int rc; - - cdev_init(&esp->cdev, &esp_fops); - esp->cdev.owner = esp->module; - rc = cdev_add(&esp->cdev, devno, 1); - if (rc) { - dev_err(esp->pdev, "Error %d adding cdev %d\n", rc, ndev); - goto out; - } - - esp->dev = device_create(esp->driver->class, esp->pdev, devno, NULL, "%s.%i", name, ndev); - if (IS_ERR(esp->dev)) { - rc = PTR_ERR(esp->dev); - dev_err(esp->pdev, "Error %d creating device %d\n", rc, ndev); - esp->dev = NULL; - goto device_create_failed; - } - - dev_set_drvdata(esp->dev, esp); - return 0; + dev_t devno = MKDEV(MAJOR(esp->driver->devno), ndev); + const char *name = esp->driver->plat.driver.name; + int rc; + + cdev_init(&esp->cdev, &esp_fops); + esp->cdev.owner = esp->module; + rc = cdev_add(&esp->cdev, devno, 1); + if (rc) { + dev_err(esp->pdev, "Error %d adding cdev %d\n", rc, ndev); + goto out; + } + + esp->dev = device_create(esp->driver->class, esp->pdev, devno, NULL, "%s.%i", name, ndev); + if (IS_ERR(esp->dev)) { + rc = PTR_ERR(esp->dev); + dev_err(esp->pdev, "Error %d creating device %d\n", rc, ndev); + esp->dev = NULL; + goto device_create_failed; + } + + dev_set_drvdata(esp->dev, esp); + return 0; device_create_failed: - cdev_del(&esp->cdev); + cdev_del(&esp->cdev); out: - return rc; + return rc; } static void esp_destroy_cdev(struct esp_device *esp, int ndev) { - dev_t devno = MKDEV(MAJOR(esp->driver->devno), ndev); + dev_t devno = MKDEV(MAJOR(esp->driver->devno), ndev); - device_destroy(esp->driver->class, devno); - cdev_del(&esp->cdev); + device_destroy(esp->driver->class, devno); + cdev_del(&esp->cdev); } int esp_device_register(struct esp_device *esp, struct platform_device *pdev) { - struct resource *res; - int rc; + struct resource *res; + int rc; - esp->pdev = &pdev->dev; - mutex_init(&esp->lock); - init_completion(&esp->completion); + esp->pdev = &pdev->dev; + mutex_init(&esp->lock); + init_completion(&esp->completion); - rc = esp_create_cdev(esp, esp->number); - if (rc) - goto out; + rc = esp_create_cdev(esp, esp->number); + if (rc) goto out; #ifndef __sparc - esp->irq = of_irq_get(pdev->dev.of_node, 0); + esp->irq = of_irq_get(pdev->dev.of_node, 0); #else - esp->irq = pdev->archdata.irqs[0]; + esp->irq = pdev->archdata.irqs[0]; #endif - rc = request_irq(esp->irq, esp_irq, IRQF_SHARED, "esp", esp->pdev); - if (rc) { - dev_info(esp->pdev, "cannot request IRQ number %d\n", esp->irq); - goto out_irq; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - esp->iomem = devm_ioremap_resource(&pdev->dev, res); - if (esp->iomem == NULL) { - dev_info(esp->pdev, "cannot map registers for I/O\n"); - goto out_iomem; - } - - /* reset device and wait for it to complete */ - iowrite32be(0x0, esp->iomem + CMD_REG); - while (ioread32be(esp->iomem + CMD_REG)){ + rc = request_irq(esp->irq, esp_irq, IRQF_SHARED, "esp", esp->pdev); + if (rc) { + dev_info(esp->pdev, "cannot request IRQ number %d\n", esp->irq); + goto out_irq; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + esp->iomem = devm_ioremap_resource(&pdev->dev, res); + if (esp->iomem == NULL) { + dev_info(esp->pdev, "cannot map registers for I/O\n"); + goto out_iomem; + } + + /* reset device and wait for it to complete */ + iowrite32be(0x0, esp->iomem + CMD_REG); + while (ioread32be(esp->iomem + CMD_REG)) { cpu_relax(); } - /* set type of coherence to no coherence by default */ - esp->coherence = ACC_COH_NONE; + /* set type of coherence to no coherence by default */ + esp->coherence = ACC_COH_NONE; - dev_info(esp->pdev, "l2_size: %zu, llc_size %zu, llc_banks: %lu.\n", - cache_l2_size, cache_llc_size, cache_llc_banks); + dev_info(esp->pdev, "l2_size: %zu, llc_size %zu, llc_banks: %lu.\n", cache_l2_size, + cache_llc_size, cache_llc_banks); - /* Add device to ESP devices list */ - spin_lock(&esp_devices_lock); - list_add(&esp->list, &esp_devices); - spin_unlock(&esp_devices_lock); + /* Add device to ESP devices list */ + spin_lock(&esp_devices_lock); + list_add(&esp->list, &esp_devices); + spin_unlock(&esp_devices_lock); - dev_info(esp->pdev, "device registered.\n"); - platform_set_drvdata(pdev, esp); - return 0; + dev_info(esp->pdev, "device registered.\n"); + platform_set_drvdata(pdev, esp); + return 0; out_iomem: - free_irq(esp->irq, esp->pdev); + free_irq(esp->irq, esp->pdev); out_irq: - esp_destroy_cdev(esp, esp->number); + esp_destroy_cdev(esp, esp->number); out: - kfree(esp); - return rc; + kfree(esp); + return rc; } EXPORT_SYMBOL_GPL(esp_device_register); void esp_device_unregister(struct esp_device *esp) { - list_del(&esp->list); - free_irq(esp->irq, esp->pdev); - esp_destroy_cdev(esp, esp->number); - devm_iounmap(esp->pdev, esp->iomem); - dev_info(esp->pdev, "device unregistered.\n"); + list_del(&esp->list); + free_irq(esp->irq, esp->pdev); + esp_destroy_cdev(esp, esp->number); + devm_iounmap(esp->pdev, esp->iomem); + dev_info(esp->pdev, "device unregistered.\n"); } EXPORT_SYMBOL_GPL(esp_device_unregister); static int esp_sysfs_device_create(struct esp_driver *drv) { - const char *name = drv->plat.driver.name; - int rc; + const char *name = drv->plat.driver.name; + int rc; - drv->class = class_create(drv->plat.driver.owner, name); - if (IS_ERR(drv->class)) { - pr_err(PFX "Failed to create esp class\n"); - rc = PTR_ERR(drv->class); - goto out; - } + drv->class = class_create(drv->plat.driver.owner, name); + if (IS_ERR(drv->class)) { + pr_err(PFX "Failed to create esp class\n"); + rc = PTR_ERR(drv->class); + goto out; + } - rc = alloc_chrdev_region(&drv->devno, 0, ESP_MAX_DEVICES, name); - if (rc) { - pr_err(PFX "Failed to allocate chrdev region\n"); - goto alloc_chrdev_region_failed; - } + rc = alloc_chrdev_region(&drv->devno, 0, ESP_MAX_DEVICES, name); + if (rc) { + pr_err(PFX "Failed to allocate chrdev region\n"); + goto alloc_chrdev_region_failed; + } - return 0; + return 0; alloc_chrdev_region_failed: - class_destroy(drv->class); + class_destroy(drv->class); out: - return rc; + return rc; } static void esp_sysfs_device_remove(struct esp_driver *drv) { - dev_t devno = MKDEV(MAJOR(drv->devno), 0); + dev_t devno = MKDEV(MAJOR(drv->devno), 0); - class_destroy(drv->class); - unregister_chrdev_region(devno, ESP_MAX_DEVICES); + class_destroy(drv->class); + unregister_chrdev_region(devno, ESP_MAX_DEVICES); } int esp_driver_register(struct esp_driver *driver) { - struct platform_driver *plat = &driver->plat; - int rc; - - rc = esp_sysfs_device_create(driver); - if (rc) - return rc; - rc = platform_driver_register(plat); - if (rc) - goto err; - return 0; + struct platform_driver *plat = &driver->plat; + int rc; + + rc = esp_sysfs_device_create(driver); + if (rc) return rc; + rc = platform_driver_register(plat); + if (rc) goto err; + return 0; err: - esp_sysfs_device_remove(driver); - return rc; + esp_sysfs_device_remove(driver); + return rc; } EXPORT_SYMBOL_GPL(esp_driver_register); void esp_driver_unregister(struct esp_driver *driver) { - platform_driver_unregister(&driver->plat); - esp_sysfs_device_remove(driver); + platform_driver_unregister(&driver->plat); + esp_sysfs_device_remove(driver); } EXPORT_SYMBOL_GPL(esp_driver_unregister); static int __init esp_init(void) { - esp_status_init(); - return 0; + esp_status_init(); + return 0; } -static void __exit esp_exit(void) -{ } +static void __exit esp_exit(void) {} -module_init(esp_init) - module_exit(esp_exit) +module_init(esp_init) module_exit(esp_exit) - MODULE_AUTHOR("Emilio G. Cota "); + MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("esp driver"); diff --git a/soft/common/drivers/linux/esp_cache/esp_cache.c b/soft/common/drivers/linux/esp_cache/esp_cache.c index 5a2c027931..b8e2d9e823 100644 --- a/soft/common/drivers/linux/esp_cache/esp_cache.c +++ b/soft/common/drivers/linux/esp_cache/esp_cache.c @@ -5,171 +5,164 @@ #include "esp_cache.h" -#define DRV_NAME "lastlevel_cache" +#define DRV_NAME "lastlevel_cache" static DEFINE_SPINLOCK(esp_cache_list_lock); static LIST_HEAD(esp_cache_list); struct esp_cache_device { - struct device *pdev; /* platform device */ - struct module *module; - struct mutex lock; - void __iomem *iomem; /* mmapped registers */ - struct list_head list; + struct device *pdev; /* platform device */ + struct module *module; + struct mutex lock; + void __iomem *iomem; /* mmapped registers */ + struct list_head list; }; - static struct of_device_id esp_cache_device_ids[] = { - { - .name = "SLD_ESP_CACHE", - }, - { - .name = "eb_021", - }, - { - .compatible = "sld,llc_cache", - }, - { - .name = "ee_021", - }, - { - .compatible = "uiuc,spandex_llc", - }, - { }, + { + .name = "SLD_ESP_CACHE", + }, + { + .name = "eb_021", + }, + { + .compatible = "sld,llc_cache", + }, + { + .name = "ee_021", + }, + { + .compatible = "uiuc,spandex_llc", + }, + {}, }; - static void esp_cache_do_flush(struct esp_cache_device *esp_cache) { - int cmd = 1 << ESP_CACHE_CMD_FLUSH_BIT; - u32 cmd_reg; - u32 satus_reg; + int cmd = 1 << ESP_CACHE_CMD_FLUSH_BIT; + u32 cmd_reg; + u32 satus_reg; - /* Check if flush is already in progress */ - cmd_reg = ioread32be(esp_cache->iomem + ESP_CACHE_REG_CMD); + /* Check if flush is already in progress */ + cmd_reg = ioread32be(esp_cache->iomem + ESP_CACHE_REG_CMD); - if (!cmd_reg) { + if (!cmd_reg) { - /* Set flush due for LLC cache */ - iowrite32be(cmd, esp_cache->iomem + ESP_CACHE_REG_CMD); + /* Set flush due for LLC cache */ + iowrite32be(cmd, esp_cache->iomem + ESP_CACHE_REG_CMD); - /* Wait for completion */ - do { - satus_reg = ioread32be(esp_cache->iomem + ESP_CACHE_REG_STATUS); - satus_reg &= ESP_CACHE_STATUS_DONE_MASK; - } while (!satus_reg); - } + /* Wait for completion */ + do { + satus_reg = ioread32be(esp_cache->iomem + ESP_CACHE_REG_STATUS); + satus_reg &= ESP_CACHE_STATUS_DONE_MASK; + } while (!satus_reg); + } - /* Clear command register */ - iowrite32be(0x0, esp_cache->iomem + ESP_CACHE_REG_CMD); + /* Clear command register */ + iowrite32be(0x0, esp_cache->iomem + ESP_CACHE_REG_CMD); } int esp_cache_flush() { - struct esp_cache_device *esp_cache = NULL; - list_for_each_entry(esp_cache, &esp_cache_list, list) { - if (mutex_lock_interruptible(&esp_cache->lock)) - return -EINTR; - esp_cache_do_flush(esp_cache); - mutex_unlock(&esp_cache->lock); - } - return 0; + struct esp_cache_device *esp_cache = NULL; + list_for_each_entry(esp_cache, &esp_cache_list, list) + { + if (mutex_lock_interruptible(&esp_cache->lock)) return -EINTR; + esp_cache_do_flush(esp_cache); + mutex_unlock(&esp_cache->lock); + } + return 0; } EXPORT_SYMBOL_GPL(esp_cache_flush); - static int esp_cache_probe(struct platform_device *pdev) { - struct esp_cache_device *esp_cache; - struct resource *res; - const char *compatible; - int cplen; - int rc = 0; + struct esp_cache_device *esp_cache; + struct resource *res; + const char *compatible; + int cplen; + int rc = 0; - esp_cache = kzalloc(sizeof(*esp_cache), GFP_KERNEL); - if (esp_cache == NULL) - return -ENOMEM; + esp_cache = kzalloc(sizeof(*esp_cache), GFP_KERNEL); + if (esp_cache == NULL) return -ENOMEM; - esp_cache->pdev = &pdev->dev; + esp_cache->pdev = &pdev->dev; - esp_cache->module = THIS_MODULE; + esp_cache->module = THIS_MODULE; - mutex_init(&esp_cache->lock); + mutex_init(&esp_cache->lock); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - esp_cache->iomem = devm_ioremap_resource(&pdev->dev, res); - if (esp_cache->iomem == NULL) { - dev_info(esp_cache->pdev, "cannot map registers for I/O\n"); - rc = -ENODEV; - goto out_iomem; - } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + esp_cache->iomem = devm_ioremap_resource(&pdev->dev, res); + if (esp_cache->iomem == NULL) { + dev_info(esp_cache->pdev, "cannot map registers for I/O\n"); + rc = -ENODEV; + goto out_iomem; + } - /* Determine which type of cache is present */ + /* Determine which type of cache is present */ #ifdef __sparc - compatible = of_get_property(esp_cache->pdev->of_node, "name", &cplen); - if (strcmp(compatible, "eb_021") == 0) + compatible = of_get_property(esp_cache->pdev->of_node, "name", &cplen); + if (strcmp(compatible, "eb_021") == 0) #else - compatible = of_get_property(esp_cache->pdev->of_node, "compatible", &cplen); - if (strcmp(compatible, "sld,llc_cache") == 0) + compatible = of_get_property(esp_cache->pdev->of_node, "compatible", &cplen); + if (strcmp(compatible, "sld,llc_cache") == 0) #endif - dev_info(esp_cache->pdev, "ESP LLC cache registered.\n"); - else - dev_info(esp_cache->pdev, "Spandex LLC cache registered.\n"); + dev_info(esp_cache->pdev, "ESP LLC cache registered.\n"); + else + dev_info(esp_cache->pdev, "Spandex LLC cache registered.\n"); - platform_set_drvdata(pdev, esp_cache); + platform_set_drvdata(pdev, esp_cache); - spin_lock(&esp_cache_list_lock); - list_add(&esp_cache->list, &esp_cache_list); - spin_unlock(&esp_cache_list_lock); + spin_lock(&esp_cache_list_lock); + list_add(&esp_cache->list, &esp_cache_list); + spin_unlock(&esp_cache_list_lock); - return 0; + return 0; - out_iomem: - kfree(esp_cache); - return rc; +out_iomem: + kfree(esp_cache); + return rc; } static int __exit esp_cache_remove(struct platform_device *pdev) { - struct esp_cache_device *esp_cache = platform_get_drvdata(pdev); + struct esp_cache_device *esp_cache = platform_get_drvdata(pdev); - spin_lock(&esp_cache_list_lock); - list_del(&esp_cache->list); - spin_unlock(&esp_cache_list_lock); + spin_lock(&esp_cache_list_lock); + list_del(&esp_cache->list); + spin_unlock(&esp_cache_list_lock); - dev_info(esp_cache->pdev, "device unregistered.\n"); + dev_info(esp_cache->pdev, "device unregistered.\n"); - devm_iounmap(&pdev->dev, esp_cache->iomem); - kfree(esp_cache); + devm_iounmap(&pdev->dev, esp_cache->iomem); + kfree(esp_cache); - return 0; + return 0; } static struct platform_driver esp_cache_driver = { - .probe = esp_cache_probe, - .remove = esp_cache_remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = esp_cache_device_ids, - }, + .probe = esp_cache_probe, + .remove = esp_cache_remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = esp_cache_device_ids, + }, }; static int __init esp_cache_init(void) { - int rc = platform_driver_register(&esp_cache_driver); - return rc; + int rc = platform_driver_register(&esp_cache_driver); + return rc; } -static void __exit esp_cache_exit(void) -{ - platform_driver_unregister(&esp_cache_driver); -} +static void __exit esp_cache_exit(void) { platform_driver_unregister(&esp_cache_driver); } -module_init(esp_cache_init) -module_exit(esp_cache_exit) +module_init(esp_cache_init) module_exit(esp_cache_exit) -MODULE_DEVICE_TABLE(of, esp_cache_device_ids); + MODULE_DEVICE_TABLE(of, esp_cache_device_ids); MODULE_AUTHOR("Paolo Mantovani "); MODULE_LICENSE("GPL"); diff --git a/soft/common/drivers/linux/include/contig.h b/soft/common/drivers/linux/include/contig.h index 837019d490..1e159243ab 100644 --- a/soft/common/drivers/linux/include/contig.h +++ b/soft/common/drivers/linux/include/contig.h @@ -13,7 +13,7 @@ /* enforce strict typecheck */ struct contig_handle_struct { - char unused; + char unused; }; typedef struct contig_handle_struct *contig_handle_t; @@ -30,7 +30,8 @@ typedef struct contig_handle_struct *contig_handle_t; * Returns 0 on success or -1 on error, setting errno. */ void *contig_alloc(unsigned long size, contig_handle_t *handle); -void *contig_alloc_policy(struct contig_alloc_params params, unsigned long size, contig_handle_t *handle); +void *contig_alloc_policy(struct contig_alloc_params params, unsigned long size, + contig_handle_t *handle); /** * contig_free - free a contiguous buffer @@ -49,7 +50,6 @@ void contig_free(contig_handle_t handle); */ contig_khandle_t contig_to_khandle(contig_handle_t handle); - /** * contig_to_most_allocated - get on which ddr node most chunks have * been allocated @@ -79,15 +79,14 @@ void contig_copy_to(contig_handle_t handle, unsigned long offset, void *from, un */ void contig_copy_from(void *to, contig_handle_t handle, unsigned long offset, unsigned long size); -#define DEF_CONTIG_READ(funcname_, type_) \ - static inline type_ \ - funcname_(contig_handle_t handle, unsigned long offs) \ - { \ - type_ ret; \ - \ - contig_copy_from(&ret, handle, offs, sizeof(ret)); \ - return ret; \ - } +#define DEF_CONTIG_READ(funcname_, type_) \ + static inline type_ funcname_(contig_handle_t handle, unsigned long offs) \ + { \ + type_ ret; \ + \ + contig_copy_from(&ret, handle, offs, sizeof(ret)); \ + return ret; \ + } /** * contig_read32 - read a uint32_t from a contig buffer @@ -98,15 +97,14 @@ void contig_copy_from(void *to, contig_handle_t handle, unsigned long offset, un */ DEF_CONTIG_READ(contig_read32, uint32_t) DEF_CONTIG_READ(contig_read16, uint16_t) -DEF_CONTIG_READ(contig_read8, uint8_t) +DEF_CONTIG_READ(contig_read8, uint8_t) DEF_CONTIG_READ(contig_read64, uint64_t) -#define DEF_CONTIG_WRITE(funcname_, type_) \ - static inline void \ - funcname_(type_ val, contig_handle_t handle, unsigned long offs)\ - { \ - contig_copy_to(handle, offs, &val, sizeof(val)); \ - } +#define DEF_CONTIG_WRITE(funcname_, type_) \ + static inline void funcname_(type_ val, contig_handle_t handle, unsigned long offs) \ + { \ + contig_copy_to(handle, offs, &val, sizeof(val)); \ + } /** * contig_write32 - write a uint32_t to a contig buffer @@ -116,7 +114,7 @@ DEF_CONTIG_READ(contig_read64, uint64_t) */ DEF_CONTIG_WRITE(contig_write32, uint32_t) DEF_CONTIG_WRITE(contig_write16, uint16_t) -DEF_CONTIG_WRITE(contig_write8, uint8_t) +DEF_CONTIG_WRITE(contig_write8, uint8_t) DEF_CONTIG_WRITE(contig_write64, uint64_t) #endif /* CONTIG_H */ diff --git a/soft/common/drivers/linux/include/test/le.h b/soft/common/drivers/linux/include/test/le.h index f573fe4967..175cf2b223 100644 --- a/soft/common/drivers/linux/include/test/le.h +++ b/soft/common/drivers/linux/include/test/le.h @@ -6,9 +6,9 @@ #ifndef TEST_LE_H #define TEST_LE_H +#include #include #include -#include size_t lefread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t lefwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); diff --git a/soft/common/drivers/linux/libesp/libesp.c b/soft/common/drivers/linux/libesp/libesp.c index 82eb8503b8..743ebab634 100644 --- a/soft/common/drivers/linux/libesp/libesp.c +++ b/soft/common/drivers/linux/libesp/libesp.c @@ -9,292 +9,270 @@ buf2handle_node *head = NULL; void insert_buf(void *buf, contig_handle_t *handle, enum contig_alloc_policy policy) { - buf2handle_node *new = malloc(sizeof(buf2handle_node)); - new->buf = buf; - new->handle = handle; - new->policy = policy; + buf2handle_node *new = malloc(sizeof(buf2handle_node)); + new->buf = buf; + new->handle = handle; + new->policy = policy; - new->next = head; - head = new; + new->next = head; + head = new; } -contig_handle_t* lookup_handle(void *buf, enum contig_alloc_policy *policy) +contig_handle_t *lookup_handle(void *buf, enum contig_alloc_policy *policy) { - buf2handle_node *cur = head; - while (cur != NULL) { - if (cur->buf == buf) { - if (policy != NULL) - *policy = cur->policy; - return cur->handle; - } - cur = cur->next; - } - die("buf not in active allocations\n"); + buf2handle_node *cur = head; + while (cur != NULL) { + if (cur->buf == buf) { + if (policy != NULL) *policy = cur->policy; + return cur->handle; + } + cur = cur->next; + } + die("buf not in active allocations\n"); } void remove_buf(void *buf) { - buf2handle_node *cur = head; - if (cur->buf == buf) { - head = cur->next; - contig_free(*(cur->handle)); - free(cur); - return; - } - - buf2handle_node *prev; - while (cur != NULL && cur->buf != buf) { - prev = cur; - cur = cur->next; - } - - if (cur == NULL) - die("buf not in active allocations\n"); - - prev->next = cur->next; - contig_free(*(cur->handle)); - free(cur->handle); - free(cur); + buf2handle_node *cur = head; + if (cur->buf == buf) { + head = cur->next; + contig_free(*(cur->handle)); + free(cur); + return; + } + + buf2handle_node *prev; + while (cur != NULL && cur->buf != buf) { + prev = cur; + cur = cur->next; + } + + if (cur == NULL) die("buf not in active allocations\n"); + + prev->next = cur->next; + contig_free(*(cur->handle)); + free(cur->handle); + free(cur); } bool thread_is_p2p(esp_thread_info_t *thread) { - return ((thread->esp_desc)->p2p_store || (thread->esp_desc)->p2p_nsrcs); + return ((thread->esp_desc)->p2p_store || (thread->esp_desc)->p2p_nsrcs); } -unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} +unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } -void *accelerator_thread( void *ptr ) +void *accelerator_thread(void *ptr) { - esp_thread_info_t *info = (esp_thread_info_t *) ptr; - struct timespec th_start; - struct timespec th_end; - int rc = 0; + esp_thread_info_t *info = (esp_thread_info_t *)ptr; + struct timespec th_start; + struct timespec th_end; + int rc = 0; - gettime(&th_start); - rc = ioctl(info->fd, info->ioctl_req, info->esp_desc); - gettime(&th_end); - if (rc < 0) { - perror("ioctl"); - } + gettime(&th_start); + rc = ioctl(info->fd, info->ioctl_req, info->esp_desc); + gettime(&th_end); + if (rc < 0) { perror("ioctl"); } - info->hw_ns = ts_subtract(&th_start, &th_end); + info->hw_ns = ts_subtract(&th_start, &th_end); - return NULL; + return NULL; } void *accelerator_thread_p2p(void *ptr) { - struct thread_args *args = (struct thread_args*) ptr; - esp_thread_info_t *thread = args->info; - unsigned nacc = args->nacc; - int rc = 0; - int i; - - pthread_t *threads = malloc(nacc * sizeof(pthread_t)); - - for (i = 0; i < nacc; i++) { - esp_thread_info_t *info = thread + i; - if (!info->run) - continue; - rc = pthread_create(&threads[i], NULL, accelerator_thread, (void*) info); - if (rc != 0) - perror("pthread_create"); - } - - for (i = 0; i < nacc; i++) { - esp_thread_info_t *info = thread + i; - if (!info->run) - continue; - rc = pthread_join(threads[i], NULL); - if (rc != 0) - perror("pthread_join"); - close(info->fd); - } - free(threads); - free(ptr); - return NULL; + struct thread_args *args = (struct thread_args *)ptr; + esp_thread_info_t *thread = args->info; + unsigned nacc = args->nacc; + int rc = 0; + int i; + + pthread_t *threads = malloc(nacc * sizeof(pthread_t)); + + for (i = 0; i < nacc; i++) { + esp_thread_info_t *info = thread + i; + if (!info->run) continue; + rc = pthread_create(&threads[i], NULL, accelerator_thread, (void *)info); + if (rc != 0) perror("pthread_create"); + } + + for (i = 0; i < nacc; i++) { + esp_thread_info_t *info = thread + i; + if (!info->run) continue; + rc = pthread_join(threads[i], NULL); + if (rc != 0) perror("pthread_join"); + close(info->fd); + } + free(threads); + free(ptr); + return NULL; } void *accelerator_thread_serial(void *ptr) { - struct thread_args *args = (struct thread_args*) ptr; - esp_thread_info_t *thread = args->info; - unsigned nacc = args->nacc; - int i; - for (i = 0; i < nacc; i++) { - - struct timespec th_start; - struct timespec th_end; - int rc = 0; - esp_thread_info_t *info = thread + i; - - if (!info->run) - continue; - - gettime(&th_start); - rc = ioctl(info->fd, info->ioctl_req, info->esp_desc); - gettime(&th_end); - if (rc < 0) { - perror("ioctl"); - } - - info->hw_ns = ts_subtract(&th_start, &th_end); - close(info->fd); - } - free(ptr); - return NULL; + struct thread_args *args = (struct thread_args *)ptr; + esp_thread_info_t *thread = args->info; + unsigned nacc = args->nacc; + int i; + for (i = 0; i < nacc; i++) { + + struct timespec th_start; + struct timespec th_end; + int rc = 0; + esp_thread_info_t *info = thread + i; + + if (!info->run) continue; + + gettime(&th_start); + rc = ioctl(info->fd, info->ioctl_req, info->esp_desc); + gettime(&th_end); + if (rc < 0) { perror("ioctl"); } + + info->hw_ns = ts_subtract(&th_start, &th_end); + close(info->fd); + } + free(ptr); + return NULL; } void *esp_alloc_policy(struct contig_alloc_params params, size_t size) { - contig_handle_t *handle = malloc(sizeof(contig_handle_t)); - void* contig_ptr = contig_alloc_policy(params, size, handle); - insert_buf(contig_ptr, handle, params.policy); - return contig_ptr; + contig_handle_t *handle = malloc(sizeof(contig_handle_t)); + void *contig_ptr = contig_alloc_policy(params, size, handle); + insert_buf(contig_ptr, handle, params.policy); + return contig_ptr; } void *esp_alloc(size_t size) { - contig_handle_t *handle = malloc(sizeof(contig_handle_t)); - void* contig_ptr = contig_alloc(size, handle); - insert_buf(contig_ptr, handle, CONTIG_ALLOC_PREFERRED); - return contig_ptr; + contig_handle_t *handle = malloc(sizeof(contig_handle_t)); + void *contig_ptr = contig_alloc(size, handle); + insert_buf(contig_ptr, handle, CONTIG_ALLOC_PREFERRED); + return contig_ptr; } -static void esp_config(esp_thread_info_t* cfg[], unsigned nthreads, unsigned *nacc) +static void esp_config(esp_thread_info_t *cfg[], unsigned nthreads, unsigned *nacc) { - int i, j; - for (i = 0; i < nthreads; i++) { - unsigned len = nacc[i]; - for(j = 0; j < len; j++) { - esp_thread_info_t *info = cfg[i] + j; - if (!info->run) - continue; - - enum contig_alloc_policy policy; - contig_handle_t *handle = lookup_handle(info->hw_buf, &policy); - - (info->esp_desc)->contig = contig_to_khandle(*handle); - (info->esp_desc)->ddr_node = contig_to_most_allocated(*handle); - (info->esp_desc)->alloc_policy = policy; - (info->esp_desc)->run = true; - } - } + int i, j; + for (i = 0; i < nthreads; i++) { + unsigned len = nacc[i]; + for (j = 0; j < len; j++) { + esp_thread_info_t *info = cfg[i] + j; + if (!info->run) continue; + + enum contig_alloc_policy policy; + contig_handle_t *handle = lookup_handle(info->hw_buf, &policy); + + (info->esp_desc)->contig = contig_to_khandle(*handle); + (info->esp_desc)->ddr_node = contig_to_most_allocated(*handle); + (info->esp_desc)->alloc_policy = policy; + (info->esp_desc)->run = true; + } + } } -static void print_time_info(esp_thread_info_t *info[], unsigned long long hw_ns, int nthreads, unsigned* nacc) +static void print_time_info(esp_thread_info_t *info[], unsigned long long hw_ns, int nthreads, + unsigned *nacc) { - int i, j; - - printf(" > Test time: %llu ns\n", hw_ns); - for (i = 0; i < nthreads; i++) { - unsigned len = nacc[i]; - for (j = 0; j < len; j++) { - esp_thread_info_t* cur = info[i] + j; - if (cur->run) - printf(" - %s time: %llu ns\n", cur->devname, cur->hw_ns); - } - } + int i, j; + + printf(" > Test time: %llu ns\n", hw_ns); + for (i = 0; i < nthreads; i++) { + unsigned len = nacc[i]; + for (j = 0; j < len; j++) { + esp_thread_info_t *cur = info[i] + j; + if (cur->run) printf(" - %s time: %llu ns\n", cur->devname, cur->hw_ns); + } + } } void esp_run(esp_thread_info_t cfg[], unsigned nacc) { - int i; - - if (thread_is_p2p(&cfg[0])) { - esp_thread_info_t *cfg_ptrs[1]; - cfg_ptrs[0] = cfg; - - esp_run_parallel(cfg_ptrs, 1, &nacc); - } else{ - esp_thread_info_t **cfg_ptrs = malloc(sizeof(esp_thread_info_t*) * nacc); - unsigned *nacc_arr = malloc(sizeof(unsigned) * nacc); - - for (i = 0; i < nacc; i++) { - nacc_arr[i] = 1; - cfg_ptrs[i] = &cfg[i]; - } - esp_run_parallel(cfg_ptrs, nacc, nacc_arr); - free(nacc_arr); - free(cfg_ptrs); - } + int i; + + if (thread_is_p2p(&cfg[0])) { + esp_thread_info_t *cfg_ptrs[1]; + cfg_ptrs[0] = cfg; + + esp_run_parallel(cfg_ptrs, 1, &nacc); + } + else { + esp_thread_info_t **cfg_ptrs = malloc(sizeof(esp_thread_info_t *) * nacc); + unsigned *nacc_arr = malloc(sizeof(unsigned) * nacc); + + for (i = 0; i < nacc; i++) { + nacc_arr[i] = 1; + cfg_ptrs[i] = &cfg[i]; + } + esp_run_parallel(cfg_ptrs, nacc, nacc_arr); + free(nacc_arr); + free(cfg_ptrs); + } } -void esp_run_parallel(esp_thread_info_t* cfg[], unsigned nthreads, unsigned* nacc) +void esp_run_parallel(esp_thread_info_t *cfg[], unsigned nthreads, unsigned *nacc) { - int i, j; - struct timespec th_start; - struct timespec th_end; - pthread_t *thread = malloc(nthreads * sizeof(pthread_t)); - int rc = 0; - esp_config(cfg, nthreads, nacc); - for (i = 0; i < nthreads; i++) { - unsigned len = nacc[i]; - for (j = 0; j < len; j++) { - esp_thread_info_t *info = cfg[i] + j; - const char *prefix = "/dev/"; - char path[70]; - - if (strlen(info->devname) > 64) { - contig_handle_t *handle = lookup_handle(info->hw_buf, NULL); - contig_free(*handle); - die("Error: device name %s exceeds maximum length of 64 characters\n", - info->devname); - } - - sprintf(path, "%s%s", prefix, info->devname); - - info->fd = open(path, O_RDWR, 0); - if (info->fd < 0) { - contig_handle_t *handle = lookup_handle(info->hw_buf, NULL); - contig_free(*handle); - die_errno("fopen failed\n"); - } - } - } - - gettime(&th_start); - for (i = 0; i < nthreads; i++) { - struct thread_args *args = malloc(sizeof(struct thread_args));; - args->info = cfg[i]; - args->nacc = nacc[i]; - - if (thread_is_p2p(cfg[i])) { - if (nthreads == 1) - accelerator_thread_p2p( (void*) args); - else - rc = pthread_create(&thread[i], NULL, accelerator_thread_p2p, (void*) args); - } else { - if (nthreads == 1) - accelerator_thread_serial( (void*) args); - else - rc = pthread_create(&thread[i], NULL, accelerator_thread_serial, (void*) args); - } - - if(rc != 0) { - perror("pthread_create"); - } - } - for (i = 0; i < nthreads; i++) { - if (nthreads > 1) - rc = pthread_join(thread[i], NULL); - - if(rc != 0) { - perror("pthread_join"); - } - } - - gettime(&th_end); - print_time_info(cfg, ts_subtract(&th_start, &th_end), nthreads, nacc); - - free(thread); + int i, j; + struct timespec th_start; + struct timespec th_end; + pthread_t *thread = malloc(nthreads * sizeof(pthread_t)); + int rc = 0; + esp_config(cfg, nthreads, nacc); + for (i = 0; i < nthreads; i++) { + unsigned len = nacc[i]; + for (j = 0; j < len; j++) { + esp_thread_info_t *info = cfg[i] + j; + const char *prefix = "/dev/"; + char path[70]; + + if (strlen(info->devname) > 64) { + contig_handle_t *handle = lookup_handle(info->hw_buf, NULL); + contig_free(*handle); + die("Error: device name %s exceeds maximum length of 64 characters\n", + info->devname); + } + + sprintf(path, "%s%s", prefix, info->devname); + + info->fd = open(path, O_RDWR, 0); + if (info->fd < 0) { + contig_handle_t *handle = lookup_handle(info->hw_buf, NULL); + contig_free(*handle); + die_errno("fopen failed\n"); + } + } + } + + gettime(&th_start); + for (i = 0; i < nthreads; i++) { + struct thread_args *args = malloc(sizeof(struct thread_args)); + ; + args->info = cfg[i]; + args->nacc = nacc[i]; + + if (thread_is_p2p(cfg[i])) { + if (nthreads == 1) accelerator_thread_p2p((void *)args); + else + rc = pthread_create(&thread[i], NULL, accelerator_thread_p2p, (void *)args); + } + else { + if (nthreads == 1) accelerator_thread_serial((void *)args); + else + rc = pthread_create(&thread[i], NULL, accelerator_thread_serial, (void *)args); + } + + if (rc != 0) { perror("pthread_create"); } + } + for (i = 0; i < nthreads; i++) { + if (nthreads > 1) rc = pthread_join(thread[i], NULL); + + if (rc != 0) { perror("pthread_join"); } + } + + gettime(&th_end); + print_time_info(cfg, ts_subtract(&th_start, &th_end), nthreads, nacc); + + free(thread); } -void esp_free(void *buf) -{ - remove_buf(buf); -} +void esp_free(void *buf) { remove_buf(buf); } diff --git a/soft/common/drivers/linux/test/le.c b/soft/common/drivers/linux/test/le.c index 9b0016c6ef..ea6c192765 100644 --- a/soft/common/drivers/linux/test/le.c +++ b/soft/common/drivers/linux/test/le.c @@ -4,104 +4,99 @@ #include #include -#include #include +#include #ifdef __sparc__ size_t lefread(void *ptr, size_t size, size_t nmemb, FILE *stream) { - /** - * fread() and fwrite() return the number of items successfully read - * or written (i.e., not the number of characters). If an error occurs, - * or the end-of-file is reached, the return value is a short item count - * (or zero). - * - * fread() does not distinguish between end-of-file and error, and - * callers must use feof(3) and ferror(3) to determine which occurred. - */ - size_t n; - unsigned char *p; - unsigned char *buf; - int i, j; - - if (size == 1) - return fread(ptr, size, nmemb, stream); - - n = fread(ptr, size, nmemb, stream); - if (n == 0) - return n; - - p = ptr; - buf = malloc(size); - if (!buf || !p) - return 0; - - for (i = 0; i < nmemb; i++) { - memcpy((void *) buf, (void *) p + size*i, size); - for (j = 0; j < size; j++) - p[size*i + j] = buf[size-j-1]; - } - - free(buf); - return n; + /** + * fread() and fwrite() return the number of items successfully read + * or written (i.e., not the number of characters). If an error occurs, + * or the end-of-file is reached, the return value is a short item count + * (or zero). + * + * fread() does not distinguish between end-of-file and error, and + * callers must use feof(3) and ferror(3) to determine which occurred. + */ + size_t n; + unsigned char *p; + unsigned char *buf; + int i, j; + + if (size == 1) return fread(ptr, size, nmemb, stream); + + n = fread(ptr, size, nmemb, stream); + if (n == 0) return n; + + p = ptr; + buf = malloc(size); + if (!buf || !p) return 0; + + for (i = 0; i < nmemb; i++) { + memcpy((void *)buf, (void *)p + size * i, size); + for (j = 0; j < size; j++) + p[size * i + j] = buf[size - j - 1]; + } + + free(buf); + return n; } size_t lefwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { - /** - * fread() and fwrite() return the number of items successfully read - * or written (i.e., not the number of characters). If an error occurs, - * or the end-of-file is reached, the return value is a short item count - * (or zero). - * - * fread() does not distinguish between end-of-file and error, and - * callers must use feof(3) and ferror(3) to determine which occurred. - */ - const unsigned char *p; - unsigned char *buf; - size_t n; - int i, j; - - if (size == 1) - return fwrite(ptr, size, nmemb, stream); - - p = ptr; - buf = malloc(nmemb * size); - if (!buf) - return 0; - - for (i = 0; i < nmemb; i++) - for (j = 0; j < size; j++) - buf[size * i + j] = p[size * (i + 1) - j - 1]; - - n = fwrite(buf, size, nmemb, stream); - free(buf); - - return n; + /** + * fread() and fwrite() return the number of items successfully read + * or written (i.e., not the number of characters). If an error occurs, + * or the end-of-file is reached, the return value is a short item count + * (or zero). + * + * fread() does not distinguish between end-of-file and error, and + * callers must use feof(3) and ferror(3) to determine which occurred. + */ + const unsigned char *p; + unsigned char *buf; + size_t n; + int i, j; + + if (size == 1) return fwrite(ptr, size, nmemb, stream); + + p = ptr; + buf = malloc(nmemb * size); + if (!buf) return 0; + + for (i = 0; i < nmemb; i++) + for (j = 0; j < size; j++) + buf[size * i + j] = p[size * (i + 1) - j - 1]; + + n = fwrite(buf, size, nmemb, stream); + free(buf); + + return n; } #else size_t lefread(void *ptr, size_t size, size_t nmemb, FILE *stream) { - return fread(ptr, size, nmemb, stream); + return fread(ptr, size, nmemb, stream); } size_t lefwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { - return fwrite(ptr, size, nmemb, stream); + return fwrite(ptr, size, nmemb, stream); } #endif /* __sparc__ */ void le_read_elem(void *dest, size_t size_elem, size_t n_elems, FILE *fp, const char *path) { - size_t n; - - n = lefread(dest, size_elem, n_elems, fp); - if (n != n_elems) { - die("Unable to read phase history data from %s " - "(read %zu elements instead of %lu).\n", - path, n, n_elems); - } + size_t n; + + n = lefread(dest, size_elem, n_elems, fp); + if (n != n_elems) { + die("Unable to read phase history data from %s " + "(read %zu elements instead of %lu).\n", + path, n, n_elems); + } } diff --git a/soft/ibex/bootrom/main.c b/soft/ibex/bootrom/main.c index 14d1b4221c..e3aa4a694b 100644 --- a/soft/ibex/bootrom/main.c +++ b/soft/ibex/bootrom/main.c @@ -2,21 +2,16 @@ int main() { - init_uart(); + init_uart(); - // jump to the address - __asm__ volatile( - "li s0, 0x80000000;" - "la a1, _dtb;" - "jr s0"); + // jump to the address + __asm__ volatile("li s0, 0x80000000;" + "la a1, _dtb;" + "jr s0"); - while (1) - { - // do nothing - } + while (1) { + // do nothing + } } -void handle_trap(void) -{ - -} +void handle_trap(void) {} diff --git a/soft/ibex/common/syscalls.c b/soft/ibex/common/syscalls.c index c00f89ef85..7468767dac 100644 --- a/soft/ibex/common/syscalls.c +++ b/soft/ibex/common/syscalls.c @@ -1,13 +1,13 @@ // See LICENSE for license details. -#include -#include +#include "uart.h" +#include "util.h" +#include #include +#include #include -#include +#include #include -#include "util.h" -#include "uart.h" #undef strcmp @@ -16,437 +16,410 @@ extern volatile uint64_t fromhost; #define NUM_COUNTERS 2 static uintptr_t counters[NUM_COUNTERS]; -static char* counter_names[NUM_COUNTERS]; +static char *counter_names[NUM_COUNTERS]; void setStats(int enable) { - int i = 0; -#define READ_CTR(name) do { \ - while (i >= NUM_COUNTERS) ; \ - uintptr_t csr = read_csr(name); \ - if (!enable) { csr -= counters[i]; counter_names[i] = #name; } \ - counters[i++] = csr; \ - } while (0) - - READ_CTR(mcycle); - READ_CTR(minstret); + int i = 0; +#define READ_CTR(name) \ + do { \ + while (i >= NUM_COUNTERS) \ + ; \ + uintptr_t csr = read_csr(name); \ + if (!enable) { \ + csr -= counters[i]; \ + counter_names[i] = #name; \ + } \ + counters[i++] = csr; \ + } while (0) + + READ_CTR(mcycle); + READ_CTR(minstret); #undef READ_CTR } void __attribute__((noreturn)) tohost_exit(uintptr_t code) { - tohost = (code << 1) | 1; - while (1); + tohost = (code << 1) | 1; + while (1) + ; } uintptr_t __attribute__((weak)) handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) { - tohost_exit(1337); + tohost_exit(1337); } -void exit(int code) -{ - tohost_exit(code); -} +void exit(int code) { tohost_exit(code); } -void abort() -{ - exit(128 + SIGABRT); -} +void abort() { exit(128 + SIGABRT); } -void printstr(const char* s) -{ - print_uart(s); -} +void printstr(const char *s) { print_uart(s); } void __attribute__((weak)) thread_entry(int cid, int nc) { - // multi-threaded programs override this function. - // for the case of single-threaded programs, only let core 0 proceed. - while (cid != 0); + // multi-threaded programs override this function. + // for the case of single-threaded programs, only let core 0 proceed. + while (cid != 0) + ; } -int __attribute__((weak)) main(int argc, char** argv) +int __attribute__((weak)) main(int argc, char **argv) { - // single-threaded programs override this function. - printstr("Implement main(), foo!\n"); - return -1; + // single-threaded programs override this function. + printstr("Implement main(), foo!\n"); + return -1; } static void init_tls() { - register void* thread_pointer asm("tp"); - extern char _tls_data; - extern __thread char _tdata_begin, _tdata_end, _tbss_end; - size_t tdata_size = &_tdata_end - &_tdata_begin; - memcpy(thread_pointer, &_tls_data, tdata_size); - size_t tbss_size = &_tbss_end - &_tdata_end; - memset(thread_pointer + tdata_size, 0, tbss_size); + register void *thread_pointer asm("tp"); + extern char _tls_data; + extern __thread char _tdata_begin, _tdata_end, _tbss_end; + size_t tdata_size = &_tdata_end - &_tdata_begin; + memcpy(thread_pointer, &_tls_data, tdata_size); + size_t tbss_size = &_tbss_end - &_tdata_end; + memset(thread_pointer + tdata_size, 0, tbss_size); } void _init(int cid, int nc) { - init_tls(); - thread_entry(cid, nc); + init_tls(); + thread_entry(cid, nc); - // only single-threaded programs should ever get here. - int ret = main(0, 0); + // only single-threaded programs should ever get here. + int ret = main(0, 0); - char buf[NUM_COUNTERS * 32] __attribute__((aligned(64))); - char* pbuf = buf; - for (int i = 0; i < NUM_COUNTERS; i++) - if (counters[i]) - pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]); - if (pbuf != buf) - printstr(buf); + char buf[NUM_COUNTERS * 32] __attribute__((aligned(64))); + char *pbuf = buf; + for (int i = 0; i < NUM_COUNTERS; i++) + if (counters[i]) pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]); + if (pbuf != buf) printstr(buf); - exit(ret); + exit(ret); } #undef putchar int putchar(int ch) { - static __thread char buf[64] __attribute__((aligned(64))); - static __thread int buflen = 0; + static __thread char buf[64] __attribute__((aligned(64))); + static __thread int buflen = 0; - buf[buflen++] = ch; + buf[buflen++] = ch; - if (ch == '\n' || buflen == (sizeof(buf) - 1)) - { - buf[buflen] = '\0'; - print_uart(buf); - buflen = 0; - } + if (ch == '\n' || buflen == (sizeof(buf) - 1)) { + buf[buflen] = '\0'; + print_uart(buf); + buflen = 0; + } - return 0; + return 0; } void printhex(uint64_t x) { - char str[17]; - int i; - for (i = 0; i < 16; i++) - { - str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10); - x >>= 4; - } - str[16] = 0; - - printstr(str); + char str[17]; + int i; + for (i = 0; i < 16; i++) { + str[15 - i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a' - 10); + x >>= 4; + } + str[16] = 0; + + printstr(str); } -static inline void printnum(void (*putch)(int, void**), void **putdat, - unsigned long long num, unsigned base, int width, int padc) +static inline void printnum(void (*putch)(int, void **), void **putdat, unsigned long long num, + unsigned base, int width, int padc) { - unsigned digs[sizeof(num)*CHAR_BIT]; - int pos = 0; - - while (1) - { - digs[pos++] = num % base; - if (num < base) - break; - num /= base; - } - - while (width-- > pos) - putch(padc, putdat); - - while (pos-- > 0) - putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat); + unsigned digs[sizeof(num) * CHAR_BIT]; + int pos = 0; + + while (1) { + digs[pos++] = num % base; + if (num < base) break; + num /= base; + } + + while (width-- > pos) + putch(padc, putdat); + + while (pos-- > 0) + putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat); } static unsigned long long getuint(va_list *ap, int lflag) { - if (lflag >= 2) - return va_arg(*ap, unsigned long long); - else if (lflag) - return va_arg(*ap, unsigned long); - else - return va_arg(*ap, unsigned int); + if (lflag >= 2) return va_arg(*ap, unsigned long long); + else if (lflag) + return va_arg(*ap, unsigned long); + else + return va_arg(*ap, unsigned int); } static long long getint(va_list *ap, int lflag) { - if (lflag >= 2) - return va_arg(*ap, long long); - else if (lflag) - return va_arg(*ap, long); - else - return va_arg(*ap, int); + if (lflag >= 2) return va_arg(*ap, long long); + else if (lflag) + return va_arg(*ap, long); + else + return va_arg(*ap, int); } -static void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap) +static void vprintfmt(void (*putch)(int, void **), void **putdat, const char *fmt, va_list ap) { - register const char* p; - const char* last_fmt; - register int ch, err; - unsigned long long num; - int base, lflag, width, precision, altflag; - char padc; - - while (1) { - while ((ch = *(unsigned char *) fmt) != '%') { - if (ch == '\0') - return; - fmt++; - putch(ch, putdat); - } - fmt++; - - // Process a %-escape sequence - last_fmt = fmt; - padc = ' '; - width = -1; - precision = -1; - lflag = 0; - altflag = 0; - reswitch: - switch (ch = *(unsigned char *) fmt++) { - - // flag to pad on the right - case '-': - padc = '-'; - goto reswitch; - - // flag to pad with 0's instead of spaces - case '0': - padc = '0'; - goto reswitch; - - // width field - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - for (precision = 0; ; ++fmt) { - precision = precision * 10 + ch - '0'; - ch = *fmt; - if (ch < '0' || ch > '9') - break; - } - goto process_precision; - - case '*': - precision = va_arg(ap, int); - goto process_precision; - - case '.': - if (width < 0) - width = 0; - goto reswitch; - - case '#': - altflag = 1; - goto reswitch; - - process_precision: - if (width < 0) - width = precision, precision = -1; - goto reswitch; - - // long flag (doubled for long long) - case 'l': - lflag++; - goto reswitch; - - // character - case 'c': - putch(va_arg(ap, int), putdat); - break; - - // string - case 's': - if ((p = va_arg(ap, char *)) == NULL) - p = "(null)"; - if (width > 0 && padc != '-') - for (width -= strnlen(p, precision); width > 0; width--) - putch(padc, putdat); - for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) { - putch(ch, putdat); - p++; - } - for (; width > 0; width--) - putch(' ', putdat); - break; - - // (signed) decimal - case 'd': - num = getint(&ap, lflag); - if ((long long) num < 0) { - putch('-', putdat); - num = -(long long) num; - } - base = 10; - goto signed_number; - - // unsigned decimal - case 'u': - base = 10; - goto unsigned_number; - - // (unsigned) octal - case 'o': - // should do something with padding so it's always 3 octits - base = 8; - goto unsigned_number; - - // pointer - case 'p': - static_assert(sizeof(long) == sizeof(void*)); - lflag = 1; - putch('0', putdat); - putch('x', putdat); - /* fall through to 'x' */ - - // (unsigned) hexadecimal - case 'x': - base = 16; - unsigned_number: - num = getuint(&ap, lflag); - signed_number: - printnum(putch, putdat, num, base, width, padc); - break; - - // escaped '%' character - case '%': - putch(ch, putdat); - break; - - // unrecognized escape sequence - just print it literally - default: - putch('%', putdat); - fmt = last_fmt; - break; + register const char *p; + const char *last_fmt; + register int ch, err; + unsigned long long num; + int base, lflag, width, precision, altflag; + char padc; + + while (1) { + while ((ch = *(unsigned char *)fmt) != '%') { + if (ch == '\0') return; + fmt++; + putch(ch, putdat); + } + fmt++; + + // Process a %-escape sequence + last_fmt = fmt; + padc = ' '; + width = -1; + precision = -1; + lflag = 0; + altflag = 0; +reswitch: + switch (ch = *(unsigned char *)fmt++) { + + // flag to pad on the right + case '-': padc = '-'; goto reswitch; + + // flag to pad with 0's instead of spaces + case '0': padc = '0'; goto reswitch; + + // width field + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + for (precision = 0;; ++fmt) { + precision = precision * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') break; + } + goto process_precision; + + case '*': precision = va_arg(ap, int); goto process_precision; + + case '.': + if (width < 0) width = 0; + goto reswitch; + + case '#': + altflag = 1; + goto reswitch; + +process_precision: + if (width < 0) width = precision, precision = -1; + goto reswitch; + + // long flag (doubled for long long) + case 'l': lflag++; goto reswitch; + + // character + case 'c': putch(va_arg(ap, int), putdat); break; + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) p = "(null)"; + if (width > 0 && padc != '-') + for (width -= strnlen(p, precision); width > 0; width--) + putch(padc, putdat); + for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) { + putch(ch, putdat); + p++; + } + for (; width > 0; width--) + putch(' ', putdat); + break; + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + if ((long long)num < 0) { + putch('-', putdat); + num = -(long long)num; + } + base = 10; + goto signed_number; + + // unsigned decimal + case 'u': base = 10; goto unsigned_number; + + // (unsigned) octal + case 'o': + // should do something with padding so it's always 3 octits + base = 8; + goto unsigned_number; + + // pointer + case 'p': + static_assert(sizeof(long) == sizeof(void *)); + lflag = 1; + putch('0', putdat); + putch('x', putdat); + /* fall through to 'x' */ + + // (unsigned) hexadecimal + case 'x': + base = 16; +unsigned_number: + num = getuint(&ap, lflag); +signed_number: + printnum(putch, putdat, num, base, width, padc); + break; + + // escaped '%' character + case '%': putch(ch, putdat); break; + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + fmt = last_fmt; + break; + } } - } } -int printf(const char* fmt, ...) +int printf(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); + va_list ap; + va_start(ap, fmt); - vprintfmt((void*)putchar, 0, fmt, ap); + vprintfmt((void *)putchar, 0, fmt, ap); - va_end(ap); - return 0; // incorrect return value, but who cares, anyway? + va_end(ap); + return 0; // incorrect return value, but who cares, anyway? } -int sprintf(char* str, const char* fmt, ...) +int sprintf(char *str, const char *fmt, ...) { - va_list ap; - char* str0 = str; - va_start(ap, fmt); - - void sprintf_putch(int ch, void** data) - { - char** pstr = (char**)data; - **pstr = ch; - (*pstr)++; - } - - vprintfmt(sprintf_putch, (void**)&str, fmt, ap); - *str = 0; - - va_end(ap); - return str - str0; + va_list ap; + char *str0 = str; + va_start(ap, fmt); + + void sprintf_putch(int ch, void **data) + { + char **pstr = (char **)data; + **pstr = ch; + (*pstr)++; + } + + vprintfmt(sprintf_putch, (void **)&str, fmt, ap); + *str = 0; + + va_end(ap); + return str - str0; } -void* memcpy(void* dest, const void* src, size_t len) +void *memcpy(void *dest, const void *src, size_t len) { - if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) { - const uintptr_t* s = src; - uintptr_t *d = dest; - while (d < (uintptr_t*)(dest + len)) - *d++ = *s++; - } else { - const char* s = src; - char *d = dest; - while (d < (char*)(dest + len)) - *d++ = *s++; - } - return dest; + if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t) - 1)) == 0) { + const uintptr_t *s = src; + uintptr_t *d = dest; + while (d < (uintptr_t *)(dest + len)) + *d++ = *s++; + } + else { + const char *s = src; + char *d = dest; + while (d < (char *)(dest + len)) + *d++ = *s++; + } + return dest; } -void* memset(void* dest, int byte, size_t len) +void *memset(void *dest, int byte, size_t len) { - if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) { - uintptr_t word = byte & 0xFF; - word |= word << 8; - word |= word << 16; - word |= word << 16 << 16; - - uintptr_t *d = dest; - while (d < (uintptr_t*)(dest + len)) - *d++ = word; - } else { - char *d = dest; - while (d < (char*)(dest + len)) - *d++ = byte; - } - return dest; + if ((((uintptr_t)dest | len) & (sizeof(uintptr_t) - 1)) == 0) { + uintptr_t word = byte & 0xFF; + word |= word << 8; + word |= word << 16; + word |= word << 16 << 16; + + uintptr_t *d = dest; + while (d < (uintptr_t *)(dest + len)) + *d++ = word; + } + else { + char *d = dest; + while (d < (char *)(dest + len)) + *d++ = byte; + } + return dest; } size_t strlen(const char *s) { - const char *p = s; - while (*p) - p++; - return p - s; + const char *p = s; + while (*p) + p++; + return p - s; } size_t strnlen(const char *s, size_t n) { - const char *p = s; - while (n-- && *p) - p++; - return p - s; + const char *p = s; + while (n-- && *p) + p++; + return p - s; } -int strcmp(const char* s1, const char* s2) +int strcmp(const char *s1, const char *s2) { - unsigned char c1, c2; + unsigned char c1, c2; - do { - c1 = *s1++; - c2 = *s2++; - } while (c1 != 0 && c1 == c2); + do { + c1 = *s1++; + c2 = *s2++; + } while (c1 != 0 && c1 == c2); - return c1 - c2; + return c1 - c2; } -char* strcpy(char* dest, const char* src) +char *strcpy(char *dest, const char *src) { - char* d = dest; - while ((*d++ = *src++)) - ; - return dest; + char *d = dest; + while ((*d++ = *src++)) + ; + return dest; } -long atol(const char* str) +long atol(const char *str) { - long res = 0; - int sign = 0; + long res = 0; + int sign = 0; - while (*str == ' ') - str++; + while (*str == ' ') + str++; - if (*str == '-' || *str == '+') { - sign = *str == '-'; - str++; - } + if (*str == '-' || *str == '+') { + sign = *str == '-'; + str++; + } - while (*str) { - res *= 10; - res += *str++ - '0'; - } + while (*str) { + res *= 10; + res += *str++ - '0'; + } - return sign ? -res : res; + return sign ? -res : res; } diff --git a/soft/leon3/bootrom/prom.h b/soft/leon3/bootrom/prom.h index e283ab8bdb..24438c9711 100644 --- a/soft/leon3/bootrom/prom.h +++ b/soft/leon3/bootrom/prom.h @@ -1,10 +1,9 @@ -#define MCFG1 0x10380133 -#define MCFG2 0xe6B86e60 -#define MCFG3 0x000ff000 -#define ASDCFG 0x80000000 -#define DSDCFG 0xe6A06e60 +#define MCFG1 0x10380133 +#define MCFG2 0xe6B86e60 +#define MCFG3 0x000ff000 +#define ASDCFG 0x80000000 +#define DSDCFG 0xe6A06e60 #define L2MCTRLIO 0x80000000 #define IRQCTRL 0x80000200 #define RAMSTART 0x40000000 #define RAMSIZE 0x00100000 - diff --git a/soft/leon3/grlib/ahbrom.c b/soft/leon3/grlib/ahbrom.c index 71949f6c60..948e138610 100644 --- a/soft/leon3/grlib/ahbrom.c +++ b/soft/leon3/grlib/ahbrom.c @@ -1,34 +1,38 @@ -#include #include +#include #include -#include #include +#include #include #ifdef WIN32 -#include + #include #endif #include -int main (int argc, char **argv) +int main(int argc, char **argv) { - struct stat sbuf; - char x[128]; - int i, res, fsize, abits, tmp; - FILE *fp, *wfp; + struct stat sbuf; + char x[128]; + int i, res, fsize, abits, tmp; + FILE *fp, *wfp; - if (argc < 2) exit(1); - res = stat(argv[1], &sbuf); - if (res < 0) exit(2); - fsize = sbuf.st_size; - fp = fopen(argv[1], "rb"); - wfp = fopen(argv[2], "w+"); - if (fp == NULL) exit(2); - if (wfp == NULL) exit(2); + if (argc < 2) exit(1); + res = stat(argv[1], &sbuf); + if (res < 0) exit(2); + fsize = sbuf.st_size; + fp = fopen(argv[1], "rb"); + wfp = fopen(argv[2], "w+"); + if (fp == NULL) exit(2); + if (wfp == NULL) exit(2); - tmp = fsize; abits = 0; - while (tmp) {tmp >>= 1; abits++;} - printf(" INFO Creating %s : file size: %d bytes, address bits %d\n", argv[2], fsize, abits); - fprintf(wfp, "\n\ + tmp = fsize; + abits = 0; + while (tmp) { + tmp >>= 1; + abits++; + } + printf(" INFO Creating %s : file size: %d bytes, address bits %d\n", argv[2], fsize, abits); + fprintf(wfp, "\n\ ----------------------------------------------------------------------------\n\ -- This file is a part of the GRLIB VHDL IP LIBRARY\n\ -- Copyright (C) 2010 Aeroflex Gaisler\n\ @@ -108,14 +112,15 @@ begin\n\ comb : process (addr)\n\ begin\n\ case conv_integer(addr) is\n\ -", abits, fsize); +", + abits, fsize); - i = 0; - while (!feof(fp)) { - fread(&tmp, 1, 4, fp); - fprintf(wfp, " when 16#%05X# => romdata <= X\"%08X\";\n", i++, htonl(tmp)); - } - fprintf(wfp, "\ + i = 0; + while (!feof(fp)) { + fread(&tmp, 1, 4, fp); + fprintf(wfp, " when 16#%05X# => romdata <= X\"%08X\";\n", i++, htonl(tmp)); + } + fprintf(wfp, "\ when others => romdata <= (others => '-');\n\ end case;\n\ end process;\n\ @@ -127,8 +132,8 @@ begin\n\ end;\n\ "); - fclose (wfp); - fclose (fp); - return(0); - exit(0); + fclose(wfp); + fclose(fp); + return (0); + exit(0); } diff --git a/soft/leon3/grlib/mkprom2/bsp/clkgate/bdinit.c b/soft/leon3/grlib/mkprom2/bsp/clkgate/bdinit.c index f5bc8b77c5..50eca9e847 100644 --- a/soft/leon3/grlib/mkprom2/bsp/clkgate/bdinit.c +++ b/soft/leon3/grlib/mkprom2/bsp/clkgate/bdinit.c @@ -6,21 +6,16 @@ * bdinit0 is called before peripheral has been initialized and before RAM is * available. */ -void bdinit0(void) -{ -} +void bdinit0(void) {} /* * bdinit1 is called after peripherals registers have been initialized, but * before RAM is available. */ -void bdinit1(void) -{ -} +void bdinit1(void) {} #include "clkgate_ut700.h" - /* * This is an example initialization table. * @@ -33,42 +28,36 @@ void bdinit1(void) * The table is terminated with the entry {0, 0} */ const struct init_dev init_dev_table_example[] = { -/* gpio0 - General Purpose I/O port */ - /* First mask interrupts and then configure all signals as inputs. */ - {0x8000090c, /* I/O interrupt mask register */ 0x00000000}, - {0x80000910, /* I/O interrupt polarity register */ 0x000003c0}, - {0x80000914, /* I/O interrupt edge register */ 0x00000000}, - {0x80000908, /* I/O port direction register */ 0x00000000}, - {0x80000904, /* I/O port output register */ 0x00000000}, + /* gpio0 - General Purpose I/O port */ + /* First mask interrupts and then configure all signals as inputs. */ + {0x8000090c, /* I/O interrupt mask register */ 0x00000000}, + {0x80000910, /* I/O interrupt polarity register */ 0x000003c0}, + {0x80000914, /* I/O interrupt edge register */ 0x00000000}, + {0x80000908, /* I/O port direction register */ 0x00000000}, + {0x80000904, /* I/O port output register */ 0x00000000}, -/* The table must be terminated with the 0 as address. */ - {0x00000000, /* END OF TABLE */ 0x00000000} -}; + /* The table must be terminated with the 0 as address. */ + {0x00000000, /* END OF TABLE */ 0x00000000}}; /* bdinit2 is called after MKPROM boot loader has initialized memory. */ void bdinit2(void) { - /* - * Do custom register initialization based on a static table, defined - * above. - */ - init_dev(&init_dev_table_example[0]); + /* + * Do custom register initialization based on a static table, defined + * above. + */ + init_dev(&init_dev_table_example[0]); - /* - * Clock gate the MIL-STD-1553, CAN and SpaceWire 3 core. More - * defines for UT700 are available in the file clkgate_ut700.h - */ - clkgate_gate( - CLKGATE_UT700_GR1553B | - CLKGATE_UT700_CAN | - CLKGATE_UT700_GRSPW3 | - 0 - ); + /* + * Clock gate the MIL-STD-1553, CAN and SpaceWire 3 core. More + * defines for UT700 are available in the file clkgate_ut700.h + */ + clkgate_gate(CLKGATE_UT700_GR1553B | CLKGATE_UT700_CAN | CLKGATE_UT700_GRSPW3 | 0); - /* - * Clock enable SpaceWire 0 core. This is not needed on UT700 since all - * cores are enabled on reset. - */ + /* + * Clock enable SpaceWire 0 core. This is not needed on UT700 since all + * cores are enabled on reset. + */ #if 0 clkgate_enable( CLKGATE_UT700_GRSPW0 | @@ -76,4 +65,3 @@ void bdinit2(void) ); #endif } - diff --git a/soft/leon3/grlib/mkprom2/bsp/shared/init_reg32.c b/soft/leon3/grlib/mkprom2/bsp/shared/init_reg32.c index c2f7517963..f9a7246e7b 100644 --- a/soft/leon3/grlib/mkprom2/bsp/shared/init_reg32.c +++ b/soft/leon3/grlib/mkprom2/bsp/shared/init_reg32.c @@ -7,8 +7,8 @@ * value: value to write to base+offset */ struct init_reg32 { - uint32_t offset; - uint32_t value; + uint32_t offset; + uint32_t value; }; /* Initialize registers given an array of offset-value pairs @@ -21,17 +21,16 @@ uintptr_t init_reg32(uintptr_t base, const struct init_reg32 *table); static const uint32_t TABLE_TERM = 0xffffffff; uintptr_t init_reg32(uintptr_t base, const struct init_reg32 *table) { - uint32_t t; + uint32_t t; - while (TABLE_TERM != (t = table->offset)) { - volatile uint32_t *addr; + while (TABLE_TERM != (t = table->offset)) { + volatile uint32_t *addr; - t += base; - addr = (uint32_t *) t; - *addr = table->value; - table++; - }; + t += base; + addr = (uint32_t *)t; + *addr = table->value; + table++; + }; - return base; + return base; } - diff --git a/soft/leon3/grlib/mkprom2/dummy.c b/soft/leon3/grlib/mkprom2/dummy.c index a46866d92e..76e8197013 100644 --- a/soft/leon3/grlib/mkprom2/dummy.c +++ b/soft/leon3/grlib/mkprom2/dummy.c @@ -1,4 +1 @@ -int main() -{ - return 0; -} +int main() { return 0; } diff --git a/soft/leon3/grlib/mkprom2/testing/sparc-elf/stanford/stanford.c b/soft/leon3/grlib/mkprom2/testing/sparc-elf/stanford/stanford.c index 6b2ea936c5..e69e179caf 100644 --- a/soft/leon3/grlib/mkprom2/testing/sparc-elf/stanford/stanford.c +++ b/soft/leon3/grlib/mkprom2/testing/sparc-elf/stanford/stanford.c @@ -8,99 +8,95 @@ that. I imagine they will include espresso, gcc, and other large, but public domain programs, for real things. here's bench.c - John Hennessy + John Hennessy */ - /* This is a suite of benchmarks that are relatively short, both in program size and execution time. It requires no input, and prints the execution time for each program, using the system- dependent routine Getclock, below, to find out the current CPU time. It does a rudimentary check to make sure each program gets the right output. These programs were - gathered by John Hennessy and modified by Peter Nye. + gathered by John Hennessy and modified by Peter Nye. 4.2 VERSION */ -#include #include -#include +#include #include +#include -#define nil 0 -#define false 0 -#define true 1 -#define bubblebase 1.61 -#define dnfbase 3.5 -#define permbase 1.75 -#define queensbase 1.83 -#define towersbase 2.39 -#define quickbase 1.92 -#define intmmbase 1.46 -#define treebase 2.5 -#define mmbase 0.0 -#define fpmmbase 2.92 -#define puzzlebase 0.5 -#define fftbase 0.0 -#define fpfftbase 4.44 - /* Towers */ -#define maxcells 18 - - /* Intmm, Mm */ -#define rowsize 40 - - /* Puzzle */ -#define size 511 -#define classmax 3 -#define typemax 12 -#define d 8 - - /* Bubble, Quick */ -#define sortelements 5000 -#define srtelements 500 - - /* fft */ -#define fftsize 256 -#define fftsize2 129 +#define nil 0 +#define false 0 +#define true 1 +#define bubblebase 1.61 +#define dnfbase 3.5 +#define permbase 1.75 +#define queensbase 1.83 +#define towersbase 2.39 +#define quickbase 1.92 +#define intmmbase 1.46 +#define treebase 2.5 +#define mmbase 0.0 +#define fpmmbase 2.92 +#define puzzlebase 0.5 +#define fftbase 0.0 +#define fpfftbase 4.44 +/* Towers */ +#define maxcells 18 + +/* Intmm, Mm */ +#define rowsize 40 + +/* Puzzle */ +#define size 511 +#define classmax 3 +#define typemax 12 +#define d 8 + +/* Bubble, Quick */ +#define sortelements 5000 +#define srtelements 500 + +/* fft */ +#define fftsize 256 +#define fftsize2 129 /* type */ - /* Perm */ -#define permrange 10 +/* Perm */ +#define permrange 10 - /* tree */ -struct node -{ +/* tree */ +struct node { struct node *left, *right; int val; }; -/* Towers *//* - discsizrange = 1..maxcells; */ -#define stackrange 3 +/* Towers */ /* + discsizrange = 1..maxcells; */ +#define stackrange 3 /* cellcursor = 0..maxcells; */ -struct element -{ +struct element { int discsize; int next; }; /* emsgtype = packed array[1..15] of char; -*/ -/* Intmm, Mm *//* - index = 1 .. rowsize; - intmatrix = array [index,index] of integer; - realmatrix = array [index,index] of real; - */ -/* Puzzle *//* - piececlass = 0..classmax; - piecetype = 0..typemax; - position = 0..size; - */ -/* Bubble, Quick *//* - listsize = 0..sortelements; - sortarray = array [listsize] of integer; */ - /* FFT */ -struct complex -{ +/* Intmm, Mm */ /* + index = 1 .. rowsize; + intmatrix = array [index,index] of integer; + realmatrix = array [index,index] of real; + */ +/* Puzzle */ /* + piececlass = 0..classmax; + piecetype = 0..typemax; + position = 0..size; + */ +/* Bubble, Quick */ /* + listsize = 0..sortelements; + sortarray = array [listsize] of integer; + */ +/* FFT */ +struct complex { float rp, ip; }; /* @@ -111,741 +107,631 @@ struct complex float value; float fixed, floated; - /* global */ +/* global */ int timer; int xtimes[11]; int seed; - /* Perm */ +/* Perm */ int permarray[permrange + 1]; int pctr; - /* tree */ +/* tree */ struct node *tree; - /* Towers */ +/* Towers */ int stack[stackrange + 1]; struct element cellspace[maxcells + 1]; int freelist, movesdone; - /* Intmm, Mm */ -int ima[rowsize + 1][rowsize + 1], imb[rowsize + 1][rowsize + 1], - imr[rowsize + 1][rowsize + 1]; -float rma[rowsize + 1][rowsize + 1], rmb[rowsize + 1][rowsize + 1], - rmr[rowsize + 1][rowsize + 1]; +/* Intmm, Mm */ +int ima[rowsize + 1][rowsize + 1], imb[rowsize + 1][rowsize + 1], imr[rowsize + 1][rowsize + 1]; +float rma[rowsize + 1][rowsize + 1], rmb[rowsize + 1][rowsize + 1], rmr[rowsize + 1][rowsize + 1]; - /* Puzzle */ -int piececount[classmax + 1], - class[typemax + 1], - piecemax[typemax + 1], - puzzl[size + 1], p[typemax + 1][size + 1], n, kount; +/* Puzzle */ +int piececount[classmax + 1], class[typemax + 1], piecemax[typemax + 1], puzzl[size + 1], + p[typemax + 1][size + 1], n, kount; - /* Bubble, Quick */ +/* Bubble, Quick */ int sortlist[sortelements + 1], biggest, littlest, top; - /* FFT */ +/* FFT */ struct complex z[fftsize + 1], w[fftsize + 1], e[fftsize2 + 1]; float zr, zi; /* global procedures */ -int -Getclock () +int Getclock() { struct tms rusage; - times (&rusage); + times(&rusage); return (rusage.tms_utime * 50 / 3); }; -Initrand () -{ - seed = 74755; -}; +Initrand() { seed = 74755; }; -int -Rand () +int Rand() { seed = (seed * 1309 + 13849) & 65535; return (seed); }; +/* Permutation program, heavily recursive, written by Denny Brown. */ - - /* Permutation program, heavily recursive, written by Denny Brown. */ - -Swap (a, b) - int *a, *b; +Swap(a, b) int *a, *b; { int t; - t = *a; + t = *a; *a = *b; *b = t; }; -Initialize () +Initialize() { int i; - for (i = 1; i <= 7; i++) - { - permarray[i] = i - 1; - }; + for (i = 1; i <= 7; i++) { + permarray[i] = i - 1; + }; }; -Permute (n) - int n; -{ /* permute */ +Permute(n) int n; +{ /* permute */ int k; pctr = pctr + 1; - if (n != 1) - { - Permute (n - 1); - for (k = n - 1; k >= 1; k--) - { - Swap (&permarray[n], &permarray[k]); - Permute (n - 1); - Swap (&permarray[n], &permarray[k]); - }; - }; -} /* permute */ ; - -Perm () -{ /* Perm */ + if (n != 1) { + Permute(n - 1); + for (k = n - 1; k >= 1; k--) { + Swap(&permarray[n], &permarray[k]); + Permute(n - 1); + Swap(&permarray[n], &permarray[k]); + }; + }; +} /* permute */; + +Perm() +{ /* Perm */ int i; pctr = 0; - for (i = 1; i <= 5; i++) - { - Initialize (); - Permute (7); - }; - if (pctr != 43300) - printf (" Error in Perm.\n"); -} /* Perm */ ; - + for (i = 1; i <= 5; i++) { + Initialize(); + Permute(7); + }; + if (pctr != 43300) printf(" Error in Perm.\n"); +} /* Perm */; +/* Program to Solve the Towers of Hanoi */ - /* Program to Solve the Towers of Hanoi */ - -Error (emsg) - char *emsg; +Error(emsg) char *emsg; { - printf (" Error in Towers: %s\n", emsg); + printf(" Error in Towers: %s\n", emsg); }; -Makenull (s) -{ - stack[s] = 0; -}; +Makenull(s) { stack[s] = 0; }; -int -Getelement () +int Getelement() { int temp; - if (freelist > 0) - { - temp = freelist; - freelist = cellspace[freelist].next; - } + if (freelist > 0) { + temp = freelist; + freelist = cellspace[freelist].next; + } else - Error ("out of space "); + Error("out of space "); return (temp); }; -Push (i, s) - int i, s; +Push(i, s) int i, s; { int errorfound, localel; errorfound = false; if (stack[s] > 0) - if (cellspace[stack[s]].discsize <= i) - { - errorfound = true; - Error ("disc size error"); - }; - if (!errorfound) - { - localel = Getelement (); - cellspace[localel].next = stack[s]; - stack[s] = localel; - cellspace[localel].discsize = i; - } + if (cellspace[stack[s]].discsize <= i) { + errorfound = true; + Error("disc size error"); + }; + if (!errorfound) { + localel = Getelement(); + cellspace[localel].next = stack[s]; + stack[s] = localel; + cellspace[localel].discsize = i; + } }; -Init (s, n) - int s, n; +Init(s, n) int s, n; { int discctr; - Makenull (s); + Makenull(s); for (discctr = n; discctr >= 1; discctr--) - Push (discctr, s); + Push(discctr, s); }; -int -Pop (s) - int s; +int Pop(s) int s; { int temp, temp1; - if (stack[s] > 0) - { - temp1 = cellspace[stack[s]].discsize; - temp = cellspace[stack[s]].next; - cellspace[stack[s]].next = freelist; - freelist = stack[s]; - stack[s] = temp; - return (temp1); - } + if (stack[s] > 0) { + temp1 = cellspace[stack[s]].discsize; + temp = cellspace[stack[s]].next; + cellspace[stack[s]].next = freelist; + freelist = stack[s]; + stack[s] = temp; + return (temp1); + } else - Error ("nothing to pop "); + Error("nothing to pop "); }; -Move (s1, s2) - int s1, s2; +Move(s1, s2) int s1, s2; { - Push (Pop (s1), s2); + Push(Pop(s1), s2); movesdone = movesdone + 1; }; -tower (i, j, k) - int i, j, k; +tower(i, j, k) int i, j, k; { int other; - if (k == 1) - Move (i, j); - else - { - other = 6 - i - j; - tower (i, other, k - 1); - Move (i, j); - tower (other, j, k - 1); - } + if (k == 1) Move(i, j); + else { + other = 6 - i - j; + tower(i, other, k - 1); + Move(i, j); + tower(other, j, k - 1); + } }; - -Towers () -{ /* Towers */ +Towers() +{ /* Towers */ int i; for (i = 1; i <= maxcells; i++) - cellspace[i].next = i - 1; + cellspace[i].next = i - 1; freelist = maxcells; - Init (1, 14); - Makenull (2); - Makenull (3); + Init(1, 14); + Makenull(2); + Makenull(3); movesdone = 0; - tower (1, 2, 14); - if (movesdone != 16383) - printf (" Error in Towers.\n"); -}; /* Towers */ + tower(1, 2, 14); + if (movesdone != 16383) printf(" Error in Towers.\n"); +}; /* Towers */ - - /* The eight queens problem, solved 50 times. */ +/* The eight queens problem, solved 50 times. */ /* - type - doubleboard = 2..16; - doublenorm = -7..7; - boardrange = 1..8; - aarray = array [boardrange] of boolean; - barray = array [doubleboard] of boolean; - carray = array [doublenorm] of boolean; - xarray = array [boardrange] of boardrange; + type + doubleboard = 2..16; + doublenorm = -7..7; + boardrange = 1..8; + aarray = array [boardrange] of boolean; + barray = array [doubleboard] of boolean; + carray = array [doublenorm] of boolean; + xarray = array [boardrange] of boardrange; */ -Try (i, q, a, b, c, x) - int i, *q, a[], b[], c[], x[]; +Try(i, q, a, b, c, x) int i, *q, a[], b[], c[], x[]; { int j; - j = 0; + j = 0; *q = false; - while ((!*q) && (j != 8)) - { - j = j + 1; - *q = false; - if (b[j] && a[i + j] && c[i - j + 7]) - { - x[i] = j; - b[j] = false; - a[i + j] = false; - c[i - j + 7] = false; - if (i < 8) - { - Try (i + 1, q, a, b, c, x); - if (!*q) - { - b[j] = true; - a[i + j] = true; - c[i - j + 7] = true; - } - } - else - *q = true; - } - } -}; - -Doit () + while ((!*q) && (j != 8)) { + j = j + 1; + *q = false; + if (b[j] && a[i + j] && c[i - j + 7]) { + x[i] = j; + b[j] = false; + a[i + j] = false; + c[i - j + 7] = false; + if (i < 8) { + Try(i + 1, q, a, b, c, x); + if (!*q) { + b[j] = true; + a[i + j] = true; + c[i - j + 7] = true; + } + } + else + *q = true; + } + } +}; + +Doit() { int i, q; int a[9], b[17], c[15], x[9]; i = 0 - 7; - while (i <= 16) - { - if ((i >= 1) && (i <= 8)) - a[i] = true; - if (i >= 2) - b[i] = true; - if (i <= 7) - c[i + 7] = true; - i = i + 1; - }; - - Try (1, &q, b, a, c, x); - if (!q) - printf (" Error in Queens.\n"); + while (i <= 16) { + if ((i >= 1) && (i <= 8)) a[i] = true; + if (i >= 2) b[i] = true; + if (i <= 7) c[i + 7] = true; + i = i + 1; + }; + + Try(1, &q, b, a, c, x); + if (!q) printf(" Error in Queens.\n"); }; -Queens () +Queens() { int i; for (i = 1; i <= 50; i++) - Doit (); + Doit(); }; - /* Multiplies two integer matrices. */ +/* Multiplies two integer matrices. */ -Initmatrix (m) - int m[rowsize + 1][rowsize + 1]; +Initmatrix(m) int m[rowsize + 1][rowsize + 1]; { int temp, i, j; for (i = 1; i <= rowsize; i++) - for (j = 1; j <= rowsize; j++) - { - temp = Rand (); - m[i][j] = temp - (temp / 120) * 120 - 60; - } + for (j = 1; j <= rowsize; j++) { + temp = Rand(); + m[i][j] = temp - (temp / 120) * 120 - 60; + } }; -Innerproduct (result, a, b, row, column) - int *result, a[rowsize + 1][rowsize + 1], b[rowsize + 1][rowsize + 1], - row, column; - /* computes the inner product of A[row,*] and B[*,column] */ +Innerproduct(result, a, b, row, column) int *result, a[rowsize + 1][rowsize + 1], + b[rowsize + 1][rowsize + 1], row, column; +/* computes the inner product of A[row,*] and B[*,column] */ { int i; *result = 0; for (i = 1; i <= rowsize; i++) - *result = *result + a[row][i] * b[i][column]; + *result = *result + a[row][i] * b[i][column]; }; -Intmm () +Intmm() { int i, j; - Initrand (); - Initmatrix (ima); - Initmatrix (imb); + Initrand(); + Initmatrix(ima); + Initmatrix(imb); for (i = 1; i <= rowsize; i++) - for (j = 1; j <= rowsize; j++) - Innerproduct (&imr[i][j], ima, imb, i, j); + for (j = 1; j <= rowsize; j++) + Innerproduct(&imr[i][j], ima, imb, i, j); }; +/* Multiplies two real matrices. */ - /* Multiplies two real matrices. */ - -rInitmatrix (m) - float m[rowsize + 1][rowsize + 1]; +rInitmatrix(m) float m[rowsize + 1][rowsize + 1]; { int temp, i, j; for (i = 1; i <= rowsize; i++) - for (j = 1; j <= rowsize; j++) - { - temp = Rand (); - m[i][j] = (temp - (temp / 120) * 120 - 60) / 3; - } + for (j = 1; j <= rowsize; j++) { + temp = Rand(); + m[i][j] = (temp - (temp / 120) * 120 - 60) / 3; + } }; -rInnerproduct (result, a, b, row, column) - float *result, a[rowsize + 1][rowsize + 1], b[rowsize + 1][rowsize + 1]; - int row, column; - /* computes the inner product of A[row,*] and B[*,column] */ +rInnerproduct(result, a, b, row, column) float *result, a[rowsize + 1][rowsize + 1], + b[rowsize + 1][rowsize + 1]; +int row, column; +/* computes the inner product of A[row,*] and B[*,column] */ { int i; *result = 0.0; for (i = 1; i <= rowsize; i++) - *result = *result + a[row][i] * b[i][column]; + *result = *result + a[row][i] * b[i][column]; }; -Mm () +Mm() { int i, j; - Initrand (); - rInitmatrix (rma); - rInitmatrix (rmb); + Initrand(); + rInitmatrix(rma); + rInitmatrix(rmb); for (i = 1; i <= rowsize; i++) - for (j = 1; j <= rowsize; j++) - rInnerproduct (&rmr[i][j], rma, rmb, i, j); + for (j = 1; j <= rowsize; j++) + rInnerproduct(&rmr[i][j], rma, rmb, i, j); }; +/* A compute-bound program from Forest Baskett. */ - - - /* A compute-bound program from Forest Baskett. */ - -int -Fit (i, j) - int i, j; +int Fit(i, j) int i, j; { int k; for (k = 0; k <= piecemax[i]; k++) - if (p[i][k]) - if (puzzl[j + k]) - return (false); + if (p[i][k]) + if (puzzl[j + k]) return (false); return (true); }; -int -Place (i, j) - int i, j; +int Place(i, j) int i, j; { int k; for (k = 0; k <= piecemax[i]; k++) - if (p[i][k]) - puzzl[j + k] = true; + if (p[i][k]) puzzl[j + k] = true; piececount[class[i]] = piececount[class[i]] - 1; for (k = j; k <= size; k++) - if (!puzzl[k]) - { - return (k); - }; + if (!puzzl[k]) { return (k); }; return (0); }; -Remove (i, j) - int i, j; +Remove(i, j) int i, j; { int k; for (k = 0; k <= piecemax[i]; k++) - if (p[i][k]) - puzzl[j + k] = false; + if (p[i][k]) puzzl[j + k] = false; piececount[class[i]] = piececount[class[i]] + 1; }; -int -Trial (j) - int j; +int Trial(j) int j; { int i, k; kount = kount + 1; for (i = 0; i <= typemax; i++) - if (piececount[class[i]] != 0) - if (Fit (i, j)) - { - k = Place (i, j); - if (Trial (k) || (k == 0)) - { - return (true); - } - else - Remove (i, j); - }; + if (piececount[class[i]] != 0) + if (Fit(i, j)) { + k = Place(i, j); + if (Trial(k) || (k == 0)) { return (true); } + else + Remove(i, j); + }; return (false); }; -Puzzle () +Puzzle() { int i, j, k, m; for (m = 0; m <= size; m++) - puzzl[m] = true; + puzzl[m] = true; for (i = 1; i <= 5; i++) - for (j = 1; j <= 5; j++) - for (k = 1; k <= 5; k++) - puzzl[i + d * (j + d * k)] = false; + for (j = 1; j <= 5; j++) + for (k = 1; k <= 5; k++) + puzzl[i + d * (j + d * k)] = false; for (i = 0; i <= typemax; i++) - for (m = 0; m <= size; m++) - p[i][m] = false; + for (m = 0; m <= size; m++) + p[i][m] = false; for (i = 0; i <= 3; i++) - for (j = 0; j <= 1; j++) - for (k = 0; k <= 0; k++) - p[0][i + d * (j + d * k)] = true; - class[0] = 0; + for (j = 0; j <= 1; j++) + for (k = 0; k <= 0; k++) + p[0][i + d * (j + d * k)] = true; + class[0] = 0; piecemax[0] = 3 + d * 1 + d * d * 0; for (i = 0; i <= 1; i++) - for (j = 0; j <= 0; j++) - for (k = 0; k <= 3; k++) - p[1][i + d * (j + d * k)] = true; - class[1] = 0; + for (j = 0; j <= 0; j++) + for (k = 0; k <= 3; k++) + p[1][i + d * (j + d * k)] = true; + class[1] = 0; piecemax[1] = 1 + d * 0 + d * d * 3; for (i = 0; i <= 0; i++) - for (j = 0; j <= 3; j++) - for (k = 0; k <= 1; k++) - p[2][i + d * (j + d * k)] = true; - class[2] = 0; + for (j = 0; j <= 3; j++) + for (k = 0; k <= 1; k++) + p[2][i + d * (j + d * k)] = true; + class[2] = 0; piecemax[2] = 0 + d * 3 + d * d * 1; for (i = 0; i <= 1; i++) - for (j = 0; j <= 3; j++) - for (k = 0; k <= 0; k++) - p[3][i + d * (j + d * k)] = true; - class[3] = 0; + for (j = 0; j <= 3; j++) + for (k = 0; k <= 0; k++) + p[3][i + d * (j + d * k)] = true; + class[3] = 0; piecemax[3] = 1 + d * 3 + d * d * 0; for (i = 0; i <= 3; i++) - for (j = 0; j <= 0; j++) - for (k = 0; k <= 1; k++) - p[4][i + d * (j + d * k)] = true; - class[4] = 0; + for (j = 0; j <= 0; j++) + for (k = 0; k <= 1; k++) + p[4][i + d * (j + d * k)] = true; + class[4] = 0; piecemax[4] = 3 + d * 0 + d * d * 1; for (i = 0; i <= 0; i++) - for (j = 0; j <= 1; j++) - for (k = 0; k <= 3; k++) - p[5][i + d * (j + d * k)] = true; - class[5] = 0; + for (j = 0; j <= 1; j++) + for (k = 0; k <= 3; k++) + p[5][i + d * (j + d * k)] = true; + class[5] = 0; piecemax[5] = 0 + d * 1 + d * d * 3; for (i = 0; i <= 2; i++) - for (j = 0; j <= 0; j++) - for (k = 0; k <= 0; k++) - p[6][i + d * (j + d * k)] = true; - class[6] = 1; + for (j = 0; j <= 0; j++) + for (k = 0; k <= 0; k++) + p[6][i + d * (j + d * k)] = true; + class[6] = 1; piecemax[6] = 2 + d * 0 + d * d * 0; for (i = 0; i <= 0; i++) - for (j = 0; j <= 2; j++) - for (k = 0; k <= 0; k++) - p[7][i + d * (j + d * k)] = true; - class[7] = 1; + for (j = 0; j <= 2; j++) + for (k = 0; k <= 0; k++) + p[7][i + d * (j + d * k)] = true; + class[7] = 1; piecemax[7] = 0 + d * 2 + d * d * 0; for (i = 0; i <= 0; i++) - for (j = 0; j <= 0; j++) - for (k = 0; k <= 2; k++) - p[8][i + d * (j + d * k)] = true; - class[8] = 1; + for (j = 0; j <= 0; j++) + for (k = 0; k <= 2; k++) + p[8][i + d * (j + d * k)] = true; + class[8] = 1; piecemax[8] = 0 + d * 0 + d * d * 2; for (i = 0; i <= 1; i++) - for (j = 0; j <= 1; j++) - for (k = 0; k <= 0; k++) - p[9][i + d * (j + d * k)] = true; - class[9] = 2; + for (j = 0; j <= 1; j++) + for (k = 0; k <= 0; k++) + p[9][i + d * (j + d * k)] = true; + class[9] = 2; piecemax[9] = 1 + d * 1 + d * d * 0; for (i = 0; i <= 1; i++) - for (j = 0; j <= 0; j++) - for (k = 0; k <= 1; k++) - p[10][i + d * (j + d * k)] = true; - class[10] = 2; + for (j = 0; j <= 0; j++) + for (k = 0; k <= 1; k++) + p[10][i + d * (j + d * k)] = true; + class[10] = 2; piecemax[10] = 1 + d * 0 + d * d * 1; for (i = 0; i <= 0; i++) - for (j = 0; j <= 1; j++) - for (k = 0; k <= 1; k++) - p[11][i + d * (j + d * k)] = true; - class[11] = 2; + for (j = 0; j <= 1; j++) + for (k = 0; k <= 1; k++) + p[11][i + d * (j + d * k)] = true; + class[11] = 2; piecemax[11] = 0 + d * 1 + d * d * 1; for (i = 0; i <= 1; i++) - for (j = 0; j <= 1; j++) - for (k = 0; k <= 1; k++) - p[12][i + d * (j + d * k)] = true; - class[12] = 3; - piecemax[12] = 1 + d * 1 + d * d * 1; + for (j = 0; j <= 1; j++) + for (k = 0; k <= 1; k++) + p[12][i + d * (j + d * k)] = true; + class[12] = 3; + piecemax[12] = 1 + d * 1 + d * d * 1; piececount[0] = 13; piececount[1] = 3; piececount[2] = 1; piececount[3] = 1; - m = 1 + d * (1 + d * 1); - kount = 0; - if (Fit (0, m)) - n = Place (0, m); + m = 1 + d * (1 + d * 1); + kount = 0; + if (Fit(0, m)) n = Place(0, m); else - printf ("Error1 in Puzzle\n"); - if (!Trial (n)) - printf ("Error2 in Puzzle.\n"); + printf("Error1 in Puzzle\n"); + if (!Trial(n)) printf("Error2 in Puzzle.\n"); else if (kount != 2005) - printf ("Error3 in Puzzle.\n"); + printf("Error3 in Puzzle.\n"); }; +/* Sorts an array using quicksort */ - - /* Sorts an array using quicksort */ - -Initarr () +Initarr() { int i, temp; - Initrand (); - biggest = 0; + Initrand(); + biggest = 0; littlest = 0; - for (i = 1; i <= sortelements; i++) - { - temp = Rand (); - sortlist[i] = temp - (temp / 100000) * 100000 - 50000; - if (sortlist[i] > biggest) - biggest = sortlist[i]; - else if (sortlist[i] < littlest) - littlest = sortlist[i]; - }; + for (i = 1; i <= sortelements; i++) { + temp = Rand(); + sortlist[i] = temp - (temp / 100000) * 100000 - 50000; + if (sortlist[i] > biggest) biggest = sortlist[i]; + else if (sortlist[i] < littlest) + littlest = sortlist[i]; + }; }; -Quicksort (a, l, r) - int a[], l, r; - /* quicksort the array A from start to finish */ +Quicksort(a, l, r) int a[], l, r; +/* quicksort the array A from start to finish */ { int i, j, x, w; i = l; j = r; x = a[(l + r) / 2]; - do - { - while (a[i] < x) - i = i + 1; - while (x < a[j]) - j = j - 1; - if (i <= j) - { - w = a[i]; - a[i] = a[j]; - a[j] = w; - i = i + 1; - j = j - 1; - } - } - while (i <= j); - if (l < j) - Quicksort (a, l, j); - if (i < r) - Quicksort (a, i, r); -}; - - -Quick () -{ - Initarr (); - Quicksort (sortlist, 1, sortelements); + do { + while (a[i] < x) + i = i + 1; + while (x < a[j]) + j = j - 1; + if (i <= j) { + w = a[i]; + a[i] = a[j]; + a[j] = w; + i = i + 1; + j = j - 1; + } + } while (i <= j); + if (l < j) Quicksort(a, l, j); + if (i < r) Quicksort(a, i, r); +}; + +Quick() +{ + Initarr(); + Quicksort(sortlist, 1, sortelements); if ((sortlist[1] != littlest) || (sortlist[sortelements] != biggest)) - printf (" Error in Quick.\n"); + printf(" Error in Quick.\n"); }; +/* Sorts an array using treesort */ - /* Sorts an array using treesort */ - -tInitarr () +tInitarr() { int i, temp; - Initrand (); - biggest = 0; + Initrand(); + biggest = 0; littlest = 0; - for (i = 1; i <= sortelements; i++) - { - temp = Rand (); - sortlist[i] = temp - (temp / 100000) * 100000 - 50000; - if (sortlist[i] > biggest) - biggest = sortlist[i]; - else if (sortlist[i] < littlest) - littlest = sortlist[i]; - }; + for (i = 1; i <= sortelements; i++) { + temp = Rand(); + sortlist[i] = temp - (temp / 100000) * 100000 - 50000; + if (sortlist[i] > biggest) biggest = sortlist[i]; + else if (sortlist[i] < littlest) + littlest = sortlist[i]; + }; }; -CreateNode (t, n) - struct node **t; - int n; +CreateNode(t, n) struct node **t; +int n; { - *t = (struct node *) malloc (sizeof (struct node)); - (*t)->left = nil; + *t = (struct node *)malloc(sizeof(struct node)); + (*t)->left = nil; (*t)->right = nil; - (*t)->val = n; + (*t)->val = n; }; -Insert (n, t) - int n; - struct node *t; - /* insert n into tree */ +Insert(n, t) int n; +struct node *t; +/* insert n into tree */ { if (n > t->val) - if (t->left == nil) - CreateNode (&t->left, n); - else - Insert (n, t->left); + if (t->left == nil) CreateNode(&t->left, n); + else + Insert(n, t->left); else if (n < t->val) - if (t->right == nil) - CreateNode (&t->right, n); - else - Insert (n, t->right); + if (t->right == nil) CreateNode(&t->right, n); + else + Insert(n, t->right); }; -int -Checktree (p) - struct node *p; - /* check by inorder traversal */ +int Checktree(p) struct node *p; +/* check by inorder traversal */ { int result; result = true; if (p->left != nil) - if (p->left->val <= p->val) - result = false; - else - result = Checktree (p->left) && result; + if (p->left->val <= p->val) result = false; + else + result = Checktree(p->left) && result; if (p->right != nil) - if (p->right->val >= p->val) - result = false; - else - result = Checktree (p->right) && result; + if (p->right->val >= p->val) result = false; + else + result = Checktree(p->right) && result; return (result); -}; /* checktree */ +}; /* checktree */ -Trees () +Trees() { int i; - tInitarr (); - tree = (struct node *) malloc (sizeof (struct node)); - tree->left = nil; + tInitarr(); + tree = (struct node *)malloc(sizeof(struct node)); + tree->left = nil; tree->right = nil; - tree->val = sortlist[1]; + tree->val = sortlist[1]; for (i = 2; i <= sortelements; i++) - Insert (sortlist[i], tree); - if (!Checktree (tree)) - printf (" Error in Tree.\n"); + Insert(sortlist[i], tree); + if (!Checktree(tree)) printf(" Error in Tree.\n"); }; +/* Sorts an array using bubblesort */ - /* Sorts an array using bubblesort */ - -bInitarr () +bInitarr() { int i, temp; - Initrand (); - biggest = 0; + Initrand(); + biggest = 0; littlest = 0; - for (i = 1; i <= srtelements; i++) - { - temp = Rand (); - sortlist[i] = temp - (temp / 100000) * 100000 - 50000; - if (sortlist[i] > biggest) - biggest = sortlist[i]; - else if (sortlist[i] < littlest) - littlest = sortlist[i]; - }; + for (i = 1; i <= srtelements; i++) { + temp = Rand(); + sortlist[i] = temp - (temp / 100000) * 100000 - 50000; + if (sortlist[i] > biggest) biggest = sortlist[i]; + else if (sortlist[i] < littlest) + littlest = sortlist[i]; + }; }; -Bubble () +Bubble() { int i, j; - bInitarr (); + bInitarr(); top = srtelements; - while (top > 1) - { + while (top > 1) { - i = 1; - while (i < top) - { + i = 1; + while (i < top) { - if (sortlist[i] > sortlist[i + 1]) - { - j = sortlist[i]; - sortlist[i] = sortlist[i + 1]; - sortlist[i + 1] = j; - }; - i = i + 1; - }; + if (sortlist[i] > sortlist[i + 1]) { + j = sortlist[i]; + sortlist[i] = sortlist[i + 1]; + sortlist[i + 1] = j; + }; + i = i + 1; + }; - top = top - 1; - }; + top = top - 1; + }; if ((sortlist[1] != littlest) || (sortlist[srtelements] != biggest)) - printf ("Error3 in Bubble.\n"); + printf("Error3 in Bubble.\n"); }; - -float -Cos (x) - float x; +float Cos(x) float x; /* computes cos of x (x in radians) by an expansion */ { int i, factor; @@ -853,256 +739,225 @@ Cos (x) result = 1.0; factor = 1; - power = x; - for (i = 2; i <= 10; i++) - { - factor = factor * i; - power = power * x; - if ((i & 1) == 0) - { - if ((i & 3) == 0) - result = result + power / factor; - else - result = result - power / factor; - }; - }; + power = x; + for (i = 2; i <= 10; i++) { + factor = factor * i; + power = power * x; + if ((i & 1) == 0) { + if ((i & 3) == 0) result = result + power / factor; + else + result = result - power / factor; + }; + }; return (result); }; -int -Min0 (arg1, arg2) - int arg1, arg2; +int Min0(arg1, arg2) int arg1, arg2; { - if (arg1 < arg2) - return (arg1); + if (arg1 < arg2) return (arg1); else - return (arg2); + return (arg2); }; -Printcomplex (arg1, arg2, zarray, start, finish, increment) - int arg1, arg2, start, finish, increment; - struct complex zarray[]; +Printcomplex(arg1, arg2, zarray, start, finish, increment) int arg1, arg2, start, finish, increment; +struct complex zarray[]; { int i; - printf ("\n"); + printf("\n"); i = start; - do - { - printf (" %15.3e%15.3e", zarray[i].rp, zarray[i].ip); - i = i + increment; - printf (" %15.3e%15.3e", zarray[i].rp, zarray[i].ip); - printf ("\n"); - i = i + increment; - } - while (i <= finish); - + do { + printf(" %15.3e%15.3e", zarray[i].rp, zarray[i].ip); + i = i + increment; + printf(" %15.3e%15.3e", zarray[i].rp, zarray[i].ip); + printf("\n"); + i = i + increment; + } while (i <= finish); }; -Uniform11 (iy, yfl) - int iy; - float yfl; +Uniform11(iy, yfl) int iy; +float yfl; { - iy = (4855 * iy + 1731) & 8191; + iy = (4855 * iy + 1731) & 8191; yfl = iy / 8192.0; -} /* uniform */ ; +} /* uniform */; -Exptab (n, e) - int n; - struct complex e[]; +Exptab(n, e) int n; +struct complex e[]; -{ /* exptab */ +{ /* exptab */ float theta, divisor, h[26]; int i, j, k, l, m; - theta = 3.1415926536; + theta = 3.1415926536; divisor = 4.0; - for (i = 1; i <= 25; i++) - { - h[i] = 1 / (2 * Cos (theta / divisor)); - divisor = divisor + divisor; - }; - - m = n / 2; - l = m / 2; - j = 1; - e[1].rp = 1.0; - e[1].ip = 0.0; + for (i = 1; i <= 25; i++) { + h[i] = 1 / (2 * Cos(theta / divisor)); + divisor = divisor + divisor; + }; + + m = n / 2; + l = m / 2; + j = 1; + e[1].rp = 1.0; + e[1].ip = 0.0; e[l + 1].rp = 0.0; e[l + 1].ip = 1.0; e[m + 1].rp = -1.0; e[m + 1].ip = 0.0; - do - { - i = l / 2; - k = i; - - do - { - e[k + 1].rp = h[j] * (e[k + i + 1].rp + e[k - i + 1].rp); - e[k + 1].ip = h[j] * (e[k + i + 1].ip + e[k - i + 1].ip); - k = k + l; - } - while (k <= m); - - j = Min0 (j + 1, 25); - l = i; - } - while (l > 1); - -} /* exptab */ ; - -Fft (n, z, w, e, sqrinv) - int n; - struct complex z[], w[]; - struct complex e[]; - float sqrinv; + do { + i = l / 2; + k = i; + + do { + e[k + 1].rp = h[j] * (e[k + i + 1].rp + e[k - i + 1].rp); + e[k + 1].ip = h[j] * (e[k + i + 1].ip + e[k - i + 1].ip); + k = k + l; + } while (k <= m); + + j = Min0(j + 1, 25); + l = i; + } while (l > 1); + +} /* exptab */; + +Fft(n, z, w, e, sqrinv) int n; +struct complex z[], w[]; +struct complex e[]; +float sqrinv; { int i, j, k, l, m, index; m = n / 2; l = 1; - do - { - k = 0; - j = l; - i = 1; - - do - { - - do - { - w[i + k].rp = z[i].rp + z[m + i].rp; - w[i + k].ip = z[i].ip + z[m + i].ip; - w[i + j].rp = e[k + 1].rp * (z[i].rp - z[i + m].rp) - - e[k + 1].ip * (z[i].ip - z[i + m].ip); - w[i + j].ip = e[k + 1].rp * (z[i].ip - z[i + m].ip) - + e[k + 1].ip * (z[i].rp - z[i + m].rp); - i = i + 1; - } - while (i <= j); - - k = j; - j = k + l; - } - while (j <= m); - - /*z = w ; */ index = 1; - do - { - z[index] = w[index]; - index = index + 1; - } - while (index <= n); - l = l + l; - } - while (l <= m); - - for (i = 1; i <= n; i++) - { - z[i].rp = sqrinv * z[i].rp; - z[i].ip = -sqrinv * z[i].ip; - }; - -}; - -Oscar () -{ /* oscar */ + do { + k = 0; + j = l; + i = 1; + + do { + + do { + w[i + k].rp = z[i].rp + z[m + i].rp; + w[i + k].ip = z[i].ip + z[m + i].ip; + w[i + j].rp = + e[k + 1].rp * (z[i].rp - z[i + m].rp) - e[k + 1].ip * (z[i].ip - z[i + m].ip); + w[i + j].ip = + e[k + 1].rp * (z[i].ip - z[i + m].ip) + e[k + 1].ip * (z[i].rp - z[i + m].rp); + i = i + 1; + } while (i <= j); + + k = j; + j = k + l; + } while (j <= m); + + /*z = w ; */ index = 1; + do { + z[index] = w[index]; + index = index + 1; + } while (index <= n); + l = l + l; + } while (l <= m); + + for (i = 1; i <= n; i++) { + z[i].rp = sqrinv * z[i].rp; + z[i].ip = -sqrinv * z[i].ip; + }; +}; + +Oscar() +{ /* oscar */ int i; - Exptab (fftsize, e); + Exptab(fftsize, e); seed = 5767; - for (i = 1; i <= fftsize; i++) - { - Uniform11 (seed, zr); - Uniform11 (seed, zi); - z[i].rp = 20.0 * zr - 10.0; - z[i].ip = 20.0 * zi - 10.0; - }; - - - for (i = 1; i <= 20; i++) - { - Fft (fftsize, z, w, e, 0.0625); - /* Printcomplex( 6, 99, z, 1, 256, 17 ); */ - }; -} /* oscar */ ; - -main () + for (i = 1; i <= fftsize; i++) { + Uniform11(seed, zr); + Uniform11(seed, zi); + z[i].rp = 20.0 * zr - 10.0; + z[i].ip = 20.0 * zi - 10.0; + }; + + for (i = 1; i <= 20; i++) { + Fft(fftsize, z, w, e, 0.0625); + /* Printcomplex( 6, 99, z, 1, 256, 17 ); */ + }; +} /* oscar */; + +main() { int i; - fixed = 0.0; + fixed = 0.0; floated = 0.0; - printf ("Starting \n"); -/* rewrite (output); */ - printf (" Perm"); - timer = Getclock (); - Perm (); - xtimes[1] = Getclock () - timer; - fixed = fixed + permbase * xtimes[1]; - floated = floated + permbase * xtimes[1]; - printf (" Towers"); - timer = Getclock (); - Towers (); - xtimes[2] = Getclock () - timer; - fixed = fixed + towersbase * xtimes[2]; - floated = floated + towersbase * xtimes[2]; - printf (" Queens"); - timer = Getclock (); - Queens (); - xtimes[3] = Getclock () - timer; - fixed = fixed + queensbase * xtimes[3]; - floated = floated + queensbase * xtimes[3]; - printf (" Intmm"); - timer = Getclock (); - Intmm (); - xtimes[4] = Getclock () - timer; - fixed = fixed + intmmbase * xtimes[4]; - floated = floated + intmmbase * xtimes[4]; - printf (" Mm"); - timer = Getclock (); - Mm (); - xtimes[5] = Getclock () - timer; - fixed = fixed + mmbase * xtimes[5]; - floated = floated + fpmmbase * xtimes[5]; - printf (" Puzzle"); - timer = Getclock (); - Puzzle (); - xtimes[6] = Getclock () - timer; - fixed = fixed + puzzlebase * xtimes[6]; - floated = floated + puzzlebase * xtimes[6]; - printf (" Quick"); - timer = Getclock (); - Quick (); - xtimes[7] = Getclock () - timer; - fixed = fixed + quickbase * xtimes[7]; - floated = floated + quickbase * xtimes[7]; - printf (" Bubble"); - timer = Getclock (); - Bubble (); - xtimes[8] = Getclock () - timer; - fixed = fixed + bubblebase * xtimes[8]; - floated = floated + bubblebase * xtimes[8]; - printf (" Tree"); - timer = Getclock (); - Trees (); - xtimes[9] = Getclock () - timer; - fixed = fixed + treebase * xtimes[9]; - floated = floated + treebase * xtimes[9]; - printf (" FFT"); - timer = Getclock (); - Oscar (); - xtimes[10] = Getclock () - timer; - fixed = fixed + fftbase * xtimes[10]; - floated = floated + fpfftbase * xtimes[10]; - printf ("\n"); + printf("Starting \n"); + /* rewrite (output); */ + printf(" Perm"); + timer = Getclock(); + Perm(); + xtimes[1] = Getclock() - timer; + fixed = fixed + permbase * xtimes[1]; + floated = floated + permbase * xtimes[1]; + printf(" Towers"); + timer = Getclock(); + Towers(); + xtimes[2] = Getclock() - timer; + fixed = fixed + towersbase * xtimes[2]; + floated = floated + towersbase * xtimes[2]; + printf(" Queens"); + timer = Getclock(); + Queens(); + xtimes[3] = Getclock() - timer; + fixed = fixed + queensbase * xtimes[3]; + floated = floated + queensbase * xtimes[3]; + printf(" Intmm"); + timer = Getclock(); + Intmm(); + xtimes[4] = Getclock() - timer; + fixed = fixed + intmmbase * xtimes[4]; + floated = floated + intmmbase * xtimes[4]; + printf(" Mm"); + timer = Getclock(); + Mm(); + xtimes[5] = Getclock() - timer; + fixed = fixed + mmbase * xtimes[5]; + floated = floated + fpmmbase * xtimes[5]; + printf(" Puzzle"); + timer = Getclock(); + Puzzle(); + xtimes[6] = Getclock() - timer; + fixed = fixed + puzzlebase * xtimes[6]; + floated = floated + puzzlebase * xtimes[6]; + printf(" Quick"); + timer = Getclock(); + Quick(); + xtimes[7] = Getclock() - timer; + fixed = fixed + quickbase * xtimes[7]; + floated = floated + quickbase * xtimes[7]; + printf(" Bubble"); + timer = Getclock(); + Bubble(); + xtimes[8] = Getclock() - timer; + fixed = fixed + bubblebase * xtimes[8]; + floated = floated + bubblebase * xtimes[8]; + printf(" Tree"); + timer = Getclock(); + Trees(); + xtimes[9] = Getclock() - timer; + fixed = fixed + treebase * xtimes[9]; + floated = floated + treebase * xtimes[9]; + printf(" FFT"); + timer = Getclock(); + Oscar(); + xtimes[10] = Getclock() - timer; + fixed = fixed + fftbase * xtimes[10]; + floated = floated + fpfftbase * xtimes[10]; + printf("\n"); for (i = 1; i <= 10; i++) - printf ("%8d", xtimes[i]); - printf ("\n"); + printf("%8d", xtimes[i]); + printf("\n"); /* compute composites */ - printf ("\n"); - printf ("Nonfloating point composite is %10.0f\n", fixed / 10.0); - printf ("\n"); - printf ("Floating point composite is %10.0f\n", floated / 10.0); + printf("\n"); + printf("Nonfloating point composite is %10.0f\n", fixed / 10.0); + printf("\n"); + printf("Floating point composite is %10.0f\n", floated / 10.0); } diff --git a/soft/leon3/grlib/mkprom2/testing/sparc-rtems/hello/hello.c b/soft/leon3/grlib/mkprom2/testing/sparc-rtems/hello/hello.c index 5ca5269991..20f77c25e9 100644 --- a/soft/leon3/grlib/mkprom2/testing/sparc-rtems/hello/hello.c +++ b/soft/leon3/grlib/mkprom2/testing/sparc-rtems/hello/hello.c @@ -9,27 +9,24 @@ #include /* for device driver prototypes */ -rtems_task Init( rtems_task_argument argument); /* forward declaration needed */ +rtems_task Init(rtems_task_argument argument); /* forward declaration needed */ /* configuration information */ #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER -#define CONFIGURE_MAXIMUM_TASKS 4 +#define CONFIGURE_MAXIMUM_TASKS 4 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE -#define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE) - +#define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE) #include -rtems_task Init( - rtems_task_argument ignored -) +rtems_task Init(rtems_task_argument ignored) { - printf( "Hello World\n" ); - exit( 0 ); + printf("Hello World\n"); + exit(0); } diff --git a/soft/leon3/grlib/software/cantest/can_receive_basic.c b/soft/leon3/grlib/software/cantest/can_receive_basic.c index 0b3d01f995..fa664c819f 100644 --- a/soft/leon3/grlib/software/cantest/can_receive_basic.c +++ b/soft/leon3/grlib/software/cantest/can_receive_basic.c @@ -7,7 +7,7 @@ //-- $Author: hobe $ //-- $Date: 2004/10/12 12:47:19 $ //-- $Revision: 1.2 $ -//-- $State: Exp $ +//-- $State: Exp $ // addressdefinition for basic can registers // tb...transmit buffer @@ -17,808 +17,760 @@ #define CANADDR 0xfffc0000 #ifdef basic -#define control_register *((unsigned char *)(CANADDR+0x0000)) -#define command_register *((unsigned char *)(CANADDR+0x0001)) -#define status_register *((unsigned char *)(CANADDR+0x0002)) -#define interrupt_register *((unsigned char *)(CANADDR+0x0003)) -#define acceptance_code_register *((unsigned char *)(CANADDR+0x0004)) -#define acceptance_mask_register *((unsigned char *)(CANADDR+0x0005)) -#define bus_timing_0_register *((unsigned char *)(CANADDR+0x0006)) -#define bus_timing_1_register *((unsigned char *)(CANADDR+0x0007)) -#define output_control_register *((unsigned char *)(CANADDR+0x0008)) -#define test_register *((unsigned char *)(CANADDR+0x0009)) -#define tb_identifier_byte_0 *((unsigned char *)(CANADDR+0x000A)) -#define tb_identifier_byte_1 *((unsigned char *)(CANADDR+0x000B)) -#define tb_data_byte_1 *((unsigned char *)(CANADDR+0x000C)) -#define tb_data_byte_2 *((unsigned char *)(CANADDR+0x000D)) -#define tb_data_byte_3 *((unsigned char *)(CANADDR+0x000E)) -#define tb_data_byte_4 *((unsigned char *)(CANADDR+0x000F)) -#define tb_data_byte_5 *((unsigned char *)(CANADDR+0x0010)) -#define tb_data_byte_6 *((unsigned char *)(CANADDR+0x0011)) -#define tb_data_byte_7 *((unsigned char *)(CANADDR+0x0012)) -#define tb_data_byte_8 *((unsigned char *)(CANADDR+0x0013)) -#define rb_identifier_byte_0 *((unsigned char *)(CANADDR+0x0014)) -#define rb_identifier_byte_1 *((unsigned char *)(CANADDR+0x0015)) -#define rb_data_byte_1 *((unsigned char *)(CANADDR+0x0016)) -#define rb_data_byte_2 *((unsigned char *)(CANADDR+0x0017)) -#define rb_data_byte_3 *((unsigned char *)(CANADDR+0x0018)) -#define rb_data_byte_4 *((unsigned char *)(CANADDR+0x0019)) -#define rb_data_byte_5 *((unsigned char *)(CANADDR+0x001A)) -#define rb_data_byte_6 *((unsigned char *)(CANADDR+0x001B)) -#define rb_data_byte_7 *((unsigned char *)(CANADDR+0x001C)) -#define rb_data_byte_8 *((unsigned char *)(CANADDR+0x001D)) -#define Extra_register *((unsigned char *)(CANADDR+0x001E)) -#define clock_divider_register *((unsigned char *)(CANADDR+0x001F)) + #define control_register *((unsigned char *)(CANADDR + 0x0000)) + #define command_register *((unsigned char *)(CANADDR + 0x0001)) + #define status_register *((unsigned char *)(CANADDR + 0x0002)) + #define interrupt_register *((unsigned char *)(CANADDR + 0x0003)) + #define acceptance_code_register *((unsigned char *)(CANADDR + 0x0004)) + #define acceptance_mask_register *((unsigned char *)(CANADDR + 0x0005)) + #define bus_timing_0_register *((unsigned char *)(CANADDR + 0x0006)) + #define bus_timing_1_register *((unsigned char *)(CANADDR + 0x0007)) + #define output_control_register *((unsigned char *)(CANADDR + 0x0008)) + #define test_register *((unsigned char *)(CANADDR + 0x0009)) + #define tb_identifier_byte_0 *((unsigned char *)(CANADDR + 0x000A)) + #define tb_identifier_byte_1 *((unsigned char *)(CANADDR + 0x000B)) + #define tb_data_byte_1 *((unsigned char *)(CANADDR + 0x000C)) + #define tb_data_byte_2 *((unsigned char *)(CANADDR + 0x000D)) + #define tb_data_byte_3 *((unsigned char *)(CANADDR + 0x000E)) + #define tb_data_byte_4 *((unsigned char *)(CANADDR + 0x000F)) + #define tb_data_byte_5 *((unsigned char *)(CANADDR + 0x0010)) + #define tb_data_byte_6 *((unsigned char *)(CANADDR + 0x0011)) + #define tb_data_byte_7 *((unsigned char *)(CANADDR + 0x0012)) + #define tb_data_byte_8 *((unsigned char *)(CANADDR + 0x0013)) + #define rb_identifier_byte_0 *((unsigned char *)(CANADDR + 0x0014)) + #define rb_identifier_byte_1 *((unsigned char *)(CANADDR + 0x0015)) + #define rb_data_byte_1 *((unsigned char *)(CANADDR + 0x0016)) + #define rb_data_byte_2 *((unsigned char *)(CANADDR + 0x0017)) + #define rb_data_byte_3 *((unsigned char *)(CANADDR + 0x0018)) + #define rb_data_byte_4 *((unsigned char *)(CANADDR + 0x0019)) + #define rb_data_byte_5 *((unsigned char *)(CANADDR + 0x001A)) + #define rb_data_byte_6 *((unsigned char *)(CANADDR + 0x001B)) + #define rb_data_byte_7 *((unsigned char *)(CANADDR + 0x001C)) + #define rb_data_byte_8 *((unsigned char *)(CANADDR + 0x001D)) + #define Extra_register *((unsigned char *)(CANADDR + 0x001E)) + #define clock_divider_register *((unsigned char *)(CANADDR + 0x001F)) #endif #ifdef extended -#define control_register *((unsigned char *)(CANADDR+0x0000)) -#define command_register *((unsigned char *)(CANADDR+0x0001)) -#define status_register *((unsigned char *)(CANADDR+0x0002)) -#define interrupt_register *((unsigned char *)(CANADDR+0x0003)) -#define interrupt_enable_register *((unsigned char *)(CANADDR+0x0004)) -#define reserved_register *((unsigned char *)(CANADDR+0x0005)) -#define bus_timing_0_register *((unsigned char *)(CANADDR+0x0006)) -#define bus_timing_1_register *((unsigned char *)(CANADDR+0x0007)) -#define output_control_register *((unsigned char *)(CANADDR+0x0008)) -#define test_register *((unsigned char *)(CANADDR+0x0009)) -#define reserved_1_register *((unsigned char *)(CANADDR+0x000A)) -#define arbitration_lost_capture *((unsigned char *)(CANADDR+0x000B)) -#define error_code_capture *((unsigned char *)(CANADDR+0x000C)) -#define error_warning_limit *((unsigned char *)(CANADDR+0x000D)) -#define rx_error_counter *((unsigned char *)(CANADDR+0x000E)) -#define tx_error_counter *((unsigned char *)(CANADDR+0x000F)) - -#define acceptance_code_0 *((unsigned char *)(CANADDR+0x0010)) -#define acceptance_code_1 *((unsigned char *)(CANADDR+0x0011)) -#define acceptance_code_2 *((unsigned char *)(CANADDR+0x0012)) -#define acceptance_code_3 *((unsigned char *)(CANADDR+0x0013)) -#define acceptance_mask_0 *((unsigned char *)(CANADDR+0x0014)) -#define acceptance_mask_1 *((unsigned char *)(CANADDR+0x0015)) -#define acceptance_mask_2 *((unsigned char *)(CANADDR+0x0016)) -#define acceptance_mask_3 *((unsigned char *)(CANADDR+0x0017)) - -#define rx_frame_information_sff *((unsigned char *)(CANADDR+0x0010)) -#define rx_identifier_1_sff *((unsigned char *)(CANADDR+0x0011)) -#define rx_identifier_2_sff *((unsigned char *)(CANADDR+0x0012)) -#define rx_data_1_sff *((unsigned char *)(CANADDR+0x0013)) -#define rx_data_2_sff *((unsigned char *)(CANADDR+0x0014)) -#define rx_data_3_sff *((unsigned char *)(CANADDR+0x0015)) -#define rx_data_4_sff *((unsigned char *)(CANADDR+0x0016)) -#define rx_data_5_sff *((unsigned char *)(CANADDR+0x0017)) -#define rx_data_6_sff *((unsigned char *)(CANADDR+0x0018)) -#define rx_data_7_sff *((unsigned char *)(CANADDR+0x0019)) -#define rx_data_8_sff *((unsigned char *)(CANADDR+0x001A)) - -#define rx_frame_information_eff *((unsigned char *)(CANADDR+0x0010)) -#define rx_identifier_1_eff *((unsigned char *)(CANADDR+0x0011)) -#define rx_identifier_2_eff *((unsigned char *)(CANADDR+0x0012)) -#define rx_identifier_3_eff *((unsigned char *)(CANADDR+0x0013)) -#define rx_identifier_4_eff *((unsigned char *)(CANADDR+0x0014)) -#define rx_data_1_eff *((unsigned char *)(CANADDR+0x0015)) -#define rx_data_2_eff *((unsigned char *)(CANADDR+0x0016)) -#define rx_data_3_eff *((unsigned char *)(CANADDR+0x0017)) -#define rx_data_4_eff *((unsigned char *)(CANADDR+0x0018)) -#define rx_data_5_eff *((unsigned char *)(CANADDR+0x0019)) -#define rx_data_6_eff *((unsigned char *)(CANADDR+0x001A)) -#define rx_data_7_eff *((unsigned char *)(CANADDR+0x001B)) -#define rx_data_8_eff *((unsigned char *)(CANADDR+0x001C)) - -#define tx_frame_information_sff *((unsigned char *)(CANADDR+0x0010)) -#define tx_identifier_1_sff *((unsigned char *)(CANADDR+0x0011)) -#define tx_identifier_2_sff *((unsigned char *)(CANADDR+0x0012)) -#define tx_data_1_sff *((unsigned char *)(CANADDR+0x0013)) -#define tx_data_2_sff *((unsigned char *)(CANADDR+0x0014)) -#define tx_data_3_sff *((unsigned char *)(CANADDR+0x0015)) -#define tx_data_4_sff *((unsigned char *)(CANADDR+0x0016)) -#define tx_data_5_sff *((unsigned char *)(CANADDR+0x0017)) -#define tx_data_6_sff *((unsigned char *)(CANADDR+0x0018)) -#define tx_data_7_sff *((unsigned char *)(CANADDR+0x0019)) -#define tx_data_8_sff *((unsigned char *)(CANADDR+0x001A)) - -#define tx_frame_information_eff *((unsigned char *)(CANADDR+0x0010)) -#define tx_identifier_1_eff *((unsigned char *)(CANADDR+0x0011)) -#define tx_identifier_2_eff *((unsigned char *)(CANADDR+0x0012)) -#define tx_identifier_3_eff *((unsigned char *)(CANADDR+0x0013)) -#define tx_identifier_4_eff *((unsigned char *)(CANADDR+0x0014)) -#define tx_data_1_eff *((unsigned char *)(CANADDR+0x0015)) -#define tx_data_2_eff *((unsigned char *)(CANADDR+0x0016)) -#define tx_data_3_eff *((unsigned char *)(CANADDR+0x0017)) -#define tx_data_4_eff *((unsigned char *)(CANADDR+0x0018)) -#define tx_data_5_eff *((unsigned char *)(CANADDR+0x0019)) -#define tx_data_6_eff *((unsigned char *)(CANADDR+0x001A)) -#define tx_data_7_eff *((unsigned char *)(CANADDR+0x001B)) -#define tx_data_8_eff *((unsigned char *)(CANADDR+0x001C)) - -#define rx_message_counter *((unsigned char *)(CANADDR+0x001D)) -#define rx_buffer_start_address *((unsigned char *)(CANADDR+0x001E)) -#define clock_divider_register *((unsigned char *)(CANADDR+0x001F)) + #define control_register *((unsigned char *)(CANADDR + 0x0000)) + #define command_register *((unsigned char *)(CANADDR + 0x0001)) + #define status_register *((unsigned char *)(CANADDR + 0x0002)) + #define interrupt_register *((unsigned char *)(CANADDR + 0x0003)) + #define interrupt_enable_register *((unsigned char *)(CANADDR + 0x0004)) + #define reserved_register *((unsigned char *)(CANADDR + 0x0005)) + #define bus_timing_0_register *((unsigned char *)(CANADDR + 0x0006)) + #define bus_timing_1_register *((unsigned char *)(CANADDR + 0x0007)) + #define output_control_register *((unsigned char *)(CANADDR + 0x0008)) + #define test_register *((unsigned char *)(CANADDR + 0x0009)) + #define reserved_1_register *((unsigned char *)(CANADDR + 0x000A)) + #define arbitration_lost_capture *((unsigned char *)(CANADDR + 0x000B)) + #define error_code_capture *((unsigned char *)(CANADDR + 0x000C)) + #define error_warning_limit *((unsigned char *)(CANADDR + 0x000D)) + #define rx_error_counter *((unsigned char *)(CANADDR + 0x000E)) + #define tx_error_counter *((unsigned char *)(CANADDR + 0x000F)) + + #define acceptance_code_0 *((unsigned char *)(CANADDR + 0x0010)) + #define acceptance_code_1 *((unsigned char *)(CANADDR + 0x0011)) + #define acceptance_code_2 *((unsigned char *)(CANADDR + 0x0012)) + #define acceptance_code_3 *((unsigned char *)(CANADDR + 0x0013)) + #define acceptance_mask_0 *((unsigned char *)(CANADDR + 0x0014)) + #define acceptance_mask_1 *((unsigned char *)(CANADDR + 0x0015)) + #define acceptance_mask_2 *((unsigned char *)(CANADDR + 0x0016)) + #define acceptance_mask_3 *((unsigned char *)(CANADDR + 0x0017)) + + #define rx_frame_information_sff *((unsigned char *)(CANADDR + 0x0010)) + #define rx_identifier_1_sff *((unsigned char *)(CANADDR + 0x0011)) + #define rx_identifier_2_sff *((unsigned char *)(CANADDR + 0x0012)) + #define rx_data_1_sff *((unsigned char *)(CANADDR + 0x0013)) + #define rx_data_2_sff *((unsigned char *)(CANADDR + 0x0014)) + #define rx_data_3_sff *((unsigned char *)(CANADDR + 0x0015)) + #define rx_data_4_sff *((unsigned char *)(CANADDR + 0x0016)) + #define rx_data_5_sff *((unsigned char *)(CANADDR + 0x0017)) + #define rx_data_6_sff *((unsigned char *)(CANADDR + 0x0018)) + #define rx_data_7_sff *((unsigned char *)(CANADDR + 0x0019)) + #define rx_data_8_sff *((unsigned char *)(CANADDR + 0x001A)) + + #define rx_frame_information_eff *((unsigned char *)(CANADDR + 0x0010)) + #define rx_identifier_1_eff *((unsigned char *)(CANADDR + 0x0011)) + #define rx_identifier_2_eff *((unsigned char *)(CANADDR + 0x0012)) + #define rx_identifier_3_eff *((unsigned char *)(CANADDR + 0x0013)) + #define rx_identifier_4_eff *((unsigned char *)(CANADDR + 0x0014)) + #define rx_data_1_eff *((unsigned char *)(CANADDR + 0x0015)) + #define rx_data_2_eff *((unsigned char *)(CANADDR + 0x0016)) + #define rx_data_3_eff *((unsigned char *)(CANADDR + 0x0017)) + #define rx_data_4_eff *((unsigned char *)(CANADDR + 0x0018)) + #define rx_data_5_eff *((unsigned char *)(CANADDR + 0x0019)) + #define rx_data_6_eff *((unsigned char *)(CANADDR + 0x001A)) + #define rx_data_7_eff *((unsigned char *)(CANADDR + 0x001B)) + #define rx_data_8_eff *((unsigned char *)(CANADDR + 0x001C)) + + #define tx_frame_information_sff *((unsigned char *)(CANADDR + 0x0010)) + #define tx_identifier_1_sff *((unsigned char *)(CANADDR + 0x0011)) + #define tx_identifier_2_sff *((unsigned char *)(CANADDR + 0x0012)) + #define tx_data_1_sff *((unsigned char *)(CANADDR + 0x0013)) + #define tx_data_2_sff *((unsigned char *)(CANADDR + 0x0014)) + #define tx_data_3_sff *((unsigned char *)(CANADDR + 0x0015)) + #define tx_data_4_sff *((unsigned char *)(CANADDR + 0x0016)) + #define tx_data_5_sff *((unsigned char *)(CANADDR + 0x0017)) + #define tx_data_6_sff *((unsigned char *)(CANADDR + 0x0018)) + #define tx_data_7_sff *((unsigned char *)(CANADDR + 0x0019)) + #define tx_data_8_sff *((unsigned char *)(CANADDR + 0x001A)) + + #define tx_frame_information_eff *((unsigned char *)(CANADDR + 0x0010)) + #define tx_identifier_1_eff *((unsigned char *)(CANADDR + 0x0011)) + #define tx_identifier_2_eff *((unsigned char *)(CANADDR + 0x0012)) + #define tx_identifier_3_eff *((unsigned char *)(CANADDR + 0x0013)) + #define tx_identifier_4_eff *((unsigned char *)(CANADDR + 0x0014)) + #define tx_data_1_eff *((unsigned char *)(CANADDR + 0x0015)) + #define tx_data_2_eff *((unsigned char *)(CANADDR + 0x0016)) + #define tx_data_3_eff *((unsigned char *)(CANADDR + 0x0017)) + #define tx_data_4_eff *((unsigned char *)(CANADDR + 0x0018)) + #define tx_data_5_eff *((unsigned char *)(CANADDR + 0x0019)) + #define tx_data_6_eff *((unsigned char *)(CANADDR + 0x001A)) + #define tx_data_7_eff *((unsigned char *)(CANADDR + 0x001B)) + #define tx_data_8_eff *((unsigned char *)(CANADDR + 0x001C)) + + #define rx_message_counter *((unsigned char *)(CANADDR + 0x001D)) + #define rx_buffer_start_address *((unsigned char *)(CANADDR + 0x001E)) + #define clock_divider_register *((unsigned char *)(CANADDR + 0x001F)) #endif - -#define reset_mode_on 0x01 -#define reset_mode_off 0xFE -#define enable_all_int 0x1E -#define tx_request 0x01 -#define basic_mode 0x7F -#define extended_mode 0x80 -#define release_buffer 0x04 +#define reset_mode_on 0x01 +#define reset_mode_off 0xFE +#define enable_all_int 0x1E +#define tx_request 0x01 +#define basic_mode 0x7F +#define extended_mode 0x80 +#define release_buffer 0x04 #define receive_interrupt 0x01 -#define self_test_mode 0x04 -#define self_reception 0x10 +#define self_test_mode 0x04 +#define self_reception 0x10 #define enable_all_int_eff 0xFF // can mode "Basic" or "Extended" -//const char * mode = "Basic"; -//const char * mode = "Extended"; +// const char * mode = "Basic"; +// const char * mode = "Extended"; // waits for some time -void kill_time(int rep) { - int i; +void kill_time(int rep) +{ + int i; - for (i=rep; i>0; --i) - asm("nop"); + for (i = rep; i > 0; --i) + asm("nop"); } - - void self_testing_mode() { - unsigned char r_val; - - printf("************************************\n"); - printf("***** Set to self testing mode *****\n"); - printf("************************************\n"); - - r_val = control_register | self_test_mode; - control_register = r_val; - printf( "control_register 0x%X \n\n",control_register); + unsigned char r_val; + printf("************************************\n"); + printf("***** Set to self testing mode *****\n"); + printf("************************************\n"); + + r_val = control_register | self_test_mode; + control_register = r_val; + printf("control_register 0x%X \n\n", control_register); } - void reset_all_irqs() { - printf("************************************\n"); - printf("********** reset all irqs **********\n"); - printf("************************************\n"); - - printf( "interrupt_register 0x%X \n\n",interrupt_register); - + printf("************************************\n"); + printf("********** reset all irqs **********\n"); + printf("************************************\n"); + printf("interrupt_register 0x%X \n\n", interrupt_register); } void disable_irq_sff() { - unsigned char r_val; - - printf("************************************\n"); - printf("*********** disable irqs ***********\n"); - printf("************************************\n"); - - r_val = interrupt_enable_register | enable_all_int_eff; - interrupt_enable_register = r_val; - printf( "interrupt_enable_register 0x%X \n\n",interrupt_enable_register); + unsigned char r_val; + + printf("************************************\n"); + printf("*********** disable irqs ***********\n"); + printf("************************************\n"); + r_val = interrupt_enable_register | enable_all_int_eff; + interrupt_enable_register = r_val; + printf("interrupt_enable_register 0x%X \n\n", interrupt_enable_register); } void enable_irq_sff() { - unsigned char r_val; - - //printf("************************************\n"); - //printf("*********** enable irqs ************\n"); - //printf("************************************\n"); - - r_val = control_register | enable_all_int; - control_register = r_val; - printf( "control_register 0x%X \n\n",control_register); + unsigned char r_val; + + // printf("************************************\n"); + // printf("*********** enable irqs ************\n"); + // printf("************************************\n"); + + r_val = control_register | enable_all_int; + control_register = r_val; + printf("control_register 0x%X \n\n", control_register); } void disable_irq_eff() { - unsigned char r_val; - - printf("************************************\n"); - printf("*********** disable irqs ***********\n"); - printf("************************************\n"); - - r_val = interrupt_enable_register | enable_all_int_eff; - interrupt_enable_register = r_val; - printf( "interrupt_enable_register 0x%X \n\n",interrupt_enable_register); + unsigned char r_val; + + printf("************************************\n"); + printf("*********** disable irqs ***********\n"); + printf("************************************\n"); + r_val = interrupt_enable_register | enable_all_int_eff; + interrupt_enable_register = r_val; + printf("interrupt_enable_register 0x%X \n\n", interrupt_enable_register); } void enable_irq_eff() { - unsigned char r_val; - - printf("************************************\n"); - printf("*********** enable irqs eff ********\n"); - printf("************************************\n"); - - r_val = interrupt_enable_register | enable_all_int_eff; - interrupt_enable_register = r_val; - printf( "interrupt_enable_register 0x%X \n\n",interrupt_enable_register); + unsigned char r_val; + printf("************************************\n"); + printf("*********** enable irqs eff ********\n"); + printf("************************************\n"); + + r_val = interrupt_enable_register | enable_all_int_eff; + interrupt_enable_register = r_val; + printf("interrupt_enable_register 0x%X \n\n", interrupt_enable_register); } - + void tx_request_command() { - unsigned char r_val; - -// printf("************************************\n"); -// printf("*********** tx requestet ***********\n"); -// printf("************************************\n"); - - printf( "Send transmit-request \n"); - r_val = command_register | tx_request; - command_register = r_val; - printf( "command register: 0x%X \n\n",command_register); + unsigned char r_val; + + // printf("************************************\n"); + // printf("*********** tx requestet ***********\n"); + // printf("************************************\n"); + + printf("Send transmit-request \n"); + r_val = command_register | tx_request; + command_register = r_val; + printf("command register: 0x%X \n\n", command_register); } void self_reception_request() { - unsigned char r_val; + unsigned char r_val; - printf("************************************\n"); - printf("***** self reception requestet *****\n"); - printf("************************************\n"); - - r_val = command_register | self_reception; - command_register = r_val; - printf( "command register : 0x%X \n\n",command_register); + printf("************************************\n"); + printf("***** self reception requestet *****\n"); + printf("************************************\n"); + r_val = command_register | self_reception; + command_register = r_val; + printf("command register : 0x%X \n\n", command_register); } void release_receive_buffer() { - unsigned char r_val; - - printf("************************************\n"); - printf("****** release receive buffer ******\n"); - printf("************************************\n"); - + unsigned char r_val; - r_val = command_register | release_buffer; - command_register = r_val; - printf( "command register : 0x%X \n\n",command_register); + printf("************************************\n"); + printf("****** release receive buffer ******\n"); + printf("************************************\n"); + r_val = command_register | release_buffer; + command_register = r_val; + printf("command register : 0x%X \n\n", command_register); } void read_receive_buffer_basic() { - unsigned char r_val; - - printf("************************************\n"); - printf("******** read receive buffer *******\n"); - printf("************************************\n"); - - printf( "identifier 0: 0x%X \n",rb_identifier_byte_0); - - printf( "identifier 1: 0x%X \n",rb_identifier_byte_1); - - printf( "data byte 1: 0x%X \n",rb_data_byte_1); - - printf( "data byte 2: 0x%X \n",rb_data_byte_2); - - printf( "data byte 3: 0x%X \n",rb_data_byte_3); - - printf( "data byte 4: 0x%X \n",rb_data_byte_4); - - printf( "data byte 5: 0x%X \n",rb_data_byte_5); - - printf( "data byte 6: 0x%X \n",rb_data_byte_6); - - printf( "data byte 7: 0x%X \n",rb_data_byte_7); - - printf( "data byte 8: 0x%X \n\n",rb_data_byte_8); - -} + unsigned char r_val; + + printf("************************************\n"); + printf("******** read receive buffer *******\n"); + printf("************************************\n"); + + printf("identifier 0: 0x%X \n", rb_identifier_byte_0); + + printf("identifier 1: 0x%X \n", rb_identifier_byte_1); + + printf("data byte 1: 0x%X \n", rb_data_byte_1); + + printf("data byte 2: 0x%X \n", rb_data_byte_2); + + printf("data byte 3: 0x%X \n", rb_data_byte_3); + printf("data byte 4: 0x%X \n", rb_data_byte_4); + + printf("data byte 5: 0x%X \n", rb_data_byte_5); + + printf("data byte 6: 0x%X \n", rb_data_byte_6); + + printf("data byte 7: 0x%X \n", rb_data_byte_7); + + printf("data byte 8: 0x%X \n\n", rb_data_byte_8); +} void read_receive_buffer_extended() { - unsigned char r_val; - - printf("************************************\n"); - printf("******* read frame extended ********\n"); - printf("************************************\n"); - - printf( "rx_frame_information_eff: 0x%X \n\n",rx_frame_information_eff); - - printf( "identifier 0: 0x%X \n",rx_identifier_1_eff); - - printf( "identifier 1: 0x%X \n",rx_identifier_2_eff); - - printf( "identifier 2: 0x%X \n",rx_identifier_3_eff); - - printf( "identifier 3: 0x%X \n\n",rx_identifier_4_eff); - - printf( "data byte 1: 0x%X \n",rx_data_1_eff); - - printf( "data byte 2: 0x%X \n",rx_data_2_eff); - - printf( "data byte 3: 0x%X \n",rx_data_3_eff); - - printf( "data byte 4: 0x%X \n",rx_data_4_eff); - - printf( "data byte 5: 0x%X \n",rx_data_5_eff); - - printf( "data byte 6: 0x%X \n",rx_data_6_eff); - - printf( "data byte 7: 0x%X \n",rx_data_7_eff); - - printf( "data byte 8: 0x%X \n\n",rx_data_8_eff); - + unsigned char r_val; + + printf("************************************\n"); + printf("******* read frame extended ********\n"); + printf("************************************\n"); + + printf("rx_frame_information_eff: 0x%X \n\n", rx_frame_information_eff); + + printf("identifier 0: 0x%X \n", rx_identifier_1_eff); + + printf("identifier 1: 0x%X \n", rx_identifier_2_eff); + + printf("identifier 2: 0x%X \n", rx_identifier_3_eff); + + printf("identifier 3: 0x%X \n\n", rx_identifier_4_eff); + + printf("data byte 1: 0x%X \n", rx_data_1_eff); + + printf("data byte 2: 0x%X \n", rx_data_2_eff); + + printf("data byte 3: 0x%X \n", rx_data_3_eff); + + printf("data byte 4: 0x%X \n", rx_data_4_eff); + + printf("data byte 5: 0x%X \n", rx_data_5_eff); + + printf("data byte 6: 0x%X \n", rx_data_6_eff); + + printf("data byte 7: 0x%X \n", rx_data_7_eff); + + printf("data byte 8: 0x%X \n\n", rx_data_8_eff); } /*void write_frame_basic() { - unsigned char r_val; - - printf("************************************\n"); - printf("********* Send frame basic *********\n"); - printf("************************************\n"); - - printf( "Set identifier - 0xEA 0x28\n"); - tb_identifier_byte_0 = 0xEA; - printf( "identifier 0: 0x%X \n",tb_identifier_byte_0); - - tb_identifier_byte_1 = 0x28; - printf( "identifier 1: 0x%X \n\n",tb_identifier_byte_1); - - printf( "Set data byte 1 \n"); - tb_data_byte_1 = 0x12; - printf( "data byte 1: 0x%X \n",tb_data_byte_1); - - printf( "Set data byte 2 \n"); - tb_data_byte_2 = 0x34; - printf( "data byte 2: 0x%X \n",tb_data_byte_2); - - printf( "Set data byte 3 \n"); - tb_data_byte_3 = 0x56; - printf( "data byte 3: 0x%X \n",tb_data_byte_3); - - printf( "Set data byte 4 \n"); - tb_data_byte_4 = 0x78; - printf( "data byte 4: 0x%X \n",tb_data_byte_4); - - printf( "Set data byte 5 \n"); - tb_data_byte_5 = 0x9A; - printf( "data byte 5: 0x%X \n",tb_data_byte_5); - - printf( "Set data byte 6 \n"); - tb_data_byte_6 = 0xBC; - printf( "data byte 6: 0x%X \n",tb_data_byte_6); - - printf( "Set data byte 7 \n"); - tb_data_byte_7 = 0xDE; - printf( "data byte 7: 0x%X \n",tb_data_byte_7); - - printf( "Set data byte 8 \n"); - tb_data_byte_8 = 0xF0; - printf( "data byte 8: 0x%X \n\n",tb_data_byte_8); + unsigned char r_val; + + printf("************************************\n"); + printf("********* Send frame basic *********\n"); + printf("************************************\n"); + + printf( "Set identifier - 0xEA 0x28\n"); + tb_identifier_byte_0 = 0xEA; + printf( "identifier 0: 0x%X \n",tb_identifier_byte_0); + + tb_identifier_byte_1 = 0x28; + printf( "identifier 1: 0x%X \n\n",tb_identifier_byte_1); + + printf( "Set data byte 1 \n"); + tb_data_byte_1 = 0x12; + printf( "data byte 1: 0x%X \n",tb_data_byte_1); + + printf( "Set data byte 2 \n"); + tb_data_byte_2 = 0x34; + printf( "data byte 2: 0x%X \n",tb_data_byte_2); + + printf( "Set data byte 3 \n"); + tb_data_byte_3 = 0x56; + printf( "data byte 3: 0x%X \n",tb_data_byte_3); + + printf( "Set data byte 4 \n"); + tb_data_byte_4 = 0x78; + printf( "data byte 4: 0x%X \n",tb_data_byte_4); + + printf( "Set data byte 5 \n"); + tb_data_byte_5 = 0x9A; + printf( "data byte 5: 0x%X \n",tb_data_byte_5); + + printf( "Set data byte 6 \n"); + tb_data_byte_6 = 0xBC; + printf( "data byte 6: 0x%X \n",tb_data_byte_6); + + printf( "Set data byte 7 \n"); + tb_data_byte_7 = 0xDE; + printf( "data byte 7: 0x%X \n",tb_data_byte_7); + + printf( "Set data byte 8 \n"); + tb_data_byte_8 = 0xF0; + printf( "data byte 8: 0x%X \n\n",tb_data_byte_8); } */ /*void write_frame_extended() { - unsigned char r_val; - - printf("************************************\n"); - printf("******* write frame extended *******\n"); - printf("************************************\n"); - - - tx_frame_information_eff = 0x88; - printf( "tx_frame_information_eff: 0x%X \n\n",tx_frame_information_eff); - - - printf( "Set identifier - 0xA6 0xB0 0x12 0x30\n"); - tx_identifier_1_eff = 0xA6; - printf( "identifier 0: 0x%X \n",tx_identifier_1_eff); - - tx_identifier_2_eff = 0xB0; - printf( "identifier 1: 0x%X \n",tx_identifier_2_eff); - - tx_identifier_3_eff = 0x12; - printf( "identifier 2: 0x%X \n",tx_identifier_3_eff); - - tx_identifier_4_eff = 0x30; - printf( "identifier 3: 0x%X \n\n",tx_identifier_4_eff); - - printf( "Set data - 0x12 0x34 0x56 0x78 0x9A 0xBC 0xDE 0xF0\n"); - tx_data_1_eff = 0x12; - printf( "data byte 1: 0x%X \n",tx_data_1_eff); - - tx_data_2_eff = 0x34; - printf( "data byte 2: 0x%X \n",tx_data_2_eff); - - tx_data_3_eff = 0x56; - printf( "data byte 3: 0x%X \n",tx_data_3_eff); - - tx_data_4_eff = 0x78; - printf( "data byte 4: 0x%X \n",tx_data_4_eff); - - tx_data_5_eff = 0x9A; - printf( "data byte 5: 0x%X \n",tx_data_5_eff); - - tx_data_6_eff = 0xBC; - printf( "data byte 6: 0x%X \n",tx_data_6_eff); - - tx_data_7_eff = 0xDE; - printf( "data byte 7: 0x%X \n",tx_data_7_eff); - - tx_data_8_eff = 0xF0; - printf( "data byte 8: 0x%X \n\n",tx_data_8_eff); - + unsigned char r_val; + + printf("************************************\n"); + printf("******* write frame extended *******\n"); + printf("************************************\n"); + + + tx_frame_information_eff = 0x88; + printf( "tx_frame_information_eff: 0x%X \n\n",tx_frame_information_eff); + + + printf( "Set identifier - 0xA6 0xB0 0x12 0x30\n"); + tx_identifier_1_eff = 0xA6; + printf( "identifier 0: 0x%X \n",tx_identifier_1_eff); + + tx_identifier_2_eff = 0xB0; + printf( "identifier 1: 0x%X \n",tx_identifier_2_eff); + + tx_identifier_3_eff = 0x12; + printf( "identifier 2: 0x%X \n",tx_identifier_3_eff); + + tx_identifier_4_eff = 0x30; + printf( "identifier 3: 0x%X \n\n",tx_identifier_4_eff); + + printf( "Set data - 0x12 0x34 0x56 0x78 0x9A 0xBC 0xDE 0xF0\n"); + tx_data_1_eff = 0x12; + printf( "data byte 1: 0x%X \n",tx_data_1_eff); + + tx_data_2_eff = 0x34; + printf( "data byte 2: 0x%X \n",tx_data_2_eff); + + tx_data_3_eff = 0x56; + printf( "data byte 3: 0x%X \n",tx_data_3_eff); + + tx_data_4_eff = 0x78; + printf( "data byte 4: 0x%X \n",tx_data_4_eff); + + tx_data_5_eff = 0x9A; + printf( "data byte 5: 0x%X \n",tx_data_5_eff); + + tx_data_6_eff = 0xBC; + printf( "data byte 6: 0x%X \n",tx_data_6_eff); + + tx_data_7_eff = 0xDE; + printf( "data byte 7: 0x%X \n",tx_data_7_eff); + + tx_data_8_eff = 0xF0; + printf( "data byte 8: 0x%X \n\n",tx_data_8_eff); + } */ -void init_can(char * mode, char * self_test) +void init_can(char *mode, char *self_test) { - unsigned char r_val; - - if (mode == "Basic") - { - //printf("************************************\n"); - printf("********** Basic Can Mode **********\n"); - //printf("************************************\n"); - - printf( "Switch on Reset Mode\n"); - r_val = control_register | reset_mode_on; - control_register = r_val; - //printf( "control_register: 0x%X \n\n",control_register); - - //printf( "Set clock divider register to basic can mode\n"); - r_val = clock_divider_register & basic_mode | 0x07; - clock_divider_register = r_val; - //printf( "clock_divider_register: 0x%X \n\n",clock_divider_register); - - //printf( "Output control register \n"); - //output_control_register = 0x01; - //printf( "output control register : 0x%X \n\n",output_control_register); - - //printf( "Set bus timing register 0\n"); - //printf( "Sync Jump Width = 2 Baudrate Prescaler = 1\n"); - bus_timing_0_register = 0x83; - //printf( "bus timing register 0: 0x%X \n\n",bus_timing_0_register); - - //printf( "Set bus timing register 1\n"); - //printf( "SAM = 0 ---> Single Sampling\n"); - bus_timing_1_register = 0x25; - //printf( "bus timing register 1: 0x%X \n\n",bus_timing_1_register); - - //printf( "Set acceptance code register\n"); - acceptance_code_register = 0x88; - //printf( "acceptance code register: 0x%X \n\n",acceptance_code_register); - - //printf( "Set acceptance mask register\n"); - acceptance_mask_register = 0xFF; - //printf( "acceptance mask register: 0x%X \n\n",acceptance_mask_register); - - - kill_time(50); - - printf( "Switch off reset mode\n"); - r_val = control_register & reset_mode_off; - control_register = r_val; - //printf( "control_register 0x%X \n\n",control_register); - - kill_time(50); - - } - else if (mode == "Extended") - { - printf("************************************\n"); - printf("******** Extended Can Mode *********\n"); - printf("************************************\n"); - - printf( "Switch on Reset Mode\n"); - r_val = control_register | reset_mode_on; - control_register = r_val; - printf( "control_register: 0x%X \n\n",control_register); - - - kill_time(50); - - - printf( "Set clock divider register to extended can mode\n"); - r_val = clock_divider_register | extended_mode | 0x07; - clock_divider_register = r_val; - printf( "clock_divider_register: 0x%X \n\n",clock_divider_register); - - kill_time(50); - - //printf( "Output control register \n"); - //output_control_register = 0x01; - //printf( "output control register: 0x%X \n\n",output_control_register); - - printf( "Set bus timing register 0\n"); - printf( "Sync Jump Width = 2 Baudrate Prescaler = 1\n"); - bus_timing_0_register = 0xA8; - printf( "bus timing register 0: 0x%X \n\n",bus_timing_0_register); - - printf( "Set bus timing register 1\n"); - printf( "SAM = 0 ---> Single Sampling\n"); - bus_timing_1_register = 0x34; - printf( "bus timing register 1: 0x%X \n\n",bus_timing_1_register); - - printf( "Set acceptance code register\n"); - acceptance_code_0 = 0xA6; - printf( "acceptance code register 0: 0x%X \n",acceptance_code_0); - - acceptance_code_1 = 0xB0; - printf( "acceptance code register 1: 0x%X \n",acceptance_code_1); - - acceptance_code_2 = 0x12; - printf( "acceptance code register 2: 0x%X \n",acceptance_code_2); - - acceptance_code_3 = 0x30; - printf( "acceptance code register 3: 0x%X \n\n",acceptance_code_3); - - - printf( "Set acceptance mask register\n"); - acceptance_mask_0 = 0x00; - printf( "acceptance mask register: 0x%X \n",acceptance_mask_0); - - acceptance_mask_1 = 0x00; - printf( "acceptance mask register: 0x%X \n",acceptance_mask_1); - - acceptance_mask_2 = 0x00; - printf( "acceptance mask register: 0x%X \n",acceptance_mask_2); - - acceptance_mask_3 = 0x00; - printf( "acceptance mask register: 0x%X \n\n",acceptance_mask_3); - - if (self_test == "self_test") - { - self_testing_mode(); - } - - printf( "Switch off reset mode\n"); - r_val = control_register & reset_mode_off; - control_register = r_val; - printf( "control_register 0x%X \n\n",control_register); - - kill_time(50); - } - + unsigned char r_val; -} + if (mode == "Basic") { + // printf("************************************\n"); + printf("********** Basic Can Mode **********\n"); + // printf("************************************\n"); + printf("Switch on Reset Mode\n"); + r_val = control_register | reset_mode_on; + control_register = r_val; + // printf( "control_register: 0x%X \n\n",control_register); -void self_reception_test() -{ - unsigned char r_val; - - printf( "Switch on Reset Mode\n"); - control_register = 0x01; - printf( "control 0x%X \n\n",control_register); - - // witch to extended mode - clock_divider_register = 0x80; - printf( "clock_divider 0x%X \n\n",clock_divider_register); - - // set bus timing - //bus_timing_0_register = 0xBF; - bus_timing_0_register = 0x80; - + // printf( "Set clock divider register to basic can mode\n"); + r_val = clock_divider_register & basic_mode | 0x07; + clock_divider_register = r_val; + // printf( "clock_divider_register: 0x%X \n\n",clock_divider_register); + + // printf( "Output control register \n"); + // output_control_register = 0x01; + // printf( "output control register : 0x%X \n\n",output_control_register); + + // printf( "Set bus timing register 0\n"); + // printf( "Sync Jump Width = 2 Baudrate Prescaler = 1\n"); + bus_timing_0_register = 0x83; + // printf( "bus timing register 0: 0x%X \n\n",bus_timing_0_register); + + // printf( "Set bus timing register 1\n"); + // printf( "SAM = 0 ---> Single Sampling\n"); + bus_timing_1_register = 0x25; + // printf( "bus timing register 1: 0x%X \n\n",bus_timing_1_register); + + // printf( "Set acceptance code register\n"); + acceptance_code_register = 0x88; + // printf( "acceptance code register: 0x%X \n\n",acceptance_code_register); + + // printf( "Set acceptance mask register\n"); + acceptance_mask_register = 0xFF; + // printf( "acceptance mask register: 0x%X \n\n",acceptance_mask_register); + + kill_time(50); + + printf("Switch off reset mode\n"); + r_val = control_register & reset_mode_off; + control_register = r_val; + // printf( "control_register 0x%X \n\n",control_register); + + kill_time(50); + } + else if (mode == "Extended") { + printf("************************************\n"); + printf("******** Extended Can Mode *********\n"); + printf("************************************\n"); + + printf("Switch on Reset Mode\n"); + r_val = control_register | reset_mode_on; + control_register = r_val; + printf("control_register: 0x%X \n\n", control_register); + + kill_time(50); + + printf("Set clock divider register to extended can mode\n"); + r_val = clock_divider_register | extended_mode | 0x07; + clock_divider_register = r_val; + printf("clock_divider_register: 0x%X \n\n", clock_divider_register); + + kill_time(50); + + // printf( "Output control register \n"); + // output_control_register = 0x01; + // printf( "output control register: 0x%X \n\n",output_control_register); + + printf("Set bus timing register 0\n"); + printf("Sync Jump Width = 2 Baudrate Prescaler = 1\n"); + bus_timing_0_register = 0xA8; + printf("bus timing register 0: 0x%X \n\n", bus_timing_0_register); + + printf("Set bus timing register 1\n"); + printf("SAM = 0 ---> Single Sampling\n"); bus_timing_1_register = 0x34; - - // set acceptance and mask register - acceptance_code_0 = 0xA6; - printf( "acceptance 0 0x%X \n",acceptance_code_0); - - acceptance_code_1 = 0xB0; - printf( "acceptance 1 0x%X \n",acceptance_code_1); - - acceptance_code_2 = 0x12; - printf( "acceptance 2 0x%X \n",acceptance_code_2); - - acceptance_code_3 = 0x30; - printf( "acceptance 3 0x%X \n\n",acceptance_code_3); - - acceptance_mask_0 = 0x00; - printf( "acceptance mask 0x%X \n",acceptance_mask_0); - - acceptance_mask_1 = 0x00; - printf( "acceptance mask 0x%X \n",acceptance_mask_1); - - acceptance_mask_2 = 0x00; - printf( "acceptance mask 0x%X \n",acceptance_mask_2); - - acceptance_mask_3 = 0x00; - printf( "acceptance mask 0x%X \n\n",acceptance_mask_3); - - // Setting the "self test mode" - control_register = 0x05; - printf( "control 0x%X \n\n",control_register); - - kill_time(50); - // Switch-off reset mode - control_register = 0X04; - printf( "control_register 0x%X \n\n",control_register); - - kill_time(150); - - // Send frame - tx_frame_information_eff = 0x88; - - printf( "Set identifier - 0xA6 0xB0 0x12 0x30\n"); - tx_identifier_1_eff = 0xA6; - //printf( "identifier 0: 0x%X \n",tx_identifier_1_eff); - - tx_identifier_2_eff = 0xB0; - //printf( "identifier 1: 0x%X \n",tx_identifier_2_eff); - - tx_identifier_3_eff = 0x12; - //printf( "identifier 2: 0x%X \n",tx_identifier_3_eff); - - tx_identifier_4_eff = 0x30; - //printf( "identifier 3: 0x%X \n\n",tx_identifier_4_eff); - - printf( "Set data - 0x12 0x34 0x56 0x78 0x9A 0xBC 0xDE 0xF0\n"); - tx_data_1_eff = 0x12; - //printf( "data byte 1: 0x%X \n",tx_data_1_eff); - - tx_data_2_eff = 0x34; - //printf( "data byte 2: 0x%X \n",tx_data_2_eff); - - tx_data_3_eff = 0x56; - //printf( "data byte 3: 0x%X \n",tx_data_3_eff); - - tx_data_4_eff = 0x78; - //printf( "data byte 4: 0x%X \n",tx_data_4_eff); - - tx_data_5_eff = 0x9A; - //printf( "data byte 5: 0x%X \n",tx_data_5_eff); - - tx_data_6_eff = 0xBC; - //printf( "data byte 6: 0x%X \n",tx_data_6_eff); - - tx_data_7_eff = 0xDE; - //printf( "data byte 7: 0x%X \n",tx_data_7_eff); - - tx_data_8_eff = 0xF0; - //printf( "data byte 8: 0x%X \n\n",tx_data_8_eff); - - - // Enable ints - interrupt_enable_register = 0xFF; - kill_time(50); - //tx_request_command(); - self_reception_request(); - - - //tx_request_command(); - printf( "Finnished \n"); - - printf( "control_register 0x%X \n\n",control_register); - - //kill_time(10000); - - printf( "interrupt_register 0x%X \n\n",interrupt_register); - - printf( "control_register 0x%X \n\n",control_register); - - //read_receive_buffer_extended(); + printf("bus timing register 1: 0x%X \n\n", bus_timing_1_register); + + printf("Set acceptance code register\n"); + acceptance_code_0 = 0xA6; + printf("acceptance code register 0: 0x%X \n", acceptance_code_0); + + acceptance_code_1 = 0xB0; + printf("acceptance code register 1: 0x%X \n", acceptance_code_1); + + acceptance_code_2 = 0x12; + printf("acceptance code register 2: 0x%X \n", acceptance_code_2); + + acceptance_code_3 = 0x30; + printf("acceptance code register 3: 0x%X \n\n", acceptance_code_3); + + printf("Set acceptance mask register\n"); + acceptance_mask_0 = 0x00; + printf("acceptance mask register: 0x%X \n", acceptance_mask_0); + + acceptance_mask_1 = 0x00; + printf("acceptance mask register: 0x%X \n", acceptance_mask_1); + + acceptance_mask_2 = 0x00; + printf("acceptance mask register: 0x%X \n", acceptance_mask_2); + + acceptance_mask_3 = 0x00; + printf("acceptance mask register: 0x%X \n\n", acceptance_mask_3); + + if (self_test == "self_test") { self_testing_mode(); } + + printf("Switch off reset mode\n"); + r_val = control_register & reset_mode_off; + control_register = r_val; + printf("control_register 0x%X \n\n", control_register); + + kill_time(50); + } +} + +void self_reception_test() +{ + unsigned char r_val; + + printf("Switch on Reset Mode\n"); + control_register = 0x01; + printf("control 0x%X \n\n", control_register); + + // witch to extended mode + clock_divider_register = 0x80; + printf("clock_divider 0x%X \n\n", clock_divider_register); + + // set bus timing + // bus_timing_0_register = 0xBF; + bus_timing_0_register = 0x80; + + bus_timing_1_register = 0x34; + + // set acceptance and mask register + acceptance_code_0 = 0xA6; + printf("acceptance 0 0x%X \n", acceptance_code_0); + + acceptance_code_1 = 0xB0; + printf("acceptance 1 0x%X \n", acceptance_code_1); + + acceptance_code_2 = 0x12; + printf("acceptance 2 0x%X \n", acceptance_code_2); + + acceptance_code_3 = 0x30; + printf("acceptance 3 0x%X \n\n", acceptance_code_3); + + acceptance_mask_0 = 0x00; + printf("acceptance mask 0x%X \n", acceptance_mask_0); + + acceptance_mask_1 = 0x00; + printf("acceptance mask 0x%X \n", acceptance_mask_1); + + acceptance_mask_2 = 0x00; + printf("acceptance mask 0x%X \n", acceptance_mask_2); + + acceptance_mask_3 = 0x00; + printf("acceptance mask 0x%X \n\n", acceptance_mask_3); + + // Setting the "self test mode" + control_register = 0x05; + printf("control 0x%X \n\n", control_register); + + kill_time(50); + // Switch-off reset mode + control_register = 0X04; + printf("control_register 0x%X \n\n", control_register); + + kill_time(150); + + // Send frame + tx_frame_information_eff = 0x88; + + printf("Set identifier - 0xA6 0xB0 0x12 0x30\n"); + tx_identifier_1_eff = 0xA6; + // printf( "identifier 0: 0x%X \n",tx_identifier_1_eff); + + tx_identifier_2_eff = 0xB0; + // printf( "identifier 1: 0x%X \n",tx_identifier_2_eff); + + tx_identifier_3_eff = 0x12; + // printf( "identifier 2: 0x%X \n",tx_identifier_3_eff); + + tx_identifier_4_eff = 0x30; + // printf( "identifier 3: 0x%X \n\n",tx_identifier_4_eff); + + printf("Set data - 0x12 0x34 0x56 0x78 0x9A 0xBC 0xDE 0xF0\n"); + tx_data_1_eff = 0x12; + // printf( "data byte 1: 0x%X \n",tx_data_1_eff); + + tx_data_2_eff = 0x34; + // printf( "data byte 2: 0x%X \n",tx_data_2_eff); + + tx_data_3_eff = 0x56; + // printf( "data byte 3: 0x%X \n",tx_data_3_eff); + + tx_data_4_eff = 0x78; + // printf( "data byte 4: 0x%X \n",tx_data_4_eff); + + tx_data_5_eff = 0x9A; + // printf( "data byte 5: 0x%X \n",tx_data_5_eff); + + tx_data_6_eff = 0xBC; + // printf( "data byte 6: 0x%X \n",tx_data_6_eff); + + tx_data_7_eff = 0xDE; + // printf( "data byte 7: 0x%X \n",tx_data_7_eff); + + tx_data_8_eff = 0xF0; + // printf( "data byte 8: 0x%X \n\n",tx_data_8_eff); + + // Enable ints + interrupt_enable_register = 0xFF; + kill_time(50); + // tx_request_command(); + self_reception_request(); + + // tx_request_command(); + printf("Finnished \n"); + + printf("control_register 0x%X \n\n", control_register); + + // kill_time(10000); + + printf("interrupt_register 0x%X \n\n", interrupt_register); + + printf("control_register 0x%X \n\n", control_register); + + // read_receive_buffer_extended(); } void write_frame_basic(unsigned char write_field[]) -{ - int i = 0; - - //printf("************************************\n"); - //printf("******** write frame basic *********\n"); - //printf("************************************\n"); - - for (i=0; i<10; i++) - { - *((unsigned char *)(CANADDR+0x000A+i)) = write_field[i]; - kill_time(10); - printf( "write data: %i , 0x%X , 0x%X \n",i,write_field[i],*((unsigned char *)(CANADDR+0x000A+i))); - } - +{ + int i = 0; + + // printf("************************************\n"); + // printf("******** write frame basic *********\n"); + // printf("************************************\n"); + + for (i = 0; i < 10; i++) { + *((unsigned char *)(CANADDR + 0x000A + i)) = write_field[i]; + kill_time(10); + printf("write data: %i , 0x%X , 0x%X \n", i, write_field[i], + *((unsigned char *)(CANADDR + 0x000A + i))); + } } void write_frame_extended(unsigned char write_field[]) -{ - int i = 0; - //printf("************************************\n"); - printf("******* write frame extended *******\n"); - //printf("************************************\n"); - - for (i=0; i<13; i++) - { - *((unsigned char *)(CANADDR+0x0010+i)) = write_field[i]; - kill_time(10); - printf( "write data %i: 0x%X , 0x%X \n",i,write_field[i],*((unsigned char *)(CANADDR+0x0010+i))); - } - +{ + int i = 0; + // printf("************************************\n"); + printf("******* write frame extended *******\n"); + // printf("************************************\n"); + + for (i = 0; i < 13; i++) { + *((unsigned char *)(CANADDR + 0x0010 + i)) = write_field[i]; + kill_time(10); + printf("write data %i: 0x%X , 0x%X \n", i, write_field[i], + *((unsigned char *)(CANADDR + 0x0010 + i))); + } } int test_read_frame_extended(unsigned char write_field[]) -{ - unsigned char read_field[13]; - int i = 0; - - for (i=0; i<13; i++) - { - read_field[i] = *((unsigned char *)(CANADDR+0x0010+i)); - } - - for (i=0; i<13; i++) - { - if (read_field[i] != write_field[i]) - { - return 0; - } - } - - return 1; +{ + unsigned char read_field[13]; + int i = 0; + + for (i = 0; i < 13; i++) { + read_field[i] = *((unsigned char *)(CANADDR + 0x0010 + i)); + } + + for (i = 0; i < 13; i++) { + if (read_field[i] != write_field[i]) { return 0; } + } + + return 1; } - - + main() { - int i; - - unsigned char frame_basic0[10] = {0xEA,0x28,0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0}; - - unsigned char frame_basic1[10] = {0xEB,0x28,0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0}; - - unsigned char frame_basic2[10] = {0xEC,0x28,0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0}; - - unsigned char frame_basic3[10] = {0xED,0x28,0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0}; - - unsigned char frame_extended[13] = {0x88,0xA6,0xB0,0x12,0x30,0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0}; - - - - unsigned char r_val; - - - init_can("Basic","normal"); - - - enable_irq_sff(); - - - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - release_receive_buffer(); - - printf("interrupt register 0x%X \n",interrupt_register); - - while(1) - { - - if ((interrupt_register & receive_interrupt) == 0) - { - kill_time(4000000); - printf("No data!\n"); + int i; + + unsigned char frame_basic0[10] = {0xEA, 0x28, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + unsigned char frame_basic1[10] = {0xEB, 0x28, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + unsigned char frame_basic2[10] = {0xEC, 0x28, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + unsigned char frame_basic3[10] = {0xED, 0x28, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + unsigned char frame_extended[13] = {0x88, 0xA6, 0xB0, 0x12, 0x30, 0x12, 0x34, + 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}; + + unsigned char r_val; + + init_can("Basic", "normal"); + + enable_irq_sff(); + + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + release_receive_buffer(); + + printf("interrupt register 0x%X \n", interrupt_register); + + while (1) { + + if ((interrupt_register & receive_interrupt) == 0) { + kill_time(4000000); + printf("No data!\n"); } - else - { - read_receive_buffer_basic(); - release_receive_buffer(); + else { + read_receive_buffer_basic(); + release_receive_buffer(); } } - } - - diff --git a/soft/leon3/grlib/software/greth/greth.c b/soft/leon3/grlib/software/greth/greth.c index b87efabf6b..450865183f 100644 --- a/soft/leon3/grlib/software/greth/greth.c +++ b/soft/leon3/grlib/software/greth/greth.c @@ -14,9 +14,9 @@ /* 2007-11-13: Simple Ethernet speed test added - Kristoffer Glembo */ /* 2007-11-13: GRETH BareC API added - Kristoffer Glembo */ +#include "greth_api.h" #include #include -#include "greth_api.h" /* Set to 1 if using GRETH_GBIT, otherwise 0 */ #define GRETH_GBIT 1 @@ -30,24 +30,25 @@ #define GRETH_ADDR 0x80000b00 /* Destination MAC address */ -#define DEST_MAC0 0x00 -#define DEST_MAC1 0x13 -#define DEST_MAC2 0x72 -#define DEST_MAC3 0xAE -#define DEST_MAC4 0x72 -#define DEST_MAC5 0x21 +#define DEST_MAC0 0x00 +#define DEST_MAC1 0x13 +#define DEST_MAC2 0x72 +#define DEST_MAC3 0xAE +#define DEST_MAC4 0x72 +#define DEST_MAC5 0x21 /* Source MAC address */ -#define SRC_MAC0 0xDE -#define SRC_MAC1 0xAD -#define SRC_MAC2 0xBE -#define SRC_MAC3 0xEF -#define SRC_MAC4 0x00 -#define SRC_MAC5 0x20 +#define SRC_MAC0 0xDE +#define SRC_MAC1 0xAD +#define SRC_MAC2 0xBE +#define SRC_MAC3 0xEF +#define SRC_MAC4 0x00 +#define SRC_MAC5 0x20 struct greth_info greth; -int main(void) { +int main(void) +{ unsigned long long i; unsigned char buf[1514]; @@ -55,7 +56,7 @@ int main(void) { unsigned long long datasize; double time, bitrate; - greth.regs = (greth_regs *) GRETH_ADDR; + greth.regs = (greth_regs *)GRETH_ADDR; /* Dest. addr */ buf[0] = DEST_MAC0; @@ -85,25 +86,23 @@ int main(void) { greth_init(&greth); - printf("\nSending 1500 Mbyte of data to %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", buf[0], buf[1], \ - buf[2], buf[3], \ - buf[4], buf[5]); + printf("\nSending 1500 Mbyte of data to %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", buf[0], buf[1], + buf[2], buf[3], buf[4], buf[5]); t1 = clock(); - i = 0; - while(i < (unsigned long long) 1024*1024) { + i = 0; + while (i < (unsigned long long)1024 * 1024) { /* greth_tx() returns 1 if a free descriptor is found, otherwise 0 */ i += greth_tx(1514, buf, &greth); - } t2 = clock(); - time = (double)(t2 - t1)/CLOCKS_PER_SEC; + time = (double)(t2 - t1) / CLOCKS_PER_SEC; printf("\nTime: %f\n", time); - datasize = (unsigned long long)1024*1024*1500*8; /* In bits */ - bitrate = (double) datasize/time; - printf("Bitrate: %f Mbps\n", bitrate/(1024*1024)); + datasize = (unsigned long long)1024 * 1024 * 1500 * 8; /* In bits */ + bitrate = (double)datasize / time; + printf("Bitrate: %f Mbps\n", bitrate / (1024 * 1024)); return 0; } diff --git a/soft/leon3/grlib/software/grpci2/grpci2api.c b/soft/leon3/grlib/software/grpci2/grpci2api.c index 7b12f95d9d..ac2f4bf513 100644 --- a/soft/leon3/grlib/software/grpci2/grpci2api.c +++ b/soft/leon3/grlib/software/grpci2/grpci2api.c @@ -1,190 +1,212 @@ #include "grpci2api.h" -static inline int loadmem(int addr){ - int tmp; - asm volatile (" lda [%1]1, %0 " - : "=r"(tmp) - : "r"(addr) - ); - return tmp; -}; - -unsigned int grpci2_tw(unsigned int data){ - return ((data & 0xff) << 24) | (((data >> 8) & 0xff) << 16) | (((data >> 16) & 0xff) << 8) | (((data >> 24) & 0xff)); +static inline int loadmem(int addr) +{ + int tmp; + asm volatile(" lda [%1]1, %0 " : "=r"(tmp) : "r"(addr)); + return tmp; +}; + +unsigned int grpci2_tw(unsigned int data) +{ + return ((data & 0xff) << 24) | (((data >> 8) & 0xff) << 16) | (((data >> 16) & 0xff) << 8) | + (((data >> 24) & 0xff)); } /* GRPCI2 Get Master/Target/DMA enabled ****************************************** */ - int grpci2_get_master(volatile struct grpci2regs* apb){ +int grpci2_get_master(volatile struct grpci2regs *apb) +{ return ((apb->status & GRPCI2_STA_MASTER) != 0); - }; +}; - int grpci2_get_target(volatile struct grpci2regs* apb){ +int grpci2_get_target(volatile struct grpci2regs *apb) +{ return ((apb->status & GRPCI2_STA_TARGET) != 0); - }; +}; - int grpci2_get_dma(volatile struct grpci2regs* apb){ +int grpci2_get_dma(volatile struct grpci2regs *apb) +{ return ((apb->status & GRPCI2_STA_DMA) != 0); - }; +}; /* GRPCI2 Set/Get AHB Master-to-PCI map ****************************************** */ - void grpci2_set_mstmap(volatile struct grpci2regs* apb, int mst, unsigned int addr){ +void grpci2_set_mstmap(volatile struct grpci2regs *apb, int mst, unsigned int addr) +{ apb->mst_to_pci[mst] = addr; - }; - - unsigned int grpci2_get_mstmap(volatile struct grpci2regs* apb, int mst){ +}; + +unsigned int grpci2_get_mstmap(volatile struct grpci2regs *apb, int mst) +{ return apb->mst_to_pci[mst]; - }; +}; /* GRPCI2 Set/Get Bus-endiannes ************************************************** */ - void grpci2_set_bus_litle_endian(volatile struct grpci2_pci_conf_space_regs* conf){ +void grpci2_set_bus_litle_endian(volatile struct grpci2_pci_conf_space_regs *conf) +{ conf->ext->ahbio_endiannes |= grpci2_tw(1); - }; - - void grpci2_set_bus_big_endian(volatile struct grpci2_pci_conf_space_regs* conf){ +}; + +void grpci2_set_bus_big_endian(volatile struct grpci2_pci_conf_space_regs *conf) +{ conf->ext->ahbio_endiannes &= grpci2_tw(0xfffffffe); - }; - - int grpci2_get_endian(volatile struct grpci2_pci_conf_space_regs* conf){ +}; + +int grpci2_get_endian(volatile struct grpci2_pci_conf_space_regs *conf) +{ return (grpci2_tw(conf->ext->ahbio_endiannes) & 1); - }; +}; /* GRPCI2 Set/Get BARMAP ********************************************************* */ - void grpci2_set_barmap(volatile struct grpci2_pci_conf_space_regs* conf, int bar, unsigned int addr){ +void grpci2_set_barmap(volatile struct grpci2_pci_conf_space_regs *conf, int bar, unsigned int addr) +{ conf->ext->bar_to_ahb[bar] = grpci2_tw(addr); - }; - - unsigned int grpci2_get_barmap(volatile struct grpci2_pci_conf_space_regs* conf, int bar){ +}; + +unsigned int grpci2_get_barmap(volatile struct grpci2_pci_conf_space_regs *conf, int bar) +{ return conf->ext->bar_to_ahb[bar]; - }; +}; /* GRPCI2 Set/Get BAR ************************************************************ */ - void grpci2_set_bar(volatile struct grpci2_pci_conf_space_regs* conf, int bar, unsigned int addr){ +void grpci2_set_bar(volatile struct grpci2_pci_conf_space_regs *conf, int bar, unsigned int addr) +{ conf->head->bar[bar] = grpci2_tw(addr); - }; - - unsigned int grpci2_get_bar(volatile struct grpci2_pci_conf_space_regs* conf, int bar){ +}; + +unsigned int grpci2_get_bar(volatile struct grpci2_pci_conf_space_regs *conf, int bar) +{ return conf->head->bar[bar]; - }; +}; /* GRPCI2 Set Latency Timer ****************************************************** */ - void grpci2_set_latency_timer(volatile struct grpci2_pci_conf_space_regs* conf, int timer){ - conf->head->lat_timer = grpci2_tw((grpci2_tw(conf->head->lat_timer) & 0xffff00ff) | (timer & 0xff) << 8); - }; +void grpci2_set_latency_timer(volatile struct grpci2_pci_conf_space_regs *conf, int timer) +{ + conf->head->lat_timer = + grpci2_tw((grpci2_tw(conf->head->lat_timer) & 0xffff00ff) | (timer & 0xff) << 8); +}; /* GRPCI2 Master Enable/Disable ************************************************** */ - void grpci2_mst_enable(volatile struct grpci2_pci_conf_space_regs* conf){ +void grpci2_mst_enable(volatile struct grpci2_pci_conf_space_regs *conf) +{ conf->head->sta_cmd |= grpci2_tw(0x4); - }; - - void grpci2_mst_disable(volatile struct grpci2_pci_conf_space_regs* conf){ +}; + +void grpci2_mst_disable(volatile struct grpci2_pci_conf_space_regs *conf) +{ conf->head->sta_cmd &= ~grpci2_tw(0x4); - }; - +}; + /* GRPCI2 Memory target Enable/Disable ******************************************* */ - void grpci2_mem_enable(volatile struct grpci2_pci_conf_space_regs* conf){ +void grpci2_mem_enable(volatile struct grpci2_pci_conf_space_regs *conf) +{ conf->head->sta_cmd |= grpci2_tw(0x2); - }; - - void grpci2_mem_disable(volatile struct grpci2_pci_conf_space_regs* conf){ +}; + +void grpci2_mem_disable(volatile struct grpci2_pci_conf_space_regs *conf) +{ conf->head->sta_cmd &= ~grpci2_tw(0x2); - }; - +}; + /* GRPCI2 IO target Enable/Disable *********************************************** */ - void grpci2_io_enable(volatile struct grpci2_pci_conf_space_regs* conf){ +void grpci2_io_enable(volatile struct grpci2_pci_conf_space_regs *conf) +{ conf->head->sta_cmd |= grpci2_tw(0x1); - }; - - void grpci2_io_disable(volatile struct grpci2_pci_conf_space_regs* conf){ +}; + +void grpci2_io_disable(volatile struct grpci2_pci_conf_space_regs *conf) +{ conf->head->sta_cmd &= ~grpci2_tw(0x1); - }; - +}; + /* GRPCI2 DMA Descriptors init *************************************************** */ - int grpci2_dma_desc_init(struct grpci2regs* apb, volatile unsigned int **chdesc, int irqen, - int num_ch, int ch_entry){ - int i,j; - struct grpci2_dma_ch_desc *ch = malloc(sizeof(struct grpci2_dma_ch_desc)*(num_ch+1)); - struct grpci2_dma_data_desc *ddesc = malloc(sizeof(struct grpci2_dma_data_desc)*(ch_entry*num_ch+1)); +int grpci2_dma_desc_init(struct grpci2regs *apb, volatile unsigned int **chdesc, int irqen, + int num_ch, int ch_entry) +{ + int i, j; + struct grpci2_dma_ch_desc *ch = malloc(sizeof(struct grpci2_dma_ch_desc) * (num_ch + 1)); + struct grpci2_dma_data_desc *ddesc = + malloc(sizeof(struct grpci2_dma_data_desc) * (ch_entry * num_ch + 1)); /*printf("ch: %p, desc: %p\n", ch, ddesc);*/ - if (((int)ch & 0xf) != 0) ch = (struct grpci2_dma_ch_desc*)((int)ch + (0x10 - (int)ch & 0xf)); - if (((int)ddesc & 0xf) != 0) ddesc = (struct grpci2_dma_data_desc*)((int)ddesc + (0x10 - (int)ddesc & 0xf)); + if (((int)ch & 0xf) != 0) ch = (struct grpci2_dma_ch_desc *)((int)ch + (0x10 - (int)ch & 0xf)); + if (((int)ddesc & 0xf) != 0) + ddesc = (struct grpci2_dma_data_desc *)((int)ddesc + (0x10 - (int)ddesc & 0xf)); /*printf("ch: %p, desc: %p\n", ch, ddesc);*/ - *chdesc = (int*)ch; + *chdesc = (int *)ch; /*printf("ch base: %08p\n", ch);*/ - for(i=0; ictrl = 0; - (ddesc + i*ch_entry + j)->paddr = 0; - (ddesc + i*ch_entry + j)->aaddr = 0; - if (j == ch_entry-1) (ddesc + i*ch_entry + j)->next = (int)(ddesc + i*ch_entry); - else (ddesc + i*ch_entry + j)->next = (int)(ddesc + i*ch_entry + j + 1); - } - - (ch + i)->ctrl = GRPCI2_DMA_CHDESC_EN | - ((i << GRPCI2_DMA_CHDESC_ID)& GRPCI2_DMA_CHDESC_ID_MASK) | - GRPCI2_DMA_DESC_TYPE_CH; - if (i == num_ch-1) (ch + i)->next = (int)ch; - else (ch + i)->next = (int)(ch + i + 1); - (ch + i)->desc = (int)(ddesc + i*ch_entry); - (ch + i)->res = 0; - - //desc[i] = (int*)(ddesc + i*CH_ENTRY); - //printf("datadesc[%d] base: %08p\n", i, desc[i]); + for (i = 0; i < num_ch; i++) { + for (j = 0; j < ch_entry; j++) { + (ddesc + i * ch_entry + j)->ctrl = 0; + (ddesc + i * ch_entry + j)->paddr = 0; + (ddesc + i * ch_entry + j)->aaddr = 0; + if (j == ch_entry - 1) (ddesc + i * ch_entry + j)->next = (int)(ddesc + i * ch_entry); + else + (ddesc + i * ch_entry + j)->next = (int)(ddesc + i * ch_entry + j + 1); + } + + (ch + i)->ctrl = GRPCI2_DMA_CHDESC_EN | + ((i << GRPCI2_DMA_CHDESC_ID) & GRPCI2_DMA_CHDESC_ID_MASK) | GRPCI2_DMA_DESC_TYPE_CH; + if (i == num_ch - 1) (ch + i)->next = (int)ch; + else + (ch + i)->next = (int)(ch + i + 1); + (ch + i)->desc = (int)(ddesc + i * ch_entry); + (ch + i)->res = 0; + + // desc[i] = (int*)(ddesc + i*CH_ENTRY); + // printf("datadesc[%d] base: %08p\n", i, desc[i]); }; - apb->dma_ctrl = GRPCI2_DMACTRL_GUARD | GRPCI2_DMACTRL_MABORT | GRPCI2_DMACTRL_TABORT | - GRPCI2_DMACTRL_PERR | GRPCI2_DMACTRL_AHBDATA_ERR | GRPCI2_DMACTRL_AHBDESC_ERR | - (((num_ch-1) << GRPCI2_DMACTRL_NUMCH) & GRPCI2_DMACTRL_NUMCH_MASK) | - (irqen*GRPCI2_DMACTRL_IRQEN); + apb->dma_ctrl = GRPCI2_DMACTRL_GUARD | GRPCI2_DMACTRL_MABORT | GRPCI2_DMACTRL_TABORT | + GRPCI2_DMACTRL_PERR | GRPCI2_DMACTRL_AHBDATA_ERR | GRPCI2_DMACTRL_AHBDESC_ERR | + (((num_ch - 1) << GRPCI2_DMACTRL_NUMCH) & GRPCI2_DMACTRL_NUMCH_MASK) | + (irqen * GRPCI2_DMACTRL_IRQEN); apb->dma_desc = (int)ch; apb->status = GRPCI2_STA_IRQ_DMAINT | GRPCI2_STA_IRQ_DMAERR; - - }; +}; /* ******************************************************************************* */ /* GRPCI2 DMA add transfer ******************************************************* */ - int grpci2_dma_add(struct grpci2regs* apb, volatile unsigned int **ddesc, unsigned int paddr, - unsigned int aaddr, int dir, int ien, int length){ - struct grpci2_dma_data_desc *desc = (struct grpci2_dma_data_desc*)*ddesc; - unsigned int tmp = loadmem((int)desc); - - /*printf("desc: %08X, ctrl: %08X, paddr: %08X, aaddr: %08X, next: %08X\n", - (desc), (desc)->ctrl, (desc)->paddr, (desc)->aaddr, (desc)->next); /**/ - - //if ((desc->ctrl & GRPCI2_DMA_DESC_EN) == 0){ - //printf("desc-ctrl: 0x%08X 0x%08X\n", tmp, desc->ctrl); - if ((tmp & GRPCI2_DMA_DESC_EN) == 0){ - desc->paddr = paddr; - desc->aaddr = aaddr; - desc->ctrl = GRPCI2_DMA_DESC_EN | GRPCI2_DMA_DESC_IRQEN*ien | GRPCI2_DMA_DESC_DIR*dir | - GRPCI2_DMA_DESC_TYPE_DATA | - (length & GRPCI2_DMA_DESC_LENGTH_MASK) << GRPCI2_DMA_DESC_LENGTH; - *ddesc = (int*)desc->next; - apb->dma_ctrl = (apb->dma_ctrl & GRPCI2_DMACTRL_NUMCH_MASK) | - (apb->dma_ctrl & GRPCI2_DMACTRL_IRQEN) | GRPCI2_DMACTRL_EN; - - /*printf("desc: %08X, ctrl: %08X, paddr: %08X, aaddr: %08X, next: %08X\n", +int grpci2_dma_add(struct grpci2regs *apb, volatile unsigned int **ddesc, unsigned int paddr, + unsigned int aaddr, int dir, int ien, int length) +{ + struct grpci2_dma_data_desc *desc = (struct grpci2_dma_data_desc *)*ddesc; + unsigned int tmp = loadmem((int)desc); + + /*printf("desc: %08X, ctrl: %08X, paddr: %08X, aaddr: %08X, next: %08X\n", (desc), (desc)->ctrl, (desc)->paddr, (desc)->aaddr, (desc)->next); /**/ - return 0; - }else{ - return -1; - }; - }; + // if ((desc->ctrl & GRPCI2_DMA_DESC_EN) == 0){ + // printf("desc-ctrl: 0x%08X 0x%08X\n", tmp, desc->ctrl); + if ((tmp & GRPCI2_DMA_DESC_EN) == 0) { + desc->paddr = paddr; + desc->aaddr = aaddr; + desc->ctrl = GRPCI2_DMA_DESC_EN | GRPCI2_DMA_DESC_IRQEN * ien | GRPCI2_DMA_DESC_DIR * dir | + GRPCI2_DMA_DESC_TYPE_DATA | + (length & GRPCI2_DMA_DESC_LENGTH_MASK) << GRPCI2_DMA_DESC_LENGTH; + *ddesc = (int *)desc->next; + apb->dma_ctrl = (apb->dma_ctrl & GRPCI2_DMACTRL_NUMCH_MASK) | + (apb->dma_ctrl & GRPCI2_DMACTRL_IRQEN) | GRPCI2_DMACTRL_EN; + + /*printf("desc: %08X, ctrl: %08X, paddr: %08X, aaddr: %08X, next: %08X\n", + (desc), (desc)->ctrl, (desc)->paddr, (desc)->aaddr, (desc)->next); /**/ + return 0; + } + else { + return -1; + }; +}; /* ******************************************************************************* */ /* GRPCI2 DMA check transfer ******************************************************* */ - unsigned int grpci2_dma_check(volatile unsigned int **ddesc){ - struct grpci2_dma_data_desc *desc = (struct grpci2_dma_data_desc*)*ddesc; +unsigned int grpci2_dma_check(volatile unsigned int **ddesc) +{ + struct grpci2_dma_data_desc *desc = (struct grpci2_dma_data_desc *)*ddesc; unsigned int res; res = loadmem((int)desc); - - if (!(res & GRPCI2_DMA_DESC_EN)) { - *ddesc = (int*)desc->next; - }; - return res; - }; + if (!(res & GRPCI2_DMA_DESC_EN)) { *ddesc = (int *)desc->next; }; + return res; +}; diff --git a/soft/leon3/grlib/software/leon3/amba.c b/soft/leon3/grlib/software/leon3/amba.c index 41af529132..8e6ca00ceb 100644 --- a/soft/leon3/grlib/software/leon3/amba.c +++ b/soft/leon3/grlib/software/leon3/amba.c @@ -1,34 +1,34 @@ #include "amba.h" -struct ahbpp_type *ahbpp = (struct ahbpp_type *) 0xFFFFF000; -struct apbpp_type *apbpp = (struct apbpp_type *) 0x800FF000; +struct ahbpp_type *ahbpp = (struct ahbpp_type *)0xFFFFF000; +struct apbpp_type *apbpp = (struct apbpp_type *)0x800FF000; find_ahb_slv(int id, struct ambadev *dev) { -struct ambadev *ahbdevpp; -int i, j; - for (i=0; i> 12) == id) { - ahbdevpp->id = id; - ahbdevpp->irq = ahbpp[i].cfg[0] & PPIRQMASK; - ahbdevpp->ppstart = (int) &ahbpp[i]; - for (j = 0; j < 4; j++) { - switch (ahbpp[i].mem[0] & 0x0F) { - case 2: - ahbdevpp->start[j] = ahbpp[i].mem[j] & PPAHBMASK; - ahbdevpp->end[j] = ahbdevpp->start[j] + - ((~(ahbpp[i].mem[j] << 16)) + 0x100000) & PPAHBMASK; - case 3: - ahbdevpp->start[j] = ((int) ahbpp) + - (ahbpp[i].mem[j] & PPAHBMASK) >> 12; - ahbdevpp->end[j] = ahbdevpp->start[j] + - (((~(ahbpp[i].mem[j] << 16)) + 0x100000) & PPAHBMASK) >> 12; - } - } - break; - } + struct ambadev *ahbdevpp; + int i, j; + for (i = 0; i < NAHBSLV; i++) { + if ((ahbpp[i].cfg[0] >> 12) == id) { + ahbdevpp->id = id; + ahbdevpp->irq = ahbpp[i].cfg[0] & PPIRQMASK; + ahbdevpp->ppstart = (int)&ahbpp[i]; + for (j = 0; j < 4; j++) { + switch (ahbpp[i].mem[0] & 0x0F) { + case 2: + ahbdevpp->start[j] = ahbpp[i].mem[j] & PPAHBMASK; + ahbdevpp->end[j] = + ahbdevpp->start[j] + ((~(ahbpp[i].mem[j] << 16)) + 0x100000) & + PPAHBMASK; + case 3: + ahbdevpp->start[j] = ((int)ahbpp) + (ahbpp[i].mem[j] & PPAHBMASK) >> 12; + ahbdevpp->end[j] = ahbdevpp->start[j] + + (((~(ahbpp[i].mem[j] << 16)) + 0x100000) & PPAHBMASK) >> + 12; + } + } + break; + } } - return(i/NAHBSLV); + return (i / NAHBSLV); } - diff --git a/tools/accgen/templates/catapult_hls/inc/accelerator.hpp b/tools/accgen/templates/catapult_hls/inc/accelerator.hpp old mode 100755 new mode 100644 index 89d6257416..e22f100e23 --- a/tools/accgen/templates/catapult_hls/inc/accelerator.hpp +++ b/tools/accgen/templates/catapult_hls/inc/accelerator.hpp @@ -6,144 +6,135 @@ #pragma once -#include "mem_wrap.hpp" #include "_data_types.hpp" #include "_specs.hpp" #include "_conf_info.hpp" +#include "mem_wrap.hpp" #define __round_mask(x, y) ((y)-1) -#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) +#define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1) SC_MODULE() { -public: - sc_in CCS_INIT_S1(clk); - sc_in CCS_INIT_S1(rst); - sc_out CCS_INIT_S1(acc_done); - - Connections::In CCS_INIT_S1(conf_info); - Connections::In< ac_int > CCS_INIT_S1(dma_read_chnl); - Connections::Out< ac_int > CCS_INIT_S1(dma_write_chnl); - Connections::Out CCS_INIT_S1(dma_read_ctrl); - Connections::Out CCS_INIT_S1(dma_write_ctrl); - - void config(void); - void load(void); - void compute_dataReq(void); - void compute(void); - void store_dataReq(void); - void store(void); - - SC_CTOR(): plm_in_ping("plm_in_ping"), plm_in_pong("plm_in_pong"), plm_out_ping("plm_out_ping"), plm_out_pong("plm_out_pong"){ - - SC_THREAD(config); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(load); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(compute_dataReq); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(compute); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(store_dataReq); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - SC_THREAD(store); - sensitive << clk.pos(); - async_reset_signal_is(rst, false); - - plm_in_ping.clk(clk); - plm_in_ping.rst(rst); - plm_in_ping.write_req(in_ping_w); - plm_in_ping.read_req(in_ping_ra); - plm_in_ping.read_rsp(in_ping_rd); - - plm_in_pong.clk(clk); - plm_in_pong.rst(rst); - plm_in_pong.write_req(in_pong_w); - plm_in_pong.read_req(in_pong_ra); - plm_in_pong.read_rsp(in_pong_rd); - - plm_out_ping.clk(clk); - plm_out_ping.rst(rst); - plm_out_ping.write_req(out_ping_w); - plm_out_ping.read_req(out_ping_ra); - plm_out_ping.read_rsp(out_ping_rd); - - plm_out_pong.clk(clk); - plm_out_pong.rst(rst); - plm_out_pong.write_req(out_pong_w); - plm_out_pong.read_req(out_pong_ra); - plm_out_pong.read_rsp(out_pong_rd); + public: + sc_in CCS_INIT_S1(clk); + sc_in CCS_INIT_S1(rst); + sc_out CCS_INIT_S1(acc_done); + + Connections::In CCS_INIT_S1(conf_info); + Connections::In> CCS_INIT_S1(dma_read_chnl); + Connections::Out> CCS_INIT_S1(dma_write_chnl); + Connections::Out CCS_INIT_S1(dma_read_ctrl); + Connections::Out CCS_INIT_S1(dma_write_ctrl); + + void config(void); + void load(void); + void compute_dataReq(void); + void compute(void); + void store_dataReq(void); + void store(void); + + SC_CTOR() : + plm_in_ping("plm_in_ping"), plm_in_pong("plm_in_pong"), plm_out_ping("plm_out_ping"), + plm_out_pong("plm_out_pong") + { + + SC_THREAD(config); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(load); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(compute_dataReq); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(compute); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(store_dataReq); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + SC_THREAD(store); + sensitive << clk.pos(); + async_reset_signal_is(rst, false); + + plm_in_ping.clk(clk); + plm_in_ping.rst(rst); + plm_in_ping.write_req(in_ping_w); + plm_in_ping.read_req(in_ping_ra); + plm_in_ping.read_rsp(in_ping_rd); + + plm_in_pong.clk(clk); + plm_in_pong.rst(rst); + plm_in_pong.write_req(in_pong_w); + plm_in_pong.read_req(in_pong_ra); + plm_in_pong.read_rsp(in_pong_rd); + + plm_out_ping.clk(clk); + plm_out_ping.rst(rst); + plm_out_ping.write_req(out_ping_w); + plm_out_ping.read_req(out_ping_ra); + plm_out_ping.read_rsp(out_ping_rd); + + plm_out_pong.clk(clk); + plm_out_pong.rst(rst); + plm_out_pong.write_req(out_pong_w); + plm_out_pong.read_req(out_pong_ra); + plm_out_pong.read_rsp(out_pong_rd); } - Connections::SyncChannel CCS_INIT_S1(sync12); - Connections::SyncChannel CCS_INIT_S1(sync12b); - Connections::SyncChannel CCS_INIT_S1(sync23); - Connections::SyncChannel CCS_INIT_S1(sync2b3); - Connections::SyncChannel CCS_INIT_S1(sync23b); - Connections::SyncChannel CCS_INIT_S1(sync2b3b); - - Connections::Combinational CCS_INIT_S1(sync01); - Connections::Combinational CCS_INIT_S1(sync02); - Connections::Combinational CCS_INIT_S1(sync02b); - Connections::Combinational CCS_INIT_S1(sync03); - Connections::Combinational CCS_INIT_S1(sync03b); - - Connections::Combinational CCS_INIT_S1(conf1); - Connections::Combinational CCS_INIT_S1(conf2); - Connections::Combinational CCS_INIT_S1(conf2b); - Connections::Combinational CCS_INIT_S1(conf3); - Connections::Combinational CCS_INIT_S1(conf3b); - - mem_wrap, - plm_RRq, - plm_RRs> CCS_INIT_S1(plm_in_ping); - mem_wrap, - plm_RRq, - plm_RRs> CCS_INIT_S1(plm_in_pong); - mem_wrap, - plm_RRq, - plm_RRs> CCS_INIT_S1(plm_out_ping); - mem_wrap, - plm_RRq, - plm_RRs> CCS_INIT_S1(plm_out_pong); - - Connections::Combinational> in_ping_w; - Connections::Combinational> in_ping_ra; - Connections::Combinational> in_ping_rd; - - Connections::Combinational> in_pong_w; - Connections::Combinational> in_pong_ra; - Connections::Combinational> in_pong_rd; - - Connections::Combinational> out_ping_w; - Connections::Combinational> out_ping_ra; - Connections::Combinational> out_ping_rd; - - Connections::Combinational> out_pong_w; - Connections::Combinational> out_pong_ra; - Connections::Combinational> out_pong_rd; + Connections::SyncChannel CCS_INIT_S1(sync12); + Connections::SyncChannel CCS_INIT_S1(sync12b); + Connections::SyncChannel CCS_INIT_S1(sync23); + Connections::SyncChannel CCS_INIT_S1(sync2b3); + Connections::SyncChannel CCS_INIT_S1(sync23b); + Connections::SyncChannel CCS_INIT_S1(sync2b3b); + + Connections::Combinational CCS_INIT_S1(sync01); + Connections::Combinational CCS_INIT_S1(sync02); + Connections::Combinational CCS_INIT_S1(sync02b); + Connections::Combinational CCS_INIT_S1(sync03); + Connections::Combinational CCS_INIT_S1(sync03b); + + Connections::Combinational CCS_INIT_S1(conf1); + Connections::Combinational CCS_INIT_S1(conf2); + Connections::Combinational CCS_INIT_S1(conf2b); + Connections::Combinational CCS_INIT_S1(conf3); + Connections::Combinational CCS_INIT_S1(conf3b); + + mem_wrap, + plm_RRq, plm_RRs> + CCS_INIT_S1(plm_in_ping); + mem_wrap, + plm_RRq, plm_RRs> + CCS_INIT_S1(plm_in_pong); + mem_wrap, + plm_RRq, plm_RRs> + CCS_INIT_S1(plm_out_ping); + mem_wrap, + plm_RRq, plm_RRs> + CCS_INIT_S1(plm_out_pong); + + Connections::Combinational> in_ping_w; + Connections::Combinational> in_ping_ra; + Connections::Combinational> in_ping_rd; + + Connections::Combinational> in_pong_w; + Connections::Combinational> in_pong_ra; + Connections::Combinational> in_pong_rd; + + Connections::Combinational> out_ping_w; + Connections::Combinational> out_ping_ra; + Connections::Combinational> out_ping_rd; + + Connections::Combinational> out_pong_w; + Connections::Combinational> out_pong_ra; + Connections::Combinational> out_pong_rd; }; #endif diff --git a/tools/accgen/templates/catapult_hls/inc/mem_bank/DUAL_PORT_RBW.v b/tools/accgen/templates/catapult_hls/inc/mem_bank/DUAL_PORT_RBW.v index 72683e00b2..1ca03c177c 100755 --- a/tools/accgen/templates/catapult_hls/inc/mem_bank/DUAL_PORT_RBW.v +++ b/tools/accgen/templates/catapult_hls/inc/mem_bank/DUAL_PORT_RBW.v @@ -2,32 +2,40 @@ // SPDX-License-Identifier: Apache-2.0 module DUAL_PORT_RBW #( - parameter AddressSz = 32 , - parameter data_width = 8 , - parameter Sz = 128 -)( clk,clk_en,din,qout,r_adr,w_adr,w_en); + parameter AddressSz = 32, + parameter data_width = 8, + parameter Sz = 128 +) ( + clk, + clk_en, + din, + qout, + r_adr, + w_adr, + w_en +); - input clk; - input clk_en; - input [data_width-1:0] din; - output [data_width-1:0] qout; - input [AddressSz-1:0] r_adr; - input [AddressSz-1:0] w_adr; - input w_en; + input clk; + input clk_en; + input [data_width-1:0] din; + output [data_width-1:0] qout; + input [AddressSz-1:0] r_adr; + input [AddressSz-1:0] w_adr; + input w_en; - (* ram_style = "block" *) - reg [data_width-1:0] out; - reg [data_width-1:0] arr [Sz-1:0]; + (* ram_style = "block" *) + reg [data_width-1:0] out; + reg [data_width-1:0] arr [Sz-1:0]; - always @(posedge clk) begin - if (clk_en) begin - out <= arr[r_adr]; - if (w_en) begin - arr[w_adr] <= din; - end - end - end + always @(posedge clk) begin + if (clk_en) begin + out <= arr[r_adr]; + if (w_en) begin + arr[w_adr] <= din; + end + end + end - assign qout = out; + assign qout = out; endmodule diff --git a/tools/accgen/templates/catapult_hls/src/accelerator.cpp b/tools/accgen/templates/catapult_hls/src/accelerator.cpp index 690d0c0b3e..7643d12bc4 100644 --- a/tools/accgen/templates/catapult_hls/src/accelerator.cpp +++ b/tools/accgen/templates/catapult_hls/src/accelerator.cpp @@ -1,10 +1,11 @@ -//Copyright (c) 2011-2024 Columbia University, System Level Design Group -//SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2011-2024 Columbia University, System Level Design Group +// SPDX-License-Identifier: Apache-2.0 #include ".hpp" #include -void :: config() { +void::config() +{ conf_info.Reset(); conf1.ResetWrite(); conf2.ResetWrite(); @@ -20,7 +21,7 @@ void :: config() { wait(); - while(1) { + while (1) { conf_info_t conf_di = conf_info.Pop(); conf1.Push(conf_di); @@ -34,13 +35,11 @@ void :: config() { sync02b.Push(1); sync03.Push(1); sync03b.Push(1); - } } - - -void :: load() { +void::load() +{ bool ping_pong = false; dma_read_chnl.Reset(); dma_read_ctrl.Reset(); @@ -56,29 +55,27 @@ void :: load() { wait(); - while(1) { + while (1) { sync01.Pop(); - bool ping = true; + bool ping = true; uint32_t offset = 0; - conf_info_t conf=conf1.Pop(); + conf_info_t conf = conf1.Pop(); /* <<--local-params-->> */ // Batching - for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) - { + for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) { wait(); #if (DMA_WORD_PER_BEAT == 0) uint32_t len = /* <<--data_in_size-->> */; #else - uint32_t len=round_up(/* <<--data_in_size-->> */, DMA_WORD_PER_BEAT); + uint32_t len = round_up(/* <<--data_in_size-->> */, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = len; rem > 0; rem -= PLM_IN_WORD) - { + for (int rem = len; rem > 0; rem -= PLM_IN_WORD) { uint32_t len1 = rem > PLM_IN_WORD ? PLM_IN_WORD : rem; #if (DMA_WORD_PER_BEAT == 0) @@ -87,50 +84,45 @@ void :: load() { dma_info_t dma_info(offset / DMA_WORD_PER_BEAT, len1 / DMA_WORD_PER_BEAT, DMA_SIZE); #endif - offset +=len1; + offset += len1; dma_read_ctrl.Push(dma_info); #if (DMA_WORD_PER_BEAT == 0) - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stallt_mode flush - for (uint32_t i =0; i < len1; i++) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stallt_mode flush + for (uint32_t i = 0; i < len1; i++) { ac_int dataBv; - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stallt_mode flush - for (uint32_t k=0; k< DMA_BEAT_PER_WORD; k++) - { - ac_int data_m=dma_read_chnl.Pop(); - dataBv.set_slc(k*DMA_WIDTH, data_m); + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stallt_mode flush + for (uint32_t k = 0; k < DMA_BEAT_PER_WORD; k++) { + ac_int data_m = dma_read_chnl.Pop(); + dataBv.set_slc(k * DMA_WIDTH, data_m); } - plm_WR wreq; - wreq.indx[0]=i; - wreq.data[0]=dataBv; + plm_WR wreq; + wreq.indx[0] = i; + wreq.data[0] = dataBv; - if (ping_pong) - in_ping_w.Push(wreq); + if (ping_pong) in_ping_w.Push(wreq); else in_pong_w.Push(wreq); } #else - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stallt_mode flush - for (uint32_t i=0; i < len1; i+= DMA_WORD_PER_BEAT) { - DMA_WORD data_dma=dma_read_chnl.Pop(); - - plm_WR wreq; - - #pragma hls_unroll yes - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { - wreq.indx[k]=i+k; - wreq.data[k]=data_dma.slc(k * DATA_WIDTH); + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stallt_mode flush + for (uint32_t i = 0; i < len1; i += DMA_WORD_PER_BEAT) { + DMA_WORD data_dma = dma_read_chnl.Pop(); + + plm_WR wreq; + + #pragma hls_unroll yes + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + wreq.indx[k] = i + k; + wreq.data[k] = data_dma.slc(k * DATA_WIDTH); } - if (ping_pong) - in_ping_w.Push(wreq); + if (ping_pong) in_ping_w.Push(wreq); else in_pong_w.Push(wreq); } @@ -146,7 +138,8 @@ void :: load() { } } -void ::compute_dataReq() { +void::compute_dataReq() +{ bool ping_pong = false; sync12.reset_sync_in(); @@ -161,45 +154,41 @@ void ::compute_dataReq() { wait(); - while(1) { + while (1) { sync02.Pop(); - conf_info_t conf=conf2.Pop(); + conf_info_t conf = conf2.Pop(); /* <<--local-params-->> */ // Batching - for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) - { + for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) { wait(); // Chunking - for (int in_rem = /* <<--data_in_size-->> */ ; in_rem > 0; in_rem -= PLM_IN_WORD) - { + for (int in_rem = /* <<--data_in_size-->> */; in_rem > 0; in_rem -= PLM_IN_WORD) { - uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; + uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; sync12.sync_in(); - //Send read memory requests to input PLM - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i=0; i < in_len; i++) { +// Send read memory requests to input PLM +#pragma hls_pipeline_init_interval 1 +#pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < in_len; i++) { wait(); FPDATA_WORD op[2]; - plm_RRq rreq; + plm_RRq rreq; - rreq.indx[0]=i; + rreq.indx[0] = i; - if (ping_pong) - in_ping_ra.Push(rreq); + if (ping_pong) in_ping_ra.Push(rreq); else in_pong_ra.Push(rreq); - } sync23.sync_out(); @@ -210,9 +199,10 @@ void ::compute_dataReq() { } } -void :: compute() { +void::compute() +{ - bool ping_pong = false; + bool ping_pong = false; bool out_ping_pong = false; sync12b.reset_sync_in(); sync2b3.reset_sync_out(); @@ -228,50 +218,45 @@ void :: compute() { wait(); - while(1) { + while (1) { sync02b.Pop(); - conf_info_t conf=conf2b.Pop(); + conf_info_t conf = conf2b.Pop(); /* <<--local-params-->> */ // Batching - for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) - { + for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) { wait(); uint32_t in_length = /* <<--data_in_size-->> */; // Chunking - for (int in_rem = in_length; in_rem > 0; in_rem -= PLM_IN_WORD) - { + for (int in_rem = in_length; in_rem > 0; in_rem -= PLM_IN_WORD) { - uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; + uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; sync12b.sync_in(); // Compute Kernel - for (uint32_t i=0; i < in_len; i+=1) { + for (uint32_t i = 0; i < in_len; i += 1) { FPDATA_WORD op; - if (ping_pong) - op=in_ping_rd.Pop().data[0]; + if (ping_pong) op = in_ping_rd.Pop().data[0]; else - op=in_pong_rd.Pop().data[0]; + op = in_pong_rd.Pop().data[0]; plm_WR rreq; - rreq.indx[0]=i; - rreq.data[0]=op; + rreq.indx[0] = i; + rreq.data[0] = op; - if (i < /* <<--data_out_size-->> */){ + if (i < /* <<--data_out_size-->> */) { - if (out_ping_pong) - out_ping_w.Push(rreq); + if (out_ping_pong) out_ping_w.Push(rreq); else out_pong_w.Push(rreq); - } } // End Compute Kernel @@ -287,7 +272,8 @@ void :: compute() { } } -void :: store_dataReq() { +void::store_dataReq() +{ bool ping_pong = false; sync23.reset_sync_in(); @@ -301,17 +287,16 @@ void :: store_dataReq() { wait(); - while(1) { + while (1) { sync03.Pop(); - conf_info_t conf=conf3.Pop(); + conf_info_t conf = conf3.Pop(); /* <<--local-params-->> */ // Batching - for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) - { + for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) { wait(); #if (DMA_WORD_PER_BEAT == 0) @@ -320,8 +305,7 @@ void :: store_dataReq() { uint32_t length = round_up(/* <<--data_out_size-->> */, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) { sync23.sync_in(); sync2b3.sync_in(); @@ -329,36 +313,30 @@ void :: store_dataReq() { uint32_t len = rem > PLM_OUT_WORD ? PLM_OUT_WORD : rem; #if (DMA_WORD_PER_BEAT == 0) - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i = 0; i < len; i++) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < len; i++) { FPDATA_WORD dataBv; - plm_RRq rreq; - rreq.indx[0]=i; + plm_RRq rreq; + rreq.indx[0] = i; - if(ping_pong) - out_ping_ra.Push(rreq); + if (ping_pong) out_ping_ra.Push(rreq); else out_pong_ra.Push(rreq); - } #else - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { DMA_WORD dataBv; - plm_RRq rreq; - for (int k = 0; k < DMA_WORD_PER_BEAT; k++) - { - rreq.indx[k]=i+k; + plm_RRq rreq; + for (int k = 0; k < DMA_WORD_PER_BEAT; k++) { + rreq.indx[k] = i + k; } - if(ping_pong) - out_ping_ra.Push(rreq); + if (ping_pong) out_ping_ra.Push(rreq); else out_pong_ra.Push(rreq); } @@ -370,8 +348,8 @@ void :: store_dataReq() { } } - -void :: store() { +void::store() +{ bool ping_pong = false; dma_write_chnl.Reset(); @@ -390,35 +368,33 @@ void :: store() { wait(); - while(1) { + while (1) { sync03b.Pop(); - conf_info_t conf=conf3b.Pop(); + conf_info_t conf = conf3b.Pop(); /* <<--local-params-->> */ #if (DMA_WORD_PER_BEAT == 0) - uint32_t store_offset = /* <<--data_in_size-->> */ * /* <<--number of transfers-->> */; + uint32_t store_offset = /* <<--data_in_size-->> */ */* <<--number of transfers-->> */; #else - uint32_t store_offset = round_up(/* <<--data_in_size-->> */, DMA_WORD_PER_BEAT) * /* <<--number of transfers-->> */; + uint32_t store_offset = round_up(/* <<--data_in_size-->> */, + DMA_WORD_PER_BEAT) * /* <<--number of transfers-->> */; #endif uint32_t offset = store_offset; // Batching - for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) - { + for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) { wait(); - #if (DMA_WORD_PER_BEAT == 0) uint32_t length = /* <<--data_out_size-->> */; #else uint32_t length = round_up(/* <<--data_out_size-->> */, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) { sync23b.sync_in(); sync2b3b.sync_in(); @@ -435,41 +411,34 @@ void :: store() { dma_write_ctrl.Push(dma_info); #if (DMA_WORD_PER_BEAT == 0) - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i = 0; i < len; i++) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < len; i++) { FPDATA_WORD dataBv; - if(ping_pong) - dataBv=out_ping_rd.Pop().data[0]; + if (ping_pong) dataBv = out_ping_rd.Pop().data[0]; else - dataBv=out_pong_rd.Pop().data[0]; + dataBv = out_pong_rd.Pop().data[0]; - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode flush - for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) - { - dma_write_chnl.Push(dataBv.slc(k*DMA_WIDTH)); + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode flush + for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) { + dma_write_chnl.Push(dataBv.slc(k * DMA_WIDTH)); } - } #else - #pragma hls_pipeline_init_interval 1 - #pragma pipeline_stall_mode stall - for (uint32_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + #pragma hls_pipeline_init_interval 1 + #pragma pipeline_stall_mode stall + for (uint32_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { DMA_WORD dataBv; - if(ping_pong) - rrsp=out_ping_rd.Pop(); + if (ping_pong) rrsp = out_ping_rd.Pop(); else - rrsp=out_pong_rd.Pop(); + rrsp = out_pong_rd.Pop(); - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { - dataBv.set_slc(k *DATA_WIDTH,rrsp.data[k]); + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { + dataBv.set_slc(k * DATA_WIDTH, rrsp.data[k]); } dma_write_chnl.Push(dataBv); @@ -481,10 +450,8 @@ void :: store() { } wait(); - acc_done.write(true); wait(); + acc_done.write(true); + wait(); acc_done.write(false); } } - - - diff --git a/tools/accgen/templates/catapult_hls/tb/sc_main.cpp b/tools/accgen/templates/catapult_hls/tb/sc_main.cpp old mode 100755 new mode 100644 index 3403dd8456..488a7b4de9 --- a/tools/accgen/templates/catapult_hls/tb/sc_main.cpp +++ b/tools/accgen/templates/catapult_hls/tb/sc_main.cpp @@ -1,13 +1,13 @@ -//Copyright (c) 2011-2024 Columbia University, System Level Design Group -//SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2011-2024 Columbia University, System Level Design Group +// SPDX-License-Identifier: Apache-2.0 #include "system.hpp" -#include #include +#include sc_trace_file *trace_file_ptr; -int sc_main (int argc, char *argv[]) +int sc_main(int argc, char *argv[]) { sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); sc_report_handler::set_actions(SC_ERROR, SC_DISPLAY); @@ -19,12 +19,10 @@ int sc_main (int argc, char *argv[]) sc_start(); int errcnt = sc_report_handler::get_count(SC_ERROR); - if (errcnt > 0) { - std::cout << "Simulation FAILED\n"; - } else { + if (errcnt > 0) { std::cout << "Simulation FAILED\n"; } + else { std::cout << "Simulation PASSED\n"; } return errcnt; // return 0 for passed } - diff --git a/tools/accgen/templates/drivers/baremetal/accelerator.c b/tools/accgen/templates/drivers/baremetal/accelerator.c index 6acba65c54..60c8c45b57 100644 --- a/tools/accgen/templates/drivers/baremetal/accelerator.c +++ b/tools/accgen/templates/drivers/baremetal/accelerator.c @@ -3,7 +3,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -12,13 +12,9 @@ typedef /* <<--token-type-->> */ token_t; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} - +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } -#define SLD_ /* <<--id-->> */ +#define SLD_ /* <<--id-->> */ #define DEV_NAME "sld," /* <<--params-->> */ @@ -34,173 +30,166 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ - static int validate_buf(token_t *out, token_t *gold) { - int i; - int j; - unsigned errors = 0; + int i; + int j; + unsigned errors = 0; - for (i = 0; i < /* <<--number of transfers-->> */; i++) - for (j = 0; j < /* <<--data_out_size-->> */; j++) - if (gold[i * out_words_adj + j] != out[i * out_words_adj + j]) - errors++; + for (i = 0; i < /* <<--number of transfers-->> */; i++) + for (j = 0; j < /* <<--data_out_size-->> */; j++) + if (gold[i * out_words_adj + j] != out[i * out_words_adj + j]) errors++; - return errors; + return errors; } - -static void init_buf (token_t *in, token_t * gold) +static void init_buf(token_t *in, token_t *gold) { - int i; - int j; + int i; + int j; - for (i = 0; i < /* <<--number of transfers-->> */; i++) - for (j = 0; j < /* <<--data_in_size-->> */; j++) - in[i * in_words_adj + j] = (token_t) j; + for (i = 0; i < /* <<--number of transfers-->> */; i++) + for (j = 0; j < /* <<--data_in_size-->> */; j++) + in[i * in_words_adj + j] = (token_t)j; - for (i = 0; i < /* <<--number of transfers-->> */; i++) - for (j = 0; j < /* <<--data_out_size-->> */; j++) - gold[i * out_words_adj + j] = (token_t) j; + for (i = 0; i < /* <<--number of transfers-->> */; i++) + for (j = 0; j < /* <<--data_out_size-->> */; j++) + gold[i * out_words_adj + j] = (token_t)j; } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable; - token_t *mem; - token_t *gold; - unsigned errors = 0; - unsigned coherence; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = /* <<--data_in_size-->> */; - out_words_adj = /* <<--data_out_size-->> */; - } else { - in_words_adj = round_up(/* <<--data_in_size-->> */, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(/* <<--data_out_size-->> */, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (/* <<--number of transfers-->> */); - out_len = out_words_adj * (/* <<--number of transfers-->> */); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = /* <<--store-offset-->> */; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_, DEV_NAME); - if (ndev == 0) { - printf(" not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - printf("**************** %s.%d ****************\n", DEV_NAME, n); - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_size); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - - // Alocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable; + token_t *mem; + token_t *gold; + unsigned errors = 0; + unsigned coherence; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = /* <<--data_in_size-->> */; + out_words_adj = /* <<--data_out_size-->> */; + } + else { + in_words_adj = round_up(/* <<--data_in_size-->> */, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(/* <<--data_out_size-->> */, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (/* <<--number of transfers-->> */); + out_len = out_words_adj * (/* <<--number of transfers-->> */); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = /* <<--store-offset-->> */; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_, DEV_NAME); + if (ndev == 0) { + printf(" not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + printf("**************** %s.%d ****************\n", DEV_NAME, n); + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_size); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); + + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_RECALL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_RECALL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - printf(" --------------------\n"); - printf(" Generate input...\n"); - init_buf(mem, gold); + printf(" --------------------\n"); + printf(" Generate input...\n"); + init_buf(mem, gold); - // Pass common configuration parameters + // Pass common configuration parameters - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); #ifndef __sparc - iowrite32(dev, PT_ADDRESS_REG, (unsigned long long) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned long long)ptable); #else - iowrite32(dev, PT_ADDRESS_REG, (unsigned) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned)ptable); #endif - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + + // Flush (customize coherence model here) + esp_flush(coherence); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/tools/accgen/templates/drivers/linux/app/accelerator.c b/tools/accgen/templates/drivers/linux/app/accelerator.c index cc915ab921..946b690384 100644 --- a/tools/accgen/templates/drivers/linux/app/accelerator.c +++ b/tools/accgen/templates/drivers/linux/app/accelerator.c @@ -1,7 +1,7 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include "libesp.h" #include "cfg.h" +#include "libesp.h" static unsigned in_words_adj; static unsigned out_words_adj; @@ -15,89 +15,85 @@ static unsigned size; /* User-defined code */ static int validate_buffer(token_t *out, token_t *gold) { - int i; - int j; - unsigned errors = 0; + int i; + int j; + unsigned errors = 0; - for (i = 0; i < /* <<--number of transfers-->> */; i++) - for (j = 0; j < /* <<--data_out_size-->> */; j++) - if (gold[i * out_words_adj + j] != out[i * out_words_adj + j]) - errors++; + for (i = 0; i < /* <<--number of transfers-->> */; i++) + for (j = 0; j < /* <<--data_out_size-->> */; j++) + if (gold[i * out_words_adj + j] != out[i * out_words_adj + j]) errors++; - return errors; + return errors; } - /* User-defined code */ -static void init_buffer(token_t *in, token_t * gold) +static void init_buffer(token_t *in, token_t *gold) { - int i; - int j; + int i; + int j; - for (i = 0; i < /* <<--number of transfers-->> */; i++) - for (j = 0; j < /* <<--data_in_size-->> */; j++) - in[i * in_words_adj + j] = (token_t) j; + for (i = 0; i < /* <<--number of transfers-->> */; i++) + for (j = 0; j < /* <<--data_in_size-->> */; j++) + in[i * in_words_adj + j] = (token_t)j; - for (i = 0; i < /* <<--number of transfers-->> */; i++) - for (j = 0; j < /* <<--data_out_size-->> */; j++) - gold[i * out_words_adj + j] = (token_t) j; + for (i = 0; i < /* <<--number of transfers-->> */; i++) + for (j = 0; j < /* <<--data_out_size-->> */; j++) + gold[i * out_words_adj + j] = (token_t)j; } - /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = /* <<--data_in_size-->> */; - out_words_adj = /* <<--data_out_size-->> */; - } else { - in_words_adj = round_up(/* <<--data_in_size-->> */, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(/* <<--data_out_size-->> */, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (/* <<--number of transfers-->> */); - out_len = out_words_adj * (/* <<--number of transfers-->> */); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = /* <<--store-offset-->> */; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = /* <<--data_in_size-->> */; + out_words_adj = /* <<--data_out_size-->> */; + } + else { + in_words_adj = round_up(/* <<--data_in_size-->> */, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(/* <<--data_out_size-->> */, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (/* <<--number of transfers-->> */); + out_len = out_words_adj * (/* <<--number of transfers-->> */); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = /* <<--store-offset-->> */; + size = (out_offset * sizeof(token_t)) + out_size; } - int main(int argc, char **argv) { - int errors; + int errors; + + token_t *gold; + token_t *buf; - token_t *gold; - token_t *buf; + init_parameters(); - init_parameters(); + buf = (token_t *)esp_alloc(size); + cfg_000[0].hw_buf = buf; - buf = (token_t *) esp_alloc(size); - cfg_000[0].hw_buf = buf; - - gold = malloc(out_size); + gold = malloc(out_size); - init_buffer(buf, gold); + init_buffer(buf, gold); - printf("\n====== %s ======\n\n", cfg_000[0].devname); - /* <<--print-params-->> */ - printf("\n ** START **\n"); + printf("\n====== %s ======\n\n", cfg_000[0].devname); + /* <<--print-params-->> */ + printf("\n ** START **\n"); - esp_run(cfg_000, NACC); + esp_run(cfg_000, NACC); - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - errors = validate_buffer(&buf[out_offset], gold); + errors = validate_buffer(&buf[out_offset], gold); - free(gold); - esp_free(buf); + free(gold); + esp_free(buf); - if (!errors) - printf("+ Test PASSED\n"); - else - printf("+ Test FAILED\n"); + if (!errors) printf("+ Test PASSED\n"); + else + printf("+ Test FAILED\n"); - printf("\n====== %s ======\n\n", cfg_000[0].devname); + printf("\n====== %s ======\n\n", cfg_000[0].devname); - return errors; + return errors; } diff --git a/tools/accgen/templates/drivers/linux/driver/acc_full.c b/tools/accgen/templates/drivers/linux/driver/acc_full.c index a6a68b3df9..f2bc8b9c79 100644 --- a/tools/accgen/templates/drivers/linux/driver/acc_full.c +++ b/tools/accgen/templates/drivers/linux/driver/acc_full.c @@ -1,127 +1,123 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include #include +#include #include -#include #include +#include #include ".h" -#define DRV_NAME "" +#define DRV_NAME "" /* <<--regs-->> */ -struct _device { - struct esp_device esp; +struct _device { + struct esp_device esp; }; -static struct esp_driver _driver; - -static struct of_device_id _device_ids[] = { - { - .name = "SLD_", - }, - { - .name = "eb_/* <<--id-->> */", - }, - { - .compatible = "sld,", - }, - { }, +static struct esp_driver _driver; + +static struct of_device_id _device_ids[] = { + { + .name = "SLD_", + }, + { + .name = "eb_/* <<--id-->> */", + }, + { + .compatible = "sld,", + }, + {}, }; -static int _devs; +static int _devs; -static inline struct _device *to_(struct esp_device *esp) -{ - return container_of(esp, struct _device, esp); +static inline struct _device *to_(struct esp_device *esp) { + return container_of(esp, struct _device, esp); } -static void _prep_xfer(struct esp_device *esp, void *arg) +static void + _prep_xfer(struct esp_device *esp, void *arg) { - struct _access *a = arg; - - /* <<--regs-config-->> */ - iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); - iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); + struct _access *a = arg; + /* <<--regs-config-->> */ + iowrite32be(a->src_offset, esp->iomem + SRC_OFFSET_REG); + iowrite32be(a->dst_offset, esp->iomem + DST_OFFSET_REG); } -static bool _xfer_input_ok(struct esp_device *esp, void *arg) +static bool _xfer_input_ok(struct esp_device *esp, void *arg) { - /* struct _device * = to_(esp); */ - /* struct _access *a = arg; */ + /* struct _device * = to_(esp); */ + /* struct _access *a = arg; */ - return true; + return true; } -static int _probe(struct platform_device *pdev) +static int _probe(struct platform_device *pdev) { - struct _device *; - struct esp_device *esp; - int rc; - - = kzalloc(sizeof(*), GFP_KERNEL); - if ( == NULL) - return -ENOMEM; - esp = &->esp; - esp->module = THIS_MODULE; - esp->number = _devs; - esp->driver = &_driver; - rc = esp_device_register(esp, pdev); - if (rc) - goto err; - - _devs++; - return 0; - err: - kfree(); - return rc; + struct _device *; + struct esp_device *esp; + int rc; + + = kzalloc(sizeof(*), GFP_KERNEL); + if ( == NULL) return -ENOMEM; + esp = &->esp; + esp->module = THIS_MODULE; + esp->number = _devs; + esp->driver = & _driver; + rc = esp_device_register(esp, pdev); + if (rc) goto err; + + _devs++; + return 0; +err: + kfree(); + return rc; } -static int __exit _remove(struct platform_device *pdev) +static int __exit _remove(struct platform_device *pdev) { - struct esp_device *esp = platform_get_drvdata(pdev); - struct _device * = to_(esp); + struct esp_device *esp = platform_get_drvdata(pdev); + struct _device * = to_(esp); - esp_device_unregister(esp); - kfree(); - return 0; + esp_device_unregister(esp); + kfree(); + return 0; } -static struct esp_driver _driver = { - .plat = { - .probe = _probe, - .remove = _remove, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = _device_ids, - }, - }, - .xfer_input_ok = _xfer_input_ok, - .prep_xfer = _prep_xfer, - .ioctl_cm = _IOC_ACCESS, - .arg_size = sizeof(struct _access), +static struct esp_driver _driver = { + .plat = + { + .probe = _probe, + .remove = _remove, + .driver = + { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = _device_ids, + }, + }, + .xfer_input_ok = _xfer_input_ok, .prep_xfer = _prep_xfer, + .ioctl_cm = _IOC_ACCESS, .arg_size = sizeof(struct _access), }; -static int __init _init(void) +static int __init _init(void) { - return esp_driver_register(&_driver); + return esp_driver_register(& _driver); } -static void __exit _exit(void) +static void __exit _exit(void) { - esp_driver_unregister(&_driver); + esp_driver_unregister(& _driver); } -module_init(_init) -module_exit(_exit) +module_init( _init) module_exit( _exit) -MODULE_DEVICE_TABLE(of, _device_ids); + MODULE_DEVICE_TABLE(of, _device_ids); MODULE_AUTHOR("Emilio G. Cota "); MODULE_LICENSE("GPL"); diff --git a/tools/accgen/templates/drivers/linux/include/acc_full.h b/tools/accgen/templates/drivers/linux/include/acc_full.h index 5cd77039fe..46ae74d5d6 100644 --- a/tools/accgen/templates/drivers/linux/include/acc_full.h +++ b/tools/accgen/templates/drivers/linux/include/acc_full.h @@ -1,29 +1,29 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#ifndef __H_ -#define __H_ +#ifndef _ < ACC_FULL_NAME> _H_ + #define _ _H_ -#ifdef __KERNEL__ -#include -#include -#else -#include -#include -#ifndef __user -#define __user -#endif -#endif /* __KERNEL__ */ + #ifdef __KERNEL__ + #include + #include + #else + #include + #include + #ifndef __user + #define __user + #endif + #endif /* __KERNEL__ */ -#include -#include + #include + #include -struct _access { - struct esp_access esp; - /* <<--regs-->> */ - unsigned src_offset; - unsigned dst_offset; +struct _access { + struct esp_access esp; + /* <<--regs-->> */ + unsigned src_offset; + unsigned dst_offset; }; -#define _IOC_ACCESS _IOW ('S', 0, struct _access) + #define < ACC_FULL_NAME> _IOC_ACCESS _IOW('S', 0, struct _access) #endif /* __H_ */ diff --git a/tools/accgen/templates/drivers_hls4ml/baremetal/accelerator.c b/tools/accgen/templates/drivers_hls4ml/baremetal/accelerator.c index 5b04921dff..30751bb356 100644 --- a/tools/accgen/templates/drivers_hls4ml/baremetal/accelerator.c +++ b/tools/accgen/templates/drivers_hls4ml/baremetal/accelerator.c @@ -3,7 +3,7 @@ #include #ifndef __riscv -#include + #include #endif #include @@ -13,21 +13,17 @@ typedef /* <<--token-type-->> */ token_t; -static unsigned DMA_WORD_PER_BEAT(unsigned _st) -{ - return (sizeof(void *) / _st); -} - +static unsigned DMA_WORD_PER_BEAT(unsigned _st) { return (sizeof(void *) / _st); } -#define SLD_ /* <<--id-->> */ +#define SLD_ /* <<--id-->> */ #define DEV_NAME "sld," #define INT_BITS /* <<--int_bits-->> */ -#define fl2fx(A) float_to_fixed/* <<--data_width-->> */(A, INT_BITS) +#define fl2fx(A) float_to_fixed /* <<--data_width-->> */ (A, INT_BITS) /* <<--params-->> */ -static unsigned in_words = /* <<--data_in_size-->> */; +static unsigned in_words = /* <<--data_in_size-->> */; static unsigned out_words = /* <<--data_out_size-->> */; static unsigned in_words_adj; static unsigned out_words_adj; @@ -40,182 +36,173 @@ static unsigned mem_size; /* Size of the contiguous chunks for scatter/gather */ #define CHUNK_SHIFT 20 -#define CHUNK_SIZE BIT(CHUNK_SHIFT) -#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? \ - (_sz / CHUNK_SIZE) : \ - (_sz / CHUNK_SIZE) + 1) +#define CHUNK_SIZE BIT(CHUNK_SHIFT) +#define NCHUNK(_sz) ((_sz % CHUNK_SIZE == 0) ? (_sz / CHUNK_SIZE) : (_sz / CHUNK_SIZE) + 1) /* User defined registers */ /* <<--regs-->> */ - static int validate_buf(token_t *out, token_t *gold) { - int i; - int j; - unsigned errors = 0; - - // Validation expecting results of a classifier in the range [0, 1] - // MODIFY the validation below if needed. - int threshold = fl2fx(0.5); - - for (i = 0; i < nbursts; i++) { - for (j = 0; j < out_words; j++) { - if ((gold[i * out_words + j] < threshold && - out[i * out_words_adj + j] >= threshold) || - (gold[i * out_words + j] > threshold && - out[i * out_words_adj + j] <= threshold)) { - errors++; - - printf("%d : gold %d : output %d : error\n", i, - (int) gold[i * out_words + j], - (int) out[i * out_words_adj + j]); - } - } - } - - return errors; + int i; + int j; + unsigned errors = 0; + + // Validation expecting results of a classifier in the range [0, 1] + // MODIFY the validation below if needed. + int threshold = fl2fx(0.5); + + for (i = 0; i < nbursts; i++) { + for (j = 0; j < out_words; j++) { + if ((gold[i * out_words + j] < threshold && out[i * out_words_adj + j] >= threshold) || + (gold[i * out_words + j] > threshold && out[i * out_words_adj + j] <= threshold)) { + errors++; + + printf("%d : gold %d : output %d : error\n", i, (int)gold[i * out_words + j], + (int)out[i * out_words_adj + j]); + } + } + } + + return errors; } - -static void init_buf (token_t *in, token_t *gold) +static void init_buf(token_t *in, token_t *gold) { - unsigned i; + unsigned i; - i = 0; + i = 0; #include "data/input.c" - i = 0; + i = 0; #include "data/output_gold.c" } - -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - int i; - int n; - int ndev; - struct esp_device *espdevs; - struct esp_device *dev; - unsigned done; - unsigned **ptable; - token_t *mem; - token_t *gold; - unsigned errors = 0; - unsigned coherence; - - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = in_words; - out_words_adj = out_words; - } else { - in_words_adj = round_up(in_words, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(out_words, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (nbursts); - out_len = out_words_adj * (nbursts); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = /* <<--store-offset-->> */; - mem_size = (out_offset * sizeof(token_t)) + out_size; - - - // Search for the device - printf("Scanning device tree... \n"); - - ndev = probe(&espdevs, VENDOR_SLD, SLD_, DEV_NAME); - if (ndev == 0) { - printf(" not found\n"); - return 0; - } - - for (n = 0; n < ndev; n++) { - - printf("**************** %s.%d ****************\n", DEV_NAME, n); - - dev = &espdevs[n]; - - // Check DMA capabilities - if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { - printf(" -> scatter-gather DMA is disabled. Abort.\n"); - return 0; - } - - if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { - printf(" -> Not enough TLB entries available. Abort.\n"); - return 0; - } - - // Allocate memory - gold = aligned_malloc(out_size); - mem = aligned_malloc(mem_size); - printf(" memory buffer base-address = %p\n", mem); - - // Alocate and populate page table - ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); - for (i = 0; i < NCHUNK(mem_size); i++) - ptable[i] = (unsigned *) &mem[i * (CHUNK_SIZE / sizeof(token_t))]; - printf(" ptable = %p\n", ptable); - printf(" nchunk = %lu\n", NCHUNK(mem_size)); + int i; + int n; + int ndev; + struct esp_device *espdevs; + struct esp_device *dev; + unsigned done; + unsigned **ptable; + token_t *mem; + token_t *gold; + unsigned errors = 0; + unsigned coherence; + + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = in_words; + out_words_adj = out_words; + } + else { + in_words_adj = round_up(in_words, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(out_words, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (nbursts); + out_len = out_words_adj * (nbursts); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = /* <<--store-offset-->> */; + mem_size = (out_offset * sizeof(token_t)) + out_size; + + // Search for the device + printf("Scanning device tree... \n"); + + ndev = probe(&espdevs, VENDOR_SLD, SLD_, DEV_NAME); + if (ndev == 0) { + printf(" not found\n"); + return 0; + } + + for (n = 0; n < ndev; n++) { + + printf("**************** %s.%d ****************\n", DEV_NAME, n); + + dev = &espdevs[n]; + + // Check DMA capabilities + if (ioread32(dev, PT_NCHUNK_MAX_REG) == 0) { + printf(" -> scatter-gather DMA is disabled. Abort.\n"); + return 0; + } + + if (ioread32(dev, PT_NCHUNK_MAX_REG) < NCHUNK(mem_size)) { + printf(" -> Not enough TLB entries available. Abort.\n"); + return 0; + } + + // Allocate memory + gold = aligned_malloc(out_size); + mem = aligned_malloc(mem_size); + printf(" memory buffer base-address = %p\n", mem); + + // Alocate and populate page table + ptable = aligned_malloc(NCHUNK(mem_size) * sizeof(unsigned *)); + for (i = 0; i < NCHUNK(mem_size); i++) + ptable[i] = (unsigned *)&mem[i * (CHUNK_SIZE / sizeof(token_t))]; + printf(" ptable = %p\n", ptable); + printf(" nchunk = %lu\n", NCHUNK(mem_size)); #ifndef __riscv - for (coherence = ACC_COH_NONE; coherence <= ACC_COH_RECALL; coherence++) { + for (coherence = ACC_COH_NONE; coherence <= ACC_COH_RECALL; coherence++) { #else - { - /* TODO: Restore full test once ESP caches are integrated */ - coherence = ACC_COH_NONE; + { + /* TODO: Restore full test once ESP caches are integrated */ + coherence = ACC_COH_NONE; #endif - printf(" --------------------\n"); - printf(" Generate input...\n"); - init_buf(mem, gold); + printf(" --------------------\n"); + printf(" Generate input...\n"); + init_buf(mem, gold); - // Pass common configuration parameters + // Pass common configuration parameters - iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); - iowrite32(dev, COHERENCE_REG, coherence); + iowrite32(dev, SELECT_REG, ioread32(dev, DEVID_REG)); + iowrite32(dev, COHERENCE_REG, coherence); #ifndef __sparc - iowrite32(dev, PT_ADDRESS_REG, (unsigned long long) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned long long)ptable); #else - iowrite32(dev, PT_ADDRESS_REG, (unsigned) ptable); + iowrite32(dev, PT_ADDRESS_REG, (unsigned)ptable); #endif - iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); - iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); - - // Use the following if input and output data are not allocated at the default offsets - iowrite32(dev, SRC_OFFSET_REG, 0x0); - iowrite32(dev, DST_OFFSET_REG, 0x0); - - // Pass accelerator-specific configuration parameters - /* <<--regs-config-->> */ - - // Flush (customize coherence model here) - esp_flush(coherence); - - // Start accelerators - printf(" Start...\n"); - iowrite32(dev, CMD_REG, CMD_MASK_START); - - // Wait for completion - done = 0; - while (!done) { - done = ioread32(dev, STATUS_REG); - done &= STATUS_MASK_DONE; - } - iowrite32(dev, CMD_REG, 0x0); - - printf(" Done\n"); - printf(" validating...\n"); - - /* Validation */ - errors = validate_buf(&mem[out_offset], gold); - if (errors) - printf(" ... FAIL\n"); - else - printf(" ... PASS\n"); - } - aligned_free(ptable); - aligned_free(mem); - aligned_free(gold); - } - - return 0; + iowrite32(dev, PT_NCHUNK_REG, NCHUNK(mem_size)); + iowrite32(dev, PT_SHIFT_REG, CHUNK_SHIFT); + + // Use the following if input and output data are not allocated at the default offsets + iowrite32(dev, SRC_OFFSET_REG, 0x0); + iowrite32(dev, DST_OFFSET_REG, 0x0); + + // Pass accelerator-specific configuration parameters + /* <<--regs-config-->> */ + + // Flush (customize coherence model here) + esp_flush(coherence); + + // Start accelerators + printf(" Start...\n"); + iowrite32(dev, CMD_REG, CMD_MASK_START); + + // Wait for completion + done = 0; + while (!done) { + done = ioread32(dev, STATUS_REG); + done &= STATUS_MASK_DONE; + } + iowrite32(dev, CMD_REG, 0x0); + + printf(" Done\n"); + printf(" validating...\n"); + + /* Validation */ + errors = validate_buf(&mem[out_offset], gold); + if (errors) printf(" ... FAIL\n"); + else + printf(" ... PASS\n"); + } + aligned_free(ptable); + aligned_free(mem); + aligned_free(gold); + } + + return 0; } diff --git a/tools/accgen/templates/drivers_hls4ml/linux/app/accelerator.c b/tools/accgen/templates/drivers_hls4ml/linux/app/accelerator.c index 58fc882dab..f6e41a2ac0 100644 --- a/tools/accgen/templates/drivers_hls4ml/linux/app/accelerator.c +++ b/tools/accgen/templates/drivers_hls4ml/linux/app/accelerator.c @@ -1,9 +1,9 @@ // Copyright (c) 2011-2024 Columbia University, System Level Design Group // SPDX-License-Identifier: Apache-2.0 -#include "libesp.h" #include "cfg.h" +#include "libesp.h" -static unsigned in_words = /* <<--data_in_size-->> */; +static unsigned in_words = /* <<--data_in_size-->> */; static unsigned out_words = /* <<--data_out_size-->> */; static unsigned in_words_adj; static unsigned out_words_adj; @@ -17,132 +17,127 @@ static unsigned size; /* User-defined code */ static int validate_buffer(token_t *out, token_t *gold) { - int i; - int j; - unsigned errors = 0; - - // Validation expecting results of a classifier in the range [0, 1] - // MODIFY the validation below if needed. - int threshold = fl2fx(0.5); - - for (i = 0; i < nbursts; i++) - for (j = 0; j < out_words; j++) - if ((gold[i * out_words_adj + j] < threshold && - out[i * out_words_adj + j] >= threshold) || - (gold[i * out_words_adj + j] > threshold && - out[i * out_words_adj + j] <= threshold)) - errors++; - - return errors; + int i; + int j; + unsigned errors = 0; + + // Validation expecting results of a classifier in the range [0, 1] + // MODIFY the validation below if needed. + int threshold = fl2fx(0.5); + + for (i = 0; i < nbursts; i++) + for (j = 0; j < out_words; j++) + if ((gold[i * out_words_adj + j] < threshold && + out[i * out_words_adj + j] >= threshold) || + (gold[i * out_words_adj + j] > threshold && + out[i * out_words_adj + j] <= threshold)) + errors++; + + return errors; } - /* User-defined code */ static void init_buffer(token_t *in, token_t *gold) { - int i; - int j; - float val_float; - FILE *fd = NULL; - - // Load input - if((fd = fopen("data/tb_input_features.dat", "r")) == (FILE*) NULL) - { - printf("[ERROR] Could not open tb_input_features.dat\n"); - exit(1); - } - - val_float = 0; - fscanf(fd, "%f", &val_float); - for (i = 0; i < nbursts; i++) - for (j = 0; j < in_words; j++) { - if (feof(fd)) { - printf("Error: unexpected EOF data/tb_input_features.dat"); - fclose(fd); - exit(EXIT_FAILURE); - } - in[i * in_words_adj + j] = (token_t) fl2fx(val_float); - fscanf(fd, "%f", &val_float); - } - fclose(fd); - - // Load golden output - if((fd = fopen("data/tb_output_predictions_fixed.dat", "r")) == (FILE*) NULL) - { - printf("[ERROR] Could not open tb_output_predictions_fixed.dat\n"); - exit(1); - } - - val_float = 0; - fscanf(fd, "%f", &val_float); - for (i = 0; i < nbursts; i++) - for (j = 0; j < out_words; j++) { - if (feof(fd)) { - printf("Error: unexpected EOF data/tb_output_predictions_fixed.dat"); - fclose(fd); - exit(EXIT_FAILURE); - } - gold[i * out_words_adj + j] = (token_t) fl2fx(val_float); - fscanf(fd, "%f", &val_float); - } - fclose(fd); + int i; + int j; + float val_float; + FILE *fd = NULL; + + // Load input + if ((fd = fopen("data/tb_input_features.dat", "r")) == (FILE *)NULL) { + printf("[ERROR] Could not open tb_input_features.dat\n"); + exit(1); + } + + val_float = 0; + fscanf(fd, "%f", &val_float); + for (i = 0; i < nbursts; i++) + for (j = 0; j < in_words; j++) { + if (feof(fd)) { + printf("Error: unexpected EOF data/tb_input_features.dat"); + fclose(fd); + exit(EXIT_FAILURE); + } + in[i * in_words_adj + j] = (token_t)fl2fx(val_float); + fscanf(fd, "%f", &val_float); + } + fclose(fd); + + // Load golden output + if ((fd = fopen("data/tb_output_predictions_fixed.dat", "r")) == (FILE *)NULL) { + printf("[ERROR] Could not open tb_output_predictions_fixed.dat\n"); + exit(1); + } + + val_float = 0; + fscanf(fd, "%f", &val_float); + for (i = 0; i < nbursts; i++) + for (j = 0; j < out_words; j++) { + if (feof(fd)) { + printf("Error: unexpected EOF data/tb_output_predictions_fixed.dat"); + fclose(fd); + exit(EXIT_FAILURE); + } + gold[i * out_words_adj + j] = (token_t)fl2fx(val_float); + fscanf(fd, "%f", &val_float); + } + fclose(fd); } - /* User-defined code */ static void init_parameters() { - if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { - in_words_adj = in_words; - out_words_adj = out_words; - } else { - in_words_adj = round_up(in_words, DMA_WORD_PER_BEAT(sizeof(token_t))); - out_words_adj = round_up(out_words, DMA_WORD_PER_BEAT(sizeof(token_t))); - } - in_len = in_words_adj * (nbursts); - out_len = out_words_adj * (nbursts); - in_size = in_len * sizeof(token_t); - out_size = out_len * sizeof(token_t); - out_offset = /* <<--store-offset-->> */; - size = (out_offset * sizeof(token_t)) + out_size; + if (DMA_WORD_PER_BEAT(sizeof(token_t)) == 0) { + in_words_adj = in_words; + out_words_adj = out_words; + } + else { + in_words_adj = round_up(in_words, DMA_WORD_PER_BEAT(sizeof(token_t))); + out_words_adj = round_up(out_words, DMA_WORD_PER_BEAT(sizeof(token_t))); + } + in_len = in_words_adj * (nbursts); + out_len = out_words_adj * (nbursts); + in_size = in_len * sizeof(token_t); + out_size = out_len * sizeof(token_t); + out_offset = /* <<--store-offset-->> */; + size = (out_offset * sizeof(token_t)) + out_size; } - int main(int argc, char **argv) { - int errors; + int errors; + + token_t *gold; + token_t *buf; - token_t *gold; - token_t *buf; + init_parameters(); - init_parameters(); + buf = (token_t *)esp_alloc(size); + cfg_000[0].hw_buf = buf; - buf = (token_t *) esp_alloc(size); - cfg_000[0].hw_buf = buf; - - gold = malloc(out_size); + gold = malloc(out_size); - init_buffer(buf, gold); + init_buffer(buf, gold); - printf("\n====== %s ======\n\n", cfg_000[0].devname); - /* <<--print-params-->> */ - printf("\n ** START **\n"); + printf("\n====== %s ======\n\n", cfg_000[0].devname); + /* <<--print-params-->> */ + printf("\n ** START **\n"); - esp_run(cfg_000, NACC); + esp_run(cfg_000, NACC); - printf("\n ** DONE **\n"); + printf("\n ** DONE **\n"); - errors = validate_buffer(&buf[out_offset], gold); + errors = validate_buffer(&buf[out_offset], gold); - free(gold); - esp_free(buf); + free(gold); + esp_free(buf); - if (!errors) - printf(" + Test PASSED\n"); - else - printf(" + Test FAILED\n"); + if (!errors) printf(" + Test PASSED\n"); + else + printf(" + Test FAILED\n"); - printf("\n====== %s ======\n\n", cfg_000[0].devname); + printf("\n====== %s ======\n\n", cfg_000[0].devname); - return errors; + return errors; } diff --git a/tools/accgen/templates/hls4ml/inc/espacc.h b/tools/accgen/templates/hls4ml/inc/espacc.h index 25a837c911..94d8e3fc11 100644 --- a/tools/accgen/templates/hls4ml/inc/espacc.h +++ b/tools/accgen/templates/hls4ml/inc/espacc.h @@ -14,27 +14,27 @@ // Data types and constants #define VALUES_PER_WORD (DMA_SIZE / DATA_BITWIDTH) #if ((SIZE_IN_CHUNK_DATA % VALUES_PER_WORD) == 0) -#define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD) + #define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD) #else -#define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD + 1) + #define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD + 1) #endif #if ((SIZE_OUT_CHUNK_DATA % VALUES_PER_WORD) == 0) -#define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD) + #define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD) #else -#define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD + 1) + #define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD + 1) #endif // data word -#if (IS_TYPE_FIXED_POINT == 1) -typedef ap_fixed word_t; +#if (IS_TYPE_FIXED_POINT == 1) +typedef ap_fixed word_t; #elif (IS_TYPE_UINT == 1) typedef ap_uint word_t; #elif (IS_TYPE_FLOAT == 1) -#if (DATA_BITWIDTH == 32) + #if (DATA_BITWIDTH == 32) typedef float word_t; -#else -#error "Floating point word bitwidth not supported. Only 32 is supported." -#endif + #else + #error "Floating point word bitwidth not supported. Only 32 is supported." + #endif #else // (IS_TYPE_INT == 1) typedef ap_int word_t; #endif @@ -55,26 +55,24 @@ typedef struct dma_info { // The 'size' variable of 'dma_info' indicates the bit-width of the words // processed by the accelerator. Here are the encodings: -#define SIZE_BYTE 0 -#define SIZE_HWORD 1 -#define SIZE_WORD 2 -#define SIZE_DWORD 3 +#define SIZE_BYTE 0 +#define SIZE_HWORD 1 +#define SIZE_WORD 2 +#define SIZE_DWORD 3 #if (DATA_BITWIDTH == 8) -#define SIZE_WORD_T SIZE_BYTE + #define SIZE_WORD_T SIZE_BYTE #elif (DATA_BITWIDTH == 16) -#define SIZE_WORD_T SIZE_HWORD + #define SIZE_WORD_T SIZE_HWORD #elif (DATA_BITWIDTH == 32) -#define SIZE_WORD_T SIZE_WORD + #define SIZE_WORD_T SIZE_WORD #else // if (DATA_BITWIDTH == 64) -#define SIZE_WORD_T SIZE_DWORD + #define SIZE_WORD_T SIZE_DWORD #endif -void top(dma_word_t *out, dma_word_t *in1, - const unsigned conf_info_nbursts, - dma_info_t &load_ctrl, dma_info_t &store_ctrl); +void top(dma_word_t *out, dma_word_t *in1, const unsigned conf_info_nbursts, dma_info_t &load_ctrl, + dma_info_t &store_ctrl); -void compute(input_t _inbuff[SIZE_IN_CHUNK_DATA], - result_t _outbuff[SIZE_OUT_CHUNK_DATA]); +void compute(input_t _inbuff[SIZE_IN_CHUNK_DATA], result_t _outbuff[SIZE_OUT_CHUNK_DATA]); #endif diff --git a/tools/accgen/templates/stratus_hls/src/accelerator.cpp b/tools/accgen/templates/stratus_hls/src/accelerator.cpp index 189fa675e8..9250216e73 100644 --- a/tools/accgen/templates/stratus_hls/src/accelerator.cpp +++ b/tools/accgen/templates/stratus_hls/src/accelerator.cpp @@ -10,7 +10,7 @@ // Processes -void ::load_input() +void::load_input() { // Reset @@ -43,12 +43,11 @@ void ::load_input() HLS_PROTO("load-dma"); wait(); - bool ping = true; + bool ping = true; uint32_t offset = 0; // Batching - for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) - { + for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) { wait(); #if (DMA_WORD_PER_BEAT == 0) uint32_t length = /* <<--data_in_size-->> */; @@ -56,8 +55,7 @@ void ::load_input() uint32_t length = round_up(/* <<--data_in_size-->> */, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_IN_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_IN_WORD) { wait(); // Configure DMA transaction uint32_t len = rem > PLM_IN_WORD ? PLM_IN_WORD : rem; @@ -73,25 +71,22 @@ void ::load_input() #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - for (uint16_t i = 0; i < len; i++) - { + for (uint16_t i = 0; i < len; i++) { sc_dt::sc_bv dataBv; - for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) - { - dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH) = this->dma_read_chnl.get(); + for (uint16_t k = 0; k < DMA_BEAT_PER_WORD; k++) { + dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH) = + this->dma_read_chnl.get(); wait(); } // Write to PLM - if (ping) - plm_in_ping[i] = dataBv.to_int64(); + if (ping) plm_in_ping[i] = dataBv.to_int64(); else plm_in_pong[i] = dataBv.to_int64(); } #else - for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { HLS_BREAK_DEP(plm_in_ping); HLS_BREAK_DEP(plm_in_pong); @@ -101,13 +96,14 @@ void ::load_input() wait(); // Write to PLM (all DMA_WORD_PER_BEAT words in one cycle) - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; if (ping) - plm_in_ping[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + plm_in_ping[i + k] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); else - plm_in_pong[i + k] = dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); + plm_in_pong[i + k] = + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH).to_int64(); } } #endif @@ -123,9 +119,7 @@ void ::load_input() } } - - -void ::store_output() +void::store_output() { // Reset { @@ -161,14 +155,14 @@ void ::store_output() #if (DMA_WORD_PER_BEAT == 0) uint32_t store_offset = (/* <<--data_in_size-->> */) * /* <<--number of transfers-->> */; #else - uint32_t store_offset = round_up(/* <<--data_in_size-->> */, DMA_WORD_PER_BEAT) * /* <<--number of transfers-->> */; + uint32_t store_offset = round_up(/* <<--data_in_size-->> */, + DMA_WORD_PER_BEAT) * /* <<--number of transfers-->> */; #endif uint32_t offset = /* <<--store-offset-->> */; wait(); // Batching - for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) - { + for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) { wait(); #if (DMA_WORD_PER_BEAT == 0) uint32_t length = /* <<--data_out_size-->> */; @@ -176,8 +170,7 @@ void ::store_output() uint32_t length = round_up(/* <<--data_out_size-->> */, DMA_WORD_PER_BEAT); #endif // Chunking - for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) - { + for (int rem = length; rem > 0; rem -= PLM_OUT_WORD) { this->store_compute_handshake(); @@ -195,41 +188,39 @@ void ::store_output() #if (DMA_WORD_PER_BEAT == 0) // data word is wider than NoC links - for (uint16_t i = 0; i < len; i++) - { + for (uint16_t i = 0; i < len; i++) { // Read from PLM sc_dt::sc_int data; wait(); - if (ping) - data = plm_out_ping[i]; + if (ping) data = plm_out_ping[i]; else data = plm_out_pong[i]; sc_dt::sc_bv dataBv(data); uint16_t k = 0; - for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) - { - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + for (k = 0; k < DMA_BEAT_PER_WORD - 1; k++) { + this->dma_write_chnl.put( + dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); wait(); } // Last beat on the bus does not require wait(), which is // placed before accessing the PLM - this->dma_write_chnl.put(dataBv.range((k+1) * DMA_WIDTH - 1, k * DMA_WIDTH)); + this->dma_write_chnl.put(dataBv.range((k + 1) * DMA_WIDTH - 1, k * DMA_WIDTH)); } #else - for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) - { + for (uint16_t i = 0; i < len; i += DMA_WORD_PER_BEAT) { sc_dt::sc_bv dataBv; // Read from PLM wait(); - for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) - { + for (uint16_t k = 0; k < DMA_WORD_PER_BEAT; k++) { HLS_UNROLL_SIMPLE; if (ping) - dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_ping[i + k]; + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = + plm_out_ping[i + k]; else - dataBv.range((k+1) * DATA_WIDTH - 1, k * DATA_WIDTH) = plm_out_pong[i + k]; + dataBv.range((k + 1) * DATA_WIDTH - 1, k * DATA_WIDTH) = + plm_out_pong[i + k]; } this->dma_write_chnl.put(dataBv); } @@ -246,8 +237,7 @@ void ::store_output() } } - -void ::compute_kernel() +void::compute_kernel() { // Reset { @@ -274,28 +264,24 @@ void ::compute_kernel() /* <<--local-params-->> */ } - // Compute bool ping = true; { - for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) - { - uint32_t in_length = /* <<--data_in_size-->> */; + for (uint16_t b = 0; b < /* <<--number of transfers-->> */; b++) { + uint32_t in_length = /* <<--data_in_size-->> */; uint32_t out_length = /* <<--data_out_size-->> */; - int out_rem = out_length; + int out_rem = out_length; - for (int in_rem = in_length; in_rem > 0; in_rem -= PLM_IN_WORD) - { + for (int in_rem = in_length; in_rem > 0; in_rem -= PLM_IN_WORD) { - uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; + uint32_t in_len = in_rem > PLM_IN_WORD ? PLM_IN_WORD : in_rem; uint32_t out_len = out_rem > PLM_OUT_WORD ? PLM_OUT_WORD : out_rem; this->compute_load_handshake(); // Computing phase implementation for (int i = 0; i < in_len; i++) { - if (ping) - plm_out_ping[i] = plm_in_ping[i]; + if (ping) plm_out_ping[i] = plm_in_ping[i]; else plm_out_pong[i] = plm_in_pong[i]; } diff --git a/tools/accgen/templates/stratus_hls/tb/sc_main.cpp b/tools/accgen/templates/stratus_hls/tb/sc_main.cpp index c465ccc433..cffde7e61b 100644 --- a/tools/accgen/templates/stratus_hls/tb/sc_main.cpp +++ b/tools/accgen/templates/stratus_hls/tb/sc_main.cpp @@ -5,44 +5,44 @@ #define RESET_PERIOD (30 * CLOCK_PERIOD) -system_t * testbench = NULL; +system_t *testbench = NULL; extern void esc_elaborate() { - // Creating the whole system - testbench = new system_t("testbench"); + // Creating the whole system + testbench = new system_t("testbench"); } extern void esc_cleanup() { - // Deleting the system - delete testbench; + // Deleting the system + delete testbench; } int sc_main(int argc, char *argv[]) { - // Kills a Warning when using SC_CTHREADS - //sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); - sc_report_handler::set_actions (SC_WARNING, SC_DO_NOTHING); + // Kills a Warning when using SC_CTHREADS + // sc_report_handler::set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + sc_report_handler::set_actions(SC_WARNING, SC_DO_NOTHING); - esc_initialize(argc, argv); - esc_elaborate(); + esc_initialize(argc, argv); + esc_elaborate(); - sc_clock clk("clk", CLOCK_PERIOD, SC_PS); - sc_signal rst("rst"); + sc_clock clk("clk", CLOCK_PERIOD, SC_PS); + sc_signal rst("rst"); - testbench->clk(clk); - testbench->rst(rst); - rst.write(false); + testbench->clk(clk); + testbench->rst(rst); + rst.write(false); - sc_start(RESET_PERIOD, SC_PS); + sc_start(RESET_PERIOD, SC_PS); - rst.write(true); + rst.write(true); - sc_start(); + sc_start(); - esc_log_pass(); - esc_cleanup(); + esc_log_pass(); + esc_cleanup(); - return 0; + return 0; } diff --git a/tools/accgen/templates/vivado_hls/inc/espacc.h b/tools/accgen/templates/vivado_hls/inc/espacc.h index 17e91c84bc..ce2652e306 100644 --- a/tools/accgen/templates/vivado_hls/inc/espacc.h +++ b/tools/accgen/templates/vivado_hls/inc/espacc.h @@ -10,32 +10,32 @@ #include #define __round_mask(x, y) ((y)-1) -#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) +#define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1) // Data types and constants #define VALUES_PER_WORD (DMA_SIZE / DATA_BITWIDTH) #if ((SIZE_IN_CHUNK_DATA % VALUES_PER_WORD) == 0) -#define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD) + #define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD) #else -#define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD + 1) + #define SIZE_IN_CHUNK (SIZE_IN_CHUNK_DATA / VALUES_PER_WORD + 1) #endif #if ((SIZE_OUT_CHUNK_DATA % VALUES_PER_WORD) == 0) -#define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD) + #define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD) #else -#define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD + 1) + #define SIZE_OUT_CHUNK (SIZE_OUT_CHUNK_DATA / VALUES_PER_WORD + 1) #endif // data word -#if (IS_TYPE_FIXED_POINT == 1) -typedef ap_fixed word_t; +#if (IS_TYPE_FIXED_POINT == 1) +typedef ap_fixed word_t; #elif (IS_TYPE_UINT == 1) typedef ap_uint word_t; #elif (IS_TYPE_FLOAT == 1) -#if (DATA_BITWIDTH == 32) + #if (DATA_BITWIDTH == 32) typedef float word_t; -#else -#error "Floating point word bitwidth not supported. Only 32 is supported." -#endif + #else + #error "Floating point word bitwidth not supported. Only 32 is supported." + #endif #else // (IS_TYPE_INT == 1) typedef ap_int word_t; #endif @@ -56,26 +56,25 @@ typedef struct dma_info { // The 'size' variable of 'dma_info' indicates the bit-width of the words // processed by the accelerator. Here are the encodings: -#define SIZE_BYTE 0 -#define SIZE_HWORD 1 -#define SIZE_WORD 2 -#define SIZE_DWORD 3 +#define SIZE_BYTE 0 +#define SIZE_HWORD 1 +#define SIZE_WORD 2 +#define SIZE_DWORD 3 #if (DATA_BITWIDTH == 8) -#define SIZE_WORD_T SIZE_BYTE + #define SIZE_WORD_T SIZE_BYTE #elif (DATA_BITWIDTH == 16) -#define SIZE_WORD_T SIZE_HWORD + #define SIZE_WORD_T SIZE_HWORD #elif (DATA_BITWIDTH == 32) -#define SIZE_WORD_T SIZE_WORD + #define SIZE_WORD_T SIZE_WORD #else // if (DATA_BITWIDTH == 64) -#define SIZE_WORD_T SIZE_DWORD + #define SIZE_WORD_T SIZE_DWORD #endif void top(dma_word_t *out, dma_word_t *in1, - /* <<--params-->> */ - dma_info_t &load_ctrl, dma_info_t &store_ctrl); + /* <<--params-->> */ + dma_info_t &load_ctrl, dma_info_t &store_ctrl); -void compute(word_t _inbuff[SIZE_IN_CHUNK_DATA], - word_t _outbuff[SIZE_OUT_CHUNK_DATA]); +void compute(word_t _inbuff[SIZE_IN_CHUNK_DATA], word_t _outbuff[SIZE_OUT_CHUNK_DATA]); #endif diff --git a/tools/asicgen/asic_memgen.py b/tools/asicgen/asic_memgen.py index 7f5d550a25..bd53355a54 100755 --- a/tools/asicgen/asic_memgen.py +++ b/tools/asicgen/asic_memgen.py @@ -5,6 +5,7 @@ import sys import math + def data_struct(memory_list): for row in memory_list: @@ -16,16 +17,16 @@ def data_struct(memory_list): "port_type": str(row[5])}) if str(row[0]) == "l2": mem_dict["l2"].append({"macro_name": str(row[1]), - "address_size": str(row[2]), - "word_size": str(row[3]), - "area": str(row[4]), - "port_type": str(row[5])}) + "address_size": str(row[2]), + "word_size": str(row[3]), + "area": str(row[4]), + "port_type": str(row[5])}) if str(row[0]) == "l1": mem_dict["l1"].append({"macro_name": str(row[1]), - "address_size": str(row[2]), - "word_size": str(row[3]), - "area": str(row[4]), - "port_type": str(row[5])}) + "address_size": str(row[2]), + "word_size": str(row[3]), + "area": str(row[4]), + "port_type": str(row[5])}) if str(row[0]) == "slm": mem_dict["slm"].append({"macro_name": str(row[1]), "address_size": str(row[2]), @@ -34,18 +35,17 @@ def data_struct(memory_list): "port_type": str(row[5])}) if str(row[0]) == "io": mem_dict["io"].append({"macro_name": str(row[1]), - "address_size": str(row[2]), - "word_size": str(row[3]), - "area": str(row[4]), - "port_type": str(row[5])}) + "address_size": str(row[2]), + "word_size": str(row[3]), + "area": str(row[4]), + "port_type": str(row[5])}) if str(row[0]) == "acc": mem_dict["acc"].append({"macro_name": str(row[1]), "address_size": str(row[2]), "word_size": str(row[3]), "area": str(row[4]), "port_type": str(row[5])}) - - + return mem_dict @@ -75,41 +75,46 @@ def print_lib(file1, lib_list): f_line = out_file.readlines() for j, line in enumerate(f_line): if line.startswith("dual_port"): - f_line.insert(j, "%s 1 \n" %(' '.join(map(str, list(single_list[i][0:-1]))))) + f_line.insert(j, "%s 1 \n" % ( + ' '.join(map(str, list(single_list[i][0:-1]))))) break out_file = open(file1, "w") out_file.writelines(f_line) out_file.close() else: out_file = open(file1, "a") - out_file.write("%s 1 \n" %(' '.join(map(str, list(single_list[i][0:-1]))))) + out_file.write("%s 1 \n" % + (' '.join(map(str, list(single_list[i][0:-1]))))) out_file.close() if len(dual_list) > 0: out_file = open(file1, "a+") for i in range(len(dual_list)): if dual_list[i][-1] == "dual": - out_file.write("%s 2 \n" %(' '.join(map(str, list(dual_list[i][0:-1]))))) + out_file.write("%s 2 \n" % + (' '.join(map(str, list(dual_list[i][0:-1]))))) out_file.close() - else: + else: out_file = open(file1, "w") out_file.write("# delay 0.5 \n") out_file.write("# setup 0.14 \n") out_file.write("# single_port \n") for i in range(len(lib_list)): if lib_list[i][-1] == "single": - out_file.write("%s 1 \n" %(' '.join(map(str, list(lib_list[i][0:-1]))))) + out_file.write("%s 1 \n" % + (' '.join(map(str, list(lib_list[i][0:-1]))))) elif lib_list[i][-1] == "dual": dual_list.append(lib_list[i]) if len(dual_list) > 0: out_file.write("# dual_port \n") for i in range(len(dual_list)): if dual_list[i][-1] == "dual": - out_file.write("%s 2 \n" %(' '.join(map(str, list(dual_list[i][0:-1]))))) - out_file.close() + out_file.write("%s 2 \n" % + (' '.join(map(str, list(dual_list[i][0:-1]))))) + out_file.close() + - def print_wrap_sp(file1, module1, address1, word1, macro_name): if os.path.exists(file1): @@ -118,24 +123,27 @@ def print_wrap_sp(file1, module1, address1, word1, macro_name): out_file = open(file1, "w") out_file.write("`timescale 1 ps / 1ps \n") out_file.write("\n") - out_file.write("module %s (CLK, A0, D0, Q0, WE0, WEM0, CE0); \n" %module1) + out_file.write( + "module %s (CLK, A0, D0, Q0, WE0, WEM0, CE0); \n" % + module1) out_file.write("\n") out_file.write(" input CLK;\n") out_file.write(" input WE0;\n") out_file.write(" input CE0;\n") - out_file.write(" input [%d : 0] A0;\n" %(address1 - 1)) - out_file.write(" input [%d : 0] D0;\n" %(word1 - 1)) - out_file.write(" input [%d : 0] WEM0;\n" %(word1 - 1)) - out_file.write(" output [%d : 0] Q0;\n" %(word1 - 1)) + out_file.write(" input [%d : 0] A0;\n" % (address1 - 1)) + out_file.write(" input [%d : 0] D0;\n" % (word1 - 1)) + out_file.write(" input [%d : 0] WEM0;\n" % (word1 - 1)) + out_file.write(" output [%d : 0] Q0;\n" % (word1 - 1)) out_file.write("\n") - out_file.write("// In case of chip enable and write enable active low \n") + out_file.write( + "// In case of chip enable and write enable active low \n") out_file.write("// Uncomment this logic \n") out_file.write("/* \n") out_file.write(" reg CEN; \n") out_file.write(" reg GWEN; \n") - out_file.write(" reg [%d : 0] WEN; \n" %(word1 -1)) - out_file.write(" reg [%d : 0] A; \n" %(address1 -1)) - out_file.write(" reg [%d : 0] D; \n" %(word1 -1)) + out_file.write(" reg [%d : 0] WEN; \n" % (word1 - 1)) + out_file.write(" reg [%d : 0] A; \n" % (address1 - 1)) + out_file.write(" reg [%d : 0] D; \n" % (word1 - 1)) out_file.write("\n") out_file.write(" always @(*) begin \n") out_file.write(" CEN = ~CE0; \n") @@ -146,10 +154,11 @@ def print_wrap_sp(file1, module1, address1, word1, macro_name): out_file.write(" end \n") out_file.write("*/ \n") out_file.write("\n") - out_file.write(" %s sram \n" %macro_name) + out_file.write(" %s sram \n" % macro_name) out_file.write(" ( \n") out_file.write("// map the memory interface with the wrapper \n") - out_file.write("// assign constants or create your own logic for missing ports \n") + out_file.write( + "// assign constants or create your own logic for missing ports \n") out_file.write(" ); \n") out_file.write("\n") out_file.write("endmodule") @@ -157,14 +166,14 @@ def print_wrap_sp(file1, module1, address1, word1, macro_name): def print_wrap_dp(file1, module1, address1, word1, macro_name): - + if os.path.exists(file1): None else: out_file = open(file1, "w") out_file.write("`timescale 1 ps / 1ps \n") out_file.write("\n") - out_file.write("module %s (CLK0, A0, Q0, CE0, \n" %module1) + out_file.write("module %s (CLK0, A0, Q0, CE0, \n" % module1) out_file.write(" CLK1, A1, D1, WE1, WEM1, CE1); \n") out_file.write("\n") out_file.write(" input CLK0;\n") @@ -172,41 +181,46 @@ def print_wrap_dp(file1, module1, address1, word1, macro_name): out_file.write(" input CE0;\n") out_file.write(" input CE1;\n") out_file.write(" input WE1;\n") - out_file.write(" input [%d : 0] A0;\n" %(address1 - 1)) - out_file.write(" input [%d : 0] A1;\n" %(address1 - 1)) - out_file.write(" input [%d : 0] D1;\n" %(word1 - 1)) - out_file.write(" input [%d : 0] WEM1;\n" %(word1 - 1)) - out_file.write(" output [%d : 0] Q0;\n" %(word1 - 1)) + out_file.write(" input [%d : 0] A0;\n" % (address1 - 1)) + out_file.write(" input [%d : 0] A1;\n" % (address1 - 1)) + out_file.write(" input [%d : 0] D1;\n" % (word1 - 1)) + out_file.write(" input [%d : 0] WEM1;\n" % (word1 - 1)) + out_file.write(" output [%d : 0] Q0;\n" % (word1 - 1)) out_file.write("\n") - out_file.write("// In case of chip enable and write enable active low \n") + out_file.write( + "// In case of chip enable and write enable active low \n") out_file.write("// Uncomment this logic \n") out_file.write("/* \n") out_file.write(" reg P0_CEN; \n") out_file.write(" reg P1_CEN; \n") - out_file.write(" reg [%d : 0] P1_WEN; \n" %(word1 -1)) - out_file.write(" reg [%d : 0] P0_A; \n" %(address1 -1)) - out_file.write(" reg [%d : 0] P1_A; \n" %(address1 -1)) - out_file.write(" reg [%d : 0] P1_D; \n" %(word1 -1)) + out_file.write(" reg [%d : 0] P1_WEN; \n" % (word1 - 1)) + out_file.write(" reg [%d : 0] P0_A; \n" % (address1 - 1)) + out_file.write(" reg [%d : 0] P1_A; \n" % (address1 - 1)) + out_file.write(" reg [%d : 0] P1_D; \n" % (word1 - 1)) out_file.write("\n") out_file.write(" always @(*) begin \n") out_file.write(" P0_CEN = ~CE0; \n") out_file.write(" P0_A = A0; \n") out_file.write(" P1_CEN = ~CE1; \n") - out_file.write(" P1_WEN = (WE1 == 1'b1)? ~WEM1 : {%d{1'b1}}; \n" %word1) + out_file.write( + " P1_WEN = (WE1 == 1'b1)? ~WEM1 : {%d{1'b1}}; \n" % + word1) out_file.write(" P1_A = A1; \n") out_file.write(" P1_D = D1; \n") out_file.write(" end \n") out_file.write("*/ \n") out_file.write("\n") - out_file.write(" %s sram \n" %macro_name) + out_file.write(" %s sram \n" % macro_name) out_file.write(" ( \n") out_file.write("// map the memory interface with the wrapper \n") - out_file.write("// assign constants or create your own logic for missing ports \n") + out_file.write( + "// assign constants or create your own logic for missing ports \n") out_file.write(" ); \n") out_file.write("\n") out_file.write("endmodule") out_file.close() + def print_cache_def(memory, module, address_size): file = "cache_def_mem_asic.sv" @@ -220,23 +234,28 @@ def print_cache_def(memory, module, address_size): f_split = f[i].split("_") f_mem_list.append(f_split[0].split()[1]) if mem_type not in f_mem_list: - out_file.write("`define %s_ASIC_SRAM_SIZE %s \n" %(mem_type, address_size)) + out_file.write( + "`define %s_ASIC_SRAM_SIZE %s \n" % + (mem_type, address_size)) if memory not in f: - out_file.write("`define %s %s \n" %(memory, module)) + out_file.write("`define %s %s \n" % (memory, module)) else: out_file = open(file, "w") - out_file.write("`define %s_ASIC_SRAM_SIZE %s \n" %(mem_type, address_size)) - out_file.write("`define %s %s \n" %(memory, module)) + out_file.write( + "`define %s_ASIC_SRAM_SIZE %s \n" % + (mem_type, address_size)) + out_file.write("`define %s %s \n" % (memory, module)) out_file.close() + def llc_policy_check(mem_dict): idx = {} valid_addresses = [] valid_bits = ["64", "28", "16"] for i in range(len(mem_dict["llc"])): idx[mem_dict["llc"][i]["address_size"]] = 0 - + for i in range(len(mem_dict["llc"])): if int(mem_dict["llc"][i]["word_size"]) == 64: idx[mem_dict["llc"][i]["address_size"]] += 1 @@ -247,25 +266,26 @@ def llc_policy_check(mem_dict): for i in idx.keys(): if idx[i] == 3: - #print("LLC address size %s passed in policy check" %i) + # print("LLC address size %s passed in policy check" %i) valid_addresses.append(i) elif idx[i] == 2: - print("Error: \"llc %s failed in policy check\" " %i) + print("Error: \"llc %s failed in policy check\" " % i) print(" LLC must have the same address size for 64, 28, and 16 bits") elif idx[i] == 1: - print("Error: \"llc %s failed in policy check\" " %i) + print("Error: \"llc %s failed in policy check\" " % i) print(" LLC must have the same address size for 64, 28, and 16 bits") - + for i in range(len(mem_dict["llc"])): if mem_dict["llc"][i]["word_size"] not in valid_bits: - print("Error: \"llc %s\" " %(' '.join(map(str, list(mem_dict["llc"][i].values()))))) + print("Error: \"llc %s\" " % + (' '.join(map(str, list(mem_dict["llc"][i].values()))))) print(''' LLC must have the following word sizes: CACHE LINE -> 64 bits CACHE MIXED -> 28 bits CACHE SHARED -> 16 bits ''') - valid_addresses.sort() + valid_addresses.sort() return valid_addresses @@ -274,15 +294,18 @@ def llc_sp_gen(out_path, mem_dict, val_addr): lib_list = [] cnt = 0 - + for idx in range(len(mem_dict["llc"])): if mem_dict["llc"][idx]["address_size"] in val_addr: if int(mem_dict["llc"][idx]["word_size"]) == 64: - file = out_path + "/LLC_SRAM_SP_LINE_" + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] + ".v" - #file = out_path + "/LLC_SRAM_SP_LINE" + ".v" - module = "LLC_SRAM_SP_LINE_" + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] + file = out_path + "/LLC_SRAM_SP_LINE_" + \ + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] + ".v" + # file = out_path + "/LLC_SRAM_SP_LINE" + ".v" + module = "LLC_SRAM_SP_LINE_" + \ + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] memory = "LLC_SRAM_SP_LINE" - address = int(math.log(int(mem_dict["llc"][idx]["address_size"]),2)) + address = int( + math.log(int(mem_dict["llc"][idx]["address_size"]), 2)) word = int(mem_dict["llc"][idx]["word_size"]) macro_name = mem_dict["llc"][idx]["macro_name"] address_size = mem_dict["llc"][idx]["address_size"] @@ -293,17 +316,21 @@ def llc_sp_gen(out_path, mem_dict, val_addr): None else: print_wrap_sp(file, module, address, word, macro_name) - print("\"llc %s\" generated!" %(' '.join(map(str, list(mem_dict["llc"][idx].values()))))) + print("\"llc %s\" generated!" % + (' '.join(map(str, list(mem_dict["llc"][idx].values()))))) if cnt < 3: print_cache_def(memory, module, address_size) cnt += 1 - + elif int(mem_dict["llc"][idx]["word_size"]) == 28: - file = out_path + "/LLC_SRAM_SP_MIXED_" + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] + ".v" - #file = out_path + "/LLC_SRAM_SP_MIXED" + ".v" - module = "LLC_SRAM_SP_MIXED_" + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] + file = out_path + "/LLC_SRAM_SP_MIXED_" + \ + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] + ".v" + # file = out_path + "/LLC_SRAM_SP_MIXED" + ".v" + module = "LLC_SRAM_SP_MIXED_" + \ + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] memory = "LLC_SRAM_SP_MIXED" - address = int(math.log(int(mem_dict["llc"][idx]["address_size"]),2)) + address = int( + math.log(int(mem_dict["llc"][idx]["address_size"]), 2)) word = int(mem_dict["llc"][idx]["word_size"]) macro_name = mem_dict["llc"][idx]["macro_name"] address_size = mem_dict["llc"][idx]["address_size"] @@ -314,18 +341,21 @@ def llc_sp_gen(out_path, mem_dict, val_addr): None else: print_wrap_sp(file, module, address, word, macro_name) - print("\"llc %s\" generated!" %(' '.join(map(str, list(mem_dict["llc"][idx].values()))))) + print("\"llc %s\" generated!" % + (' '.join(map(str, list(mem_dict["llc"][idx].values()))))) if cnt < 3: print_cache_def(memory, module, address_size) cnt += 1 - elif int(mem_dict["llc"][idx]["word_size"]) == 16: - file = out_path + "/LLC_SRAM_SP_SHARED_" + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] + ".v" - #file = out_path + "/LLC_SRAM_SP_SHARED" + ".v" - module = "LLC_SRAM_SP_SHARED_" + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] + file = out_path + "/LLC_SRAM_SP_SHARED_" + \ + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] + ".v" + # file = out_path + "/LLC_SRAM_SP_SHARED" + ".v" + module = "LLC_SRAM_SP_SHARED_" + \ + mem_dict["llc"][idx]["address_size"] + "x" + mem_dict["llc"][idx]["word_size"] memory = "LLC_SRAM_SP_SHARED" - address = int(math.log(int(mem_dict["llc"][idx]["address_size"]),2)) + address = int( + math.log(int(mem_dict["llc"][idx]["address_size"]), 2)) word = int(mem_dict["llc"][idx]["word_size"]) macro_name = mem_dict["llc"][idx]["macro_name"] address_size = mem_dict["llc"][idx]["address_size"] @@ -336,15 +366,16 @@ def llc_sp_gen(out_path, mem_dict, val_addr): None else: print_wrap_sp(file, module, address, word, macro_name) - print("\"llc %s\" generated!" %(' '.join(map(str, list(mem_dict["llc"][idx].values()))))) + print("\"llc %s\" generated!" % + (' '.join(map(str, list(mem_dict["llc"][idx].values()))))) if cnt < 3: print_cache_def(memory, module, address_size) cnt += 1 - + else: None - - if len(lib_list)>0: + + if len(lib_list) > 0: file = out_path + "/llc_lib.txt" print_lib(file, lib_list) @@ -355,7 +386,7 @@ def l2_policy_check(mem_dict): valid_bits = ["64", "24"] for i in range(len(mem_dict["l2"])): idx[mem_dict["l2"][i]["address_size"]] = 0 - + for i in range(len(mem_dict["l2"])): if int(mem_dict["l2"][i]["word_size"]) == 64: idx[mem_dict["l2"][i]["address_size"]] += 1 @@ -364,22 +395,23 @@ def l2_policy_check(mem_dict): for i in idx.keys(): if idx[i] == 2: - #print("L2 address size %s passed in policy check" %i) + # print("L2 address size %s passed in policy check" %i) valid_addresses.append(i) elif idx[i] == 1: - print("Error: \"l2 %s failed in policy check\" " %i) + print("Error: \"l2 %s failed in policy check\" " % i) print(" L2 must have the same address size for 64, and 24 bits") - + for i in range(len(mem_dict["l2"])): if mem_dict["l2"][i]["word_size"] not in valid_bits: - print("Error: \"l2 %s\" " %(' '.join(map(str, list(mem_dict["l2"][i].values()))))) + print("Error: \"l2 %s\" " % + (' '.join(map(str, list(mem_dict["l2"][i].values()))))) print(''' L2 must have the following word sizes: CACHE LINE -> 64 bits CACHE MIXED -> 24 bits ''') - + valid_addresses.sort() - + return valid_addresses @@ -387,15 +419,18 @@ def l2_sp_gen(out_path, mem_dict, val_addr): lib_list = [] cnt = 0 - + for idx in range(len(mem_dict["l2"])): if mem_dict["l2"][idx]["address_size"] in val_addr: if int(mem_dict["l2"][idx]["word_size"]) == 64: - file = out_path + "/L2_SRAM_SP_LINE_" + mem_dict["l2"][idx]["address_size"] + "x" + mem_dict["l2"][idx]["word_size"] + ".v" - #file = out_path + "/L2_SRAM_SP_LINE" + ".v" - module = "L2_SRAM_SP_LINE_" + mem_dict["l2"][idx]["address_size"] + "x" + mem_dict["l2"][idx]["word_size"] + file = out_path + "/L2_SRAM_SP_LINE_" + \ + mem_dict["l2"][idx]["address_size"] + "x" + mem_dict["l2"][idx]["word_size"] + ".v" + # file = out_path + "/L2_SRAM_SP_LINE" + ".v" + module = "L2_SRAM_SP_LINE_" + \ + mem_dict["l2"][idx]["address_size"] + "x" + mem_dict["l2"][idx]["word_size"] memory = "L2_SRAM_SP_LINE" - address = int(math.log(int(mem_dict["l2"][idx]["address_size"]),2)) + address = int( + math.log(int(mem_dict["l2"][idx]["address_size"]), 2)) word = int(mem_dict["l2"][idx]["word_size"]) macro_name = mem_dict["l2"][idx]["macro_name"] address_size = mem_dict["l2"][idx]["address_size"] @@ -406,17 +441,21 @@ def l2_sp_gen(out_path, mem_dict, val_addr): None else: print_wrap_sp(file, module, address, word, macro_name) - print("\"l2 %s\" generated!" %(' '.join(map(str, list(mem_dict["l2"][idx].values()))))) + print("\"l2 %s\" generated!" % + (' '.join(map(str, list(mem_dict["l2"][idx].values()))))) if cnt < 2: print_cache_def(memory, module, address_size) cnt += 1 - + elif int(mem_dict["l2"][idx]["word_size"]) == 24: - file = out_path + "/L2_SRAM_SP_MIXED_" + mem_dict["l2"][idx]["address_size"] + "x" + mem_dict["l2"][idx]["word_size"] + ".v" - #file = out_path + "/L2_SRAM_SP_MIXED" + ".v" - module = "L2_SRAM_SP_MIXED_" + mem_dict["l2"][idx]["address_size"] + "x" + mem_dict["l2"][idx]["word_size"] + file = out_path + "/L2_SRAM_SP_MIXED_" + \ + mem_dict["l2"][idx]["address_size"] + "x" + mem_dict["l2"][idx]["word_size"] + ".v" + # file = out_path + "/L2_SRAM_SP_MIXED" + ".v" + module = "L2_SRAM_SP_MIXED_" + \ + mem_dict["l2"][idx]["address_size"] + "x" + mem_dict["l2"][idx]["word_size"] memory = "L2_SRAM_SP_MIXED" - address = int(math.log(int(mem_dict["l2"][idx]["address_size"]),2)) + address = int( + math.log(int(mem_dict["l2"][idx]["address_size"]), 2)) word = int(mem_dict["l2"][idx]["word_size"]) macro_name = mem_dict["l2"][idx]["macro_name"] address_size = mem_dict["l2"][idx]["address_size"] @@ -427,30 +466,31 @@ def l2_sp_gen(out_path, mem_dict, val_addr): None else: print_wrap_sp(file, module, address, word, macro_name) - print("\"l2 %s\" generated!" %(' '.join(map(str, list(mem_dict["l2"][idx].values()))))) + print("\"l2 %s\" generated!" % + (' '.join(map(str, list(mem_dict["l2"][idx].values()))))) if cnt < 2: print_cache_def(memory, module, address_size) cnt += 1 - + else: None - - if len(lib_list)>0: + + if len(lib_list) > 0: file = out_path + "/l2_lib.txt" print_lib(file, lib_list) def l1_sp_gen(out_path, mem_dict): - + lib_list = [] if int(mem_dict["l1"][0]["word_size"]) == 64: if int(mem_dict["l1"][0]["address_size"]) == 256: - #file = out_path + "/L1_SRAM_SP_" + mem_dict["l1"][0]["address_size"] + "x" + mem_dict["l1"][0]["word_size"] + ".v" + # file = out_path + "/L1_SRAM_SP_" + mem_dict["l1"][0]["address_size"] + "x" + mem_dict["l1"][0]["word_size"] + ".v" file = out_path + "/L1_SRAM_SP" + ".v" - #module = "L1_SRAM_SP_" + mem_dict["l1"][0]["address_size"] + "x" + mem_dict["l1"][0]["word_size"] + # module = "L1_SRAM_SP_" + mem_dict["l1"][0]["address_size"] + "x" + mem_dict["l1"][0]["word_size"] module = "L1_SRAM_SP" - address = int(math.log(int(mem_dict["l1"][0]["address_size"]),2)) + address = int(math.log(int(mem_dict["l1"][0]["address_size"]), 2)) word = int(mem_dict["l1"][0]["word_size"]) macro_name = mem_dict["l1"][0]["macro_name"] address_size = mem_dict["l1"][0]["address_size"] @@ -461,45 +501,51 @@ def l1_sp_gen(out_path, mem_dict): None else: print_wrap_sp(file, module, address, word, macro_name) - print("\"l1 %s\" generated!" %(' '.join(map(str, list(mem_dict["l1"][0].values()))))) + print("\"l1 %s\" generated!" % + (' '.join(map(str, list(mem_dict["l1"][0].values()))))) file = out_path + "/l1_lib.txt" print_lib(file, lib_list) - + else: - print("Error: \"l1 %s\" " %(' '.join(map(str, list(mem_dict["l1"][0].values()))))) + print("Error: \"l1 %s\" " % + (' '.join(map(str, list(mem_dict["l1"][0].values()))))) print(''' L1 must have 256 address size ''') else: - print("Error: \"l1 %s\" " %(' '.join(map(str, list(mem_dict["l1"][0].values()))))) + print("Error: \"l1 %s\" " % + (' '.join(map(str, list(mem_dict["l1"][0].values()))))) print(''' L1 must have 64 word size ''') - def slm_policy_check(mem_dict): valid_word_size = [] valid_bits = ["64"] - + for i in range(len(mem_dict["slm"])): if mem_dict["slm"][i]["word_size"] not in valid_bits: - print("Error: \"slm %s\" " %(' '.join(map(str, list(mem_dict["slm"][i].values()))))) + print("Error: \"slm %s\" " % + (' '.join(map(str, list(mem_dict["slm"][i].values()))))) print(''' SLM must have word size of 64 ''') else: valid_word_size.append(mem_dict["slm"][i]["word_size"]) - + return valid_word_size def slm_sp_gen(out_path, mem_dict, val_word): lib_list = [] - + for idx in range(len(mem_dict["slm"])): if mem_dict["slm"][idx]["word_size"] in val_word: - file = out_path + "/SLM_SRAM_SP_" + mem_dict["slm"][idx]["address_size"] + "x" + mem_dict["slm"][idx]["word_size"] + ".v" - module = "SLM_SRAM_SP_" + mem_dict["slm"][idx]["address_size"] + "x" + mem_dict["slm"][idx]["word_size"] - address = int(math.log(int(mem_dict["slm"][idx]["address_size"]),2)) + file = out_path + "/SLM_SRAM_SP_" + \ + mem_dict["slm"][idx]["address_size"] + "x" + mem_dict["slm"][idx]["word_size"] + ".v" + module = "SLM_SRAM_SP_" + \ + mem_dict["slm"][idx]["address_size"] + "x" + mem_dict["slm"][idx]["word_size"] + address = int( + math.log(int(mem_dict["slm"][idx]["address_size"]), 2)) word = int(mem_dict["slm"][idx]["word_size"]) macro_name = mem_dict["slm"][idx]["macro_name"] address_size = mem_dict["slm"][idx]["address_size"] @@ -510,8 +556,9 @@ def slm_sp_gen(out_path, mem_dict, val_word): None else: print_wrap_sp(file, module, address, word, macro_name) - print("\"slm %s\" generated!" %(' '.join(map(str, list(mem_dict["slm"][idx].values()))))) - + print("\"slm %s\" generated!" % + (' '.join(map(str, list(mem_dict["slm"][idx].values()))))) + else: None @@ -521,59 +568,74 @@ def slm_sp_gen(out_path, mem_dict, val_word): def io_dp_policy_check(mem_dict): - + valid_conf = [] - valid_comb = [("4096","16"), ("256","32")] - + valid_comb = [("4096", "16"), ("256", "32")] + for i in range(len(mem_dict["io"])): if mem_dict["io"][i]["port_type"] == "dual": - if (mem_dict["io"][i]["address_size"], mem_dict["io"][i]["word_size"]) not in valid_comb: - print("Error: \"io %s\" " %(' '.join(map(str, list(mem_dict["io"][i].values()))))) - print(''' Dual port IO memory supports the following configuration: + if (mem_dict["io"][i]["address_size"], + mem_dict["io"][i]["word_size"]) not in valid_comb: + print("Error: \"io %s\" " % + (' '.join(map(str, list(mem_dict["io"][i].values()))))) + print( + ''' Dual port IO memory supports the following configuration: address size of 4096 and word size of 16 bits address size of 256 and word size of 32 bits ''') else: - valid_conf.append((mem_dict["io"][i]["address_size"], mem_dict["io"][i]["word_size"])) - + valid_conf.append( + (mem_dict["io"][i]["address_size"], + mem_dict["io"][i]["word_size"])) + return valid_conf def io_sp_policy_check(mem_dict): - + valid_conf = [] valid_bits = ["8"] valid_addresses = ["256", "512", "1024", "2048", "4096", "8192", "16384"] - + for i in range(len(mem_dict["io"])): if mem_dict["io"][i]["port_type"] == "single": if mem_dict["io"][i]["address_size"] not in valid_addresses: - print("Error: \"io %s\" " %(' '.join(map(str, list(mem_dict["io"][i].values()))))) - print(''' Single port IO memory support the following address sizes: + print("Error: \"io %s\" " % + (' '.join(map(str, list(mem_dict["io"][i].values()))))) + print( + ''' Single port IO memory support the following address sizes: %s - ''' %(' '.join(map(str, list(valid_addresses))))) + ''' % (' '.join(map(str, list(valid_addresses))))) elif mem_dict["io"][i]["word_size"] not in valid_bits: - print("Error: \"io %s\" " %(' '.join(map(str, list(mem_dict["io"][i].values()))))) - print(''' Single port IO memory support the following bit sizes: + print("Error: \"io %s\" " % + (' '.join(map(str, list(mem_dict["io"][i].values()))))) + print( + ''' Single port IO memory support the following bit sizes: %s - ''' %(' '.join(map(str, list(valid_bits))))) - + ''' % (' '.join(map(str, list(valid_bits))))) + else: - valid_conf.append((mem_dict["io"][i]["address_size"], mem_dict["io"][i]["word_size"])) - + valid_conf.append( + (mem_dict["io"][i]["address_size"], + mem_dict["io"][i]["word_size"])) + return valid_conf def io_gen(out_path, mem_dict, val_dp_conf, val_sp_conf): - + lib_list = [] for idx in range(len(mem_dict["io"])): if mem_dict["io"][idx]["port_type"] == "dual": - if (mem_dict["io"][idx]["address_size"], mem_dict["io"][idx]["word_size"]) in val_dp_conf: - file = out_path + "/IO_DP_" + mem_dict["io"][idx]["address_size"] + "x" + mem_dict["io"][idx]["word_size"] + ".v" - module = "IO_DP_" + mem_dict["io"][idx]["address_size"] + "x" + mem_dict["io"][idx]["word_size"] - address = int(math.log(int(mem_dict["io"][idx]["address_size"]),2)) + if (mem_dict["io"][idx]["address_size"], + mem_dict["io"][idx]["word_size"]) in val_dp_conf: + file = out_path + "/IO_DP_" + \ + mem_dict["io"][idx]["address_size"] + "x" + mem_dict["io"][idx]["word_size"] + ".v" + module = "IO_DP_" + \ + mem_dict["io"][idx]["address_size"] + "x" + mem_dict["io"][idx]["word_size"] + address = int( + math.log(int(mem_dict["io"][idx]["address_size"]), 2)) word = int(mem_dict["io"][idx]["word_size"]) macro_name = mem_dict["io"][idx]["macro_name"] address_size = mem_dict["io"][idx]["address_size"] @@ -584,16 +646,21 @@ def io_gen(out_path, mem_dict, val_dp_conf, val_sp_conf): None else: print_wrap_dp(file, module, address, word, macro_name) - print("\"io dual port %s\" generated!" %(' '.join(map(str, list(mem_dict["io"][idx].values()))))) - + print("\"io dual port %s\" generated!" % + (' '.join(map(str, list(mem_dict["io"][idx].values()))))) + else: None elif mem_dict["io"][idx]["port_type"] == "single": - if (mem_dict["io"][idx]["address_size"], mem_dict["io"][idx]["word_size"]) in val_sp_conf: - file = out_path + "/IO_SP_" + mem_dict["io"][idx]["address_size"] + "x" + mem_dict["io"][idx]["word_size"] + ".v" - module = "IO_SP_" + mem_dict["io"][idx]["address_size"] + "x" + mem_dict["io"][idx]["word_size"] - address = int(math.log(int(mem_dict["io"][idx]["address_size"]),2)) + if (mem_dict["io"][idx]["address_size"], + mem_dict["io"][idx]["word_size"]) in val_sp_conf: + file = out_path + "/IO_SP_" + \ + mem_dict["io"][idx]["address_size"] + "x" + mem_dict["io"][idx]["word_size"] + ".v" + module = "IO_SP_" + \ + mem_dict["io"][idx]["address_size"] + "x" + mem_dict["io"][idx]["word_size"] + address = int( + math.log(int(mem_dict["io"][idx]["address_size"]), 2)) word = int(mem_dict["io"][idx]["word_size"]) macro_name = mem_dict["io"][idx]["macro_name"] address_size = mem_dict["io"][idx]["address_size"] @@ -604,24 +671,29 @@ def io_gen(out_path, mem_dict, val_dp_conf, val_sp_conf): None else: print_wrap_sp(file, module, address, word, macro_name) - print("\"io single port %s\" generated!" %(' '.join(map(str, list(mem_dict["io"][idx].values()))))) - + print("\"io single port %s\" generated!" % + (' '.join(map(str, list(mem_dict["io"][idx].values()))))) + else: - None - + None + if len(lib_list) > 0: file = out_path + "/io_lib.txt" print_lib(file, lib_list) + def acc_gen(out_path, mem_dict): - + lib_list = [] for idx in range(len(mem_dict["acc"])): if mem_dict["acc"][idx]["port_type"] == "dual": - file = out_path + "/ACC_SRAM_DP_" + mem_dict["acc"][idx]["address_size"] + "x" + mem_dict["acc"][idx]["word_size"] + ".v" - module = "ACC_SRAM_DP_" + mem_dict["acc"][idx]["address_size"] + "x" + mem_dict["acc"][idx]["word_size"] - address = int(math.log(int(mem_dict["acc"][idx]["address_size"]),2)) + file = out_path + "/ACC_SRAM_DP_" + \ + mem_dict["acc"][idx]["address_size"] + "x" + mem_dict["acc"][idx]["word_size"] + ".v" + module = "ACC_SRAM_DP_" + \ + mem_dict["acc"][idx]["address_size"] + "x" + mem_dict["acc"][idx]["word_size"] + address = int( + math.log(int(mem_dict["acc"][idx]["address_size"]), 2)) word = int(mem_dict["acc"][idx]["word_size"]) macro_name = mem_dict["acc"][idx]["macro_name"] address_size = mem_dict["acc"][idx]["address_size"] @@ -632,12 +704,16 @@ def acc_gen(out_path, mem_dict): None else: print_wrap_dp(file, module, address, word, macro_name) - print("\"acc dual port %s\" generated!" %(' '.join(map(str, list(mem_dict["acc"][idx].values()))))) - + print("\"acc dual port %s\" generated!" % + (' '.join(map(str, list(mem_dict["acc"][idx].values()))))) + elif mem_dict["acc"][idx]["port_type"] == "single": - file = out_path + "/ACC_SRAM_SP_" + mem_dict["acc"][idx]["address_size"] + "x" + mem_dict["acc"][idx]["word_size"] + ".v" - module = "ACC_SRAM_SP_" + mem_dict["acc"][idx]["address_size"] + "x" + mem_dict["acc"][idx]["word_size"] - address = int(math.log(int(mem_dict["acc"][idx]["address_size"]),2)) + file = out_path + "/ACC_SRAM_SP_" + \ + mem_dict["acc"][idx]["address_size"] + "x" + mem_dict["acc"][idx]["word_size"] + ".v" + module = "ACC_SRAM_SP_" + \ + mem_dict["acc"][idx]["address_size"] + "x" + mem_dict["acc"][idx]["word_size"] + address = int( + math.log(int(mem_dict["acc"][idx]["address_size"]), 2)) word = int(mem_dict["acc"][idx]["word_size"]) macro_name = mem_dict["acc"][idx]["macro_name"] address_size = mem_dict["acc"][idx]["address_size"] @@ -648,15 +724,17 @@ def acc_gen(out_path, mem_dict): None else: print_wrap_sp(file, module, address, word, macro_name) - print("\"acc single port %s\" generated!" %(' '.join(map(str, list(mem_dict["acc"][idx].values()))))) - + print("\"acc single port %s\" generated!" % + (' '.join(map(str, list(mem_dict["acc"][idx].values()))))) + else: - None - + None + if len(lib_list) > 0: file = out_path + "/acc_lib.txt" print_lib(file, lib_list) + out_path = sys.argv[1] memory_list = [] with open("asic_memlist.txt", "r") as memories: @@ -665,11 +743,11 @@ def acc_gen(out_path, mem_dict): memories.close() mem_dict = {"llc": [], - "l2": [], - "l1": [], - "slm": [], - "io": [], - "acc": []} + "l2": [], + "l1": [], + "slm": [], + "io": [], + "acc": []} mem_dict = data_struct(memory_list) diff --git a/tools/esplink/src/edcl.c b/tools/esplink/src/edcl.c index 96e134cb8b..84a37b0667 100644 --- a/tools/esplink/src/edcl.c +++ b/tools/esplink/src/edcl.c @@ -5,146 +5,141 @@ // Helper functions static void print_progress(u64 progress, u64 total, const char *prefix) { - const u32 symbols = 40; - int i; + const u32 symbols = 40; + int i; - u64 percent = progress * 100 / total; + u64 percent = progress * 100 / total; - u64 fraction = progress * symbols / total; + u64 fraction = progress * symbols / total; - printf("%s: [", prefix); + printf("%s: [", prefix); - for (i = 0; i < symbols; ++i) { - char c = i < fraction ? '#' : ' '; - printf("%c", c); - } + for (i = 0; i < symbols; ++i) { + char c = i < fraction ? '#' : ' '; + printf("%c", c); + } - printf("] %lld%%", percent); - if (progress == total) - printf("\n"); - else - printf("\r"); - fflush(stdout); + printf("] %lld%%", percent); + if (progress == total) printf("\n"); + else + printf("\r"); + fflush(stdout); } static void set_offset(u8 *_m, u32 _x) { - _m[0] = (u8) (_x >> 8); - _m[1] = (u8) (_x >> 0); + _m[0] = (u8)(_x >> 8); + _m[1] = (u8)(_x >> 0); } static u32 get_offset(u8 *_m) { - u32 _x; - _x = ((u32) _m[0]) << 8; - _x |= ((u32) _m[1]) << 0; - return _x; + u32 _x; + _x = ((u32)_m[0]) << 8; + _x |= ((u32)_m[1]) << 0; + return _x; } void set_sequence(u8 *_m, u32 _x) { - _m[2] = _m[2] | (u8) (0xff & ((_x << 2) >> 8)); - _m[3] = _m[3] | (u8) (0xff & ((_x << 2) >> 0)); + _m[2] = _m[2] | (u8)(0xff & ((_x << 2) >> 8)); + _m[3] = _m[3] | (u8)(0xff & ((_x << 2) >> 0)); } u32 get_sequence(u8 *_m) { - u32 _x; - _x = (((u32) _m[2]) << 8) >> 2; - _x |= (((u32) _m[3]) << 0) >> 2; - return _x; + u32 _x; + _x = (((u32)_m[2]) << 8) >> 2; + _x |= (((u32)_m[3]) << 0) >> 2; + return _x; } -void set_write(u8 *_m, u32 _x) -{ - _m[3] = _m[3] | (u8) (_x << 1); -} +void set_write(u8 *_m, u32 _x) { _m[3] = _m[3] | (u8)(_x << 1); } u32 get_nack(u8 *_m) { - u32 _x; - _x = 0x1 & (((u32) _m[3]) >> 1); - return _x; + u32 _x; + _x = 0x1 & (((u32)_m[3]) >> 1); + return _x; } void set_length(u8 *_m, u32 _x) { - _m[3] = _m[3] | (u8) (0xff & (_x >> 9)); - _m[4] = _m[4] | (u8) (0xff & (_x >> 1)); - _m[5] = _m[5] | (u8) (0xff & (_x << 7)); + _m[3] = _m[3] | (u8)(0xff & (_x >> 9)); + _m[4] = _m[4] | (u8)(0xff & (_x >> 1)); + _m[5] = _m[5] | (u8)(0xff & (_x << 7)); } u32 get_length(u8 *_m) { - u32 _x; - _x = (0x1 & (u32) _m[3]) << 9; - _x |= ((u32) _m[4]) << 1; - _x |= ((u32) _m[5]) >> 7; - return _x; + u32 _x; + _x = (0x1 & (u32)_m[3]) << 9; + _x |= ((u32)_m[4]) << 1; + _x |= ((u32)_m[5]) >> 7; + return _x; } void set_address(u8 *_m, u32 _x) { - _m[6] = (u8) (0xff & (_x >> 24)); - _m[7] = (u8) (0xff & (_x >> 16)); - _m[8] = (u8) (0xff & (_x >> 8)); - _m[9] = (u8) (0xff & (_x >> 0)); + _m[6] = (u8)(0xff & (_x >> 24)); + _m[7] = (u8)(0xff & (_x >> 16)); + _m[8] = (u8)(0xff & (_x >> 8)); + _m[9] = (u8)(0xff & (_x >> 0)); } u32 get_address(u8 *_m) { - u32 _x; - _x = ((u32) _m[6]) << 24; - _x |= ((u32) _m[7]) << 16; - _x |= ((u32) _m[8]) << 8; - _x |= ((u32) _m[9]) << 0; - return _x; + u32 _x; + _x = ((u32)_m[6]) << 24; + _x |= ((u32)_m[7]) << 16; + _x |= ((u32)_m[8]) << 8; + _x |= ((u32)_m[9]) << 0; + return _x; } void set_data(u8 *_m, u32 *_x, u32 _n) { - u32 i; - for (i = 0; i < _n; i++) { - u32 index = i * 4 + 10; - _m[index + 0] = (u8) (0xff & (_x[i] >> 24)); - _m[index + 1] = (u8) (0xff & (_x[i] >> 16)); - _m[index + 2] = (u8) (0xff & (_x[i] >> 8)); - _m[index + 3] = (u8) (0xff & (_x[i] >> 0)); - } + u32 i; + for (i = 0; i < _n; i++) { + u32 index = i * 4 + 10; + _m[index + 0] = (u8)(0xff & (_x[i] >> 24)); + _m[index + 1] = (u8)(0xff & (_x[i] >> 16)); + _m[index + 2] = (u8)(0xff & (_x[i] >> 8)); + _m[index + 3] = (u8)(0xff & (_x[i] >> 0)); + } } void get_data(u8 *_m, u32 *_x, u32 _n) { - u32 i; - for (i = 0; i < _n; i++) { - u32 index = i * 4 + 10; - _x[i] = ((u32) _m[index + 0]) << 24; - _x[i] |= ((u32) _m[index + 1]) << 16; - _x[i] |= ((u32) _m[index + 2]) << 8; - _x[i] |= ((u32) _m[index + 3]) << 0; - } + u32 i; + for (i = 0; i < _n; i++) { + u32 index = i * 4 + 10; + _x[i] = ((u32)_m[index + 0]) << 24; + _x[i] |= ((u32)_m[index + 1]) << 16; + _x[i] |= ((u32)_m[index + 2]) << 8; + _x[i] |= ((u32)_m[index + 3]) << 0; + } } static void set_edcl_msg(u8 *buf, edcl_snd_t *msg) { - set_offset(buf, msg->offset); - set_sequence(buf, msg->sequence); - set_write(buf, msg->write); - set_length(buf, msg->length); - set_address(buf, msg->address); - if (msg->write) - set_data(buf, msg->data, msg->length / 4); - msg->msglen = 10 + (msg->write * msg->length); + set_offset(buf, msg->offset); + set_sequence(buf, msg->sequence); + set_write(buf, msg->write); + set_length(buf, msg->length); + set_address(buf, msg->address); + if (msg->write) set_data(buf, msg->data, msg->length / 4); + msg->msglen = 10 + (msg->write * msg->length); } static void get_edcl_msg(u8 *buf, edcl_rcv_t *msg) { - msg->offset = get_offset(buf); - msg->sequence = get_sequence(buf); - msg->nack = get_nack(buf); - msg->length = get_length(buf); - msg->address = get_address(buf); - get_data(buf, msg->data, msg->length / 4); - msg->msglen = 10 + msg->length; + msg->offset = get_offset(buf); + msg->sequence = get_sequence(buf); + msg->nack = get_nack(buf); + msg->length = get_length(buf); + msg->address = get_address(buf); + get_data(buf, msg->data, msg->length / 4); + msg->msglen = 10 + msg->length; } struct sockaddr_in serv_addr, cli_addr; @@ -153,70 +148,72 @@ static int s; static void handle_edcl_message(edcl_snd_t *snd, edcl_rcv_t *rcv) { #ifdef VERBOSE - int i = 0; + int i = 0; #endif - int iter = 0; - u8 *buf_snd = malloc(BUFSIZE_MAX_SND * sizeof(u8)); - u8 *buf_rcv = malloc(BUFSIZE_MAX_RCV * sizeof(u8)); - socklen_t clen = sizeof(struct sockaddr_in); + int iter = 0; + u8 *buf_snd = malloc(BUFSIZE_MAX_SND * sizeof(u8)); + u8 *buf_rcv = malloc(BUFSIZE_MAX_RCV * sizeof(u8)); + socklen_t clen = sizeof(struct sockaddr_in); - // Prepare Ethernet packet payload - set_edcl_msg(buf_snd, snd); + // Prepare Ethernet packet payload + set_edcl_msg(buf_snd, snd); - while (1) { + while (1) { #ifdef VERBOSE - // Print message payload - printf("Sending payload: "); - for (i = 0; i < snd->msglen; i++) - printf("%02x ", buf_snd[i]); - printf("\n"); + // Print message payload + printf("Sending payload: "); + for (i = 0; i < snd->msglen; i++) + printf("%02x ", buf_snd[i]); + printf("\n"); #endif retry: - //send the message - if (sendto(s, buf_snd, snd->msglen , 0 , (struct sockaddr *) &serv_addr, sizeof(struct sockaddr_in)) == -1) - die("sendto()"); - - /* if (!snd->write) { */ - //clear the buffer by filling null, it might have previously received data - memset(buf_rcv,'\0', BUFSIZE_MAX_RCV); - - //try to receive some data, this is a blocking call - if (recvfrom(s, buf_rcv, BUFSIZE_MAX_RCV, 0, (struct sockaddr *) &cli_addr, &clen) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - printf("\ntimeout, retrying...\n"); - goto retry; - } else { - die("recvfrom()"); - } - } - - get_edcl_msg(buf_rcv, rcv); + // send the message + if (sendto(s, buf_snd, snd->msglen, 0, (struct sockaddr *)&serv_addr, + sizeof(struct sockaddr_in)) == -1) + die("sendto()"); + + /* if (!snd->write) { */ + // clear the buffer by filling null, it might have previously received data + memset(buf_rcv, '\0', BUFSIZE_MAX_RCV); + + // try to receive some data, this is a blocking call + if (recvfrom(s, buf_rcv, BUFSIZE_MAX_RCV, 0, (struct sockaddr *)&cli_addr, &clen) == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + printf("\ntimeout, retrying...\n"); + goto retry; + } + else { + die("recvfrom()"); + } + } + + get_edcl_msg(buf_rcv, rcv); #ifdef VERBOSE - // Print received message payload - printf("Receiving payload: "); - for (i = 0; i < rcv->msglen; i++) - printf("%02x ", buf_rcv[i]); - printf("\n"); + // Print received message payload + printf("Receiving payload: "); + for (i = 0; i < rcv->msglen; i++) + printf("%02x ", buf_rcv[i]); + printf("\n"); #endif - // Resend if necessary - if (rcv->nack) { - snd->sequence = rcv->sequence; - set_sequence(buf_snd, snd->sequence); - iter++; - } else { - break; - } - - if (iter > 10) - die("Error: Handle EDCL message failed after 10 attempts"); - /* } else { */ - /* break; */ - /* } */ - } - - free(buf_snd); - free(buf_rcv); + // Resend if necessary + if (rcv->nack) { + snd->sequence = rcv->sequence; + set_sequence(buf_snd, snd->sequence); + iter++; + } + else { + break; + } + + if (iter > 10) die("Error: Handle EDCL message failed after 10 attempts"); + /* } else { */ + /* break; */ + /* } */ + } + + free(buf_snd); + free(buf_rcv); } /* static void clear_rcv_edcl() */ @@ -225,7 +222,8 @@ static void handle_edcl_message(edcl_snd_t *snd, edcl_rcv_t *rcv) /* u8 *buf_rcv = malloc(BUFSIZE_MAX_RCV * sizeof(u8)); */ /* socklen_t clen = sizeof(struct sockaddr_in); */ -/* while (recvfrom(s, buf_rcv, BUFSIZE_MAX_RCV, MSG_DONTWAIT, (struct sockaddr *) &cli_addr, &clen) >= 0) */ +/* while (recvfrom(s, buf_rcv, BUFSIZE_MAX_RCV, MSG_DONTWAIT, (struct sockaddr *) &cli_addr, + * &clen) >= 0) */ /* iter++; */ /* free(buf_rcv); */ @@ -234,291 +232,274 @@ static void handle_edcl_message(edcl_snd_t *snd, edcl_rcv_t *rcv) // EDCL API Functions void die(char *s) { - perror(s); - exit(EXIT_FAILURE); + perror(s); + exit(EXIT_FAILURE); } - void connect_edcl(const char *server) { - /* printf("Connect ESPLink\n"); */ - - // Open socket - if ( (s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - die("socket"); - - struct timeval tv; - tv.tv_sec = 3; - tv.tv_usec = 0; - if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) - die("setsockopt"); - - // Configure EDCL server address - memset((char *) &serv_addr, 0, sizeof(struct sockaddr_in)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(PORT); - if (inet_aton(server , &serv_addr.sin_addr) == 0) - die("inet_aton"); - - // Configure client address - memset((char *) &cli_addr, 0, sizeof(struct sockaddr_in)); - cli_addr.sin_family = AF_INET; - cli_addr.sin_port = htons(PORT); - cli_addr.sin_addr.s_addr = htonl(INADDR_ANY); - if ( bind(s, (struct sockaddr *) &cli_addr, sizeof(struct sockaddr_in)) == -1) - die("bind"); + /* printf("Connect ESPLink\n"); */ + + // Open socket + if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) die("socket"); + + struct timeval tv; + tv.tv_sec = 3; + tv.tv_usec = 0; + if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) die("setsockopt"); + + // Configure EDCL server address + memset((char *)&serv_addr, 0, sizeof(struct sockaddr_in)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(PORT); + if (inet_aton(server, &serv_addr.sin_addr) == 0) die("inet_aton"); + + // Configure client address + memset((char *)&cli_addr, 0, sizeof(struct sockaddr_in)); + cli_addr.sin_family = AF_INET; + cli_addr.sin_port = htons(PORT); + cli_addr.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind(s, (struct sockaddr *)&cli_addr, sizeof(struct sockaddr_in)) == -1) die("bind"); } void load_memory(char *fname) { - edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); - edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); - u32 i; - int r; - u32 addr; - FILE *fp = fopen(fname, "r"); - if (!fp) - die("fopen"); - - // First packet - snd->offset = 0; - snd->sequence = 0x0; - snd->write = 1; + edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); + edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); + u32 i; + int r; + u32 addr; + FILE *fp = fopen(fname, "r"); + if (!fp) die("fopen"); + // First packet + snd->offset = 0; + snd->sequence = 0x0; + snd->write = 1; - while (1) { - r = fscanf(fp, "%08x %08x\n", &snd->address, &snd->data[0]); + while (1) { + r = fscanf(fp, "%08x %08x\n", &snd->address, &snd->data[0]); - if (r == EOF) - break; + if (r == EOF) break; - if (r != 2) - die("fscanf"); + if (r != 2) die("fscanf"); - for (i = 1; i < NWORD_MAX_SND; i++) { - r = fscanf(fp, "%08x %08x\n", &addr, &snd->data[i]); - if (r == EOF) - break; - if (r != 2) - die("fscanf"); - } + for (i = 1; i < NWORD_MAX_SND; i++) { + r = fscanf(fp, "%08x %08x\n", &addr, &snd->data[i]); + if (r == EOF) break; + if (r != 2) die("fscanf"); + } - snd->length = i * 4; + snd->length = i * 4; - handle_edcl_message(snd, rcv); + handle_edcl_message(snd, rcv); - snd->sequence++; - } + snd->sequence++; + } - fclose(fp); - free(snd); - free(rcv); + fclose(fp); + free(snd); + free(rcv); } void dump_memory(u32 address, u32 size, char *fname) { - edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); - edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); - u32 rem = size; - u32 i; - FILE *fp = fopen(fname, "w+"); - if (!fp) - die("fopen"); - - // First packet - snd->offset = 0; - snd->sequence = 0x0; - snd->write = 0; - snd->length = size < MAX_RCV_SZ ? size : MAX_RCV_SZ; - snd->address = address; - - while (rem > 0) { - handle_edcl_message(snd, rcv); - - for (i = 0; i < snd->length / 4; i++) { - u32 addr = rcv->address + i * 4; - u32 data = rcv->data[i]; - fprintf(fp, "%08x %08x\n", addr, data); - } - - rem -= snd->length; - - snd->sequence++; - snd->address += snd->length; - snd->length = rem < MAX_RCV_SZ ? rem : MAX_RCV_SZ; - } - - fclose(fp); - free(snd); - free(rcv); + edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); + edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); + u32 rem = size; + u32 i; + FILE *fp = fopen(fname, "w+"); + if (!fp) die("fopen"); + + // First packet + snd->offset = 0; + snd->sequence = 0x0; + snd->write = 0; + snd->length = size < MAX_RCV_SZ ? size : MAX_RCV_SZ; + snd->address = address; + + while (rem > 0) { + handle_edcl_message(snd, rcv); + + for (i = 0; i < snd->length / 4; i++) { + u32 addr = rcv->address + i * 4; + u32 data = rcv->data[i]; + fprintf(fp, "%08x %08x\n", addr, data); + } + + rem -= snd->length; + + snd->sequence++; + snd->address += snd->length; + snd->length = rem < MAX_RCV_SZ ? rem : MAX_RCV_SZ; + } + + fclose(fp); + free(snd); + free(rcv); } void load_memory_bin(u32 base_addr, char *fname) { - edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); - edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); - FILE *fp = fopen(fname, "rb"); - size_t sz; - size_t rem; - u32 i = 0; - - if (!fp) - die("fopen"); - - // Get binary size - fseek(fp, 0L, SEEK_END); - sz = ftell(fp); - rewind(fp); - rem = sz; - - // First packet - snd->offset = 0; - snd->sequence = 0x0; - snd->write = 1; - snd->address = base_addr; - snd->length = rem < MAX_SND_SZ ? rem : MAX_SND_SZ; - - while (rem > 0) { - if (lefread(&snd->data[0], sizeof(u32), snd->length / sizeof(u32), fp) != snd->length / sizeof(u32)) - die("fread"); - - handle_edcl_message(snd, rcv); - - rem -= snd->length; - i += snd->length / sizeof(u32); - - print_progress(sz - rem, sz, "loading binary"); - - snd->address += snd->length; - snd->length = rem < MAX_SND_SZ ? rem : MAX_SND_SZ; - snd->sequence++; - } - - fclose(fp); - free(snd); - free(rcv); - - /* clear_rcv_edcl(); */ - printf("Loaded %zu Bytes at %08x\n", sz, base_addr); + edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); + edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); + FILE *fp = fopen(fname, "rb"); + size_t sz; + size_t rem; + u32 i = 0; + + if (!fp) die("fopen"); + + // Get binary size + fseek(fp, 0L, SEEK_END); + sz = ftell(fp); + rewind(fp); + rem = sz; + + // First packet + snd->offset = 0; + snd->sequence = 0x0; + snd->write = 1; + snd->address = base_addr; + snd->length = rem < MAX_SND_SZ ? rem : MAX_SND_SZ; + + while (rem > 0) { + if (lefread(&snd->data[0], sizeof(u32), snd->length / sizeof(u32), fp) != + snd->length / sizeof(u32)) + die("fread"); + + handle_edcl_message(snd, rcv); + + rem -= snd->length; + i += snd->length / sizeof(u32); + + print_progress(sz - rem, sz, "loading binary"); + + snd->address += snd->length; + snd->length = rem < MAX_SND_SZ ? rem : MAX_SND_SZ; + snd->sequence++; + } + + fclose(fp); + free(snd); + free(rcv); + + /* clear_rcv_edcl(); */ + printf("Loaded %zu Bytes at %08x\n", sz, base_addr); } void dump_memory_bin(u32 address, u32 size, char *fname) { - edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); - edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); - u32 rem = size; - FILE *fp = fopen(fname, "wb+"); - if (!fp) - die("fopen"); - - // First packet - snd->offset = 0; - snd->sequence = 0x0; - snd->write = 0; - snd->length = size < MAX_RCV_SZ ? size : MAX_RCV_SZ; - snd->address = address; - - while (rem > 0) { - handle_edcl_message(snd, rcv); - fwrite(&rcv->data[0], sizeof(u32), snd->length / sizeof(u32), fp); - - rem -= snd->length; - - print_progress(size - rem, size, "loading binary"); - - snd->sequence++; - snd->address += snd->length; - snd->length = rem < MAX_RCV_SZ ? rem : MAX_RCV_SZ; - } - - fclose(fp); - free(snd); - free(rcv); - - printf("Dumped %u Bytes starting at %08x\n", size, address); + edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); + edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); + u32 rem = size; + FILE *fp = fopen(fname, "wb+"); + if (!fp) die("fopen"); + + // First packet + snd->offset = 0; + snd->sequence = 0x0; + snd->write = 0; + snd->length = size < MAX_RCV_SZ ? size : MAX_RCV_SZ; + snd->address = address; + + while (rem > 0) { + handle_edcl_message(snd, rcv); + fwrite(&rcv->data[0], sizeof(u32), snd->length / sizeof(u32), fp); + + rem -= snd->length; + + print_progress(size - rem, size, "loading binary"); + + snd->sequence++; + snd->address += snd->length; + snd->length = rem < MAX_RCV_SZ ? rem : MAX_RCV_SZ; + } + + fclose(fp); + free(snd); + free(rcv); + + printf("Dumped %u Bytes starting at %08x\n", size, address); } void reset(u32 addr) { - edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); - edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); + edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); + edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); - snd->offset = 0; - snd->sequence = 0x0; - snd->write = 1; - snd->address = addr; - snd->data[0] = 0x1; - snd->length = 4; + snd->offset = 0; + snd->sequence = 0x0; + snd->write = 1; + snd->address = addr; + snd->data[0] = 0x1; + snd->length = 4; - // Reset must be sent twice - handle_edcl_message(snd, rcv); - usleep(500000); + // Reset must be sent twice + handle_edcl_message(snd, rcv); + usleep(500000); - free(snd); - free(rcv); + free(snd); + free(rcv); - snd = malloc(sizeof(edcl_snd_t)); - rcv = malloc(sizeof(edcl_rcv_t)); + snd = malloc(sizeof(edcl_snd_t)); + rcv = malloc(sizeof(edcl_rcv_t)); - snd->offset = 0; - snd->sequence = 0x0; - snd->write = 1; - snd->address = addr; - snd->data[0] = 0x1; - snd->length = 4; + snd->offset = 0; + snd->sequence = 0x0; + snd->write = 1; + snd->address = addr; + snd->data[0] = 0x1; + snd->length = 4; - handle_edcl_message(snd, rcv); - usleep(500000); + handle_edcl_message(snd, rcv); + usleep(500000); - free(snd); - free(rcv); + free(snd); + free(rcv); - printf("Reset ESP processor cores\n"); + printf("Reset ESP processor cores\n"); } void set_word(u32 addr, u32 data) { - edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); - edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); + edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); + edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); - // First packet - snd->offset = 0; - snd->sequence = 0x0; - snd->write = 1; - snd->address = addr; - snd->data[0] = data; - snd->length = 4; + // First packet + snd->offset = 0; + snd->sequence = 0x0; + snd->write = 1; + snd->address = addr; + snd->data[0] = data; + snd->length = 4; - handle_edcl_message(snd, rcv); + handle_edcl_message(snd, rcv); - free(snd); - free(rcv); + free(snd); + free(rcv); - printf("Write %08x at %08x\n", data, addr); + printf("Write %08x at %08x\n", data, addr); } void get_word(u32 addr) { - edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); - edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); + edcl_snd_t *snd = malloc(sizeof(edcl_snd_t)); + edcl_rcv_t *rcv = malloc(sizeof(edcl_rcv_t)); - // First packet - snd->offset = 0; - snd->sequence = 0x0; - snd->write = 0; - snd->address = addr; - snd->length = 4; + // First packet + snd->offset = 0; + snd->sequence = 0x0; + snd->write = 0; + snd->address = addr; + snd->length = 4; - handle_edcl_message(snd, rcv); + handle_edcl_message(snd, rcv); - printf("Read %08x at %08x\n", rcv->data[0], addr); + printf("Read %08x at %08x\n", rcv->data[0], addr); - free(snd); - free(rcv); -} - -void disconnect_edcl() -{ - close(s); + free(snd); + free(rcv); } +void disconnect_edcl() { close(s); } diff --git a/tools/espmon/espmonmain.cpp b/tools/espmon/espmonmain.cpp index 20a100d2e1..70a1941d91 100644 --- a/tools/espmon/espmonmain.cpp +++ b/tools/espmon/espmonmain.cpp @@ -4,94 +4,91 @@ #include "espmonmain.h" #include "ui_espmonmain.h" -#include -#include -#include +#include #include #include -#include +#include +#include +#include -template < typename T > std::string to_string( const T& n ) +template std::string to_string(const T &n) { - std::ostringstream stm ; - stm << n ; - return stm.str() ; + std::ostringstream stm; + stm << n; + return stm.str(); } - EspMonMain::EspMonMain(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::EspMonMain), - mmi(new mmi64_mon) + QMainWindow(parent), ui(new Ui::EspMonMain), mmi(new mmi64_mon) { - ui->setupUi(this); - - // MMI - mmi_is_open = false; - mmi_is_running = false; - ave_not_max = true; - - // Build panels - show_soc(); - show_dvfs(); - show_acc(); - show_heatmap(); + ui->setupUi(this); + + // MMI + mmi_is_open = false; + mmi_is_running = false; + ave_not_max = true; + + // Build panels + show_soc(); + show_dvfs(); + show_acc(); + show_heatmap(); } EspMonMain::~EspMonMain() { - // Close MMI to avoid deadlock on next open - profpga_error_t status __attribute__((unused)); - if (mmi_is_open) - status = mmi->close_system(); + // Close MMI to avoid deadlock on next open + profpga_error_t status __attribute__((unused)); + if (mmi_is_open) status = mmi->close_system(); - delete ui; + delete ui; } -void EspMonMain::ErrorMessage(const char * c_str) +void EspMonMain::ErrorMessage(const char *c_str) { - std::ostringstream stm; - stm << "Error: " << c_str; - QMessageBox messageBox; - messageBox.critical(0,"Error", stm.str().c_str()); - messageBox.setFixedSize(500,200); + std::ostringstream stm; + stm << "Error: " << c_str; + QMessageBox messageBox; + messageBox.critical(0, "Error", stm.str().c_str()); + messageBox.setFixedSize(500, 200); } void EspMonMain::errorString(QString str) { - QMessageBox messageBox; - messageBox.critical(0,"Error", str); - messageBox.setFixedSize(500,200); + QMessageBox messageBox; + messageBox.critical(0, "Error", str); + messageBox.setFixedSize(500, 200); } void EspMonMain::show_soc() { - for (int i = 0; i < TILES_NUM; i++) { - const struct tile_info *t = &tiles[i]; - QPushButton *btn = new QPushButton(); - std::ostringstream stm; - stm << i << ". " << t->name; - btn->setText(stm.str().c_str()); - QFont f("Arial", 13, -1, false); - btn->setFont(f); - std::string color_html; - if (t->type == (int) cpu_tile) { - color_html="#fd8276"; - } else if (t->type == (int) accelerator_tile) { - color_html="#8ad0c5"; - } else if (t->type == (int) empty_tile) { - color_html="#e5e5e5"; - } else { - color_html="#84bcf2"; - } - QColor col(color_html.c_str()); - QString qss = QString("background-color: %1").arg(col.name()); - btn->setStyleSheet(qss); - btn->setMinimumHeight(50); - - btn_tiles.push_back(btn); - ui->layout_soc->addWidget(btn, t->position.y, t->position.x, 1, 1); - } + for (int i = 0; i < TILES_NUM; i++) { + const struct tile_info *t = &tiles[i]; + QPushButton *btn = new QPushButton(); + std::ostringstream stm; + stm << i << ". " << t->name; + btn->setText(stm.str().c_str()); + QFont f("Arial", 13, -1, false); + btn->setFont(f); + std::string color_html; + if (t->type == (int)cpu_tile) { color_html = "#fd8276"; } + else if (t->type == (int)accelerator_tile) { + color_html = "#8ad0c5"; + } + else if (t->type == (int)empty_tile) { + color_html = "#e5e5e5"; + } + else { + color_html = "#84bcf2"; + } + QColor col(color_html.c_str()); + QString qss = QString("background-color: %1").arg(col.name()); + btn->setStyleSheet(qss); + btn->setMinimumHeight(50); + + btn_tiles.push_back(btn); + ui->layout_soc->addWidget(btn, t->position.y, t->position.x, 1, 1); + } } // Less contrast @@ -108,7 +105,7 @@ void EspMonMain::show_soc() // static const QColor heat_90("#E50029"); // More constrast -//static const QColor heat_no("#007CBF"); +// static const QColor heat_no("#007CBF"); static const QColor heat_no("#dfdfdf"); static const QColor heat_00("#00C2C2"); static const QColor heat_10("#00C67F"); @@ -157,795 +154,766 @@ static const QColor heat_1000("#E50029"); void EspMonMain::show_heatmap() { - layout_heat = new QGridLayout(); - layout_heat->setSpacing(1); - - ui->layout_frame_heat->addLayout(layout_heat); - - for (int y = 0; y < YLEN * 6; y++) - for (int x = 0; x < XLEN * 6; x++) - for (int h = 0; h < NOCS_NUM; h++) { - QPalette Pal(palette()); - Pal.setColor(QPalette::Background, heat_no); - QWidget *w = new QWidget(); - w->setAutoFillBackground(true); - w->setPalette(Pal); - - QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - sizePolicy.setHeightForWidth(w->sizePolicy().hasHeightForWidth()); - w->setSizePolicy(sizePolicy); - w->setMinimumSize(QSize(9, 9)); - - int y0 = (y * NOCS_NUM) + h; - int x0 = (x * NOCS_NUM) + h; - wid_map[h].push_back(w); - layout_heat->addWidget(w, y0, x0, 1, 1); - - QPalette Pal1(palette()); - Pal1.setColor(QPalette::Background, heat_no); - QWidget *w1 = new QWidget(); - w1->setAutoFillBackground(true); - w1->setPalette(Pal); - - QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed); - sizePolicy1.setHorizontalStretch(0); - sizePolicy1.setVerticalStretch(0); - sizePolicy1.setHeightForWidth(w->sizePolicy().hasHeightForWidth()); - w1->setSizePolicy(sizePolicy1); - w1->setMinimumSize(QSize(9, 9)); - - if ((x0 % (6 * NOCS_NUM)) < (2 * NOCS_NUM)) { - if ((y0 % 2) == 0) - layout_heat->addWidget(w1, y0, x0 + 1, 1, 1); - else - layout_heat->addWidget(w1, y0, x0 - 1, 1, 1); - } else if ((x0 % (6 * NOCS_NUM)) < (4 * NOCS_NUM)) { - if ((y0 % 2) == 0) - layout_heat->addWidget(w1, y0 + 1, x0, 1, 1); - else - layout_heat->addWidget(w1, y0 - 1, x0, 1, 1); - - } else { - if ((y0 % 2) == 0) - layout_heat->addWidget(w1, y0, x0 + 1, 1, 1); - else - layout_heat->addWidget(w1, y0, x0 - 1, 1, 1); - } - wid_map1[h].push_back(w1); - - } - - for (int i = 0; i < TILES_NUM; i++) - for (int h = 0; h < NOCS_NUM; h++) - router_is_active[h][i] = 0; + layout_heat = new QGridLayout(); + layout_heat->setSpacing(1); + + ui->layout_frame_heat->addLayout(layout_heat); + + for (int y = 0; y < YLEN * 6; y++) + for (int x = 0; x < XLEN * 6; x++) + for (int h = 0; h < NOCS_NUM; h++) { + QPalette Pal(palette()); + Pal.setColor(QPalette::Background, heat_no); + QWidget *w = new QWidget(); + w->setAutoFillBackground(true); + w->setPalette(Pal); + + QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(w->sizePolicy().hasHeightForWidth()); + w->setSizePolicy(sizePolicy); + w->setMinimumSize(QSize(9, 9)); + + int y0 = (y * NOCS_NUM) + h; + int x0 = (x * NOCS_NUM) + h; + wid_map[h].push_back(w); + layout_heat->addWidget(w, y0, x0, 1, 1); + + QPalette Pal1(palette()); + Pal1.setColor(QPalette::Background, heat_no); + QWidget *w1 = new QWidget(); + w1->setAutoFillBackground(true); + w1->setPalette(Pal); + + QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(w->sizePolicy().hasHeightForWidth()); + w1->setSizePolicy(sizePolicy1); + w1->setMinimumSize(QSize(9, 9)); + + if ((x0 % (6 * NOCS_NUM)) < (2 * NOCS_NUM)) { + if ((y0 % 2) == 0) layout_heat->addWidget(w1, y0, x0 + 1, 1, 1); + else + layout_heat->addWidget(w1, y0, x0 - 1, 1, 1); + } + else if ((x0 % (6 * NOCS_NUM)) < (4 * NOCS_NUM)) { + if ((y0 % 2) == 0) layout_heat->addWidget(w1, y0 + 1, x0, 1, 1); + else + layout_heat->addWidget(w1, y0 - 1, x0, 1, 1); + } + else { + if ((y0 % 2) == 0) layout_heat->addWidget(w1, y0, x0 + 1, 1, 1); + else + layout_heat->addWidget(w1, y0, x0 - 1, 1, 1); + } + wid_map1[h].push_back(w1); + } + + for (int i = 0; i < TILES_NUM; i++) + for (int h = 0; h < NOCS_NUM; h++) + router_is_active[h][i] = 0; } void EspMonMain::show_dvfs() { - for (int i = 0; i < TILES_NUM; i++) { - QProgressBar *pb = new QProgressBar(); - pb->setOrientation(Qt::Vertical); + for (int i = 0; i < TILES_NUM; i++) { + QProgressBar *pb = new QProgressBar(); + pb->setOrientation(Qt::Vertical); #ifndef DVFS_offset - pb->setEnabled(false); + pb->setEnabled(false); #endif - pbar_dvfs.push_back(pb); - const struct tile_info *t = &tiles[i]; - if (t->type == accelerator_tile) - // Do not show other tiles for now - ui->layout_power->addWidget(pb); - } - - for (int i = 0; i < TILES_NUM; i++) { - const struct tile_info *t = &tiles[i]; - if (t->type != accelerator_tile) - continue; - - QLabel *label_power = new QLabel(ui->frame_4); - std::ostringstream stm; - stm << i; - label_power->setObjectName(stm.str().c_str()); - label_power->setText(stm.str().c_str()); - ui->layout_power_label->addWidget(label_power); - } - + pbar_dvfs.push_back(pb); + const struct tile_info *t = &tiles[i]; + if (t->type == accelerator_tile) + // Do not show other tiles for now + ui->layout_power->addWidget(pb); + } + + for (int i = 0; i < TILES_NUM; i++) { + const struct tile_info *t = &tiles[i]; + if (t->type != accelerator_tile) continue; + + QLabel *label_power = new QLabel(ui->frame_4); + std::ostringstream stm; + stm << i; + label_power->setObjectName(stm.str().c_str()); + label_power->setText(stm.str().c_str()); + ui->layout_power_label->addWidget(label_power); + } } void EspMonMain::show_acc() { - for (int i = 0; i < ACCS_NUM; i++) { - QProgressBar *pb = new QProgressBar(); - pb->setOrientation(Qt::Vertical); + for (int i = 0; i < ACCS_NUM; i++) { + QProgressBar *pb = new QProgressBar(); + pb->setOrientation(Qt::Vertical); #ifndef ACC_offset - pb->setEnabled(false); + pb->setEnabled(false); #endif - pbar_acc.push_back(pb); - ui->layout_acc->addWidget(pb); - } - - for (int i = 0; i < TILES_NUM; i++) { - const struct tile_info *t = &tiles[i]; - if (t->type != accelerator_tile) - continue; - - QLabel *label_acc = new QLabel(ui->frame_5); - std::ostringstream stm; - stm << i; - label_acc->setObjectName(stm.str().c_str()); - label_acc->setText(stm.str().c_str()); - ui->layout_acc_label->addWidget(label_acc); - } - + pbar_acc.push_back(pb); + ui->layout_acc->addWidget(pb); + } + + for (int i = 0; i < TILES_NUM; i++) { + const struct tile_info *t = &tiles[i]; + if (t->type != accelerator_tile) continue; + + QLabel *label_acc = new QLabel(ui->frame_5); + std::ostringstream stm; + stm << i; + label_acc->setObjectName(stm.str().c_str()); + label_acc->setText(stm.str().c_str()); + ui->layout_acc_label->addWidget(label_acc); + } } void EspMonMain::enable_mmi_panel() { - ui->check_mmi_ddr->setEnabled(true); + ui->check_mmi_ddr->setEnabled(true); #ifdef NOC_QUEUES_offset - ui->check_mmi_traffic->setEnabled(true); + ui->check_mmi_traffic->setEnabled(true); #endif #ifdef ACC_offset - ui->check_mmi_acc->setEnabled(true); + ui->check_mmi_acc->setEnabled(true); #endif #ifdef DVFS_offset - ui->check_mmi_dvfs->setEnabled(true); + ui->check_mmi_dvfs->setEnabled(true); #endif - if (ui->check_mmi_acc->isChecked() || - ui->check_mmi_dvfs->isChecked()) - ui->check_mmi_auto->setEnabled(true); - - if (!ui->check_mmi_auto->isChecked()) { - ui->btn_mmi_start->setEnabled(true); - ui->dial_mmi_win->setEnabled(true); - } - - ui->label_mmi_win->setEnabled(true); - ui->label_mmi_win_fixed->setEnabled(true); - ui->feedback->setEnabled(true); + if (ui->check_mmi_acc->isChecked() || ui->check_mmi_dvfs->isChecked()) + ui->check_mmi_auto->setEnabled(true); + + if (!ui->check_mmi_auto->isChecked()) { + ui->btn_mmi_start->setEnabled(true); + ui->dial_mmi_win->setEnabled(true); + } + + ui->label_mmi_win->setEnabled(true); + ui->label_mmi_win_fixed->setEnabled(true); + ui->feedback->setEnabled(true); } void EspMonMain::disable_mmi_panel() { - ui->check_mmi_ddr->setEnabled(false); - ui->check_mmi_traffic->setEnabled(false); - ui->check_mmi_acc->setEnabled(false); - ui->check_mmi_dvfs->setEnabled(false); - ui->check_mmi_auto->setEnabled(false); - ui->btn_mmi_start->setEnabled(false); - ui->dial_mmi_win->setEnabled(false); - ui->label_mmi_win->setEnabled(false); - ui->label_mmi_win_fixed->setEnabled(false); - ui->feedback->setEnabled(false); - - ui->btn_stat_ave->setEnabled(false); - ui->btn_stat_max->setEnabled(false); + ui->check_mmi_ddr->setEnabled(false); + ui->check_mmi_traffic->setEnabled(false); + ui->check_mmi_acc->setEnabled(false); + ui->check_mmi_dvfs->setEnabled(false); + ui->check_mmi_auto->setEnabled(false); + ui->btn_mmi_start->setEnabled(false); + ui->dial_mmi_win->setEnabled(false); + ui->label_mmi_win->setEnabled(false); + ui->label_mmi_win_fixed->setEnabled(false); + ui->feedback->setEnabled(false); + + ui->btn_stat_ave->setEnabled(false); + ui->btn_stat_max->setEnabled(false); } void EspMonMain::on_btn_mmi_open_clicked() { - profpga_error_t status; - if (mmi_is_open) - status = mmi->close_system(); - else - status = mmi->open_system(); - - if (status == E_PROFPGA_OK) { - if (mmi_is_open) { - mmi_is_open = false; - ui->btn_mmi_open->setText("Connect"); - disable_mmi_panel(); - } else { - mmi64_error_t mmi_status; - mmi_status = mmi->get_user_module(); - if (mmi_status == E_MMI64_OK) { - mmi_is_open = true; - ui->btn_mmi_open->setText("Disconnect"); - enable_mmi_panel(); - uint32_t win = 1 << ui->dial_mmi_win->value(); - set_window(win); - } else { - status = mmi->close_system(); - std::ostringstream stm; - stm << "Failed to find MMI user module (" << mmi64_strerror(mmi_status) << ")"; - const char *err = stm.str().c_str(); - ErrorMessage(err); - } - } - } else { - std::ostringstream stm; - stm << "Failed connect to PROFPGA system (" << profpga_strerror(status) << ")"; - const char *err = stm.str().c_str(); - ErrorMessage(err); - } + profpga_error_t status; + if (mmi_is_open) status = mmi->close_system(); + else + status = mmi->open_system(); + + if (status == E_PROFPGA_OK) { + if (mmi_is_open) { + mmi_is_open = false; + ui->btn_mmi_open->setText("Connect"); + disable_mmi_panel(); + } + else { + mmi64_error_t mmi_status; + mmi_status = mmi->get_user_module(); + if (mmi_status == E_MMI64_OK) { + mmi_is_open = true; + ui->btn_mmi_open->setText("Disconnect"); + enable_mmi_panel(); + uint32_t win = 1 << ui->dial_mmi_win->value(); + set_window(win); + } + else { + status = mmi->close_system(); + std::ostringstream stm; + stm << "Failed to find MMI user module (" << mmi64_strerror(mmi_status) << ")"; + const char *err = stm.str().c_str(); + ErrorMessage(err); + } + } + } + else { + std::ostringstream stm; + stm << "Failed connect to PROFPGA system (" << profpga_strerror(status) << ")"; + const char *err = stm.str().c_str(); + ErrorMessage(err); + } } void EspMonMain::set_window(uint32_t win) { - mmi64_error_t status = mmi->set_window(win); - if (status != E_MMI64_OK) { - std::ostringstream stm; - stm << "Failed to write window size (" << mmi64_strerror(status) << ")"; - const char *err = stm.str().c_str(); - ErrorMessage(err); - } + mmi64_error_t status = mmi->set_window(win); + if (status != E_MMI64_OK) { + std::ostringstream stm; + stm << "Failed to write window size (" << mmi64_strerror(status) << ")"; + const char *err = stm.str().c_str(); + ErrorMessage(err); + } } void EspMonMain::on_dial_mmi_win_sliderMoved(int position) { - ui->dial_mmi_win->setValue(position); - ui->label_mmi_win->setText(to_string(position).c_str()); - uint32_t win = 1 << position; - set_window(win); + ui->dial_mmi_win->setValue(position); + ui->label_mmi_win->setText(to_string(position).c_str()); + uint32_t win = 1 << position; + set_window(win); } bool EspMonMain::read_probes() { - mmi64_error_t status; - status = mmi->read_timestamp(); - if (status != E_MMI64_OK) - ErrorMessage(mmi64_strerror(status)); + mmi64_error_t status; + status = mmi->read_timestamp(); + if (status != E_MMI64_OK) ErrorMessage(mmi64_strerror(status)); - if (current_time == mmi->current_time) - return false; - new_time = mmi->current_time; + if (current_time == mmi->current_time) return false; + new_time = mmi->current_time; #ifdef NOC_QUEUES_offset - if (ui->check_mmi_traffic->isChecked()) { - status = mmi->read_queues(); - if (status != E_MMI64_OK) - ErrorMessage(mmi64_strerror(status)); - } + if (ui->check_mmi_traffic->isChecked()) { + status = mmi->read_queues(); + if (status != E_MMI64_OK) ErrorMessage(mmi64_strerror(status)); + } #endif #ifdef DVFS_offset - if (ui->check_mmi_dvfs->isChecked()) { - status = mmi->read_dvfs(); - if (status != E_MMI64_OK) - ErrorMessage(mmi64_strerror(status)); - } + if (ui->check_mmi_dvfs->isChecked()) { + status = mmi->read_dvfs(); + if (status != E_MMI64_OK) ErrorMessage(mmi64_strerror(status)); + } #endif #ifdef ACC_offset - if (ui->check_mmi_acc->isChecked()) { - status = mmi->read_accs(); - if (status != E_MMI64_OK) - ErrorMessage(mmi64_strerror(status)); - } + if (ui->check_mmi_acc->isChecked()) { + status = mmi->read_accs(); + if (status != E_MMI64_OK) ErrorMessage(mmi64_strerror(status)); + } #endif - return true; + return true; } static QColor get_color_heatmap(unsigned long long probe, float max) { - float rate = 100 * probe / max; + float rate = 100 * probe / max; #ifdef SIGNATURE_offset - if (rate >= 100) - return heat_1000; - if (rate > 87.5) - return heat_875; - if (rate > 75) - return heat_750; - if (rate > 62.5) - return heat_625; - if (rate > 50) - return heat_500; - if (rate > 37.5) - return heat_375; - if (rate > 25) - return heat_250; - if (rate > 0) - return heat_00; - return heat_no; + if (rate >= 100) return heat_1000; + if (rate > 87.5) return heat_875; + if (rate > 75) return heat_750; + if (rate > 62.5) return heat_625; + if (rate > 50) return heat_500; + if (rate > 37.5) return heat_375; + if (rate > 25) return heat_250; + if (rate > 0) return heat_00; + return heat_no; #else - if (rate > 90) - return heat_90; - if (rate > 80) - return heat_80; - if (rate > 70) - return heat_70; - if (rate > 60) - return heat_60; - if (rate > 50) - return heat_50; - if (rate > 40) - return heat_40; - if (rate > 30) - return heat_30; - if (rate > 20) - return heat_20; - if (rate > 10) - return heat_10; - if (rate > 0) - return heat_00; - return heat_no; + if (rate > 90) return heat_90; + if (rate > 80) return heat_80; + if (rate > 70) return heat_70; + if (rate > 60) return heat_60; + if (rate > 50) return heat_50; + if (rate > 40) return heat_40; + if (rate > 30) return heat_30; + if (rate > 20) return heat_20; + if (rate > 10) return heat_10; + if (rate > 0) return heat_00; + return heat_no; #endif } #ifdef NOC_QUEUES_offset -void EspMonMain::update_heatmap(int noc, float max, uint32_t (&probes_queue)[NOCS_NUM][TILES_NUM][DIRECTIONS]) +void EspMonMain::update_heatmap(int noc, float max, + uint32_t (&probes_queue)[NOCS_NUM][TILES_NUM][DIRECTIONS]) { - const int N = 6; - for (int i = 0; i < TILES_NUM; i++) - router_is_active[noc][i] = 0; - - for (int i = 0; i < TILES_NUM; i++) { - const struct tile_info *t = &tiles[i]; - // Notrth out - int y0 = N * t->position.y + 2; - int x0 = N * t->position.x + 2; - if (t->position.y != 0) { - QColor col = get_color_heatmap(probes_queue[noc][i][0], max); - router_is_active[noc][(t->position.y) * XLEN + t->position.x] += probes_queue[noc][i][0]; - for (int y = 1; y < N-1; y++) { - QPalette Pal(palette()); - Pal.setColor(QPalette::Background, col); - wid_map[noc][(y0 - y) * N * XLEN + x0]->setPalette(Pal); - wid_map1[noc][(y0 - y) * N * XLEN + x0]->setPalette(Pal); - } - } - - // South out - y0 = N * t->position.y + 3; - x0 = N * t->position.x + 3; - if (t->position.y != YLEN - 1) { - QColor col = get_color_heatmap(probes_queue[noc][i][1], max); - router_is_active[noc][(t->position.y) * XLEN + t->position.x] += probes_queue[noc][i][1]; - for (int y = 1; y < N-1; y++) { - QPalette Pal(palette()); - Pal.setColor(QPalette::Background, col); - wid_map[noc][(y0 + y) * N * XLEN + x0]->setPalette(Pal); - wid_map1[noc][(y0 + y) * N * XLEN + x0]->setPalette(Pal); - } - } - - // West out - y0 = N * t->position.y + 3; - x0 = N * t->position.x + 2; - if (t->position.x != 0) { - QColor col = get_color_heatmap(probes_queue[noc][i][2], max); - router_is_active[noc][t->position.y * XLEN + t->position.x] += probes_queue[noc][i][2]; - for (int x = 1; x < N-1; x++) { - QPalette Pal(palette()); - Pal.setColor(QPalette::Background, col); - wid_map[noc][y0 * N * XLEN + x0 - x]->setPalette(Pal); - wid_map1[noc][y0 * N * XLEN + x0 - x]->setPalette(Pal); - } - } - - // East out - y0 = N * t->position.y + 2; - x0 = N * t->position.x + 3; - if (t->position.x != XLEN - 1) { - QColor col = get_color_heatmap(probes_queue[noc][i][3], max); - router_is_active[noc][t->position.y * XLEN + t->position.x] += probes_queue[noc][i][3]; - for (int x = 1; x < N-1; x++) { - QPalette Pal(palette()); - Pal.setColor(QPalette::Background, col); - wid_map[noc][y0 * N * XLEN + x0 + x]->setPalette(Pal); - wid_map1[noc][y0 * N * XLEN + x0 + x]->setPalette(Pal); - } - } - } - - // Routers - for (int i = 0; i < TILES_NUM; i++) { - const struct tile_info *t = &tiles[i]; - // Notrth out - int y0 = N * t->position.y + 2; - int y1 = N * t->position.y + 3; - int x0 = N * t->position.x + 2; - int x1 = N * t->position.x + 3; - QPalette Pal0(palette()); - QPalette Pal1(palette()); - QPalette Pal2(palette()); - QPalette Pal3(palette()); - //QColor col = get_color_heatmap(router_is_active[noc][i], max); - QColor col; - if (noc % NOCS_NUM == 0) - col = QColor("#bfbfbf"); - else - col = QColor("#7f7f7f"); - - Pal0.setColor(QPalette::Background, col); - Pal1.setColor(QPalette::Background, col); - Pal2.setColor(QPalette::Background, col); - Pal3.setColor(QPalette::Background, col); - wid_map[noc][y0 * N * XLEN + x0]->setPalette(Pal0); - wid_map[noc][y0 * N * XLEN + x1]->setPalette(Pal1); - wid_map[noc][y1 * N * XLEN + x0]->setPalette(Pal2); - wid_map[noc][y1 * N * XLEN + x1]->setPalette(Pal3); - } + const int N = 6; + for (int i = 0; i < TILES_NUM; i++) + router_is_active[noc][i] = 0; + + for (int i = 0; i < TILES_NUM; i++) { + const struct tile_info *t = &tiles[i]; + // Notrth out + int y0 = N * t->position.y + 2; + int x0 = N * t->position.x + 2; + if (t->position.y != 0) { + QColor col = get_color_heatmap(probes_queue[noc][i][0], max); + router_is_active[noc][(t->position.y) * XLEN + t->position.x] += + probes_queue[noc][i][0]; + for (int y = 1; y < N - 1; y++) { + QPalette Pal(palette()); + Pal.setColor(QPalette::Background, col); + wid_map[noc][(y0 - y) * N * XLEN + x0]->setPalette(Pal); + wid_map1[noc][(y0 - y) * N * XLEN + x0]->setPalette(Pal); + } + } + + // South out + y0 = N * t->position.y + 3; + x0 = N * t->position.x + 3; + if (t->position.y != YLEN - 1) { + QColor col = get_color_heatmap(probes_queue[noc][i][1], max); + router_is_active[noc][(t->position.y) * XLEN + t->position.x] += + probes_queue[noc][i][1]; + for (int y = 1; y < N - 1; y++) { + QPalette Pal(palette()); + Pal.setColor(QPalette::Background, col); + wid_map[noc][(y0 + y) * N * XLEN + x0]->setPalette(Pal); + wid_map1[noc][(y0 + y) * N * XLEN + x0]->setPalette(Pal); + } + } + + // West out + y0 = N * t->position.y + 3; + x0 = N * t->position.x + 2; + if (t->position.x != 0) { + QColor col = get_color_heatmap(probes_queue[noc][i][2], max); + router_is_active[noc][t->position.y * XLEN + t->position.x] += probes_queue[noc][i][2]; + for (int x = 1; x < N - 1; x++) { + QPalette Pal(palette()); + Pal.setColor(QPalette::Background, col); + wid_map[noc][y0 * N * XLEN + x0 - x]->setPalette(Pal); + wid_map1[noc][y0 * N * XLEN + x0 - x]->setPalette(Pal); + } + } + + // East out + y0 = N * t->position.y + 2; + x0 = N * t->position.x + 3; + if (t->position.x != XLEN - 1) { + QColor col = get_color_heatmap(probes_queue[noc][i][3], max); + router_is_active[noc][t->position.y * XLEN + t->position.x] += probes_queue[noc][i][3]; + for (int x = 1; x < N - 1; x++) { + QPalette Pal(palette()); + Pal.setColor(QPalette::Background, col); + wid_map[noc][y0 * N * XLEN + x0 + x]->setPalette(Pal); + wid_map1[noc][y0 * N * XLEN + x0 + x]->setPalette(Pal); + } + } + } + + // Routers + for (int i = 0; i < TILES_NUM; i++) { + const struct tile_info *t = &tiles[i]; + // Notrth out + int y0 = N * t->position.y + 2; + int y1 = N * t->position.y + 3; + int x0 = N * t->position.x + 2; + int x1 = N * t->position.x + 3; + QPalette Pal0(palette()); + QPalette Pal1(palette()); + QPalette Pal2(palette()); + QPalette Pal3(palette()); + // QColor col = get_color_heatmap(router_is_active[noc][i], max); + QColor col; + if (noc % NOCS_NUM == 0) col = QColor("#bfbfbf"); + else + col = QColor("#7f7f7f"); + + Pal0.setColor(QPalette::Background, col); + Pal1.setColor(QPalette::Background, col); + Pal2.setColor(QPalette::Background, col); + Pal3.setColor(QPalette::Background, col); + wid_map[noc][y0 * N * XLEN + x0]->setPalette(Pal0); + wid_map[noc][y0 * N * XLEN + x1]->setPalette(Pal1); + wid_map[noc][y1 * N * XLEN + x0]->setPalette(Pal2); + wid_map[noc][y1 * N * XLEN + x1]->setPalette(Pal3); + } } #endif - void EspMonMain::update_probes() { - const float max = 0.8 * (1<dial_mmi_win->value()); - - if (first_sample) { - first_sample = false; - mmi->probes_statistics_reset(); - for (int k = 0; k < TILES_NUM; k++) { - power_tot[k] = 0.0; - power_max[k] = 0.0; - } - for (int k = 0; k < ACCS_NUM; k++) { - mem_compute_tot[k] = 0.0; - mem_compute_max[k] = 0.0; - exec_compute_tot[k] = 0.0; - exec_compute_max[k] = 0.0; - } - ui->label_mmi_warn->setText(""); - } else { - if (new_time > current_time + 1) - ui->label_mmi_warn->setText("Data loss!"); - } - current_time = new_time; - std::ostringstream stm; - stm << current_time; - ui->feedback->setText(stm.str().c_str()); + const float max = 0.8 * (1 << ui->dial_mmi_win->value()); + + if (first_sample) { + first_sample = false; + mmi->probes_statistics_reset(); + for (int k = 0; k < TILES_NUM; k++) { + power_tot[k] = 0.0; + power_max[k] = 0.0; + } + for (int k = 0; k < ACCS_NUM; k++) { + mem_compute_tot[k] = 0.0; + mem_compute_max[k] = 0.0; + exec_compute_tot[k] = 0.0; + exec_compute_max[k] = 0.0; + } + ui->label_mmi_warn->setText(""); + } + else { + if (new_time > current_time + 1) ui->label_mmi_warn->setText("Data loss!"); + } + current_time = new_time; + std::ostringstream stm; + stm << current_time; + ui->feedback->setText(stm.str().c_str()); #ifdef NOC_QUEUES_offset - if (ui->check_mmi_traffic->isChecked()) - for (int h = 0; h < NOCS_NUM; h++) { -#ifdef SIGNATURE_offset - const float max_noc_queues = (1<dial_mmi_win->value()); -#else - const float max_noc_queues = max; -#endif - update_heatmap(h, max_noc_queues, mmi->probes_queue); - } + if (ui->check_mmi_traffic->isChecked()) + for (int h = 0; h < NOCS_NUM; h++) { + #ifdef SIGNATURE_offset + const float max_noc_queues = (1 << ui->dial_mmi_win->value()); + #else + const float max_noc_queues = max; + #endif + update_heatmap(h, max_noc_queues, mmi->probes_queue); + } #endif #ifdef DVFS_offset - if (ui->check_mmi_dvfs->isChecked()) { - for (int k = 0; k < TILES_NUM; k++) { - float pow = 0; - const struct tile_info *t = &tiles[k]; - if (t->type != accelerator_tile) - continue; - // computing pJ / ns -> mW - assert(period[k][VF_OP_POINTS - 1] != 0); - const float pow_max = energy_weight[k][VF_OP_POINTS - 1] / period[k][VF_OP_POINTS - 1]; - for (int i = 0; i < VF_OP_POINTS; i++) { - assert(period[k][i] != 0); - assert(pow_max != 0); - float weight = (100.0 * (energy_weight[k][i] / period[k][i])) / pow_max; - pow += mmi->probes_dvfs[k][i] * weight; - } - - // Record power max and ave for later - power_tot[k] += pow; - assert(mmi->current_time - mmi->sample_start != 0); - power_ave[k] = power_tot[k] / (mmi->current_time - mmi->sample_start); - if (pow > power_max[k]) - power_max[k] = pow; - - assert(max != 0); - float bar_value = pow / max; - if (bar_value != 0 && bar_value < 1) - bar_value = 1.0; - pbar_dvfs[k]->setValue(bar_value); - } - } + if (ui->check_mmi_dvfs->isChecked()) { + for (int k = 0; k < TILES_NUM; k++) { + float pow = 0; + const struct tile_info *t = &tiles[k]; + if (t->type != accelerator_tile) continue; + // computing pJ / ns -> mW + assert(period[k][VF_OP_POINTS - 1] != 0); + const float pow_max = energy_weight[k][VF_OP_POINTS - 1] / period[k][VF_OP_POINTS - 1]; + for (int i = 0; i < VF_OP_POINTS; i++) { + assert(period[k][i] != 0); + assert(pow_max != 0); + float weight = (100.0 * (energy_weight[k][i] / period[k][i])) / pow_max; + pow += mmi->probes_dvfs[k][i] * weight; + } + + // Record power max and ave for later + power_tot[k] += pow; + assert(mmi->current_time - mmi->sample_start != 0); + power_ave[k] = power_tot[k] / (mmi->current_time - mmi->sample_start); + if (pow > power_max[k]) power_max[k] = pow; + + assert(max != 0); + float bar_value = pow / max; + if (bar_value != 0 && bar_value < 1) bar_value = 1.0; + pbar_dvfs[k]->setValue(bar_value); + } + } #endif #ifdef ACC_offset - if (ui->check_mmi_acc->isChecked()) { - for (int k = 0; k < ACCS_NUM; k++) { - float mem = 0.0; - float tot = 0.0; - float mem_compute = 0.0; - float exec_compute = 0.0; - mem += mmi->probes_acc[k][0]; // TLB - mem += mmi->probes_acc[k][1]; // DMA - tot += mmi->probes_acc[k][2]; // TOT - if (tot == 0.0) { - pbar_acc[k]->setValue(mem_compute); - continue; - } - mem_compute = (100.0 * mem) / tot; - exec_compute = (100.0 * tot) / max; - - // Record memory over computation ratio for later - mem_compute_tot[k] += mem_compute; - mem_compute_ave[k] = mem_compute_tot[k] / (mmi->current_time - mmi->sample_start); - exec_compute_tot[k] += exec_compute; - exec_compute_ave[k] = exec_compute_tot[k] / (mmi->current_time - mmi->sample_start); - if (mem_compute > mem_compute_max[k]) - mem_compute_max[k] = mem_compute; - if (exec_compute > exec_compute_max[k]) - exec_compute_max[k] = exec_compute; - - pbar_acc[k]->setValue(mem_compute); - } - } + if (ui->check_mmi_acc->isChecked()) { + for (int k = 0; k < ACCS_NUM; k++) { + float mem = 0.0; + float tot = 0.0; + float mem_compute = 0.0; + float exec_compute = 0.0; + mem += mmi->probes_acc[k][0]; // TLB + mem += mmi->probes_acc[k][1]; // DMA + tot += mmi->probes_acc[k][2]; // TOT + if (tot == 0.0) { + pbar_acc[k]->setValue(mem_compute); + continue; + } + mem_compute = (100.0 * mem) / tot; + exec_compute = (100.0 * tot) / max; + + // Record memory over computation ratio for later + mem_compute_tot[k] += mem_compute; + mem_compute_ave[k] = mem_compute_tot[k] / (mmi->current_time - mmi->sample_start); + exec_compute_tot[k] += exec_compute; + exec_compute_ave[k] = exec_compute_tot[k] / (mmi->current_time - mmi->sample_start); + if (mem_compute > mem_compute_max[k]) mem_compute_max[k] = mem_compute; + if (exec_compute > exec_compute_max[k]) exec_compute_max[k] = exec_compute; + + pbar_acc[k]->setValue(mem_compute); + } + } #endif } - void MmiWorker::process() { - bool relevant_sample = false; - bool auto_start = mon->ui->check_mmi_auto->isChecked(); - unsigned no_activity_counter = 4; - while(mon->mmi_is_running) { - if(mon->read_probes()) { - if (mon->mmi->relevant_sample() || !auto_start) { - relevant_sample = true; - emit update(); - no_activity_counter = 4; - } else { - if (relevant_sample) { - emit update(); - no_activity_counter--; - - if (no_activity_counter == 0) - break; - } - } - } - } - emit finished(); - usleep(1000); - mon->ui->feedback->setText("Not Sampling"); - mon->ui->check_mmi_auto->setChecked(false); + bool relevant_sample = false; + bool auto_start = mon->ui->check_mmi_auto->isChecked(); + unsigned no_activity_counter = 4; + while (mon->mmi_is_running) { + if (mon->read_probes()) { + if (mon->mmi->relevant_sample() || !auto_start) { + relevant_sample = true; + emit update(); + no_activity_counter = 4; + } + else { + if (relevant_sample) { + emit update(); + no_activity_counter--; + + if (no_activity_counter == 0) break; + } + } + } + } + emit finished(); + usleep(1000); + mon->ui->feedback->setText("Not Sampling"); + mon->ui->check_mmi_auto->setChecked(false); } void EspMonMain::start_probes() { - ui->btn_mmi_open->setEnabled(false); - disable_mmi_panel(); - - mmi_is_running = true; - first_sample = true; - - // Create and connect MmiWorker - MmiWorker *mwk = new MmiWorker(this); - QThread *mth = new QThread(); - mwk->moveToThread(mth); - connect(mwk, SIGNAL(error(QString)), this, SLOT(errorString(QString))); - connect(mth, SIGNAL(started()), mwk, SLOT(process())); - connect(mwk, SIGNAL(finished()), mth, SLOT(quit())); - connect(mwk, SIGNAL(finished()), mwk, SLOT(deleteLater())); - connect(mth, SIGNAL(finished()), mth, SLOT(deleteLater())); - connect(mwk, SIGNAL(update()), this, SLOT(update_probes())); - - mth->start(); + ui->btn_mmi_open->setEnabled(false); + disable_mmi_panel(); + + mmi_is_running = true; + first_sample = true; + + // Create and connect MmiWorker + MmiWorker *mwk = new MmiWorker(this); + QThread *mth = new QThread(); + mwk->moveToThread(mth); + connect(mwk, SIGNAL(error(QString)), this, SLOT(errorString(QString))); + connect(mth, SIGNAL(started()), mwk, SLOT(process())); + connect(mwk, SIGNAL(finished()), mth, SLOT(quit())); + connect(mwk, SIGNAL(finished()), mwk, SLOT(deleteLater())); + connect(mth, SIGNAL(finished()), mth, SLOT(deleteLater())); + connect(mwk, SIGNAL(update()), this, SLOT(update_probes())); + + mth->start(); } void EspMonMain::on_btn_mmi_start_pressed() { - ui->btn_mmi_stop->setEnabled(true); - start_probes(); + ui->btn_mmi_stop->setEnabled(true); + start_probes(); } void EspMonMain::on_btn_mmi_stop_clicked() { - mmi_is_running = false; - if (ui->check_mmi_auto->isChecked()) { - ui->check_mmi_auto->setChecked(false); - } else { - ui->btn_mmi_stop->setEnabled(false); - get_statistics(); - enable_mmi_panel(); - ui->btn_mmi_open->setEnabled(true); - } + mmi_is_running = false; + if (ui->check_mmi_auto->isChecked()) { ui->check_mmi_auto->setChecked(false); } + else { + ui->btn_mmi_stop->setEnabled(false); + get_statistics(); + enable_mmi_panel(); + ui->btn_mmi_open->setEnabled(true); + } } void EspMonMain::enable_mmi_auto() { - if (ui->check_mmi_acc->isChecked() || - ui->check_mmi_dvfs->isChecked()) { - ui->check_mmi_auto->setEnabled(true); - } else { - ui->check_mmi_auto->setChecked(false); - ui->check_mmi_auto->setEnabled(false); - } + if (ui->check_mmi_acc->isChecked() || ui->check_mmi_dvfs->isChecked()) { + ui->check_mmi_auto->setEnabled(true); + } + else { + ui->check_mmi_auto->setChecked(false); + ui->check_mmi_auto->setEnabled(false); + } } void EspMonMain::on_check_mmi_acc_toggled(bool checked __attribute__((unused))) { - enable_mmi_auto(); + enable_mmi_auto(); } void EspMonMain::on_check_mmi_dvfs_toggled(bool checked __attribute__((unused))) { - enable_mmi_auto(); + enable_mmi_auto(); } void EspMonMain::on_check_mmi_auto_toggled(bool checked) { - if (checked) { - ui->btn_mmi_stop->setEnabled(true); - start_probes(); - } else { - mmi_is_running = false; - ui->btn_mmi_stop->setEnabled(false); - get_statistics(); - enable_mmi_panel(); - ui->btn_mmi_open->setEnabled(true); - } + if (checked) { + ui->btn_mmi_stop->setEnabled(true); + start_probes(); + } + else { + mmi_is_running = false; + ui->btn_mmi_stop->setEnabled(false); + get_statistics(); + enable_mmi_panel(); + ui->btn_mmi_open->setEnabled(true); + } } void EspMonMain::get_statistics() { - // Open report file using time stamp from mmi - std::ostringstream file_name_max; - std::ostringstream file_name_ave; - file_name_max << "espmon_max" << mmi->current_time << ".rpt"; - file_name_ave << "espmon_ave" << mmi->current_time << ".rpt"; - std::ofstream rpt_max; - std::ofstream rpt_ave; - rpt_max.open(file_name_max.str().c_str()); - rpt_ave.open(file_name_ave.str().c_str()); - - // Enable statistics toggle push buttons - ui->btn_stat_ave->setEnabled(true); - ui->btn_stat_max->setEnabled(true); - - // Note that these are the number of cycles in a window. - // The 0.8 factor is needed to account for the scaling between - // 100 MHz (mmi_clk) and 80 MHz (clkm) - const float max = 0.8 * (1<dial_mmi_win->value()); - + // Open report file using time stamp from mmi + std::ostringstream file_name_max; + std::ostringstream file_name_ave; + file_name_max << "espmon_max" << mmi->current_time << ".rpt"; + file_name_ave << "espmon_ave" << mmi->current_time << ".rpt"; + std::ofstream rpt_max; + std::ofstream rpt_ave; + rpt_max.open(file_name_max.str().c_str()); + rpt_ave.open(file_name_ave.str().c_str()); + + // Enable statistics toggle push buttons + ui->btn_stat_ave->setEnabled(true); + ui->btn_stat_max->setEnabled(true); + + // Note that these are the number of cycles in a window. + // The 0.8 factor is needed to account for the scaling between + // 100 MHz (mmi_clk) and 80 MHz (clkm) + const float max = 0.8 * (1 << ui->dial_mmi_win->value()); #ifdef DVFS_offset - if (ui->check_mmi_dvfs->isChecked()) { - float total_energy = 0.0; - rpt_max << "=== Maximum Power (mW) ===" << std::endl; - rpt_ave << "=== Average Power (mW) and Total Energy ===" << std::endl; - for (int k = 0; k < TILES_NUM; k++) { - float pow = 0; - const struct tile_info *t = &tiles[k]; - if (t->type != accelerator_tile) - continue; - const float pow_max = energy_weight[k][VF_OP_POINTS - 1] / period[k][VF_OP_POINTS - 1]; - if (ave_not_max) - pow = power_ave[k]; - else - pow = power_max[k]; - - float bar_value = pow / max; - if (bar_value != 0 && bar_value < 1) - bar_value = 1.0; - pbar_dvfs[k]->setValue(bar_value); - - // TODO: if we change sample window before printing the log, we'll print it wrong! - // Execution time in ns (no need to scale because target fastest clock cycle is 1ns) - float exec_time = (mmi->current_time - mmi->sample_start) * (1<dial_mmi_win->value()); - rpt_max << k << ". " << t->name << ": "; - rpt_ave << k << ". " << t->name << ": "; - rpt_max << std::setprecision(5) << " " << (power_max[k] / max) * pow_max / 100.0 << "mW" << std::endl; - rpt_ave << std::setprecision(5) << " " << (power_ave[k] / max) * pow_max / 100.0 << "mW, "; - float en = exec_time * (power_ave[k] / max) * pow_max / 100.0; - rpt_ave << std::setprecision(5) << " " << en << "pJ" << std::endl; - total_energy += en; - } - rpt_ave << " ** Total Energy: " << std::setprecision(5) << " " << total_energy << "pj **" << std::endl; - } - - rpt_max << std::endl; - rpt_ave << std::endl; + if (ui->check_mmi_dvfs->isChecked()) { + float total_energy = 0.0; + rpt_max << "=== Maximum Power (mW) ===" << std::endl; + rpt_ave << "=== Average Power (mW) and Total Energy ===" << std::endl; + for (int k = 0; k < TILES_NUM; k++) { + float pow = 0; + const struct tile_info *t = &tiles[k]; + if (t->type != accelerator_tile) continue; + const float pow_max = energy_weight[k][VF_OP_POINTS - 1] / period[k][VF_OP_POINTS - 1]; + if (ave_not_max) pow = power_ave[k]; + else + pow = power_max[k]; + + float bar_value = pow / max; + if (bar_value != 0 && bar_value < 1) bar_value = 1.0; + pbar_dvfs[k]->setValue(bar_value); + + // TODO: if we change sample window before printing the log, we'll print it wrong! + // Execution time in ns (no need to scale because target fastest clock cycle is 1ns) + float exec_time = + (mmi->current_time - mmi->sample_start) * (1 << ui->dial_mmi_win->value()); + rpt_max << k << ". " << t->name << ": "; + rpt_ave << k << ". " << t->name << ": "; + rpt_max << std::setprecision(5) << " " << (power_max[k] / max) * pow_max / 100.0 + << "mW" << std::endl; + rpt_ave << std::setprecision(5) << " " << (power_ave[k] / max) * pow_max / 100.0 + << "mW, "; + float en = exec_time * (power_ave[k] / max) * pow_max / 100.0; + rpt_ave << std::setprecision(5) << " " << en << "pJ" << std::endl; + total_energy += en; + } + rpt_ave << " ** Total Energy: " << std::setprecision(5) << " " << total_energy << "pj **" + << std::endl; + } + + rpt_max << std::endl; + rpt_ave << std::endl; #endif #ifdef NOC_QUEUES_offset - /* - * N = 0 - * S = 1 - * W = 2 - * E = 3 - * L = 4 - */ - float global_ave_bandwidth = 0.0; - if (ui->check_mmi_traffic->isChecked()) { - for (int h = 0; h < NOCS_NUM; h++) { - if (ave_not_max) - update_heatmap(h, max, mmi->probes_queue_ave); - else - update_heatmap(h, max, mmi->probes_queue_max); - if (h == 0) { - rpt_max << "=== DMA Mem-to-Dev ===" << std::endl; - rpt_ave << "=== DMA Mem-to-Dev ===" << std::endl; - } else { - rpt_max << "=== DMA Dev-to-Mem ===" << std::endl; - rpt_ave << "=== DMA Dev-to-Mem ===" << std::endl; - } - rpt_max << " Maximum Link Activity % (N, S, W, E, L) ===" << std::endl; - rpt_ave << " Average Link Activity % (N, S, W, E, L) ===" << std::endl; - for (int k = 0; k < TILES_NUM; k++) { - const struct tile_info *t = &tiles[k]; - rpt_max << k << ". " << t->name << ": "; - rpt_ave << k << ". " << t->name << ": "; - for (int i = 0; i < DIRECTIONS; i++) { - rpt_max << std::setprecision(5) << (100.0 * mmi->probes_queue_max[h][k][i]) / max << "%, "; - rpt_ave << std::setprecision(5) << (100.0 * mmi->probes_queue_ave[h][k][i]) / max << "%, "; - global_ave_bandwidth += (100 * mmi->probes_queue_ave[h][k][i]) / max; - } - rpt_max << std::endl; - rpt_ave << std::endl; - } - rpt_max << std::endl; - rpt_ave << std::endl; - } - global_ave_bandwidth /= ((NOCS_NUM * TILES_NUM * DIRECTIONS) - (2 * (XLEN + YLEN) * NOCS_NUM)); - rpt_ave << " ** Average Bandwidth: " << std::setprecision(5) << " " << global_ave_bandwidth << "% **" << std::endl; - } - rpt_max << std::endl; - rpt_ave << std::endl; + /* + * N = 0 + * S = 1 + * W = 2 + * E = 3 + * L = 4 + */ + float global_ave_bandwidth = 0.0; + if (ui->check_mmi_traffic->isChecked()) { + for (int h = 0; h < NOCS_NUM; h++) { + if (ave_not_max) update_heatmap(h, max, mmi->probes_queue_ave); + else + update_heatmap(h, max, mmi->probes_queue_max); + if (h == 0) { + rpt_max << "=== DMA Mem-to-Dev ===" << std::endl; + rpt_ave << "=== DMA Mem-to-Dev ===" << std::endl; + } + else { + rpt_max << "=== DMA Dev-to-Mem ===" << std::endl; + rpt_ave << "=== DMA Dev-to-Mem ===" << std::endl; + } + rpt_max << " Maximum Link Activity % (N, S, W, E, L) ===" << std::endl; + rpt_ave << " Average Link Activity % (N, S, W, E, L) ===" << std::endl; + for (int k = 0; k < TILES_NUM; k++) { + const struct tile_info *t = &tiles[k]; + rpt_max << k << ". " << t->name << ": "; + rpt_ave << k << ". " << t->name << ": "; + for (int i = 0; i < DIRECTIONS; i++) { + rpt_max << std::setprecision(5) + << (100.0 * mmi->probes_queue_max[h][k][i]) / max << "%, "; + rpt_ave << std::setprecision(5) + << (100.0 * mmi->probes_queue_ave[h][k][i]) / max << "%, "; + global_ave_bandwidth += (100 * mmi->probes_queue_ave[h][k][i]) / max; + } + rpt_max << std::endl; + rpt_ave << std::endl; + } + rpt_max << std::endl; + rpt_ave << std::endl; + } + global_ave_bandwidth /= + ((NOCS_NUM * TILES_NUM * DIRECTIONS) - (2 * (XLEN + YLEN) * NOCS_NUM)); + rpt_ave << " ** Average Bandwidth: " << std::setprecision(5) << " " << global_ave_bandwidth + << "% **" << std::endl; + } + rpt_max << std::endl; + rpt_ave << std::endl; #endif #ifdef ACC_offset - if (ui->check_mmi_acc->isChecked()) { - rpt_max << "=== Maximum Communication over Execution Time ratio (%) ===" << std::endl; - rpt_ave << "=== Average Communication over Execution Time ratio (%) ===" << std::endl; - int accelerator = 0; - for (int k = 0; k < TILES_NUM; k++) { - const struct tile_info *t = &tiles[k]; - if (t->type != accelerator_tile) - continue; - - if (ave_not_max) - pbar_acc[accelerator]->setValue(mem_compute_ave[accelerator]); - else - pbar_acc[accelerator]->setValue(mem_compute_max[accelerator]); - - rpt_max << k << ". " << t->name << ": "; - rpt_ave << k << ". " << t->name << ": "; - rpt_max << std::setprecision(5) << mem_compute_max[accelerator] << "%" << std::endl; - rpt_ave << std::setprecision(5) << mem_compute_ave[accelerator] << "%" << std::endl; - accelerator++; - } - rpt_max << "=== Maximum Total Execution Time ratio (%) ===" << std::endl; - rpt_ave << "=== Average Total Execution Time ratio (%) ===" << std::endl; - accelerator = 0; - for (int k = 0; k < TILES_NUM; k++) { - const struct tile_info *t = &tiles[k]; - if (t->type != accelerator_tile) - continue; - - rpt_max << k << ". " << t->name << ": "; - rpt_ave << k << ". " << t->name << ": "; - rpt_max << std::setprecision(5) << exec_compute_max[accelerator] << "%" << std::endl; - rpt_ave << std::setprecision(5) << exec_compute_ave[accelerator] << "%" << std::endl; - accelerator++; - } - - rpt_max << std::endl << "=== Samping time ===" << (mmi->current_time - mmi->sample_start) * (1<dial_mmi_win->value()) * 10 << " ns" << std::endl; - rpt_ave << std::endl << "=== Samping time ===" << (mmi->current_time - mmi->sample_start) * (1<dial_mmi_win->value()) * 10 << " ns" << std::endl; - } + if (ui->check_mmi_acc->isChecked()) { + rpt_max << "=== Maximum Communication over Execution Time ratio (%) ===" << std::endl; + rpt_ave << "=== Average Communication over Execution Time ratio (%) ===" << std::endl; + int accelerator = 0; + for (int k = 0; k < TILES_NUM; k++) { + const struct tile_info *t = &tiles[k]; + if (t->type != accelerator_tile) continue; + + if (ave_not_max) pbar_acc[accelerator]->setValue(mem_compute_ave[accelerator]); + else + pbar_acc[accelerator]->setValue(mem_compute_max[accelerator]); + + rpt_max << k << ". " << t->name << ": "; + rpt_ave << k << ". " << t->name << ": "; + rpt_max << std::setprecision(5) << mem_compute_max[accelerator] << "%" << std::endl; + rpt_ave << std::setprecision(5) << mem_compute_ave[accelerator] << "%" << std::endl; + accelerator++; + } + rpt_max << "=== Maximum Total Execution Time ratio (%) ===" << std::endl; + rpt_ave << "=== Average Total Execution Time ratio (%) ===" << std::endl; + accelerator = 0; + for (int k = 0; k < TILES_NUM; k++) { + const struct tile_info *t = &tiles[k]; + if (t->type != accelerator_tile) continue; + + rpt_max << k << ". " << t->name << ": "; + rpt_ave << k << ". " << t->name << ": "; + rpt_max << std::setprecision(5) << exec_compute_max[accelerator] << "%" << std::endl; + rpt_ave << std::setprecision(5) << exec_compute_ave[accelerator] << "%" << std::endl; + accelerator++; + } + + rpt_max << std::endl + << "=== Samping time ===" + << (mmi->current_time - mmi->sample_start) * (1 << ui->dial_mmi_win->value()) * 10 + << " ns" << std::endl; + rpt_ave << std::endl + << "=== Samping time ===" + << (mmi->current_time - mmi->sample_start) * (1 << ui->dial_mmi_win->value()) * 10 + << " ns" << std::endl; + } #endif - rpt_max.close(); - rpt_ave.close(); - - if (ave_not_max) - print_statistics(file_name_ave.str().c_str()); - else - print_statistics(file_name_max.str().c_str()); + rpt_max.close(); + rpt_ave.close(); + if (ave_not_max) print_statistics(file_name_ave.str().c_str()); + else + print_statistics(file_name_max.str().c_str()); } void EspMonMain::print_statistics(const char *file_name) { - QFile file(file_name); - file.open(QIODevice::ReadOnly); - QTextStream in(&file); - ui->textBrowser->setText(in.readAll()); + QFile file(file_name); + file.open(QIODevice::ReadOnly); + QTextStream in(&file); + ui->textBrowser->setText(in.readAll()); } void EspMonMain::on_btn_stat_ave_clicked() { - ave_not_max = true; - get_statistics(); + ave_not_max = true; + get_statistics(); } void EspMonMain::on_btn_stat_max_clicked() { - ave_not_max = false; - get_statistics(); + ave_not_max = false; + get_statistics(); } diff --git a/tools/espmon/espmonmain.h b/tools/espmon/espmonmain.h index d13f1631e9..1ceeb9233b 100644 --- a/tools/espmon/espmonmain.h +++ b/tools/espmon/espmonmain.h @@ -4,94 +4,92 @@ #ifndef ESPMONMAIN_H #define ESPMONMAIN_H +#include +#include +#include +#include +#include +#include #include #include -#include #include -#include -#include -#include +#include +#include #include -#include #include -#include -#include -#include #include "mmi64_mon.h" #include "power.h" namespace Ui { - class EspMonMain; +class EspMonMain; } class EspMonMain; class MmiWorker : public QObject { - Q_OBJECT + Q_OBJECT - public: - MmiWorker(EspMonMain *mon) { - this->mon = mon; - } + public: + MmiWorker(EspMonMain *mon) { this->mon = mon; } - //~MmiWorker(); + //~MmiWorker(); - public slots: - void process(); + public slots: + void process(); -signals: - void finished(); - void update(); - void error(QString err); + signals: + void finished(); + void update(); + void error(QString err); -private: - EspMonMain *mon; + private: + EspMonMain *mon; }; -class EspMonMain : public QMainWindow -{ - Q_OBJECT +class EspMonMain : public QMainWindow { + Q_OBJECT -public: - explicit EspMonMain(QWidget *parent = 0); - ~EspMonMain(); + public: + explicit EspMonMain(QWidget *parent = 0); + ~EspMonMain(); - void ErrorMessage(const char * c_str); + void ErrorMessage(const char *c_str); - void enable_mmi_panel(); - void disable_mmi_panel(); - void enable_mmi_auto(); + void enable_mmi_panel(); + void disable_mmi_panel(); + void enable_mmi_auto(); - void show_soc(); - void show_dvfs(); - void show_acc(); - void show_heatmap(); + void show_soc(); + void show_dvfs(); + void show_acc(); + void show_heatmap(); - void update_heatmap(int noc, float max, uint32_t (&probes_queue)[NOCS_NUM][TILES_NUM][DIRECTIONS]); + void update_heatmap(int noc, float max, + uint32_t (&probes_queue)[NOCS_NUM][TILES_NUM][DIRECTIONS]); - void set_window(uint32_t win); - void start_probes(); - bool read_probes(); - void get_statistics(); - void print_statistics(const char * file_name); + void set_window(uint32_t win); + void start_probes(); + bool read_probes(); + void get_statistics(); + void print_statistics(const char *file_name); -private slots: - void on_btn_mmi_open_clicked(); + private slots: + void on_btn_mmi_open_clicked(); - void on_dial_mmi_win_sliderMoved(int position); + void on_dial_mmi_win_sliderMoved(int position); - void on_btn_mmi_start_pressed(); + void on_btn_mmi_start_pressed(); - void on_btn_mmi_stop_clicked(); + void on_btn_mmi_stop_clicked(); - void update_probes(); + void update_probes(); - void errorString(QString); + void errorString(QString); - void on_check_mmi_acc_toggled(bool checked); + void on_check_mmi_acc_toggled(bool checked); - void on_check_mmi_dvfs_toggled(bool checked); + void on_check_mmi_dvfs_toggled(bool checked); void on_check_mmi_auto_toggled(bool checked); @@ -99,35 +97,34 @@ private slots: void on_btn_stat_max_clicked(); -public: - Ui::EspMonMain *ui; - std::vector btn_tiles; - std::vector pbar_dvfs; - std::vector pbar_acc; - QGridLayout *layout_heat; - std::vector wid_map[NOCS_NUM]; - std::vector wid_map1[NOCS_NUM]; - - unsigned long long router_is_active[NOCS_NUM][TILES_NUM]; - - // MMI - mmi64_mon *mmi; - bool mmi_is_open; - bool mmi_is_running; - unsigned long long current_time; - unsigned long long new_time; - bool first_sample; - bool ave_not_max; - float power_tot[TILES_NUM]; - float power_max[TILES_NUM]; - float power_ave[TILES_NUM]; - double mem_compute_tot[ACCS_NUM]; - float mem_compute_max[ACCS_NUM]; - float mem_compute_ave[ACCS_NUM]; - double exec_compute_tot[ACCS_NUM]; - float exec_compute_max[ACCS_NUM]; - float exec_compute_ave[ACCS_NUM]; - + public: + Ui::EspMonMain *ui; + std::vector btn_tiles; + std::vector pbar_dvfs; + std::vector pbar_acc; + QGridLayout *layout_heat; + std::vector wid_map[NOCS_NUM]; + std::vector wid_map1[NOCS_NUM]; + + unsigned long long router_is_active[NOCS_NUM][TILES_NUM]; + + // MMI + mmi64_mon *mmi; + bool mmi_is_open; + bool mmi_is_running; + unsigned long long current_time; + unsigned long long new_time; + bool first_sample; + bool ave_not_max; + float power_tot[TILES_NUM]; + float power_max[TILES_NUM]; + float power_ave[TILES_NUM]; + double mem_compute_tot[ACCS_NUM]; + float mem_compute_max[ACCS_NUM]; + float mem_compute_ave[ACCS_NUM]; + double exec_compute_tot[ACCS_NUM]; + float exec_compute_max[ACCS_NUM]; + float exec_compute_ave[ACCS_NUM]; }; #endif // ESPMONMAIN_H diff --git a/tools/mmi64/mmi64.c b/tools/mmi64/mmi64.c index 8d019dde38..b54aef3291 100644 --- a/tools/mmi64/mmi64.c +++ b/tools/mmi64/mmi64.c @@ -3,56 +3,56 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include -#include -#include -#include "profpga.h" #include "mmi64.h" -#include "mmi64_module_regif.h" #include "mmi64_module_devzero.h" -#include "profpga_error.h" +#include "mmi64_module_regif.h" +#include "profpga.h" #include "profpga_acm.h" +#include "profpga_error.h" #include +#include +#include #include "mmi64_regs.h" #ifdef PRINT_COLORS -#define KNRM "\x1B[0m" -#define KRED "\x1B[31m" -#define KGRN "\x1B[32m" -#define KYEL "\x1B[33m" -#define KBLU "\x1B[34m" -#define KMAG "\x1B[35m" -#define KCYN "\x1B[36m" -#define KWHT "\x1B[37m" - -#define SET_RED(_fp) fprintf(_fp, "%s", KRED) -#define SET_GRN(_fp) fprintf(_fp, "%s", KGRN) -#define SET_YEL(_fp) fprintf(_fp, "%s", KYEL) -#define SET_BLU(_fp) fprintf(_fp, "%s", KBLU) -#define SET_MAG(_fp) fprintf(_fp, "%s", KMAG) -#define SET_CYN(_fp) fprintf(_fp, "%s", KCYN) -#define SET_WHT(_fp) fprintf(_fp, "%s", KWHT) -#define SET_NRM(_fp) fprintf(_fp, "%s", KNRM) + #define KNRM "\x1B[0m" + #define KRED "\x1B[31m" + #define KGRN "\x1B[32m" + #define KYEL "\x1B[33m" + #define KBLU "\x1B[34m" + #define KMAG "\x1B[35m" + #define KCYN "\x1B[36m" + #define KWHT "\x1B[37m" + + #define SET_RED(_fp) fprintf(_fp, "%s", KRED) + #define SET_GRN(_fp) fprintf(_fp, "%s", KGRN) + #define SET_YEL(_fp) fprintf(_fp, "%s", KYEL) + #define SET_BLU(_fp) fprintf(_fp, "%s", KBLU) + #define SET_MAG(_fp) fprintf(_fp, "%s", KMAG) + #define SET_CYN(_fp) fprintf(_fp, "%s", KCYN) + #define SET_WHT(_fp) fprintf(_fp, "%s", KWHT) + #define SET_NRM(_fp) fprintf(_fp, "%s", KNRM) #else -#define SET_RED(_fp) -#define SET_GRN(_fp) -#define SET_YEL(_fp) -#define SET_BLU(_fp) -#define SET_MAG(_fp) -#define SET_CYN(_fp) -#define SET_WHT(_fp) -#define SET_NRM(_fp) + #define SET_RED(_fp) + #define SET_GRN(_fp) + #define SET_YEL(_fp) + #define SET_BLU(_fp) + #define SET_MAG(_fp) + #define SET_CYN(_fp) + #define SET_WHT(_fp) + #define SET_NRM(_fp) #endif @@ -71,512 +71,502 @@ FILE *fp; void reset_all_counters(mmi64_module_t *user_module) { - int i; - profpga_error_t status; - int reset_regid = MONITOR_RESET_offset; - for (i = 0; i < MONITOR_REG_COUNT; i++) { - int ireg = i; - status = mmi64_regif_write_32_ack(user_module, reset_regid, 1, &ireg); - } + int i; + profpga_error_t status; + int reset_regid = MONITOR_RESET_offset; + for (i = 0; i < MONITOR_REG_COUNT; i++) { + int ireg = i; + status = mmi64_regif_write_32_ack(user_module, reset_regid, 1, &ireg); + } } void read_counter(mmi64_module_t *user_module, int regid) { - if (regid >= TOTAL_REG_COUNT) { - fprintf(stderr, "%s: invalid register id %d; range is [0-%d]\n", __func__, regid, TOTAL_REG_COUNT); - exit(EXIT_FAILURE); - } - profpga_error_t status; - unsigned rdata; - status = mmi64_regif_read_32(user_module, regid, 1, &rdata); - fprintf(fp, "r%d = %d\n", regid, rdata); + if (regid >= TOTAL_REG_COUNT) { + fprintf(stderr, "%s: invalid register id %d; range is [0-%d]\n", __func__, regid, + TOTAL_REG_COUNT); + exit(EXIT_FAILURE); + } + profpga_error_t status; + unsigned rdata; + status = mmi64_regif_read_32(user_module, regid, 1, &rdata); + fprintf(fp, "r%d = %d\n", regid, rdata); } long long unsigned read_timestamp(mmi64_module_t *user_module) { - profpga_error_t status; - int window_lo_regid = MONITOR_WINDOW_LO_offset; - int window_hi_regid = MONITOR_WINDOW_HI_offset; - long long unsigned time_stamp = 0; - unsigned rdata; - status = mmi64_regif_read_32(user_module, window_hi_regid, 1, &rdata); - time_stamp = ((long long unsigned) rdata) << 32; - status = mmi64_regif_read_32(user_module, window_lo_regid, 1, &rdata); - time_stamp |= (long long unsigned) rdata; - return time_stamp; + profpga_error_t status; + int window_lo_regid = MONITOR_WINDOW_LO_offset; + int window_hi_regid = MONITOR_WINDOW_HI_offset; + long long unsigned time_stamp = 0; + unsigned rdata; + status = mmi64_regif_read_32(user_module, window_hi_regid, 1, &rdata); + time_stamp = ((long long unsigned)rdata) << 32; + status = mmi64_regif_read_32(user_module, window_lo_regid, 1, &rdata); + time_stamp |= (long long unsigned)rdata; + return time_stamp; } #ifdef NOC_QUEUES_offset void read_noc_traffic(mmi64_module_t *user_module) { -/* - # NoC.queue_n_traffic_ - # NoC.queue_s_traffic_ - # NoC.queue_w_traffic_ - # NoC.queue_e_traffic_ - # NoC.queue_l_traffic_ -*/ - profpga_error_t status; - int noc, tile, dir; - unsigned rdata[NOCS_NUM][TILES_NUM][5]; - int regid; - - for (noc = 0; noc < NOCS_NUM; noc++) - for (tile = 0; tile < TILES_NUM; tile++) - for (dir = 0; dir < 5; dir++) { - regid = NOC_QUEUES_offset + noc * TILES_NUM * 5 + tile * 5 + dir; - status = mmi64_regif_read_32(user_module, regid, 1, &rdata[noc][tile][dir]); - } - - for (noc = 0; noc < NOCS_NUM; noc++) - for (tile = 0; tile < TILES_NUM; tile++) - for (dir = 0; dir < 5; dir++) - fprintf(fp, "%d\t", rdata[noc][tile][dir]); - + /* + # NoC.queue_n_traffic_ + # NoC.queue_s_traffic_ + # NoC.queue_w_traffic_ + # NoC.queue_e_traffic_ + # NoC.queue_l_traffic_ + */ + profpga_error_t status; + int noc, tile, dir; + unsigned rdata[NOCS_NUM][TILES_NUM][5]; + int regid; + + for (noc = 0; noc < NOCS_NUM; noc++) + for (tile = 0; tile < TILES_NUM; tile++) + for (dir = 0; dir < 5; dir++) { + regid = NOC_QUEUES_offset + noc * TILES_NUM * 5 + tile * 5 + dir; + status = mmi64_regif_read_32(user_module, regid, 1, &rdata[noc][tile][dir]); + } + + for (noc = 0; noc < NOCS_NUM; noc++) + for (tile = 0; tile < TILES_NUM; tile++) + for (dir = 0; dir < 5; dir++) + fprintf(fp, "%d\t", rdata[noc][tile][dir]); } #endif #ifdef ACC_offset int read_accelerator_mon(mmi64_module_t *user_module, int accelerator) { - int relevant = 0; - profpga_error_t status; - int tlb_regid = ACC_offset + accelerator * 5; - int mem_lo_regid = ACC_offset + accelerator * 5 + 1; - int mem_hi_regid = ACC_offset + accelerator * 5 + 2; - int tot_lo_regid = ACC_offset + accelerator * 5 + 3; - int tot_hi_regid = ACC_offset + accelerator * 5 + 4; - - long long unsigned tlb = 0; - long long unsigned mem = 0; - long long unsigned tot = 0; - unsigned rdata; - status = mmi64_regif_read_32(user_module, tot_hi_regid, 1, &rdata); - tot = ((long long unsigned) rdata) << 32; - status = mmi64_regif_read_32(user_module, tot_lo_regid, 1, &rdata); - tot |= (long long unsigned ) rdata; - status = mmi64_regif_read_32(user_module, mem_hi_regid, 1, &rdata); - mem = ((long long unsigned) rdata) << 32; - status = mmi64_regif_read_32(user_module, mem_lo_regid, 1, &rdata); - mem |= (long long unsigned ) rdata; - status = mmi64_regif_read_32(user_module, tlb_regid, 1, &rdata); - tlb = (long long unsigned) rdata; - - if (accelerator % 2) - SET_CYN(fp); - else - SET_WHT(fp); - fprintf(fp, "%d\t%d\t%d\t", tlb, mem, tot); - if (tot != 0) - relevant = 1; - - SET_NRM(fp); - - return relevant; + int relevant = 0; + profpga_error_t status; + int tlb_regid = ACC_offset + accelerator * 5; + int mem_lo_regid = ACC_offset + accelerator * 5 + 1; + int mem_hi_regid = ACC_offset + accelerator * 5 + 2; + int tot_lo_regid = ACC_offset + accelerator * 5 + 3; + int tot_hi_regid = ACC_offset + accelerator * 5 + 4; + + long long unsigned tlb = 0; + long long unsigned mem = 0; + long long unsigned tot = 0; + unsigned rdata; + status = mmi64_regif_read_32(user_module, tot_hi_regid, 1, &rdata); + tot = ((long long unsigned)rdata) << 32; + status = mmi64_regif_read_32(user_module, tot_lo_regid, 1, &rdata); + tot |= (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, mem_hi_regid, 1, &rdata); + mem = ((long long unsigned)rdata) << 32; + status = mmi64_regif_read_32(user_module, mem_lo_regid, 1, &rdata); + mem |= (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, tlb_regid, 1, &rdata); + tlb = (long long unsigned)rdata; + + if (accelerator % 2) SET_CYN(fp); + else + SET_WHT(fp); + fprintf(fp, "%d\t%d\t%d\t", tlb, mem, tot); + if (tot != 0) relevant = 1; + + SET_NRM(fp); + + return relevant; } int read_accelerators_mon(mmi64_module_t *user_module) { - int i; - int relevant = 0; - for (i = 0; i < ACCS_NUM; i++) - if (read_accelerator_mon(user_module, i)) - relevant = 1; - return relevant; + int i; + int relevant = 0; + for (i = 0; i < ACCS_NUM; i++) + if (read_accelerator_mon(user_module, i)) relevant = 1; + return relevant; } #endif - #ifdef L2_offset void read_l2_stats(mmi64_module_t *user_module, int cache_id) { - profpga_error_t status; - int hit_regid = L2_offset + cache_id * 2; - int miss_regid = L2_offset + cache_id * 2 + 1; - - long long unsigned hit = 0; - long long unsigned miss = 0; - unsigned rdata; - - status = mmi64_regif_read_32(user_module, hit_regid, 1, &rdata); - hit = (long long unsigned) rdata; - status = mmi64_regif_read_32(user_module, miss_regid, 1, &rdata); - miss = (long long unsigned) rdata; - - if (cache_id % 2) - SET_MAG(fp); - else - SET_BLU(fp); - fprintf(fp, "%d\t%d\t", hit, miss); - - SET_NRM(fp); + profpga_error_t status; + int hit_regid = L2_offset + cache_id * 2; + int miss_regid = L2_offset + cache_id * 2 + 1; + + long long unsigned hit = 0; + long long unsigned miss = 0; + unsigned rdata; + + status = mmi64_regif_read_32(user_module, hit_regid, 1, &rdata); + hit = (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, miss_regid, 1, &rdata); + miss = (long long unsigned)rdata; + + if (cache_id % 2) SET_MAG(fp); + else + SET_BLU(fp); + fprintf(fp, "%d\t%d\t", hit, miss); + + SET_NRM(fp); } void read_l2s_stats(mmi64_module_t *user_module) { - int i; - for (i = 0; i < L2S_NUM; i++) - read_l2_stats(user_module, i); + int i; + for (i = 0; i < L2S_NUM; i++) + read_l2_stats(user_module, i); } #endif #ifdef LLC_offset void read_llc_stats(mmi64_module_t *user_module, int cache_id) { - profpga_error_t status; - int hit_regid = LLC_offset + cache_id * 2; - int miss_regid = LLC_offset + cache_id * 2 + 1; + profpga_error_t status; + int hit_regid = LLC_offset + cache_id * 2; + int miss_regid = LLC_offset + cache_id * 2 + 1; - long long unsigned hit = 0; - long long unsigned miss = 0; - unsigned rdata; + long long unsigned hit = 0; + long long unsigned miss = 0; + unsigned rdata; - status = mmi64_regif_read_32(user_module, hit_regid, 1, &rdata); - hit = (long long unsigned) rdata; - status = mmi64_regif_read_32(user_module, miss_regid, 1, &rdata); - miss = (long long unsigned) rdata; + status = mmi64_regif_read_32(user_module, hit_regid, 1, &rdata); + hit = (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, miss_regid, 1, &rdata); + miss = (long long unsigned)rdata; - fprintf(fp, "%d\t%d\t", hit, miss); + fprintf(fp, "%d\t%d\t", hit, miss); } void read_llcs_stats(mmi64_module_t *user_module) { - int i; - for (i = 0; i < LLCS_NUM; i++) - read_llc_stats(user_module, i); + int i; + for (i = 0; i < LLCS_NUM; i++) + read_llc_stats(user_module, i); } #endif - #ifdef DDR_offset void read_ddr(mmi64_module_t *user_module) { - profpga_error_t status; - int i; - for (i = 0; i < DDRS_NUM; i++) { - int ddr_regid = DDR_offset + i; - unsigned ddr; - status = mmi64_regif_read_32(user_module, ddr_regid, 1, &ddr); - fprintf(fp, "%d\t", ddr); - } + profpga_error_t status; + int i; + for (i = 0; i < DDRS_NUM; i++) { + int ddr_regid = DDR_offset + i; + unsigned ddr; + status = mmi64_regif_read_32(user_module, ddr_regid, 1, &ddr); + fprintf(fp, "%d\t", ddr); + } } #endif #ifdef MEM_offset void read_mem_stats(mmi64_module_t *user_module, int mem_id) { - profpga_error_t status; - - int coh_req_regid = MEM_offset + mem_id * 8; - int coh_fwd_regid = MEM_offset + mem_id * 8 + 1; - int coh_rsp_rcv_regid = MEM_offset + mem_id * 8 + 2; - int coh_rsp_snd_regid = MEM_offset + mem_id * 8 + 3; - int dma_req_regid = MEM_offset + mem_id * 8 + 4; - int dma_rsp_regid = MEM_offset + mem_id * 8 + 5; - int coh_dma_req_regid = MEM_offset + mem_id * 8 + 6; - int coh_dma_rsp_regid = MEM_offset + mem_id * 8 + 7; - - long long unsigned coh_req = 0; - long long unsigned coh_fwd = 0; - long long unsigned coh_rsp_rcv = 0; - long long unsigned coh_rsp_snd = 0; - long long unsigned dma_req = 0; - long long unsigned dma_rsp = 0; - long long unsigned coh_dma_req = 0; - long long unsigned coh_dma_rsp = 0; - - unsigned rdata; - - status = mmi64_regif_read_32(user_module, coh_req_regid, 1, &rdata); - coh_req = (long long unsigned) rdata; - status = mmi64_regif_read_32(user_module, coh_fwd_regid, 1, &rdata); - coh_fwd = (long long unsigned) rdata; - status = mmi64_regif_read_32(user_module, coh_rsp_rcv_regid, 1, &rdata); - coh_rsp_rcv = (long long unsigned) rdata; - status = mmi64_regif_read_32(user_module, coh_rsp_snd_regid, 1, &rdata); - coh_rsp_snd = (long long unsigned) rdata; - status = mmi64_regif_read_32(user_module, dma_req_regid, 1, &rdata); - dma_req = (long long unsigned) rdata; - status = mmi64_regif_read_32(user_module, dma_rsp_regid, 1, &rdata); - dma_rsp = (long long unsigned) rdata; - status = mmi64_regif_read_32(user_module, coh_dma_req_regid, 1, &rdata); - coh_dma_req = (long long unsigned) rdata; - status = mmi64_regif_read_32(user_module, coh_dma_rsp_regid, 1, &rdata); - coh_dma_rsp = (long long unsigned) rdata; - - SET_GRN(fp); - fprintf(fp, "%d\t%d\t%d\t%d\t", - coh_req, coh_fwd, coh_rsp_rcv, coh_rsp_snd); - - SET_RED(fp); - fprintf(fp, "%d\t%d\t", - dma_req, dma_rsp); - - SET_YEL(fp); - fprintf(fp, "%d\t%d\t", - coh_dma_req, coh_dma_rsp); - - SET_NRM(fp); + profpga_error_t status; + + int coh_req_regid = MEM_offset + mem_id * 8; + int coh_fwd_regid = MEM_offset + mem_id * 8 + 1; + int coh_rsp_rcv_regid = MEM_offset + mem_id * 8 + 2; + int coh_rsp_snd_regid = MEM_offset + mem_id * 8 + 3; + int dma_req_regid = MEM_offset + mem_id * 8 + 4; + int dma_rsp_regid = MEM_offset + mem_id * 8 + 5; + int coh_dma_req_regid = MEM_offset + mem_id * 8 + 6; + int coh_dma_rsp_regid = MEM_offset + mem_id * 8 + 7; + + long long unsigned coh_req = 0; + long long unsigned coh_fwd = 0; + long long unsigned coh_rsp_rcv = 0; + long long unsigned coh_rsp_snd = 0; + long long unsigned dma_req = 0; + long long unsigned dma_rsp = 0; + long long unsigned coh_dma_req = 0; + long long unsigned coh_dma_rsp = 0; + + unsigned rdata; + + status = mmi64_regif_read_32(user_module, coh_req_regid, 1, &rdata); + coh_req = (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, coh_fwd_regid, 1, &rdata); + coh_fwd = (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, coh_rsp_rcv_regid, 1, &rdata); + coh_rsp_rcv = (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, coh_rsp_snd_regid, 1, &rdata); + coh_rsp_snd = (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, dma_req_regid, 1, &rdata); + dma_req = (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, dma_rsp_regid, 1, &rdata); + dma_rsp = (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, coh_dma_req_regid, 1, &rdata); + coh_dma_req = (long long unsigned)rdata; + status = mmi64_regif_read_32(user_module, coh_dma_rsp_regid, 1, &rdata); + coh_dma_rsp = (long long unsigned)rdata; + + SET_GRN(fp); + fprintf(fp, "%d\t%d\t%d\t%d\t", coh_req, coh_fwd, coh_rsp_rcv, coh_rsp_snd); + + SET_RED(fp); + fprintf(fp, "%d\t%d\t", dma_req, dma_rsp); + + SET_YEL(fp); + fprintf(fp, "%d\t%d\t", coh_dma_req, coh_dma_rsp); + + SET_NRM(fp); } void read_mems_stats(mmi64_module_t *user_module) { - int i; - for (i = 0; i < MEMS_NUM; i++) - read_mem_stats(user_module, i); + int i; + for (i = 0; i < MEMS_NUM; i++) + read_mem_stats(user_module, i); } #endif #ifdef NOC_INJECT_offset void read_injection_rate(mmi64_module_t *user_module) { - profpga_error_t status; - int i, k; - unsigned rdata[NOCS_NUM][TILES_NUM]; - for (k = 0; k < NOCS_NUM; k++) { - for (i = 0; i < TILES_NUM; i++) { - int injection_regid = NOC_INJECT_offset + (k * TILES_NUM) + i; - status = mmi64_regif_read_32(user_module, injection_regid, 1, &rdata[k][i]); - } - } - for (k = 0; k < NOCS_NUM; k++) - for (i = 0; i < TILES_NUM; i++) - fprintf(fp, "%d\t", rdata[k][i]); - + profpga_error_t status; + int i, k; + unsigned rdata[NOCS_NUM][TILES_NUM]; + for (k = 0; k < NOCS_NUM; k++) { + for (i = 0; i < TILES_NUM; i++) { + int injection_regid = NOC_INJECT_offset + (k * TILES_NUM) + i; + status = mmi64_regif_read_32(user_module, injection_regid, 1, &rdata[k][i]); + } + } + for (k = 0; k < NOCS_NUM; k++) + for (i = 0; i < TILES_NUM; i++) + fprintf(fp, "%d\t", rdata[k][i]); } #endif #ifdef DVFS_offset void read_dvfs(mmi64_module_t *user_module) { - profpga_error_t status; - int i, k; - unsigned rdata[TILES_NUM][VF_OP_POINTS]; - for (k = 0; k < TILES_NUM; k++) { - for (i = 0; i < VF_OP_POINTS; i++) { - int dvfs_regid = DVFS_offset + (k * VF_OP_POINTS) + i; - status = mmi64_regif_read_32(user_module, dvfs_regid, 1, &rdata[k][i]); - } - } - for (k = 0; k < TILES_NUM; k++) - for (i = 0; i < VF_OP_POINTS; i++) { - if (rdata[k][i] != 0 && tile_has_dvfs[k]) - relevant_window = 1; - fprintf(fp, "%d\t", rdata[k][i]); - } - + profpga_error_t status; + int i, k; + unsigned rdata[TILES_NUM][VF_OP_POINTS]; + for (k = 0; k < TILES_NUM; k++) { + for (i = 0; i < VF_OP_POINTS; i++) { + int dvfs_regid = DVFS_offset + (k * VF_OP_POINTS) + i; + status = mmi64_regif_read_32(user_module, dvfs_regid, 1, &rdata[k][i]); + } + } + for (k = 0; k < TILES_NUM; k++) + for (i = 0; i < VF_OP_POINTS; i++) { + if (rdata[k][i] != 0 && tile_has_dvfs[k]) relevant_window = 1; + fprintf(fp, "%d\t", rdata[k][i]); + } } #endif - void set_window(mmi64_module_t *user_module, int window) { - profpga_error_t status; - int window_size_regid = MONITOR_WINDOW_SIZE_offset; - status = mmi64_regif_write_32_ack(user_module, window_size_regid, 1, &window); + profpga_error_t status; + int window_size_regid = MONITOR_WINDOW_SIZE_offset; + status = mmi64_regif_write_32_ack(user_module, window_size_regid, 1, &window); } -#define CHECK(status) if (status!=E_PROFPGA_OK) { \ - printf(NOW("ERROR: %s\n"), profpga_strerror(status)); \ - return status; } +#define CHECK(status) \ + if (status != E_PROFPGA_OK) { \ + printf(NOW("ERROR: %s\n"), profpga_strerror(status)); \ + return status; \ + } - -int message_handler(const int messagetype, const char *fmt,...) +int message_handler(const int messagetype, const char *fmt, ...) { - int n; - va_list ap; - va_start(ap, fmt); - n = vfprintf(stdout, fmt, ap); - va_end(ap); - return n; + int n; + va_list ap; + va_start(ap, fmt); + n = vfprintf(stdout, fmt, ap); + va_end(ap); + return n; } -char * cfgfilename = "profpga.cfg"; +char *cfgfilename = "profpga.cfg"; void *wait_for_user_stop(void *stop) { - char val; - int *local_stop = (int *) stop; - printf("Press any key to stop Monitor...\n"); - scanf("%c", &val); - *local_stop = 1; - return NULL; + char val; + int *local_stop = (int *)stop; + printf("Press any key to stop Monitor...\n"); + scanf("%c", &val); + *local_stop = 1; + return NULL; } -mmi64_error_t mmi64_main(int argc, char * argv[]) +mmi64_error_t mmi64_main(int argc, char *argv[]) { - profpga_handle_t * profpga; - profpga_error_t status; - uint32_t data[8]; - const mmi64_addr_t user_addr[] = {2, 1, 0}; - mmi64_module_t * user_module; - - int mh_status = profpga_set_message_handler(message_handler); - int i, j, k; - - pid_t pid; - pthread_t aux; - int stop = 0; - long long unsigned new_time; - - if (mh_status!=0) { - printf("ERROR: Failed to install message handler (code %d)\n", mh_status); - return mh_status; - } - - // connect to system - printf(NOW("Open connection to profpga platform...\n")); - - status = profpga_open (&profpga, cfgfilename); - if (status!=E_PROFPGA_OK) { // cannot use NOW() macro because required MMI-64 domain handle has not been initialized - printf("ERROR: Failed connect to PROFPGA system (%s)\n", profpga_strerror(status)); - return status; - } + profpga_handle_t *profpga; + profpga_error_t status; + uint32_t data[8]; + const mmi64_addr_t user_addr[] = {2, 1, 0}; + mmi64_module_t *user_module; + + int mh_status = profpga_set_message_handler(message_handler); + int i, j, k; + + pid_t pid; + pthread_t aux; + int stop = 0; + long long unsigned new_time; + + if (mh_status != 0) { + printf("ERROR: Failed to install message handler (code %d)\n", mh_status); + return mh_status; + } + + // connect to system + printf(NOW("Open connection to profpga platform...\n")); + + status = profpga_open(&profpga, cfgfilename); + if (status != E_PROFPGA_OK) { // cannot use NOW() macro because required MMI-64 domain handle + // has not been initialized + printf("ERROR: Failed connect to PROFPGA system (%s)\n", profpga_strerror(status)); + return status; + } #ifdef HDL_SIM - // for HDL simulation: perform configuration as done by profpga_run --up - printf(NOW("Bring up system.\n")); - status = profpga_up(profpga); - CHECK(status); + // for HDL simulation: perform configuration as done by profpga_run --up + printf(NOW("Bring up system.\n")); + status = profpga_up(profpga); + CHECK(status); #endif - // scan for MMI-64 modules - printf(NOW("Scan hardware...\n")); - status = mmi64_identify_scan(profpga->mmi64_domain); - CHECK(status); - - // print scan results - status = mmi64_info_print(profpga->mmi64_domain); - CHECK(status); + // scan for MMI-64 modules + printf(NOW("Scan hardware...\n")); + status = mmi64_identify_scan(profpga->mmi64_domain); + CHECK(status); - // find user module - status = mmi64_identify_by_address(profpga->mmi64_domain, user_addr, &user_module); - CHECK(status); - if (user_module==NULL) { - printf("ERROR: Failed to identify user module. \n"); - return -1; - } + // print scan results + status = mmi64_info_print(profpga->mmi64_domain); + CHECK(status); + // find user module + status = mmi64_identify_by_address(profpga->mmi64_domain, user_addr, &user_module); + CHECK(status); + if (user_module == NULL) { + printf("ERROR: Failed to identify user module. \n"); + return -1; + } - fp = fopen("mmi64.rpt", "w+"); + fp = fopen("mmi64.rpt", "w+"); - if (pthread_create(&aux, NULL, wait_for_user_stop, (void *) &stop)) { - fprintf(stderr, "Error creating thread\n"); - exit(EXIT_FAILURE); - } + if (pthread_create(&aux, NULL, wait_for_user_stop, (void *)&stop)) { + fprintf(stderr, "Error creating thread\n"); + exit(EXIT_FAILURE); + } - fprintf(fp, "win\t"); + fprintf(fp, "win\t"); #ifdef DDR_offset - fprintf(fp, "ddr0\tddr1\t"); + fprintf(fp, "ddr0\tddr1\t"); #endif #ifdef LLC_offset - for (i = 0; i < LLCS_NUM; i++) - fprintf(fp, "coh-req-%d\tcoh-fwd-%d\tcoh_rsp_rcv-%d\tcoh_rsp_snd-%d\tdma_req-%d\tdma_rsp-%d\tcoh_dma_req-%d\tcoh_dma_rsp-%d\t", - i, i, i, i, i, i, i, i); + for (i = 0; i < LLCS_NUM; i++) + fprintf(fp, + "coh-req-%d\tcoh-fwd-%d\tcoh_rsp_rcv-%d\tcoh_rsp_snd-%d\tdma_req-%d\tdma_rsp-%" + "d\tcoh_dma_req-%d\tcoh_dma_rsp-%d\t", + i, i, i, i, i, i, i, i); #endif #ifdef NOC_INJECT_offset - for (k = 0; k < NOCS_NUM; k++) - for (i = 0; i < TILES_NUM; i++) - fprintf(fp, "inj-%d-%d\t", k, i); + for (k = 0; k < NOCS_NUM; k++) + for (i = 0; i < TILES_NUM; i++) + fprintf(fp, "inj-%d-%d\t", k, i); #endif #ifdef NOC_QUEUES_offset - for (k = 0; k < NOCS_NUM; k++) - for (i = 0; i < TILES_NUM; i++) - for (j = 0; j < 5; j++) - fprintf(fp, "v-%d-%d-%s\t", k, i, direction[j]); + for (k = 0; k < NOCS_NUM; k++) + for (i = 0; i < TILES_NUM; i++) + for (j = 0; j < 5; j++) + fprintf(fp, "v-%d-%d-%s\t", k, i, direction[j]); #endif #ifdef ACC_offset - for (i = 0; i < ACCS_NUM; i++) - fprintf(fp, "tlb-%d\tmem-%d\ttot-%d\t", i, i, i); + for (i = 0; i < ACCS_NUM; i++) + fprintf(fp, "tlb-%d\tmem-%d\ttot-%d\t", i, i, i); #endif #ifdef L2_offset - for (i = 0; i < L2S_NUM; i++) - fprintf(fp, "hit-%d\tmiss-%d\t", i, i); + for (i = 0; i < L2S_NUM; i++) + fprintf(fp, "hit-%d\tmiss-%d\t", i, i); #endif #ifdef LLC_offset - for (i = 0; i < LLCS_NUM; i++) - fprintf(fp, "hit-%d\tmiss-%d\t", i, i); + for (i = 0; i < LLCS_NUM; i++) + fprintf(fp, "hit-%d\tmiss-%d\t", i, i); #endif #ifdef DVFS_offset - for (k = 0; k < TILES_NUM; k++) - for (i = 0; i < VF_OP_POINTS; i++) - fprintf(fp, "vf-%d-%d\t", k, i); + for (k = 0; k < TILES_NUM; k++) + for (i = 0; i < VF_OP_POINTS; i++) + fprintf(fp, "vf-%d-%d\t", k, i); #endif - fprintf(fp, "\n"); - fflush(fp); - - set_window(user_module, (1<<21)); - - int relevant; - int count = 0; - while(!stop) { - /* if (count == 30) */ - /* goto close_fpga; */ - relevant = 0; - new_time = read_timestamp(user_module); - if (new_time != current_time) { - current_time = new_time; - fprintf(fp, "%d\t", new_time); + fprintf(fp, "\n"); + fflush(fp); + + set_window(user_module, (1 << 21)); + + int relevant; + int count = 0; + while (!stop) { + /* if (count == 30) */ + /* goto close_fpga; */ + relevant = 0; + new_time = read_timestamp(user_module); + if (new_time != current_time) { + current_time = new_time; + fprintf(fp, "%d\t", new_time); #ifdef DDR_offset - read_ddr(user_module); + read_ddr(user_module); #endif #ifdef MEM_offset - read_mems_stats(user_module); + read_mems_stats(user_module); #endif #ifdef NOC_INJECT_offset - read_injection_rate(user_module); + read_injection_rate(user_module); #endif #ifdef NOC_QUEUES_offset - read_noc_traffic(user_module); + read_noc_traffic(user_module); #endif #ifdef ACC_offset - relevant = read_accelerators_mon(user_module); + relevant = read_accelerators_mon(user_module); #endif #ifdef L2_offset - read_l2s_stats(user_module); + read_l2s_stats(user_module); #endif #ifdef LLC_offset - read_llcs_stats(user_module); + read_llcs_stats(user_module); #endif #ifdef DVFS_offset - read_dvfs(user_module); + read_dvfs(user_module); #endif - if (!relevant) { - fprintf(fp, "\tN"); - count++; - } - else { - fprintf(fp, "\tY"); - count = 0; - } - fprintf(fp, "\n"); - fflush(fp); - } - } + if (!relevant) { + fprintf(fp, "\tN"); + count++; + } + else { + fprintf(fp, "\tY"); + count = 0; + } + fprintf(fp, "\n"); + fflush(fp); + } + } close_fpga: - printf(NOW("Done. Closing connection...\n")); - return profpga_close(&profpga); + printf(NOW("Done. Closing connection...\n")); + return profpga_close(&profpga); } #ifndef HDL_SIM -int main(int argc, char * argv[]) +int main(int argc, char *argv[]) { - if (argc!=2) { - printf("Wrong arguments! Usage:\n mmi64basic_test [CONFIGFILE.cfg]\n"); - return -1; - } - printf("Using configuration file %s\n", argv[1]); - cfgfilename = argv[1]; - return mmi64_main(argc, argv); + if (argc != 2) { + printf("Wrong arguments! Usage:\n mmi64basic_test [CONFIGFILE.cfg]\n"); + return -1; + } + printf("Using configuration file %s\n", argv[1]); + cfgfilename = argv[1]; + return mmi64_main(argc, argv); } #endif diff --git a/tools/plmgen/plmgen.py b/tools/plmgen/plmgen.py index 0fbe135bd8..1967d70585 100755 --- a/tools/plmgen/plmgen.py +++ b/tools/plmgen/plmgen.py @@ -9,6 +9,8 @@ import math ### Helpers ### + + def print_usage(): print("Usage : ./plmgen.py ") print("") @@ -47,7 +49,8 @@ def print_usage(): print(" : 0w -> no write operation. The first operation in the list cannot have") print(" zero write interfaces or the testbench will fail") print(" : 1w -> 1 write operation") - print(" : <[2|4|8|16]>w -> 2 parallel write operations with known (modulo) address pattern.") + print( + " : <[2|4|8|16]>w -> 2 parallel write operations with known (modulo) address pattern.") print(" Data are distributed across banks and the number of banks must") print(" be a power of two to have low-overhead bank-selection logic") print(" : 2wu -> 2 parallel write operations with unknown address pattern. This is") @@ -56,7 +59,8 @@ def print_usage(): print("") print(" : 0r -> no read operation") print(" : 1r -> 1 read operation") - print(" : <[2|4|8|16]>r -> parallel read operations with known (modulo) address pattern.") + print( + " : <[2|4|8|16]>r -> parallel read operations with known (modulo) address pattern.") print(" Data are distributed across banks and the number of banks must") print(" be a power of two to have low-overhead bank-selection logic") print(" : ru -> N parallel read operations with unknown address pattern. This") @@ -79,14 +83,17 @@ def is_power2z(n): # True if zero or power of 2 return ((n & (n - 1)) == 0) + ASSERT_ON = True -### Default memory delay (must be included int he mem/lib.txt file" +# Default memory delay (must be included int he mem/lib.txt file" mem_delay = 0.2 mem_setup = 0.06 single_port = False ### Data structures ### + + class sram(): def __init__(self, name, words, width, area, ports): @@ -105,12 +112,11 @@ def print(self): token3 = format(token3, '>3') token4 = str(self.ports) token4 = format(token4, '>2') - print(" INFO: Found SRAM definition " + \ - token1 + token2 + token3 + "-bit words " + \ + print(" INFO: Found SRAM definition " + + token1 + token2 + token3 + "-bit words " + token4 + " read/write ports ") - class memory_operation(): def __init__(self, rn, rp, wn, wp): @@ -131,15 +137,14 @@ def __str__(self): return str(self.wn) + wp + ":" + str(self.rn) + rp - class memory(): def __init__(self, name, words, width, ops): self.name = name if words <= 0: - die_werr("Memory "+name+" has illegal number of words") + die_werr("Memory " + name + " has illegal number of words") if width <= 0: - die_werr("Memory "+name+" has illegal bit-width") + die_werr("Memory " + name + " has illegal bit-width") if len(ops) == 0: die_werr("No operation specified for memory \"" + name + "\"") self.words = words @@ -164,14 +169,14 @@ def __init__(self, name, words, width, ops): # Total area self.area = float('inf') # Port assignment array - self.read_ports = [ ] - self.write_ports = [ ] - + self.read_ports = [] + self.write_ports = [] def print(self): operations = " ".join(map(str, self.ops)) print(" INFO: Generating " + self.name + "...") - print(" " + str(self.words) + " words, " + str(self.width) + " bits, " + operations) + print(" " + str(self.words) + " words, " + + str(self.width) + " bits, " + operations) def __find_hbanks(self): for op in self.ops: @@ -183,15 +188,20 @@ def __find_hbanks(self): # Note that we force dual-port memories to get half the number of hbanks when possible # dual_port if single_port: - if self.need_parallel_rw or (op.wn == 2 and op.wp == "unknown"): - print("Requested memory " + self.name + " requires a dual-port SRAM bank, which is not available for the target technology") + if self.need_parallel_rw or ( + op.wn == 2 and op.wp == "unknown"): + print( + "Requested memory " + + self.name + + " requires a dual-port SRAM bank, which is not available for the target technology") sys.exit(0) self.need_dual_port = False else: - self.need_dual_port = (self.need_dual_port or - self.need_parallel_rw or - (op.wn == 2 and op.wp == "unknown") or - ((not self.need_parallel_rw) and (op.rn > 1 or op.wn > 1))) + self.need_dual_port = ( + self.need_dual_port or self.need_parallel_rw or ( + op.wn == 2 and op.wp == "unknown") or ( + (not self.need_parallel_rw) and ( + op.rn > 1 or op.wn > 1))) for op in self.ops: # Duplication @@ -206,7 +216,8 @@ def __find_hbanks(self): op_duplication_factor = max(op_duplication_factor, op.wn) else: op_duplication_factor = int(math.ceil(op.wn / 2)) - self.duplication_factor = max(self.duplication_factor, op_duplication_factor) + self.duplication_factor = max( + self.duplication_factor, op_duplication_factor) for op in self.ops: # Distribution @@ -221,7 +232,8 @@ def __find_hbanks(self): op_distribution_factor = max(op_distribution_factor, op.wn) else: op_distribution_factor = op.wn >> 1 - self.distribution_factor = max(self.distribution_factor, op_distribution_factor) + self.distribution_factor = max( + self.distribution_factor, op_distribution_factor) # Number of distributed banks and duplicated bank sets self.dbanks = self.duplication_factor @@ -254,8 +266,10 @@ def __write_check_access_task(self, fd): fd.write(" input integer p;\n") fd.write(" begin\n") fd.write(" if ((check_bank_access[d][h][v][hh][p] != -1) &&\n") - fd.write(" (check_bank_access[d][h][v][hh][p] != iface)) begin\n") - fd.write(" $display(\"ASSERTION FAILED in %m: port conflict on bank\", h, \"h\", v, \"v\", hh, \"hh\", \" for port\", p, \" involving interfaces\", check_bank_access[d][h][v][hh][p], iface);\n") + fd.write( + " (check_bank_access[d][h][v][hh][p] != iface)) begin\n") + fd.write( + " $display(\"ASSERTION FAILED in %m: port conflict on bank\", h, \"h\", v, \"v\", hh, \"hh\", \" for port\", p, \" involving interfaces\", check_bank_access[d][h][v][hh][p], iface);\n") fd.write(" $finish;\n") fd.write(" end\n") fd.write(" else begin\n") @@ -264,26 +278,59 @@ def __write_check_access_task(self, fd): fd.write(" end\n") fd.write(" endtask\n") - - - def __write_ctrl_assignment(self, fd, bank_addr_range_str, hh_range_str, last_hh_range_str, duplicated_bank_set, port, iface, is_write, parallelism): - ce_str = [ ] - a_str = [ ] - d_str = [ ] - we_str = [ ] - wem_str = [ ] + def __write_ctrl_assignment( + self, + fd, + bank_addr_range_str, + hh_range_str, + last_hh_range_str, + duplicated_bank_set, + port, + iface, + is_write, + parallelism): + ce_str = [] + a_str = [] + d_str = [] + we_str = [] + wem_str = [] for d in range(0, self.dbanks): - ce_str_i = [ ] - a_str_i = [ ] - d_str_i = [ ] - we_str_i = [ ] - wem_str_i = [ ] + ce_str_i = [] + a_str_i = [] + d_str_i = [] + we_str_i = [] + wem_str_i = [] for p in range(0, self.bank_type.ports): - ce_str_i.append (" bank_CE[" + str(d) + "][h][v][hh][" + str(p) + "] = CE") - a_str_i.append (" bank_A[" + str(d) + "][h][v][hh][" + str(p) + "] = A") - d_str_i.append (" bank_D[" + str(d) + "][h][v][hh][" + str(p) + "] = D") - we_str_i.append (" bank_WE[" + str(d) + "][h][v][hh][" + str(p) + "] = WE") - wem_str_i.append(" bank_WEM[" + str(d) + "][h][v][hh][" + str(p) + "] = WEM") + ce_str_i.append( + " bank_CE[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = CE") + a_str_i.append( + " bank_A[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = A") + d_str_i.append( + " bank_D[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = D") + we_str_i.append( + " bank_WE[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = WE") + wem_str_i.append( + " bank_WEM[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = WEM") ce_str.append(ce_str_i) a_str.append(a_str_i) d_str.append(d_str_i) @@ -299,26 +346,58 @@ def __write_ctrl_assignment(self, fd, bank_addr_range_str, hh_range_str, last_hh # normalized_iface = normalized_iface % self.hbanks # normalized_parallelism = min(parallelism, self.hbanks) # fd.write(" if (h % " + str(normalized_parallelism) + " == " + str(normalized_iface) + ") begin\n") - fd.write(" if (ctrlh[" + str(iface) + "] == h && ctrlv[" + str(iface) + "] == v && CE" + str(iface) + " == 1'b1) begin\n") + fd.write( + " if (ctrlh[" + + str(iface) + + "] == h && ctrlv[" + + str(iface) + + "] == v && CE" + + str(iface) + + " == 1'b1) begin\n") # Check that no port is accessed by more than one interface if (ASSERT_ON): fd.write("// synthesis translate_off\n") fd.write("// synopsys translate_off\n") - fd.write(" check_access(" + str(iface) + ", " + str(duplicated_bank_set) + ", h, v, hh, " + str(port) + ");\n") + fd.write( + " check_access(" + + str(iface) + + ", " + + str(duplicated_bank_set) + + ", h, v, hh, " + + str(port) + + ");\n") fd.write("// synopsys translate_on\n") fd.write("// synthesis translate_on\n") - fd.write(ce_str[duplicated_bank_set][port] + str(iface) + ";\n") - fd.write(a_str[duplicated_bank_set][port] + str(iface) + bank_addr_range_str + ";\n") + fd.write(ce_str[duplicated_bank_set][port] + str(iface) + ";\n") + fd.write( + a_str[duplicated_bank_set][port] + + str(iface) + + bank_addr_range_str + + ";\n") if is_write: - fd.write(" if (hh != " + str(self.hhbanks - 1) + ") begin\n") - fd.write(d_str[duplicated_bank_set][port] + str(iface) + hh_range_str + ";\n") - fd.write(wem_str[duplicated_bank_set][port] + str(iface) + hh_range_str + ";\n") + fd.write(" if (hh != " + + str(self.hhbanks - 1) + ") begin\n") + fd.write( + d_str[duplicated_bank_set][port] + + str(iface) + + hh_range_str + + ";\n") + fd.write( + wem_str[duplicated_bank_set][port] + + str(iface) + + hh_range_str + + ";\n") fd.write(" end\n") fd.write(" else begin\n") - fd.write(d_str[duplicated_bank_set][port] + str(iface) + last_hh_range_str + ";\n") - fd.write(wem_str[duplicated_bank_set][port] + str(iface) + last_hh_range_str + ";\n") + fd.write( + d_str[duplicated_bank_set][port] + + str(iface) + + last_hh_range_str + + ";\n") + fd.write(wem_str[duplicated_bank_set][port] + + str(iface) + last_hh_range_str + ";\n") fd.write(" end\n") - fd.write(we_str[duplicated_bank_set][port] + str(iface) + ";\n") + fd.write(we_str[duplicated_bank_set][port] + str(iface) + ";\n") fd.write(" end\n") # if parallelism != 0: # fd.write(" end\n") @@ -331,7 +410,8 @@ def write_verilog(self, out_path): fd.write("//\n") fd.write("// Created with the ESP Memory Generator\n") fd.write("//\n") - fd.write("// Copyright (c) 2011-2024 Columbia University, System Level Design Group\n") + fd.write( + "// Copyright (c) 2011-2024 Columbia University, System Level Design Group\n") fd.write("// SPDX-License-Identifier: Apache-2.0\n") fd.write("//\n") fd.write("// @author Paolo Mantovani \n") @@ -348,7 +428,10 @@ def write_verilog(self, out_path): fd.write(",\n D" + str(i)) fd.write(",\n WE" + str(i)) fd.write(",\n WEM" + str(i)) - for i in range(self.write_interfaces, self.write_interfaces + self.read_interfaces): + for i in range( + self.write_interfaces, + self.write_interfaces + + self.read_interfaces): fd.write(",\n CE" + str(i)) fd.write(",\n A" + str(i)) fd.write(",\n Q" + str(i)) @@ -356,89 +439,224 @@ def write_verilog(self, out_path): fd.write(" input CLK;\n") for i in range(0, self.write_interfaces): fd.write(" " + "input CE" + str(i) + ";\n") - fd.write(" " + "input " + "[" + str(int(math.ceil(math.log(self.words, 2)))-1) + ":0] A" + str(i) + ";\n") - fd.write(" " + "input " + "[" + str(self.width-1) + ":0] D" + str(i) + ";\n") + fd.write(" " + + "input " + + "[" + + str(int(math.ceil(math.log(self.words, 2))) - + 1) + + ":0] A" + + str(i) + + ";\n") + fd.write(" " + "input " + + "[" + str(self.width - 1) + ":0] D" + str(i) + ";\n") fd.write(" " + "input WE" + str(i) + ";\n") - fd.write(" " + "input " + "[" + str(self.width-1) + ":0] WEM" + str(i) + ";\n") - for i in range(self.write_interfaces, self.write_interfaces + self.read_interfaces): + fd.write(" " + "input " + + "[" + str(self.width - 1) + ":0] WEM" + str(i) + ";\n") + for i in range( + self.write_interfaces, + self.write_interfaces + + self.read_interfaces): fd.write(" " + "input CE" + str(i) + ";\n") - fd.write(" " + "input " + "[" + str(int(math.ceil(math.log(self.words, 2)))-1) + ":0] A" + str(i) + ";\n") - fd.write(" " + "output " + "[" + str(self.width-1) + ":0] Q" + str(i) + ";\n") + fd.write(" " + + "input " + + "[" + + str(int(math.ceil(math.log(self.words, 2))) - + 1) + + ":0] A" + + str(i) + + ";\n") + fd.write(" " + "output " + + "[" + str(self.width - 1) + ":0] Q" + str(i) + ";\n") fd.write(" genvar d, h, v, hh;\n") fd.write("\n") # Wire for banks - bank_wire_addr_width = int(math.ceil(math.log(self.bank_type.words, 2))) - bank_wire_data_width = self.bank_type.width - sel_dbank_reg_width = int(math.ceil(math.log(self.dbanks, 2))) - sel_hbank_reg_width = int(math.ceil(math.log(self.hbanks, 2))) - sel_vbank_reg_width = int(math.ceil(math.log(self.vbanks, 2))) - signle_wire_width_str = " " - bank_wire_dims_str = "[" + str(self.dbanks - 1) + ":0]" + "[" + str(self.hbanks - 1) + ":0]" + "[" + str(self.vbanks - 1) + ":0]" + "[" + str(self.hhbanks - 1) + ":0]" + "[" + str(self.bank_type.ports - 1) + ":0]" + bank_wire_addr_width = int( + math.ceil( + math.log( + self.bank_type.words, + 2))) + bank_wire_data_width = self.bank_type.width + sel_dbank_reg_width = int(math.ceil(math.log(self.dbanks, 2))) + sel_hbank_reg_width = int(math.ceil(math.log(self.hbanks, 2))) + sel_vbank_reg_width = int(math.ceil(math.log(self.vbanks, 2))) + signle_wire_width_str = " " + bank_wire_dims_str = "[" + str(self.dbanks - 1) + ":0]" + "[" + str(self.hbanks - 1) + ":0]" + "[" + str( + self.vbanks - 1) + ":0]" + "[" + str(self.hhbanks - 1) + ":0]" + "[" + str(self.bank_type.ports - 1) + ":0]" bank_wire_addr_width_str = "[" + str(bank_wire_addr_width - 1) + ":0]" bank_wire_addr_width_str = format(bank_wire_addr_width_str, ">12") bank_wire_data_width_str = "[" + str(bank_wire_data_width - 1) + ":0]" bank_wire_data_width_str = format(bank_wire_data_width_str, ">12") - ctrl_wire_dims_str = "[" + str(self.write_interfaces + self.read_interfaces - 1) + ":0]" - sel_reg_dims_str = "[" + str(self.write_interfaces + self.read_interfaces - 1) + ":" + str(self.write_interfaces) + "]" + ctrl_wire_dims_str = "[" + \ + str(self.write_interfaces + self.read_interfaces - 1) + ":0]" + sel_reg_dims_str = "[" + str(self.write_interfaces + + self.read_interfaces - 1) + ":" + str(self.write_interfaces) + "]" if self.dbanks > 1: - sel_dbank_reg_width_str = "[" + str(sel_dbank_reg_width - 1) + ":0]" + sel_dbank_reg_width_str = "[" + \ + str(sel_dbank_reg_width - 1) + ":0]" else: - sel_dbank_reg_width_str = "[0:0]" - sel_dbank_reg_width_str = format(sel_dbank_reg_width_str, ">12") + sel_dbank_reg_width_str = "[0:0]" + sel_dbank_reg_width_str = format(sel_dbank_reg_width_str, ">12") if self.hbanks > 1: - sel_hbank_reg_width_str = "[" + str(sel_hbank_reg_width - 1) + ":0]" + sel_hbank_reg_width_str = "[" + \ + str(sel_hbank_reg_width - 1) + ":0]" else: - sel_hbank_reg_width_str = "[0:0]" - sel_hbank_reg_width_str = format(sel_hbank_reg_width_str, ">12") + sel_hbank_reg_width_str = "[0:0]" + sel_hbank_reg_width_str = format(sel_hbank_reg_width_str, ">12") if self.vbanks > 1: - sel_vbank_reg_width_str = "[" + str(sel_vbank_reg_width - 1) + ":0]" + sel_vbank_reg_width_str = "[" + \ + str(sel_vbank_reg_width - 1) + ":0]" else: - sel_vbank_reg_width_str = "[0:0]" - sel_vbank_reg_width_str = format(sel_vbank_reg_width_str, ">12") - fd.write(" " + "reg " + signle_wire_width_str + " bank_CE " + bank_wire_dims_str + ";\n") - fd.write(" " + "reg " + bank_wire_addr_width_str + " bank_A " + bank_wire_dims_str + ";\n") - fd.write(" " + "reg " + bank_wire_data_width_str + " bank_D " + bank_wire_dims_str + ";\n") - fd.write(" " + "reg " + signle_wire_width_str + " bank_WE " + bank_wire_dims_str + ";\n") - fd.write(" " + "reg " + bank_wire_data_width_str + " bank_WEM " + bank_wire_dims_str + ";\n") - fd.write(" " + "wire " + bank_wire_data_width_str + " bank_Q " + bank_wire_dims_str + ";\n") - fd.write(" " + "wire " + sel_dbank_reg_width_str + " ctrld " + sel_reg_dims_str + ";\n") - fd.write(" " + "wire " + sel_hbank_reg_width_str + " ctrlh " + ctrl_wire_dims_str + ";\n") - fd.write(" " + "wire " + sel_vbank_reg_width_str + " ctrlv " + ctrl_wire_dims_str + ";\n") - fd.write(" " + "reg " + sel_dbank_reg_width_str + " seld " + sel_reg_dims_str + ";\n") - fd.write(" " + "reg " + sel_hbank_reg_width_str + " selh " + sel_reg_dims_str + ";\n") - fd.write(" " + "reg " + sel_vbank_reg_width_str + " selv " + sel_reg_dims_str + ";\n") + sel_vbank_reg_width_str = "[0:0]" + sel_vbank_reg_width_str = format(sel_vbank_reg_width_str, ">12") + fd.write( + " " + + "reg " + + signle_wire_width_str + + " bank_CE " + + bank_wire_dims_str + + ";\n") + fd.write( + " " + + "reg " + + bank_wire_addr_width_str + + " bank_A " + + bank_wire_dims_str + + ";\n") + fd.write( + " " + + "reg " + + bank_wire_data_width_str + + " bank_D " + + bank_wire_dims_str + + ";\n") + fd.write( + " " + + "reg " + + signle_wire_width_str + + " bank_WE " + + bank_wire_dims_str + + ";\n") + fd.write( + " " + + "reg " + + bank_wire_data_width_str + + " bank_WEM " + + bank_wire_dims_str + + ";\n") + fd.write( + " " + + "wire " + + bank_wire_data_width_str + + " bank_Q " + + bank_wire_dims_str + + ";\n") + fd.write( + " " + + "wire " + + sel_dbank_reg_width_str + + " ctrld " + + sel_reg_dims_str + + ";\n") + fd.write( + " " + + "wire " + + sel_hbank_reg_width_str + + " ctrlh " + + ctrl_wire_dims_str + + ";\n") + fd.write( + " " + + "wire " + + sel_vbank_reg_width_str + + " ctrlv " + + ctrl_wire_dims_str + + ";\n") + fd.write( + " " + + "reg " + + sel_dbank_reg_width_str + + " seld " + + sel_reg_dims_str + + ";\n") + fd.write( + " " + + "reg " + + sel_hbank_reg_width_str + + " selh " + + sel_reg_dims_str + + ";\n") + fd.write( + " " + + "reg " + + sel_vbank_reg_width_str + + " selv " + + sel_reg_dims_str + + ";\n") if (ASSERT_ON): fd.write("// synthesis translate_off\n") fd.write("// synopsys translate_off\n") - fd.write(" " + "integer check_bank_access " + bank_wire_dims_str + ";\n") + fd.write( + " " + + "integer check_bank_access " + + bank_wire_dims_str + + ";\n") self.__write_check_access_task(fd) fd.write("// synopsys translate_on\n") fd.write("// synthesis translate_on\n") fd.write("\n") # Control selection - for ri in range(self.write_interfaces, self.write_interfaces + self.read_interfaces): - # For ru type of operations we guarantee to insist on different copies of the memory structure + for ri in range( + self.write_interfaces, + self.write_interfaces + + self.read_interfaces): + # For ru type of operations we guarantee to insist on different + # copies of the memory structure if self.dbanks > 1: - fd.write(" assign ctrld[" + str(ri) + "] = " + str(ri % self.dbanks) + ";\n") + fd.write(" assign ctrld[" + str(ri) + + "] = " + str(ri % self.dbanks) + ";\n") else: fd.write(" assign ctrld[" + str(ri) + "] = 0;\n") for ri in range(0, self.write_interfaces + self.read_interfaces): if self.hbanks > 1: - fd.write(" assign ctrlh[" + str(ri) + "] = A" + str(ri) + "[" + str(sel_hbank_reg_width - 1) + ":" + "0" + "];\n") + fd.write(" assign ctrlh[" + + str(ri) + + "] = A" + + str(ri) + + "[" + + str(sel_hbank_reg_width - + 1) + + ":" + + "0" + + "];\n") else: fd.write(" assign ctrlh[" + str(ri) + "] = 0;\n") for ri in range(0, self.write_interfaces + self.read_interfaces): if self.vbanks > 1: - fd.write(" assign ctrlv[" + str(ri) + "] = A" + str(ri) + "[" + str(bank_wire_addr_width + sel_hbank_reg_width + sel_vbank_reg_width - 1) + ":" +str(bank_wire_addr_width + sel_hbank_reg_width) + "];\n") + fd.write(" assign ctrlv[" + + str(ri) + + "] = A" + + str(ri) + + "[" + + str(bank_wire_addr_width + + sel_hbank_reg_width + + sel_vbank_reg_width - + 1) + + ":" + + str(bank_wire_addr_width + + sel_hbank_reg_width) + + "];\n") else: fd.write(" assign ctrlv[" + str(ri) + "] = 0;\n") fd.write("\n") # Output bank selection fd.write(" always @(posedge CLK) begin\n") - for ri in range(self.write_interfaces, self.write_interfaces + self.read_interfaces): + for ri in range( + self.write_interfaces, + self.write_interfaces + + self.read_interfaces): fd.write(" seld[" + str(ri) + "] <= ctrld[" + str(ri) + "];\n") fd.write(" selh[" + str(ri) + "] <= ctrlh[" + str(ri) + "];\n") fd.write(" selv[" + str(ri) + "] <= ctrlv[" + str(ri) + "];\n") @@ -449,16 +667,22 @@ def write_verilog(self, out_path): hh_msb_str = str(bank_wire_data_width) + " * (hh + 1) - 1" hh_lsb_str = str(bank_wire_data_width) + " * hh" hh_range_str = "[" + hh_msb_str + ":" + hh_lsb_str + "]" - last_hh_msb_str = str((self.width - 1) % bank_wire_data_width) + " + " + hh_lsb_str + last_hh_msb_str = str((self.width - 1) % + bank_wire_data_width) + " + " + hh_lsb_str last_hh_lsb_str = hh_lsb_str last_hh_range_str = "[" + last_hh_msb_str + ":" + last_hh_lsb_str + "]" - bank_addr_msb_str = str(min(int(math.ceil(math.log(self.words, 2))) - 1, bank_wire_addr_width + sel_hbank_reg_width - 1)) + bank_addr_msb_str = str(min(int(math.ceil( + math.log(self.words, 2))) - 1, bank_wire_addr_width + sel_hbank_reg_width - 1)) bank_addr_lsb_str = str(sel_hbank_reg_width) - bank_addr_range_str = "[" + bank_addr_msb_str + ":" + bank_addr_lsb_str + "]" + bank_addr_range_str = "[" + bank_addr_msb_str + \ + ":" + bank_addr_lsb_str + "]" fd.write(" generate\n") - fd.write(" for (h = 0; h < " + str(self.hbanks) + "; h = h + 1) begin : gen_ctrl_hbanks\n") - fd.write(" for (v = 0; v < " + str(self.vbanks) + "; v = v + 1) begin : gen_ctrl_vbanks\n") - fd.write(" for (hh = 0; hh < " + str(self.hhbanks) + "; hh = hh + 1) begin : gen_ctrl_hhbanks\n") + fd.write(" for (h = 0; h < " + str(self.hbanks) + + "; h = h + 1) begin : gen_ctrl_hbanks\n") + fd.write(" for (v = 0; v < " + str(self.vbanks) + + "; v = v + 1) begin : gen_ctrl_vbanks\n") + fd.write(" for (hh = 0; hh < " + str(self.hhbanks) + + "; hh = hh + 1) begin : gen_ctrl_hhbanks\n") fd.write("\n") fd.write(" always @(*) begin : handle_ops\n") fd.write("\n") @@ -476,15 +700,45 @@ def write_verilog(self, out_path): # Initialize variable for conflicts check fd.write("// synthesis translate_off\n") fd.write("// synopsys translate_off\n") - fd.write(" check_bank_access[" + str(d) + "][h][v][hh][" + str(p) + "] = -1;\n") + fd.write( + " check_bank_access[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = -1;\n") fd.write("// synopsys translate_on\n") fd.write("// synthesis translate_on\n") # Dfault assignment - fd.write(" bank_CE[" + str(d) + "][h][v][hh][" + str(p) + "] = 0;\n") - fd.write(" bank_A[" + str(d) + "][h][v][hh][" + str(p) + "] = 0;\n") - fd.write(" bank_D[" + str(d) + "][h][v][hh][" + str(p) + "] = 0;\n") - fd.write(" bank_WE[" + str(d) + "][h][v][hh][" + str(p) + "] = 0;\n") - fd.write(" bank_WEM[" + str(d) + "][h][v][hh][" + str(p) + "] = 0;\n") + fd.write( + " bank_CE[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = 0;\n") + fd.write( + " bank_A[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = 0;\n") + fd.write( + " bank_D[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = 0;\n") + fd.write( + " bank_WE[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = 0;\n") + fd.write( + " bank_WEM[" + + str(d) + + "][h][v][hh][" + + str(p) + + "] = 0;\n") fd.write("\n") # Go through parallel accesses # In some cases we're building a full cross-bar, however most links will be trimmed away by @@ -495,61 +749,142 @@ def write_verilog(self, out_path): # Handle 2wu:0r if op.wp == "unknown" and op.wn == 2: for d in range(0, self.dbanks): - fd.write(" // Duplicated bank set " + str(d) + "\n") + fd.write( + " // Duplicated bank set " + str(d) + "\n") for wi in range(0, op.wn): p = self.write_ports[wi] - self.__write_ctrl_assignment(fd, bank_addr_range_str, hh_range_str, last_hh_range_str, d, p, wi, True, 0) + self.__write_ctrl_assignment( + fd, bank_addr_range_str, hh_range_str, last_hh_range_str, d, p, wi, True, 0) # Handle w:0r with N power of 2 if op.rn == 0 and op.wp == "modulo": # Write to all duplicated sets for d in range(0, self.dbanks): - fd.write(" // Duplicated bank set " + str(d) + "\n") + fd.write( + " // Duplicated bank set " + str(d) + "\n") for wi in range(0, op.wn): p = self.write_ports[wi] - self.__write_ctrl_assignment(fd, bank_addr_range_str, hh_range_str, last_hh_range_str, d, p, wi, True, op.wn) + self.__write_ctrl_assignment( + fd, + bank_addr_range_str, + hh_range_str, + last_hh_range_str, + d, + p, + wi, + True, + op.wn) # Handle 0w:r with N power of 2 if op.wn == 0 and op.rp == "modulo": - # All duplicated sets would return the same data. 0 is correct even with no duplication + # All duplicated sets would return the same data. 0 is correct + # even with no duplication d = 0 - fd.write(" // Always choose duplicated bank set " + str(d) + "\n") + fd.write( + " // Always choose duplicated bank set " + + str(d) + + "\n") for ri in range(0, op.rn): p = self.read_ports[ri] - self.__write_ctrl_assignment(fd, bank_addr_range_str, hh_range_str, last_hh_range_str, d, p, ri + self.write_interfaces, False, op.rn) - - # Handle w:r with N and M power of 2. In this case hbanks matches max(op.rn, op.wn) foreach op in the list of operations + self.__write_ctrl_assignment( + fd, + bank_addr_range_str, + hh_range_str, + last_hh_range_str, + d, + p, + ri + + self.write_interfaces, + False, + op.rn) + + # Handle w:r with N and M power of 2. In this case hbanks + # matches max(op.rn, op.wn) foreach op in the list of operations if op.wn > 0 and op.rn > 0 and op.wp == "modulo" and op.rp == "modulo": # Write to all duplicated sets for d in range(0, self.dbanks): - fd.write(" // Duplicated bank set " + str(d) + "\n") + fd.write( + " // Duplicated bank set " + str(d) + "\n") for wi in range(0, op.wn): p = self.write_ports[wi] - self.__write_ctrl_assignment(fd, bank_addr_range_str, hh_range_str, last_hh_range_str, d, p, wi, True, op.wn) - # All duplicated sets would return the same data. 0 is correct even with no duplication + self.__write_ctrl_assignment( + fd, + bank_addr_range_str, + hh_range_str, + last_hh_range_str, + d, + p, + wi, + True, + op.wn) + # All duplicated sets would return the same data. 0 is correct + # even with no duplication d = 0 - fd.write(" // Always choose duplicated bank set " + str(d) + "\n") + fd.write( + " // Always choose duplicated bank set " + + str(d) + + "\n") for ri in range(0, op.rn): p = self.read_ports[ri] - self.__write_ctrl_assignment(fd, bank_addr_range_str, hh_range_str, last_hh_range_str, d, p, ri + self.write_interfaces, False, op.rn) + self.__write_ctrl_assignment( + fd, + bank_addr_range_str, + hh_range_str, + last_hh_range_str, + d, + p, + ri + + self.write_interfaces, + False, + op.rn) # Handle ru:0w with N > 1 if op.rn > 1 and op.wn == 0 and op.rp == "unknown": # Duplicated set matches the read interface number for ri in range(0, op.rn): p = self.read_ports[ri] d = (ri + self.write_interfaces) % self.dbanks - self.__write_ctrl_assignment(fd, bank_addr_range_str, hh_range_str, last_hh_range_str, d, p, ri + self.write_interfaces, False, 0) + self.__write_ctrl_assignment( + fd, + bank_addr_range_str, + hh_range_str, + last_hh_range_str, + d, + p, + ri + + self.write_interfaces, + False, + 0) # Handle ru:w with N > 1 and M power of 2 if op.rn > 1 and op.wn > 0 and op.rp == "unknown" and op.wp == "modulo": # Write to all duplicated sets for d in range(0, self.dbanks): - fd.write(" // Duplicated bank set " + str(d) + "\n") + fd.write( + " // Duplicated bank set " + str(d) + "\n") for wi in range(0, op.wn): p = self.write_ports[wi] - self.__write_ctrl_assignment(fd, bank_addr_range_str, hh_range_str, last_hh_range_str, d, p, wi, True, op.wn) + self.__write_ctrl_assignment( + fd, + bank_addr_range_str, + hh_range_str, + last_hh_range_str, + d, + p, + wi, + True, + op.wn) # Duplicated set matches the read interface number for ri in range(0, op.rn): p = self.read_ports[ri] d = (ri + self.write_interfaces) % self.dbanks - self.__write_ctrl_assignment(fd, bank_addr_range_str, hh_range_str, last_hh_range_str, d, p, ri + self.write_interfaces, False, 0) + self.__write_ctrl_assignment( + fd, + bank_addr_range_str, + hh_range_str, + last_hh_range_str, + d, + p, + ri + + self.write_interfaces, + False, + 0) fd.write("\n") fd.write(" end\n") fd.write("\n") @@ -563,16 +898,70 @@ def write_verilog(self, out_path): # When parallel rw is required, port 0 is used for write and port 1 is used for read # Otherwise, modulo is applied to choose which port should be used. fd.write(" generate\n") - fd.write(" for (hh = 0; hh < " + str(self.hhbanks) + "; hh = hh + 1) begin : gen_q_assign_hhbanks\n") - q_last_hh_msb_str = str(int(min(self.width - 1, self.hhbanks * self.bank_type.width - 1))) + fd.write(" for (hh = 0; hh < " + str(self.hhbanks) + + "; hh = hh + 1) begin : gen_q_assign_hhbanks\n") + q_last_hh_msb_str = str( + int(min(self.width - 1, self.hhbanks * self.bank_type.width - 1))) q_last_hh_range_str = "[" + q_last_hh_msb_str + ":" + hh_lsb_str + "]" - for ri in range(self.write_interfaces, self.write_interfaces + self.read_interfaces): + for ri in range( + self.write_interfaces, + self.write_interfaces + + self.read_interfaces): p = self.read_ports[ri - self.write_interfaces] - fd.write(" if (hh == " + str(self.hhbanks - 1) + " && (hh + 1) * " + str(self.bank_type.width) + " > " + str(self.width) + ") begin : gen_q_assign_hhbanks_last_" + str(ri) + " \n ") - fd.write(" assign Q" + str(ri) + q_last_hh_range_str + " = bank_Q" + "[seld[" + str(ri) +"]]" + "[selh[" + str(ri) +"]]" + "[selv[" + str(ri) +"]]" + "[hh]" + "[" + str(p) + "][" + str((self.width - 1) % self.bank_type.width) + ":0];\n") - fd.write(" end else begin : gen_q_assign_hhbanks_others_" + str(ri) + " \n") - fd.write(" assign Q" + str(ri) + hh_range_str + " = bank_Q" + "[seld[" + str(ri) +"]]" + "[selh[" + str(ri) +"]]" + "[selv[" + str(ri) +"]]" + "[hh]" + "[" + str(p) + "];\n") + fd.write(" if (hh == " + + str(self.hhbanks - + 1) + + " && (hh + 1) * " + + str(self.bank_type.width) + + " > " + + str(self.width) + + ") begin : gen_q_assign_hhbanks_last_" + + str(ri) + + " \n ") + fd.write(" assign Q" + + str(ri) + + q_last_hh_range_str + + " = bank_Q" + + "[seld[" + + str(ri) + + "]]" + + "[selh[" + + str(ri) + + "]]" + + "[selv[" + + str(ri) + + "]]" + + "[hh]" + + "[" + + str(p) + + "][" + + str((self.width - + 1) % + self.bank_type.width) + + ":0];\n") + fd.write( + " end else begin : gen_q_assign_hhbanks_others_" + + str(ri) + + " \n") + fd.write( + " assign Q" + + str(ri) + + hh_range_str + + " = bank_Q" + + "[seld[" + + str(ri) + + "]]" + + "[selh[" + + str(ri) + + "]]" + + "[selv[" + + str(ri) + + "]]" + + "[hh]" + + "[" + + str(p) + + "];\n") fd.write(" end\n") fd.write(" end\n") fd.write(" endgenerate\n") @@ -580,20 +969,30 @@ def write_verilog(self, out_path): # Bank instances fd.write(" generate\n") - fd.write(" for (d = 0; d < " + str(self.dbanks) + "; d = d + 1) begin : gen_wires_dbanks\n") - fd.write(" for (h = 0; h < " + str(self.hbanks) + "; h = h + 1) begin : gen_wires_hbanks\n") - fd.write(" for (v = 0; v < " + str(self.vbanks) + "; v = v + 1) begin : gen_wires_vbanks\n") - fd.write(" for (hh = 0; hh < " + str(self.hhbanks) + "; hh = hh + 1) begin : gen_wires_hhbanks\n") + fd.write(" for (d = 0; d < " + str(self.dbanks) + + "; d = d + 1) begin : gen_wires_dbanks\n") + fd.write(" for (h = 0; h < " + str(self.hbanks) + + "; h = h + 1) begin : gen_wires_hbanks\n") + fd.write(" for (v = 0; v < " + str(self.vbanks) + + "; v = v + 1) begin : gen_wires_vbanks\n") + fd.write(" for (hh = 0; hh < " + str(self.hhbanks) + + "; hh = hh + 1) begin : gen_wires_hhbanks\n") fd.write("\n") fd.write(" " + self.bank_type.name + " bank_i(\n") fd.write(" .CLK(CLK)") for p in range(0, self.bank_type.ports): - fd.write(",\n .CE" + str(p) + "(bank_CE[d][h][v][hh][" + str(p) + "])") - fd.write(",\n .A" + str(p) + "(bank_A[d][h][v][hh][" + str(p) + "])") - fd.write(",\n .D" + str(p) + "(bank_D[d][h][v][hh][" + str(p) + "])") - fd.write(",\n .WE" + str(p) + "(bank_WE[d][h][v][hh][" + str(p) + "])") - fd.write(",\n .WEM" + str(p) + "(bank_WEM[d][h][v][hh][" + str(p) + "])") - fd.write(",\n .Q" + str(p) + "(bank_Q[d][h][v][hh][" + str(p) + "])") + fd.write(",\n .CE" + str(p) + + "(bank_CE[d][h][v][hh][" + str(p) + "])") + fd.write(",\n .A" + str(p) + + "(bank_A[d][h][v][hh][" + str(p) + "])") + fd.write(",\n .D" + str(p) + + "(bank_D[d][h][v][hh][" + str(p) + "])") + fd.write(",\n .WE" + str(p) + + "(bank_WE[d][h][v][hh][" + str(p) + "])") + fd.write(",\n .WEM" + str(p) + + "(bank_WEM[d][h][v][hh][" + str(p) + "])") + fd.write(",\n .Q" + str(p) + + "(bank_Q[d][h][v][hh][" + str(p) + "])") fd.write("\n );\n") fd.write("\n") if (ASSERT_ON and (self.bank_type.ports > 1)): @@ -602,10 +1001,32 @@ def write_verilog(self, out_path): fd.write(" always @(posedge CLK) begin\n") for p0 in range(0, self.bank_type.ports): for p1 in range(p0 + 1, self.bank_type.ports): - fd.write(" if " + "((bank_CE[d][h][v][hh][" + str(p0) + "] & " + "bank_CE[d][h][v][hh][" + str(p1) + "]) &&\n") - fd.write(" " + " (bank_WE[d][h][v][hh][" + str(p0) + "] | " + "bank_WE[d][h][v][hh][" + str(p1) + "]) &&\n") - fd.write(" " + " (bank_A[d][h][v][hh][" + str(p0) + "] == " + "bank_A[d][h][v][hh][" + str(p1) + "])) begin\n") - fd.write(" $display(\"ASSERTION FAILED in %m: address conflict on bank\", h, \"h\", v, \"v\", hh, \"hh\");\n") + fd.write( + " if " + + "((bank_CE[d][h][v][hh][" + + str(p0) + + "] & " + + "bank_CE[d][h][v][hh][" + + str(p1) + + "]) &&\n") + fd.write( + " " + + " (bank_WE[d][h][v][hh][" + + str(p0) + + "] | " + + "bank_WE[d][h][v][hh][" + + str(p1) + + "]) &&\n") + fd.write( + " " + + " (bank_A[d][h][v][hh][" + + str(p0) + + "] == " + + "bank_A[d][h][v][hh][" + + str(p1) + + "])) begin\n") + fd.write( + " $display(\"ASSERTION FAILED in %m: address conflict on bank\", h, \"h\", v, \"v\", hh, \"hh\");\n") fd.write(" $finish;\n") fd.write(" end\n") fd.write(" end\n") @@ -633,7 +1054,8 @@ def __set_rwports(self): self.write_ports.append(wi) else: if self.hbanks != 1: - self.write_ports.append((int(wi / self.hbanks) + (wi % self.bank_type.ports)) % self.bank_type.ports) + self.write_ports.append( + (int(wi / self.hbanks) + (wi % self.bank_type.ports)) % self.bank_type.ports) else: self.write_ports.append(wi % self.bank_type.ports) for ri in range(0, self.read_interfaces): @@ -647,12 +1069,11 @@ def __set_rwports(self): self.read_ports.append(ri) else: if self.hbanks != 1: - self.read_ports.append((int(ri / self.hbanks) + (ri % self.bank_type.ports)) % self.bank_type.ports) + self.read_ports.append( + (int(ri / self.hbanks) + (ri % self.bank_type.ports)) % self.bank_type.ports) else: self.read_ports.append(ri % self.bank_type.ports) - - def gen(self, lib): # Determine memory requirements (first pass over ops list) self.__find_hbanks() @@ -661,7 +1082,9 @@ def gen(self, lib): print(" " + "read_interfaces " + str(self.read_interfaces)) print(" " + "write_interfaces " + str(self.write_interfaces)) print(" " + "duplication_factor " + str(self.duplication_factor)) - print(" " + "distribution_factor " + str(self.distribution_factor)) + print(" " + + "distribution_factor " + + str(self.distribution_factor)) print(" " + "need_dual_port " + str(self.need_dual_port)) print(" " + "need_parallel_rw " + str(self.need_parallel_rw)) print(" " + "d-banks " + str(self.dbanks)) @@ -669,11 +1092,14 @@ def gen(self, lib): print(" " + "v-banks " + str(self.vbanks)) print(" " + "hh-banks " + str(self.hhbanks)) print(" " + "bank type " + str(self.bank_type.name)) - print(" " + "Write interfaces are assigned to ports " + str(self.write_ports)) - print(" " + "Read interfaces are assigned to ports " + str(self.read_ports)) + print(" " + + "Write interfaces are assigned to ports " + + str(self.write_ports)) + print(" " + + "Read interfaces are assigned to ports " + + str(self.read_ports)) print(" " + "Total area " + str(self.area)) - def write_tb(self, tb_path): try: fd = open(tb_path + "/" + self.name + "_tb.v", 'w') @@ -682,7 +1108,8 @@ def write_tb(self, tb_path): fd.write("//\n") fd.write("// Created with the ESP Memory Generator\n") fd.write("//\n") - fd.write("// Copyright (c) 2011-2024 Columbia University, System Level Design Group\n") + fd.write( + "// Copyright (c) 2011-2024 Columbia University, System Level Design Group\n") fd.write("// SPDX-License-Identifier: Apache-2.0\n") fd.write("//\n") fd.write("// @author Paolo Mantovani \n") @@ -695,14 +1122,34 @@ def write_tb(self, tb_path): fd.write(" reg CLK;\n") for i in range(0, self.write_interfaces): fd.write(" " + "reg CE" + str(i) + ";\n") - fd.write(" " + "reg " + "[" + str(int(math.ceil(math.log(self.words, 2)))-1) + ":0] A" + str(i) + ";\n") - fd.write(" " + "reg " + "[" + str(self.width-1) + ":0] D" + str(i) + ";\n") + fd.write(" " + + "reg " + + "[" + + str(int(math.ceil(math.log(self.words, 2))) - + 1) + + ":0] A" + + str(i) + + ";\n") + fd.write(" " + "reg " + + "[" + str(self.width - 1) + ":0] D" + str(i) + ";\n") fd.write(" " + "reg WE" + str(i) + ";\n") - fd.write(" " + "reg " + "[" + str(self.width-1) + ":0] WEM" + str(i) + ";\n") - for i in range(self.write_interfaces, self.write_interfaces + self.read_interfaces): + fd.write(" " + "reg " + + "[" + str(self.width - 1) + ":0] WEM" + str(i) + ";\n") + for i in range( + self.write_interfaces, + self.write_interfaces + + self.read_interfaces): fd.write(" " + "reg CE" + str(i) + ";\n") - fd.write(" " + "reg " + "[" + str(int(math.ceil(math.log(self.words, 2)))-1) + ":0] A" + str(i) + ";\n") - fd.write(" " + "wire " + "[" + str(self.width-1) + ":0] Q" + str(i) + ";\n") + fd.write(" " + + "reg " + + "[" + + str(int(math.ceil(math.log(self.words, 2))) - + 1) + + ":0] A" + + str(i) + + ";\n") + fd.write(" " + "wire " + + "[" + str(self.width - 1) + ":0] Q" + str(i) + ";\n") fd.write("\n") fd.write(" initial begin\n") fd.write(" CLK = 0;\n") @@ -718,11 +1165,14 @@ def write_tb(self, tb_path): fd.write(" D" + str(iface) + " = 0;\n") fd.write(" WE" + str(iface) + " = 0;\n") fd.write(" WEM" + str(iface) + " = 0;\n") - for iface in range(self.write_interfaces, self.write_interfaces + self.read_interfaces): + for iface in range( + self.write_interfaces, + self.write_interfaces + + self.read_interfaces): fd.write(" CE" + str(iface) + " = 0;\n") fd.write(" A" + str(iface) + " = 0;\n") # Go through operations and merge them for testing purposes - tb_ops = [ ] + tb_ops = [] wmax = 0 wumax = 0 rmax = 0 @@ -739,7 +1189,8 @@ def write_tb(self, tb_path): # Do 2wu:0r first, if required if wumax != 0: tb_ops.append(memory_operation(0, "modulo", wumax, "unknown")) - # Check what's written with any read-only op (even if not in the original list of ops) + # Check what's written with any read-only op (even if not in the + # original list of ops) if rumax != 0: tb_ops.append(memory_operation(rumax, "unknown", 0, "modulo")) else: @@ -758,26 +1209,36 @@ def write_tb(self, tb_path): elif rumax != 0: tb_ops.append(memory_operation(rumax, "unknown", 0, "modulo")) tb_operations = " ".join(map(str, tb_ops)) - print(" INFO: Generating testbench for " + self.name + " with merged operations " + tb_operations) + print( + " INFO: Generating testbench for " + + self.name + + " with merged operations " + + tb_operations) # Write testbench for op in tb_ops: fd.write(" $display(\"\");\n") - fd.write(" #500000 $display(\"* Testing parallel access " + str(op) + " *\");\n") + fd.write( + " #500000 $display(\"* Testing parallel access " + + str(op) + + " *\");\n") # Reset memory content if op.wn != 0: fd.write(" $display(\"\");\n") - fd.write(" $display(\"--- Set all memory cells to 0 for writing test ---\");\n") + fd.write( + " $display(\"--- Set all memory cells to 0 for writing test ---\");\n") fd.write(" $display(\"\");\n") for addr in range(0, self.words): wi = addr % op.wn - fd.write(" @ (posedge CLK) $display(\"Reset addr " + str(addr) + "\");\n") + fd.write( + " @ (posedge CLK) $display(\"Reset addr " + str(addr) + "\");\n") fd.write(" CE" + str(wi) + " = 1'b1;\n") fd.write(" A" + str(wi) + " = " + str(addr) + ";\n") data = 0 data_str = str(data) fd.write(" D" + str(wi) + " = " + data_str + ";\n") fd.write(" WE" + str(wi) + " = 1'b1;\n") - fd.write(" WEM" + str(wi) + " = {" + str(self.width) + "{1'b1}};\n") + fd.write(" WEM" + str(wi) + + " = {" + str(self.width) + "{1'b1}};\n") # Disable write interfaces before testing fd.write(" @ (posedge CLK) CE" + str(wi) + " = 1'b0;\n") # By default we assume modulo access pattern @@ -787,17 +1248,21 @@ def write_tb(self, tb_path): ri_start = self.write_interfaces ri_end = self.write_interfaces + op.rn ri_step = 1 - # Reversing the interface order makes them access different banks than the ones assigned for pattern modulo + # Reversing the interface order makes them access different banks + # than the ones assigned for pattern modulo if op.wp == "unknown": wi_start = op.wn - 1 wi_end = -1 wi_step = -1 if op.rp == "unknown": ri_start = self.write_interfaces + op.rn - 1 - ri_end = self.write_interfaces - 1 + ri_end = self.write_interfaces - 1 ri_step = -1 fd.write(" $display(\"\");\n") - fd.write(" $display(\"--- Begin test for " + str(op) + " ---\");\n") + fd.write( + " $display(\"--- Begin test for " + + str(op) + + " ---\");\n") fd.write(" $display(\"\");\n") waddr = 0 raddr = 0 @@ -807,77 +1272,119 @@ def write_tb(self, tb_path): ccycle = 1 format_str = "0" + str(int(math.ceil(self.width / 4))) + "x" while True: - fd.write(" @ (posedge CLK) $display(\"Current waddr and raddr are " + str(waddr) + ", " + str(raddr) + "\");\n") + fd.write( + " @ (posedge CLK) $display(\"Current waddr and raddr are " + + str(waddr) + + ", " + + str(raddr) + + "\");\n") if waddr >= self.words: if op.wn != 0: for wi in range(0, self.write_interfaces): fd.write(" CE" + str(wi) + " = 1'b0;\n") if op.rn == 0: fd.write(" $display(\"\");\n") - fd.write(" $display(\"--- End of Test " + str(op) + " PASSED ---\");\n") + fd.write( + " $display(\"--- End of Test " + str(op) + " PASSED ---\");\n") fd.write(" $display(\"\");\n") break if raddr >= self.words: if op.rn != 0: - for ri in range(self.write_interfaces, self.write_interfaces + self.read_interfaces): + for ri in range( + self.write_interfaces, + self.write_interfaces + + self.read_interfaces): fd.write(" CE" + str(ri) + " = 1'b0;\n") for wi in range(wi_start, wi_end, wi_step): if waddr < self.words: if op.wn != 0: fd.write(" CE" + str(wi) + " = 1'b1;\n") - fd.write(" A" + str(wi) + " = " + str(waddr) + ";\n") - addr_width = int(math.ceil(math.log(self.words, 2))) + fd.write( + " A" + str(wi) + " = " + str(waddr) + ";\n") + addr_width = int( + math.ceil(math.log(self.words, 2))) data = waddr - if ( addr_width > self.width): - data = waddr % (int(math.pow(2, self.width)) - 1) + if (addr_width > self.width): + data = waddr % ( + int(math.pow(2, self.width)) - 1) if waddr % 2 != 0: - data = (data << (self.width - int(math.log(max(data, 1), 2)) - 1)) | data - data_str = str(self.width) + "'h" + format(data, format_str) - fd.write(" D" + str(wi) + " = " + data_str + ";\n") + data = ( + data << (self.width - int(math.log(max(data, 1), 2)) - 1)) | data + data_str = str(self.width) + "'h" + \ + format(data, format_str) + fd.write( + " D" + str(wi) + " = " + data_str + ";\n") fd.write(" WE" + str(wi) + " = 1'b1;\n") - fd.write(" WEM" + str(wi) + " = {" + str(self.width) + "{1'b1}};\n") + fd.write(" WEM" + str(wi) + + " = {" + str(self.width) + "{1'b1}};\n") waddr = waddr + 1 else: if op.wn != 0: fd.write(" CE" + str(wi) + " = 1'b0;\n") wcycle = wcycle + 1 if op.wn != 0: - if waddr < (min(raddr + op.rn - 1, self.words - 1)) or (wcycle - 1) / rcycle <= math.ceil(op.rn / op.wn): + if waddr < (min(raddr + op.rn - 1, self.words - 1) + ) or (wcycle - 1) / rcycle <= math.ceil(op.rn / op.wn): continue for ri in range(ri_start, ri_end, ri_step): if raddr < self.words: if op.rn != 0: fd.write(" CE" + str(ri) + " = 1'b1;\n") - fd.write(" A" + str(ri) + " = " + str(raddr) + ";\n") + fd.write( + " A" + str(ri) + " = " + str(raddr) + ";\n") raddr = raddr + 1 else: if op.rn != 0: fd.write(" CE" + str(ri) + " = 1'b0;\n") rcycle = rcycle + 1 - if raddr < (min(caddr + op.rn - 1, self.words - 1)) or rcycle - ccycle <= 1: + if raddr < (min(caddr + op.rn - 1, self.words - 1) + ) or rcycle - ccycle <= 1: continue for ri in range(ri_start, ri_end, ri_step): if caddr < self.words: if op.rn != 0: data = caddr - if ( addr_width > self.width): - data = caddr % (int(math.pow(2, self.width)) - 1) + if (addr_width > self.width): + data = caddr % ( + int(math.pow(2, self.width)) - 1) if caddr % 2 != 0: - data = (data << (self.width - int(math.log(max(data, 1), 2)) - 1)) | data - data_str = str(self.width) + "'h" + format(data, format_str) + data = ( + data << (self.width - int(math.log(max(data, 1), 2)) - 1)) | data + data_str = str(self.width) + "'h" + \ + format(data, format_str) fd.write(" #200 ;\n") - fd.write(" if (Q" + str(ri) + " != " + str(data_str) + ") begin\n") - fd.write(" $display(\"Memory failure on interface " + str(ri) + " at address " + str(caddr) + ": reading %h, but expecting %h\", Q" + str(ri) + ", " + data_str + ");\n") + fd.write( + " if (Q" + str(ri) + " != " + str(data_str) + ") begin\n") + fd.write( + " $display(\"Memory failure on interface " + + str(ri) + + " at address " + + str(caddr) + + ": reading %h, but expecting %h\", Q" + + str(ri) + + ", " + + data_str + + ");\n") fd.write(" $finish;\n") fd.write(" end\n") fd.write(" else begin\n") - fd.write(" $display(\"Memory read on interface " + str(ri) + " at address " + str(caddr) + ": reading %h\", Q" + str(ri) + ");\n") + fd.write( + " $display(\"Memory read on interface " + + str(ri) + + " at address " + + str(caddr) + + ": reading %h\", Q" + + str(ri) + + ");\n") fd.write(" end\n") caddr = caddr + 1 ccycle = ccycle + 1 if caddr >= self.words: fd.write(" $display(\"\");\n") - fd.write(" $display(\"--- End of Test " + str(op) + " PASSED ---\");\n") + fd.write( + " $display(\"--- End of Test " + + str(op) + + " PASSED ---\");\n") fd.write(" $display(\"\");\n") break @@ -896,7 +1403,10 @@ def write_tb(self, tb_path): fd.write(",\n .D" + str(i) + "(D" + str(i) + ")") fd.write(",\n .WE" + str(i) + "(WE" + str(i) + ")") fd.write(",\n .WEM" + str(i) + "(WEM" + str(i) + ")") - for i in range(self.write_interfaces, self.write_interfaces + self.read_interfaces): + for i in range( + self.write_interfaces, + self.write_interfaces + + self.read_interfaces): fd.write(",\n .CE" + str(i) + "(CE" + str(i) + ")") fd.write(",\n .A" + str(i) + "(A" + str(i) + ")") fd.write(",\n .Q" + str(i) + "(Q" + str(i) + ")") @@ -905,17 +1415,19 @@ def write_tb(self, tb_path): fd.write("endmodule\n") fd.close() - def write_hpp(self): try: fd = open("./memlib/" + self.name + ".hpp", 'w') except IOError as e: die_werr(e) - print(" INFO: Generating SystemC explicit memory definition for " + self.name) + print( + " INFO: Generating SystemC explicit memory definition for " + + self.name) fd.write("//\n") fd.write("// Created with the ESP Memory Generator\n") fd.write("//\n") - fd.write("// Copyright (c) 2011-2024 Columbia University, System Level Design Group\n") + fd.write( + "// Copyright (c) 2011-2024 Columbia University, System Level Design Group\n") fd.write("// SPDX-License-Identifier: Apache-2.0\n") fd.write("//\n") fd.write("// @author Paolo Mantovani \n") @@ -925,31 +1437,50 @@ def write_hpp(self): fd.write("#define __" + self.name.upper() + "_HPP__\n") fd.write("#include \"" + self.name + ".h\"\n") fd.write("template\n") - fd.write("class " + self.name +"_t : public sc_module\n") + fd.write("class " + self.name + "_t : public sc_module\n") fd.write("{\n") fd.write("\n") fd.write(" HLS_INLINE_MODULE;\n") fd.write("public:\n") - fd.write(" " + self.name + "_t(const sc_module_name& name = sc_gen_unique_name(\"" + self.name + "\"))\n") + fd.write( + " " + + self.name + + "_t(const sc_module_name& name = sc_gen_unique_name(\"" + + self.name + + "\"))\n") fd.write(" : sc_module(name)\n") fd.write(" , clk(\"clk\")\n") - for iface in range(1, self.read_interfaces + self.write_interfaces + 1): - fd.write(" , port" + str(iface) + "(\"port" + str(iface) + "\")\n") + for iface in range(1, self.read_interfaces + + self.write_interfaces + 1): + fd.write(" , port" + str(iface) + + "(\"port" + str(iface) + "\")\n") fd.write(" {\n") fd.write(" m_m0.clk_rst(clk);\n") - for iface in range(1, self.read_interfaces + self.write_interfaces + 1): - fd.write(" port" + str(iface) + "(m_m0.if" + str(iface) + ");\n") + for iface in range(1, self.read_interfaces + + self.write_interfaces + 1): + fd.write(" port" + str(iface) + + "(m_m0.if" + str(iface) + ");\n") fd.write(" }\n") fd.write("\n") fd.write(" sc_in clk;\n") fd.write("\n") fd.write(" " + self.name + "::wrapper m_m0;\n") fd.write("\n") - for iface in range(1, self.read_interfaces + self.write_interfaces + 1): - # TODO: there is a bug in Stratus that prevents a port interface to have a single dimension (so use [1] for now) - fd.write(" typedef " + self.name + "::port_" + str(iface) + " Port" + str(iface) + "_t;\n") + for iface in range(1, self.read_interfaces + + self.write_interfaces + 1): + # TODO: there is a bug in Stratus that prevents a port interface to + # have a single dimension (so use [1] for now) + fd.write( + " typedef " + + self.name + + "::port_" + + str(iface) + + " Port" + + str(iface) + + "_t;\n") fd.write("\n") - for iface in range(1, self.read_interfaces + self.write_interfaces + 1): + for iface in range(1, self.read_interfaces + + self.write_interfaces + 1): fd.write(" Port" + str(iface) + "_t port" + str(iface) + ";\n") fd.write("};\n") fd.write("#endif\n") @@ -985,41 +1516,100 @@ def write_bdm(self, out_path, tech_path): fd.write("setExtRegsAtMemIn 0\n") fd.write("setExtRegsAtMemOut 0\n") fd.write("setClockMult 0\n") - fd.write("setNumAccessPorts " + str(self.read_interfaces + self.write_interfaces) + "\n") + fd.write("setNumAccessPorts " + + str(self.read_interfaces + self.write_interfaces) + "\n") fd.write("setNumExtraPorts 0\n") fd.write("setPipelined 0\n") - fd.write("setVendorModel \"" + tech_path + "/" + self.bank_type.name + ".v\"\n") + fd.write( + "setVendorModel \"" + + tech_path + + "/" + + self.bank_type.name + + ".v\"\n") fd.write("setModelWrapper \"" + out_path + "/" + self.name + ".v\"\n") fd.write("setExtraPortsInWrapper 0\n") - port_count = 0; + port_count = 0 for wi in range(self.write_interfaces): fd.write("setPortData " + str(port_count) + " setType 1\n") - fd.write("setPortData " + str(port_count) + " setAddr \"A" + str(wi) + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setAddr \"A" + + str(wi) + + "\"\n") fd.write("setPortData " + str(port_count) + " setClk \"CLK\"\n") - fd.write("setPortData " + str(port_count) + " setReqName \"REQ" + str(wi) + "\"\n") - fd.write("setPortData " + str(port_count) + " setDin \"D" + str(wi) + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setReqName \"REQ" + + str(wi) + + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setDin \"D" + + str(wi) + + "\"\n") fd.write("setPortData " + str(port_count) + " setHasRW 1\n") - fd.write("setPortData " + str(port_count) + " setRwName \"WE" + str(wi) + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setRwName \"WE" + + str(wi) + + "\"\n") fd.write("setPortData " + str(port_count) + " setRwActive 1\n") fd.write("setPortData " + str(port_count) + " setWMWord 1\n") - fd.write("setPortData " + str(port_count) + " setWMName \"WEM" + str(wi) + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setWMName \"WEM" + + str(wi) + + "\"\n") fd.write("setPortData " + str(port_count) + " setWMActive 1\n") fd.write("setPortData " + str(port_count) + " setHasCE 1\n") - fd.write("setPortData " + str(port_count) + " setCEName \"CE" + str(wi) + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setCEName \"CE" + + str(wi) + + "\"\n") fd.write("setPortData " + str(port_count) + " setCEActive 1\n") - port_count = port_count + 1; - for ri in range(self.write_interfaces, self.read_interfaces + self.write_interfaces): + port_count = port_count + 1 + for ri in range( + self.write_interfaces, + self.read_interfaces + + self.write_interfaces): fd.write("setPortData " + str(port_count) + " setType 0\n") - fd.write("setPortData " + str(port_count) + " setAddr \"A" + str(ri) + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setAddr \"A" + + str(ri) + + "\"\n") fd.write("setPortData " + str(port_count) + " setClk \"CLK\"\n") - fd.write("setPortData " + str(port_count) + " setReqName \"REQ" + str(ri) + "\"\n") - fd.write("setPortData " + str(port_count) + " setDout \"Q" + str(ri) + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setReqName \"REQ" + + str(ri) + + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setDout \"Q" + + str(ri) + + "\"\n") fd.write("setPortData " + str(port_count) + " setHasOE 0\n") fd.write("setPortData " + str(port_count) + " setHasRE 0\n") fd.write("setPortData " + str(port_count) + " setHasCE 1\n") - fd.write("setPortData " + str(port_count) + " setCEName \"CE" + str(ri) + "\"\n") + fd.write( + "setPortData " + + str(port_count) + + " setCEName \"CE" + + str(ri) + + "\"\n") fd.write("setPortData " + str(port_count) + " setCEActive 1\n") - port_count = port_count + 1; + port_count = port_count + 1 fd.close() # for wi in range(self.write_interfaces - 1, -1, -1): @@ -1067,46 +1657,60 @@ def parse_sram(s): return None return sram(name, words, width, area, ports) + def parse_op(op, mem_words): item = op.split(":") - write_number = int(re.split('[a-z]+', item[0], re.M|re.I)[0]) - write_pattern_abbrv = str(re.split('[0-9]+', item[0], re.M|re.I)[1]) - read_number = int(re.split('[a-z]+', item[1], re.M|re.I)[0]) - read_pattern_abbrv = str(re.split('[0-9]+', item[1], re.M|re.I)[1]) + write_number = int(re.split('[a-z]+', item[0], re.M | re.I)[0]) + write_pattern_abbrv = str(re.split('[0-9]+', item[0], re.M | re.I)[1]) + read_number = int(re.split('[a-z]+', item[1], re.M | re.I)[0]) + read_pattern_abbrv = str(re.split('[0-9]+', item[1], re.M | re.I)[1]) if read_number > mem_words or write_number > mem_words: - die_werr("Too many ports for the specified number of words for "+op) + die_werr("Too many ports for the specified number of words for " + op) if read_number > 16 or read_number < 0: - die_werr("Too many paralle accesses specified for "+op); + die_werr("Too many paralle accesses specified for " + op) - if re.match(r'ru', read_pattern_abbrv, re.M|re.I): + if re.match(r'ru', read_pattern_abbrv, re.M | re.I): read_pattern = "unknown" - elif re.match(r'r', read_pattern_abbrv, re.M|re.I): + elif re.match(r'r', read_pattern_abbrv, re.M | re.I): read_pattern = "modulo" if not is_power2z(read_number): - die_werr("Operation "+op+" implies known access patter (modulo), but the number of accesses is not a power of 2") + die_werr( + "Operation " + + op + + " implies known access patter (modulo), but the number of accesses is not a power of 2") else: - die_werr("Parallel read access "+op+" not recognized") + die_werr("Parallel read access " + op + " not recognized") if write_number > 16 or write_number < 0: - die_werr("Too many paralle accesses specified for "+op); + die_werr("Too many paralle accesses specified for " + op) - if re.match(r'wu', write_pattern_abbrv, re.M|re.I): + if re.match(r'wu', write_pattern_abbrv, re.M | re.I): write_pattern = "unknown" if write_number > 2: - die_werr("Too many parallel write accesses with unknown pattern for "+op) + die_werr( + "Too many parallel write accesses with unknown pattern for " + op) if write_number == 2 and read_number != 0: - die_werr("2 parallel write accesses with unknown pattern for "+op+" have non-zero parallel read access") - elif re.match(r'w', write_pattern_abbrv, re.M|re.I): + die_werr( + "2 parallel write accesses with unknown pattern for " + + op + + " have non-zero parallel read access") + elif re.match(r'w', write_pattern_abbrv, re.M | re.I): write_pattern = "modulo" if not is_power2z(write_number): - die_werr("Operation "+op+" implies known access patter (modulo), but the number of accesses is not a power of 2") + die_werr( + "Operation " + + op + + " implies known access patter (modulo), but the number of accesses is not a power of 2") else: - die_werr("Parallel write access "+op+" not recognized") - - return memory_operation(read_number, read_pattern, write_number, write_pattern) + die_werr("Parallel write access " + op + " not recognized") + return memory_operation( + read_number, + read_pattern, + write_number, + write_pattern) def read_techfile(tech_path, sram_list): @@ -1121,16 +1725,16 @@ def read_techfile(tech_path, sram_list): line.strip() item = line.split() # Check for commented line - if re.match(r'# delay*', line, re.M|re.I): + if re.match(r'# delay*', line, re.M | re.I): mem_delay = float(item[2]) - if re.match(r'# setup*', line, re.M|re.I): + if re.match(r'# setup*', line, re.M | re.I): mem_setup = float(item[2]) - if re.match(r'# single_port*', line, re.M|re.I): + if re.match(r'# single_port*', line, re.M | re.I): single_port = True - if re.match(r'#\.*', line, re.M|re.I): + if re.match(r'#\.*', line, re.M | re.I): continue ram = parse_sram(line) - if ram == None: + if ram is None: continue sram_list.append(ram) fd.close() @@ -1145,7 +1749,7 @@ def read_infile(name, mem_list): line.strip() item = line.split() # Check for commented line - if re.match(r'#\.*', line, re.M|re.I): + if re.match(r'#\.*', line, re.M | re.I): continue mem_name = item[0] mem_words = int(item[1]) @@ -1199,4 +1803,3 @@ def read_infile(name, mem_list): mem.write_tb(tb_path) mem.write_hpp() mem.write_bdm(out_path, tech_path) - diff --git a/tools/socgen/NoCConfiguration.py b/tools/socgen/NoCConfiguration.py index 632f12f7e7..73e63abb85 100644 --- a/tools/socgen/NoCConfiguration.py +++ b/tools/socgen/NoCConfiguration.py @@ -22,775 +22,1005 @@ def isInt(s): - try: - int(s) - return True - except ValueError: - return False + try: + int(s) + return True + except ValueError: + return False class Characterization(): - ip = "" - vf_points = [] + ip = "" + vf_points = [] -class VFPoint(): - voltage = 0 - frequency = 0 - energy = 0 -class Tile(): - - def update_tile(self, soc): - selection = self.ip_type.get() - self.label.config(text=selection) - self.point_label.forget() - self.point_select.forget() - self.ip_list.forget() - self.ip_list.setitems(soc.list_of_ips) - self.ip_list.pack(side=LEFT) - if soc.IPs.PROCESSORS.count(selection): - self.label.config(bg="#ef6865") - elif soc.IPs.MISC.count(selection): - self.label.config(bg="#fdfda0") - elif soc.IPs.MEM.count(selection): - self.label.config(bg="#6ab0d4") - elif soc.IPs.SLM.count(selection): - self.label.config(bg="#c9a6e4") - elif soc.IPs.ACCELERATORS.count(selection): - self.label.config(bg="#78cbbb") - self.point_label.pack(side=LEFT) - self.vendor = soc.IPs.VENDOR[selection] - dma_width = str(soc.noc.dma_noc_width.get()) - display_points = [point for point in soc.IPs.POINTS[selection] if "dma" + str(dma_width) in point] - self.point_select.setitems(display_points) - point = self.point.get() - self.point_select.setvalue("") - for p in display_points: - if point == p: - self.point_select.setvalue(point) - break; - else: - self.point_select.setvalue(str(display_points[0])) - self.point_select.pack(side=LEFT) - else: - self.label.config(bg='white') - if self.ip_type.get() != "empty": - self.ip_type.set("empty") - self.clk_reg_selection.config(to=soc.noc.get_clk_regions_max()) +class VFPoint(): + voltage = 0 + frequency = 0 + energy = 0 +class Tile(): - try: - if soc.IPs.PROCESSORS.count(selection) or soc.IPs.ACCELERATORS.count(selection): - self.clk_reg_selection.config(state='readonly') - if self.clk_region.get() != 0: - self.pll_selection.config(state=NORMAL) - else: - self.pll_selection.config(state=DISABLED) - if self.has_pll.get() == 1 : - self.has_pll.set(0) - if self.has_pll.get() == 1: - self.clkbuf_selection.config(state=NORMAL) - else: - self.clkbuf_selection.config(state=DISABLED) - if self.has_clkbuf.get() == 1 : - self.has_clkbuf.set(0) - else: - self.clk_reg_selection.config(state=DISABLED) - self.pll_selection.config(state=DISABLED) - self.clkbuf_selection.config(state=DISABLED) - if self.clk_region.get() > 0 : - self.clk_region.set(0) - if self.has_pll.get() == 1 : - self.has_pll.set(0) - if self.has_clkbuf.get() == 1 : - self.has_clkbuf.set(0) - if soc.IPs.ACCELERATORS.count(selection) and soc.cache_en.get() == 1 and soc.noc.noc_width.get() == soc.ARCH_BITS: - self.has_l2_selection.config(state=NORMAL) - else: - if soc.IPs.PROCESSORS.count(selection) and soc.cache_en.get() == 1: - self.has_l2.set(1) + def update_tile(self, soc): + selection = self.ip_type.get() + self.label.config(text=selection) + self.point_label.forget() + self.point_select.forget() + self.ip_list.forget() + self.ip_list.setitems(soc.list_of_ips) + self.ip_list.pack(side=LEFT) + if soc.IPs.PROCESSORS.count(selection): + self.label.config(bg="#ef6865") + elif soc.IPs.MISC.count(selection): + self.label.config(bg="#fdfda0") + elif soc.IPs.MEM.count(selection): + self.label.config(bg="#6ab0d4") + elif soc.IPs.SLM.count(selection): + self.label.config(bg="#c9a6e4") + elif soc.IPs.ACCELERATORS.count(selection): + self.label.config(bg="#78cbbb") + self.point_label.pack(side=LEFT) + self.vendor = soc.IPs.VENDOR[selection] + dma_width = str(soc.noc.dma_noc_width.get()) + display_points = [ + point for point in soc.IPs.POINTS[selection] if "dma" + + str(dma_width) in point] + self.point_select.setitems(display_points) + point = self.point.get() + self.point_select.setvalue("") + for p in display_points: + if point == p: + self.point_select.setvalue(point) + break + else: + self.point_select.setvalue(str(display_points[0])) + self.point_select.pack(side=LEFT) else: - self.has_l2.set(0) - self.has_l2_selection.config(state=DISABLED) - #if soc.IPs.SLM.count(selection) and soc.TECH == "gf12": - if soc.IPs.SLM.count(selection) and soc.TECH == "asic": - self.has_ddr_selection.config(state=NORMAL) - else: - # DDR SLM tile only supported w/ GF12 technology - self.has_ddr.set(0) - self.has_ddr_selection.config(state=DISABLED) - except: - pass - - self.load_characterization(soc, soc.noc.vf_points) - - def get_clk_region(self): - return self.clk_region.get() - - def center(self, toplevel): - toplevel.update_idletasks() - w = toplevel.winfo_screenwidth() - h = toplevel.winfo_screenheight() - size = tuple(int(_) for _ in toplevel.geometry().split('+')[0].split('x')) - x = w/2 - size[0]/2 + 100 - y = h/2 - size[1]/2 - toplevel.geometry("%dx%d+%d+%d" % (size + (x, y))) - - def create_characterization(self, soc, num_points): - self.energy_values = Characterization() - self.energy_values.ip = self.ip_type.get() - self.energy_values.vf_points = [VFPoint() for x in range(num_points)] - - def load_characterization(self, soc, num_points): - ESP_ROOT = os.path.realpath(os.path.dirname(os.path.realpath(__file__)) + "/../../") - selection = self.ip_type.get() - if self.energy_values == None or len(self.energy_values.vf_points) == 0: - self.create_characterization(soc, num_points) - if self.energy_values.ip != selection and soc.IPs.ACCELERATORS.count(selection): - e = xml.etree.ElementTree.parse(ESP_ROOT + "/tools/socgen/power.xml").getroot() - self.energy_values.ip = selection - for atype in e.findall('accelerator'): - if atype.get('name') == self.ip_type.get(): - xml_vf_points = atype.findall('vf_point') - end_point = num_points - if len(xml_vf_points) < end_point: - end_point = len(xml_vf_points) - for x in range(end_point): - self.energy_values.vf_points[x].voltage = float(xml_vf_points[x].get('voltage')) - self.energy_values.vf_points[x].frequency = float(xml_vf_points[x].get('frequency')) - self.energy_values.vf_points[x].energy = float(xml_vf_points[x].get('energy')) + self.label.config(bg='white') + if self.ip_type.get() != "empty": + self.ip_type.set("empty") + self.clk_reg_selection.config(to=soc.noc.get_clk_regions_max()) + + try: + if soc.IPs.PROCESSORS.count( + selection) or soc.IPs.ACCELERATORS.count(selection): + self.clk_reg_selection.config(state='readonly') + if self.clk_region.get() != 0: + self.pll_selection.config(state=NORMAL) + else: + self.pll_selection.config(state=DISABLED) + if self.has_pll.get() == 1: + self.has_pll.set(0) + if self.has_pll.get() == 1: + self.clkbuf_selection.config(state=NORMAL) + else: + self.clkbuf_selection.config(state=DISABLED) + if self.has_clkbuf.get() == 1: + self.has_clkbuf.set(0) + else: + self.clk_reg_selection.config(state=DISABLED) + self.pll_selection.config(state=DISABLED) + self.clkbuf_selection.config(state=DISABLED) + if self.clk_region.get() > 0: + self.clk_region.set(0) + if self.has_pll.get() == 1: + self.has_pll.set(0) + if self.has_clkbuf.get() == 1: + self.has_clkbuf.set(0) + if soc.IPs.ACCELERATORS.count(selection) and soc.cache_en.get( + ) == 1 and soc.noc.noc_width.get() == soc.ARCH_BITS: + self.has_l2_selection.config(state=NORMAL) + else: + if soc.IPs.PROCESSORS.count( + selection) and soc.cache_en.get() == 1: + self.has_l2.set(1) + else: + self.has_l2.set(0) + self.has_l2_selection.config(state=DISABLED) + # if soc.IPs.SLM.count(selection) and soc.TECH == "gf12": + if soc.IPs.SLM.count(selection) and soc.TECH == "asic": + self.has_ddr_selection.config(state=NORMAL) + else: + # DDR SLM tile only supported w/ GF12 technology + self.has_ddr.set(0) + self.has_ddr_selection.config(state=DISABLED) + except BaseException: + pass + + self.load_characterization(soc, soc.noc.vf_points) + + def get_clk_region(self): + return self.clk_region.get() + + def center(self, toplevel): + toplevel.update_idletasks() + w = toplevel.winfo_screenwidth() + h = toplevel.winfo_screenheight() + size = tuple(int(_) + for _ in toplevel.geometry().split('+')[0].split('x')) + x = w / 2 - size[0] / 2 + 100 + y = h / 2 - size[1] / 2 + toplevel.geometry("%dx%d+%d+%d" % (size + (x, y))) + + def create_characterization(self, soc, num_points): + self.energy_values = Characterization() + self.energy_values.ip = self.ip_type.get() + self.energy_values.vf_points = [VFPoint() for x in range(num_points)] + + def load_characterization(self, soc, num_points): + ESP_ROOT = os.path.realpath( + os.path.dirname( + os.path.realpath(__file__)) + + "/../../") + selection = self.ip_type.get() + if self.energy_values is None or len( + self.energy_values.vf_points) == 0: + self.create_characterization(soc, num_points) + if self.energy_values.ip != selection and soc.IPs.ACCELERATORS.count( + selection): + e = xml.etree.ElementTree.parse( + ESP_ROOT + "/tools/socgen/power.xml").getroot() + self.energy_values.ip = selection + for atype in e.findall('accelerator'): + if atype.get('name') == self.ip_type.get(): + xml_vf_points = atype.findall('vf_point') + end_point = num_points + if len(xml_vf_points) < end_point: + end_point = len(xml_vf_points) + for x in range(end_point): + self.energy_values.vf_points[x].voltage = float( + xml_vf_points[x].get('voltage')) + self.energy_values.vf_points[x].frequency = float( + xml_vf_points[x].get('frequency')) + self.energy_values.vf_points[x].energy = float( + xml_vf_points[x].get('energy')) + else: + end_point = num_points + for x in range(end_point): + self.energy_values.vf_points[x].voltage = 0.0 + self.energy_values.vf_points[x].frequency = 0.0 + self.energy_values.vf_points[x].energy = 0.0 else: - end_point = num_points - for x in range(end_point): - self.energy_values.vf_points[x].voltage = 0.0 - self.energy_values.vf_points[x].frequency = 0.0 - self.energy_values.vf_points[x].energy = 0.0 - else: - new_vf_points = [VFPoint() for x in range(num_points)] - end_point = num_points - if len(self.energy_values.vf_points) < end_point: - end_point = len(self.energy_values.vf_points) - for x in range(end_point): - new_vf_points[x] = self.energy_values.vf_points[x] - self.energy_values.vf_points = new_vf_points - - def power_window(self, event, soc, nocframe): - selection = self.ip_type.get() - if soc.IPs.ACCELERATORS.count(selection) == 0 or self.clk_region.get() == 0: - return - try: - int(nocframe.vf_points_entry.get()) - except: - return - self.toplevel = Toplevel() - label1 = Label(self.toplevel, text="Power Information for \"" + selection + "\"", height=0, width=50, font="TkDefaultFont 11 bold") - label1.pack() - entry = [Frame(self.toplevel) for x in range(int(nocframe.vf_points_entry.get()))] - for x in range(len(entry)): - entry[x].pack(side=LEFT) - Label(entry[x], text="Voltage ("+str(x)+") (V)", height=0, width=20).pack(side=TOP) - entry[x].e1 = Entry(entry[x], width=10) - entry[x].e1.pack(side=TOP) - Label(entry[x], text="Frequency ("+str(x)+") (MHz)", height=0, width=20).pack(side=TOP) - entry[x].e2 = Entry(entry[x], width=10) - entry[x].e2.pack(side=TOP) - Label(entry[x], text="Tot Energy ("+str(x)+") (pJ)", height=0, width=20).pack(side=TOP) - entry[x].e3 = Entry(entry[x], width=10) - entry[x].e3.pack(side=TOP) - entry[x].e1.delete(0, END) - entry[x].e2.delete(0, END) - entry[x].e3.delete(0, END) - entry[x].e1.insert(0, str(self.energy_values.vf_points[x].voltage)) - entry[x].e2.insert(0, str(self.energy_values.vf_points[x].frequency)) - entry[x].e3.insert(0, str(self.energy_values.vf_points[x].energy)) - Label(entry[x], height=1).pack(side=TOP) - self.toplevel.entry = entry - self.center(self.toplevel) - self.toplevel.protocol("WM_DELETE_WINDOW", functools.partial(self.on_closing, toplevel=self.toplevel)) - - def on_closing(self, toplevel): - if messagebox.askyesno("Save", "Do you want to save the modifications?"): - for x in range(len(self.energy_values.vf_points)): - self.energy_values.vf_points[x].voltage = float(toplevel.entry[x].e1.get()) - self.energy_values.vf_points[x].frequency = float(toplevel.entry[x].e2.get()) - self.energy_values.vf_points[x].energy = float(toplevel.entry[x].e3.get()) - toplevel.destroy() - - def __init__(self, top, x, y): - self.row = x - self.col = y - self.ip_type = StringVar() - self.point = StringVar() - self.vendor = "" - self.clk_region = IntVar() - self.has_l2 = IntVar() - self.has_ddr = IntVar() - self.has_pll = IntVar() - self.has_clkbuf = IntVar() - self.clk_reg_active = StringVar() - self.label = Label(top) - self.energy_values = None + new_vf_points = [VFPoint() for x in range(num_points)] + end_point = num_points + if len(self.energy_values.vf_points) < end_point: + end_point = len(self.energy_values.vf_points) + for x in range(end_point): + new_vf_points[x] = self.energy_values.vf_points[x] + self.energy_values.vf_points = new_vf_points + + def power_window(self, event, soc, nocframe): + selection = self.ip_type.get() + if soc.IPs.ACCELERATORS.count( + selection) == 0 or self.clk_region.get() == 0: + return + try: + int(nocframe.vf_points_entry.get()) + except BaseException: + return + self.toplevel = Toplevel() + label1 = Label( + self.toplevel, + text="Power Information for \"" + + selection + + "\"", + height=0, + width=50, + font="TkDefaultFont 11 bold") + label1.pack() + entry = [Frame(self.toplevel) + for x in range(int(nocframe.vf_points_entry.get()))] + for x in range(len(entry)): + entry[x].pack(side=LEFT) + Label( + entry[x], + text="Voltage (" + str(x) + ") (V)", + height=0, + width=20).pack( + side=TOP) + entry[x].e1 = Entry(entry[x], width=10) + entry[x].e1.pack(side=TOP) + Label( + entry[x], + text="Frequency (" + str(x) + ") (MHz)", + height=0, + width=20).pack( + side=TOP) + entry[x].e2 = Entry(entry[x], width=10) + entry[x].e2.pack(side=TOP) + Label( + entry[x], + text="Tot Energy (" + str(x) + ") (pJ)", + height=0, + width=20).pack( + side=TOP) + entry[x].e3 = Entry(entry[x], width=10) + entry[x].e3.pack(side=TOP) + entry[x].e1.delete(0, END) + entry[x].e2.delete(0, END) + entry[x].e3.delete(0, END) + entry[x].e1.insert(0, str(self.energy_values.vf_points[x].voltage)) + entry[x].e2.insert( + 0, str( + self.energy_values.vf_points[x].frequency)) + entry[x].e3.insert(0, str(self.energy_values.vf_points[x].energy)) + Label(entry[x], height=1).pack(side=TOP) + self.toplevel.entry = entry + self.center(self.toplevel) + self.toplevel.protocol( + "WM_DELETE_WINDOW", + functools.partial( + self.on_closing, + toplevel=self.toplevel)) + + def on_closing(self, toplevel): + if messagebox.askyesno("Save", + "Do you want to save the modifications?"): + for x in range(len(self.energy_values.vf_points)): + self.energy_values.vf_points[x].voltage = float( + toplevel.entry[x].e1.get()) + self.energy_values.vf_points[x].frequency = float( + toplevel.entry[x].e2.get()) + self.energy_values.vf_points[x].energy = float( + toplevel.entry[x].e3.get()) + toplevel.destroy() + + def __init__(self, top, x, y): + self.row = x + self.col = y + self.ip_type = StringVar() + self.point = StringVar() + self.vendor = "" + self.clk_region = IntVar() + self.has_l2 = IntVar() + self.has_ddr = IntVar() + self.has_pll = IntVar() + self.has_clkbuf = IntVar() + self.clk_reg_active = StringVar() + self.label = Label(top) + self.energy_values = None + class NoC(): - rows = 0 - cols = 0 - top = "" - - vf_points = 4 - - topology = [] - - def create_topology(self, top, _R, _C): - self.top = top - new_topology = [] - for y in range(_R): - new_topology.append([]) - for x in range(_C): - new_topology[y].append(Tile(top, y, x)) - if x < self.cols and y < self.rows: - new_topology[y][x].ip_type.set(self.topology[y][x].ip_type.get()) - new_topology[y][x].has_l2.set(self.topology[y][x].has_l2.get()) - new_topology[y][x].has_ddr.set(self.topology[y][x].has_ddr.get()) - new_topology[y][x].clk_region.set(self.topology[y][x].clk_region.get()) - new_topology[y][x].has_pll.set(self.topology[y][x].has_pll.get()) - new_topology[y][x].has_clkbuf.set(self.topology[y][x].has_clkbuf.get()) - new_topology[y][x].point.set(self.topology[y][x].point.get()) - new_topology[y][x].vendor = self.topology[y][x].vendor - new_topology[y][x].energy_values = self.topology[y][x].energy_values - self.topology = new_topology - self.rows = _R - self.cols = _C - - def get_clk_regions(self): - regions = [] - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - if tile.clk_region is not None and regions.count(tile.clk_region.get()) == 0: - regions.append(tile.clk_region.get()) - return regions - - def get_clk_regions_max(self): - region_max = 0 - max_count = 0 - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - if tile.clk_region is not None and tile.clk_region.get() > region_max: - region_max = tile.clk_region.get() - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - if tile.clk_region is not None and tile.clk_region.get() == region_max: - max_count = max_count + 1 - if max_count > 1: - region_max = region_max + 1 - return region_max - - def get_clkbuf_num(self, soc): - tot_clkbuf = 0 - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - selection = tile.ip_type.get() - if soc.IPs.ACCELERATORS.count(selection) and tile.has_clkbuf.get() == 1: - tot_clkbuf += 1 - return tot_clkbuf - - def has_dvfs(self): - regions = [] - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - if tile.clk_region is not None and tile.clk_region.get() != 0: - return True - return False - - def get_cpu_num(self, soc): - tot_cpu = 0 - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - selection = tile.ip_type.get() - if soc.IPs.PROCESSORS.count(selection): - tot_cpu += 1 - return tot_cpu - - def get_acc_num(self, soc): - tot_acc = 0 - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - selection = tile.ip_type.get() - if soc.IPs.ACCELERATORS.count(selection): - tot_acc += 1 - return tot_acc - - def get_acc_l2_num(self, soc): - tot_acc_l2 = 0 - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - selection = tile.ip_type.get() - if soc.IPs.ACCELERATORS.count(selection): - if tile.has_l2.get() != 0: - tot_acc_l2 += 1 - return tot_acc_l2 - - def get_acc_impl_valid(self, soc): - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - selection = tile.ip_type.get() - if soc.IPs.ACCELERATORS.count(selection): - if tile.point_select.getvalue() == "" and (not tile.ip_type.get().lower() in THIRDPARTY_COMPATIBLE): - return False - return True - - def get_mem_num(self, soc): - tot_mem = 0 - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - selection = tile.ip_type.get() - if soc.IPs.MEM.count(selection): - tot_mem += 1 - return tot_mem - - def get_slm_num(self, soc): - tot_slm = 0 - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - selection = tile.ip_type.get() - if soc.IPs.SLM.count(selection) and tile.has_ddr.get() == 0: - tot_slm += 1 - return tot_slm - - def get_slmddr_num(self, soc): - tot_slmddr = 0 - for y in range(0, self.rows): - for x in range(0, self.cols): - tile = self.topology[y][x] - selection = tile.ip_type.get() - if soc.IPs.SLM.count(selection) and tile.has_ddr.get() != 0: - tot_slmddr += 1 - return tot_slmddr - - # WARNING: Geometry in this class only uses x=rows, y=cols, but socmap uses y=row, x=cols! - def __init__(self): - self.cols = 0 - self.rows = 0 - self.coh_noc_width = IntVar() - self.dma_noc_width = IntVar() - self.monitor_ddr = IntVar() - self.monitor_mem = IntVar() - self.monitor_inj = IntVar() - self.monitor_routers = IntVar() - self.monitor_accelerators = IntVar() - self.monitor_l2 = IntVar() - self.monitor_llc = IntVar() - self.monitor_dvfs = IntVar() - -#NoC configuration frame (middle) + rows = 0 + cols = 0 + top = "" + + vf_points = 4 + + topology = [] + + def create_topology(self, top, _R, _C): + self.top = top + new_topology = [] + for y in range(_R): + new_topology.append([]) + for x in range(_C): + new_topology[y].append(Tile(top, y, x)) + if x < self.cols and y < self.rows: + new_topology[y][x].ip_type.set( + self.topology[y][x].ip_type.get()) + new_topology[y][x].has_l2.set( + self.topology[y][x].has_l2.get()) + new_topology[y][x].has_ddr.set( + self.topology[y][x].has_ddr.get()) + new_topology[y][x].clk_region.set( + self.topology[y][x].clk_region.get()) + new_topology[y][x].has_pll.set( + self.topology[y][x].has_pll.get()) + new_topology[y][x].has_clkbuf.set( + self.topology[y][x].has_clkbuf.get()) + new_topology[y][x].point.set( + self.topology[y][x].point.get()) + new_topology[y][x].vendor = self.topology[y][x].vendor + new_topology[y][x].energy_values = self.topology[y][x].energy_values + self.topology = new_topology + self.rows = _R + self.cols = _C + + def get_clk_regions(self): + regions = [] + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + if tile.clk_region is not None and regions.count( + tile.clk_region.get()) == 0: + regions.append(tile.clk_region.get()) + return regions + + def get_clk_regions_max(self): + region_max = 0 + max_count = 0 + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + if tile.clk_region is not None and tile.clk_region.get() > region_max: + region_max = tile.clk_region.get() + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + if tile.clk_region is not None and tile.clk_region.get() == region_max: + max_count = max_count + 1 + if max_count > 1: + region_max = region_max + 1 + return region_max + + def get_clkbuf_num(self, soc): + tot_clkbuf = 0 + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + selection = tile.ip_type.get() + if soc.IPs.ACCELERATORS.count( + selection) and tile.has_clkbuf.get() == 1: + tot_clkbuf += 1 + return tot_clkbuf + + def has_dvfs(self): + regions = [] + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + if tile.clk_region is not None and tile.clk_region.get() != 0: + return True + return False + + def get_cpu_num(self, soc): + tot_cpu = 0 + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + selection = tile.ip_type.get() + if soc.IPs.PROCESSORS.count(selection): + tot_cpu += 1 + return tot_cpu + + def get_acc_num(self, soc): + tot_acc = 0 + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + selection = tile.ip_type.get() + if soc.IPs.ACCELERATORS.count(selection): + tot_acc += 1 + return tot_acc + + def get_acc_l2_num(self, soc): + tot_acc_l2 = 0 + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + selection = tile.ip_type.get() + if soc.IPs.ACCELERATORS.count(selection): + if tile.has_l2.get() != 0: + tot_acc_l2 += 1 + return tot_acc_l2 + + def get_acc_impl_valid(self, soc): + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + selection = tile.ip_type.get() + if soc.IPs.ACCELERATORS.count(selection): + if tile.point_select.getvalue() == "" and ( + not tile.ip_type.get().lower() in THIRDPARTY_COMPATIBLE): + return False + return True + + def get_mem_num(self, soc): + tot_mem = 0 + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + selection = tile.ip_type.get() + if soc.IPs.MEM.count(selection): + tot_mem += 1 + return tot_mem + + def get_slm_num(self, soc): + tot_slm = 0 + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + selection = tile.ip_type.get() + if soc.IPs.SLM.count(selection) and tile.has_ddr.get() == 0: + tot_slm += 1 + return tot_slm + + def get_slmddr_num(self, soc): + tot_slmddr = 0 + for y in range(0, self.rows): + for x in range(0, self.cols): + tile = self.topology[y][x] + selection = tile.ip_type.get() + if soc.IPs.SLM.count(selection) and tile.has_ddr.get() != 0: + tot_slmddr += 1 + return tot_slmddr + + # WARNING: Geometry in this class only uses x=rows, y=cols, but socmap + # uses y=row, x=cols! + def __init__(self): + self.cols = 0 + self.rows = 0 + self.coh_noc_width = IntVar() + self.dma_noc_width = IntVar() + self.monitor_ddr = IntVar() + self.monitor_mem = IntVar() + self.monitor_inj = IntVar() + self.monitor_routers = IntVar() + self.monitor_accelerators = IntVar() + self.monitor_l2 = IntVar() + self.monitor_llc = IntVar() + self.monitor_dvfs = IntVar() + +# NoC configuration frame (middle) + + class NoCFrame(Pmw.ScrolledFrame): - current_nocx = 0 - current_nocy = 0 - - noc_tiles = [] - row_frames = [] - - def changed(self,*args): - if isInt(self.ROWS.get()) == False or isInt(self.COLS.get()) == False: - return - for y in range(0, int(self.ROWS.get())): - for x in range(0, int(self.COLS.get())): - self.noc.topology[y][x].update_tile(self.soc) - self.update_msg() - - def update_frame(self): - if self.noc.cols > 0 and self.noc.rows > 0: - self.COLS.insert(0, str(self.noc.cols)) - self.ROWS.insert(0, str(self.noc.rows)) - self.create_noc() - self.changed() - - def create_tile(self, frame, tile): - #computing the width of the widget - list_items = self.soc.list_of_ips - width = 0 - for x in range(0, len(list_items)): - if len(list_items[x]) > width: - width = len(list_items[x]) - #creating tile - select_frame = Frame(frame) - select_frame.pack(side=TOP) - - display_frame = Frame(frame) - display_frame.pack(side=TOP) - - config_frame = Frame(frame) - config_frame.pack(side=TOP) - - tile.ip_list = Pmw.OptionMenu(select_frame, menubutton_font="TkDefaultFont 8", - menubutton_textvariable=tile.ip_type, - menubutton_width = width+2, - items=list_items - ) - tile.ip_list.pack(side=LEFT) - tile.point_label = Label(select_frame, text="Impl.: ", width=5) - tile.point_select = Pmw.OptionMenu(select_frame, menubutton_font="TkDefaultFont 8", - menubutton_textvariable=tile.point, - menubutton_width = 10, - items=[] - ) - - tile.label = Label(display_frame, text=tile.ip_type.get()) - tile.label.config(height=4,bg='white', width=width+25) - tile.label.pack() - - tile.has_l2_selection = Checkbutton(config_frame, text="Has cache", variable=tile.has_l2, onvalue = 1, offvalue = 0, command=self.changed); - tile.has_l2_selection.grid(row=1, column=1) - tile.has_ddr_selection = Checkbutton(config_frame, text="Has DDR", variable=tile.has_ddr, onvalue = 1, offvalue = 0, command=self.changed); - tile.has_ddr_selection.grid(row=1, column=4) - Separator(config_frame, orient="horizontal").grid(row=2, column=1, columnspan=4, ipadx=140, pady=3) - - tile.label.bind("", lambda event:tile.power_window(event, self.soc, self)) - Label(config_frame, text="Clk Reg: ", justify=LEFT, anchor="w").grid(sticky = W, row=3, column=1) - tile.clk_reg_selection = Spinbox(config_frame, state='readonly', from_=0, to=len(self.soc.noc.get_clk_regions()), wrap=True, textvariable=tile.clk_region,width=3, justify=RIGHT); - tile.clk_reg_selection.grid(sticky = E, row=3, column=1) - tile.pll_selection = Checkbutton(config_frame, text="Has PLL", variable=tile.has_pll, onvalue = 1, offvalue = 0, command=self.changed); - tile.pll_selection.grid(row=3, column=2) - tile.clkbuf_selection = Checkbutton(config_frame, text="CLK BUF", variable=tile.has_clkbuf, onvalue = 1, offvalue = 0, command=self.changed); - tile.clkbuf_selection.grid(row=3, column=3) - try: - int(self.vf_points_entry.get()) - tile.load_characterization(self.soc, int(self.vf_points_entry.get())) - except: - pass - - def __init__(self, soc, bottom_frame): - self.soc = soc - self.noc = self.soc.noc - #configuration frame - self.noc_config_frame = Frame(bottom_frame) - Label(self.noc_config_frame, text="NoC configuration", font="TkDefaultFont 11 bold").pack(side = TOP) - self.config_noc_frame = Frame(self.noc_config_frame) - self.config_noc_frame.pack(side=TOP) - Label(self.config_noc_frame, text="Rows: ").pack(side = LEFT) - self.ROWS = Entry(self.config_noc_frame, width=3) - self.ROWS.pack(side = LEFT) - Label(self.config_noc_frame, text="Cols: ").pack(side = LEFT) - self.COLS = Entry(self.config_noc_frame, width=3) - self.COLS.pack(side = LEFT) - - noc_width_choices = ["32", "64", "128", "256", "512", "1024"] - Label(self.noc_config_frame, text = "Coherence NoC Planes (1,2,3) Bitwidth: ", height=1).pack() - OptionMenu(self.noc_config_frame, self.noc.coh_noc_width, *noc_width_choices).pack() - Label(self.noc_config_frame, text = "DMA NoC Planes (4,6) Bitwidth: ", height=1).pack() - OptionMenu(self.noc_config_frame, self.noc.dma_noc_width, *noc_width_choices).pack() - Label(self.noc_config_frame, text = "MMIO/Irq NoC Plane (5) Bitwidth is always 32", height=1).pack(side=TOP) - Button(self.noc_config_frame, text = "Config", command=self.create_noc).pack(side=TOP) - - Label(self.noc_config_frame, height=1).pack() - Checkbutton(self.noc_config_frame, text="Monitor DDR bandwidth", variable=self.noc.monitor_ddr, anchor=W, width=20).pack() - Checkbutton(self.noc_config_frame, text="Monitor memory access", variable=self.noc.monitor_mem, anchor=W, width=20).pack() - Checkbutton(self.noc_config_frame, text="Monitor injection rate", variable=self.noc.monitor_inj, anchor=W, width=20).pack() - Checkbutton(self.noc_config_frame, text="Monitor router ports", variable=self.noc.monitor_routers, anchor=W, width=20).pack() - self.monitor_acc_selection = Checkbutton(self.noc_config_frame, text="Monitor accelerator status", variable=self.noc.monitor_accelerators, anchor=W, width=20) - self.monitor_acc_selection.pack() - Checkbutton(self.noc_config_frame, text="Monitor L2 Hit/Miss", variable=self.noc.monitor_l2, anchor=W, width=20).pack() - Checkbutton(self.noc_config_frame, text="Monitor LLC Hit/Miss", variable=self.noc.monitor_llc, anchor=W, width=20).pack() - self.monitor_dvfs_selection = Checkbutton(self.noc_config_frame, text="Monitor DVFS", variable=self.noc.monitor_dvfs, width=20, anchor=W) - self.monitor_dvfs_selection.pack() - - - #statistics - Label(self.noc_config_frame, height=1).pack() - self.TOT_CPU = Label(self.noc_config_frame, anchor=W, width=20) - self.TOT_MEM = Label(self.noc_config_frame, anchor=W, width=25) - self.TOT_SLM = Label(self.noc_config_frame, anchor=W, width=25) - self.TOT_SLMDDR = Label(self.noc_config_frame, anchor=W, width=25) - self.TOT_MISC = Label(self.noc_config_frame, anchor=W, width=20) - self.TOT_ACC = Label(self.noc_config_frame, anchor=W, width=20) - self.TOT_IVR = Label(self.noc_config_frame, anchor=W, width=20) - self.TOT_CLKBUF = Label(self.noc_config_frame, anchor=W, width=20) - self.TOT_CPU.pack(side=TOP, fill=BOTH) - self.TOT_MEM.pack(side=TOP, fill=BOTH) - self.TOT_SLM.pack(side=TOP, fill=BOTH) - self.TOT_SLMDDR.pack(side=TOP, fill=BOTH) - self.TOT_MISC.pack(side=TOP, fill=BOTH) - self.TOT_ACC.pack(side=TOP, fill=BOTH) - Label(self.noc_config_frame, height=1).pack() - self.TOT_IVR.pack(side=TOP, fill=BOTH) - Label(self.noc_config_frame, height=1).pack() - self.TOT_CLKBUF.pack(side=TOP, fill=BOTH) - - Label(self.noc_config_frame, height=1).pack() - - self.vf_frame = Frame(self.noc_config_frame) - self.vf_frame.pack(side=TOP, fill=BOTH) - Label(self.vf_frame, anchor=W, width=10, text=" VF points: ").pack(side=LEFT) - self.vf_points_entry = Entry(self.vf_frame, width=3) - self.vf_points_entry.pack(side=LEFT) - self.vf_points_entry.delete(0, END) - self.vf_points_entry.insert(0, "4") - - #frame for the tiles - Pmw.ScrolledFrame.__init__(self, bottom_frame, - labelpos = 'n', - label_text = 'NoC Tile Configuration', - label_font="TkDefaultFont 11 bold", - usehullsize = 1, - horizflex='expand', - hull_width = 1180, - hull_height = 520,) - self.noc_frame = self.interior() - - def update_msg(self): - self.done.config(state=DISABLED) - tot_tiles = self.noc.rows * self.noc.cols - tot_cpu = self.noc.get_cpu_num(self.soc) - if self.soc.cache_en.get(): - tot_full_coherent = self.noc.get_acc_l2_num(self.soc) + self.noc.get_cpu_num(self.soc) - tot_llc_coherent = self.noc.get_acc_num(self.soc) - else: - tot_full_coherent = 0 - tot_llc_coherent = 0 - tot_io = 0 - tot_clkbuf = self.noc.get_clkbuf_num(self.soc) - tot_mem = self.noc.get_mem_num(self.soc) - tot_slm = self.noc.get_slm_num(self.soc) - tot_slm_size = tot_slm * self.soc.slm_kbytes.get() - tot_slmddr = self.noc.get_slmddr_num(self.soc) - tot_acc = self.noc.get_acc_num(self.soc) - regions = self.noc.get_clk_regions() - acc_impl_valid = self.noc.get_acc_impl_valid(self.soc) - for y in range(0, self.noc.rows): - for x in range(0, self.noc.cols): - tile = self.noc.topology[y][x] - selection = tile.ip_type.get() - if self.soc.IPs.MISC.count(selection): - tot_io += 1 - #update statistics - self.TOT_CPU.config(text=" Num CPUs: " + str(tot_cpu)) - self.TOT_MEM.config(text=" Num memory controllers: " + str(tot_mem)) - self.TOT_SLM.config(text=" Num local memory tiles using on-chip memory: " + str(tot_slm)) - self.TOT_SLMDDR.config(text=" Num local memory tiles using off-chip DDR memory: " + str(tot_slmddr)) - self.TOT_MISC.config(text=" Num I/O tiles: " + str(tot_io)) - self.TOT_ACC.config(text=" Num accelerators: " + str(tot_acc)) - self.TOT_IVR.config(text=" Num CLK regions: " + str(len(regions))) - self.TOT_CLKBUF.config(text=" Num CLKBUF: " + str(tot_clkbuf)) - clkbuf_ok = True - if tot_clkbuf <= 9: - self.TOT_CLKBUF.config(fg="black") - else: - clkbuf_ok = False - self.TOT_CLKBUF.config(fg="red") - - if self.soc.noc.get_acc_num(self.soc) > 0: - self.monitor_acc_selection.config(state=NORMAL) - else: - self.monitor_acc_selection.config(state=DISABLED) - self.noc.monitor_accelerators.set(0) - - if self.soc.noc.has_dvfs(): - self.monitor_dvfs_selection.config(state=NORMAL) - self.vf_points_entry.config(state=NORMAL) - else: - self.monitor_dvfs_selection.config(state=DISABLED) - self.vf_points_entry.config(state=DISABLED) - self.noc.monitor_dvfs.set(0) - - pll_string = "" - num_pll = [0 for x in range(self.noc.cols * self.noc.rows)] - num_components = [0 for x in range(self.noc.cols * self.noc.rows)] - for y in range(0, self.noc.rows): - for x in range(0, self.noc.cols): - tile = self.noc.topology[y][x] - selection = tile.ip_type.get() - if self.soc.IPs.EMPTY.count(selection) == 0: - num_components[tile.clk_region.get()] += 1 - if tile.has_pll.get() == 1: - num_pll[tile.clk_region.get()] += 1 - pll_ok = True - for x in range(len(regions)): - if num_pll[x] == 0 and x > 0 and num_components[x] > 0: - pll_ok = False - pll_string += "Region \"" + str(x) + "\" requires at least one PLL\n" - if num_pll[x] > 1 and x > 0: - pll_ok = False - pll_string += "Region \"" + str(x) + "\" cannot have more than one PLL\n" - - clk_region_skip = 0 - regions = self.noc.get_clk_regions() - regions = sorted(regions, key=int) - current_region = regions[0] - for r in regions: - if r > current_region + 1: - clk_region_skip = current_region + 1 - break - current_region = r - - #update message box - self.message.delete(0.0, END) - self.cpu_frame.set_cpu_specific_labels(self.soc) - - string = "" - if (tot_cpu > 0) and \ - (tot_cpu <= NCPU_MAX) and \ - (tot_mem > 0 or (tot_slm > 0 and (self.soc.cache_en.get() == 0) and self.soc.CPU_ARCH.get() == "ibex")) and \ - (tot_mem <= self.soc.nmem_max) and \ - (tot_mem != 3) and \ - (tot_slm <= NSLM_MAX) and \ - (tot_slm <= 1 or self.soc.slm_kbytes.get() >= 1024) and \ - (tot_acc <= NACC_MAX) and \ - (tot_io == 1 ) and \ - (pll_ok) and \ - (clkbuf_ok) and \ - (clk_region_skip == 0) and \ - (tot_tiles <= NTILE_MAX) and \ - (self.noc.cols <= 8 and self.noc.rows <= 8) and \ - (tot_full_coherent <= NFULL_COHERENT_MAX) and \ - (tot_llc_coherent <= NLLC_COHERENT_MAX) and \ - (not (self.soc.TECH == "virtexu" and tot_mem >= 2 and (self.noc.rows < 3 or self.noc.cols < 3))) and \ - (self.soc.cache_spandex.get() == 0 or self.soc.CPU_ARCH.get() == "ariane" or self.soc.cache_en.get() == 0) and \ - (tot_cpu == 1 or self.soc.cache_en.get()) and \ - (self.soc.llc_sets.get() < 8192 or self.soc.llc_ways.get() < 16 or tot_mem > 1) and \ - (self.soc.cache_en.get() != 1 or self.soc.cache_line_size.get() >= self.noc.coh_noc_width.get()) and \ - (self.soc.cache_en.get() != 1 or self.soc.cache_line_size.get() >= self.noc.dma_noc_width.get()) and \ - (self.soc.TECH != "asic" or self.soc.cache_line_size.get() >= self.soc.mem_link_width.get()) and \ - (self.soc.TECH != "asic" or self.noc.coh_noc_width.get() >= self.soc.mem_link_width.get()) and \ - (self.soc.TECH != "asic" or self.noc.dma_noc_width.get() >= self.soc.mem_link_width.get()) and \ - ((self.soc.cache_en.get() == 1) or (self.noc.coh_noc_width.get() == self.soc.ARCH_BITS)) and \ - (self.noc.coh_noc_width.get() >= self.soc.ARCH_BITS) and \ - (self.noc.dma_noc_width.get() >= self.soc.ARCH_BITS) and acc_impl_valid and \ - (self.soc.cache_line_size.get() == 128 or (self.soc.cache_spandex.get() == 0 and self.soc.cache_rtl.get() == 1)) and \ - (self.soc.jtag_en.get() == 0 or (self.noc.dma_noc_width.get() == 64 and self.noc.coh_noc_width.get() == 64)) and \ - ((self.soc.TECH != "asic" and self.soc.TECH != "inferred" and self.soc.ESP_EMU_TECH == "none") \ - or tot_mem == 0 or self.soc.cache_en.get() == 1): - # Spandex beta warning - if self.soc.cache_spandex.get() != 0 and self.soc.cache_en.get() == 1: - string += "*** Spandex support is still beta ***\n" - string += " The default HLS configuration is 512x4 L2 and 1024x8 LLC\n" - #if self.soc.TECH != "gf12" and self.soc.TECH != "virtexu" and self.soc.TECH != "virtexup": - if self.soc.TECH != "asic" and self.soc.TECH != "virtexu" and self.soc.TECH != "virtexup": - string += " Use a smaller implementation if not using a Virtex US/US+\n" - self.done.config(state=NORMAL) - else: - if (self.noc.cols > 8 or self.noc.rows > 8): - string += "Maximum number of rows and columns is 8.\n" - if (tot_cpu == 0): - string += "At least one CPU is required.\n" - if (tot_cpu > 1 and not self.soc.cache_en.get()): - string += "Caches are required for multicore SoCs.\n" - if (tot_io == 0): - string += "At least I/O tile is required.\n" - if (tot_cpu > NCPU_MAX): - new_err = "Maximum number of supported CPUs is " + str(NCPU_MAX) + ".\n" - string += new_err - if (tot_io > 1): - string += "Multiple I/O tiles are not supported.\n" - if (tot_mem < 1 and tot_slm < 1): - string += "There must be at least 1 memory tile or 1 SLM tile.\n" - if (tot_mem > self.soc.nmem_max): - string += "There must be no more than " + str(self.soc.nmem_max) + " memory tiles.\n" - if (tot_mem == 0 and (self.soc.CPU_ARCH.get() != "ibex")): - string += "SLM tiles can be used in place of memory tiles only with the lowRISC ibex core.\n" - if (tot_mem == 0 and (self.soc.cache_en.get() == 1)): - string += "There must be at least 1 memory tile to enable the ESP cache hierarchy.\n" - if (tot_mem == 3): - string += "Number of memory tiles must be a power of 2.\n" - if (tot_slm > NSLM_MAX): - string += "There must be no more than " + str(NSLM_MAX) + " SLM tiles.\n" - if (tot_slm > 1 and self.soc.slm_kbytes.get() < 1024): - string += "SLM size must be 1024 KB or more if placing more than one SLM tile.\n" - if (self.soc.llc_sets.get() >= 8192 and self.soc.llc_ways.get() >= 16 and tot_mem == 1): - string += "A 2MB LLC (8192 sets and 16 ways) requires multiple memory tiles.\n" - if (self.soc.TECH == "virtexu" and tot_mem >= 2 and (self.noc.rows < 3 or self.noc.cols < 3)): - string += "A 3x3 NoC or larger is recommended for multiple memory tiles for virtexu (profpga-xcvu440).\n" - if (tot_acc > NACC_MAX): - string += "There must no more than " + str(NACC_MAX) + " (can be relaxed).\n" - if (tot_tiles > NTILE_MAX): - string += "Maximum number of supported tiles is " + str(NTILE_MAX) + ".\n" - if (tot_full_coherent > NFULL_COHERENT_MAX): - string += "Maximum number of supported fully-coherent devices is " + str(NFULL_COHERENT_MAX) + ".\n" - if (tot_llc_coherent > NLLC_COHERENT_MAX): - string += "Maximum number of supported LLC-coherent devices is " + str(NLLC_COHERENT_MAX) + ".\n" - if (self.soc.cache_spandex.get() != 0 and self.soc.CPU_ARCH.get() != "ariane" and self.soc.cache_en.get() == 1): - string += "Spandex currently supports only RISC-V Ariane processor core.\n" - if (tot_clkbuf > 9): - string += "The FPGA board supports no more than 9 CLKBUF's.\n" - string += pll_string - if (clk_region_skip > 0): - string += "Clock-region IDs must be consecutive; skipping region " + str(clk_region_skip) +" intead.\n" - if (self.soc.cache_en.get() == 1 and self.soc.cache_line_size.get() < self.noc.coh_noc_width.get()): - string += "Cache line size must be greater than or equal to coherence NoC bitwidth.\n" - if (self.soc.cache_en.get() == 1 and self.soc.cache_line_size.get() < self.noc.dma_noc_width.get()): - string += "Cache line size must be greater than or equal to DMA NoC bitwidth.\n" - if (self.soc.TECH == "asic" and self.soc.cache_line_size.get() < self.soc.mem_link_width.get()): - string += "Cache line size must be greater than or equal to mem link bitwidth.\n" - if (self.soc.TECH == "asic" and self.noc.coh_noc_width.get() < self.soc.mem_link_width.get()): - string += "Coherence NoC bitwdith must be greater than or equal to mem link bitwidth.\n" - if (self.soc.TECH == "asic" and self.noc.dma_noc_width.get() < self.soc.mem_link_width.get()): - string += "DMA NoC bitwdith must be greater than or equal to mem link bitwidth.\n" - if (self.soc.cache_en.get() != 1) and (self.noc.coh_noc_width.get() > self.soc.ARCH_BITS): - string += "Caches must be enabled to support a coherence NoC width larger than the CPU architecture size.\n" - if (self.noc.coh_noc_width.get() < self.soc.ARCH_BITS): - string += "Coherence NoC width must be greater than or equal to the CPU architecture size.\n" - if (self.noc.dma_noc_width.get() < self.soc.ARCH_BITS): - string += "DMA NoC width must be greater than or equal to the CPU architecture size.\n" - if (not acc_impl_valid): - string += "All accelerators must have a selected implementation.\n" - if (self.soc.cache_line_size.get() > 128 and (self.soc.cache_spandex.get() == 1 or self.soc.cache_rtl.get() == 0)): - string += "Only ESP RTL caches support cache line size greater than 128 bits.\n" - if (self.soc.jtag_en.get() == 1 and (self.noc.dma_noc_width.get() != 64 or self.noc.coh_noc_width.get() != 64)): - string += "JTAG is only supported for 64-bit coherence and DMA NoC planes.\n" - if ((self.soc.TECH == "asic" or self.soc.TECH == "inferred" or self.soc.ESP_EMU_TECH != "none") \ - and tot_mem >= 1 and self.soc.cache_en.get() == 0): - string += "Caches must be enabled for ASIC design with memory tiles.\n" - - # Update message box - self.message.insert(0.0, string) - - def set_message(self, message, cfg_frame, cpu_frame, done): - self.message = message - self.cfg_frame = cfg_frame - self.cpu_frame = cpu_frame - self.done = done - - def create_noc(self): - self.pack(side=LEFT,fill=BOTH,expand=YES) - if isInt(self.ROWS.get()) == False or isInt(self.COLS.get()) == False: - return - #destroy current topology - if len(self.row_frames) > 0: - for x in range(0, len(self.row_frames)): - self.row_frames[x].destroy() - self.noc_tiles = [] - self.row_frames = [] - #create new topology - self.noc.create_topology(self.noc_frame, int(self.ROWS.get()), int(self.COLS.get())) - for y in range(0, int(self.ROWS.get())): - self.row_frames.append(Frame(self.noc_frame, borderwidth=2, relief=RIDGE)) - self.row_frames[y].pack(side=TOP) - self.noc_tiles.append([]) - for x in range(0, int(self.COLS.get())): - self.noc_tiles[y].append(Frame(self.row_frames[y], borderwidth=2, relief=RIDGE)) - self.noc_tiles[y][x].pack(side=LEFT) - Label(self.noc_tiles[y][x], text="("+str(y)+","+str(x)+")").pack() - self.create_tile(self.noc_tiles[y][x], self.noc.topology[y][x]) - if len(self.noc.topology[y][x].ip_type.get()) == 0: - self.noc.topology[y][x].ip_type.set("empty") # default value - #set call-backs and default value - for y in range(0, int(self.ROWS.get())): - for x in range(0, int(self.COLS.get())): - tile = self.noc.topology[y][x] - tile.ip_type.trace('w', self.changed) - tile.clk_region.trace('w', self.changed) - self.soc.IPs = Components(self.soc.TECH, self.noc.dma_noc_width.get(), self.soc.CPU_ARCH.get()) - self.soc.update_list_of_ips() - self.changed() + current_nocx = 0 + current_nocy = 0 + + noc_tiles = [] + row_frames = [] + + def changed(self, *args): + if isInt(self.ROWS.get()) == False or isInt(self.COLS.get()) == False: + return + for y in range(0, int(self.ROWS.get())): + for x in range(0, int(self.COLS.get())): + self.noc.topology[y][x].update_tile(self.soc) + self.update_msg() + + def update_frame(self): + if self.noc.cols > 0 and self.noc.rows > 0: + self.COLS.insert(0, str(self.noc.cols)) + self.ROWS.insert(0, str(self.noc.rows)) + self.create_noc() + self.changed() + + def create_tile(self, frame, tile): + # computing the width of the widget + list_items = self.soc.list_of_ips + width = 0 + for x in range(0, len(list_items)): + if len(list_items[x]) > width: + width = len(list_items[x]) + # creating tile + select_frame = Frame(frame) + select_frame.pack(side=TOP) + + display_frame = Frame(frame) + display_frame.pack(side=TOP) + + config_frame = Frame(frame) + config_frame.pack(side=TOP) + + tile.ip_list = Pmw.OptionMenu( + select_frame, + menubutton_font="TkDefaultFont 8", + menubutton_textvariable=tile.ip_type, + menubutton_width=width + 2, + items=list_items) + tile.ip_list.pack(side=LEFT) + tile.point_label = Label(select_frame, text="Impl.: ", width=5) + tile.point_select = Pmw.OptionMenu( + select_frame, + menubutton_font="TkDefaultFont 8", + menubutton_textvariable=tile.point, + menubutton_width=10, + items=[]) + + tile.label = Label(display_frame, text=tile.ip_type.get()) + tile.label.config(height=4, bg='white', width=width + 25) + tile.label.pack() + + tile.has_l2_selection = Checkbutton( + config_frame, + text="Has cache", + variable=tile.has_l2, + onvalue=1, + offvalue=0, + command=self.changed) + tile.has_l2_selection.grid(row=1, column=1) + tile.has_ddr_selection = Checkbutton( + config_frame, + text="Has DDR", + variable=tile.has_ddr, + onvalue=1, + offvalue=0, + command=self.changed) + tile.has_ddr_selection.grid(row=1, column=4) + Separator( + config_frame, + orient="horizontal").grid( + row=2, + column=1, + columnspan=4, + ipadx=140, + pady=3) + + tile.label.bind( + "", + lambda event: tile.power_window( + event, + self.soc, + self)) + Label( + config_frame, + text="Clk Reg: ", + justify=LEFT, + anchor="w").grid( + sticky=W, + row=3, + column=1) + tile.clk_reg_selection = Spinbox( + config_frame, + state='readonly', + from_=0, + to=len( + self.soc.noc.get_clk_regions()), + wrap=True, + textvariable=tile.clk_region, + width=3, + justify=RIGHT) + tile.clk_reg_selection.grid(sticky=E, row=3, column=1) + tile.pll_selection = Checkbutton( + config_frame, + text="Has PLL", + variable=tile.has_pll, + onvalue=1, + offvalue=0, + command=self.changed) + tile.pll_selection.grid(row=3, column=2) + tile.clkbuf_selection = Checkbutton( + config_frame, + text="CLK BUF", + variable=tile.has_clkbuf, + onvalue=1, + offvalue=0, + command=self.changed) + tile.clkbuf_selection.grid(row=3, column=3) + try: + int(self.vf_points_entry.get()) + tile.load_characterization( + self.soc, int(self.vf_points_entry.get())) + except BaseException: + pass + + def __init__(self, soc, bottom_frame): + self.soc = soc + self.noc = self.soc.noc + # configuration frame + self.noc_config_frame = Frame(bottom_frame) + Label( + self.noc_config_frame, + text="NoC configuration", + font="TkDefaultFont 11 bold").pack( + side=TOP) + self.config_noc_frame = Frame(self.noc_config_frame) + self.config_noc_frame.pack(side=TOP) + Label(self.config_noc_frame, text="Rows: ").pack(side=LEFT) + self.ROWS = Entry(self.config_noc_frame, width=3) + self.ROWS.pack(side=LEFT) + Label(self.config_noc_frame, text="Cols: ").pack(side=LEFT) + self.COLS = Entry(self.config_noc_frame, width=3) + self.COLS.pack(side=LEFT) + + noc_width_choices = ["32", "64", "128", "256", "512", "1024"] + Label( + self.noc_config_frame, + text="Coherence NoC Planes (1,2,3) Bitwidth: ", + height=1).pack() + OptionMenu( + self.noc_config_frame, + self.noc.coh_noc_width, + *noc_width_choices).pack() + Label( + self.noc_config_frame, + text="DMA NoC Planes (4,6) Bitwidth: ", + height=1).pack() + OptionMenu( + self.noc_config_frame, + self.noc.dma_noc_width, + *noc_width_choices).pack() + Label( + self.noc_config_frame, + text="MMIO/Irq NoC Plane (5) Bitwidth is always 32", + height=1).pack( + side=TOP) + Button( + self.noc_config_frame, + text="Config", + command=self.create_noc).pack( + side=TOP) + + Label(self.noc_config_frame, height=1).pack() + Checkbutton( + self.noc_config_frame, + text="Monitor DDR bandwidth", + variable=self.noc.monitor_ddr, + anchor=W, + width=20).pack() + Checkbutton( + self.noc_config_frame, + text="Monitor memory access", + variable=self.noc.monitor_mem, + anchor=W, + width=20).pack() + Checkbutton( + self.noc_config_frame, + text="Monitor injection rate", + variable=self.noc.monitor_inj, + anchor=W, + width=20).pack() + Checkbutton( + self.noc_config_frame, + text="Monitor router ports", + variable=self.noc.monitor_routers, + anchor=W, + width=20).pack() + self.monitor_acc_selection = Checkbutton( + self.noc_config_frame, + text="Monitor accelerator status", + variable=self.noc.monitor_accelerators, + anchor=W, + width=20) + self.monitor_acc_selection.pack() + Checkbutton( + self.noc_config_frame, + text="Monitor L2 Hit/Miss", + variable=self.noc.monitor_l2, + anchor=W, + width=20).pack() + Checkbutton( + self.noc_config_frame, + text="Monitor LLC Hit/Miss", + variable=self.noc.monitor_llc, + anchor=W, + width=20).pack() + self.monitor_dvfs_selection = Checkbutton( + self.noc_config_frame, + text="Monitor DVFS", + variable=self.noc.monitor_dvfs, + width=20, + anchor=W) + self.monitor_dvfs_selection.pack() + + # statistics + Label(self.noc_config_frame, height=1).pack() + self.TOT_CPU = Label(self.noc_config_frame, anchor=W, width=20) + self.TOT_MEM = Label(self.noc_config_frame, anchor=W, width=25) + self.TOT_SLM = Label(self.noc_config_frame, anchor=W, width=25) + self.TOT_SLMDDR = Label(self.noc_config_frame, anchor=W, width=25) + self.TOT_MISC = Label(self.noc_config_frame, anchor=W, width=20) + self.TOT_ACC = Label(self.noc_config_frame, anchor=W, width=20) + self.TOT_IVR = Label(self.noc_config_frame, anchor=W, width=20) + self.TOT_CLKBUF = Label(self.noc_config_frame, anchor=W, width=20) + self.TOT_CPU.pack(side=TOP, fill=BOTH) + self.TOT_MEM.pack(side=TOP, fill=BOTH) + self.TOT_SLM.pack(side=TOP, fill=BOTH) + self.TOT_SLMDDR.pack(side=TOP, fill=BOTH) + self.TOT_MISC.pack(side=TOP, fill=BOTH) + self.TOT_ACC.pack(side=TOP, fill=BOTH) + Label(self.noc_config_frame, height=1).pack() + self.TOT_IVR.pack(side=TOP, fill=BOTH) + Label(self.noc_config_frame, height=1).pack() + self.TOT_CLKBUF.pack(side=TOP, fill=BOTH) + + Label(self.noc_config_frame, height=1).pack() + + self.vf_frame = Frame(self.noc_config_frame) + self.vf_frame.pack(side=TOP, fill=BOTH) + Label( + self.vf_frame, + anchor=W, + width=10, + text=" VF points: ").pack( + side=LEFT) + self.vf_points_entry = Entry(self.vf_frame, width=3) + self.vf_points_entry.pack(side=LEFT) + self.vf_points_entry.delete(0, END) + self.vf_points_entry.insert(0, "4") + + # frame for the tiles + Pmw.ScrolledFrame.__init__(self, bottom_frame, + labelpos='n', + label_text='NoC Tile Configuration', + label_font="TkDefaultFont 11 bold", + usehullsize=1, + horizflex='expand', + hull_width=1180, + hull_height=520,) + self.noc_frame = self.interior() + + def update_msg(self): + self.done.config(state=DISABLED) + tot_tiles = self.noc.rows * self.noc.cols + tot_cpu = self.noc.get_cpu_num(self.soc) + if self.soc.cache_en.get(): + tot_full_coherent = self.noc.get_acc_l2_num( + self.soc) + self.noc.get_cpu_num(self.soc) + tot_llc_coherent = self.noc.get_acc_num(self.soc) + else: + tot_full_coherent = 0 + tot_llc_coherent = 0 + tot_io = 0 + tot_clkbuf = self.noc.get_clkbuf_num(self.soc) + tot_mem = self.noc.get_mem_num(self.soc) + tot_slm = self.noc.get_slm_num(self.soc) + tot_slm_size = tot_slm * self.soc.slm_kbytes.get() + tot_slmddr = self.noc.get_slmddr_num(self.soc) + tot_acc = self.noc.get_acc_num(self.soc) + regions = self.noc.get_clk_regions() + acc_impl_valid = self.noc.get_acc_impl_valid(self.soc) + for y in range(0, self.noc.rows): + for x in range(0, self.noc.cols): + tile = self.noc.topology[y][x] + selection = tile.ip_type.get() + if self.soc.IPs.MISC.count(selection): + tot_io += 1 + # update statistics + self.TOT_CPU.config(text=" Num CPUs: " + str(tot_cpu)) + self.TOT_MEM.config(text=" Num memory controllers: " + str(tot_mem)) + self.TOT_SLM.config( + text=" Num local memory tiles using on-chip memory: " + + str(tot_slm)) + self.TOT_SLMDDR.config( + text=" Num local memory tiles using off-chip DDR memory: " + + str(tot_slmddr)) + self.TOT_MISC.config(text=" Num I/O tiles: " + str(tot_io)) + self.TOT_ACC.config(text=" Num accelerators: " + str(tot_acc)) + self.TOT_IVR.config(text=" Num CLK regions: " + str(len(regions))) + self.TOT_CLKBUF.config(text=" Num CLKBUF: " + str(tot_clkbuf)) + clkbuf_ok = True + if tot_clkbuf <= 9: + self.TOT_CLKBUF.config(fg="black") + else: + clkbuf_ok = False + self.TOT_CLKBUF.config(fg="red") + + if self.soc.noc.get_acc_num(self.soc) > 0: + self.monitor_acc_selection.config(state=NORMAL) + else: + self.monitor_acc_selection.config(state=DISABLED) + self.noc.monitor_accelerators.set(0) + + if self.soc.noc.has_dvfs(): + self.monitor_dvfs_selection.config(state=NORMAL) + self.vf_points_entry.config(state=NORMAL) + else: + self.monitor_dvfs_selection.config(state=DISABLED) + self.vf_points_entry.config(state=DISABLED) + self.noc.monitor_dvfs.set(0) + + pll_string = "" + num_pll = [0 for x in range(self.noc.cols * self.noc.rows)] + num_components = [0 for x in range(self.noc.cols * self.noc.rows)] + for y in range(0, self.noc.rows): + for x in range(0, self.noc.cols): + tile = self.noc.topology[y][x] + selection = tile.ip_type.get() + if self.soc.IPs.EMPTY.count(selection) == 0: + num_components[tile.clk_region.get()] += 1 + if tile.has_pll.get() == 1: + num_pll[tile.clk_region.get()] += 1 + pll_ok = True + for x in range(len(regions)): + if num_pll[x] == 0 and x > 0 and num_components[x] > 0: + pll_ok = False + pll_string += "Region \"" + \ + str(x) + "\" requires at least one PLL\n" + if num_pll[x] > 1 and x > 0: + pll_ok = False + pll_string += "Region \"" + \ + str(x) + "\" cannot have more than one PLL\n" + + clk_region_skip = 0 + regions = self.noc.get_clk_regions() + regions = sorted(regions, key=int) + current_region = regions[0] + for r in regions: + if r > current_region + 1: + clk_region_skip = current_region + 1 + break + current_region = r + + # update message box + self.message.delete(0.0, END) + self.cpu_frame.set_cpu_specific_labels(self.soc) + + string = "" + if (tot_cpu > 0) and \ + (tot_cpu <= NCPU_MAX) and \ + (tot_mem > 0 or (tot_slm > 0 and (self.soc.cache_en.get() == 0) and self.soc.CPU_ARCH.get() == "ibex")) and \ + (tot_mem <= self.soc.nmem_max) and \ + (tot_mem != 3) and \ + (tot_slm <= NSLM_MAX) and \ + (tot_slm <= 1 or self.soc.slm_kbytes.get() >= 1024) and \ + (tot_acc <= NACC_MAX) and \ + (tot_io == 1) and \ + (pll_ok) and \ + (clkbuf_ok) and \ + (clk_region_skip == 0) and \ + (tot_tiles <= NTILE_MAX) and \ + (self.noc.cols <= 8 and self.noc.rows <= 8) and \ + (tot_full_coherent <= NFULL_COHERENT_MAX) and \ + (tot_llc_coherent <= NLLC_COHERENT_MAX) and \ + (not (self.soc.TECH == "virtexu" and tot_mem >= 2 and (self.noc.rows < 3 or self.noc.cols < 3))) and \ + (self.soc.cache_spandex.get() == 0 or self.soc.CPU_ARCH.get() == "ariane" or self.soc.cache_en.get() == 0) and \ + (tot_cpu == 1 or self.soc.cache_en.get()) and \ + (self.soc.llc_sets.get() < 8192 or self.soc.llc_ways.get() < 16 or tot_mem > 1) and \ + (self.soc.cache_en.get() != 1 or self.soc.cache_line_size.get() >= self.noc.coh_noc_width.get()) and \ + (self.soc.cache_en.get() != 1 or self.soc.cache_line_size.get() >= self.noc.dma_noc_width.get()) and \ + (self.soc.TECH != "asic" or self.soc.cache_line_size.get() >= self.soc.mem_link_width.get()) and \ + (self.soc.TECH != "asic" or self.noc.coh_noc_width.get() >= self.soc.mem_link_width.get()) and \ + (self.soc.TECH != "asic" or self.noc.dma_noc_width.get() >= self.soc.mem_link_width.get()) and \ + ((self.soc.cache_en.get() == 1) or (self.noc.coh_noc_width.get() == self.soc.ARCH_BITS)) and \ + (self.noc.coh_noc_width.get() >= self.soc.ARCH_BITS) and \ + (self.noc.dma_noc_width.get() >= self.soc.ARCH_BITS) and acc_impl_valid and \ + (self.soc.cache_line_size.get() == 128 or (self.soc.cache_spandex.get() == 0 and self.soc.cache_rtl.get() == 1)) and \ + (self.soc.jtag_en.get() == 0 or (self.noc.dma_noc_width.get() == 64 and self.noc.coh_noc_width.get() == 64)) and \ + ((self.soc.TECH != "asic" and self.soc.TECH != "inferred" and self.soc.ESP_EMU_TECH == "none") + or tot_mem == 0 or self.soc.cache_en.get() == 1): + # Spandex beta warning + if self.soc.cache_spandex.get() != 0 and self.soc.cache_en.get() == 1: + string += "*** Spandex support is still beta ***\n" + string += " The default HLS configuration is 512x4 L2 and 1024x8 LLC\n" + # if self.soc.TECH != "gf12" and self.soc.TECH != "virtexu" and + # self.soc.TECH != "virtexup": + if self.soc.TECH != "asic" and self.soc.TECH != "virtexu" and self.soc.TECH != "virtexup": + string += " Use a smaller implementation if not using a Virtex US/US+\n" + self.done.config(state=NORMAL) + else: + if (self.noc.cols > 8 or self.noc.rows > 8): + string += "Maximum number of rows and columns is 8.\n" + if (tot_cpu == 0): + string += "At least one CPU is required.\n" + if (tot_cpu > 1 and not self.soc.cache_en.get()): + string += "Caches are required for multicore SoCs.\n" + if (tot_io == 0): + string += "At least I/O tile is required.\n" + if (tot_cpu > NCPU_MAX): + new_err = "Maximum number of supported CPUs is " + \ + str(NCPU_MAX) + ".\n" + string += new_err + if (tot_io > 1): + string += "Multiple I/O tiles are not supported.\n" + if (tot_mem < 1 and tot_slm < 1): + string += "There must be at least 1 memory tile or 1 SLM tile.\n" + if (tot_mem > self.soc.nmem_max): + string += "There must be no more than " + \ + str(self.soc.nmem_max) + " memory tiles.\n" + if (tot_mem == 0 and (self.soc.CPU_ARCH.get() != "ibex")): + string += "SLM tiles can be used in place of memory tiles only with the lowRISC ibex core.\n" + if (tot_mem == 0 and (self.soc.cache_en.get() == 1)): + string += "There must be at least 1 memory tile to enable the ESP cache hierarchy.\n" + if (tot_mem == 3): + string += "Number of memory tiles must be a power of 2.\n" + if (tot_slm > NSLM_MAX): + string += "There must be no more than " + \ + str(NSLM_MAX) + " SLM tiles.\n" + if (tot_slm > 1 and self.soc.slm_kbytes.get() < 1024): + string += "SLM size must be 1024 KB or more if placing more than one SLM tile.\n" + if (self.soc.llc_sets.get() >= + 8192 and self.soc.llc_ways.get() >= 16 and tot_mem == 1): + string += "A 2MB LLC (8192 sets and 16 ways) requires multiple memory tiles.\n" + if (self.soc.TECH == "virtexu" and tot_mem >= + 2 and (self.noc.rows < 3 or self.noc.cols < 3)): + string += "A 3x3 NoC or larger is recommended for multiple memory tiles for virtexu (profpga-xcvu440).\n" + if (tot_acc > NACC_MAX): + string += "There must no more than " + \ + str(NACC_MAX) + " (can be relaxed).\n" + if (tot_tiles > NTILE_MAX): + string += "Maximum number of supported tiles is " + \ + str(NTILE_MAX) + ".\n" + if (tot_full_coherent > NFULL_COHERENT_MAX): + string += "Maximum number of supported fully-coherent devices is " + \ + str(NFULL_COHERENT_MAX) + ".\n" + if (tot_llc_coherent > NLLC_COHERENT_MAX): + string += "Maximum number of supported LLC-coherent devices is " + \ + str(NLLC_COHERENT_MAX) + ".\n" + if (self.soc.cache_spandex.get() != 0 and self.soc.CPU_ARCH.get() + != "ariane" and self.soc.cache_en.get() == 1): + string += "Spandex currently supports only RISC-V Ariane processor core.\n" + if (tot_clkbuf > 9): + string += "The FPGA board supports no more than 9 CLKBUF's.\n" + string += pll_string + if (clk_region_skip > 0): + string += "Clock-region IDs must be consecutive; skipping region " + \ + str(clk_region_skip) + " intead.\n" + if (self.soc.cache_en.get() == 1 and self.soc.cache_line_size.get() + < self.noc.coh_noc_width.get()): + string += "Cache line size must be greater than or equal to coherence NoC bitwidth.\n" + if (self.soc.cache_en.get() == 1 and self.soc.cache_line_size.get() + < self.noc.dma_noc_width.get()): + string += "Cache line size must be greater than or equal to DMA NoC bitwidth.\n" + if (self.soc.TECH == "asic" and self.soc.cache_line_size.get() + < self.soc.mem_link_width.get()): + string += "Cache line size must be greater than or equal to mem link bitwidth.\n" + if (self.soc.TECH == "asic" and self.noc.coh_noc_width.get() + < self.soc.mem_link_width.get()): + string += "Coherence NoC bitwdith must be greater than or equal to mem link bitwidth.\n" + if (self.soc.TECH == "asic" and self.noc.dma_noc_width.get() + < self.soc.mem_link_width.get()): + string += "DMA NoC bitwdith must be greater than or equal to mem link bitwidth.\n" + if (self.soc.cache_en.get() != 1) and ( + self.noc.coh_noc_width.get() > self.soc.ARCH_BITS): + string += "Caches must be enabled to support a coherence NoC width larger than the CPU architecture size.\n" + if (self.noc.coh_noc_width.get() < self.soc.ARCH_BITS): + string += "Coherence NoC width must be greater than or equal to the CPU architecture size.\n" + if (self.noc.dma_noc_width.get() < self.soc.ARCH_BITS): + string += "DMA NoC width must be greater than or equal to the CPU architecture size.\n" + if (not acc_impl_valid): + string += "All accelerators must have a selected implementation.\n" + if (self.soc.cache_line_size.get() > 128 and ( + self.soc.cache_spandex.get() == 1 or self.soc.cache_rtl.get() == 0)): + string += "Only ESP RTL caches support cache line size greater than 128 bits.\n" + if (self.soc.jtag_en.get() == 1 and ( + self.noc.dma_noc_width.get() != 64 or self.noc.coh_noc_width.get() != 64)): + string += "JTAG is only supported for 64-bit coherence and DMA NoC planes.\n" + if ((self.soc.TECH == "asic" or self.soc.TECH == "inferred" or self.soc.ESP_EMU_TECH != + "none") and tot_mem >= 1 and self.soc.cache_en.get() == 0): + string += "Caches must be enabled for ASIC design with memory tiles.\n" + + # Update message box + self.message.insert(0.0, string) + + def set_message(self, message, cfg_frame, cpu_frame, done): + self.message = message + self.cfg_frame = cfg_frame + self.cpu_frame = cpu_frame + self.done = done + + def create_noc(self): + self.pack(side=LEFT, fill=BOTH, expand=YES) + if isInt(self.ROWS.get()) == False or isInt(self.COLS.get()) == False: + return + # destroy current topology + if len(self.row_frames) > 0: + for x in range(0, len(self.row_frames)): + self.row_frames[x].destroy() + self.noc_tiles = [] + self.row_frames = [] + # create new topology + self.noc.create_topology( + self.noc_frame, int( + self.ROWS.get()), int( + self.COLS.get())) + for y in range(0, int(self.ROWS.get())): + self.row_frames.append( + Frame( + self.noc_frame, + borderwidth=2, + relief=RIDGE)) + self.row_frames[y].pack(side=TOP) + self.noc_tiles.append([]) + for x in range(0, int(self.COLS.get())): + self.noc_tiles[y].append( + Frame( + self.row_frames[y], + borderwidth=2, + relief=RIDGE)) + self.noc_tiles[y][x].pack(side=LEFT) + Label( + self.noc_tiles[y][x], + text="(" + str(y) + "," + str(x) + ")").pack() + self.create_tile(self.noc_tiles[y][x], self.noc.topology[y][x]) + if len(self.noc.topology[y][x].ip_type.get()) == 0: + self.noc.topology[y][x].ip_type.set( + "empty") # default value + # set call-backs and default value + for y in range(0, int(self.ROWS.get())): + for x in range(0, int(self.COLS.get())): + tile = self.noc.topology[y][x] + tile.ip_type.trace('w', self.changed) + tile.clk_region.trace('w', self.changed) + self.soc.IPs = Components( + self.soc.TECH, + self.noc.dma_noc_width.get(), + self.soc.CPU_ARCH.get()) + self.soc.update_list_of_ips() + self.changed() diff --git a/tools/socketgen/socketgen.py b/tools/socketgen/socketgen.py index a30af08750..0111c74238 100755 --- a/tools/socketgen/socketgen.py +++ b/tools/socketgen/socketgen.py @@ -17,109 +17,119 @@ import re import math + def get_immediate_subdirectories(a_dir): - return [name for name in os.listdir(a_dir) - if os.path.isdir(os.path.join(a_dir, name))] + return [name for name in os.listdir(a_dir) + if os.path.isdir(os.path.join(a_dir, name))] + def print_usage(): - print(sys.argv) - print("Usage : ./socketgen.py ") - print("") - print(" : Bit-width for the DMA channel (32, 64)") - print("") - print(" : Target processor (ariane, ibex, leon3)") - print("") - print(" : Cache line size in bits (128, 256, 512, 1024)") - print("") - print(" : NoC width. Must be >= arch_bits and <= cache_line size. (32, 64, 128, 256, 512, 1024)") - print("") - print(" : Path to accelerators' RTL for the target technology") - print("") - print(" : Path to file templates") - print("") - print(" : Output path") - print("") + print(sys.argv) + print("Usage : ./socketgen.py ") + print("") + print(" : Bit-width for the DMA channel (32, 64)") + print("") + print(" : Target processor (ariane, ibex, leon3)") + print("") + print(" : Cache line size in bits (128, 256, 512, 1024)") + print("") + print(" : NoC width. Must be >= arch_bits and <= cache_line size. (32, 64, 128, 256, 512, 1024)") + print("") + print(" : Path to accelerators' RTL for the target technology") + print("") + print(" : Path to file templates") + print("") + print(" : Output path") + print("") # ### Data structures # # + class Parameter(): - def __init__(self): - self.name = "" - self.desc = "" - self.size = 0 - self.reg = 0 - self.readonly = False - self.value = 0 + def __init__(self): + self.name = "" + self.desc = "" + self.size = 0 + self.reg = 0 + self.readonly = False + self.value = 0 + + def __str__(self): + return " " + self.name + ", " + self.desc + ", " + \ + str(self.size) + "bits, register " + str(self.reg) + ", def. value " + str(self.value) + "\n" - def __str__(self): - return " " + self.name + ", " + self.desc + ", " + str(self.size) + "bits, register " + str(self.reg) + ", def. value " + str(self.value) + "\n" class Implementation(): - def __init__(self): - self.name = "" - self.arch_bits = 0 - self.cache_line_size = 0 - self.datatype = "" + def __init__(self): + self.name = "" + self.arch_bits = 0 + self.cache_line_size = 0 + self.datatype = "" + + def __str__(self): + return self.name - def __str__(self): - return self.name class Accelerator(): - def __init__(self): - self.name = "" - self.hlscfg = [] - self.desc = "" - self.data = 0 - self.device_id = "" - self.hls_tool = "" - self.param = [] - - def __str__(self): - params = "\n {\n" - for i in range(0, len(self.param)): - params = params + str(self.param[i]) - params = params + " }" - cfgs = "[" - for i in range(0, len(self.hlscfg) - 1): - cfgs = cfgs + str(self.hlscfg[i]) + " | " - cfgs = cfgs + str(self.hlscfg[len(self.hlscfg) - 1]) - cfgs = cfgs + "]" - return " " + self.name + "_" + cfgs + ": " + self.desc + ", " + str(self.data) + "MB, ID " + self.device_id + str(params) + def __init__(self): + self.name = "" + self.hlscfg = [] + self.desc = "" + self.data = 0 + self.device_id = "" + self.hls_tool = "" + self.param = [] + + def __str__(self): + params = "\n {\n" + for i in range(0, len(self.param)): + params = params + str(self.param[i]) + params = params + " }" + cfgs = "[" + for i in range(0, len(self.hlscfg) - 1): + cfgs = cfgs + str(self.hlscfg[i]) + " | " + cfgs = cfgs + str(self.hlscfg[len(self.hlscfg) - 1]) + cfgs = cfgs + "]" + return " " + self.name + "_" + cfgs + ": " + self.desc + \ + ", " + str(self.data) + "MB, ID " + self.device_id + str(params) + class AxiAccelerator(): - def __init__(self): - self.name = "" - self.desc = "" - self.device_id = "" - self.clocks = [ ] - self.resets = [ ] - self.interrupt = "" - self.axi_prefix = "" - self.apb_prefix = "" - self.addr_widh = 32 - self.id_width = 8 - self.user_width = 0 - - def __str__(self): - return " " + self.name + ": " + self.desc + ", ID " + self.device_id + def __init__(self): + self.name = "" + self.desc = "" + self.device_id = "" + self.clocks = [] + self.resets = [] + self.interrupt = "" + self.axi_prefix = "" + self.apb_prefix = "" + self.addr_widh = 32 + self.id_width = 8 + self.user_width = 0 + + def __str__(self): + return " " + self.name + ": " + self.desc + ", ID " + self.device_id + class Component(): - def __init__(self): - self.name = "" - self.hlscfg = [] - - def __str__(self): - cfgs = "[" - for i in range(0, len(self.hlscfg) - 1): - cfgs = cfgs + str(self.hlscfg[i]) + " | " - cfgs = cfgs + str(self.hlscfg[len(self.hlscfg) - 1]) - cfgs = cfgs + "]" - return " " + self.name + "_" + cfgs + def __init__(self): + self.name = "" + self.hlscfg = [] + + def __str__(self): + cfgs = "[" + for i in range(0, len(self.hlscfg) - 1): + cfgs = cfgs + str(self.hlscfg[i]) + " | " + cfgs = cfgs + str(self.hlscfg[len(self.hlscfg) - 1]) + cfgs = cfgs + "]" + return " " + self.name + "_" + cfgs + # -### Globals (updated based on DMA_WIDTH) +# Globals (updated based on DMA_WIDTH) # bits_per_line = 128 words_per_line = 4 @@ -135,1763 +145,2565 @@ def __str__(self): ### VHDL writer ### # -def gen_device_id(accelerator_list, axi_accelerator_list, template_dir, out_dir): - f = open(out_dir + '/sld_devices.vhd', 'w') - with open(template_dir + '/sld_devices.vhd', 'r') as ftemplate: - for tline in ftemplate: - if tline.find("-- <>") >= 0: - conf_id = 1 - for acc in accelerator_list: - for cfg in acc.hlscfg: - f.write(" constant HLSCFG_" + acc.name.upper() + "_" + cfg.name.upper() + " " + ": hlscfg_t := " + str(conf_id) + ";\n") - conf_id = conf_id + 1 - elif tline.find("-- <>") >= 0: - for acc in accelerator_list + axi_accelerator_list: - f.write(" constant SLD_" + acc.name.upper() + " " + ": devid_t := 16#" + acc.device_id + "#;\n") - elif tline.find("-- <>") >= 0: - for acc in accelerator_list + axi_accelerator_list: - desc = acc.desc - if len(acc.desc) < 31: - desc = acc.desc + (31 - len(acc.desc))*" " - elif len(acc.desc) > 31: - desc = acc.desc[0:30] - f.write(" SLD_" + acc.name.upper() + " " + "=> \"" + desc + "\",\n") - else: - f.write(tline) + +def gen_device_id( + accelerator_list, + axi_accelerator_list, + template_dir, + out_dir): + f = open(out_dir + '/sld_devices.vhd', 'w') + with open(template_dir + '/sld_devices.vhd', 'r') as ftemplate: + for tline in ftemplate: + if tline.find("-- <>") >= 0: + conf_id = 1 + for acc in accelerator_list: + for cfg in acc.hlscfg: + f.write( + " constant HLSCFG_" + + acc.name.upper() + + "_" + + cfg.name.upper() + + " " + + ": hlscfg_t := " + + str(conf_id) + + ";\n") + conf_id = conf_id + 1 + elif tline.find("-- <>") >= 0: + for acc in accelerator_list + axi_accelerator_list: + f.write( + " constant SLD_" + + acc.name.upper() + + " " + + ": devid_t := 16#" + + acc.device_id + + "#;\n") + elif tline.find("-- <>") >= 0: + for acc in accelerator_list + axi_accelerator_list: + desc = acc.desc + if len(acc.desc) < 31: + desc = acc.desc + (31 - len(acc.desc)) * " " + elif len(acc.desc) > 31: + desc = acc.desc[0:30] + f.write( + " SLD_" + + acc.name.upper() + + " " + + "=> \"" + + desc + + "\",\n") + else: + f.write(tline) def write_axi_acc_interface(f, acc, noc_width): - for clk in acc.clocks: - f.write(" " + clk + " : in std_logic;\n") - for rst in acc.resets: - f.write(" " + rst + " : in std_logic;\n") - f.write(" " + acc.apb_prefix + "psel : in std_ulogic;\n") - f.write(" " + acc.apb_prefix + "penable : in std_ulogic;\n") - f.write(" " + acc.apb_prefix + "paddr : in std_logic_vector(31 downto 0);\n") - f.write(" " + acc.apb_prefix + "pwrite : in std_ulogic;\n") - f.write(" " + acc.apb_prefix + "pwdata : in std_logic_vector(31 downto 0);\n") - f.write(" " + acc.apb_prefix + "prdata : out std_Logic_vector(31 downto 0);\n") - f.write(" " + acc.apb_prefix + "pready : out std_logic;\n") - f.write(" " + acc.apb_prefix + "pslverr : out std_logic;\n") - f.write(" " + acc.axi_prefix + "awid : out std_logic_vector(" + str(acc.id_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "awaddr : out std_logic_vector(" + str(acc.addr_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "awlen : out std_logic_vector(7 downto 0);\n") - f.write(" " + acc.axi_prefix + "awsize : out std_logic_vector(2 downto 0);\n") - f.write(" " + acc.axi_prefix + "awburst : out std_logic_vector(1 downto 0);\n") - f.write(" " + acc.axi_prefix + "awlock : out std_logic;\n") - f.write(" " + acc.axi_prefix + "awcache : out std_logic_vector(3 downto 0);\n") - f.write(" " + acc.axi_prefix + "awprot : out std_logic_vector(2 downto 0);\n") - f.write(" " + acc.axi_prefix + "awvalid : out std_logic;\n") - f.write(" " + acc.axi_prefix + "awqos : out std_logic_vector(3 downto 0);\n") - f.write(" " + acc.axi_prefix + "awatop : out std_logic_vector(5 downto 0);\n") - f.write(" " + acc.axi_prefix + "awregion : out std_logic_vector(3 downto 0);\n") - if acc.user_width != "0": - f.write(" " + acc.axi_prefix + "awuser : out std_logic_vector(" + str(acc.user_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "awready : in std_logic;\n") - f.write(" " + acc.axi_prefix + "wdata : out std_logic_vector (" + str(noc_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "wstrb : out std_logic_vector (" + str(noc_width) + "/8 - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "wlast : out std_logic;\n") - f.write(" " + acc.axi_prefix + "wvalid : out std_logic;\n") - if acc.user_width != "0": - f.write(" " + acc.axi_prefix + "wuser : out std_logic_vector(" + str(acc.user_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "wready : in std_logic;\n") - f.write(" " + acc.axi_prefix + "arid : out std_logic_vector (" + str(acc.id_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "araddr : out std_logic_vector (" + str(acc.addr_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "arlen : out std_logic_vector (7 downto 0);\n") - f.write(" " + acc.axi_prefix + "arsize : out std_logic_vector (2 downto 0);\n") - f.write(" " + acc.axi_prefix + "arburst : out std_logic_vector (1 downto 0);\n") - f.write(" " + acc.axi_prefix + "arlock : out std_logic;\n") - f.write(" " + acc.axi_prefix + "arcache : out std_logic_vector (3 downto 0);\n") - f.write(" " + acc.axi_prefix + "arprot : out std_logic_vector (2 downto 0);\n") - f.write(" " + acc.axi_prefix + "arvalid : out std_logic;\n") - f.write(" " + acc.axi_prefix + "arqos : out std_logic_vector (3 downto 0);\n") - f.write(" " + acc.axi_prefix + "arregion : out std_logic_vector(3 downto 0);\n") - if acc.user_width != "0": - f.write(" " + acc.axi_prefix + "aruser : out std_logic_vector(" + str(acc.user_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "arready : in std_logic;\n") - f.write(" " + acc.axi_prefix + "rready : out std_logic;\n") - f.write(" " + acc.axi_prefix + "rid : in std_logic_vector (" + str(acc.id_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "rdata : in std_logic_vector (" + str(noc_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "rresp : in std_logic_vector (1 downto 0);\n") - f.write(" " + acc.axi_prefix + "rlast : in std_logic;\n") - f.write(" " + acc.axi_prefix + "rvalid : in std_logic;\n") - if acc.user_width != "0": - f.write(" " + acc.axi_prefix + "ruser : in std_logic_vector(" + str(acc.user_width) + " - 1 downto 0);\n") - f.write(" " + acc.axi_prefix + "bready : out std_logic;\n") - f.write(" " + acc.axi_prefix + "bid : in std_logic_vector (" + str(acc.id_width) + "-1 downto 0);\n") - f.write(" " + acc.axi_prefix + "bresp : in std_logic_vector (1 downto 0);\n") - f.write(" " + acc.axi_prefix + "bvalid : in std_logic") - if acc.user_width != "0" or acc.interrupt != "": - f.write(";\n") - if acc.user_width != "0": - f.write(" " + acc.axi_prefix + "buser : in std_logic_vector(" + str(acc.user_width) + "-1 downto 0)") + for clk in acc.clocks: + f.write(" " + clk + " : in std_logic;\n") + for rst in acc.resets: + f.write(" " + rst + " : in std_logic;\n") + f.write(" " + acc.apb_prefix + "psel : in std_ulogic;\n") + f.write(" " + acc.apb_prefix + "penable : in std_ulogic;\n") + f.write( + " " + + acc.apb_prefix + + "paddr : in std_logic_vector(31 downto 0);\n") + f.write(" " + acc.apb_prefix + "pwrite : in std_ulogic;\n") + f.write( + " " + + acc.apb_prefix + + "pwdata : in std_logic_vector(31 downto 0);\n") + f.write( + " " + + acc.apb_prefix + + "prdata : out std_Logic_vector(31 downto 0);\n") + f.write(" " + acc.apb_prefix + "pready : out std_logic;\n") + f.write(" " + acc.apb_prefix + "pslverr : out std_logic;\n") + f.write(" " + + acc.axi_prefix + + "awid : out std_logic_vector(" + + str(acc.id_width) + + " - 1 downto 0);\n") + f.write(" " + + acc.axi_prefix + + "awaddr : out std_logic_vector(" + + str(acc.addr_width) + + " - 1 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "awlen : out std_logic_vector(7 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "awsize : out std_logic_vector(2 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "awburst : out std_logic_vector(1 downto 0);\n") + f.write(" " + acc.axi_prefix + "awlock : out std_logic;\n") + f.write( + " " + + acc.axi_prefix + + "awcache : out std_logic_vector(3 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "awprot : out std_logic_vector(2 downto 0);\n") + f.write(" " + acc.axi_prefix + "awvalid : out std_logic;\n") + f.write( + " " + + acc.axi_prefix + + "awqos : out std_logic_vector(3 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "awatop : out std_logic_vector(5 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "awregion : out std_logic_vector(3 downto 0);\n") + if acc.user_width != "0": + f.write(" " + + acc.axi_prefix + + "awuser : out std_logic_vector(" + + str(acc.user_width) + + " - 1 downto 0);\n") + f.write(" " + acc.axi_prefix + "awready : in std_logic;\n") + f.write( + " " + + acc.axi_prefix + + "wdata : out std_logic_vector (" + + str(noc_width) + + " - 1 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "wstrb : out std_logic_vector (" + + str(noc_width) + + "/8 - 1 downto 0);\n") + f.write(" " + acc.axi_prefix + "wlast : out std_logic;\n") + f.write(" " + acc.axi_prefix + "wvalid : out std_logic;\n") + if acc.user_width != "0": + f.write(" " + + acc.axi_prefix + + "wuser : out std_logic_vector(" + + str(acc.user_width) + + " - 1 downto 0);\n") + f.write(" " + acc.axi_prefix + "wready : in std_logic;\n") + f.write(" " + + acc.axi_prefix + + "arid : out std_logic_vector (" + + str(acc.id_width) + + " - 1 downto 0);\n") + f.write(" " + + acc.axi_prefix + + "araddr : out std_logic_vector (" + + str(acc.addr_width) + + " - 1 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "arlen : out std_logic_vector (7 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "arsize : out std_logic_vector (2 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "arburst : out std_logic_vector (1 downto 0);\n") + f.write(" " + acc.axi_prefix + "arlock : out std_logic;\n") + f.write( + " " + + acc.axi_prefix + + "arcache : out std_logic_vector (3 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "arprot : out std_logic_vector (2 downto 0);\n") + f.write(" " + acc.axi_prefix + "arvalid : out std_logic;\n") + f.write( + " " + + acc.axi_prefix + + "arqos : out std_logic_vector (3 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "arregion : out std_logic_vector(3 downto 0);\n") + if acc.user_width != "0": + f.write(" " + + acc.axi_prefix + + "aruser : out std_logic_vector(" + + str(acc.user_width) + + " - 1 downto 0);\n") + f.write(" " + acc.axi_prefix + "arready : in std_logic;\n") + f.write(" " + acc.axi_prefix + "rready : out std_logic;\n") + f.write(" " + + acc.axi_prefix + + "rid : in std_logic_vector (" + + str(acc.id_width) + + " - 1 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "rdata : in std_logic_vector (" + + str(noc_width) + + " - 1 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "rresp : in std_logic_vector (1 downto 0);\n") + f.write(" " + acc.axi_prefix + "rlast : in std_logic;\n") + f.write(" " + acc.axi_prefix + "rvalid : in std_logic;\n") + if acc.user_width != "0": + f.write(" " + + acc.axi_prefix + + "ruser : in std_logic_vector(" + + str(acc.user_width) + + " - 1 downto 0);\n") + f.write(" " + acc.axi_prefix + "bready : out std_logic;\n") + f.write(" " + + acc.axi_prefix + + "bid : in std_logic_vector (" + + str(acc.id_width) + + "-1 downto 0);\n") + f.write( + " " + + acc.axi_prefix + + "bresp : in std_logic_vector (1 downto 0);\n") + f.write(" " + acc.axi_prefix + "bvalid : in std_logic") + if acc.user_width != "0" or acc.interrupt != "": + f.write(";\n") + if acc.user_width != "0": + f.write(" " + + acc.axi_prefix + + "buser : in std_logic_vector(" + + str(acc.user_width) + + "-1 downto 0)") + if acc.interrupt != "": + f.write(";\n") if acc.interrupt != "": - f.write(";\n") - if acc.interrupt != "": - f.write(" " + acc.interrupt + " : out std_logic\n") + f.write(" " + acc.interrupt + " : out std_logic\n") + def bind_apb3(f, prefix): - f.write(" " + prefix + "psel => apbi.psel(pindex),\n"); - f.write(" " + prefix + "penable => apbi.penable,\n"); - f.write(" " + prefix + "paddr => apbi_paddr,\n"); - f.write(" " + prefix + "pwrite => apbi.pwrite,\n"); - f.write(" " + prefix + "pwdata => apbi.pwdata,\n"); - f.write(" " + prefix + "prdata => apbo.prdata,\n"); - f.write(" " + prefix + "pready => pready,\n"); - f.write(" " + prefix + "pslverr => open, -- TODO: handle APB3 error\n"); + f.write(" " + prefix + "psel => apbi.psel(pindex),\n") + f.write(" " + prefix + "penable => apbi.penable,\n") + f.write(" " + prefix + "paddr => apbi_paddr,\n") + f.write(" " + prefix + "pwrite => apbi.pwrite,\n") + f.write(" " + prefix + "pwdata => apbi.pwdata,\n") + f.write(" " + prefix + "prdata => apbo.prdata,\n") + f.write(" " + prefix + "pready => pready,\n") + f.write(" " + prefix + "pslverr => open, -- TODO: handle APB3 error\n") def bind_axi(f, acc, noc_width): - f.write(" " + acc.axi_prefix + "awid => mosi(0).aw.id(" + str(acc.id_width) + " - 1 downto 0),\n") - f.write(" " + acc.axi_prefix + "awaddr => mosi(0).aw.addr(" + str(acc.addr_width) + " - 1 downto 0),\n") - f.write(" " + acc.axi_prefix + "awlen => mosi(0).aw.len,\n") - f.write(" " + acc.axi_prefix + "awsize => mosi(0).aw.size,\n") - f.write(" " + acc.axi_prefix + "awburst => mosi(0).aw.burst,\n") - f.write(" " + acc.axi_prefix + "awlock => mosi(0).aw.lock,\n") - f.write(" " + acc.axi_prefix + "awcache => mosi(0).aw.cache,\n") - f.write(" " + acc.axi_prefix + "awprot => mosi(0).aw.prot,\n") - f.write(" " + acc.axi_prefix + "awvalid => mosi(0).aw.valid,\n") - f.write(" " + acc.axi_prefix + "awqos => mosi(0).aw.qos,\n") - f.write(" " + acc.axi_prefix + "awatop => mosi(0).aw.atop,\n") - f.write(" " + acc.axi_prefix + "awregion => mosi(0).aw.region,\n") - if acc.user_width != "0": - f.write(" " + acc.axi_prefix + "awuser => mosi(0).aw.user(" + str(acc.user_width) + " - 1 downto 0),\n") - f.write(" " + acc.axi_prefix + "awready => somi(0).aw.ready,\n") - f.write(" " + acc.axi_prefix + "wdata => mosi(0).w.data,\n") - f.write(" " + acc.axi_prefix + "wstrb => mosi(0).w.strb,\n") - f.write(" " + acc.axi_prefix + "wlast => mosi(0).w.last,\n") - f.write(" " + acc.axi_prefix + "wvalid => mosi(0).w.valid,\n") - if acc.user_width != "0": - f.write(" " + acc.axi_prefix + "wuser => mosi(0).w.user(" + str(acc.user_width) + " - 1 downto 0),\n") - f.write(" " + acc.axi_prefix + "wready => somi(0).w.ready,\n") - f.write(" " + acc.axi_prefix + "arid => mosi(0).ar.id(" + str(acc.id_width) + " - 1 downto 0) ,\n") - f.write(" " + acc.axi_prefix + "araddr => mosi(0).ar.addr(" + str(acc.addr_width) + " - 1 downto 0),\n") - f.write(" " + acc.axi_prefix + "arlen => mosi(0).ar.len,\n") - f.write(" " + acc.axi_prefix + "arsize => mosi(0).ar.size,\n") - f.write(" " + acc.axi_prefix + "arburst => mosi(0).ar.burst,\n") - f.write(" " + acc.axi_prefix + "arlock => mosi(0).ar.lock,\n") - f.write(" " + acc.axi_prefix + "arcache => mosi(0).ar.cache,\n") - f.write(" " + acc.axi_prefix + "arprot => mosi(0).ar.prot,\n") - f.write(" " + acc.axi_prefix + "arvalid => mosi(0).ar.valid,\n") - f.write(" " + acc.axi_prefix + "arqos => mosi(0).ar.qos,\n") - f.write(" " + acc.axi_prefix + "arregion => mosi(0).ar.region,\n") - if acc.user_width != "0": - f.write(" " + acc.axi_prefix + "aruser => mosi(0).ar.user(" + str(acc.user_width) + " - 1 downto 0),\n") - f.write(" " + acc.axi_prefix + "arready => somi(0).ar.ready,\n") - f.write(" " + acc.axi_prefix + "rready => mosi(0).r.ready,\n") - f.write(" " + acc.axi_prefix + "rid => somi(0).r.id(" + str(acc.id_width) + " - 1 downto 0),\n") - f.write(" " + acc.axi_prefix + "rdata => somi(0).r.data,\n") - f.write(" " + acc.axi_prefix + "rresp => somi(0).r.resp,\n") - f.write(" " + acc.axi_prefix + "rlast => somi(0).r.last,\n") - f.write(" " + acc.axi_prefix + "rvalid => somi(0).r.valid,\n") - if acc.user_width != "0": - f.write(" " + acc.axi_prefix + "ruser => somi(0).r.user(" + str(acc.user_width) + " - 1 downto 0),\n") - f.write(" " + acc.axi_prefix + "bready => mosi(0).b.ready,\n") - f.write(" " + acc.axi_prefix + "bid => somi(0).b.id(" + str(acc.id_width) + " - 1 downto 0),\n") - f.write(" " + acc.axi_prefix + "bresp => somi(0).b.resp,\n") - f.write(" " + acc.axi_prefix + "bvalid => somi(0).b.valid") - if acc.user_width != "0": - f.write(",\n") - f.write(" " + acc.axi_prefix + "buser => somi(0).b.user") + f.write(" " + + acc.axi_prefix + + "awid => mosi(0).aw.id(" + + str(acc.id_width) + + " - 1 downto 0),\n") + f.write(" " + + acc.axi_prefix + + "awaddr => mosi(0).aw.addr(" + + str(acc.addr_width) + + " - 1 downto 0),\n") + f.write(" " + acc.axi_prefix + "awlen => mosi(0).aw.len,\n") + f.write(" " + acc.axi_prefix + "awsize => mosi(0).aw.size,\n") + f.write(" " + acc.axi_prefix + "awburst => mosi(0).aw.burst,\n") + f.write(" " + acc.axi_prefix + "awlock => mosi(0).aw.lock,\n") + f.write(" " + acc.axi_prefix + "awcache => mosi(0).aw.cache,\n") + f.write(" " + acc.axi_prefix + "awprot => mosi(0).aw.prot,\n") + f.write(" " + acc.axi_prefix + "awvalid => mosi(0).aw.valid,\n") + f.write(" " + acc.axi_prefix + "awqos => mosi(0).aw.qos,\n") + f.write(" " + acc.axi_prefix + "awatop => mosi(0).aw.atop,\n") + f.write(" " + acc.axi_prefix + "awregion => mosi(0).aw.region,\n") + if acc.user_width != "0": + f.write(" " + + acc.axi_prefix + + "awuser => mosi(0).aw.user(" + + str(acc.user_width) + + " - 1 downto 0),\n") + f.write(" " + acc.axi_prefix + "awready => somi(0).aw.ready,\n") + f.write(" " + acc.axi_prefix + "wdata => mosi(0).w.data,\n") + f.write(" " + acc.axi_prefix + "wstrb => mosi(0).w.strb,\n") + f.write(" " + acc.axi_prefix + "wlast => mosi(0).w.last,\n") + f.write(" " + acc.axi_prefix + "wvalid => mosi(0).w.valid,\n") + if acc.user_width != "0": + f.write(" " + + acc.axi_prefix + + "wuser => mosi(0).w.user(" + + str(acc.user_width) + + " - 1 downto 0),\n") + f.write(" " + acc.axi_prefix + "wready => somi(0).w.ready,\n") + f.write(" " + + acc.axi_prefix + + "arid => mosi(0).ar.id(" + + str(acc.id_width) + + " - 1 downto 0) ,\n") + f.write(" " + + acc.axi_prefix + + "araddr => mosi(0).ar.addr(" + + str(acc.addr_width) + + " - 1 downto 0),\n") + f.write(" " + acc.axi_prefix + "arlen => mosi(0).ar.len,\n") + f.write(" " + acc.axi_prefix + "arsize => mosi(0).ar.size,\n") + f.write(" " + acc.axi_prefix + "arburst => mosi(0).ar.burst,\n") + f.write(" " + acc.axi_prefix + "arlock => mosi(0).ar.lock,\n") + f.write(" " + acc.axi_prefix + "arcache => mosi(0).ar.cache,\n") + f.write(" " + acc.axi_prefix + "arprot => mosi(0).ar.prot,\n") + f.write(" " + acc.axi_prefix + "arvalid => mosi(0).ar.valid,\n") + f.write(" " + acc.axi_prefix + "arqos => mosi(0).ar.qos,\n") + f.write(" " + acc.axi_prefix + "arregion => mosi(0).ar.region,\n") + if acc.user_width != "0": + f.write(" " + + acc.axi_prefix + + "aruser => mosi(0).ar.user(" + + str(acc.user_width) + + " - 1 downto 0),\n") + f.write(" " + acc.axi_prefix + "arready => somi(0).ar.ready,\n") + f.write(" " + acc.axi_prefix + "rready => mosi(0).r.ready,\n") + f.write(" " + + acc.axi_prefix + + "rid => somi(0).r.id(" + + str(acc.id_width) + + " - 1 downto 0),\n") + f.write(" " + acc.axi_prefix + "rdata => somi(0).r.data,\n") + f.write(" " + acc.axi_prefix + "rresp => somi(0).r.resp,\n") + f.write(" " + acc.axi_prefix + "rlast => somi(0).r.last,\n") + f.write(" " + acc.axi_prefix + "rvalid => somi(0).r.valid,\n") + if acc.user_width != "0": + f.write(" " + + acc.axi_prefix + + "ruser => somi(0).r.user(" + + str(acc.user_width) + + " - 1 downto 0),\n") + f.write(" " + acc.axi_prefix + "bready => mosi(0).b.ready,\n") + f.write(" " + + acc.axi_prefix + + "bid => somi(0).b.id(" + + str(acc.id_width) + + " - 1 downto 0),\n") + f.write(" " + acc.axi_prefix + "bresp => somi(0).b.resp,\n") + f.write(" " + acc.axi_prefix + "bvalid => somi(0).b.valid") + if acc.user_width != "0": + f.write(",\n") + f.write(" " + acc.axi_prefix + "buser => somi(0).b.user") def tie_unused_axi(f, acc, noc_width): - f.write(" pad_id_gen : if XID_WIDTH > " + str(acc.id_width) + " generate\n") - f.write(" mosi(0).aw.id(XID_WIDTH - 1 downto " + str(acc.id_width) + ") <= (others => '0');\n") - f.write(" mosi(0).ar.id(XID_WIDTH - 1 downto " + str(acc.id_width) + ") <= (others => '0');\n") - f.write(" end generate;\n") - f.write(" pad_paddr_gen : if GLOB_PHYS_ADDR_BITS > " + str(acc.addr_width) + " generate\n") - f.write(" mosi(0).aw.addr(GLOB_PHYS_ADDR_BITS - 1 downto " + str(acc.addr_width) + ") <= (others => '0');\n") - f.write(" mosi(0).ar.addr(GLOB_PHYS_ADDR_BITS - 1 downto " + str(acc.addr_width) + ") <= (others => '0');\n") - f.write(" end generate;\n") - f.write(" pad_user_gen : if XUSER_WIDTH > " + str(acc.user_width) + " generate\n") - f.write(" mosi(0).aw.user(XUSER_WIDTH - 1 downto " + str(acc.user_width) + ") <= (others => '0');\n") - f.write(" mosi(0).w.user(XUSER_WIDTH - 1 downto " + str(acc.user_width) + ") <= (others => '0');\n") - f.write(" mosi(0).ar.user(XUSER_WIDTH - 1 downto " + str(acc.user_width) + ") <= (others => '0');\n") - f.write(" end generate;\n") + f.write(" pad_id_gen : if XID_WIDTH > " + + str(acc.id_width) + " generate\n") + f.write(" mosi(0).aw.id(XID_WIDTH - 1 downto " + + str(acc.id_width) + ") <= (others => '0');\n") + f.write(" mosi(0).ar.id(XID_WIDTH - 1 downto " + + str(acc.id_width) + ") <= (others => '0');\n") + f.write(" end generate;\n") + f.write(" pad_paddr_gen : if GLOB_PHYS_ADDR_BITS > " + + str(acc.addr_width) + " generate\n") + f.write(" mosi(0).aw.addr(GLOB_PHYS_ADDR_BITS - 1 downto " + + str(acc.addr_width) + ") <= (others => '0');\n") + f.write(" mosi(0).ar.addr(GLOB_PHYS_ADDR_BITS - 1 downto " + + str(acc.addr_width) + ") <= (others => '0');\n") + f.write(" end generate;\n") + f.write(" pad_user_gen : if XUSER_WIDTH > " + + str(acc.user_width) + " generate\n") + f.write(" mosi(0).aw.user(XUSER_WIDTH - 1 downto " + + str(acc.user_width) + ") <= (others => '0');\n") + f.write(" mosi(0).w.user(XUSER_WIDTH - 1 downto " + + str(acc.user_width) + ") <= (others => '0');\n") + f.write(" mosi(0).ar.user(XUSER_WIDTH - 1 downto " + + str(acc.user_width) + ") <= (others => '0');\n") + f.write(" end generate;\n") def write_axi_acc_port_map(f, acc, noc_width): - f.write(" port map(\n") - for clk in acc.clocks: - f.write(" " + clk + " => clk,\n") - for rst in acc.resets: - f.write(" " + rst + " => rst,\n") - bind_apb3(f, acc.apb_prefix) - bind_axi(f, acc, noc_width) - if acc.interrupt != "": - f.write(",\n") - f.write(" " + acc.interrupt + " => acc_done\n") - f.write(" );\n") - - -def write_acc_interface(f, acc, noc_width, datatype, rst, is_vivadohls_if, is_catapulthls_cxx_if, is_catapulthls_sysc_if): - - if is_catapulthls_cxx_if: - conf_info_size = 0 - for param in acc.param: - if not param.readonly: - conf_info_size = conf_info_size + param.size - spacing = " " - f.write(" clk : in std_ulogic;\n") - spacing = (27-len(rst))*" " - f.write(" " + rst + spacing + ": in std_ulogic;\n") - f.write("\n") - f.write(" conf_info_rsc_dat : in std_logic_vector(" + str(conf_info_size - 1) + " downto 0);\n") - f.write(" conf_info_rsc_vld : in std_ulogic;\n") - f.write(" conf_info_rsc_rdy : out std_ulogic;\n") - f.write("\n") - f.write(" dma_read_ctrl_rsc_dat : out std_logic_vector(" + str(66) + " downto 0);\n") - f.write(" dma_read_ctrl_rsc_vld : out std_ulogic;\n") - f.write(" dma_read_ctrl_rsc_rdy : in std_ulogic;\n") - f.write("\n") - f.write(" dma_write_ctrl_rsc_dat : out std_logic_vector(" + str(66) + " downto 0);\n") - f.write(" dma_write_ctrl_rsc_vld : out std_ulogic;\n") - f.write(" dma_write_ctrl_rsc_rdy : in std_ulogic;\n") - f.write("\n") - f.write(" dma_read_chnl_rsc_dat : in std_logic_vector(" + str(noc_width - 1) + " downto 0);\n") - f.write(" dma_read_chnl_rsc_vld : in std_ulogic;\n") - f.write(" dma_read_chnl_rsc_rdy : out std_ulogic;\n") - f.write("\n") - f.write(" dma_write_chnl_rsc_dat : out std_logic_vector(" + str(noc_width - 1) + " downto 0);\n") - f.write(" dma_write_chnl_rsc_vld : out std_ulogic;\n") - f.write(" dma_write_chnl_rsc_rdy : in std_ulogic;\n") - f.write("\n") - f.write(" acc_done_rsc_vld : out std_ulogic\n") - - elif is_catapulthls_sysc_if: - conf_info_size = 0 - for param in acc.param: - if not param.readonly: - conf_info_size = conf_info_size + param.size - spacing = " " - f.write(" clk : in std_ulogic;\n") - spacing = (27-len(rst))*" " - f.write(" " + rst + spacing + ": in std_ulogic;\n") - f.write("\n") - f.write(" conf_info_msg : in std_logic_vector(" + str(conf_info_size - 1) + " downto 0);\n") - f.write(" conf_info_val : in std_ulogic;\n") - f.write(" conf_info_rdy : out std_ulogic;\n") - f.write("\n") - f.write(" dma_read_ctrl_msg : out std_logic_vector(" + str(66) + " downto 0);\n") - f.write(" dma_read_ctrl_val : out std_ulogic;\n") - f.write(" dma_read_ctrl_rdy : in std_ulogic;\n") - f.write("\n") - f.write(" dma_write_ctrl_msg : out std_logic_vector(" + str(66) + " downto 0);\n") - f.write(" dma_write_ctrl_val : out std_ulogic;\n") - f.write(" dma_write_ctrl_rdy : in std_ulogic;\n") - f.write("\n") - f.write(" dma_read_chnl_msg : in std_logic_vector(" + str(noc_width - 1) + " downto 0);\n") - f.write(" dma_read_chnl_val : in std_ulogic;\n") - f.write(" dma_read_chnl_rdy : out std_ulogic;\n") - f.write("\n") - f.write(" dma_write_chnl_msg : out std_logic_vector(" + str(noc_width - 1) + " downto 0);\n") - f.write(" dma_write_chnl_val : out std_ulogic;\n") - f.write(" dma_write_chnl_rdy : in std_ulogic;\n") - f.write("\n") - f.write(" acc_done : out std_ulogic\n") - elif is_vivadohls_if: - for param in acc.param: - if not param.readonly: - spacing = " " - if 17 - len(param.name) > 0: - spacing = (17-len(param.name))*" " - f.write(" conf_info_" + param.name + spacing + ": in std_logic_vector(" + str(param.size - 1) + " downto 0);\n") - f.write(" ap_clk : in std_ulogic;\n") - spacing = (27-len(rst))*" " - f.write(" " + rst + spacing + ": in std_ulogic;\n") - f.write(" ap_start : in std_ulogic;\n") - f.write(" ap_done : out std_ulogic;\n") - f.write(" ap_idle : out std_ulogic;\n") - f.write(" ap_ready : out std_ulogic;\n") - if datatype == 'float' or datatype == 'float_out': - f.write(" out_word_din : out std_logic_vector (" + str(noc_width - 1) + " downto 0);\n") - f.write(" out_word_full_n : in std_logic;\n") - f.write(" out_word_write : out std_logic;\n") - else: - f.write(" out_word_V_din : out std_logic_vector (" + str(noc_width - 1) + " downto 0);\n") - f.write(" out_word_V_full_n : in std_logic;\n") - f.write(" out_word_V_write : out std_logic;\n") - if datatype == 'float' or datatype == 'float_in': - f.write(" in1_word_dout : in std_logic_vector (" + str(noc_width - 1) + " downto 0);\n") - f.write(" in1_word_empty_n : in std_logic;\n") - f.write(" in1_word_read : out std_logic;\n") - else: - f.write(" in1_word_V_dout : in std_logic_vector (" + str(noc_width - 1) + " downto 0);\n") - f.write(" in1_word_V_empty_n : in std_logic;\n") - f.write(" in1_word_V_read : out std_logic;\n") - f.write(" load_ctrl : out std_logic_vector (" + str(95) + " downto 0);\n") - f.write(" load_ctrl_ap_ack : in std_logic;\n") - f.write(" load_ctrl_ap_vld : out std_logic;\n") - f.write(" store_ctrl : out std_logic_vector (" + str(95) + " downto 0);\n") - f.write(" store_ctrl_ap_ack : in std_logic;\n") - f.write(" store_ctrl_ap_vld : out std_logic\n") - else: - for param in acc.param: - if not param.readonly: + f.write(" port map(\n") + for clk in acc.clocks: + f.write(" " + clk + " => clk,\n") + for rst in acc.resets: + f.write(" " + rst + " => rst,\n") + bind_apb3(f, acc.apb_prefix) + bind_axi(f, acc, noc_width) + if acc.interrupt != "": + f.write(",\n") + f.write(" " + acc.interrupt + " => acc_done\n") + f.write(" );\n") + + +def write_acc_interface( + f, + acc, + noc_width, + datatype, + rst, + is_vivadohls_if, + is_catapulthls_cxx_if, + is_catapulthls_sysc_if): + + if is_catapulthls_cxx_if: + conf_info_size = 0 + for param in acc.param: + if not param.readonly: + conf_info_size = conf_info_size + param.size spacing = " " - if 17 - len(param.name) > 0: - spacing = (17-len(param.name))*" " - f.write(" conf_info_" + param.name + spacing + ": in std_logic_vector(" + str(param.size - 1) + " downto 0);\n") - f.write(" clk : in std_ulogic;\n") - spacing = (27-len(rst))*" " - f.write(" " + rst + spacing + ": in std_ulogic;\n") - f.write(" conf_done : in std_ulogic;\n") - f.write(" dma_read_ctrl_valid : out std_ulogic;\n") - f.write(" dma_read_ctrl_ready : in std_ulogic;\n") - f.write(" dma_read_ctrl_data_index : out std_logic_vector(" + str(31) + " downto 0);\n") - f.write(" dma_read_ctrl_data_length : out std_logic_vector(" + str(31) + " downto 0);\n") - f.write(" dma_read_ctrl_data_size : out std_logic_vector(" + str(2) + " downto 0);\n") - f.write(" dma_write_ctrl_valid : out std_ulogic;\n") - f.write(" dma_write_ctrl_ready : in std_ulogic;\n") - f.write(" dma_write_ctrl_data_index : out std_logic_vector(" + str(31) + " downto 0);\n") - f.write(" dma_write_ctrl_data_length : out std_logic_vector(" + str(31) + " downto 0);\n") - f.write(" dma_write_ctrl_data_size : out std_logic_vector(" + str(2) + " downto 0);\n") - f.write(" dma_read_chnl_valid : in std_ulogic;\n") - f.write(" dma_read_chnl_ready : out std_ulogic;\n") - f.write(" dma_read_chnl_data : in std_logic_vector(" + str(noc_width - 1) + " downto 0);\n") - f.write(" dma_write_chnl_valid : out std_ulogic;\n") - f.write(" dma_write_chnl_ready : in std_ulogic;\n") - f.write(" dma_write_chnl_data : out std_logic_vector(" + str(noc_width - 1) + " downto 0);\n") - f.write(" acc_done : out std_ulogic\n") + f.write(" clk : in std_ulogic;\n") + spacing = (27 - len(rst)) * " " + f.write(" " + rst + spacing + ": in std_ulogic;\n") + f.write("\n") + f.write(" conf_info_rsc_dat : in std_logic_vector(" + + str(conf_info_size - 1) + " downto 0);\n") + f.write(" conf_info_rsc_vld : in std_ulogic;\n") + f.write(" conf_info_rsc_rdy : out std_ulogic;\n") + f.write("\n") + f.write( + " dma_read_ctrl_rsc_dat : out std_logic_vector(" + + str(66) + + " downto 0);\n") + f.write(" dma_read_ctrl_rsc_vld : out std_ulogic;\n") + f.write(" dma_read_ctrl_rsc_rdy : in std_ulogic;\n") + f.write("\n") + f.write( + " dma_write_ctrl_rsc_dat : out std_logic_vector(" + + str(66) + + " downto 0);\n") + f.write(" dma_write_ctrl_rsc_vld : out std_ulogic;\n") + f.write(" dma_write_ctrl_rsc_rdy : in std_ulogic;\n") + f.write("\n") + f.write(" dma_read_chnl_rsc_dat : in std_logic_vector(" + + str(noc_width - 1) + " downto 0);\n") + f.write(" dma_read_chnl_rsc_vld : in std_ulogic;\n") + f.write(" dma_read_chnl_rsc_rdy : out std_ulogic;\n") + f.write("\n") + f.write(" dma_write_chnl_rsc_dat : out std_logic_vector(" + + str(noc_width - 1) + " downto 0);\n") + f.write(" dma_write_chnl_rsc_vld : out std_ulogic;\n") + f.write(" dma_write_chnl_rsc_rdy : in std_ulogic;\n") + f.write("\n") + f.write(" acc_done_rsc_vld : out std_ulogic\n") -def write_ap_acc_signals(f): - f.write("\n") - f.write("signal ap_rst : std_ulogic;\n") - f.write("\n") - f.write("-- signals for start fsm\n") - f.write("\n") - f.write("type start_state_t is (aps_idle, aps_starting, aps_running, aps_wait_for_completion);\n") - f.write("signal ap_state, ap_next : start_state_t;\n") - f.write("signal ap_start : std_ulogic;\n") - f.write("signal ap_done : std_ulogic;\n") - f.write("signal ap_idle : std_ulogic;\n") - f.write("signal ap_ready : std_ulogic;\n") - f.write("\n") - f.write("-- signals for ctrl struct unpakc\n") - f.write("\n") - f.write("signal dma_read_ctrl_data : std_logic_vector(95 downto 0);\n") - f.write("signal dma_write_ctrl_data : std_logic_vector(95 downto 0);\n") - f.write("\n") - -def write_acc_port_map(f, acc, noc_width, datatype, rst, is_noc_interface, is_vivadohls_if, is_catapulthls_cxx_if, is_catapulthls_sysc_if): - - if is_vivadohls_if: - f.write(" port map(\n") - for param in acc.param: - if not param.readonly: + elif is_catapulthls_sysc_if: + conf_info_size = 0 + for param in acc.param: + if not param.readonly: + conf_info_size = conf_info_size + param.size spacing = " " - if 16 - len(param.name) > 0: - spacing = (16-len(param.name))*" " - if is_noc_interface: - f.write(" conf_info_" + param.name + spacing + " => " + "bank(" + acc.name.upper() + "_" + param.name.upper() + "_REG)(" + str(param.size - 1) + " downto 0),\n") + f.write(" clk : in std_ulogic;\n") + spacing = (27 - len(rst)) * " " + f.write(" " + rst + spacing + ": in std_ulogic;\n") + f.write("\n") + f.write(" conf_info_msg : in std_logic_vector(" + + str(conf_info_size - 1) + " downto 0);\n") + f.write(" conf_info_val : in std_ulogic;\n") + f.write(" conf_info_rdy : out std_ulogic;\n") + f.write("\n") + f.write( + " dma_read_ctrl_msg : out std_logic_vector(" + + str(66) + + " downto 0);\n") + f.write(" dma_read_ctrl_val : out std_ulogic;\n") + f.write(" dma_read_ctrl_rdy : in std_ulogic;\n") + f.write("\n") + f.write( + " dma_write_ctrl_msg : out std_logic_vector(" + + str(66) + + " downto 0);\n") + f.write(" dma_write_ctrl_val : out std_ulogic;\n") + f.write(" dma_write_ctrl_rdy : in std_ulogic;\n") + f.write("\n") + f.write(" dma_read_chnl_msg : in std_logic_vector(" + + str(noc_width - 1) + " downto 0);\n") + f.write(" dma_read_chnl_val : in std_ulogic;\n") + f.write(" dma_read_chnl_rdy : out std_ulogic;\n") + f.write("\n") + f.write(" dma_write_chnl_msg : out std_logic_vector(" + + str(noc_width - 1) + " downto 0);\n") + f.write(" dma_write_chnl_val : out std_ulogic;\n") + f.write(" dma_write_chnl_rdy : in std_ulogic;\n") + f.write("\n") + f.write(" acc_done : out std_ulogic\n") + elif is_vivadohls_if: + for param in acc.param: + if not param.readonly: + spacing = " " + if 17 - len(param.name) > 0: + spacing = (17 - len(param.name)) * " " + f.write(" conf_info_" + param.name + spacing + + ": in std_logic_vector(" + str(param.size - 1) + " downto 0);\n") + f.write(" ap_clk : in std_ulogic;\n") + spacing = (27 - len(rst)) * " " + f.write(" " + rst + spacing + ": in std_ulogic;\n") + f.write(" ap_start : in std_ulogic;\n") + f.write(" ap_done : out std_ulogic;\n") + f.write(" ap_idle : out std_ulogic;\n") + f.write(" ap_ready : out std_ulogic;\n") + if datatype == 'float' or datatype == 'float_out': + f.write(" out_word_din : out std_logic_vector (" + + str(noc_width - 1) + " downto 0);\n") + f.write(" out_word_full_n : in std_logic;\n") + f.write(" out_word_write : out std_logic;\n") else: - f.write(" conf_info_" + param.name + spacing + " => " + "conf_info_" + param.name +",\n") - f.write(" ap_clk => clk,\n") - f.write(" ap_rst => ap_rst,\n") - f.write(" ap_start => ap_start,\n") - f.write(" load_ctrl_ap_vld => dma_read_ctrl_valid,\n") - f.write(" load_ctrl_ap_ack => dma_read_ctrl_ready,\n") - f.write(" load_ctrl => dma_read_ctrl_data,\n") - f.write(" store_ctrl_ap_vld => dma_write_ctrl_valid,\n") - f.write(" store_ctrl_ap_ack => dma_write_ctrl_ready,\n") - f.write(" store_ctrl => dma_write_ctrl_data,\n") - if datatype == 'float': - f.write(" in1_word_empty_n => dma_read_chnl_valid,\n") - f.write(" in1_word_read => dma_read_chnl_ready,\n") - f.write(" in1_word_dout => dma_read_chnl_data,\n") - f.write(" out_word_write => dma_write_chnl_valid,\n") - f.write(" out_word_full_n => dma_write_chnl_ready,\n") - f.write(" out_word_din => dma_write_chnl_data,\n") + f.write(" out_word_V_din : out std_logic_vector (" + + str(noc_width - 1) + " downto 0);\n") + f.write(" out_word_V_full_n : in std_logic;\n") + f.write(" out_word_V_write : out std_logic;\n") + if datatype == 'float' or datatype == 'float_in': + f.write(" in1_word_dout : in std_logic_vector (" + + str(noc_width - 1) + " downto 0);\n") + f.write(" in1_word_empty_n : in std_logic;\n") + f.write(" in1_word_read : out std_logic;\n") + else: + f.write(" in1_word_V_dout : in std_logic_vector (" + + str(noc_width - 1) + " downto 0);\n") + f.write(" in1_word_V_empty_n : in std_logic;\n") + f.write(" in1_word_V_read : out std_logic;\n") + f.write( + " load_ctrl : out std_logic_vector (" + + str(95) + + " downto 0);\n") + f.write(" load_ctrl_ap_ack : in std_logic;\n") + f.write(" load_ctrl_ap_vld : out std_logic;\n") + f.write( + " store_ctrl : out std_logic_vector (" + + str(95) + + " downto 0);\n") + f.write(" store_ctrl_ap_ack : in std_logic;\n") + f.write(" store_ctrl_ap_vld : out std_logic\n") else: - f.write(" in1_word_V_empty_n => dma_read_chnl_valid,\n") - f.write(" in1_word_V_read => dma_read_chnl_ready,\n") - f.write(" in1_word_V_dout => dma_read_chnl_data,\n") - f.write(" out_word_V_write => dma_write_chnl_valid,\n") - f.write(" out_word_V_full_n => dma_write_chnl_ready,\n") - f.write(" out_word_V_din => dma_write_chnl_data,\n") - f.write(" ap_done => ap_done,\n") - f.write(" ap_idle => ap_idle,\n") - f.write(" ap_ready => ap_ready\n") - f.write(" );\n") - f.write("\n") - f.write(" ap_rst <= not acc_rst;\n") - f.write(" acc_done <= ap_done;\n"); - f.write("\n") - f.write(" -- START FSM\n") - f.write("\n") - f.write(" ap_acc_fsm: process (ap_state, conf_done, ap_idle, ap_ready, ap_done) is\n") - f.write(" begin -- process ap_acc_fsm\n") - f.write(" ap_next <= ap_state;\n") - f.write(" ap_start <= '0';\n") - f.write("\n") - f.write(" case ap_state is\n") - f.write("\n") - f.write(" when aps_idle =>\n") - f.write(" if (ap_idle and conf_done) = '1' then\n") - f.write(" ap_next <= aps_starting;\n") - f.write(" end if;\n") - f.write("\n") - f.write(" when aps_starting =>\n") - f.write(" ap_start <= '1';\n") - f.write(" if ap_ready = '1' then\n") - f.write(" ap_next <= aps_wait_for_completion;\n") - f.write(" elsif ap_idle = '0' then\n") - f.write(" ap_next <= aps_running;\n") - f.write(" end if;\n") - f.write("\n") - f.write(" when aps_running =>\n") - f.write(" ap_start <= '1';\n") - f.write(" if ap_done = '1' then\n") - f.write(" ap_next <= aps_idle;\n") - f.write(" elsif ap_ready = '1' then\n") - f.write(" ap_next <= aps_wait_for_completion;\n") - f.write(" end if;\n") - f.write("\n") - f.write(" when aps_wait_for_completion =>\n") - f.write(" if ap_done = '1' then\n") - f.write(" ap_next <= aps_idle;\n") - f.write(" end if;\n") - f.write("\n") - f.write(" when others =>\n") - f.write(" ap_next <= aps_idle;\n") - f.write("\n") - f.write(" end case;\n") - f.write(" end process ap_acc_fsm;\n") - f.write("\n") - f.write(" ap_acc_state_update: process (clk, ap_rst) is\n") - f.write(" begin -- process ap_acc_state_update\n") - f.write(" if clk'event and clk = '1' then -- rising clock edge\n") - f.write(" if ap_rst = '1' then -- synchronous active high\n") - f.write(" ap_state <= aps_idle;\n") - f.write(" else\n") - f.write(" ap_state <= ap_next;\n") - f.write(" end if;\n") - f.write(" end if;\n") - f.write(" end process ap_acc_state_update;\n") - f.write("\n") - f.write(" ---- CTRL FSM\n") - f.write("\n") - f.write(" dma_read_ctrl_data_size <= dma_read_ctrl_data(66 downto 64);\n") - f.write(" dma_read_ctrl_data_length <= dma_read_ctrl_data(63 downto 32);\n") - f.write(" dma_read_ctrl_data_index <= dma_read_ctrl_data(31 downto 0);\n") - f.write(" dma_write_ctrl_data_size <= dma_write_ctrl_data(66 downto 64);\n") - f.write(" dma_write_ctrl_data_length <= dma_write_ctrl_data(63 downto 32);\n") - f.write(" dma_write_ctrl_data_index <= dma_write_ctrl_data(31 downto 0);\n") - f.write("\n") - elif is_catapulthls_cxx_if: - f.write(" port map(\n") - f.write(" clk => clk,\n") - spacing = (27-len(rst))*" " - f.write(" " + rst + spacing + "=> acc_rst,\n") - f.write("\n") - conf_info_rsc_data_size = 0 - for param in acc.param: - if not param.readonly: - conf_info_rsc_data_size += param.size - for param in acc.param: - if not param.readonly: - spacing = " " - if 14 - len(param.name) > 0: - spacing = (14-len(param.name))*" " - f.write(" conf_info_rsc_dat(" + str(conf_info_rsc_data_size-1) + " downto " + str(conf_info_rsc_data_size-param.size) + ") => " + "conf_info_" + param.name +",\n") - conf_info_rsc_data_size -= param.size - f.write(" conf_info_rsc_vld => conf_info_rsc_valid,\n") - f.write(" conf_info_rsc_rdy => conf_info_rsc_ready,\n") + for param in acc.param: + if not param.readonly: + spacing = " " + if 17 - len(param.name) > 0: + spacing = (17 - len(param.name)) * " " + f.write(" conf_info_" + param.name + spacing + + ": in std_logic_vector(" + str(param.size - 1) + " downto 0);\n") + f.write(" clk : in std_ulogic;\n") + spacing = (27 - len(rst)) * " " + f.write(" " + rst + spacing + ": in std_ulogic;\n") + f.write(" conf_done : in std_ulogic;\n") + f.write(" dma_read_ctrl_valid : out std_ulogic;\n") + f.write(" dma_read_ctrl_ready : in std_ulogic;\n") + f.write( + " dma_read_ctrl_data_index : out std_logic_vector(" + + str(31) + + " downto 0);\n") + f.write( + " dma_read_ctrl_data_length : out std_logic_vector(" + + str(31) + + " downto 0);\n") + f.write( + " dma_read_ctrl_data_size : out std_logic_vector(" + + str(2) + + " downto 0);\n") + f.write(" dma_write_ctrl_valid : out std_ulogic;\n") + f.write(" dma_write_ctrl_ready : in std_ulogic;\n") + f.write( + " dma_write_ctrl_data_index : out std_logic_vector(" + + str(31) + + " downto 0);\n") + f.write( + " dma_write_ctrl_data_length : out std_logic_vector(" + + str(31) + + " downto 0);\n") + f.write( + " dma_write_ctrl_data_size : out std_logic_vector(" + + str(2) + + " downto 0);\n") + f.write(" dma_read_chnl_valid : in std_ulogic;\n") + f.write(" dma_read_chnl_ready : out std_ulogic;\n") + f.write(" dma_read_chnl_data : in std_logic_vector(" + + str(noc_width - 1) + " downto 0);\n") + f.write(" dma_write_chnl_valid : out std_ulogic;\n") + f.write(" dma_write_chnl_ready : in std_ulogic;\n") + f.write(" dma_write_chnl_data : out std_logic_vector(" + + str(noc_width - 1) + " downto 0);\n") + f.write(" acc_done : out std_ulogic\n") + + +def write_ap_acc_signals(f): f.write("\n") - f.write(" dma_read_ctrl_rsc_dat(66 downto 64) => dma_read_ctrl_data_size,\n") - f.write(" dma_read_ctrl_rsc_dat(63 downto 32) => dma_read_ctrl_data_length,\n") - f.write(" dma_read_ctrl_rsc_dat(31 downto 0) => dma_read_ctrl_data_index,\n") - f.write(" dma_read_ctrl_rsc_vld => dma_read_ctrl_valid,\n") - f.write(" dma_read_ctrl_rsc_rdy => dma_read_ctrl_ready,\n") + f.write("signal ap_rst : std_ulogic;\n") f.write("\n") - f.write(" dma_write_ctrl_rsc_dat(" + str(66) + " downto " + str(64) + ") => dma_write_ctrl_data_size,\n"), - f.write(" dma_write_ctrl_rsc_dat(" + str(63) + " downto " + str(32) + ") => dma_write_ctrl_data_length,\n") - f.write(" dma_write_ctrl_rsc_dat(" + str(31) + " downto 0) => dma_write_ctrl_data_index,\n") - f.write(" dma_write_ctrl_rsc_vld => dma_write_ctrl_valid,\n") - f.write(" dma_write_ctrl_rsc_rdy => dma_write_ctrl_ready,\n") + f.write("-- signals for start fsm\n") f.write("\n") - f.write(" dma_read_chnl_rsc_dat => dma_read_chnl_data,\n") - f.write(" dma_read_chnl_rsc_vld => dma_read_chnl_valid,\n") - f.write(" dma_read_chnl_rsc_rdy => dma_read_chnl_ready,\n") + f.write("type start_state_t is (aps_idle, aps_starting, aps_running, aps_wait_for_completion);\n") + f.write("signal ap_state, ap_next : start_state_t;\n") + f.write("signal ap_start : std_ulogic;\n") + f.write("signal ap_done : std_ulogic;\n") + f.write("signal ap_idle : std_ulogic;\n") + f.write("signal ap_ready : std_ulogic;\n") f.write("\n") - f.write(" dma_write_chnl_rsc_dat => dma_write_chnl_data,\n") - f.write(" dma_write_chnl_rsc_vld => dma_write_chnl_valid,\n") - f.write(" dma_write_chnl_rsc_rdy => dma_write_chnl_ready,\n") + f.write("-- signals for ctrl struct unpakc\n") f.write("\n") - f.write(" acc_done_rsc_vld => acc_done\n") - f.write(" );\n") - elif is_catapulthls_sysc_if: - - f.write(" port map(\n") - f.write(" clk => clk,\n") - spacing = (27-len(rst))*" " - f.write(" " + rst + spacing + "=> acc_rst,\n") + f.write("signal dma_read_ctrl_data : std_logic_vector(95 downto 0);\n") + f.write("signal dma_write_ctrl_data : std_logic_vector(95 downto 0);\n") f.write("\n") - conf_info_size = 0 - for param in acc.param: - if not param.readonly: - conf_info_size += param.size - for param in acc.param: - if not param.readonly: - spacing = " " - if 14 - len(param.name) > 0: - spacing = (14-len(param.name))*" " - f.write(" conf_info_msg(" + str(conf_info_size-1) + " downto " + str(conf_info_size-param.size) + ") => " + "conf_info_" + param.name +",\n") - conf_info_size -= param.size - f.write(" conf_info_val => conf_info_rsc_valid,\n") - f.write(" conf_info_rdy => conf_info_rsc_ready,\n") - f.write("\n") - f.write(" dma_read_ctrl_val => dma_read_ctrl_valid,\n") - f.write(" dma_read_ctrl_rdy => dma_read_ctrl_ready,\n") - f.write(" dma_read_ctrl_msg(" + str(66) + " downto " + str(64) + ") => dma_read_ctrl_data_size,\n") - f.write(" dma_read_ctrl_msg(" + str(63) + " downto " + str(32) + ") => dma_read_ctrl_data_length,\n") - f.write(" dma_read_ctrl_msg(" + str(31) + " downto " + str(0) + ") => dma_read_ctrl_data_index,\n") - f.write(" dma_write_ctrl_val => dma_write_ctrl_valid,\n") - f.write(" dma_write_ctrl_rdy => dma_write_ctrl_ready,\n") - f.write(" dma_write_ctrl_msg(" + str(66) + " downto " + str(64) + ") => dma_write_ctrl_data_size,\n") - f.write(" dma_write_ctrl_msg(" + str(63) + " downto " + str(32) + ") => dma_write_ctrl_data_length,\n") - f.write(" dma_write_ctrl_msg(" + str(31) + " downto " + str(0) + ") => dma_write_ctrl_data_index,\n") - f.write(" dma_read_chnl_val => dma_read_chnl_valid,\n") - f.write(" dma_read_chnl_rdy => dma_read_chnl_ready,\n") - f.write(" dma_read_chnl_msg => dma_read_chnl_data,\n") - f.write(" dma_write_chnl_val => dma_write_chnl_valid,\n") - f.write(" dma_write_chnl_rdy => dma_write_chnl_ready,\n") - f.write(" dma_write_chnl_msg => dma_write_chnl_data,\n") - f.write(" acc_done => acc_done\n") - f.write(" );\n") +def write_acc_port_map( + f, + acc, + noc_width, + datatype, + rst, + is_noc_interface, + is_vivadohls_if, + is_catapulthls_cxx_if, + is_catapulthls_sysc_if): - else: - f.write(" port map(\n") - for param in acc.param: - if not param.readonly: - spacing = " " - if 16 - len(param.name) > 0: - spacing = (16-len(param.name))*" " - if is_noc_interface: - f.write(" conf_info_" + param.name + spacing + " => " + "bank(" + acc.name.upper() + "_" + param.name.upper() + "_REG)(" + str(param.size - 1) + " downto 0),\n") + if is_vivadohls_if: + f.write(" port map(\n") + for param in acc.param: + if not param.readonly: + spacing = " " + if 16 - len(param.name) > 0: + spacing = (16 - len(param.name)) * " " + if is_noc_interface: + f.write(" conf_info_" + + param.name + + spacing + + " => " + + "bank(" + + acc.name.upper() + + "_" + + param.name.upper() + + "_REG)(" + + str(param.size - + 1) + + " downto 0),\n") + else: + f.write( + " conf_info_" + + param.name + + spacing + + " => " + + "conf_info_" + + param.name + + ",\n") + f.write(" ap_clk => clk,\n") + f.write(" ap_rst => ap_rst,\n") + f.write(" ap_start => ap_start,\n") + f.write(" load_ctrl_ap_vld => dma_read_ctrl_valid,\n") + f.write(" load_ctrl_ap_ack => dma_read_ctrl_ready,\n") + f.write(" load_ctrl => dma_read_ctrl_data,\n") + f.write(" store_ctrl_ap_vld => dma_write_ctrl_valid,\n") + f.write(" store_ctrl_ap_ack => dma_write_ctrl_ready,\n") + f.write(" store_ctrl => dma_write_ctrl_data,\n") + if datatype == 'float': + f.write(" in1_word_empty_n => dma_read_chnl_valid,\n") + f.write(" in1_word_read => dma_read_chnl_ready,\n") + f.write(" in1_word_dout => dma_read_chnl_data,\n") + f.write(" out_word_write => dma_write_chnl_valid,\n") + f.write(" out_word_full_n => dma_write_chnl_ready,\n") + f.write(" out_word_din => dma_write_chnl_data,\n") else: - f.write(" conf_info_" + param.name + spacing + " => " + "conf_info_" + param.name +",\n") - f.write(" clk => clk,\n") - spacing = (27-len(rst))*" " - f.write(" " + rst + spacing + "=> acc_rst,\n") - f.write(" conf_done => conf_done,\n") - f.write(" dma_read_ctrl_valid => dma_read_ctrl_valid,\n") - f.write(" dma_read_ctrl_ready => dma_read_ctrl_ready,\n") - f.write(" dma_read_ctrl_data_index => dma_read_ctrl_data_index,\n") - f.write(" dma_read_ctrl_data_length => dma_read_ctrl_data_length,\n") - f.write(" dma_read_ctrl_data_size => dma_read_ctrl_data_size,\n") - f.write(" dma_write_ctrl_valid => dma_write_ctrl_valid,\n") - f.write(" dma_write_ctrl_ready => dma_write_ctrl_ready,\n") - f.write(" dma_write_ctrl_data_index => dma_write_ctrl_data_index,\n") - f.write(" dma_write_ctrl_data_length => dma_write_ctrl_data_length,\n") - f.write(" dma_write_ctrl_data_size => dma_write_ctrl_data_size,\n") - f.write(" dma_read_chnl_valid => dma_read_chnl_valid,\n") - f.write(" dma_read_chnl_ready => dma_read_chnl_ready,\n") - f.write(" dma_read_chnl_data => dma_read_chnl_data,\n") - f.write(" dma_write_chnl_valid => dma_write_chnl_valid,\n") - f.write(" dma_write_chnl_ready => dma_write_chnl_ready,\n") - f.write(" dma_write_chnl_data => dma_write_chnl_data,\n") - f.write(" acc_done => acc_done\n") - f.write(" );\n") + f.write(" in1_word_V_empty_n => dma_read_chnl_valid,\n") + f.write(" in1_word_V_read => dma_read_chnl_ready,\n") + f.write(" in1_word_V_dout => dma_read_chnl_data,\n") + f.write(" out_word_V_write => dma_write_chnl_valid,\n") + f.write(" out_word_V_full_n => dma_write_chnl_ready,\n") + f.write(" out_word_V_din => dma_write_chnl_data,\n") + f.write(" ap_done => ap_done,\n") + f.write(" ap_idle => ap_idle,\n") + f.write(" ap_ready => ap_ready\n") + f.write(" );\n") + f.write("\n") + f.write(" ap_rst <= not acc_rst;\n") + f.write(" acc_done <= ap_done;\n") + f.write("\n") + f.write(" -- START FSM\n") + f.write("\n") + f.write( + " ap_acc_fsm: process (ap_state, conf_done, ap_idle, ap_ready, ap_done) is\n") + f.write(" begin -- process ap_acc_fsm\n") + f.write(" ap_next <= ap_state;\n") + f.write(" ap_start <= '0';\n") + f.write("\n") + f.write(" case ap_state is\n") + f.write("\n") + f.write(" when aps_idle =>\n") + f.write(" if (ap_idle and conf_done) = '1' then\n") + f.write(" ap_next <= aps_starting;\n") + f.write(" end if;\n") + f.write("\n") + f.write(" when aps_starting =>\n") + f.write(" ap_start <= '1';\n") + f.write(" if ap_ready = '1' then\n") + f.write(" ap_next <= aps_wait_for_completion;\n") + f.write(" elsif ap_idle = '0' then\n") + f.write(" ap_next <= aps_running;\n") + f.write(" end if;\n") + f.write("\n") + f.write(" when aps_running =>\n") + f.write(" ap_start <= '1';\n") + f.write(" if ap_done = '1' then\n") + f.write(" ap_next <= aps_idle;\n") + f.write(" elsif ap_ready = '1' then\n") + f.write(" ap_next <= aps_wait_for_completion;\n") + f.write(" end if;\n") + f.write("\n") + f.write(" when aps_wait_for_completion =>\n") + f.write(" if ap_done = '1' then\n") + f.write(" ap_next <= aps_idle;\n") + f.write(" end if;\n") + f.write("\n") + f.write(" when others =>\n") + f.write(" ap_next <= aps_idle;\n") + f.write("\n") + f.write(" end case;\n") + f.write(" end process ap_acc_fsm;\n") + f.write("\n") + f.write(" ap_acc_state_update: process (clk, ap_rst) is\n") + f.write(" begin -- process ap_acc_state_update\n") + f.write(" if clk'event and clk = '1' then -- rising clock edge\n") + f.write( + " if ap_rst = '1' then -- synchronous active high\n") + f.write(" ap_state <= aps_idle;\n") + f.write(" else\n") + f.write(" ap_state <= ap_next;\n") + f.write(" end if;\n") + f.write(" end if;\n") + f.write(" end process ap_acc_state_update;\n") + f.write("\n") + f.write(" ---- CTRL FSM\n") + f.write("\n") + f.write(" dma_read_ctrl_data_size <= dma_read_ctrl_data(66 downto 64);\n") + f.write(" dma_read_ctrl_data_length <= dma_read_ctrl_data(63 downto 32);\n") + f.write(" dma_read_ctrl_data_index <= dma_read_ctrl_data(31 downto 0);\n") + f.write(" dma_write_ctrl_data_size <= dma_write_ctrl_data(66 downto 64);\n") + f.write(" dma_write_ctrl_data_length <= dma_write_ctrl_data(63 downto 32);\n") + f.write(" dma_write_ctrl_data_index <= dma_write_ctrl_data(31 downto 0);\n") + f.write("\n") + elif is_catapulthls_cxx_if: + f.write(" port map(\n") + f.write(" clk => clk,\n") + spacing = (27 - len(rst)) * " " + f.write(" " + rst + spacing + "=> acc_rst,\n") + f.write("\n") + conf_info_rsc_data_size = 0 + for param in acc.param: + if not param.readonly: + conf_info_rsc_data_size += param.size + for param in acc.param: + if not param.readonly: + spacing = " " + if 14 - len(param.name) > 0: + spacing = (14 - len(param.name)) * " " + f.write(" conf_info_rsc_dat(" + + str(conf_info_rsc_data_size - + 1) + + " downto " + + str(conf_info_rsc_data_size - + param.size) + + ") => " + + "conf_info_" + + param.name + + ",\n") + conf_info_rsc_data_size -= param.size + f.write(" conf_info_rsc_vld => conf_info_rsc_valid,\n") + f.write(" conf_info_rsc_rdy => conf_info_rsc_ready,\n") + f.write("\n") + f.write( + " dma_read_ctrl_rsc_dat(66 downto 64) => dma_read_ctrl_data_size,\n") + f.write( + " dma_read_ctrl_rsc_dat(63 downto 32) => dma_read_ctrl_data_length,\n") + f.write( + " dma_read_ctrl_rsc_dat(31 downto 0) => dma_read_ctrl_data_index,\n") + f.write(" dma_read_ctrl_rsc_vld => dma_read_ctrl_valid,\n") + f.write(" dma_read_ctrl_rsc_rdy => dma_read_ctrl_ready,\n") + f.write("\n") + f.write( + " dma_write_ctrl_rsc_dat(" + + str(66) + + " downto " + + str(64) + + ") => dma_write_ctrl_data_size,\n"), + f.write( + " dma_write_ctrl_rsc_dat(" + + str(63) + + " downto " + + str(32) + + ") => dma_write_ctrl_data_length,\n") + f.write(" dma_write_ctrl_rsc_dat(" + str(31) + + " downto 0) => dma_write_ctrl_data_index,\n") + f.write(" dma_write_ctrl_rsc_vld => dma_write_ctrl_valid,\n") + f.write(" dma_write_ctrl_rsc_rdy => dma_write_ctrl_ready,\n") + f.write("\n") + f.write(" dma_read_chnl_rsc_dat => dma_read_chnl_data,\n") + f.write(" dma_read_chnl_rsc_vld => dma_read_chnl_valid,\n") + f.write(" dma_read_chnl_rsc_rdy => dma_read_chnl_ready,\n") + f.write("\n") + f.write(" dma_write_chnl_rsc_dat => dma_write_chnl_data,\n") + f.write(" dma_write_chnl_rsc_vld => dma_write_chnl_valid,\n") + f.write(" dma_write_chnl_rsc_rdy => dma_write_chnl_ready,\n") + f.write("\n") + f.write(" acc_done_rsc_vld => acc_done\n") + f.write(" );\n") + elif is_catapulthls_sysc_if: + + f.write(" port map(\n") + f.write(" clk => clk,\n") + spacing = (27 - len(rst)) * " " + f.write(" " + rst + spacing + "=> acc_rst,\n") + f.write("\n") + conf_info_size = 0 + + for param in acc.param: + if not param.readonly: + conf_info_size += param.size + for param in acc.param: + if not param.readonly: + spacing = " " + if 14 - len(param.name) > 0: + spacing = (14 - len(param.name)) * " " + f.write(" conf_info_msg(" + + str(conf_info_size - + 1) + + " downto " + + str(conf_info_size - + param.size) + + ") => " + + "conf_info_" + + param.name + + ",\n") + conf_info_size -= param.size + + f.write(" conf_info_val => conf_info_rsc_valid,\n") + f.write(" conf_info_rdy => conf_info_rsc_ready,\n") + f.write("\n") + f.write(" dma_read_ctrl_val => dma_read_ctrl_valid,\n") + f.write(" dma_read_ctrl_rdy => dma_read_ctrl_ready,\n") + f.write( + " dma_read_ctrl_msg(" + + str(66) + + " downto " + + str(64) + + ") => dma_read_ctrl_data_size,\n") + f.write( + " dma_read_ctrl_msg(" + + str(63) + + " downto " + + str(32) + + ") => dma_read_ctrl_data_length,\n") + f.write( + " dma_read_ctrl_msg(" + + str(31) + + " downto " + + str(0) + + ") => dma_read_ctrl_data_index,\n") + f.write(" dma_write_ctrl_val => dma_write_ctrl_valid,\n") + f.write(" dma_write_ctrl_rdy => dma_write_ctrl_ready,\n") + f.write( + " dma_write_ctrl_msg(" + + str(66) + + " downto " + + str(64) + + ") => dma_write_ctrl_data_size,\n") + f.write( + " dma_write_ctrl_msg(" + + str(63) + + " downto " + + str(32) + + ") => dma_write_ctrl_data_length,\n") + f.write( + " dma_write_ctrl_msg(" + + str(31) + + " downto " + + str(0) + + ") => dma_write_ctrl_data_index,\n") + f.write(" dma_read_chnl_val => dma_read_chnl_valid,\n") + f.write(" dma_read_chnl_rdy => dma_read_chnl_ready,\n") + f.write(" dma_read_chnl_msg => dma_read_chnl_data,\n") + f.write(" dma_write_chnl_val => dma_write_chnl_valid,\n") + f.write(" dma_write_chnl_rdy => dma_write_chnl_ready,\n") + f.write(" dma_write_chnl_msg => dma_write_chnl_data,\n") + f.write(" acc_done => acc_done\n") + f.write(" );\n") + + else: + f.write(" port map(\n") + for param in acc.param: + if not param.readonly: + spacing = " " + if 16 - len(param.name) > 0: + spacing = (16 - len(param.name)) * " " + if is_noc_interface: + f.write(" conf_info_" + + param.name + + spacing + + " => " + + "bank(" + + acc.name.upper() + + "_" + + param.name.upper() + + "_REG)(" + + str(param.size - + 1) + + " downto 0),\n") + else: + f.write( + " conf_info_" + + param.name + + spacing + + " => " + + "conf_info_" + + param.name + + ",\n") + f.write(" clk => clk,\n") + spacing = (27 - len(rst)) * " " + f.write(" " + rst + spacing + "=> acc_rst,\n") + f.write(" conf_done => conf_done,\n") + f.write(" dma_read_ctrl_valid => dma_read_ctrl_valid,\n") + f.write(" dma_read_ctrl_ready => dma_read_ctrl_ready,\n") + f.write(" dma_read_ctrl_data_index => dma_read_ctrl_data_index,\n") + f.write(" dma_read_ctrl_data_length => dma_read_ctrl_data_length,\n") + f.write(" dma_read_ctrl_data_size => dma_read_ctrl_data_size,\n") + f.write(" dma_write_ctrl_valid => dma_write_ctrl_valid,\n") + f.write(" dma_write_ctrl_ready => dma_write_ctrl_ready,\n") + f.write(" dma_write_ctrl_data_index => dma_write_ctrl_data_index,\n") + f.write(" dma_write_ctrl_data_length => dma_write_ctrl_data_length,\n") + f.write(" dma_write_ctrl_data_size => dma_write_ctrl_data_size,\n") + f.write(" dma_read_chnl_valid => dma_read_chnl_valid,\n") + f.write(" dma_read_chnl_ready => dma_read_chnl_ready,\n") + f.write(" dma_read_chnl_data => dma_read_chnl_data,\n") + f.write(" dma_write_chnl_valid => dma_write_chnl_valid,\n") + f.write(" dma_write_chnl_ready => dma_write_chnl_ready,\n") + f.write(" dma_write_chnl_data => dma_write_chnl_data,\n") + f.write(" acc_done => acc_done\n") + f.write(" );\n") # TODO replace all hardcoded vector lengths with constants def write_cache_interface(f, cac, is_llc): - if (is_llc and 'spandex' not in cac.name): - f.write(" clk : in std_ulogic;\n") - f.write(" rst : in std_ulogic;\n") - f.write(" llc_req_in_valid : in std_ulogic;\n") - f.write(" llc_req_in_data_coh_msg : in std_logic_vector(2 downto 0);\n") - f.write(" llc_req_in_data_hprot : in std_logic_vector(1 downto 0);\n") - f.write(" llc_req_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_req_in_data_word_offset : in std_logic_vector(" + str(word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_req_in_data_valid_words : in std_logic_vector(" + str(word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_req_in_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_req_in_data_req_id : in std_logic_vector(3 downto 0);\n") - f.write(" llc_dma_req_in_valid : in std_ulogic;\n") - f.write(" llc_dma_req_in_data_coh_msg : in std_logic_vector(2 downto 0);\n") - f.write(" llc_dma_req_in_data_hprot : in std_logic_vector(1 downto 0);\n") - f.write(" llc_dma_req_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_req_in_data_word_offset : in std_logic_vector(" + str(dma_word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_req_in_data_valid_words : in std_logic_vector(" + str(dma_word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_req_in_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_dma_req_in_data_req_id : in std_logic_vector(5 downto 0);\n") - f.write(" llc_rsp_in_valid : in std_ulogic;\n") - f.write(" llc_rsp_in_data_coh_msg : in std_logic_vector(1 downto 0);\n") - f.write(" llc_rsp_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_rsp_in_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_rsp_in_data_req_id : in std_logic_vector(3 downto 0);\n") - f.write(" llc_mem_rsp_valid : in std_ulogic;\n") - f.write(" llc_mem_rsp_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_rst_tb_valid : in std_ulogic;\n") - f.write(" llc_rst_tb_data : in std_ulogic;\n") - f.write(" llc_rsp_out_ready : in std_ulogic;\n") - f.write(" llc_dma_rsp_out_ready : in std_ulogic;\n") - f.write(" llc_fwd_out_ready : in std_ulogic;\n") - f.write(" llc_mem_req_ready : in std_ulogic;\n") - f.write(" llc_rst_tb_done_ready : in std_ulogic;\n") - f.write(" llc_stats_ready : in std_ulogic;\n") - f.write(" llc_req_in_ready : out std_ulogic;\n") - f.write(" llc_dma_req_in_ready : out std_ulogic;\n") - f.write(" llc_rsp_in_ready : out std_ulogic;\n") - f.write(" llc_mem_rsp_ready : out std_ulogic;\n") - f.write(" llc_rst_tb_ready : out std_ulogic;\n") - f.write(" llc_rsp_out_valid : out std_ulogic;\n") - f.write(" llc_rsp_out_data_coh_msg : out std_logic_vector(1 downto 0);\n") - f.write(" llc_rsp_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_rsp_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_rsp_out_data_invack_cnt : out std_logic_vector(" + str(invack_cnt_bits - 1) + " downto 0);\n") - f.write(" llc_rsp_out_data_req_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_rsp_out_data_dest_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_rsp_out_data_word_offset : out std_logic_vector(" + str(word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_rsp_out_valid : out std_ulogic;\n") - f.write(" llc_dma_rsp_out_data_coh_msg : out std_logic_vector(1 downto 0);\n") - f.write(" llc_dma_rsp_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_rsp_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_dma_rsp_out_data_invack_cnt : out std_logic_vector(" + str(invack_cnt_bits - 1) + " downto 0);\n") - f.write(" llc_dma_rsp_out_data_req_id : out std_logic_vector(5 downto 0);\n") - f.write(" llc_dma_rsp_out_data_dest_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_dma_rsp_out_data_word_offset : out std_logic_vector(" + str(dma_word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_fwd_out_valid : out std_ulogic;\n") - f.write(" llc_fwd_out_data_coh_msg : out std_logic_vector(2 downto 0);\n") - f.write(" llc_fwd_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_fwd_out_data_req_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_fwd_out_data_dest_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_mem_req_valid : out std_ulogic;\n") - f.write(" llc_mem_req_data_hwrite : out std_ulogic;\n") - f.write(" llc_mem_req_data_hsize : out std_logic_vector(2 downto 0);\n") - f.write(" llc_mem_req_data_hprot : out std_logic_vector(1 downto 0);\n") - f.write(" llc_mem_req_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_mem_req_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_stats_valid : out std_ulogic;\n") - f.write(" llc_stats_data : out std_ulogic;\n") - f.write(" llc_rst_tb_done_valid : out std_ulogic;\n") - f.write(" llc_rst_tb_done_data : out std_ulogic\n") - elif (is_llc and 'spandex' in cac.name): - f.write(" clk : in std_ulogic;\n") - f.write(" rst : in std_ulogic;\n") - f.write(" llc_req_in_valid : in std_ulogic;\n") - f.write(" llc_req_in_data_coh_msg : in std_logic_vector(4 downto 0);\n") - f.write(" llc_req_in_data_hprot : in std_logic_vector(1 downto 0);\n") - f.write(" llc_req_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_req_in_data_word_offset : in std_logic_vector(" + str(word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_req_in_data_valid_words : in std_logic_vector(" + str(word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_req_in_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_req_in_data_word_mask : in std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" llc_req_in_data_req_id : in std_logic_vector(3 downto 0);\n") - f.write(" llc_dma_req_in_valid : in std_ulogic;\n") - f.write(" llc_dma_req_in_data_coh_msg : in std_logic_vector(4 downto 0);\n") - f.write(" llc_dma_req_in_data_hprot : in std_logic_vector(1 downto 0);\n") - f.write(" llc_dma_req_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_req_in_data_word_offset : in std_logic_vector(" + str(dma_word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_req_in_data_valid_words : in std_logic_vector(" + str(dma_word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_req_in_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_dma_req_in_data_req_id : in std_logic_vector(5 downto 0);\n") - f.write(" llc_dma_req_in_data_word_mask : in std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" llc_rsp_in_valid : in std_ulogic;\n") - f.write(" llc_rsp_in_data_coh_msg : in std_logic_vector(3 downto 0);\n") - f.write(" llc_rsp_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_rsp_in_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_rsp_in_data_word_mask : in std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" llc_rsp_in_data_req_id : in std_logic_vector(3 downto 0);\n") - f.write(" llc_mem_rsp_valid : in std_ulogic;\n") - f.write(" llc_mem_rsp_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_rst_tb_valid : in std_ulogic;\n") - f.write(" llc_rst_tb_data : in std_ulogic;\n") - f.write(" llc_rsp_out_ready : in std_ulogic;\n") - f.write(" llc_dma_rsp_out_ready : in std_ulogic;\n") - f.write(" llc_fwd_out_ready : in std_ulogic;\n") - f.write(" llc_mem_req_ready : in std_ulogic;\n") - f.write(" llc_rst_tb_done_ready : in std_ulogic;\n") - f.write(" llc_stats_ready : in std_ulogic;\n") - f.write(" llc_req_in_ready : out std_ulogic;\n") - f.write(" llc_dma_req_in_ready : out std_ulogic;\n") - f.write(" llc_rsp_in_ready : out std_ulogic;\n") - f.write(" llc_mem_rsp_ready : out std_ulogic;\n") - f.write(" llc_rst_tb_ready : out std_ulogic;\n") - f.write(" llc_rsp_out_valid : out std_ulogic;\n") - f.write(" llc_rsp_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") - f.write(" llc_rsp_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_rsp_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_rsp_out_data_word_mask : out std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" llc_rsp_out_data_invack_cnt : out std_logic_vector(" + str(invack_cnt_bits - 1) + " downto 0);\n") - f.write(" llc_rsp_out_data_req_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_rsp_out_data_dest_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_rsp_out_data_word_offset : out std_logic_vector(" + str(word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_rsp_out_valid : out std_ulogic;\n") - f.write(" llc_dma_rsp_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") - f.write(" llc_dma_rsp_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_rsp_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_dma_rsp_out_data_invack_cnt : out std_logic_vector(" + str(invack_cnt_bits - 1) + " downto 0);\n") - f.write(" llc_dma_rsp_out_data_req_id : out std_logic_vector(5 downto 0);\n") - f.write(" llc_dma_rsp_out_data_dest_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_dma_rsp_out_data_word_offset : out std_logic_vector(" + str(dma_word_offset_bits - 1) + " downto 0);\n") - f.write(" llc_dma_rsp_out_data_word_mask : out std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" llc_fwd_out_valid : out std_ulogic;\n") - f.write(" llc_fwd_out_data_coh_msg : out std_logic_vector(4 downto 0);\n") - f.write(" llc_fwd_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_fwd_out_data_req_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_fwd_out_data_dest_id : out std_logic_vector(3 downto 0);\n") - f.write(" llc_fwd_out_data_word_mask : out std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" llc_fwd_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_mem_req_valid : out std_ulogic;\n") - f.write(" llc_mem_req_data_hwrite : out std_ulogic;\n") - f.write(" llc_mem_req_data_hsize : out std_logic_vector(2 downto 0);\n") - f.write(" llc_mem_req_data_hprot : out std_logic_vector(1 downto 0);\n") - f.write(" llc_mem_req_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" llc_mem_req_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" llc_stats_valid : out std_ulogic;\n") - f.write(" llc_stats_data : out std_ulogic;\n") - f.write(" llc_rst_tb_done_valid : out std_ulogic;\n") - f.write(" llc_rst_tb_done_data : out std_ulogic\n") - elif (not is_llc and 'spandex' in cac.name): - f.write(" clk : in std_ulogic;\n") - f.write(" rst : in std_ulogic;\n") - f.write(" l2_cpu_req_valid : in std_ulogic;\n") - f.write(" l2_cpu_req_data_cpu_msg : in std_logic_vector(1 downto 0);\n") - f.write(" l2_cpu_req_data_hsize : in std_logic_vector(2 downto 0);\n") - f.write(" l2_cpu_req_data_hprot : in std_logic_vector(1 downto 0);\n") - f.write(" l2_cpu_req_data_addr : in std_logic_vector(" + str(phys_addr_bits - 1) + " downto 0);\n") - f.write(" l2_cpu_req_data_word : in std_logic_vector(" + str(arch_bits - 1) + " downto 0);\n") - f.write(" l2_cpu_req_data_amo : in std_logic_vector(5 downto 0);\n") - f.write(" l2_cpu_req_data_aq : in std_ulogic;\n") - f.write(" l2_cpu_req_data_rl : in std_ulogic;\n") - f.write(" l2_cpu_req_data_dcs_en : in std_ulogic;\n") - f.write(" l2_cpu_req_data_use_owner_pred : in std_ulogic;\n") - f.write(" l2_cpu_req_data_dcs : in std_logic_vector(1 downto 0);\n") - f.write(" l2_cpu_req_data_pred_cid : in std_logic_vector(3 downto 0);\n") - f.write(" l2_fwd_in_valid : in std_ulogic;\n") - f.write(" l2_fwd_in_data_coh_msg : in std_logic_vector(4 downto 0);\n") - f.write(" l2_fwd_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" l2_fwd_in_data_req_id : in std_logic_vector(3 downto 0);\n") - f.write(" l2_fwd_in_data_word_mask : in std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" l2_fwd_in_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_rsp_in_valid : in std_ulogic;\n") - f.write(" l2_rsp_in_data_coh_msg : in std_logic_vector(3 downto 0);\n") - f.write(" l2_rsp_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" l2_rsp_in_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_rsp_in_data_word_mask : in std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" l2_rsp_in_data_invack_cnt : in std_logic_vector(" + str(invack_cnt_bits - 1) + " downto 0);\n") - f.write(" l2_flush_valid : in std_ulogic;\n") - f.write(" l2_flush_data : in std_ulogic;\n") - f.write(" l2_rd_rsp_ready : in std_ulogic;\n") - f.write(" l2_inval_ready : in std_ulogic;\n") - f.write(" l2_bresp_ready : in std_ulogic;\n") - f.write(" l2_req_out_ready : in std_ulogic;\n") - f.write(" l2_rsp_out_ready : in std_ulogic;\n") - f.write(" l2_fwd_out_ready : in std_ulogic;\n") - f.write(" l2_stats_ready : in std_ulogic;\n") - f.write(" flush_done : out std_ulogic;\n") - f.write(" acc_flush_done : out std_ulogic;\n") - f.write(" l2_cpu_req_ready : out std_ulogic;\n") - f.write(" l2_fwd_in_ready : out std_ulogic;\n") - f.write(" l2_rsp_in_ready : out std_ulogic;\n") - f.write(" l2_flush_ready : out std_ulogic;\n") - f.write(" l2_rd_rsp_valid : out std_ulogic;\n") - f.write(" l2_rd_rsp_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_inval_valid : out std_ulogic;\n") - f.write(" l2_inval_data_addr : out std_logic_vector(" + str(phys_addr_bits - 1) + " downto 0);\n") - f.write(" l2_inval_data_hprot : out std_logic_vector(1 downto 0);\n") - f.write(" l2_bresp_valid : out std_ulogic;\n") - f.write(" l2_bresp_data : out std_logic_vector(1 downto 0);\n") - f.write(" l2_req_out_valid : out std_ulogic;\n") - f.write(" l2_req_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") - f.write(" l2_req_out_data_hprot : out std_logic_vector(1 downto 0);\n") - f.write(" l2_req_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" l2_req_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_req_out_data_word_mask : out std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" l2_rsp_out_valid : out std_ulogic;\n") - f.write(" l2_rsp_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") - f.write(" l2_rsp_out_data_req_id : out std_logic_vector(3 downto 0);\n") - f.write(" l2_rsp_out_data_to_req : out std_logic_vector(1 downto 0);\n") - f.write(" l2_rsp_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" l2_rsp_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_rsp_out_data_word_mask : out std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" l2_fwd_out_valid : out std_ulogic;\n") - f.write(" l2_fwd_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") - f.write(" l2_fwd_out_data_req_id : out std_logic_vector(3 downto 0);\n") - f.write(" l2_fwd_out_data_to_req : out std_logic_vector(1 downto 0);\n") - f.write(" l2_fwd_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" l2_fwd_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_fwd_out_data_word_mask : out std_logic_vector(" + str(words_per_line - 1) + " downto 0);\n") - f.write(" l2_stats_valid : out std_ulogic;\n") - f.write(" l2_stats_data : out std_ulogic;\n") - f.write(" l2_fence_ready : out std_ulogic;\n") - f.write(" l2_fence_valid : in std_ulogic;\n") - f.write(" l2_fence_data : in std_logic_vector(1 downto 0)\n") - elif (not is_llc and 'spandex' not in cac.name): - f.write(" clk : in std_ulogic;\n") - f.write(" rst : in std_ulogic;\n") - f.write(" l2_cpu_req_valid : in std_ulogic;\n") - f.write(" l2_cpu_req_data_cpu_msg : in std_logic_vector(1 downto 0);\n") - f.write(" l2_cpu_req_data_hsize : in std_logic_vector(2 downto 0);\n") - f.write(" l2_cpu_req_data_hprot : in std_logic_vector(1 downto 0);\n") - f.write(" l2_cpu_req_data_addr : in std_logic_vector(" + str(phys_addr_bits - 1) + " downto 0);\n") - f.write(" l2_cpu_req_data_word : in std_logic_vector(" + str(arch_bits - 1) + " downto 0);\n") - f.write(" l2_cpu_req_data_amo : in std_logic_vector(5 downto 0);\n") - f.write(" l2_fwd_in_valid : in std_ulogic;\n") - f.write(" l2_fwd_in_data_coh_msg : in std_logic_vector(2 downto 0);\n") - f.write(" l2_fwd_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" l2_fwd_in_data_req_id : in std_logic_vector(3 downto 0);\n") - f.write(" l2_rsp_in_valid : in std_ulogic;\n") - f.write(" l2_rsp_in_data_coh_msg : in std_logic_vector(1 downto 0);\n") - f.write(" l2_rsp_in_data_addr : in std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" l2_rsp_in_data_line : in std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_rsp_in_data_invack_cnt : in std_logic_vector(" + str(invack_cnt_bits - 1) + " downto 0);\n") - f.write(" l2_flush_valid : in std_ulogic;\n") - f.write(" l2_flush_data : in std_ulogic;\n") - f.write(" l2_rd_rsp_ready : in std_ulogic;\n") - f.write(" l2_inval_ready : in std_ulogic;\n") - f.write(" l2_bresp_ready : in std_ulogic;\n") - f.write(" l2_req_out_ready : in std_ulogic;\n") - f.write(" l2_rsp_out_ready : in std_ulogic;\n") - f.write(" l2_stats_ready : in std_ulogic;\n") - f.write(" flush_done : out std_ulogic;\n") - f.write(" l2_cpu_req_ready : out std_ulogic;\n") - f.write(" l2_fwd_in_ready : out std_ulogic;\n") - f.write(" l2_rsp_in_ready : out std_ulogic;\n") - f.write(" l2_flush_ready : out std_ulogic;\n") - f.write(" l2_rd_rsp_valid : out std_ulogic;\n") - f.write(" l2_rd_rsp_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_inval_valid : out std_ulogic;\n") - f.write(" l2_inval_data_addr : out std_logic_vector(" + str(phys_addr_bits - 1) + " downto 0);\n") - f.write(" l2_inval_data_hprot : out std_logic_vector(1 downto 0);\n") - f.write(" l2_bresp_valid : out std_ulogic;\n") - f.write(" l2_bresp_data : out std_logic_vector(1 downto 0);\n") - f.write(" l2_req_out_valid : out std_ulogic;\n") - f.write(" l2_req_out_data_coh_msg : out std_logic_vector(1 downto 0);\n") - f.write(" l2_req_out_data_hprot : out std_logic_vector(1 downto 0);\n") - f.write(" l2_req_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" l2_req_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_rsp_out_valid : out std_ulogic;\n") - f.write(" l2_rsp_out_data_coh_msg : out std_logic_vector(1 downto 0);\n") - f.write(" l2_rsp_out_data_req_id : out std_logic_vector(3 downto 0);\n") - f.write(" l2_rsp_out_data_to_req : out std_logic_vector(1 downto 0);\n") - f.write(" l2_rsp_out_data_addr : out std_logic_vector(" + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") - f.write(" l2_rsp_out_data_line : out std_logic_vector(" + str(bits_per_line - 1) + " downto 0);\n") - f.write(" l2_stats_valid : out std_ulogic;\n") - f.write(" l2_stats_data : out std_ulogic\n") + if (is_llc and 'spandex' not in cac.name): + f.write(" clk : in std_ulogic;\n") + f.write(" rst : in std_ulogic;\n") + f.write(" llc_req_in_valid : in std_ulogic;\n") + f.write( + " llc_req_in_data_coh_msg : in std_logic_vector(2 downto 0);\n") + f.write( + " llc_req_in_data_hprot : in std_logic_vector(1 downto 0);\n") + f.write(" llc_req_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_req_in_data_word_offset : in std_logic_vector(" + + str(word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_req_in_data_valid_words : in std_logic_vector(" + + str(word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_req_in_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write( + " llc_req_in_data_req_id : in std_logic_vector(3 downto 0);\n") + f.write(" llc_dma_req_in_valid : in std_ulogic;\n") + f.write( + " llc_dma_req_in_data_coh_msg : in std_logic_vector(2 downto 0);\n") + f.write( + " llc_dma_req_in_data_hprot : in std_logic_vector(1 downto 0);\n") + f.write(" llc_dma_req_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_req_in_data_word_offset : in std_logic_vector(" + + str(dma_word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_req_in_data_valid_words : in std_logic_vector(" + + str(dma_word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_req_in_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write( + " llc_dma_req_in_data_req_id : in std_logic_vector(5 downto 0);\n") + f.write(" llc_rsp_in_valid : in std_ulogic;\n") + f.write( + " llc_rsp_in_data_coh_msg : in std_logic_vector(1 downto 0);\n") + f.write(" llc_rsp_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_rsp_in_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write( + " llc_rsp_in_data_req_id : in std_logic_vector(3 downto 0);\n") + f.write(" llc_mem_rsp_valid : in std_ulogic;\n") + f.write(" llc_mem_rsp_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_rst_tb_valid : in std_ulogic;\n") + f.write(" llc_rst_tb_data : in std_ulogic;\n") + f.write(" llc_rsp_out_ready : in std_ulogic;\n") + f.write(" llc_dma_rsp_out_ready : in std_ulogic;\n") + f.write(" llc_fwd_out_ready : in std_ulogic;\n") + f.write(" llc_mem_req_ready : in std_ulogic;\n") + f.write(" llc_rst_tb_done_ready : in std_ulogic;\n") + f.write(" llc_stats_ready : in std_ulogic;\n") + f.write(" llc_req_in_ready : out std_ulogic;\n") + f.write(" llc_dma_req_in_ready : out std_ulogic;\n") + f.write(" llc_rsp_in_ready : out std_ulogic;\n") + f.write(" llc_mem_rsp_ready : out std_ulogic;\n") + f.write(" llc_rst_tb_ready : out std_ulogic;\n") + f.write(" llc_rsp_out_valid : out std_ulogic;\n") + f.write( + " llc_rsp_out_data_coh_msg : out std_logic_vector(1 downto 0);\n") + f.write(" llc_rsp_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_rsp_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_rsp_out_data_invack_cnt : out std_logic_vector(" + + str(invack_cnt_bits - 1) + " downto 0);\n") + f.write( + " llc_rsp_out_data_req_id : out std_logic_vector(3 downto 0);\n") + f.write( + " llc_rsp_out_data_dest_id : out std_logic_vector(3 downto 0);\n") + f.write(" llc_rsp_out_data_word_offset : out std_logic_vector(" + + str(word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_rsp_out_valid : out std_ulogic;\n") + f.write( + " llc_dma_rsp_out_data_coh_msg : out std_logic_vector(1 downto 0);\n") + f.write(" llc_dma_rsp_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_rsp_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_dma_rsp_out_data_invack_cnt : out std_logic_vector(" + + str(invack_cnt_bits - 1) + " downto 0);\n") + f.write( + " llc_dma_rsp_out_data_req_id : out std_logic_vector(5 downto 0);\n") + f.write( + " llc_dma_rsp_out_data_dest_id : out std_logic_vector(3 downto 0);\n") + f.write(" llc_dma_rsp_out_data_word_offset : out std_logic_vector(" + + str(dma_word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_fwd_out_valid : out std_ulogic;\n") + f.write( + " llc_fwd_out_data_coh_msg : out std_logic_vector(2 downto 0);\n") + f.write(" llc_fwd_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write( + " llc_fwd_out_data_req_id : out std_logic_vector(3 downto 0);\n") + f.write( + " llc_fwd_out_data_dest_id : out std_logic_vector(3 downto 0);\n") + f.write(" llc_mem_req_valid : out std_ulogic;\n") + f.write(" llc_mem_req_data_hwrite : out std_ulogic;\n") + f.write( + " llc_mem_req_data_hsize : out std_logic_vector(2 downto 0);\n") + f.write( + " llc_mem_req_data_hprot : out std_logic_vector(1 downto 0);\n") + f.write(" llc_mem_req_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_mem_req_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_stats_valid : out std_ulogic;\n") + f.write(" llc_stats_data : out std_ulogic;\n") + f.write(" llc_rst_tb_done_valid : out std_ulogic;\n") + f.write(" llc_rst_tb_done_data : out std_ulogic\n") + elif (is_llc and 'spandex' in cac.name): + f.write(" clk : in std_ulogic;\n") + f.write(" rst : in std_ulogic;\n") + f.write(" llc_req_in_valid : in std_ulogic;\n") + f.write( + " llc_req_in_data_coh_msg : in std_logic_vector(4 downto 0);\n") + f.write( + " llc_req_in_data_hprot : in std_logic_vector(1 downto 0);\n") + f.write(" llc_req_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_req_in_data_word_offset : in std_logic_vector(" + + str(word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_req_in_data_valid_words : in std_logic_vector(" + + str(word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_req_in_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_req_in_data_word_mask : in std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write( + " llc_req_in_data_req_id : in std_logic_vector(3 downto 0);\n") + f.write(" llc_dma_req_in_valid : in std_ulogic;\n") + f.write( + " llc_dma_req_in_data_coh_msg : in std_logic_vector(4 downto 0);\n") + f.write( + " llc_dma_req_in_data_hprot : in std_logic_vector(1 downto 0);\n") + f.write(" llc_dma_req_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_req_in_data_word_offset : in std_logic_vector(" + + str(dma_word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_req_in_data_valid_words : in std_logic_vector(" + + str(dma_word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_req_in_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write( + " llc_dma_req_in_data_req_id : in std_logic_vector(5 downto 0);\n") + f.write(" llc_dma_req_in_data_word_mask : in std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write(" llc_rsp_in_valid : in std_ulogic;\n") + f.write( + " llc_rsp_in_data_coh_msg : in std_logic_vector(3 downto 0);\n") + f.write(" llc_rsp_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_rsp_in_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_rsp_in_data_word_mask : in std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write( + " llc_rsp_in_data_req_id : in std_logic_vector(3 downto 0);\n") + f.write(" llc_mem_rsp_valid : in std_ulogic;\n") + f.write(" llc_mem_rsp_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_rst_tb_valid : in std_ulogic;\n") + f.write(" llc_rst_tb_data : in std_ulogic;\n") + f.write(" llc_rsp_out_ready : in std_ulogic;\n") + f.write(" llc_dma_rsp_out_ready : in std_ulogic;\n") + f.write(" llc_fwd_out_ready : in std_ulogic;\n") + f.write(" llc_mem_req_ready : in std_ulogic;\n") + f.write(" llc_rst_tb_done_ready : in std_ulogic;\n") + f.write(" llc_stats_ready : in std_ulogic;\n") + f.write(" llc_req_in_ready : out std_ulogic;\n") + f.write(" llc_dma_req_in_ready : out std_ulogic;\n") + f.write(" llc_rsp_in_ready : out std_ulogic;\n") + f.write(" llc_mem_rsp_ready : out std_ulogic;\n") + f.write(" llc_rst_tb_ready : out std_ulogic;\n") + f.write(" llc_rsp_out_valid : out std_ulogic;\n") + f.write( + " llc_rsp_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") + f.write(" llc_rsp_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_rsp_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_rsp_out_data_word_mask : out std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write(" llc_rsp_out_data_invack_cnt : out std_logic_vector(" + + str(invack_cnt_bits - 1) + " downto 0);\n") + f.write( + " llc_rsp_out_data_req_id : out std_logic_vector(3 downto 0);\n") + f.write( + " llc_rsp_out_data_dest_id : out std_logic_vector(3 downto 0);\n") + f.write(" llc_rsp_out_data_word_offset : out std_logic_vector(" + + str(word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_rsp_out_valid : out std_ulogic;\n") + f.write( + " llc_dma_rsp_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") + f.write(" llc_dma_rsp_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_rsp_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_dma_rsp_out_data_invack_cnt : out std_logic_vector(" + + str(invack_cnt_bits - 1) + " downto 0);\n") + f.write( + " llc_dma_rsp_out_data_req_id : out std_logic_vector(5 downto 0);\n") + f.write( + " llc_dma_rsp_out_data_dest_id : out std_logic_vector(3 downto 0);\n") + f.write(" llc_dma_rsp_out_data_word_offset : out std_logic_vector(" + + str(dma_word_offset_bits - 1) + " downto 0);\n") + f.write(" llc_dma_rsp_out_data_word_mask : out std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write(" llc_fwd_out_valid : out std_ulogic;\n") + f.write( + " llc_fwd_out_data_coh_msg : out std_logic_vector(4 downto 0);\n") + f.write(" llc_fwd_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write( + " llc_fwd_out_data_req_id : out std_logic_vector(3 downto 0);\n") + f.write( + " llc_fwd_out_data_dest_id : out std_logic_vector(3 downto 0);\n") + f.write(" llc_fwd_out_data_word_mask : out std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write(" llc_fwd_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_mem_req_valid : out std_ulogic;\n") + f.write(" llc_mem_req_data_hwrite : out std_ulogic;\n") + f.write( + " llc_mem_req_data_hsize : out std_logic_vector(2 downto 0);\n") + f.write( + " llc_mem_req_data_hprot : out std_logic_vector(1 downto 0);\n") + f.write(" llc_mem_req_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" llc_mem_req_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" llc_stats_valid : out std_ulogic;\n") + f.write(" llc_stats_data : out std_ulogic;\n") + f.write(" llc_rst_tb_done_valid : out std_ulogic;\n") + f.write(" llc_rst_tb_done_data : out std_ulogic\n") + elif (not is_llc and 'spandex' in cac.name): + f.write(" clk : in std_ulogic;\n") + f.write(" rst : in std_ulogic;\n") + f.write(" l2_cpu_req_valid : in std_ulogic;\n") + f.write(" l2_cpu_req_data_cpu_msg : in std_logic_vector(1 downto 0);\n") + f.write(" l2_cpu_req_data_hsize : in std_logic_vector(2 downto 0);\n") + f.write(" l2_cpu_req_data_hprot : in std_logic_vector(1 downto 0);\n") + f.write(" l2_cpu_req_data_addr : in std_logic_vector(" + + str(phys_addr_bits - 1) + " downto 0);\n") + f.write(" l2_cpu_req_data_word : in std_logic_vector(" + + str(arch_bits - 1) + " downto 0);\n") + f.write(" l2_cpu_req_data_amo : in std_logic_vector(5 downto 0);\n") + f.write(" l2_cpu_req_data_aq : in std_ulogic;\n") + f.write(" l2_cpu_req_data_rl : in std_ulogic;\n") + f.write(" l2_cpu_req_data_dcs_en : in std_ulogic;\n") + f.write(" l2_cpu_req_data_use_owner_pred : in std_ulogic;\n") + f.write(" l2_cpu_req_data_dcs : in std_logic_vector(1 downto 0);\n") + f.write(" l2_cpu_req_data_pred_cid : in std_logic_vector(3 downto 0);\n") + f.write(" l2_fwd_in_valid : in std_ulogic;\n") + f.write(" l2_fwd_in_data_coh_msg : in std_logic_vector(4 downto 0);\n") + f.write(" l2_fwd_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" l2_fwd_in_data_req_id : in std_logic_vector(3 downto 0);\n") + f.write(" l2_fwd_in_data_word_mask : in std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write(" l2_fwd_in_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_rsp_in_valid : in std_ulogic;\n") + f.write(" l2_rsp_in_data_coh_msg : in std_logic_vector(3 downto 0);\n") + f.write(" l2_rsp_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" l2_rsp_in_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_rsp_in_data_word_mask : in std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write(" l2_rsp_in_data_invack_cnt : in std_logic_vector(" + + str(invack_cnt_bits - 1) + " downto 0);\n") + f.write(" l2_flush_valid : in std_ulogic;\n") + f.write(" l2_flush_data : in std_ulogic;\n") + f.write(" l2_rd_rsp_ready : in std_ulogic;\n") + f.write(" l2_inval_ready : in std_ulogic;\n") + f.write(" l2_bresp_ready : in std_ulogic;\n") + f.write(" l2_req_out_ready : in std_ulogic;\n") + f.write(" l2_rsp_out_ready : in std_ulogic;\n") + f.write(" l2_fwd_out_ready : in std_ulogic;\n") + f.write(" l2_stats_ready : in std_ulogic;\n") + f.write(" flush_done : out std_ulogic;\n") + f.write(" acc_flush_done : out std_ulogic;\n") + f.write(" l2_cpu_req_ready : out std_ulogic;\n") + f.write(" l2_fwd_in_ready : out std_ulogic;\n") + f.write(" l2_rsp_in_ready : out std_ulogic;\n") + f.write(" l2_flush_ready : out std_ulogic;\n") + f.write(" l2_rd_rsp_valid : out std_ulogic;\n") + f.write(" l2_rd_rsp_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_inval_valid : out std_ulogic;\n") + f.write(" l2_inval_data_addr : out std_logic_vector(" + + str(phys_addr_bits - 1) + " downto 0);\n") + f.write(" l2_inval_data_hprot : out std_logic_vector(1 downto 0);\n") + f.write(" l2_bresp_valid : out std_ulogic;\n") + f.write(" l2_bresp_data : out std_logic_vector(1 downto 0);\n") + f.write(" l2_req_out_valid : out std_ulogic;\n") + f.write(" l2_req_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") + f.write(" l2_req_out_data_hprot : out std_logic_vector(1 downto 0);\n") + f.write(" l2_req_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" l2_req_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_req_out_data_word_mask : out std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write(" l2_rsp_out_valid : out std_ulogic;\n") + f.write(" l2_rsp_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") + f.write(" l2_rsp_out_data_req_id : out std_logic_vector(3 downto 0);\n") + f.write(" l2_rsp_out_data_to_req : out std_logic_vector(1 downto 0);\n") + f.write(" l2_rsp_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" l2_rsp_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_rsp_out_data_word_mask : out std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write(" l2_fwd_out_valid : out std_ulogic;\n") + f.write(" l2_fwd_out_data_coh_msg : out std_logic_vector(3 downto 0);\n") + f.write(" l2_fwd_out_data_req_id : out std_logic_vector(3 downto 0);\n") + f.write(" l2_fwd_out_data_to_req : out std_logic_vector(1 downto 0);\n") + f.write(" l2_fwd_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" l2_fwd_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_fwd_out_data_word_mask : out std_logic_vector(" + + str(words_per_line - 1) + " downto 0);\n") + f.write(" l2_stats_valid : out std_ulogic;\n") + f.write(" l2_stats_data : out std_ulogic;\n") + f.write(" l2_fence_ready : out std_ulogic;\n") + f.write(" l2_fence_valid : in std_ulogic;\n") + f.write(" l2_fence_data : in std_logic_vector(1 downto 0)\n") + elif (not is_llc and 'spandex' not in cac.name): + f.write(" clk : in std_ulogic;\n") + f.write(" rst : in std_ulogic;\n") + f.write(" l2_cpu_req_valid : in std_ulogic;\n") + f.write(" l2_cpu_req_data_cpu_msg : in std_logic_vector(1 downto 0);\n") + f.write(" l2_cpu_req_data_hsize : in std_logic_vector(2 downto 0);\n") + f.write(" l2_cpu_req_data_hprot : in std_logic_vector(1 downto 0);\n") + f.write(" l2_cpu_req_data_addr : in std_logic_vector(" + + str(phys_addr_bits - 1) + " downto 0);\n") + f.write(" l2_cpu_req_data_word : in std_logic_vector(" + + str(arch_bits - 1) + " downto 0);\n") + f.write(" l2_cpu_req_data_amo : in std_logic_vector(5 downto 0);\n") + f.write(" l2_fwd_in_valid : in std_ulogic;\n") + f.write(" l2_fwd_in_data_coh_msg : in std_logic_vector(2 downto 0);\n") + f.write(" l2_fwd_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" l2_fwd_in_data_req_id : in std_logic_vector(3 downto 0);\n") + f.write(" l2_rsp_in_valid : in std_ulogic;\n") + f.write(" l2_rsp_in_data_coh_msg : in std_logic_vector(1 downto 0);\n") + f.write(" l2_rsp_in_data_addr : in std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" l2_rsp_in_data_line : in std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_rsp_in_data_invack_cnt : in std_logic_vector(" + + str(invack_cnt_bits - 1) + " downto 0);\n") + f.write(" l2_flush_valid : in std_ulogic;\n") + f.write(" l2_flush_data : in std_ulogic;\n") + f.write(" l2_rd_rsp_ready : in std_ulogic;\n") + f.write(" l2_inval_ready : in std_ulogic;\n") + f.write(" l2_bresp_ready : in std_ulogic;\n") + f.write(" l2_req_out_ready : in std_ulogic;\n") + f.write(" l2_rsp_out_ready : in std_ulogic;\n") + f.write(" l2_stats_ready : in std_ulogic;\n") + f.write(" flush_done : out std_ulogic;\n") + f.write(" l2_cpu_req_ready : out std_ulogic;\n") + f.write(" l2_fwd_in_ready : out std_ulogic;\n") + f.write(" l2_rsp_in_ready : out std_ulogic;\n") + f.write(" l2_flush_ready : out std_ulogic;\n") + f.write(" l2_rd_rsp_valid : out std_ulogic;\n") + f.write(" l2_rd_rsp_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_inval_valid : out std_ulogic;\n") + f.write(" l2_inval_data_addr : out std_logic_vector(" + + str(phys_addr_bits - 1) + " downto 0);\n") + f.write(" l2_inval_data_hprot : out std_logic_vector(1 downto 0);\n") + f.write(" l2_bresp_valid : out std_ulogic;\n") + f.write(" l2_bresp_data : out std_logic_vector(1 downto 0);\n") + f.write(" l2_req_out_valid : out std_ulogic;\n") + f.write(" l2_req_out_data_coh_msg : out std_logic_vector(1 downto 0);\n") + f.write(" l2_req_out_data_hprot : out std_logic_vector(1 downto 0);\n") + f.write(" l2_req_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" l2_req_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_rsp_out_valid : out std_ulogic;\n") + f.write(" l2_rsp_out_data_coh_msg : out std_logic_vector(1 downto 0);\n") + f.write(" l2_rsp_out_data_req_id : out std_logic_vector(3 downto 0);\n") + f.write(" l2_rsp_out_data_to_req : out std_logic_vector(1 downto 0);\n") + f.write(" l2_rsp_out_data_addr : out std_logic_vector(" + + str(phys_addr_bits - offset_bits - 1) + " downto 0);\n") + f.write(" l2_rsp_out_data_line : out std_logic_vector(" + + str(bits_per_line - 1) + " downto 0);\n") + f.write(" l2_stats_valid : out std_ulogic;\n") + f.write(" l2_stats_data : out std_ulogic\n") def write_cache_port_map(f, cac, is_llc): - f.write(" port map(\n") - if is_llc and 'spandex' in cac.name: - f.write(" clk => clk,\n") - f.write(" rst => rst,\n") - f.write(" llc_req_in_valid => llc_req_in_valid,\n") - f.write(" llc_req_in_data_coh_msg => llc_req_in_data_coh_msg,\n") - f.write(" llc_req_in_data_hprot => llc_req_in_data_hprot,\n") - f.write(" llc_req_in_data_addr => llc_req_in_data_addr,\n") - f.write(" llc_req_in_data_word_offset => llc_req_in_data_word_offset,\n") - f.write(" llc_req_in_data_valid_words => llc_req_in_data_valid_words,\n") - f.write(" llc_req_in_data_line => llc_req_in_data_line,\n") - f.write(" llc_req_in_data_word_mask => llc_req_in_data_word_mask,\n") - f.write(" llc_req_in_data_req_id => llc_req_in_data_req_id,\n") - f.write(" llc_dma_req_in_valid => llc_dma_req_in_valid,\n") - f.write(" llc_dma_req_in_data_coh_msg => llc_dma_req_in_data_coh_msg,\n") - f.write(" llc_dma_req_in_data_hprot => llc_dma_req_in_data_hprot,\n") - f.write(" llc_dma_req_in_data_addr => llc_dma_req_in_data_addr,\n") - f.write(" llc_dma_req_in_data_word_offset => llc_dma_req_in_data_word_offset,\n") - f.write(" llc_dma_req_in_data_valid_words => llc_dma_req_in_data_valid_words,\n") - f.write(" llc_dma_req_in_data_line => llc_dma_req_in_data_line,\n") - f.write(" llc_dma_req_in_data_req_id => llc_dma_req_in_data_req_id,\n") - f.write(" llc_dma_req_in_data_word_mask => llc_dma_req_in_data_word_mask,\n") - f.write(" llc_rsp_in_valid => llc_rsp_in_valid,\n") - f.write(" llc_rsp_in_data_coh_msg => llc_rsp_in_data_coh_msg,\n") - f.write(" llc_rsp_in_data_addr => llc_rsp_in_data_addr,\n") - f.write(" llc_rsp_in_data_line => llc_rsp_in_data_line,\n") - f.write(" llc_rsp_in_data_word_mask => llc_rsp_in_data_word_mask,\n") - f.write(" llc_rsp_in_data_req_id => llc_rsp_in_data_req_id,\n") - f.write(" llc_mem_rsp_valid => llc_mem_rsp_valid,\n") - f.write(" llc_mem_rsp_data_line => llc_mem_rsp_data_line,\n") - f.write(" llc_rst_tb_valid => llc_rst_tb_valid,\n") - f.write(" llc_rst_tb_data => llc_rst_tb_data,\n") - f.write(" llc_rsp_out_ready => llc_rsp_out_ready,\n") - f.write(" llc_dma_rsp_out_ready => llc_dma_rsp_out_ready,\n") - f.write(" llc_fwd_out_ready => llc_fwd_out_ready,\n") - f.write(" llc_mem_req_ready => llc_mem_req_ready,\n") - f.write(" llc_rst_tb_done_ready => llc_rst_tb_done_ready,\n") - f.write(" llc_stats_ready => llc_stats_ready,\n") - f.write(" llc_req_in_ready => llc_req_in_ready,\n") - f.write(" llc_dma_req_in_ready => llc_dma_req_in_ready,\n") - f.write(" llc_rsp_in_ready => llc_rsp_in_ready,\n") - f.write(" llc_mem_rsp_ready => llc_mem_rsp_ready,\n") - f.write(" llc_rst_tb_ready => llc_rst_tb_ready,\n") - f.write(" llc_rsp_out_valid => llc_rsp_out_valid,\n") - f.write(" llc_rsp_out_data_coh_msg => llc_rsp_out_data_coh_msg,\n") - f.write(" llc_rsp_out_data_addr => llc_rsp_out_data_addr,\n") - f.write(" llc_rsp_out_data_line => llc_rsp_out_data_line,\n") - f.write(" llc_rsp_out_data_invack_cnt => llc_rsp_out_data_invack_cnt,\n") - f.write(" llc_rsp_out_data_req_id => llc_rsp_out_data_req_id,\n") - f.write(" llc_rsp_out_data_dest_id => llc_rsp_out_data_dest_id,\n") - f.write(" llc_rsp_out_data_word_offset => llc_rsp_out_data_word_offset,\n") - f.write(" llc_rsp_out_data_word_mask => llc_rsp_out_data_word_mask,\n") - f.write(" llc_dma_rsp_out_valid => llc_dma_rsp_out_valid,\n") - f.write(" llc_dma_rsp_out_data_coh_msg => llc_dma_rsp_out_data_coh_msg,\n") - f.write(" llc_dma_rsp_out_data_addr => llc_dma_rsp_out_data_addr,\n") - f.write(" llc_dma_rsp_out_data_line => llc_dma_rsp_out_data_line,\n") - f.write(" llc_dma_rsp_out_data_invack_cnt => llc_dma_rsp_out_data_invack_cnt,\n") - f.write(" llc_dma_rsp_out_data_req_id => llc_dma_rsp_out_data_req_id,\n") - f.write(" llc_dma_rsp_out_data_dest_id => llc_dma_rsp_out_data_dest_id,\n") - f.write(" llc_dma_rsp_out_data_word_offset => llc_dma_rsp_out_data_word_offset,\n") - f.write(" llc_dma_rsp_out_data_word_mask => llc_dma_rsp_out_data_word_mask,\n") - f.write(" llc_fwd_out_valid => llc_fwd_out_valid,\n") - f.write(" llc_fwd_out_data_coh_msg => llc_fwd_out_data_coh_msg,\n") - f.write(" llc_fwd_out_data_addr => llc_fwd_out_data_addr,\n") - f.write(" llc_fwd_out_data_req_id => llc_fwd_out_data_req_id,\n") - f.write(" llc_fwd_out_data_dest_id => llc_fwd_out_data_dest_id,\n") - f.write(" llc_fwd_out_data_word_mask => llc_fwd_out_data_word_mask,\n") - f.write(" llc_fwd_out_data_line => llc_fwd_out_data_line,\n") - f.write(" llc_mem_req_valid => llc_mem_req_valid,\n") - f.write(" llc_mem_req_data_hwrite => llc_mem_req_data_hwrite,\n") - f.write(" llc_mem_req_data_hsize => llc_mem_req_data_hsize,\n") - f.write(" llc_mem_req_data_hprot => llc_mem_req_data_hprot,\n") - f.write(" llc_mem_req_data_addr => llc_mem_req_data_addr,\n") - f.write(" llc_mem_req_data_line => llc_mem_req_data_line,\n") - f.write(" llc_stats_valid => llc_stats_valid,\n") - f.write(" llc_stats_data => llc_stats_data,\n") - f.write(" llc_rst_tb_done_valid => llc_rst_tb_done_valid,\n") - f.write(" llc_rst_tb_done_data => llc_rst_tb_done_data\n") - elif is_llc and 'spandex' not in cac.name: - f.write(" clk => clk,\n") - f.write(" rst => rst,\n") - f.write(" llc_req_in_valid => llc_req_in_valid,\n") - f.write(" llc_req_in_data_coh_msg => llc_req_in_data_coh_msg,\n") - f.write(" llc_req_in_data_hprot => llc_req_in_data_hprot,\n") - f.write(" llc_req_in_data_addr => llc_req_in_data_addr,\n") - f.write(" llc_req_in_data_word_offset => llc_req_in_data_word_offset,\n") - f.write(" llc_req_in_data_valid_words => llc_req_in_data_valid_words,\n") - f.write(" llc_req_in_data_line => llc_req_in_data_line,\n") - f.write(" llc_req_in_data_req_id => llc_req_in_data_req_id,\n") - f.write(" llc_dma_req_in_valid => llc_dma_req_in_valid,\n") - f.write(" llc_dma_req_in_data_coh_msg => llc_dma_req_in_data_coh_msg,\n") - f.write(" llc_dma_req_in_data_hprot => llc_dma_req_in_data_hprot,\n") - f.write(" llc_dma_req_in_data_addr => llc_dma_req_in_data_addr,\n") - f.write(" llc_dma_req_in_data_word_offset => llc_dma_req_in_data_word_offset,\n") - f.write(" llc_dma_req_in_data_valid_words => llc_dma_req_in_data_valid_words,\n") - f.write(" llc_dma_req_in_data_line => llc_dma_req_in_data_line,\n") - f.write(" llc_dma_req_in_data_req_id => llc_dma_req_in_data_req_id,\n") - f.write(" llc_rsp_in_valid => llc_rsp_in_valid,\n") - f.write(" llc_rsp_in_data_coh_msg => llc_rsp_in_data_coh_msg,\n") - f.write(" llc_rsp_in_data_addr => llc_rsp_in_data_addr,\n") - f.write(" llc_rsp_in_data_line => llc_rsp_in_data_line,\n") - f.write(" llc_rsp_in_data_req_id => llc_rsp_in_data_req_id,\n") - f.write(" llc_mem_rsp_valid => llc_mem_rsp_valid,\n") - f.write(" llc_mem_rsp_data_line => llc_mem_rsp_data_line,\n") - f.write(" llc_rst_tb_valid => llc_rst_tb_valid,\n") - f.write(" llc_rst_tb_data => llc_rst_tb_data,\n") - f.write(" llc_rsp_out_ready => llc_rsp_out_ready,\n") - f.write(" llc_dma_rsp_out_ready => llc_dma_rsp_out_ready,\n") - f.write(" llc_fwd_out_ready => llc_fwd_out_ready,\n") - f.write(" llc_mem_req_ready => llc_mem_req_ready,\n") - f.write(" llc_rst_tb_done_ready => llc_rst_tb_done_ready,\n") - f.write(" llc_stats_ready => llc_stats_ready,\n") - f.write(" llc_req_in_ready => llc_req_in_ready,\n") - f.write(" llc_dma_req_in_ready => llc_dma_req_in_ready,\n") - f.write(" llc_rsp_in_ready => llc_rsp_in_ready,\n") - f.write(" llc_mem_rsp_ready => llc_mem_rsp_ready,\n") - f.write(" llc_rst_tb_ready => llc_rst_tb_ready,\n") - f.write(" llc_rsp_out_valid => llc_rsp_out_valid,\n") - f.write(" llc_rsp_out_data_coh_msg => llc_rsp_out_data_coh_msg,\n") - f.write(" llc_rsp_out_data_addr => llc_rsp_out_data_addr,\n") - f.write(" llc_rsp_out_data_line => llc_rsp_out_data_line,\n") - f.write(" llc_rsp_out_data_invack_cnt => llc_rsp_out_data_invack_cnt,\n") - f.write(" llc_rsp_out_data_req_id => llc_rsp_out_data_req_id,\n") - f.write(" llc_rsp_out_data_dest_id => llc_rsp_out_data_dest_id,\n") - f.write(" llc_rsp_out_data_word_offset => llc_rsp_out_data_word_offset,\n") - f.write(" llc_dma_rsp_out_valid => llc_dma_rsp_out_valid,\n") - f.write(" llc_dma_rsp_out_data_coh_msg => llc_dma_rsp_out_data_coh_msg,\n") - f.write(" llc_dma_rsp_out_data_addr => llc_dma_rsp_out_data_addr,\n") - f.write(" llc_dma_rsp_out_data_line => llc_dma_rsp_out_data_line,\n") - f.write(" llc_dma_rsp_out_data_invack_cnt => llc_dma_rsp_out_data_invack_cnt,\n") - f.write(" llc_dma_rsp_out_data_req_id => llc_dma_rsp_out_data_req_id,\n") - f.write(" llc_dma_rsp_out_data_dest_id => llc_dma_rsp_out_data_dest_id,\n") - f.write(" llc_dma_rsp_out_data_word_offset => llc_dma_rsp_out_data_word_offset,\n") - f.write(" llc_fwd_out_valid => llc_fwd_out_valid,\n") - f.write(" llc_fwd_out_data_coh_msg => llc_fwd_out_data_coh_msg,\n") - f.write(" llc_fwd_out_data_addr => llc_fwd_out_data_addr,\n") - f.write(" llc_fwd_out_data_req_id => llc_fwd_out_data_req_id,\n") - f.write(" llc_fwd_out_data_dest_id => llc_fwd_out_data_dest_id,\n") - f.write(" llc_mem_req_valid => llc_mem_req_valid,\n") - f.write(" llc_mem_req_data_hwrite => llc_mem_req_data_hwrite,\n") - f.write(" llc_mem_req_data_hsize => llc_mem_req_data_hsize,\n") - f.write(" llc_mem_req_data_hprot => llc_mem_req_data_hprot,\n") - f.write(" llc_mem_req_data_addr => llc_mem_req_data_addr,\n") - f.write(" llc_mem_req_data_line => llc_mem_req_data_line,\n") - f.write(" llc_stats_valid => llc_stats_valid,\n") - f.write(" llc_stats_data => llc_stats_data,\n") - f.write(" llc_rst_tb_done_valid => llc_rst_tb_done_valid,\n") - f.write(" llc_rst_tb_done_data => llc_rst_tb_done_data\n") - elif not is_llc and 'spandex' in cac.name: - f.write(" clk => clk,\n") - f.write(" rst => rst,\n") - f.write(" l2_cpu_req_valid => l2_cpu_req_valid,\n") - f.write(" l2_cpu_req_data_cpu_msg => l2_cpu_req_data_cpu_msg,\n") - f.write(" l2_cpu_req_data_hsize => l2_cpu_req_data_hsize,\n") - f.write(" l2_cpu_req_data_hprot => l2_cpu_req_data_hprot,\n") - f.write(" l2_cpu_req_data_addr => l2_cpu_req_data_addr,\n") - f.write(" l2_cpu_req_data_word => l2_cpu_req_data_word,\n") - f.write(" l2_cpu_req_data_amo => l2_cpu_req_data_amo,\n") - f.write(" l2_cpu_req_data_aq => l2_cpu_req_data_aq,\n") - f.write(" l2_cpu_req_data_rl => l2_cpu_req_data_rl,\n") - f.write(" l2_cpu_req_data_dcs_en => l2_cpu_req_data_dcs_en,\n") - f.write(" l2_cpu_req_data_use_owner_pred => l2_cpu_req_data_use_owner_pred,\n") - f.write(" l2_cpu_req_data_dcs => l2_cpu_req_data_dcs,\n") - f.write(" l2_cpu_req_data_pred_cid => l2_cpu_req_data_pred_cid,\n") - f.write(" l2_fwd_in_valid => l2_fwd_in_valid,\n") - f.write(" l2_fwd_in_data_coh_msg => l2_fwd_in_data_coh_msg,\n") - f.write(" l2_fwd_in_data_addr => l2_fwd_in_data_addr,\n") - f.write(" l2_fwd_in_data_req_id => l2_fwd_in_data_req_id,\n") - f.write(" l2_fwd_in_data_word_mask => l2_fwd_in_data_word_mask,\n") - f.write(" l2_fwd_in_data_line => l2_fwd_in_data_line,\n") - f.write(" l2_rsp_in_valid => l2_rsp_in_valid,\n") - f.write(" l2_rsp_in_data_coh_msg => l2_rsp_in_data_coh_msg,\n") - f.write(" l2_rsp_in_data_addr => l2_rsp_in_data_addr,\n") - f.write(" l2_rsp_in_data_line => l2_rsp_in_data_line,\n") - f.write(" l2_rsp_in_data_invack_cnt => l2_rsp_in_data_invack_cnt,\n") - f.write(" l2_rsp_in_data_word_mask => l2_rsp_in_data_word_mask,\n") - f.write(" l2_flush_valid => l2_flush_valid,\n") - f.write(" l2_flush_data => l2_flush_data,\n") - f.write(" l2_rd_rsp_ready => l2_rd_rsp_ready,\n") - f.write(" l2_inval_ready => l2_inval_ready,\n") - f.write(" l2_bresp_ready => l2_bresp_ready,\n") - f.write(" l2_req_out_ready => l2_req_out_ready,\n") - f.write(" l2_rsp_out_ready => l2_rsp_out_ready,\n") - f.write(" l2_fwd_out_ready => l2_rsp_out_ready,\n") - f.write(" l2_stats_ready => l2_stats_ready,\n") - f.write(" flush_done => flush_done,\n") - f.write(" acc_flush_done => acc_flush_done,\n") - f.write(" l2_cpu_req_ready => l2_cpu_req_ready,\n") - f.write(" l2_fwd_in_ready => l2_fwd_in_ready,\n") - f.write(" l2_rsp_in_ready => l2_rsp_in_ready,\n") - f.write(" l2_flush_ready => l2_flush_ready,\n") - f.write(" l2_rd_rsp_valid => l2_rd_rsp_valid,\n") - f.write(" l2_rd_rsp_data_line => l2_rd_rsp_data_line,\n") - f.write(" l2_inval_valid => l2_inval_valid,\n") - f.write(" l2_inval_data_addr => l2_inval_data_addr,\n") - f.write(" l2_inval_data_hprot => l2_inval_data_hprot,\n") - f.write(" l2_bresp_valid => l2_bresp_valid,\n") - f.write(" l2_bresp_data => l2_bresp_data,\n") - f.write(" l2_req_out_valid => l2_req_out_valid,\n") - f.write(" l2_req_out_data_coh_msg => l2_req_out_data_coh_msg,\n") - f.write(" l2_req_out_data_hprot => l2_req_out_data_hprot,\n") - f.write(" l2_req_out_data_addr => l2_req_out_data_addr,\n") - f.write(" l2_req_out_data_line => l2_req_out_data_line,\n") - f.write(" l2_req_out_data_word_mask => l2_req_out_data_word_mask,\n") - f.write(" l2_rsp_out_valid => l2_rsp_out_valid,\n") - f.write(" l2_rsp_out_data_coh_msg => l2_rsp_out_data_coh_msg,\n") - f.write(" l2_rsp_out_data_req_id => l2_rsp_out_data_req_id,\n") - f.write(" l2_rsp_out_data_to_req => l2_rsp_out_data_to_req,\n") - f.write(" l2_rsp_out_data_addr => l2_rsp_out_data_addr,\n") - f.write(" l2_rsp_out_data_line => l2_rsp_out_data_line,\n") - f.write(" l2_rsp_out_data_word_mask => l2_rsp_out_data_word_mask,\n") - f.write(" l2_fwd_out_valid => l2_fwd_out_valid,\n") - f.write(" l2_fwd_out_data_coh_msg => l2_fwd_out_data_coh_msg,\n") - f.write(" l2_fwd_out_data_req_id => l2_fwd_out_data_req_id,\n") - f.write(" l2_fwd_out_data_to_req => l2_fwd_out_data_to_req,\n") - f.write(" l2_fwd_out_data_addr => l2_fwd_out_data_addr,\n") - f.write(" l2_fwd_out_data_line => l2_fwd_out_data_line,\n") - f.write(" l2_fwd_out_data_word_mask => l2_fwd_out_data_word_mask,\n") - f.write(" l2_stats_valid => l2_stats_valid,\n") - f.write(" l2_stats_data => l2_stats_data,\n") - f.write(" l2_fence_ready => l2_fence_ready,\n") - f.write(" l2_fence_valid => l2_fence_valid,\n") - f.write(" l2_fence_data => l2_fence_data\n") - elif not is_llc and 'spandex' not in cac.name: - f.write(" clk => clk,\n") - f.write(" rst => rst,\n") - f.write(" l2_cpu_req_valid => l2_cpu_req_valid,\n") - f.write(" l2_cpu_req_data_cpu_msg => l2_cpu_req_data_cpu_msg,\n") - f.write(" l2_cpu_req_data_hsize => l2_cpu_req_data_hsize,\n") - f.write(" l2_cpu_req_data_hprot => l2_cpu_req_data_hprot,\n") - f.write(" l2_cpu_req_data_addr => l2_cpu_req_data_addr,\n") - f.write(" l2_cpu_req_data_word => l2_cpu_req_data_word,\n") - f.write(" l2_cpu_req_data_amo => l2_cpu_req_data_amo,\n") - f.write(" l2_fwd_in_valid => l2_fwd_in_valid,\n") - f.write(" l2_fwd_in_data_coh_msg => l2_fwd_in_data_coh_msg,\n") - f.write(" l2_fwd_in_data_addr => l2_fwd_in_data_addr,\n") - f.write(" l2_fwd_in_data_req_id => l2_fwd_in_data_req_id,\n") - f.write(" l2_rsp_in_valid => l2_rsp_in_valid,\n") - f.write(" l2_rsp_in_data_coh_msg => l2_rsp_in_data_coh_msg,\n") - f.write(" l2_rsp_in_data_addr => l2_rsp_in_data_addr,\n") - f.write(" l2_rsp_in_data_line => l2_rsp_in_data_line,\n") - f.write(" l2_rsp_in_data_invack_cnt => l2_rsp_in_data_invack_cnt,\n") - f.write(" l2_flush_valid => l2_flush_valid,\n") - f.write(" l2_flush_data => l2_flush_data,\n") - f.write(" l2_rd_rsp_ready => l2_rd_rsp_ready,\n") - f.write(" l2_inval_ready => l2_inval_ready,\n") - f.write(" l2_bresp_ready => l2_bresp_ready,\n") - f.write(" l2_req_out_ready => l2_req_out_ready,\n") - f.write(" l2_rsp_out_ready => l2_rsp_out_ready,\n") - f.write(" l2_stats_ready => l2_stats_ready,\n") - f.write(" flush_done => flush_done,\n") - f.write(" l2_cpu_req_ready => l2_cpu_req_ready,\n") - f.write(" l2_fwd_in_ready => l2_fwd_in_ready,\n") - f.write(" l2_rsp_in_ready => l2_rsp_in_ready,\n") - f.write(" l2_flush_ready => l2_flush_ready,\n") - f.write(" l2_rd_rsp_valid => l2_rd_rsp_valid,\n") - f.write(" l2_rd_rsp_data_line => l2_rd_rsp_data_line,\n") - f.write(" l2_inval_valid => l2_inval_valid,\n") - f.write(" l2_inval_data_addr => l2_inval_data_addr,\n") - f.write(" l2_inval_data_hprot => l2_inval_data_hprot,\n") - f.write(" l2_bresp_valid => l2_bresp_valid,\n") - f.write(" l2_bresp_data => l2_bresp_data,\n") - f.write(" l2_req_out_valid => l2_req_out_valid,\n") - f.write(" l2_req_out_data_coh_msg => l2_req_out_data_coh_msg,\n") - f.write(" l2_req_out_data_hprot => l2_req_out_data_hprot,\n") - f.write(" l2_req_out_data_addr => l2_req_out_data_addr,\n") - f.write(" l2_req_out_data_line => l2_req_out_data_line,\n") - f.write(" l2_rsp_out_valid => l2_rsp_out_valid,\n") - f.write(" l2_rsp_out_data_coh_msg => l2_rsp_out_data_coh_msg,\n") - f.write(" l2_rsp_out_data_req_id => l2_rsp_out_data_req_id,\n") - f.write(" l2_rsp_out_data_to_req => l2_rsp_out_data_to_req,\n") - f.write(" l2_rsp_out_data_addr => l2_rsp_out_data_addr,\n") - f.write(" l2_rsp_out_data_line => l2_rsp_out_data_line,\n") - f.write(" l2_stats_valid => l2_stats_valid,\n") - f.write(" l2_stats_data => l2_stats_data\n") - f.write(" );\n") + f.write(" port map(\n") + if is_llc and 'spandex' in cac.name: + f.write(" clk => clk,\n") + f.write(" rst => rst,\n") + f.write(" llc_req_in_valid => llc_req_in_valid,\n") + f.write(" llc_req_in_data_coh_msg => llc_req_in_data_coh_msg,\n") + f.write(" llc_req_in_data_hprot => llc_req_in_data_hprot,\n") + f.write(" llc_req_in_data_addr => llc_req_in_data_addr,\n") + f.write(" llc_req_in_data_word_offset => llc_req_in_data_word_offset,\n") + f.write(" llc_req_in_data_valid_words => llc_req_in_data_valid_words,\n") + f.write(" llc_req_in_data_line => llc_req_in_data_line,\n") + f.write(" llc_req_in_data_word_mask => llc_req_in_data_word_mask,\n") + f.write(" llc_req_in_data_req_id => llc_req_in_data_req_id,\n") + f.write(" llc_dma_req_in_valid => llc_dma_req_in_valid,\n") + f.write( + " llc_dma_req_in_data_coh_msg => llc_dma_req_in_data_coh_msg,\n") + f.write( + " llc_dma_req_in_data_hprot => llc_dma_req_in_data_hprot,\n") + f.write(" llc_dma_req_in_data_addr => llc_dma_req_in_data_addr,\n") + f.write( + " llc_dma_req_in_data_word_offset => llc_dma_req_in_data_word_offset,\n") + f.write( + " llc_dma_req_in_data_valid_words => llc_dma_req_in_data_valid_words,\n") + f.write(" llc_dma_req_in_data_line => llc_dma_req_in_data_line,\n") + f.write( + " llc_dma_req_in_data_req_id => llc_dma_req_in_data_req_id,\n") + f.write( + " llc_dma_req_in_data_word_mask => llc_dma_req_in_data_word_mask,\n") + f.write(" llc_rsp_in_valid => llc_rsp_in_valid,\n") + f.write(" llc_rsp_in_data_coh_msg => llc_rsp_in_data_coh_msg,\n") + f.write(" llc_rsp_in_data_addr => llc_rsp_in_data_addr,\n") + f.write(" llc_rsp_in_data_line => llc_rsp_in_data_line,\n") + f.write(" llc_rsp_in_data_word_mask => llc_rsp_in_data_word_mask,\n") + f.write(" llc_rsp_in_data_req_id => llc_rsp_in_data_req_id,\n") + f.write(" llc_mem_rsp_valid => llc_mem_rsp_valid,\n") + f.write(" llc_mem_rsp_data_line => llc_mem_rsp_data_line,\n") + f.write(" llc_rst_tb_valid => llc_rst_tb_valid,\n") + f.write(" llc_rst_tb_data => llc_rst_tb_data,\n") + f.write(" llc_rsp_out_ready => llc_rsp_out_ready,\n") + f.write(" llc_dma_rsp_out_ready => llc_dma_rsp_out_ready,\n") + f.write(" llc_fwd_out_ready => llc_fwd_out_ready,\n") + f.write(" llc_mem_req_ready => llc_mem_req_ready,\n") + f.write(" llc_rst_tb_done_ready => llc_rst_tb_done_ready,\n") + f.write(" llc_stats_ready => llc_stats_ready,\n") + f.write(" llc_req_in_ready => llc_req_in_ready,\n") + f.write(" llc_dma_req_in_ready => llc_dma_req_in_ready,\n") + f.write(" llc_rsp_in_ready => llc_rsp_in_ready,\n") + f.write(" llc_mem_rsp_ready => llc_mem_rsp_ready,\n") + f.write(" llc_rst_tb_ready => llc_rst_tb_ready,\n") + f.write(" llc_rsp_out_valid => llc_rsp_out_valid,\n") + f.write(" llc_rsp_out_data_coh_msg => llc_rsp_out_data_coh_msg,\n") + f.write(" llc_rsp_out_data_addr => llc_rsp_out_data_addr,\n") + f.write(" llc_rsp_out_data_line => llc_rsp_out_data_line,\n") + f.write(" llc_rsp_out_data_invack_cnt => llc_rsp_out_data_invack_cnt,\n") + f.write(" llc_rsp_out_data_req_id => llc_rsp_out_data_req_id,\n") + f.write(" llc_rsp_out_data_dest_id => llc_rsp_out_data_dest_id,\n") + f.write(" llc_rsp_out_data_word_offset => llc_rsp_out_data_word_offset,\n") + f.write(" llc_rsp_out_data_word_mask => llc_rsp_out_data_word_mask,\n") + f.write(" llc_dma_rsp_out_valid => llc_dma_rsp_out_valid,\n") + f.write( + " llc_dma_rsp_out_data_coh_msg => llc_dma_rsp_out_data_coh_msg,\n") + f.write( + " llc_dma_rsp_out_data_addr => llc_dma_rsp_out_data_addr,\n") + f.write( + " llc_dma_rsp_out_data_line => llc_dma_rsp_out_data_line,\n") + f.write( + " llc_dma_rsp_out_data_invack_cnt => llc_dma_rsp_out_data_invack_cnt,\n") + f.write( + " llc_dma_rsp_out_data_req_id => llc_dma_rsp_out_data_req_id,\n") + f.write( + " llc_dma_rsp_out_data_dest_id => llc_dma_rsp_out_data_dest_id,\n") + f.write( + " llc_dma_rsp_out_data_word_offset => llc_dma_rsp_out_data_word_offset,\n") + f.write( + " llc_dma_rsp_out_data_word_mask => llc_dma_rsp_out_data_word_mask,\n") + f.write(" llc_fwd_out_valid => llc_fwd_out_valid,\n") + f.write(" llc_fwd_out_data_coh_msg => llc_fwd_out_data_coh_msg,\n") + f.write(" llc_fwd_out_data_addr => llc_fwd_out_data_addr,\n") + f.write(" llc_fwd_out_data_req_id => llc_fwd_out_data_req_id,\n") + f.write(" llc_fwd_out_data_dest_id => llc_fwd_out_data_dest_id,\n") + f.write(" llc_fwd_out_data_word_mask => llc_fwd_out_data_word_mask,\n") + f.write(" llc_fwd_out_data_line => llc_fwd_out_data_line,\n") + f.write(" llc_mem_req_valid => llc_mem_req_valid,\n") + f.write(" llc_mem_req_data_hwrite => llc_mem_req_data_hwrite,\n") + f.write(" llc_mem_req_data_hsize => llc_mem_req_data_hsize,\n") + f.write(" llc_mem_req_data_hprot => llc_mem_req_data_hprot,\n") + f.write(" llc_mem_req_data_addr => llc_mem_req_data_addr,\n") + f.write(" llc_mem_req_data_line => llc_mem_req_data_line,\n") + f.write(" llc_stats_valid => llc_stats_valid,\n") + f.write(" llc_stats_data => llc_stats_data,\n") + f.write(" llc_rst_tb_done_valid => llc_rst_tb_done_valid,\n") + f.write(" llc_rst_tb_done_data => llc_rst_tb_done_data\n") + elif is_llc and 'spandex' not in cac.name: + f.write(" clk => clk,\n") + f.write(" rst => rst,\n") + f.write(" llc_req_in_valid => llc_req_in_valid,\n") + f.write(" llc_req_in_data_coh_msg => llc_req_in_data_coh_msg,\n") + f.write(" llc_req_in_data_hprot => llc_req_in_data_hprot,\n") + f.write(" llc_req_in_data_addr => llc_req_in_data_addr,\n") + f.write(" llc_req_in_data_word_offset => llc_req_in_data_word_offset,\n") + f.write(" llc_req_in_data_valid_words => llc_req_in_data_valid_words,\n") + f.write(" llc_req_in_data_line => llc_req_in_data_line,\n") + f.write(" llc_req_in_data_req_id => llc_req_in_data_req_id,\n") + f.write(" llc_dma_req_in_valid => llc_dma_req_in_valid,\n") + f.write( + " llc_dma_req_in_data_coh_msg => llc_dma_req_in_data_coh_msg,\n") + f.write( + " llc_dma_req_in_data_hprot => llc_dma_req_in_data_hprot,\n") + f.write(" llc_dma_req_in_data_addr => llc_dma_req_in_data_addr,\n") + f.write( + " llc_dma_req_in_data_word_offset => llc_dma_req_in_data_word_offset,\n") + f.write( + " llc_dma_req_in_data_valid_words => llc_dma_req_in_data_valid_words,\n") + f.write(" llc_dma_req_in_data_line => llc_dma_req_in_data_line,\n") + f.write( + " llc_dma_req_in_data_req_id => llc_dma_req_in_data_req_id,\n") + f.write(" llc_rsp_in_valid => llc_rsp_in_valid,\n") + f.write(" llc_rsp_in_data_coh_msg => llc_rsp_in_data_coh_msg,\n") + f.write(" llc_rsp_in_data_addr => llc_rsp_in_data_addr,\n") + f.write(" llc_rsp_in_data_line => llc_rsp_in_data_line,\n") + f.write(" llc_rsp_in_data_req_id => llc_rsp_in_data_req_id,\n") + f.write(" llc_mem_rsp_valid => llc_mem_rsp_valid,\n") + f.write(" llc_mem_rsp_data_line => llc_mem_rsp_data_line,\n") + f.write(" llc_rst_tb_valid => llc_rst_tb_valid,\n") + f.write(" llc_rst_tb_data => llc_rst_tb_data,\n") + f.write(" llc_rsp_out_ready => llc_rsp_out_ready,\n") + f.write(" llc_dma_rsp_out_ready => llc_dma_rsp_out_ready,\n") + f.write(" llc_fwd_out_ready => llc_fwd_out_ready,\n") + f.write(" llc_mem_req_ready => llc_mem_req_ready,\n") + f.write(" llc_rst_tb_done_ready => llc_rst_tb_done_ready,\n") + f.write(" llc_stats_ready => llc_stats_ready,\n") + f.write(" llc_req_in_ready => llc_req_in_ready,\n") + f.write(" llc_dma_req_in_ready => llc_dma_req_in_ready,\n") + f.write(" llc_rsp_in_ready => llc_rsp_in_ready,\n") + f.write(" llc_mem_rsp_ready => llc_mem_rsp_ready,\n") + f.write(" llc_rst_tb_ready => llc_rst_tb_ready,\n") + f.write(" llc_rsp_out_valid => llc_rsp_out_valid,\n") + f.write(" llc_rsp_out_data_coh_msg => llc_rsp_out_data_coh_msg,\n") + f.write(" llc_rsp_out_data_addr => llc_rsp_out_data_addr,\n") + f.write(" llc_rsp_out_data_line => llc_rsp_out_data_line,\n") + f.write(" llc_rsp_out_data_invack_cnt => llc_rsp_out_data_invack_cnt,\n") + f.write(" llc_rsp_out_data_req_id => llc_rsp_out_data_req_id,\n") + f.write(" llc_rsp_out_data_dest_id => llc_rsp_out_data_dest_id,\n") + f.write(" llc_rsp_out_data_word_offset => llc_rsp_out_data_word_offset,\n") + f.write(" llc_dma_rsp_out_valid => llc_dma_rsp_out_valid,\n") + f.write( + " llc_dma_rsp_out_data_coh_msg => llc_dma_rsp_out_data_coh_msg,\n") + f.write( + " llc_dma_rsp_out_data_addr => llc_dma_rsp_out_data_addr,\n") + f.write( + " llc_dma_rsp_out_data_line => llc_dma_rsp_out_data_line,\n") + f.write( + " llc_dma_rsp_out_data_invack_cnt => llc_dma_rsp_out_data_invack_cnt,\n") + f.write( + " llc_dma_rsp_out_data_req_id => llc_dma_rsp_out_data_req_id,\n") + f.write( + " llc_dma_rsp_out_data_dest_id => llc_dma_rsp_out_data_dest_id,\n") + f.write( + " llc_dma_rsp_out_data_word_offset => llc_dma_rsp_out_data_word_offset,\n") + f.write(" llc_fwd_out_valid => llc_fwd_out_valid,\n") + f.write(" llc_fwd_out_data_coh_msg => llc_fwd_out_data_coh_msg,\n") + f.write(" llc_fwd_out_data_addr => llc_fwd_out_data_addr,\n") + f.write(" llc_fwd_out_data_req_id => llc_fwd_out_data_req_id,\n") + f.write(" llc_fwd_out_data_dest_id => llc_fwd_out_data_dest_id,\n") + f.write(" llc_mem_req_valid => llc_mem_req_valid,\n") + f.write(" llc_mem_req_data_hwrite => llc_mem_req_data_hwrite,\n") + f.write(" llc_mem_req_data_hsize => llc_mem_req_data_hsize,\n") + f.write(" llc_mem_req_data_hprot => llc_mem_req_data_hprot,\n") + f.write(" llc_mem_req_data_addr => llc_mem_req_data_addr,\n") + f.write(" llc_mem_req_data_line => llc_mem_req_data_line,\n") + f.write(" llc_stats_valid => llc_stats_valid,\n") + f.write(" llc_stats_data => llc_stats_data,\n") + f.write(" llc_rst_tb_done_valid => llc_rst_tb_done_valid,\n") + f.write(" llc_rst_tb_done_data => llc_rst_tb_done_data\n") + elif not is_llc and 'spandex' in cac.name: + f.write(" clk => clk,\n") + f.write(" rst => rst,\n") + f.write(" l2_cpu_req_valid => l2_cpu_req_valid,\n") + f.write(" l2_cpu_req_data_cpu_msg => l2_cpu_req_data_cpu_msg,\n") + f.write(" l2_cpu_req_data_hsize => l2_cpu_req_data_hsize,\n") + f.write(" l2_cpu_req_data_hprot => l2_cpu_req_data_hprot,\n") + f.write(" l2_cpu_req_data_addr => l2_cpu_req_data_addr,\n") + f.write(" l2_cpu_req_data_word => l2_cpu_req_data_word,\n") + f.write(" l2_cpu_req_data_amo => l2_cpu_req_data_amo,\n") + f.write(" l2_cpu_req_data_aq => l2_cpu_req_data_aq,\n") + f.write(" l2_cpu_req_data_rl => l2_cpu_req_data_rl,\n") + f.write(" l2_cpu_req_data_dcs_en => l2_cpu_req_data_dcs_en,\n") + f.write( + " l2_cpu_req_data_use_owner_pred => l2_cpu_req_data_use_owner_pred,\n") + f.write(" l2_cpu_req_data_dcs => l2_cpu_req_data_dcs,\n") + f.write(" l2_cpu_req_data_pred_cid => l2_cpu_req_data_pred_cid,\n") + f.write(" l2_fwd_in_valid => l2_fwd_in_valid,\n") + f.write(" l2_fwd_in_data_coh_msg => l2_fwd_in_data_coh_msg,\n") + f.write(" l2_fwd_in_data_addr => l2_fwd_in_data_addr,\n") + f.write(" l2_fwd_in_data_req_id => l2_fwd_in_data_req_id,\n") + f.write(" l2_fwd_in_data_word_mask => l2_fwd_in_data_word_mask,\n") + f.write(" l2_fwd_in_data_line => l2_fwd_in_data_line,\n") + f.write(" l2_rsp_in_valid => l2_rsp_in_valid,\n") + f.write(" l2_rsp_in_data_coh_msg => l2_rsp_in_data_coh_msg,\n") + f.write(" l2_rsp_in_data_addr => l2_rsp_in_data_addr,\n") + f.write(" l2_rsp_in_data_line => l2_rsp_in_data_line,\n") + f.write(" l2_rsp_in_data_invack_cnt => l2_rsp_in_data_invack_cnt,\n") + f.write(" l2_rsp_in_data_word_mask => l2_rsp_in_data_word_mask,\n") + f.write(" l2_flush_valid => l2_flush_valid,\n") + f.write(" l2_flush_data => l2_flush_data,\n") + f.write(" l2_rd_rsp_ready => l2_rd_rsp_ready,\n") + f.write(" l2_inval_ready => l2_inval_ready,\n") + f.write(" l2_bresp_ready => l2_bresp_ready,\n") + f.write(" l2_req_out_ready => l2_req_out_ready,\n") + f.write(" l2_rsp_out_ready => l2_rsp_out_ready,\n") + f.write(" l2_fwd_out_ready => l2_rsp_out_ready,\n") + f.write(" l2_stats_ready => l2_stats_ready,\n") + f.write(" flush_done => flush_done,\n") + f.write(" acc_flush_done => acc_flush_done,\n") + f.write(" l2_cpu_req_ready => l2_cpu_req_ready,\n") + f.write(" l2_fwd_in_ready => l2_fwd_in_ready,\n") + f.write(" l2_rsp_in_ready => l2_rsp_in_ready,\n") + f.write(" l2_flush_ready => l2_flush_ready,\n") + f.write(" l2_rd_rsp_valid => l2_rd_rsp_valid,\n") + f.write(" l2_rd_rsp_data_line => l2_rd_rsp_data_line,\n") + f.write(" l2_inval_valid => l2_inval_valid,\n") + f.write(" l2_inval_data_addr => l2_inval_data_addr,\n") + f.write(" l2_inval_data_hprot => l2_inval_data_hprot,\n") + f.write(" l2_bresp_valid => l2_bresp_valid,\n") + f.write(" l2_bresp_data => l2_bresp_data,\n") + f.write(" l2_req_out_valid => l2_req_out_valid,\n") + f.write(" l2_req_out_data_coh_msg => l2_req_out_data_coh_msg,\n") + f.write(" l2_req_out_data_hprot => l2_req_out_data_hprot,\n") + f.write(" l2_req_out_data_addr => l2_req_out_data_addr,\n") + f.write(" l2_req_out_data_line => l2_req_out_data_line,\n") + f.write(" l2_req_out_data_word_mask => l2_req_out_data_word_mask,\n") + f.write(" l2_rsp_out_valid => l2_rsp_out_valid,\n") + f.write(" l2_rsp_out_data_coh_msg => l2_rsp_out_data_coh_msg,\n") + f.write(" l2_rsp_out_data_req_id => l2_rsp_out_data_req_id,\n") + f.write(" l2_rsp_out_data_to_req => l2_rsp_out_data_to_req,\n") + f.write(" l2_rsp_out_data_addr => l2_rsp_out_data_addr,\n") + f.write(" l2_rsp_out_data_line => l2_rsp_out_data_line,\n") + f.write(" l2_rsp_out_data_word_mask => l2_rsp_out_data_word_mask,\n") + f.write(" l2_fwd_out_valid => l2_fwd_out_valid,\n") + f.write(" l2_fwd_out_data_coh_msg => l2_fwd_out_data_coh_msg,\n") + f.write(" l2_fwd_out_data_req_id => l2_fwd_out_data_req_id,\n") + f.write(" l2_fwd_out_data_to_req => l2_fwd_out_data_to_req,\n") + f.write(" l2_fwd_out_data_addr => l2_fwd_out_data_addr,\n") + f.write(" l2_fwd_out_data_line => l2_fwd_out_data_line,\n") + f.write(" l2_fwd_out_data_word_mask => l2_fwd_out_data_word_mask,\n") + f.write(" l2_stats_valid => l2_stats_valid,\n") + f.write(" l2_stats_data => l2_stats_data,\n") + f.write(" l2_fence_ready => l2_fence_ready,\n") + f.write(" l2_fence_valid => l2_fence_valid,\n") + f.write(" l2_fence_data => l2_fence_data\n") + elif not is_llc and 'spandex' not in cac.name: + f.write(" clk => clk,\n") + f.write(" rst => rst,\n") + f.write(" l2_cpu_req_valid => l2_cpu_req_valid,\n") + f.write(" l2_cpu_req_data_cpu_msg => l2_cpu_req_data_cpu_msg,\n") + f.write(" l2_cpu_req_data_hsize => l2_cpu_req_data_hsize,\n") + f.write(" l2_cpu_req_data_hprot => l2_cpu_req_data_hprot,\n") + f.write(" l2_cpu_req_data_addr => l2_cpu_req_data_addr,\n") + f.write(" l2_cpu_req_data_word => l2_cpu_req_data_word,\n") + f.write(" l2_cpu_req_data_amo => l2_cpu_req_data_amo,\n") + f.write(" l2_fwd_in_valid => l2_fwd_in_valid,\n") + f.write(" l2_fwd_in_data_coh_msg => l2_fwd_in_data_coh_msg,\n") + f.write(" l2_fwd_in_data_addr => l2_fwd_in_data_addr,\n") + f.write(" l2_fwd_in_data_req_id => l2_fwd_in_data_req_id,\n") + f.write(" l2_rsp_in_valid => l2_rsp_in_valid,\n") + f.write(" l2_rsp_in_data_coh_msg => l2_rsp_in_data_coh_msg,\n") + f.write(" l2_rsp_in_data_addr => l2_rsp_in_data_addr,\n") + f.write(" l2_rsp_in_data_line => l2_rsp_in_data_line,\n") + f.write(" l2_rsp_in_data_invack_cnt => l2_rsp_in_data_invack_cnt,\n") + f.write(" l2_flush_valid => l2_flush_valid,\n") + f.write(" l2_flush_data => l2_flush_data,\n") + f.write(" l2_rd_rsp_ready => l2_rd_rsp_ready,\n") + f.write(" l2_inval_ready => l2_inval_ready,\n") + f.write(" l2_bresp_ready => l2_bresp_ready,\n") + f.write(" l2_req_out_ready => l2_req_out_ready,\n") + f.write(" l2_rsp_out_ready => l2_rsp_out_ready,\n") + f.write(" l2_stats_ready => l2_stats_ready,\n") + f.write(" flush_done => flush_done,\n") + f.write(" l2_cpu_req_ready => l2_cpu_req_ready,\n") + f.write(" l2_fwd_in_ready => l2_fwd_in_ready,\n") + f.write(" l2_rsp_in_ready => l2_rsp_in_ready,\n") + f.write(" l2_flush_ready => l2_flush_ready,\n") + f.write(" l2_rd_rsp_valid => l2_rd_rsp_valid,\n") + f.write(" l2_rd_rsp_data_line => l2_rd_rsp_data_line,\n") + f.write(" l2_inval_valid => l2_inval_valid,\n") + f.write(" l2_inval_data_addr => l2_inval_data_addr,\n") + f.write(" l2_inval_data_hprot => l2_inval_data_hprot,\n") + f.write(" l2_bresp_valid => l2_bresp_valid,\n") + f.write(" l2_bresp_data => l2_bresp_data,\n") + f.write(" l2_req_out_valid => l2_req_out_valid,\n") + f.write(" l2_req_out_data_coh_msg => l2_req_out_data_coh_msg,\n") + f.write(" l2_req_out_data_hprot => l2_req_out_data_hprot,\n") + f.write(" l2_req_out_data_addr => l2_req_out_data_addr,\n") + f.write(" l2_req_out_data_line => l2_req_out_data_line,\n") + f.write(" l2_rsp_out_valid => l2_rsp_out_valid,\n") + f.write(" l2_rsp_out_data_coh_msg => l2_rsp_out_data_coh_msg,\n") + f.write(" l2_rsp_out_data_req_id => l2_rsp_out_data_req_id,\n") + f.write(" l2_rsp_out_data_to_req => l2_rsp_out_data_to_req,\n") + f.write(" l2_rsp_out_data_addr => l2_rsp_out_data_addr,\n") + f.write(" l2_rsp_out_data_line => l2_rsp_out_data_line,\n") + f.write(" l2_stats_valid => l2_stats_valid,\n") + f.write(" l2_stats_data => l2_stats_data\n") + f.write(" );\n") # Component declaration matching HLS-generated verilog -def gen_tech_dep(accelerator_list, cache_list, noc_width, template_dir, out_dir): - f = open(out_dir + '/allacc.vhd', 'w') - with open(template_dir + '/allacc.vhd', 'r') as ftemplate: - for tline in ftemplate: - if tline.find("-- <>") < 0: - f.write(tline) - continue - for acc in accelerator_list: - for impl in acc.hlscfg: - f.write("\n") - if acc.hls_tool == 'stratus_hls' or acc.hls_tool == 'rtl': - f.write(" component " + acc.name + "_" + impl.name + "\n") - f.write(" port (\n") - write_acc_interface(f, acc, noc_width, impl.datatype, "rst", False, False, False) - elif acc.hls_tool == 'catapult_hls_cxx': - f.write(" component " + acc.name + "_" + impl.name + "\n") - f.write(" port (\n") - write_acc_interface(f, acc, noc_width, impl.datatype, "rst", False, True, False) - elif acc.hls_tool == 'catapult_hls_sysc': - f.write(" component " + acc.name + "_" + impl.name + "\n") - f.write(" port (\n") - write_acc_interface(f, acc, noc_width, impl.datatype, "rst", False, False, True) - else: - f.write(" component " + acc.name + "_" + impl.name + "_top\n") - f.write(" port (\n") - write_acc_interface(f, acc, noc_width, impl.datatype, "ap_rst", True, False, False) - f.write(" );\n") - f.write(" end component;\n\n") - f.write("\n") - f.close() - ftemplate.close() - f = open(out_dir + '/allcaches.vhd', 'w') - with open(template_dir + '/allcaches.vhd', 'r') as ftemplate: - for tline in ftemplate: - if tline.find("-- <>") >= 0: - f.write(" constant INVACK_CNT_WIDTH : integer := " + str(invack_cnt_bits) + ";\n") - elif tline.find("-- <>") < 0: - f.write(tline) - continue - for cac in cache_list: - is_llc = "llc" in cac.name - for impl in cac.hlscfg: - f.write("\n") - f.write(" component " + cac.name + "_" + impl + "\n") - f.write(" port (\n") - write_cache_interface(f, cac, is_llc) - f.write(" );\n") - f.write(" end component;\n\n") - f.write("\n") - f.close() - ftemplate.close() +def gen_tech_dep( + accelerator_list, + cache_list, + noc_width, + template_dir, + out_dir): + f = open(out_dir + '/allacc.vhd', 'w') + with open(template_dir + '/allacc.vhd', 'r') as ftemplate: + for tline in ftemplate: + if tline.find("-- <>") < 0: + f.write(tline) + continue + for acc in accelerator_list: + for impl in acc.hlscfg: + f.write("\n") + if acc.hls_tool == 'stratus_hls' or acc.hls_tool == 'rtl': + f.write( + " component " + + acc.name + + "_" + + impl.name + + "\n") + f.write(" port (\n") + write_acc_interface( + f, acc, noc_width, impl.datatype, "rst", False, False, False) + elif acc.hls_tool == 'catapult_hls_cxx': + f.write( + " component " + + acc.name + + "_" + + impl.name + + "\n") + f.write(" port (\n") + write_acc_interface( + f, acc, noc_width, impl.datatype, "rst", False, True, False) + elif acc.hls_tool == 'catapult_hls_sysc': + f.write( + " component " + + acc.name + + "_" + + impl.name + + "\n") + f.write(" port (\n") + write_acc_interface( + f, acc, noc_width, impl.datatype, "rst", False, False, True) + else: + f.write( + " component " + + acc.name + + "_" + + impl.name + + "_top\n") + f.write(" port (\n") + write_acc_interface( + f, acc, noc_width, impl.datatype, "ap_rst", True, False, False) + f.write(" );\n") + f.write(" end component;\n\n") + f.write("\n") + f.close() + ftemplate.close() + f = open(out_dir + '/allcaches.vhd', 'w') + with open(template_dir + '/allcaches.vhd', 'r') as ftemplate: + for tline in ftemplate: + if tline.find("-- <>") >= 0: + f.write( + " constant INVACK_CNT_WIDTH : integer := " + + str(invack_cnt_bits) + + ";\n") + elif tline.find("-- <>") < 0: + f.write(tline) + continue + for cac in cache_list: + is_llc = "llc" in cac.name + for impl in cac.hlscfg: + f.write("\n") + f.write(" component " + cac.name + "_" + impl + "\n") + f.write(" port (\n") + write_cache_interface(f, cac, is_llc) + f.write(" );\n") + f.write(" end component;\n\n") + f.write("\n") + f.close() + ftemplate.close() # Component declaration independent from technology and implementation -def gen_tech_indep(accelerator_list, axi_accelerator_list, cache_list, noc_width, template_dir, out_dir): - f = open(out_dir + '/genacc.vhd', 'w') - with open(template_dir + '/genacc.vhd', 'r') as ftemplate: - for tline in ftemplate: - if tline.find("-- <>") < 0: - f.write(tline) - continue - for acc in accelerator_list: - f.write("\n") - f.write(" component " + acc.name + "_rtl\n") - f.write(" generic (\n") - f.write(" hls_conf : hlscfg_t\n") - f.write(" );\n") - f.write("\n") - f.write(" port (\n") - write_acc_interface(f, acc, noc_width, "", "acc_rst", False, False, False) - f.write(" );\n") - f.write(" end component;\n\n") - f.write("\n") - for acc in axi_accelerator_list: - f.write("\n") - f.write(" component " + acc.name + "_wrapper\n") - f.write(" port (\n") - write_axi_acc_interface(f, acc, noc_width) - f.write(" );\n") - f.write(" end component;\n\n") - f.write("\n") - f.close() - ftemplate.close() - # f = open(out_dir + '/gencaches.vhd', 'w') - # with open(template_dir + '/gencaches.vhd', 'r') as ftemplate: - # for tline in ftemplate: - # if tline.find("-- <>") < 0: - # f.write(tline) - # continue - # for cac in cache_list: - # is_llc = cac.name == "llc" - # f.write("\n") - # f.write(" component " + cac.name + "\n") - # f.write(" generic (\n") - # f.write(" sets : integer;\n") - # f.write(" ways : integer\n") - # f.write(" );\n") - # f.write("\n") - # f.write(" port (\n") - # write_cache_interface(f, cac, is_llc) - # f.write(" );\n") - # f.write(" end component;\n\n") - # f.write("\n") - # f.close() - # ftemplate.close() - - -# Mapping from generic components to technology and implementation dependent ones -def gen_tech_indep_impl(accelerator_list, cache_list, noc_width, template_dir, out_dir): - f = open(out_dir + '/accelerators.vhd', 'w') - with open(template_dir + '/accelerators.vhd', 'r') as ftemplate: - for tline in ftemplate: - if tline.find("-- <>") < 0: - f.write(tline) - continue - for acc in accelerator_list: - if acc.hls_tool == 'catapult_hls_cxx': - f.write("library ieee;\n") - f.write("use ieee.std_logic_1164.all;\n") - f.write("use work.sld_devices.all;\n") - f.write("use work.allacc.all;\n") - f.write("\n") - f.write("entity " + acc.name + "_rtl is\n\n") - f.write(" generic (\n") - f.write(" hls_conf : hlscfg_t\n") - f.write(" );\n") - f.write("\n") - f.write(" port (\n") - write_acc_interface(f, acc, noc_width, "", "acc_rst", False, False, False) - f.write(" );\n") - f.write("\n") - f.write("end entity " + acc.name + "_rtl;\n\n") - f.write("\n") - f.write("architecture mapping of " + acc.name + "_rtl is\n\n") - f.write("\n") - f.write("-- signals for conf_done fsm\n") - f.write("\n") - f.write("type rsc_state_t is (rsc_idle, rsc_handshake);\n") - f.write("signal rsc_state, rsc_state_next : rsc_state_t;\n") - f.write("\n") - f.write("signal conf_info_rsc_valid : std_ulogic;\n") - f.write("signal conf_info_rsc_ready : std_ulogic;\n") - f.write("\n") - f.write("\n") - f.write("begin -- mapping\n\n") - for impl in acc.hlscfg: - f.write("\n") - f.write(" impl_" + impl.name + "_gen: if hls_conf = HLSCFG_" + acc.name.upper() + "_" + impl.name.upper() + " generate\n") - f.write(" " + acc.name + "_" + impl.name + "_i: " + acc.name + "_" + impl.name + "\n") - write_acc_port_map(f, acc, noc_width, impl.datatype, "rst", False, False, True, False) - f.write("\n\n") - f.write(" -- CONF_DONE FSM\n") - f.write("\n") - f.write(" conf_done_fsm: process (rsc_state, conf_done, conf_info_rsc_ready) is\n") - f.write(" begin -- process conf_done_fsm\n") - f.write(" rsc_state_next <= rsc_state;\n") - f.write(" conf_info_rsc_valid <= '0';\n") - f.write("\n") - f.write(" case rsc_state is\n") - f.write("\n") - f.write(" when rsc_idle =>\n") - f.write(" if conf_done = '1' then\n") - f.write(" rsc_state_next <= rsc_handshake;\n") - f.write(" end if;\n") - f.write("\n") - f.write(" when rsc_handshake =>\n") - f.write(" conf_info_rsc_valid <= '1';\n") - f.write(" if conf_info_rsc_ready = '1' then\n") - f.write(" rsc_state_next <= rsc_idle;\n") - f.write(" end if;\n") - f.write("\n") - f.write(" when others =>\n") - f.write(" rsc_state_next <= rsc_idle;\n") - f.write("\n") - f.write(" end case;\n") - f.write(" end process conf_done_fsm;\n") - f.write("\n") - f.write(" conf_done_state_update: process (clk, acc_rst) is\n") - f.write(" begin -- process conf_done_state_update\n") - f.write(" if clk'event and clk = '1' then -- rising clock edge\n") - f.write(" if acc_rst = '0' then -- synchronous active low\n") - f.write(" rsc_state <= rsc_idle;\n") - f.write(" else\n") - f.write(" rsc_state <= rsc_state_next;\n") - f.write(" end if;\n") - f.write(" end if;\n") - f.write(" end process conf_done_state_update;\n") - f.write("\n") - f.write(" end generate impl_" + impl.name + "_gen;\n\n") - f.write("end mapping;\n\n") - elif acc.hls_tool == 'catapult_hls_sysc': - f.write("library ieee;\n") - f.write("use ieee.std_logic_1164.all;\n") - f.write("use work.sld_devices.all;\n") - f.write("use work.allacc.all;\n") - f.write("\n") - f.write("entity " + acc.name + "_rtl is\n\n") - f.write(" generic (\n") - f.write(" hls_conf : hlscfg_t\n") - f.write(" );\n") - f.write("\n") - f.write(" port (\n") - write_acc_interface(f, acc, noc_width, "", "acc_rst", False, False, False) - f.write(" );\n") - f.write("\n") - f.write("end entity " + acc.name + "_rtl;\n\n") - f.write("\n") - f.write("architecture mapping of " + acc.name + "_rtl is\n\n") - f.write("\n") - f.write("-- signals for conf_done fsm\n") - f.write("\n") - f.write("type rsc_state_t is (rsc_idle, rsc_handshake);\n") - f.write("signal rsc_state, rsc_state_next : rsc_state_t;\n") - f.write("\n") - f.write("signal conf_info_rsc_valid : std_ulogic;\n") - f.write("signal conf_info_rsc_ready : std_ulogic;\n") - f.write("\n") - f.write("\n") - f.write("begin -- mapping\n\n") - for impl in acc.hlscfg: - f.write("\n") - f.write(" impl_" + impl.name + "_gen: if hls_conf = HLSCFG_" + acc.name.upper() + "_" + impl.name.upper() + " generate\n") - f.write(" " + acc.name + "_" + impl.name + "_i: " + acc.name + "_" + impl.name + "\n") - write_acc_port_map(f, acc, noc_width, impl.datatype, "rst", False, False, False, True) - f.write("\n\n") - f.write(" -- CONF_DONE FSM\n") - f.write("\n") - f.write(" conf_done_fsm: process (rsc_state, conf_done, conf_info_rsc_ready) is\n") - f.write(" begin -- process conf_done_fsm\n") - f.write(" rsc_state_next <= rsc_state;\n") - f.write(" conf_info_rsc_valid <= '0';\n") - f.write("\n") - f.write(" case rsc_state is\n") - f.write("\n") - f.write(" when rsc_idle =>\n") - f.write(" if conf_done = '1' then\n") - f.write(" rsc_state_next <= rsc_handshake;\n") - f.write(" end if;\n") - f.write("\n") - f.write(" when rsc_handshake =>\n") - f.write(" conf_info_rsc_valid <= '1';\n") - f.write(" if conf_info_rsc_ready = '1' then\n") - f.write(" rsc_state_next <= rsc_idle;\n") - f.write(" end if;\n") - f.write("\n") - f.write(" when others =>\n") - f.write(" rsc_state_next <= rsc_idle;\n") - f.write("\n") - f.write(" end case;\n") - f.write(" end process conf_done_fsm;\n") - f.write("\n") - f.write(" conf_done_state_update: process (clk, acc_rst) is\n") - f.write(" begin -- process conf_done_state_update\n") - f.write(" if clk'event and clk = '1' then -- rising clock edge\n") - f.write(" if acc_rst = '0' then -- synchronous active low\n") - f.write(" rsc_state <= rsc_idle;\n") - f.write(" else\n") - f.write(" rsc_state <= rsc_state_next;\n") - f.write(" end if;\n") - f.write(" end if;\n") - f.write(" end process conf_done_state_update;\n") - f.write("\n") - f.write(" end generate impl_" + impl.name + "_gen;\n\n") - f.write("end mapping;\n\n") - - else: - f.write("library ieee;\n") - f.write("use ieee.std_logic_1164.all;\n") - f.write("use work.sld_devices.all;\n") - f.write("use work.allacc.all;\n") - f.write("\n") - f.write("entity " + acc.name + "_rtl is\n\n") - f.write(" generic (\n") - f.write(" hls_conf : hlscfg_t\n") - f.write(" );\n") - f.write("\n") - f.write(" port (\n") - write_acc_interface(f, acc, noc_width, "", "acc_rst", False, False, False) - f.write(" );\n") - f.write("\n") - f.write("end entity " + acc.name + "_rtl;\n\n") - f.write("\n") - f.write("architecture mapping of " + acc.name + "_rtl is\n\n") - if acc.hls_tool == 'vivado_hls': - write_ap_acc_signals(f) - f.write("begin -- mapping\n\n") - for impl in acc.hlscfg: - f.write("\n") - f.write(" impl_" + impl.name + "_gen: if hls_conf = HLSCFG_" + acc.name.upper() + "_" + impl.name.upper() + " generate\n") - if acc.hls_tool == 'stratus_hls' or acc.hls_tool == 'rtl': - f.write(" " + acc.name + "_" + impl.name + "_i: " + acc.name + "_" + impl.name + "\n") - write_acc_port_map(f, acc, noc_width, impl.datatype, "rst", False, False, False, False) - else: - f.write(" " + acc.name + "_" + impl.name + "_top_i: " + acc.name + "_" + impl.name + "_top\n") - write_acc_port_map(f, acc, noc_width, impl.datatype, "rst", False, True, False, False) - f.write(" end generate impl_" + impl.name + "_gen;\n\n") - f.write("end mapping;\n\n") - f.close() - ftemplate.close() - f = open(out_dir + '/caches.vhd', 'w') - with open(template_dir + '/caches.vhd', 'r') as ftemplate: - for tline in ftemplate: - if tline.find("-- <>") < 0: - f.write(tline) - continue - for cac in cache_list: - is_llc = "llc" in cac.name - f.write("library ieee;\n") - f.write("use ieee.std_logic_1164.all;\n") - f.write("use work.sld_devices.all;\n") - f.write("use work.allcaches.all;\n") - f.write("\n") - f.write("entity " + cac.name + " is\n\n") - f.write(" generic (\n") - f.write(" use_rtl : integer;\n") - if (not is_llc): - f.write(" little_end : integer range 0 to 1;\n") - if 'spandex' not in cac.name: - f.write(" llsc : integer range 0 to 1;\n") - f.write(" sets : integer;\n") - f.write(" ways : integer\n") - f.write(" );\n") - f.write("\n") - f.write(" port (\n") - write_cache_interface(f, cac, is_llc) - f.write(" );\n") - f.write("\n") - f.write("end entity " + cac.name + ";\n\n") - f.write("\n") - f.write("architecture mapping of " + cac.name + " is\n\n") - f.write("begin -- mapping\n\n") - if 'spandex' in cac.name: - pass - else: - f.write(" rtl_gen: if use_rtl /= 0 generate\n") - f.write(" " + cac.name + "_rtl_top_i: " + cac.name + "_rtl_top\n") - write_cache_port_map(f, cac, is_llc) - f.write(" end generate rtl_gen;\n\n") - f.write("\n") - f.write(" hls_gen: if use_rtl = 0 generate\n") - for impl in cac.hlscfg: - info = re.split('_|x', impl) - sets = 0 - ways = 0 - this_addr_bits = 0 - this_word_offset_bits = 0 - this_offset_bits = 0 - this_llsc = 0 - this_endian = "le" - for item in info: - if re.match(r'[0-9]+sets', item, re.M|re.I): - sets = int(item.replace("sets", "")) - elif re.match(r'[0-9]+ways', item, re.M|re.I): - ways = int(item.replace("ways", "")) - elif re.match(r'[0-9]+$', item, re.M|re.I): - this_word_offset_bits = int(math.log2(int(item))) - elif re.match(r'[0-9]+line', item, re.M|re.I): - this_offset_bits = int(int(math.log2((int(item.replace("line", "")))/8) + word_offset_bits)) - elif re.match(r'[0-9]+addr', item, re.M|re.I): - this_addr_bits = int(item.replace("addr", "")) - elif re.match(r'(no)?llsc', item, re.M|re.I): - if item == "llsc": - this_llsc = 1 - else: - this_llsc = 0 - elif re.match(r'[b|l]e', item, re.M|re.I): - if item == "le": - this_endian = 1 - else: - this_endian = 0 - if is_llc: - this_endian = little_endian - if sets * ways == 0: - print(" ERROR: hls config must report number of sets and ways, both different from zero") - sys.exit(1) - if this_word_offset_bits != word_offset_bits or this_offset_bits != offset_bits or this_addr_bits != phys_addr_bits or this_endian != little_endian: - print(" INFO: skipping cache implementation " + impl + " incompatible with SoC architecture") - continue - f.write("\n") - if is_llc: - f.write(" " + impl + "_gen: if sets = " + str(sets) + " and ways = " + str(ways) + " generate\n") - elif 'spandex' in cac.name: - f.write(" " + impl + "_gen: if little_end = " + str(this_endian) + " and sets = " + str(sets) + " and ways = " + str(ways) + " generate\n") - else: - f.write(" " + impl + "_gen: if little_end = " + str(this_endian) + " and llsc = " + str(this_llsc) + " and sets = " + str(sets) + " and ways = " + str(ways) + " generate\n") - f.write(" " + cac.name + "_" + impl + "_i: " + cac.name + "_" + impl + "\n") - write_cache_port_map(f, cac, is_llc) - f.write(" end generate " + impl + "_gen;\n\n") - f.write(" end generate hls_gen;\n\n") - f.write("end mapping;\n\n") - f.close() - ftemplate.close() +def gen_tech_indep( + accelerator_list, + axi_accelerator_list, + cache_list, + noc_width, + template_dir, + out_dir): + f = open(out_dir + '/genacc.vhd', 'w') + with open(template_dir + '/genacc.vhd', 'r') as ftemplate: + for tline in ftemplate: + if tline.find("-- <>") < 0: + f.write(tline) + continue + for acc in accelerator_list: + f.write("\n") + f.write(" component " + acc.name + "_rtl\n") + f.write(" generic (\n") + f.write(" hls_conf : hlscfg_t\n") + f.write(" );\n") + f.write("\n") + f.write(" port (\n") + write_acc_interface( + f, acc, noc_width, "", "acc_rst", False, False, False) + f.write(" );\n") + f.write(" end component;\n\n") + f.write("\n") + for acc in axi_accelerator_list: + f.write("\n") + f.write(" component " + acc.name + "_wrapper\n") + f.write(" port (\n") + write_axi_acc_interface(f, acc, noc_width) + f.write(" );\n") + f.write(" end component;\n\n") + f.write("\n") + f.close() + ftemplate.close() + # f = open(out_dir + '/gencaches.vhd', 'w') + # with open(template_dir + '/gencaches.vhd', 'r') as ftemplate: + # for tline in ftemplate: + # if tline.find("-- <>") < 0: + # f.write(tline) + # continue + # for cac in cache_list: + # is_llc = cac.name == "llc" + # f.write("\n") + # f.write(" component " + cac.name + "\n") + # f.write(" generic (\n") + # f.write(" sets : integer;\n") + # f.write(" ways : integer\n") + # f.write(" );\n") + # f.write("\n") + # f.write(" port (\n") + # write_cache_interface(f, cac, is_llc) + # f.write(" );\n") + # f.write(" end component;\n\n") + # f.write("\n") + # f.close() + # ftemplate.close() + + +# Mapping from generic components to technology and implementation +# dependent ones +def gen_tech_indep_impl( + accelerator_list, + cache_list, + noc_width, + template_dir, + out_dir): + f = open(out_dir + '/accelerators.vhd', 'w') + with open(template_dir + '/accelerators.vhd', 'r') as ftemplate: + for tline in ftemplate: + if tline.find("-- <>") < 0: + f.write(tline) + continue + for acc in accelerator_list: + if acc.hls_tool == 'catapult_hls_cxx': + f.write("library ieee;\n") + f.write("use ieee.std_logic_1164.all;\n") + f.write("use work.sld_devices.all;\n") + f.write("use work.allacc.all;\n") + f.write("\n") + f.write("entity " + acc.name + "_rtl is\n\n") + f.write(" generic (\n") + f.write(" hls_conf : hlscfg_t\n") + f.write(" );\n") + f.write("\n") + f.write(" port (\n") + write_acc_interface( + f, acc, noc_width, "", "acc_rst", False, False, False) + f.write(" );\n") + f.write("\n") + f.write("end entity " + acc.name + "_rtl;\n\n") + f.write("\n") + f.write( + "architecture mapping of " + + acc.name + + "_rtl is\n\n") + f.write("\n") + f.write("-- signals for conf_done fsm\n") + f.write("\n") + f.write("type rsc_state_t is (rsc_idle, rsc_handshake);\n") + f.write("signal rsc_state, rsc_state_next : rsc_state_t;\n") + f.write("\n") + f.write("signal conf_info_rsc_valid : std_ulogic;\n") + f.write("signal conf_info_rsc_ready : std_ulogic;\n") + f.write("\n") + f.write("\n") + f.write("begin -- mapping\n\n") + for impl in acc.hlscfg: + f.write("\n") + f.write( + " impl_" + + impl.name + + "_gen: if hls_conf = HLSCFG_" + + acc.name.upper() + + "_" + + impl.name.upper() + + " generate\n") + f.write( + " " + + acc.name + + "_" + + impl.name + + "_i: " + + acc.name + + "_" + + impl.name + + "\n") + write_acc_port_map( + f, + acc, + noc_width, + impl.datatype, + "rst", + False, + False, + True, + False) + f.write("\n\n") + f.write(" -- CONF_DONE FSM\n") + f.write("\n") + f.write( + " conf_done_fsm: process (rsc_state, conf_done, conf_info_rsc_ready) is\n") + f.write(" begin -- process conf_done_fsm\n") + f.write(" rsc_state_next <= rsc_state;\n") + f.write(" conf_info_rsc_valid <= '0';\n") + f.write("\n") + f.write(" case rsc_state is\n") + f.write("\n") + f.write(" when rsc_idle =>\n") + f.write(" if conf_done = '1' then\n") + f.write(" rsc_state_next <= rsc_handshake;\n") + f.write(" end if;\n") + f.write("\n") + f.write(" when rsc_handshake =>\n") + f.write(" conf_info_rsc_valid <= '1';\n") + f.write(" if conf_info_rsc_ready = '1' then\n") + f.write(" rsc_state_next <= rsc_idle;\n") + f.write(" end if;\n") + f.write("\n") + f.write(" when others =>\n") + f.write(" rsc_state_next <= rsc_idle;\n") + f.write("\n") + f.write(" end case;\n") + f.write(" end process conf_done_fsm;\n") + f.write("\n") + f.write( + " conf_done_state_update: process (clk, acc_rst) is\n") + f.write(" begin -- process conf_done_state_update\n") + f.write( + " if clk'event and clk = '1' then -- rising clock edge\n") + f.write( + " if acc_rst = '0' then -- synchronous active low\n") + f.write(" rsc_state <= rsc_idle;\n") + f.write(" else\n") + f.write(" rsc_state <= rsc_state_next;\n") + f.write(" end if;\n") + f.write(" end if;\n") + f.write(" end process conf_done_state_update;\n") + f.write("\n") + f.write( + " end generate impl_" + + impl.name + + "_gen;\n\n") + f.write("end mapping;\n\n") + elif acc.hls_tool == 'catapult_hls_sysc': + f.write("library ieee;\n") + f.write("use ieee.std_logic_1164.all;\n") + f.write("use work.sld_devices.all;\n") + f.write("use work.allacc.all;\n") + f.write("\n") + f.write("entity " + acc.name + "_rtl is\n\n") + f.write(" generic (\n") + f.write(" hls_conf : hlscfg_t\n") + f.write(" );\n") + f.write("\n") + f.write(" port (\n") + write_acc_interface( + f, acc, noc_width, "", "acc_rst", False, False, False) + f.write(" );\n") + f.write("\n") + f.write("end entity " + acc.name + "_rtl;\n\n") + f.write("\n") + f.write( + "architecture mapping of " + + acc.name + + "_rtl is\n\n") + f.write("\n") + f.write("-- signals for conf_done fsm\n") + f.write("\n") + f.write("type rsc_state_t is (rsc_idle, rsc_handshake);\n") + f.write("signal rsc_state, rsc_state_next : rsc_state_t;\n") + f.write("\n") + f.write("signal conf_info_rsc_valid : std_ulogic;\n") + f.write("signal conf_info_rsc_ready : std_ulogic;\n") + f.write("\n") + f.write("\n") + f.write("begin -- mapping\n\n") + for impl in acc.hlscfg: + f.write("\n") + f.write( + " impl_" + + impl.name + + "_gen: if hls_conf = HLSCFG_" + + acc.name.upper() + + "_" + + impl.name.upper() + + " generate\n") + f.write( + " " + + acc.name + + "_" + + impl.name + + "_i: " + + acc.name + + "_" + + impl.name + + "\n") + write_acc_port_map( + f, + acc, + noc_width, + impl.datatype, + "rst", + False, + False, + False, + True) + f.write("\n\n") + f.write(" -- CONF_DONE FSM\n") + f.write("\n") + f.write( + " conf_done_fsm: process (rsc_state, conf_done, conf_info_rsc_ready) is\n") + f.write(" begin -- process conf_done_fsm\n") + f.write(" rsc_state_next <= rsc_state;\n") + f.write(" conf_info_rsc_valid <= '0';\n") + f.write("\n") + f.write(" case rsc_state is\n") + f.write("\n") + f.write(" when rsc_idle =>\n") + f.write(" if conf_done = '1' then\n") + f.write(" rsc_state_next <= rsc_handshake;\n") + f.write(" end if;\n") + f.write("\n") + f.write(" when rsc_handshake =>\n") + f.write(" conf_info_rsc_valid <= '1';\n") + f.write(" if conf_info_rsc_ready = '1' then\n") + f.write(" rsc_state_next <= rsc_idle;\n") + f.write(" end if;\n") + f.write("\n") + f.write(" when others =>\n") + f.write(" rsc_state_next <= rsc_idle;\n") + f.write("\n") + f.write(" end case;\n") + f.write(" end process conf_done_fsm;\n") + f.write("\n") + f.write( + " conf_done_state_update: process (clk, acc_rst) is\n") + f.write(" begin -- process conf_done_state_update\n") + f.write( + " if clk'event and clk = '1' then -- rising clock edge\n") + f.write( + " if acc_rst = '0' then -- synchronous active low\n") + f.write(" rsc_state <= rsc_idle;\n") + f.write(" else\n") + f.write(" rsc_state <= rsc_state_next;\n") + f.write(" end if;\n") + f.write(" end if;\n") + f.write(" end process conf_done_state_update;\n") + f.write("\n") + f.write( + " end generate impl_" + + impl.name + + "_gen;\n\n") + f.write("end mapping;\n\n") + + else: + f.write("library ieee;\n") + f.write("use ieee.std_logic_1164.all;\n") + f.write("use work.sld_devices.all;\n") + f.write("use work.allacc.all;\n") + f.write("\n") + f.write("entity " + acc.name + "_rtl is\n\n") + f.write(" generic (\n") + f.write(" hls_conf : hlscfg_t\n") + f.write(" );\n") + f.write("\n") + f.write(" port (\n") + write_acc_interface( + f, acc, noc_width, "", "acc_rst", False, False, False) + f.write(" );\n") + f.write("\n") + f.write("end entity " + acc.name + "_rtl;\n\n") + f.write("\n") + f.write( + "architecture mapping of " + + acc.name + + "_rtl is\n\n") + if acc.hls_tool == 'vivado_hls': + write_ap_acc_signals(f) + f.write("begin -- mapping\n\n") + for impl in acc.hlscfg: + f.write("\n") + f.write( + " impl_" + + impl.name + + "_gen: if hls_conf = HLSCFG_" + + acc.name.upper() + + "_" + + impl.name.upper() + + " generate\n") + if acc.hls_tool == 'stratus_hls' or acc.hls_tool == 'rtl': + f.write( + " " + + acc.name + + "_" + + impl.name + + "_i: " + + acc.name + + "_" + + impl.name + + "\n") + write_acc_port_map( + f, acc, noc_width, impl.datatype, "rst", False, False, False, False) + else: + f.write( + " " + + acc.name + + "_" + + impl.name + + "_top_i: " + + acc.name + + "_" + + impl.name + + "_top\n") + write_acc_port_map( + f, acc, noc_width, impl.datatype, "rst", False, True, False, False) + f.write( + " end generate impl_" + + impl.name + + "_gen;\n\n") + f.write("end mapping;\n\n") + f.close() + ftemplate.close() + f = open(out_dir + '/caches.vhd', 'w') + with open(template_dir + '/caches.vhd', 'r') as ftemplate: + for tline in ftemplate: + if tline.find("-- <>") < 0: + f.write(tline) + continue + for cac in cache_list: + is_llc = "llc" in cac.name + f.write("library ieee;\n") + f.write("use ieee.std_logic_1164.all;\n") + f.write("use work.sld_devices.all;\n") + f.write("use work.allcaches.all;\n") + f.write("\n") + f.write("entity " + cac.name + " is\n\n") + f.write(" generic (\n") + f.write(" use_rtl : integer;\n") + if (not is_llc): + f.write(" little_end : integer range 0 to 1;\n") + if 'spandex' not in cac.name: + f.write( + " llsc : integer range 0 to 1;\n") + f.write(" sets : integer;\n") + f.write(" ways : integer\n") + f.write(" );\n") + f.write("\n") + f.write(" port (\n") + write_cache_interface(f, cac, is_llc) + f.write(" );\n") + f.write("\n") + f.write("end entity " + cac.name + ";\n\n") + f.write("\n") + f.write("architecture mapping of " + cac.name + " is\n\n") + f.write("begin -- mapping\n\n") + if 'spandex' in cac.name: + pass + else: + f.write(" rtl_gen: if use_rtl /= 0 generate\n") + f.write( + " " + + cac.name + + "_rtl_top_i: " + + cac.name + + "_rtl_top\n") + write_cache_port_map(f, cac, is_llc) + f.write(" end generate rtl_gen;\n\n") + f.write("\n") + f.write(" hls_gen: if use_rtl = 0 generate\n") + for impl in cac.hlscfg: + info = re.split('_|x', impl) + sets = 0 + ways = 0 + this_addr_bits = 0 + this_word_offset_bits = 0 + this_offset_bits = 0 + this_llsc = 0 + this_endian = "le" + for item in info: + if re.match(r'[0-9]+sets', item, re.M | re.I): + sets = int(item.replace("sets", "")) + elif re.match(r'[0-9]+ways', item, re.M | re.I): + ways = int(item.replace("ways", "")) + elif re.match(r'[0-9]+$', item, re.M | re.I): + this_word_offset_bits = int(math.log2(int(item))) + elif re.match(r'[0-9]+line', item, re.M | re.I): + this_offset_bits = int( + int(math.log2((int(item.replace("line", ""))) / 8) + word_offset_bits)) + elif re.match(r'[0-9]+addr', item, re.M | re.I): + this_addr_bits = int(item.replace("addr", "")) + elif re.match(r'(no)?llsc', item, re.M | re.I): + if item == "llsc": + this_llsc = 1 + else: + this_llsc = 0 + elif re.match(r'[b|l]e', item, re.M | re.I): + if item == "le": + this_endian = 1 + else: + this_endian = 0 + if is_llc: + this_endian = little_endian + if sets * ways == 0: + print( + " ERROR: hls config must report number of sets and ways, both different from zero") + sys.exit(1) + if this_word_offset_bits != word_offset_bits or this_offset_bits != offset_bits or this_addr_bits != phys_addr_bits or this_endian != little_endian: + print( + " INFO: skipping cache implementation " + + impl + + " incompatible with SoC architecture") + continue + f.write("\n") + if is_llc: + f.write( + " " + + impl + + "_gen: if sets = " + + str(sets) + + " and ways = " + + str(ways) + + " generate\n") + elif 'spandex' in cac.name: + f.write( + " " + + impl + + "_gen: if little_end = " + + str(this_endian) + + " and sets = " + + str(sets) + + " and ways = " + + str(ways) + + " generate\n") + else: + f.write( + " " + + impl + + "_gen: if little_end = " + + str(this_endian) + + " and llsc = " + + str(this_llsc) + + " and sets = " + + str(sets) + + " and ways = " + + str(ways) + + " generate\n") + f.write( + " " + + cac.name + + "_" + + impl + + "_i: " + + cac.name + + "_" + + impl + + "\n") + write_cache_port_map(f, cac, is_llc) + f.write(" end generate " + impl + "_gen;\n\n") + f.write(" end generate hls_gen;\n\n") + f.write("end mapping;\n\n") + f.close() + ftemplate.close() # Component declaration of NoC wrappers -def gen_interfaces(accelerator_list, axi_accelerator_list, noc_width, template_dir, out_dir): - f = open(out_dir + '/sldacc.vhd', 'w') - with open(template_dir + '/sldacc.vhd', 'r') as ftemplate: - for tline in ftemplate: - if tline.find("-- <>") < 0: - f.write(tline) - continue - for acc in accelerator_list + axi_accelerator_list: - f.write("\n") - f.write(" component noc_" + acc.name + "\n") - f.write(" generic (\n") - f.write(" hls_conf : hlscfg_t;\n") - f.write(" tech : integer;\n") - f.write(" mem_num : integer;\n") - f.write(" cacheable_mem_num : integer;\n") - f.write(" mem_info : tile_mem_info_vector(0 to CFG_NMEM_TILE + CFG_NSLM_TILE + CFG_NSLMDDR_TILE);\n") - f.write(" io_y : local_yx;\n") - f.write(" io_x : local_yx;\n") - f.write(" pindex : integer;\n") - f.write(" irq_type : integer := 0;\n") - f.write(" scatter_gather : integer := 1;\n") - f.write(" sets : integer;\n") - f.write(" ways : integer;\n") - f.write(" little_end : integer range 0 to 1;\n") - f.write(" cache_tile_id : cache_attribute_array;\n") - f.write(" cache_y : yx_vec(0 to 2**NL2_MAX_LOG2 - 1);\n") - f.write(" cache_x : yx_vec(0 to 2**NL2_MAX_LOG2 - 1);\n") - f.write(" has_l2 : integer := 1;\n") - f.write(" has_dvfs : integer := 1;\n") - f.write(" has_pll : integer;\n") - f.write(" extra_clk_buf : integer\n") - f.write(" );\n") - f.write("\n") - f.write(" port (\n") - f.write(" rst : in std_ulogic;\n") - f.write(" clk : in std_ulogic;\n") - f.write(" refclk : in std_ulogic;\n") - f.write(" pllbypass : in std_ulogic;\n") - f.write(" pllclk : out std_ulogic;\n") - f.write(" local_y : in local_yx;\n") - f.write(" local_x : in local_yx;\n") - f.write(" tile_id : in integer range 0 to CFG_TILES_NUM - 1;\n") - f.write(" paddr : in integer range 0 to 4095;\n") - f.write(" pmask : in integer range 0 to 4095;\n") - f.write(" paddr_ext : in integer range 0 to 4095;\n") - f.write(" pmask_ext : in integer range 0 to 4095;\n") - f.write(" pirq : in integer range 0 to NAHBIRQ - 1;\n") - f.write(" apbi : in apb_slv_in_type;\n") - f.write(" apbo : out apb_slv_out_type;\n") - f.write(" pready : out std_ulogic;\n") - f.write(" coherence_req_wrreq : out std_ulogic;\n") - f.write(" coherence_req_data_in : out coh_noc_flit_type;\n") - f.write(" coherence_req_full : in std_ulogic;\n") - f.write(" coherence_fwd_rdreq : out std_ulogic;\n") - f.write(" coherence_fwd_data_out : in coh_noc_flit_type;\n") - f.write(" coherence_fwd_empty : in std_ulogic;\n") - f.write(" coherence_rsp_rcv_rdreq : out std_ulogic;\n") - f.write(" coherence_rsp_rcv_data_out : in coh_noc_flit_type;\n") - f.write(" coherence_rsp_rcv_empty : in std_ulogic;\n") - f.write(" coherence_rsp_snd_wrreq : out std_ulogic;\n") - f.write(" coherence_rsp_snd_data_in : out coh_noc_flit_type;\n") - f.write(" coherence_rsp_snd_full : in std_ulogic;\n") - f.write(" coherence_fwd_snd_wrreq : out std_ulogic;\n") - f.write(" coherence_fwd_snd_data_in : out coh_noc_flit_type;\n") - f.write(" coherence_fwd_snd_full : in std_ulogic;\n") - f.write(" dma_rcv_rdreq : out std_ulogic;\n") - f.write(" dma_rcv_data_out : in dma_noc_flit_type;\n") - f.write(" dma_rcv_empty : in std_ulogic;\n") - f.write(" dma_snd_wrreq : out std_ulogic;\n") - f.write(" dma_snd_data_in : out dma_noc_flit_type;\n") - f.write(" dma_snd_full : in std_ulogic;\n") - f.write(" coherent_dma_rcv_rdreq : out std_ulogic;\n") - f.write(" coherent_dma_rcv_data_out : in dma_noc_flit_type;\n") - f.write(" coherent_dma_rcv_empty : in std_ulogic;\n") - f.write(" coherent_dma_snd_wrreq : out std_ulogic;\n") - f.write(" coherent_dma_snd_data_in : out dma_noc_flit_type;\n") - f.write(" coherent_dma_snd_full : in std_ulogic;\n") - f.write(" interrupt_wrreq : out std_ulogic;\n") - f.write(" interrupt_data_in : out misc_noc_flit_type;\n") - f.write(" interrupt_full : in std_ulogic;\n") - f.write(" interrupt_ack_rdreq : out std_ulogic;\n") - f.write(" interrupt_ack_data_out : in misc_noc_flit_type;\n") - f.write(" interrupt_ack_empty : in std_ulogic;\n") - f.write(" mon_dvfs_in : in monitor_dvfs_type;\n") - f.write(" mon_acc : out monitor_acc_type;\n") - f.write(" mon_cache : out monitor_cache_type;\n") - f.write(" mon_dvfs : out monitor_dvfs_type;\n") - f.write(" coherence : in integer range 0 to 3);\n") - f.write(" end component;\n\n") - f.write("\n") - f.close() - ftemplate.close() +def gen_interfaces( + accelerator_list, + axi_accelerator_list, + noc_width, + template_dir, + out_dir): + f = open(out_dir + '/sldacc.vhd', 'w') + with open(template_dir + '/sldacc.vhd', 'r') as ftemplate: + for tline in ftemplate: + if tline.find("-- <>") < 0: + f.write(tline) + continue + for acc in accelerator_list + axi_accelerator_list: + f.write("\n") + f.write(" component noc_" + acc.name + "\n") + f.write(" generic (\n") + f.write(" hls_conf : hlscfg_t;\n") + f.write(" tech : integer;\n") + f.write(" mem_num : integer;\n") + f.write(" cacheable_mem_num : integer;\n") + f.write( + " mem_info : tile_mem_info_vector(0 to CFG_NMEM_TILE + CFG_NSLM_TILE + CFG_NSLMDDR_TILE);\n") + f.write(" io_y : local_yx;\n") + f.write(" io_x : local_yx;\n") + f.write(" pindex : integer;\n") + f.write(" irq_type : integer := 0;\n") + f.write(" scatter_gather : integer := 1;\n") + f.write(" sets : integer;\n") + f.write(" ways : integer;\n") + f.write(" little_end : integer range 0 to 1;\n") + f.write(" cache_tile_id : cache_attribute_array;\n") + f.write(" cache_y : yx_vec(0 to 2**NL2_MAX_LOG2 - 1);\n") + f.write(" cache_x : yx_vec(0 to 2**NL2_MAX_LOG2 - 1);\n") + f.write(" has_l2 : integer := 1;\n") + f.write(" has_dvfs : integer := 1;\n") + f.write(" has_pll : integer;\n") + f.write(" extra_clk_buf : integer\n") + f.write(" );\n") + f.write("\n") + f.write(" port (\n") + f.write(" rst : in std_ulogic;\n") + f.write(" clk : in std_ulogic;\n") + f.write(" refclk : in std_ulogic;\n") + f.write(" pllbypass : in std_ulogic;\n") + f.write(" pllclk : out std_ulogic;\n") + f.write(" local_y : in local_yx;\n") + f.write(" local_x : in local_yx;\n") + f.write( + " tile_id : in integer range 0 to CFG_TILES_NUM - 1;\n") + f.write(" paddr : in integer range 0 to 4095;\n") + f.write(" pmask : in integer range 0 to 4095;\n") + f.write(" paddr_ext : in integer range 0 to 4095;\n") + f.write(" pmask_ext : in integer range 0 to 4095;\n") + f.write( + " pirq : in integer range 0 to NAHBIRQ - 1;\n") + f.write(" apbi : in apb_slv_in_type;\n") + f.write(" apbo : out apb_slv_out_type;\n") + f.write(" pready : out std_ulogic;\n") + f.write(" coherence_req_wrreq : out std_ulogic;\n") + f.write( + " coherence_req_data_in : out coh_noc_flit_type;\n") + f.write(" coherence_req_full : in std_ulogic;\n") + f.write(" coherence_fwd_rdreq : out std_ulogic;\n") + f.write( + " coherence_fwd_data_out : in coh_noc_flit_type;\n") + f.write(" coherence_fwd_empty : in std_ulogic;\n") + f.write(" coherence_rsp_rcv_rdreq : out std_ulogic;\n") + f.write( + " coherence_rsp_rcv_data_out : in coh_noc_flit_type;\n") + f.write(" coherence_rsp_rcv_empty : in std_ulogic;\n") + f.write(" coherence_rsp_snd_wrreq : out std_ulogic;\n") + f.write( + " coherence_rsp_snd_data_in : out coh_noc_flit_type;\n") + f.write(" coherence_rsp_snd_full : in std_ulogic;\n") + f.write(" coherence_fwd_snd_wrreq : out std_ulogic;\n") + f.write( + " coherence_fwd_snd_data_in : out coh_noc_flit_type;\n") + f.write(" coherence_fwd_snd_full : in std_ulogic;\n") + f.write(" dma_rcv_rdreq : out std_ulogic;\n") + f.write(" dma_rcv_data_out : in dma_noc_flit_type;\n") + f.write(" dma_rcv_empty : in std_ulogic;\n") + f.write(" dma_snd_wrreq : out std_ulogic;\n") + f.write(" dma_snd_data_in : out dma_noc_flit_type;\n") + f.write(" dma_snd_full : in std_ulogic;\n") + f.write(" coherent_dma_rcv_rdreq : out std_ulogic;\n") + f.write( + " coherent_dma_rcv_data_out : in dma_noc_flit_type;\n") + f.write(" coherent_dma_rcv_empty : in std_ulogic;\n") + f.write(" coherent_dma_snd_wrreq : out std_ulogic;\n") + f.write( + " coherent_dma_snd_data_in : out dma_noc_flit_type;\n") + f.write(" coherent_dma_snd_full : in std_ulogic;\n") + f.write(" interrupt_wrreq : out std_ulogic;\n") + f.write(" interrupt_data_in : out misc_noc_flit_type;\n") + f.write(" interrupt_full : in std_ulogic;\n") + f.write(" interrupt_ack_rdreq : out std_ulogic;\n") + f.write(" interrupt_ack_data_out : in misc_noc_flit_type;\n") + f.write(" interrupt_ack_empty : in std_ulogic;\n") + f.write(" mon_dvfs_in : in monitor_dvfs_type;\n") + f.write(" mon_acc : out monitor_acc_type;\n") + f.write(" mon_cache : out monitor_cache_type;\n") + f.write(" mon_dvfs : out monitor_dvfs_type;\n") + f.write(" coherence : in integer range 0 to 3);\n") + f.write(" end component;\n\n") + f.write("\n") + f.close() + ftemplate.close() def gen_noc_interface(acc, noc_width, template_dir, out_dir, is_axi): - f = open(out_dir + "/noc_" + acc.name + ".vhd", 'w') - - if not is_axi: - extra_str = "" - else: - extra_str = "2axi" - - template_file = template_dir + '/noc' + extra_str + '_interface.vhd' - - with open(template_file, 'r') as ftemplate: - for tline in ftemplate: - if tline.find("-- <>") >= 0: - f.write("entity noc" + "_" + acc.name + " is\n") - elif tline.find("-- <>") >= 0: - f.write("architecture rtl of noc" + "_" + acc.name + " is\n") - elif tline.find("-- <>") >= 0: - f.write(" constant devid : devid_t := SLD_" + acc.name.upper() + ";\n") - elif tline.find("-- <>") >= 0: - f.write(" constant tlb_entries : integer := " + str(acc.data) + ";\n") - elif tline.find("-- <>") >= 0: - for param in acc.param: - f.write(" -- bank(" + str(param.reg) + "): " + param.desc + "\n") - f.write(" constant " + acc.name.upper() + "_" + param.name.upper() + "_REG : integer range 0 to MAXREGNUM - 1 := " + str(param.reg) + ";\n\n") - elif tline.find("-- <>") >= 0: - for param in acc.param: - if param.readonly: - f.write(" " + acc.name.upper() + "_" + param.name.upper() + "_REG" + (31 - len(acc.name) - len(param.name))*" " + "=> '1',\n") - elif tline.find("-- <>") >= 0: - for param in acc.param: - f.write(" " + acc.name.upper() + "_" + param.name.upper() + "_REG" + (31 - len(acc.name) - len(param.name))*" " + "=> '1',\n") - elif tline.find("-- <>") >= 0: - for param in acc.param: - if param.readonly: - f.write(" " + acc.name.upper() + "_" + param.name.upper() + "_REG" + (31 - len(acc.name) - len(param.name))*" " + "=> X\"" + format(param.value, '08x') + "\",\n") - elif tline.find("-- <>") >= 0: - tie_unused_axi(f, acc, noc_width) - elif tline.find("-- <>") >= 0: - f.write(" " + acc.name + "_rlt_i: " + acc.name) - if is_axi: - f.write("_wrapper\n") - write_axi_acc_port_map(f, acc, noc_width) - else: - f.write("_rtl\n") - f.write(" generic map (\n") - f.write(" hls_conf => hls_conf\n") - f.write(" )\n") - write_acc_port_map(f, acc, noc_width, "", "acc_rst", True, False, False, False) - else: - f.write(tline) + f = open(out_dir + "/noc_" + acc.name + ".vhd", 'w') + + if not is_axi: + extra_str = "" + else: + extra_str = "2axi" + + template_file = template_dir + '/noc' + extra_str + '_interface.vhd' + + with open(template_file, 'r') as ftemplate: + for tline in ftemplate: + if tline.find("-- <>") >= 0: + f.write("entity noc" + "_" + acc.name + " is\n") + elif tline.find("-- <>") >= 0: + f.write("architecture rtl of noc" + "_" + acc.name + " is\n") + elif tline.find("-- <>") >= 0: + f.write( + " constant devid : devid_t := SLD_" + + acc.name.upper() + + ";\n") + elif tline.find("-- <>") >= 0: + f.write( + " constant tlb_entries : integer := " + str(acc.data) + ";\n") + elif tline.find("-- <>") >= 0: + for param in acc.param: + f.write(" -- bank(" + str(param.reg) + "): " + + param.desc + "\n") + f.write(" constant " + + acc.name.upper() + + "_" + + param.name.upper() + + "_REG : integer range 0 to MAXREGNUM - 1 := " + + str(param.reg) + + ";\n\n") + elif tline.find("-- <>") >= 0: + for param in acc.param: + if param.readonly: + f.write(" " + + acc.name.upper() + + "_" + + param.name.upper() + + "_REG" + + (31 - + len(acc.name) - + len(param.name)) * + " " + + "=> '1',\n") + elif tline.find("-- <>") >= 0: + for param in acc.param: + f.write(" " + + acc.name.upper() + + "_" + + param.name.upper() + + "_REG" + + (31 - + len(acc.name) - + len(param.name)) * + " " + + "=> '1',\n") + elif tline.find("-- <>") >= 0: + for param in acc.param: + if param.readonly: + f.write(" " + + acc.name.upper() + + "_" + + param.name.upper() + + "_REG" + + (31 - + len(acc.name) - + len(param.name)) * + " " + + "=> X\"" + + format(param.value, '08x') + + "\",\n") + elif tline.find("-- <>") >= 0: + tie_unused_axi(f, acc, noc_width) + elif tline.find("-- <>") >= 0: + f.write(" " + acc.name + "_rlt_i: " + acc.name) + if is_axi: + f.write("_wrapper\n") + write_axi_acc_port_map(f, acc, noc_width) + else: + f.write("_rtl\n") + f.write(" generic map (\n") + f.write(" hls_conf => hls_conf\n") + f.write(" )\n") + write_acc_port_map( + f, acc, noc_width, "", "acc_rst", True, False, False, False) + else: + f.write(tline) def gen_tile_acc(accelerator_list, axi_acceleratorlist, template_dir, out_dir): - f = open(out_dir + "/tile_acc.vhd", 'w') - with open(template_dir + '/tile_acc.vhd', 'r') as ftemplate: - for tline in ftemplate: - if tline.find("-- <>") >= 0: - for acc in accelerator_list + axi_accelerator_list: - f.write(" " + acc.name + "_gen: if this_device = SLD_" + acc.name.upper() + " generate\n") - f.write(" noc_" + acc.name + "_i: noc_" + acc.name + "\n") - f.write(" generic map (\n") - f.write(" hls_conf => this_hls_conf,\n") - f.write(" tech => CFG_FABTECH,\n") - f.write(" mem_num => CFG_NMEM_TILE + CFG_NSLM_TILE + CFG_NSLMDDR_TILE + CFG_SVGA_ENABLE,\n") - f.write(" cacheable_mem_num => CFG_NMEM_TILE,\n") - f.write(" mem_info => tile_acc_mem_list,\n") - f.write(" io_y => io_y,\n") - f.write(" io_x => io_x,\n") - f.write(" pindex => 1,\n") - f.write(" irq_type => this_irq_type,\n") - f.write(" scatter_gather => this_scatter_gather,\n") - f.write(" sets => CFG_ACC_L2_SETS,\n") - f.write(" ways => CFG_ACC_L2_WAYS,\n") - f.write(" little_end => little_end,\n") - f.write(" cache_tile_id => cache_tile_id,\n") - f.write(" cache_y => cache_y,\n") - f.write(" cache_x => cache_x,\n") - f.write(" has_l2 => this_has_l2,\n") - f.write(" has_dvfs => this_has_dvfs,\n") - f.write(" has_pll => this_has_pll,\n") - f.write(" extra_clk_buf => this_extra_clk_buf)\n") - f.write(" port map (\n") - f.write(" rst => rst,\n") - f.write(" clk => clk_feedthru,\n") - f.write(" refclk => dvfs_clk,\n") - f.write(" pllbypass => pllbypass,\n") - f.write(" pllclk => clk_feedthru,\n") - f.write(" local_y => this_local_y,\n") - f.write(" local_x => this_local_x,\n") - f.write(" tile_id => tile_id,\n") - f.write(" paddr => this_paddr,\n") - f.write(" pmask => this_pmask,\n") - f.write(" paddr_ext => this_paddr_ext,\n") - f.write(" pmask_ext => this_pmask_ext,\n") - f.write(" pirq => this_pirq,\n") - f.write(" apbi => apbi,\n") - f.write(" apbo => apbo(1),\n") - f.write(" pready => pready,\n") - f.write(" coherence_req_wrreq => coherence_req_wrreq,\n") - f.write(" coherence_req_data_in => coherence_req_data_in,\n") - f.write(" coherence_req_full => coherence_req_full,\n") - f.write(" coherent_dma_rcv_rdreq => coherent_dma_rcv_rdreq,\n") - f.write(" coherent_dma_rcv_data_out => coherent_dma_rcv_data_out,\n") - f.write(" coherent_dma_rcv_empty => coherent_dma_rcv_empty,\n") - f.write(" coherence_fwd_rdreq => coherence_fwd_rdreq,\n") - f.write(" coherence_fwd_data_out => coherence_fwd_data_out,\n") - f.write(" coherence_fwd_empty => coherence_fwd_empty,\n") - f.write(" coherent_dma_snd_wrreq => coherent_dma_snd_wrreq,\n") - f.write(" coherent_dma_snd_data_in => coherent_dma_snd_data_in,\n") - f.write(" coherent_dma_snd_full => coherent_dma_snd_full,\n") - f.write(" coherence_rsp_rcv_rdreq => coherence_rsp_rcv_rdreq,\n") - f.write(" coherence_rsp_rcv_data_out => coherence_rsp_rcv_data_out,\n") - f.write(" coherence_rsp_rcv_empty => coherence_rsp_rcv_empty,\n") - f.write(" coherence_rsp_snd_wrreq => coherence_rsp_snd_wrreq,\n") - f.write(" coherence_rsp_snd_data_in => coherence_rsp_snd_data_in,\n") - f.write(" coherence_rsp_snd_full => coherence_rsp_snd_full,\n") - f.write(" coherence_fwd_snd_wrreq => coherence_fwd_snd_wrreq,\n") - f.write(" coherence_fwd_snd_data_in => coherence_fwd_snd_data_in,\n") - f.write(" coherence_fwd_snd_full => coherence_fwd_snd_full,\n") - f.write(" dma_rcv_rdreq => dma_rcv_rdreq,\n") - f.write(" dma_rcv_data_out => dma_rcv_data_out,\n") - f.write(" dma_rcv_empty => dma_rcv_empty,\n") - f.write(" dma_snd_wrreq => dma_snd_wrreq,\n") - f.write(" dma_snd_data_in => dma_snd_data_in,\n") - f.write(" dma_snd_full => dma_snd_full,\n") - f.write(" interrupt_wrreq => interrupt_wrreq,\n") - f.write(" interrupt_data_in => interrupt_data_in,\n") - f.write(" interrupt_full => interrupt_full,\n") - f.write(" interrupt_ack_rdreq => interrupt_ack_rdreq,\n") - f.write(" interrupt_ack_data_out => interrupt_ack_data_out,\n") - f.write(" interrupt_ack_empty => interrupt_ack_empty,\n") - f.write(" mon_dvfs_in => mon_dvfs_in,\n") - f.write(" -- Monitor signals\n") - f.write(" mon_acc => mon_acc_int,\n") - f.write(" mon_cache => mon_cache_int,\n") - f.write(" mon_dvfs => mon_dvfs_int,\n") - f.write(" -- Coherence\n") - f.write(" coherence => coherence\n") - f.write(" );\n") - f.write(" end generate " + acc.name + "_gen;\n\n") - else: - f.write(tline) + f = open(out_dir + "/tile_acc.vhd", 'w') + with open(template_dir + '/tile_acc.vhd', 'r') as ftemplate: + for tline in ftemplate: + if tline.find("-- <>") >= 0: + for acc in accelerator_list + axi_accelerator_list: + f.write( + " " + + acc.name + + "_gen: if this_device = SLD_" + + acc.name.upper() + + " generate\n") + f.write( + " noc_" + + acc.name + + "_i: noc_" + + acc.name + + "\n") + f.write(" generic map (\n") + f.write(" hls_conf => this_hls_conf,\n") + f.write(" tech => CFG_FABTECH,\n") + f.write( + " mem_num => CFG_NMEM_TILE + CFG_NSLM_TILE + CFG_NSLMDDR_TILE + CFG_SVGA_ENABLE,\n") + f.write(" cacheable_mem_num => CFG_NMEM_TILE,\n") + f.write(" mem_info => tile_acc_mem_list,\n") + f.write(" io_y => io_y,\n") + f.write(" io_x => io_x,\n") + f.write(" pindex => 1,\n") + f.write(" irq_type => this_irq_type,\n") + f.write(" scatter_gather => this_scatter_gather,\n") + f.write(" sets => CFG_ACC_L2_SETS,\n") + f.write(" ways => CFG_ACC_L2_WAYS,\n") + f.write(" little_end => little_end,\n") + f.write(" cache_tile_id => cache_tile_id,\n") + f.write(" cache_y => cache_y,\n") + f.write(" cache_x => cache_x,\n") + f.write(" has_l2 => this_has_l2,\n") + f.write(" has_dvfs => this_has_dvfs,\n") + f.write(" has_pll => this_has_pll,\n") + f.write(" extra_clk_buf => this_extra_clk_buf)\n") + f.write(" port map (\n") + f.write(" rst => rst,\n") + f.write(" clk => clk_feedthru,\n") + f.write(" refclk => dvfs_clk,\n") + f.write(" pllbypass => pllbypass,\n") + f.write(" pllclk => clk_feedthru,\n") + f.write(" local_y => this_local_y,\n") + f.write(" local_x => this_local_x,\n") + f.write(" tile_id => tile_id,\n") + f.write(" paddr => this_paddr,\n") + f.write(" pmask => this_pmask,\n") + f.write(" paddr_ext => this_paddr_ext,\n") + f.write(" pmask_ext => this_pmask_ext,\n") + f.write(" pirq => this_pirq,\n") + f.write(" apbi => apbi,\n") + f.write(" apbo => apbo(1),\n") + f.write(" pready => pready,\n") + f.write( + " coherence_req_wrreq => coherence_req_wrreq,\n") + f.write( + " coherence_req_data_in => coherence_req_data_in,\n") + f.write( + " coherence_req_full => coherence_req_full,\n") + f.write( + " coherent_dma_rcv_rdreq => coherent_dma_rcv_rdreq,\n") + f.write( + " coherent_dma_rcv_data_out => coherent_dma_rcv_data_out,\n") + f.write( + " coherent_dma_rcv_empty => coherent_dma_rcv_empty,\n") + f.write( + " coherence_fwd_rdreq => coherence_fwd_rdreq,\n") + f.write( + " coherence_fwd_data_out => coherence_fwd_data_out,\n") + f.write( + " coherence_fwd_empty => coherence_fwd_empty,\n") + f.write( + " coherent_dma_snd_wrreq => coherent_dma_snd_wrreq,\n") + f.write( + " coherent_dma_snd_data_in => coherent_dma_snd_data_in,\n") + f.write( + " coherent_dma_snd_full => coherent_dma_snd_full,\n") + f.write( + " coherence_rsp_rcv_rdreq => coherence_rsp_rcv_rdreq,\n") + f.write( + " coherence_rsp_rcv_data_out => coherence_rsp_rcv_data_out,\n") + f.write( + " coherence_rsp_rcv_empty => coherence_rsp_rcv_empty,\n") + f.write( + " coherence_rsp_snd_wrreq => coherence_rsp_snd_wrreq,\n") + f.write( + " coherence_rsp_snd_data_in => coherence_rsp_snd_data_in,\n") + f.write( + " coherence_rsp_snd_full => coherence_rsp_snd_full,\n") + f.write( + " coherence_fwd_snd_wrreq => coherence_fwd_snd_wrreq,\n") + f.write( + " coherence_fwd_snd_data_in => coherence_fwd_snd_data_in,\n") + f.write( + " coherence_fwd_snd_full => coherence_fwd_snd_full,\n") + f.write(" dma_rcv_rdreq => dma_rcv_rdreq,\n") + f.write(" dma_rcv_data_out => dma_rcv_data_out,\n") + f.write(" dma_rcv_empty => dma_rcv_empty,\n") + f.write(" dma_snd_wrreq => dma_snd_wrreq,\n") + f.write(" dma_snd_data_in => dma_snd_data_in,\n") + f.write(" dma_snd_full => dma_snd_full,\n") + f.write(" interrupt_wrreq => interrupt_wrreq,\n") + f.write(" interrupt_data_in => interrupt_data_in,\n") + f.write(" interrupt_full => interrupt_full,\n") + f.write( + " interrupt_ack_rdreq => interrupt_ack_rdreq,\n") + f.write( + " interrupt_ack_data_out => interrupt_ack_data_out,\n") + f.write( + " interrupt_ack_empty => interrupt_ack_empty,\n") + f.write(" mon_dvfs_in => mon_dvfs_in,\n") + f.write(" -- Monitor signals\n") + f.write(" mon_acc => mon_acc_int,\n") + f.write(" mon_cache => mon_cache_int,\n") + f.write(" mon_dvfs => mon_dvfs_int,\n") + f.write(" -- Coherence\n") + f.write(" coherence => coherence\n") + f.write(" );\n") + f.write(" end generate " + acc.name + "_gen;\n\n") + else: + f.write(tline) # ### Main script ### # + if len(sys.argv) != 9: print_usage() sys.exit(1) @@ -1906,12 +2718,12 @@ def gen_tile_acc(accelerator_list, axi_acceleratorlist, template_dir, out_dir): template_dir = sys.argv[7] out_dir = sys.argv[8] if cpu_arch == "leon3": - little_endian = 0 + little_endian = 0 else: - little_endian = 1 -accelerator_list = [ ] -axi_accelerator_list = [ ] -cache_list = [ ] + little_endian = 1 +accelerator_list = [] +axi_accelerator_list = [] +cache_list = [] # Get scheduled accelerators accelerators = next(os.walk(acc_rtl_dir))[1] @@ -1919,7 +2731,7 @@ def gen_tile_acc(accelerator_list, axi_acceleratorlist, template_dir, out_dir): accelerators.sort() axi_accelerators.sort() -caches = [ ] +caches = [] tmp_l2_dir = caches_rtl_dir + '/l2' tmp_l2_spandex_dir = caches_rtl_dir + '/l2_spandex' @@ -1932,213 +2744,251 @@ def gen_tile_acc(accelerator_list, axi_acceleratorlist, template_dir, out_dir): if (len(accelerators) == 0): - print(" INFO: No accelerators found in " + acc_rtl_dir + ".") - print(" Please run 'make accelerators' or make -hls.") - print(" Get available accelerators with 'make print-available-accelerators'") + print(" INFO: No accelerators found in " + acc_rtl_dir + ".") + print(" Please run 'make accelerators' or make -hls.") + print(" Get available accelerators with 'make print-available-accelerators'") if (not os.path.exists(tmp_l2_dir) or not os.path.exists(tmp_llc_dir)): - print(" WARNING: No caches found in " + caches_rtl_dir + ".") - print(" Please check the \"Use RTL\" option in the \"Cache Configuration\" tab when configuring ESP.") + print(" WARNING: No caches found in " + caches_rtl_dir + ".") + print(" Please check the \"Use RTL\" option in the \"Cache Configuration\" tab when configuring ESP.") for acc in axi_accelerators: - f = open(axi_acc_dir + "/" + acc + "/" + acc + ".dma_widths") - buf = f.read() - if not str(noc_width) in buf: - print(" INFO: System DMA_WIDTH is " + str(noc_width) + "; skipping " + acc) - continue - - accd = AxiAccelerator() - accd.name = acc - - elem = xml.etree.ElementTree.parse(axi_acc_dir + "/" + acc + "/" + acc + ".xml") - e = elem.getroot() - for xmlacc in e.findall('accelerator'): - acc_name = xmlacc.get('name') - if acc_name != acc: - continue - - print(" INFO: Retrieving information for " + acc) - if "desc" in xmlacc.attrib: - accd.desc = xmlacc.get('desc') - else: - print(" ERROR: Missing description for " + acc) - sys.exit(1) - if "device_id" in xmlacc.attrib: - accd.device_id = xmlacc.get('device_id') - else: - print(" ERROR: Missing device ID for " + acc) - sys.exit(1) + f = open(axi_acc_dir + "/" + acc + "/" + acc + ".dma_widths") + buf = f.read() + if not str(noc_width) in buf: + print(" INFO: System DMA_WIDTH is " + + str(noc_width) + "; skipping " + acc) + continue + + accd = AxiAccelerator() + accd.name = acc + + elem = xml.etree.ElementTree.parse( + axi_acc_dir + "/" + acc + "/" + acc + ".xml") + e = elem.getroot() + for xmlacc in e.findall('accelerator'): + acc_name = xmlacc.get('name') + if acc_name != acc: + continue + + print(" INFO: Retrieving information for " + acc) + if "desc" in xmlacc.attrib: + accd.desc = xmlacc.get('desc') + else: + print(" ERROR: Missing description for " + acc) + sys.exit(1) + if "device_id" in xmlacc.attrib: + accd.device_id = xmlacc.get('device_id') + else: + print(" ERROR: Missing device ID for " + acc) + sys.exit(1) - if "interrupt" in xmlacc.attrib: - accd.interrupt = xmlacc.get('interrupt') + if "interrupt" in xmlacc.attrib: + accd.interrupt = xmlacc.get('interrupt') - if "axi_prefix" in xmlacc.attrib: - accd.axi_prefix = xmlacc.get('axi_prefix') + if "axi_prefix" in xmlacc.attrib: + accd.axi_prefix = xmlacc.get('axi_prefix') - if "apb_prefix" in xmlacc.attrib: - accd.apb_prefix = xmlacc.get('apb_prefix') + if "apb_prefix" in xmlacc.attrib: + accd.apb_prefix = xmlacc.get('apb_prefix') - if "addr_width" in xmlacc.attrib: - accd.addr_width = xmlacc.get('addr_width') + if "addr_width" in xmlacc.attrib: + accd.addr_width = xmlacc.get('addr_width') - if "id_width" in xmlacc.attrib: - accd.id_width = xmlacc.get('id_width') + if "id_width" in xmlacc.attrib: + accd.id_width = xmlacc.get('id_width') - if "user_width" in xmlacc.attrib: - accd.user_width = xmlacc.get('user_width') + if "user_width" in xmlacc.attrib: + accd.user_width = xmlacc.get('user_width') - for xmlparam in xmlacc.findall('clock'): - accd.clocks.append(xmlparam.get('name')) - for xmlparam in xmlacc.findall('reset'): - #TODO: get polarity from XML (assuming active low for now) - accd.resets.append(xmlparam.get('name')) + for xmlparam in xmlacc.findall('clock'): + accd.clocks.append(xmlparam.get('name')) + for xmlparam in xmlacc.findall('reset'): + # TODO: get polarity from XML (assuming active low for now) + accd.resets.append(xmlparam.get('name')) - axi_accelerator_list.append(accd) - print(str(accd)) - break + axi_accelerator_list.append(accd) + print(str(accd)) + break for acc in accelerators: - accd = Accelerator() - accd.name = acc - - # Get scheduled HLS configurations - acc_dir = acc_rtl_dir + "/" + acc - acc_dp = get_immediate_subdirectories(acc_dir) - for dp_str in acc_dp: - dp = dp_str.replace(acc + "_", "") - dp_info = dp.split("_") - skip = False - datatype = "" - for item in dp_info: - if re.match(r'dma[1-9]+', item, re.M|re.I): - dp_noc_width = int(item.replace("dma", "")) - if dp_noc_width != noc_width: - skip = True - break; - if re.fullmatch(r'fl32in', item): - datatype = "float_in" - elif re.fullmatch(r'fl32out', item): - datatype = "float_out" - elif re.fullmatch(r'fl32', item): - datatype = "float" - - if skip: - print(" INFO: System DMA_WIDTH is " + str(noc_width) + "; skipping " + acc + "_" + dp) - continue - print(" INFO: Found implementation " + dp + " for " + acc) - impl = Implementation() - impl.name = dp - impl.noc_width = noc_width - impl.datatype = datatype - accd.hlscfg.append(impl) - - # Read accelerator parameters and info - if len(accd.hlscfg) == 0: - print(" WARNING: No valid HLS configuration found for " + acc) - continue - - elem = xml.etree.ElementTree.parse(acc_dir + "/" + acc + ".xml") - e = elem.getroot() - for xmlacc in e.findall('accelerator'): - acc_name = xmlacc.get('name') - - print(" INFO: Retrieving information for " + acc) - if "desc" in xmlacc.attrib: - accd.desc = xmlacc.get('desc') - else: - print(" ERROR: Missing description for " + acc) - sys.exit(1) - if "data_size" in xmlacc.attrib: - accd.data = int(xmlacc.get('data_size')) - else: - print(" ERROR: Missing memory footprint (MB) for " + acc) - sys.exit(1) - if accd.data == 0: - print(" WARNING: memory footprint (MB) for " + acc + " is 0; defaulting to 4") - accd.data = 4 - if "device_id" in xmlacc.attrib: - accd.device_id = xmlacc.get('device_id') - else: - print(" ERROR: Missing device ID for " + acc) - sys.exit(1) - - if "hls_tool" in xmlacc.attrib: - accd.hls_tool = xmlacc.get('hls_tool') - # hls4ml accelerators are implemented as Vivado HLS accelerators - if accd.hls_tool in ('hls4ml'): - accd.hls_tool = 'vivado_hls' - if not accd.hls_tool in ('stratus_hls', 'vivado_hls', 'catapult_hls_cxx', 'catapult_hls_sysc', 'rtl'): - print(" ERROR: Wrong HLS tool for " + acc) - print(" " + accd.hls_tool) - sys.exit(1) + accd = Accelerator() + accd.name = acc + + # Get scheduled HLS configurations + acc_dir = acc_rtl_dir + "/" + acc + acc_dp = get_immediate_subdirectories(acc_dir) + for dp_str in acc_dp: + dp = dp_str.replace(acc + "_", "") + dp_info = dp.split("_") + skip = False + datatype = "" + for item in dp_info: + if re.match(r'dma[1-9]+', item, re.M | re.I): + dp_noc_width = int(item.replace("dma", "")) + if dp_noc_width != noc_width: + skip = True + break + if re.fullmatch(r'fl32in', item): + datatype = "float_in" + elif re.fullmatch(r'fl32out', item): + datatype = "float_out" + elif re.fullmatch(r'fl32', item): + datatype = "float" + + if skip: + print( + " INFO: System DMA_WIDTH is " + + str(noc_width) + + "; skipping " + + acc + + "_" + + dp) + continue + print(" INFO: Found implementation " + dp + " for " + acc) + impl = Implementation() + impl.name = dp + impl.noc_width = noc_width + impl.datatype = datatype + accd.hlscfg.append(impl) + + # Read accelerator parameters and info + if len(accd.hlscfg) == 0: + print(" WARNING: No valid HLS configuration found for " + acc) + continue - else: - # Default to stratus_hls for Chisel, because the interface matches the Stratus HLS flow - accd.hls_tool = 'stratus_hls' - - reg = 16 - for xmlparam in xmlacc.findall('param'): - param = Parameter() - param.name = xmlparam.get('name') - param.reg = reg - reg += 1 - if "desc" in xmlparam.attrib: - param.desc = xmlparam.get('desc') - if "value" in xmlparam.attrib: - param.value = int(xmlparam.get('value')) - param.readonly = True - if "size" in xmlparam.attrib: - param.size = int(xmlparam.get('size')) - else: - param.size = 32 - if param.size > 32: - print(" ERROR: configuration parameter " + param.name + " of " + acc + " has bit-width larger than 32") - sys.exit(1) - accd.param.append(param) - accelerator_list.append(accd) - print(str(accd)) - break + elem = xml.etree.ElementTree.parse(acc_dir + "/" + acc + ".xml") + e = elem.getroot() + for xmlacc in e.findall('accelerator'): + acc_name = xmlacc.get('name') + + print(" INFO: Retrieving information for " + acc) + if "desc" in xmlacc.attrib: + accd.desc = xmlacc.get('desc') + else: + print(" ERROR: Missing description for " + acc) + sys.exit(1) + if "data_size" in xmlacc.attrib: + accd.data = int(xmlacc.get('data_size')) + else: + print(" ERROR: Missing memory footprint (MB) for " + acc) + sys.exit(1) + if accd.data == 0: + print( + " WARNING: memory footprint (MB) for " + + acc + + " is 0; defaulting to 4") + accd.data = 4 + if "device_id" in xmlacc.attrib: + accd.device_id = xmlacc.get('device_id') + else: + print(" ERROR: Missing device ID for " + acc) + sys.exit(1) + + if "hls_tool" in xmlacc.attrib: + accd.hls_tool = xmlacc.get('hls_tool') + # hls4ml accelerators are implemented as Vivado HLS accelerators + if accd.hls_tool in ('hls4ml'): + accd.hls_tool = 'vivado_hls' + if accd.hls_tool not in ( + 'stratus_hls', + 'vivado_hls', + 'catapult_hls_cxx', + 'catapult_hls_sysc', + 'rtl'): + print(" ERROR: Wrong HLS tool for " + acc) + print(" " + accd.hls_tool) + sys.exit(1) + + else: + # Default to stratus_hls for Chisel, because the interface matches + # the Stratus HLS flow + accd.hls_tool = 'stratus_hls' + + reg = 16 + for xmlparam in xmlacc.findall('param'): + param = Parameter() + param.name = xmlparam.get('name') + param.reg = reg + reg += 1 + if "desc" in xmlparam.attrib: + param.desc = xmlparam.get('desc') + if "value" in xmlparam.attrib: + param.value = int(xmlparam.get('value')) + param.readonly = True + if "size" in xmlparam.attrib: + param.size = int(xmlparam.get('size')) + else: + param.size = 32 + if param.size > 32: + print( + " ERROR: configuration parameter " + + param.name + + " of " + + acc + + " has bit-width larger than 32") + sys.exit(1) + accd.param.append(param) + accelerator_list.append(accd) + print(str(accd)) + break # Compute relevan bitwidths for cache interfaces # based on DMA_WIDTH and a fixed 128-bits cache line bits_per_line = cache_line_size -words_per_line = int(bits_per_line/arch_bits) -dma_words_per_line = int(bits_per_line/32) +words_per_line = int(bits_per_line / arch_bits) +dma_words_per_line = int(bits_per_line / 32) word_offset_bits = int(math.log2(words_per_line)) dma_word_offset_bits = int(math.log2(dma_words_per_line)) -byte_offset_bits = int(math.log2(arch_bits/8)) +byte_offset_bits = int(math.log2(arch_bits / 8)) offset_bits = word_offset_bits + byte_offset_bits nl2_max_log2 = 4 if dma_word_offset_bits + 1 < nl2_max_log2: - invack_cnt_bits = nl2_max_log2 + invack_cnt_bits = nl2_max_log2 else: - invack_cnt_bits = dma_word_offset_bits + 1 + invack_cnt_bits = dma_word_offset_bits + 1 for cac in caches: - cacd = Component() - cacd.name = cac + cacd = Component() + cacd.name = cac - # Get scheduled HLS configurations - cac_dir = caches_rtl_dir + "/" + cac - if os.path.exists(cac_dir): - cac_dp = get_immediate_subdirectories(cac_dir) - for dp_str in cac_dp: - dp = dp_str.replace(cac + "_", "") - cacd.hlscfg.append(dp) - print(" INFO: Found implementation " + dp + " for " + cac) - cache_list.append(cacd) + # Get scheduled HLS configurations + cac_dir = caches_rtl_dir + "/" + cac + if os.path.exists(cac_dir): + cac_dp = get_immediate_subdirectories(cac_dir) + for dp_str in cac_dp: + dp = dp_str.replace(cac + "_", "") + cacd.hlscfg.append(dp) + print(" INFO: Found implementation " + dp + " for " + cac) + cache_list.append(cacd) # Generate RTL print(" INFO: Generating RTL to " + out_dir) gen_device_id(accelerator_list, axi_accelerator_list, template_dir, out_dir) gen_tech_dep(accelerator_list, cache_list, noc_width, template_dir, out_dir) -gen_tech_indep(accelerator_list, axi_accelerator_list, cache_list, noc_width, template_dir, out_dir) -gen_tech_indep_impl(accelerator_list, cache_list, noc_width, template_dir, out_dir) -gen_interfaces(accelerator_list, axi_accelerator_list, noc_width, template_dir, out_dir) +gen_tech_indep( + accelerator_list, + axi_accelerator_list, + cache_list, + noc_width, + template_dir, + out_dir) +gen_tech_indep_impl( + accelerator_list, + cache_list, + noc_width, + template_dir, + out_dir) +gen_interfaces( + accelerator_list, + axi_accelerator_list, + noc_width, + template_dir, + out_dir) for acc in accelerator_list: - gen_noc_interface(acc, noc_width, template_dir, out_dir, False) + gen_noc_interface(acc, noc_width, template_dir, out_dir, False) for acc in axi_accelerator_list: - gen_noc_interface(acc, noc_width, template_dir, out_dir, True) + gen_noc_interface(acc, noc_width, template_dir, out_dir, True) gen_tile_acc(accelerator_list, axi_accelerator_list, template_dir, out_dir) diff --git a/tools/socketgen/templates/accelerators.vhd b/tools/socketgen/templates/accelerators.vhd index 90dfea6c99..f6107065c2 100644 --- a/tools/socketgen/templates/accelerators.vhd +++ b/tools/socketgen/templates/accelerators.vhd @@ -1,5 +1,4 @@ -- Copyright (c) 2011-2024 Columbia University, System Level Design Group -- SPDX-License-Identifier: Apache-2.0 - -- <> diff --git a/utils/grlib_tkconfig/config.vhd b/utils/grlib_tkconfig/config.vhd index 80f2111193..7769f10526 100644 --- a/utils/grlib_tkconfig/config.vhd +++ b/utils/grlib_tkconfig/config.vhd @@ -1,18 +1,14 @@ #include "grlib_config.h" #include "tkconfig.h" ------------------------------------------------------------------------------ --- LEON3 Demonstration design test bench configuration --- Copyright (C) 2009 Aeroflex Gaisler ------------------------------------------------------------------------------- - - -use work.gencomp.all; + ----------------------------------------------------------------------------- + -- LEON3 Demonstration design test bench configuration + -- Copyright (C) 2009 Aeroflex Gaisler + ------------------------------------------------------------------------------ + use work.gencomp.all; package grlib_config is #include "grlib_config.vhd.h" - - -end; +end package grlib_config; diff --git a/utils/grlib_tkconfig/in/gptimer.in.h b/utils/grlib_tkconfig/in/gptimer.in.h index 51830c29db..646573af1f 100644 --- a/utils/grlib_tkconfig/in/gptimer.in.h +++ b/utils/grlib_tkconfig/in/gptimer.in.h @@ -52,4 +52,3 @@ #ifndef CONFIG_GPT_WDOG #define CONFIG_GPT_WDOG 0 #endif - diff --git a/utils/grlib_tkconfig/mkdevice.c b/utils/grlib_tkconfig/mkdevice.c index 73e7e8434b..7fe4761a5f 100644 --- a/utils/grlib_tkconfig/mkdevice.c +++ b/utils/grlib_tkconfig/mkdevice.c @@ -3,56 +3,55 @@ Copyright Cobham Gaisler, all rights reserved. */ -#include #include +#include #include - -#define VAL(x) strtoul(x,(char **)NULL,0) +#define VAL(x) strtoul(x, (char **)NULL, 0) FILE *fp; char false[] = "false"; -char true[] = "true"; +char true[] = "true"; /* Synthesis options */ -char CONFIG_CFG_NAME[16] = "config"; -char CFG_SYN_TARGET_TECH[128] = "gen"; -char *CONFIG_SYN_INFER_PADS = false; +char CONFIG_CFG_NAME[16] = "config"; +char CFG_SYN_TARGET_TECH[128] = "gen"; +char *CONFIG_SYN_INFER_PADS = false; char *CONFIG_SYN_INFER_PCI_PADS = false; -char *CONFIG_SYN_INFER_RAM = false; -char *CONFIG_SYN_INFER_ROM = false; -char *CONFIG_SYN_INFER_REGF = false; -char *CONFIG_SYN_INFER_MULT = false; -int CONFIG_SYN_RFTYPE = 1; -char CONFIG_TARGET_CLK[128] = "gen"; -int CONFIG_PLL_CLK_MUL = 1; -int CONFIG_PLL_CLK_DIV = 1; -char *CONFIG_PCI_CLKDLL = false; -char *CONFIG_PCI_SYSCLK = false; +char *CONFIG_SYN_INFER_RAM = false; +char *CONFIG_SYN_INFER_ROM = false; +char *CONFIG_SYN_INFER_REGF = false; +char *CONFIG_SYN_INFER_MULT = false; +int CONFIG_SYN_RFTYPE = 1; +char CONFIG_TARGET_CLK[128] = "gen"; +int CONFIG_PLL_CLK_MUL = 1; +int CONFIG_PLL_CLK_DIV = 1; +char *CONFIG_PCI_CLKDLL = false; +char *CONFIG_PCI_SYSCLK = false; /* IU options */ -int CONFIG_IU_NWINDOWS = 8; -char CFG_IU_MUL_TYPE[16] = "none"; -char CFG_IU_DIVIDER[16] = "none"; -char *CONFIG_IU_MUL_MAC = false; -char *CONFIG_IU_MULPIPE = false; -char *CONFIG_IU_FASTJUMP = false; -char *CONFIG_IU_ICCHOLD = false; +int CONFIG_IU_NWINDOWS = 8; +char CFG_IU_MUL_TYPE[16] = "none"; +char CFG_IU_DIVIDER[16] = "none"; +char *CONFIG_IU_MUL_MAC = false; +char *CONFIG_IU_MULPIPE = false; +char *CONFIG_IU_FASTJUMP = false; +char *CONFIG_IU_ICCHOLD = false; char *CONFIG_IU_FASTDECODE = false; -char *CONFIG_IU_RFPOW = false; -int CONFIG_IU_LDELAY = 1; -int CONFIG_IU_WATCHPOINTS = 0; +char *CONFIG_IU_RFPOW = false; +int CONFIG_IU_LDELAY = 1; +int CONFIG_IU_WATCHPOINTS = 0; /* FPU config */ int CONFIG_FPU_ENABLE = 0; -char *CFG_FPU_CORE = "meiko"; -char *CFG_FPU_IF = "none"; -int CONFIG_FPU_REGS = 32; -int CONFIG_FPU_VER = 0; +char *CFG_FPU_CORE = "meiko"; +char *CFG_FPU_IF = "none"; +int CONFIG_FPU_REGS = 32; +int CONFIG_FPU_VER = 0; /* CP config */ @@ -60,120 +59,119 @@ char CONFIG_CP_CFG[128] = "cp_none"; /* cache configuration */ -int CFG_ICACHE_SZ = 2; -int CFG_ICACHE_LSZ = 16; -int CFG_ICACHE_ASSO = 1; -char *CFG_ICACHE_ALGO = "rnd"; -int CFG_ICACHE_LOCK = 0; -int CFG_DCACHE_SZ = 1; -int CFG_DCACHE_LSZ = 16; +int CFG_ICACHE_SZ = 2; +int CFG_ICACHE_LSZ = 16; +int CFG_ICACHE_ASSO = 1; +char *CFG_ICACHE_ALGO = "rnd"; +int CFG_ICACHE_LOCK = 0; +int CFG_DCACHE_SZ = 1; +int CFG_DCACHE_LSZ = 16; char *CFG_DCACHE_SNOOP = "none"; -int CFG_DCACHE_ASSO = 1; -char *CFG_DCACHE_ALGO = "rnd"; -int CFG_DCACHE_LOCK = 0; +int CFG_DCACHE_ASSO = 1; +char *CFG_DCACHE_ALGO = "rnd"; +int CFG_DCACHE_LOCK = 0; char *CFG_DCACHE_RFAST = false; char *CFG_DCACHE_WFAST = false; char *CFG_DCACHE_LRAM = false; -int CFG_DCACHE_LRSZ = 1; +int CFG_DCACHE_LRSZ = 1; int CFG_DCACHE_LRSTART = 0x8f; /* MMU config */ int CFG_MMU_ENABLE = 0; char *CFG_MMU_TYPE = "combinedtlb"; -char *CFG_MMU_REP = "replruarray"; -int CFG_MMU_I = 8; -int CFG_MMU_D = 8; +char *CFG_MMU_REP = "replruarray"; +int CFG_MMU_I = 8; +int CFG_MMU_D = 8; char *CFG_MMU_DIAG = false; /* Memory controller config */ -char *CONFIG_MCTRL_8BIT = false; -char *CONFIG_MCTRL_16BIT = false; -char *CONFIG_MCTRL_5CS = false; -char *CONFIG_MCTRL_WFB = false; -char *CONFIG_MCTRL_SDRAM = false; +char *CONFIG_MCTRL_8BIT = false; +char *CONFIG_MCTRL_16BIT = false; +char *CONFIG_MCTRL_5CS = false; +char *CONFIG_MCTRL_WFB = false; +char *CONFIG_MCTRL_SDRAM = false; char *CONFIG_MCTRL_SDRAM_INVCLK = false; char *CONFIG_MCTRL_SDRAM_SEPBUS = false; /* Peripherals */ -char *CONFIG_PERI_LCONF = false; +char *CONFIG_PERI_LCONF = false; char *CONFIG_PERI_AHBSTAT = false; -char *CONFIG_PERI_WPROT = false; -char *CONFIG_PERI_WDOG = false; -char *CONFIG_PERI_IRQ2 = false; +char *CONFIG_PERI_WPROT = false; +char *CONFIG_PERI_WDOG = false; +char *CONFIG_PERI_IRQ2 = false; /* AHB */ -int CONFIG_AHB_DEFMST = 0; -char *CONFIG_AHB_SPLIT = false; +int CONFIG_AHB_DEFMST = 0; +char *CONFIG_AHB_SPLIT = false; char *CONFIG_AHBRAM_ENABLE = false; -int CFG_AHBRAM_SZ = 4; +int CFG_AHBRAM_SZ = 4; /* Debug */ -char *CONFIG_DEBUG_UART = false; -char *CONFIG_DEBUG_IURF = false; -char *CONFIG_DEBUG_FPURF = false; -char *CONFIG_DEBUG_NOHALT = false; -int CFG_DEBUG_PCLOW = 2; -char *CONFIG_DEBUG_RFERR = false; +char *CONFIG_DEBUG_UART = false; +char *CONFIG_DEBUG_IURF = false; +char *CONFIG_DEBUG_FPURF = false; +char *CONFIG_DEBUG_NOHALT = false; +int CFG_DEBUG_PCLOW = 2; +char *CONFIG_DEBUG_RFERR = false; char *CONFIG_DEBUG_CACHEMEMERR = false; /* DSU */ -char *CONFIG_DSU_ENABLE = false; -char *CONFIG_DSU_TRACEBUF = false; +char *CONFIG_DSU_ENABLE = false; +char *CONFIG_DSU_TRACEBUF = false; char *CONFIG_DSU_MIXED_TRACE = false; char *CONFIG_SYN_TRACE_DPRAM = false; -int CFG_DSU_TRACE_SZ = 64; +int CFG_DSU_TRACE_SZ = 64; /* Boot */ -char *CFG_BOOT_SOURCE = "memory"; -int CONFIG_BOOT_RWS = 0; -int CONFIG_BOOT_WWS = 0; -int CONFIG_BOOT_SYSCLK = 25000000; -int CONFIG_BOOT_BAUDRATE = 19200; +char *CFG_BOOT_SOURCE = "memory"; +int CONFIG_BOOT_RWS = 0; +int CONFIG_BOOT_WWS = 0; +int CONFIG_BOOT_SYSCLK = 25000000; +int CONFIG_BOOT_BAUDRATE = 19200; char *CONFIG_BOOT_EXTBAUD = false; int CONFIG_BOOT_PROMABITS = 11; /* Ethernet */ char *CONFIG_ETH_ENABLE = false; -int CONFIG_ETH_TXFIFO = 8; -int CONFIG_ETH_RXFIFO = 8; -int CONFIG_ETH_BURST = 4; +int CONFIG_ETH_TXFIFO = 8; +int CONFIG_ETH_RXFIFO = 8; +int CONFIG_ETH_BURST = 4; /* PCI */ -char *CFG_PCI_CORE = "none"; -char *CONFIG_PCI_ENABLE = false; -int CONFIG_PCI_VENDORID = 0; -int CONFIG_PCI_DEVICEID = 0; -int CONFIG_PCI_SUBSYSID = 0; -int CONFIG_PCI_REVID = 0; -int CONFIG_PCI_CLASSCODE = 0; -int CFG_PCI_FIFO = 8; -int CFG_PCI_TDEPTH = 256; -char *CONFIG_PCI_TRACE = false; -char *CONFIG_PCI_PMEPADS = false; -char *CONFIG_PCI_P66PAD = false; +char *CFG_PCI_CORE = "none"; +char *CONFIG_PCI_ENABLE = false; +int CONFIG_PCI_VENDORID = 0; +int CONFIG_PCI_DEVICEID = 0; +int CONFIG_PCI_SUBSYSID = 0; +int CONFIG_PCI_REVID = 0; +int CONFIG_PCI_CLASSCODE = 0; +int CFG_PCI_FIFO = 8; +int CFG_PCI_TDEPTH = 256; +char *CONFIG_PCI_TRACE = false; +char *CONFIG_PCI_PMEPADS = false; +char *CONFIG_PCI_P66PAD = false; char *CONFIG_PCI_RESETALL = false; -char *CONFIG_PCI_ARBEN = false; -int pciahbmst = 0; +char *CONFIG_PCI_ARBEN = false; +int pciahbmst = 0; /* FT */ -int CONFIG_FT_ENABLE = 0; -char *CONFIG_FT_RF_ENABLE = false; -char *CONFIG_FT_RF_PARITY = false; -char *CONFIG_FT_RF_EDAC = false; -int CONFIG_FT_RF_PARBITS = 0; -char *CONFIG_FT_RF_WRFAST = false; -char *CONFIG_FT_TMR_REG = false; -char *CONFIG_FT_TMR_CLK = false; -char *CONFIG_FT_MC = false; -char *CONFIG_FT_MEMEDAC = false; +int CONFIG_FT_ENABLE = 0; +char *CONFIG_FT_RF_ENABLE = false; +char *CONFIG_FT_RF_PARITY = false; +char *CONFIG_FT_RF_EDAC = false; +int CONFIG_FT_RF_PARBITS = 0; +char *CONFIG_FT_RF_WRFAST = false; +char *CONFIG_FT_TMR_REG = false; +char *CONFIG_FT_TMR_CLK = false; +char *CONFIG_FT_MC = false; +char *CONFIG_FT_MEMEDAC = false; char *CONFIG_FT_CACHEMEM_ENABLE = false; -int CONFIG_FT_CACHEMEM_PARBITS = 0; -char *CONFIG_FT_CACHEMEM_APAR = false; - +int CONFIG_FT_CACHEMEM_PARBITS = 0; +char *CONFIG_FT_CACHEMEM_APAR = false; int dsuen, pcien, ahbram, ethen; char tmps[32]; @@ -184,8 +182,9 @@ int log2(int x) int i; x--; - for (i=0; x!=0; i++) x >>= 1; - return(i); + for (i = 0; x != 0; i++) + x >>= 1; + return (i); } main() @@ -195,508 +194,554 @@ main() fp = fopen("device.vhd", "w+"); if (!fp) { - printf("could not open file device.vhd\n"); - exit(1); + printf("could not open file device.vhd\n"); + exit(1); } - while (!feof(stdin)) - { - lbuf[0] = 0; - fgets (lbuf, 1023, stdin); - if (strncmp(lbuf, "CONFIG", 6) == 0) { - value = strchr(lbuf,'='); - value[0] = 0; - value++; - while ((strlen (value) > 0) && - ((value[strlen (value) - 1] == '\n') - || (value[strlen (value) - 1] == '\r') - || (value[strlen (value) - 1] == '"') - )) value[strlen (value) - 1] = 0; - if ((strlen (value) > 0) && (value[0] == '"')) { - value++; - } - - /* synthesis options */ - else if (strcmp("CONFIG_SYN_GENERIC", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "gen"); - else if (strcmp("CONFIG_SYN_ATC35", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "atc35"); - else if (strcmp("CONFIG_SYN_ATC25", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "atc25"); - else if (strcmp("CONFIG_SYN_ATC18", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "atc18"); - else if (strcmp("CONFIG_SYN_FS90", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "fs90"); - else if (strcmp("CONFIG_SYN_UMC018", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "umc18"); - else if (strcmp("CONFIG_SYN_TSMC025", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "tsmc25"); - else if (strcmp("CONFIG_SYN_PROASIC", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "proasic"); - else if (strcmp("CONFIG_SYN_AXCEL", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "axcel"); - else if (strcmp("CONFIG_SYN_VIRTEX", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "virtex"); - else if (strcmp("CONFIG_SYN_VIRTEX2", lbuf) == 0) - strcpy(CFG_SYN_TARGET_TECH, "virtex2"); - else if (strcmp("CONFIG_SYN_INFER_PADS", lbuf) == 0) - CONFIG_SYN_INFER_PADS = true; - else if (strcmp("CONFIG_SYN_INFER_PCI_PADS", lbuf) == 0) - CONFIG_SYN_INFER_PCI_PADS = true; - else if (strcmp("CONFIG_SYN_INFER_RAM", lbuf) == 0) - CONFIG_SYN_INFER_RAM = true; - else if (strcmp("CONFIG_SYN_INFER_ROM", lbuf) == 0) - CONFIG_SYN_INFER_ROM = true; - else if (strcmp("CONFIG_SYN_INFER_REGF", lbuf) == 0) - CONFIG_SYN_INFER_REGF = true; - else if (strcmp("CONFIG_SYN_INFER_MULT", lbuf) == 0) - CONFIG_SYN_INFER_MULT = true; - else if (strcmp("CONFIG_SYN_RFTYPE", lbuf) == 0) - CONFIG_SYN_RFTYPE = 2; - else if (strcmp("CONFIG_SYN_TRACE_DPRAM", lbuf) == 0) - CONFIG_SYN_TRACE_DPRAM = true; - else if (strcmp("CONFIG_CLK_VIRTEX", lbuf) == 0) - strcpy(CONFIG_TARGET_CLK, "virtex"); - else if (strcmp("CONFIG_AXCEL_HCLKBUF", lbuf) == 0) - strcpy(CONFIG_TARGET_CLK, "axcel"); - else if (strcmp("CONFIG_CLKDLL_1_2", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 1; CONFIG_PLL_CLK_DIV = 2; - } else if (strcmp("CONFIG_CLKDLL_1_1", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 1; CONFIG_PLL_CLK_DIV = 1; - } else if (strcmp("CONFIG_CLKDLL_2_1", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 2; CONFIG_PLL_CLK_DIV = 1; - } else if (strcmp("CONFIG_CLK_VIRTEX2", lbuf) == 0) - strcpy(CONFIG_TARGET_CLK, "virtex2"); - else if (strcmp("CONFIG_DCM_2_3", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 2; CONFIG_PLL_CLK_DIV = 3; - } else if (strcmp("CONFIG_DCM_3_4", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 3; CONFIG_PLL_CLK_DIV = 4; - } else if (strcmp("CONFIG_DCM_4_5", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 4; CONFIG_PLL_CLK_DIV = 5; - } else if (strcmp("CONFIG_DCM_1_1", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 2; CONFIG_PLL_CLK_DIV = 2; - } else if (strcmp("CONFIG_DCM_5_4", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 5; CONFIG_PLL_CLK_DIV = 4; - } else if (strcmp("CONFIG_DCM_4_3", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 4; CONFIG_PLL_CLK_DIV = 3; - } else if (strcmp("CONFIG_DCM_3_2", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 3; CONFIG_PLL_CLK_DIV = 2; - } else if (strcmp("CONFIG_DCM_5_3", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 5; CONFIG_PLL_CLK_DIV = 3; - } else if (strcmp("CONFIG_DCM_2_1", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 2; CONFIG_PLL_CLK_DIV = 1; - } else if (strcmp("CONFIG_DCM_3_1", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 3; CONFIG_PLL_CLK_DIV = 1; - } else if (strcmp("CONFIG_DCM_4_1", lbuf) == 0) { - CONFIG_PLL_CLK_MUL = 4; CONFIG_PLL_CLK_DIV = 1; - } else if (strcmp("CONFIG_PCI_DLL", lbuf) == 0) - CONFIG_PCI_CLKDLL = true; - else if (strcmp("CONFIG_PCI_SYSCLK", lbuf) == 0) - CONFIG_PCI_SYSCLK = true; - /* IU options */ - else if (strcmp("CONFIG_IU_NWINDOWS", lbuf) == 0) { - CONFIG_IU_NWINDOWS = VAL(value); - if ((CONFIG_IU_NWINDOWS > 32) || (CONFIG_IU_NWINDOWS < 1)) - CONFIG_IU_NWINDOWS = 8; - } else if (strcmp("CONFIG_IU_V8MULDIV", lbuf) == 0) - strcpy(CFG_IU_DIVIDER, "radix2"); - else if (strcmp("CONFIG_IU_MUL_LATENCY_1", lbuf) == 0) - strcpy(CFG_IU_MUL_TYPE, "m32x32"); - else if (strcmp("CONFIG_IU_MUL_LATENCY_2", lbuf) == 0) - strcpy(CFG_IU_MUL_TYPE, "m32x16"); - else if (strcmp("CONFIG_IU_MUL_LATENCY_4", lbuf) == 0) - strcpy(CFG_IU_MUL_TYPE, "m16x16"); - else if (strcmp("CONFIG_IU_MUL_LATENCY_5", lbuf) == 0) { - strcpy(CFG_IU_MUL_TYPE, "m16x16"); - CONFIG_IU_MULPIPE = true; - } - else if (strcmp("CONFIG_IU_MUL_LATENCY_35", lbuf) == 0) - strcpy(CFG_IU_MUL_TYPE, "iterative"); - else if (strcmp("CONFIG_IU_MUL_MAC", lbuf) == 0) { - strcpy(CFG_IU_MUL_TYPE, "m16x16"); - CONFIG_IU_MUL_MAC = true; - } - else if (strcmp("CONFIG_IU_FASTJUMP", lbuf) == 0) - CONFIG_IU_FASTJUMP = true; - else if (strcmp("CONFIG_IU_FASTDECODE", lbuf) == 0) - CONFIG_IU_FASTDECODE = true; - else if (strcmp("CONFIG_IU_RFPOW", lbuf) == 0) - CONFIG_IU_RFPOW = true; - else if (strcmp("CONFIG_IU_ICCHOLD", lbuf) == 0) - CONFIG_IU_ICCHOLD = true; - else if (strcmp("CONFIG_IU_LDELAY", lbuf) == 0) { - CONFIG_IU_LDELAY = VAL(value); - if ((CONFIG_IU_LDELAY > 2) || (CONFIG_IU_LDELAY < 1)) - CONFIG_IU_LDELAY = 2; - } else if (strcmp("CONFIG_IU_WATCHPOINTS", lbuf) == 0) { - CONFIG_IU_WATCHPOINTS = VAL(value); - if ((CONFIG_IU_WATCHPOINTS > 4) || (CONFIG_IU_WATCHPOINTS < 0)) - CONFIG_IU_WATCHPOINTS = 0; - /* FPU config */ - } else if (strcmp("CONFIG_FPU_ENABLE", lbuf) == 0) - CONFIG_FPU_ENABLE = 1; - else if (strcmp("CONFIG_FPU_GRFPU", lbuf) == 0) { - CFG_FPU_CORE = "grfpu"; CFG_FPU_IF = "parallel"; - CONFIG_FPU_REGS = 0; - } else if (strcmp("CONFIG_FPU_MEIKO", lbuf) == 0) { - CFG_FPU_CORE = "meiko"; CFG_FPU_IF = "serial"; - } else if (strcmp("CONFIG_FPU_LTH", lbuf) == 0) { - CFG_FPU_CORE = "lth"; CFG_FPU_IF = "serial"; - } else if (strcmp("CONFIG_FPU_VER", lbuf) == 0) - CONFIG_FPU_VER = VAL(value) & 0x07; - /* CP config */ - else if (strcmp("CONFIG_CP_ENABLE", lbuf) == 0) {} - else if (strcmp("CONFIG_CP_CFG", lbuf) == 0) - strcpy(CONFIG_CP_CFG, value); - /* cache config */ - else if (strcmp("CONFIG_ICACHE_ASSO1", lbuf) == 0) - CFG_ICACHE_ASSO = 1; - else if (strcmp("CONFIG_ICACHE_ASSO2", lbuf) == 0) - CFG_ICACHE_ASSO = 2; - else if (strcmp("CONFIG_ICACHE_ASSO3", lbuf) == 0) - CFG_ICACHE_ASSO = 3; - else if (strcmp("CONFIG_ICACHE_ASSO4", lbuf) == 0) - CFG_ICACHE_ASSO = 4; - else if (strcmp("CONFIG_ICACHE_ALGORND", lbuf) == 0) - CFG_ICACHE_ALGO = "rnd"; - else if (strcmp("CONFIG_ICACHE_ALGOLRR", lbuf) == 0) - CFG_ICACHE_ALGO = "lrr"; - else if (strcmp("CONFIG_ICACHE_ALGOLRU", lbuf) == 0) - CFG_ICACHE_ALGO = "lru"; - else if (strcmp("CONFIG_ICACHE_LOCK", lbuf) == 0) - CFG_ICACHE_LOCK = 1; - else if (strcmp("CONFIG_ICACHE_SZ1", lbuf) == 0) - CFG_ICACHE_SZ = 1; - else if (strcmp("CONFIG_ICACHE_SZ2", lbuf) == 0) - CFG_ICACHE_SZ = 2; - else if (strcmp("CONFIG_ICACHE_SZ4", lbuf) == 0) - CFG_ICACHE_SZ = 4; - else if (strcmp("CONFIG_ICACHE_SZ8", lbuf) == 0) - CFG_ICACHE_SZ = 8; - else if (strcmp("CONFIG_ICACHE_SZ16", lbuf) == 0) - CFG_ICACHE_SZ = 16; - else if (strcmp("CONFIG_ICACHE_SZ32", lbuf) == 0) - CFG_ICACHE_SZ = 32; - else if (strcmp("CONFIG_ICACHE_SZ64", lbuf) == 0) - CFG_ICACHE_SZ = 64; - else if (strcmp("CONFIG_ICACHE_LZ16", lbuf) == 0) - CFG_ICACHE_LSZ = 16; - else if (strcmp("CONFIG_ICACHE_LZ32", lbuf) == 0) - CFG_ICACHE_LSZ = 32; - else if (strcmp("CONFIG_DCACHE_SZ1", lbuf) == 0) - CFG_DCACHE_SZ = 1; - else if (strcmp("CONFIG_DCACHE_SZ2", lbuf) == 0) - CFG_DCACHE_SZ = 2; - else if (strcmp("CONFIG_DCACHE_SZ4", lbuf) == 0) - CFG_DCACHE_SZ = 4; - else if (strcmp("CONFIG_DCACHE_SZ8", lbuf) == 0) - CFG_DCACHE_SZ = 8; - else if (strcmp("CONFIG_DCACHE_SZ16", lbuf) == 0) - CFG_DCACHE_SZ = 16; - else if (strcmp("CONFIG_DCACHE_SZ32", lbuf) == 0) - CFG_DCACHE_SZ = 32; - else if (strcmp("CONFIG_DCACHE_SZ64", lbuf) == 0) - CFG_DCACHE_SZ = 64; - else if (strcmp("CONFIG_DCACHE_LZ16", lbuf) == 0) - CFG_DCACHE_LSZ = 16; - else if (strcmp("CONFIG_DCACHE_LZ32", lbuf) == 0) - CFG_DCACHE_LSZ = 32; - else if (strcmp("CONFIG_DCACHE_SNOOP_SLOW", lbuf) == 0) - CFG_DCACHE_SNOOP = "slow"; - else if (strcmp("CONFIG_DCACHE_SNOOP_FAST", lbuf) == 0) - CFG_DCACHE_SNOOP = "fast"; - else if (strcmp("CONFIG_DCACHE_SNOOP", lbuf) == 0) {} - else if (strcmp("CONFIG_DCACHE_ASSO1", lbuf) == 0) - CFG_DCACHE_ASSO = 1; - else if (strcmp("CONFIG_DCACHE_ASSO2", lbuf) == 0) - CFG_DCACHE_ASSO = 2; - else if (strcmp("CONFIG_DCACHE_ASSO3", lbuf) == 0) - CFG_DCACHE_ASSO = 3; - else if (strcmp("CONFIG_DCACHE_ASSO4", lbuf) == 0) - CFG_DCACHE_ASSO = 4; - else if (strcmp("CONFIG_DCACHE_ALGORND", lbuf) == 0) - CFG_DCACHE_ALGO = "rnd"; - else if (strcmp("CONFIG_DCACHE_ALGOLRR", lbuf) == 0) - CFG_DCACHE_ALGO = "lrr"; - else if (strcmp("CONFIG_DCACHE_ALGOLRU", lbuf) == 0) - CFG_DCACHE_ALGO = "lru"; - else if (strcmp("CONFIG_DCACHE_LOCK", lbuf) == 0) - CFG_DCACHE_LOCK = 1; - else if (strcmp("CONFIG_DCACHE_RFAST", lbuf) == 0) - CFG_DCACHE_RFAST = true; - else if (strcmp("CONFIG_DCACHE_WFAST", lbuf) == 0) - CFG_DCACHE_WFAST = true; - else if (strcmp("CONFIG_DCACHE_LRAM", lbuf) == 0) - CFG_DCACHE_LRAM = true; - else if (strcmp("CONFIG_DCACHE_LRAM_SZ1", lbuf) == 0) - CFG_DCACHE_LRSZ = 1; - else if (strcmp("CONFIG_DCACHE_LRAM_SZ2", lbuf) == 0) - CFG_DCACHE_LRSZ = 2; - else if (strcmp("CONFIG_DCACHE_LRAM_SZ4", lbuf) == 0) - CFG_DCACHE_LRSZ = 4; - else if (strcmp("CONFIG_DCACHE_LRAM_SZ8", lbuf) == 0) - CFG_DCACHE_LRSZ = 8; - else if (strcmp("CONFIG_DCACHE_LRAM_SZ16", lbuf) == 0) - CFG_DCACHE_LRSZ = 16; - else if (strcmp("CONFIG_DCACHE_LRAM_SZ32", lbuf) == 0) - CFG_DCACHE_LRSZ = 32; - else if (strcmp("CONFIG_DCACHE_LRAM_SZ64", lbuf) == 0) - CFG_DCACHE_LRSZ = 64; - else if (strcmp("CONFIG_DCACHE_LRSTART", lbuf) == 0) { - strcpy(tmps, "0x"); strcat(tmps, value); - CFG_DCACHE_LRSTART = VAL(tmps) & 0x0ff; - } else if (strcmp("CONFIG_MMU_ENABLE", lbuf) == 0) - CFG_MMU_ENABLE = 1; - else if (strcmp("CONFIG_MMU_DIAG", lbuf) == 0) - CFG_MMU_DIAG = true; - else if (strcmp("CONFIG_MMU_SPLIT", lbuf) == 0) + while (!feof(stdin)) { + lbuf[0] = 0; + fgets(lbuf, 1023, stdin); + if (strncmp(lbuf, "CONFIG", 6) == 0) { + value = strchr(lbuf, '='); + value[0] = 0; + value++; + while ((strlen(value) > 0) && + ((value[strlen(value) - 1] == '\n') || (value[strlen(value) - 1] == '\r') || + (value[strlen(value) - 1] == '"'))) + value[strlen(value) - 1] = 0; + if ((strlen(value) > 0) && (value[0] == '"')) { value++; } + + /* synthesis options */ + else if (strcmp("CONFIG_SYN_GENERIC", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "gen"); + else if (strcmp("CONFIG_SYN_ATC35", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "atc35"); + else if (strcmp("CONFIG_SYN_ATC25", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "atc25"); + else if (strcmp("CONFIG_SYN_ATC18", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "atc18"); + else if (strcmp("CONFIG_SYN_FS90", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "fs90"); + else if (strcmp("CONFIG_SYN_UMC018", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "umc18"); + else if (strcmp("CONFIG_SYN_TSMC025", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "tsmc25"); + else if (strcmp("CONFIG_SYN_PROASIC", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "proasic"); + else if (strcmp("CONFIG_SYN_AXCEL", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "axcel"); + else if (strcmp("CONFIG_SYN_VIRTEX", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "virtex"); + else if (strcmp("CONFIG_SYN_VIRTEX2", lbuf) == 0) + strcpy(CFG_SYN_TARGET_TECH, "virtex2"); + else if (strcmp("CONFIG_SYN_INFER_PADS", lbuf) == 0) + CONFIG_SYN_INFER_PADS = true; + else if (strcmp("CONFIG_SYN_INFER_PCI_PADS", lbuf) == 0) + CONFIG_SYN_INFER_PCI_PADS = true; + else if (strcmp("CONFIG_SYN_INFER_RAM", lbuf) == 0) + CONFIG_SYN_INFER_RAM = true; + else if (strcmp("CONFIG_SYN_INFER_ROM", lbuf) == 0) + CONFIG_SYN_INFER_ROM = true; + else if (strcmp("CONFIG_SYN_INFER_REGF", lbuf) == 0) + CONFIG_SYN_INFER_REGF = true; + else if (strcmp("CONFIG_SYN_INFER_MULT", lbuf) == 0) + CONFIG_SYN_INFER_MULT = true; + else if (strcmp("CONFIG_SYN_RFTYPE", lbuf) == 0) + CONFIG_SYN_RFTYPE = 2; + else if (strcmp("CONFIG_SYN_TRACE_DPRAM", lbuf) == 0) + CONFIG_SYN_TRACE_DPRAM = true; + else if (strcmp("CONFIG_CLK_VIRTEX", lbuf) == 0) + strcpy(CONFIG_TARGET_CLK, "virtex"); + else if (strcmp("CONFIG_AXCEL_HCLKBUF", lbuf) == 0) + strcpy(CONFIG_TARGET_CLK, "axcel"); + else if (strcmp("CONFIG_CLKDLL_1_2", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 1; + CONFIG_PLL_CLK_DIV = 2; + } + else if (strcmp("CONFIG_CLKDLL_1_1", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 1; + CONFIG_PLL_CLK_DIV = 1; + } + else if (strcmp("CONFIG_CLKDLL_2_1", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 2; + CONFIG_PLL_CLK_DIV = 1; + } + else if (strcmp("CONFIG_CLK_VIRTEX2", lbuf) == 0) + strcpy(CONFIG_TARGET_CLK, "virtex2"); + else if (strcmp("CONFIG_DCM_2_3", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 2; + CONFIG_PLL_CLK_DIV = 3; + } + else if (strcmp("CONFIG_DCM_3_4", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 3; + CONFIG_PLL_CLK_DIV = 4; + } + else if (strcmp("CONFIG_DCM_4_5", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 4; + CONFIG_PLL_CLK_DIV = 5; + } + else if (strcmp("CONFIG_DCM_1_1", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 2; + CONFIG_PLL_CLK_DIV = 2; + } + else if (strcmp("CONFIG_DCM_5_4", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 5; + CONFIG_PLL_CLK_DIV = 4; + } + else if (strcmp("CONFIG_DCM_4_3", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 4; + CONFIG_PLL_CLK_DIV = 3; + } + else if (strcmp("CONFIG_DCM_3_2", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 3; + CONFIG_PLL_CLK_DIV = 2; + } + else if (strcmp("CONFIG_DCM_5_3", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 5; + CONFIG_PLL_CLK_DIV = 3; + } + else if (strcmp("CONFIG_DCM_2_1", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 2; + CONFIG_PLL_CLK_DIV = 1; + } + else if (strcmp("CONFIG_DCM_3_1", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 3; + CONFIG_PLL_CLK_DIV = 1; + } + else if (strcmp("CONFIG_DCM_4_1", lbuf) == 0) { + CONFIG_PLL_CLK_MUL = 4; + CONFIG_PLL_CLK_DIV = 1; + } + else if (strcmp("CONFIG_PCI_DLL", lbuf) == 0) + CONFIG_PCI_CLKDLL = true; + else if (strcmp("CONFIG_PCI_SYSCLK", lbuf) == 0) + CONFIG_PCI_SYSCLK = true; + /* IU options */ + else if (strcmp("CONFIG_IU_NWINDOWS", lbuf) == 0) { + CONFIG_IU_NWINDOWS = VAL(value); + if ((CONFIG_IU_NWINDOWS > 32) || (CONFIG_IU_NWINDOWS < 1)) CONFIG_IU_NWINDOWS = 8; + } + else if (strcmp("CONFIG_IU_V8MULDIV", lbuf) == 0) + strcpy(CFG_IU_DIVIDER, "radix2"); + else if (strcmp("CONFIG_IU_MUL_LATENCY_1", lbuf) == 0) + strcpy(CFG_IU_MUL_TYPE, "m32x32"); + else if (strcmp("CONFIG_IU_MUL_LATENCY_2", lbuf) == 0) + strcpy(CFG_IU_MUL_TYPE, "m32x16"); + else if (strcmp("CONFIG_IU_MUL_LATENCY_4", lbuf) == 0) + strcpy(CFG_IU_MUL_TYPE, "m16x16"); + else if (strcmp("CONFIG_IU_MUL_LATENCY_5", lbuf) == 0) { + strcpy(CFG_IU_MUL_TYPE, "m16x16"); + CONFIG_IU_MULPIPE = true; + } + else if (strcmp("CONFIG_IU_MUL_LATENCY_35", lbuf) == 0) + strcpy(CFG_IU_MUL_TYPE, "iterative"); + else if (strcmp("CONFIG_IU_MUL_MAC", lbuf) == 0) { + strcpy(CFG_IU_MUL_TYPE, "m16x16"); + CONFIG_IU_MUL_MAC = true; + } + else if (strcmp("CONFIG_IU_FASTJUMP", lbuf) == 0) + CONFIG_IU_FASTJUMP = true; + else if (strcmp("CONFIG_IU_FASTDECODE", lbuf) == 0) + CONFIG_IU_FASTDECODE = true; + else if (strcmp("CONFIG_IU_RFPOW", lbuf) == 0) + CONFIG_IU_RFPOW = true; + else if (strcmp("CONFIG_IU_ICCHOLD", lbuf) == 0) + CONFIG_IU_ICCHOLD = true; + else if (strcmp("CONFIG_IU_LDELAY", lbuf) == 0) { + CONFIG_IU_LDELAY = VAL(value); + if ((CONFIG_IU_LDELAY > 2) || (CONFIG_IU_LDELAY < 1)) CONFIG_IU_LDELAY = 2; + } + else if (strcmp("CONFIG_IU_WATCHPOINTS", lbuf) == 0) { + CONFIG_IU_WATCHPOINTS = VAL(value); + if ((CONFIG_IU_WATCHPOINTS > 4) || (CONFIG_IU_WATCHPOINTS < 0)) + CONFIG_IU_WATCHPOINTS = 0; + /* FPU config */ + } + else if (strcmp("CONFIG_FPU_ENABLE", lbuf) == 0) + CONFIG_FPU_ENABLE = 1; + else if (strcmp("CONFIG_FPU_GRFPU", lbuf) == 0) { + CFG_FPU_CORE = "grfpu"; + CFG_FPU_IF = "parallel"; + CONFIG_FPU_REGS = 0; + } + else if (strcmp("CONFIG_FPU_MEIKO", lbuf) == 0) { + CFG_FPU_CORE = "meiko"; + CFG_FPU_IF = "serial"; + } + else if (strcmp("CONFIG_FPU_LTH", lbuf) == 0) { + CFG_FPU_CORE = "lth"; + CFG_FPU_IF = "serial"; + } + else if (strcmp("CONFIG_FPU_VER", lbuf) == 0) + CONFIG_FPU_VER = VAL(value) & 0x07; + /* CP config */ + else if (strcmp("CONFIG_CP_ENABLE", lbuf) == 0) { + } + else if (strcmp("CONFIG_CP_CFG", lbuf) == 0) + strcpy(CONFIG_CP_CFG, value); + /* cache config */ + else if (strcmp("CONFIG_ICACHE_ASSO1", lbuf) == 0) + CFG_ICACHE_ASSO = 1; + else if (strcmp("CONFIG_ICACHE_ASSO2", lbuf) == 0) + CFG_ICACHE_ASSO = 2; + else if (strcmp("CONFIG_ICACHE_ASSO3", lbuf) == 0) + CFG_ICACHE_ASSO = 3; + else if (strcmp("CONFIG_ICACHE_ASSO4", lbuf) == 0) + CFG_ICACHE_ASSO = 4; + else if (strcmp("CONFIG_ICACHE_ALGORND", lbuf) == 0) + CFG_ICACHE_ALGO = "rnd"; + else if (strcmp("CONFIG_ICACHE_ALGOLRR", lbuf) == 0) + CFG_ICACHE_ALGO = "lrr"; + else if (strcmp("CONFIG_ICACHE_ALGOLRU", lbuf) == 0) + CFG_ICACHE_ALGO = "lru"; + else if (strcmp("CONFIG_ICACHE_LOCK", lbuf) == 0) + CFG_ICACHE_LOCK = 1; + else if (strcmp("CONFIG_ICACHE_SZ1", lbuf) == 0) + CFG_ICACHE_SZ = 1; + else if (strcmp("CONFIG_ICACHE_SZ2", lbuf) == 0) + CFG_ICACHE_SZ = 2; + else if (strcmp("CONFIG_ICACHE_SZ4", lbuf) == 0) + CFG_ICACHE_SZ = 4; + else if (strcmp("CONFIG_ICACHE_SZ8", lbuf) == 0) + CFG_ICACHE_SZ = 8; + else if (strcmp("CONFIG_ICACHE_SZ16", lbuf) == 0) + CFG_ICACHE_SZ = 16; + else if (strcmp("CONFIG_ICACHE_SZ32", lbuf) == 0) + CFG_ICACHE_SZ = 32; + else if (strcmp("CONFIG_ICACHE_SZ64", lbuf) == 0) + CFG_ICACHE_SZ = 64; + else if (strcmp("CONFIG_ICACHE_LZ16", lbuf) == 0) + CFG_ICACHE_LSZ = 16; + else if (strcmp("CONFIG_ICACHE_LZ32", lbuf) == 0) + CFG_ICACHE_LSZ = 32; + else if (strcmp("CONFIG_DCACHE_SZ1", lbuf) == 0) + CFG_DCACHE_SZ = 1; + else if (strcmp("CONFIG_DCACHE_SZ2", lbuf) == 0) + CFG_DCACHE_SZ = 2; + else if (strcmp("CONFIG_DCACHE_SZ4", lbuf) == 0) + CFG_DCACHE_SZ = 4; + else if (strcmp("CONFIG_DCACHE_SZ8", lbuf) == 0) + CFG_DCACHE_SZ = 8; + else if (strcmp("CONFIG_DCACHE_SZ16", lbuf) == 0) + CFG_DCACHE_SZ = 16; + else if (strcmp("CONFIG_DCACHE_SZ32", lbuf) == 0) + CFG_DCACHE_SZ = 32; + else if (strcmp("CONFIG_DCACHE_SZ64", lbuf) == 0) + CFG_DCACHE_SZ = 64; + else if (strcmp("CONFIG_DCACHE_LZ16", lbuf) == 0) + CFG_DCACHE_LSZ = 16; + else if (strcmp("CONFIG_DCACHE_LZ32", lbuf) == 0) + CFG_DCACHE_LSZ = 32; + else if (strcmp("CONFIG_DCACHE_SNOOP_SLOW", lbuf) == 0) + CFG_DCACHE_SNOOP = "slow"; + else if (strcmp("CONFIG_DCACHE_SNOOP_FAST", lbuf) == 0) + CFG_DCACHE_SNOOP = "fast"; + else if (strcmp("CONFIG_DCACHE_SNOOP", lbuf) == 0) { + } + else if (strcmp("CONFIG_DCACHE_ASSO1", lbuf) == 0) + CFG_DCACHE_ASSO = 1; + else if (strcmp("CONFIG_DCACHE_ASSO2", lbuf) == 0) + CFG_DCACHE_ASSO = 2; + else if (strcmp("CONFIG_DCACHE_ASSO3", lbuf) == 0) + CFG_DCACHE_ASSO = 3; + else if (strcmp("CONFIG_DCACHE_ASSO4", lbuf) == 0) + CFG_DCACHE_ASSO = 4; + else if (strcmp("CONFIG_DCACHE_ALGORND", lbuf) == 0) + CFG_DCACHE_ALGO = "rnd"; + else if (strcmp("CONFIG_DCACHE_ALGOLRR", lbuf) == 0) + CFG_DCACHE_ALGO = "lrr"; + else if (strcmp("CONFIG_DCACHE_ALGOLRU", lbuf) == 0) + CFG_DCACHE_ALGO = "lru"; + else if (strcmp("CONFIG_DCACHE_LOCK", lbuf) == 0) + CFG_DCACHE_LOCK = 1; + else if (strcmp("CONFIG_DCACHE_RFAST", lbuf) == 0) + CFG_DCACHE_RFAST = true; + else if (strcmp("CONFIG_DCACHE_WFAST", lbuf) == 0) + CFG_DCACHE_WFAST = true; + else if (strcmp("CONFIG_DCACHE_LRAM", lbuf) == 0) + CFG_DCACHE_LRAM = true; + else if (strcmp("CONFIG_DCACHE_LRAM_SZ1", lbuf) == 0) + CFG_DCACHE_LRSZ = 1; + else if (strcmp("CONFIG_DCACHE_LRAM_SZ2", lbuf) == 0) + CFG_DCACHE_LRSZ = 2; + else if (strcmp("CONFIG_DCACHE_LRAM_SZ4", lbuf) == 0) + CFG_DCACHE_LRSZ = 4; + else if (strcmp("CONFIG_DCACHE_LRAM_SZ8", lbuf) == 0) + CFG_DCACHE_LRSZ = 8; + else if (strcmp("CONFIG_DCACHE_LRAM_SZ16", lbuf) == 0) + CFG_DCACHE_LRSZ = 16; + else if (strcmp("CONFIG_DCACHE_LRAM_SZ32", lbuf) == 0) + CFG_DCACHE_LRSZ = 32; + else if (strcmp("CONFIG_DCACHE_LRAM_SZ64", lbuf) == 0) + CFG_DCACHE_LRSZ = 64; + else if (strcmp("CONFIG_DCACHE_LRSTART", lbuf) == 0) { + strcpy(tmps, "0x"); + strcat(tmps, value); + CFG_DCACHE_LRSTART = VAL(tmps) & 0x0ff; + } + else if (strcmp("CONFIG_MMU_ENABLE", lbuf) == 0) + CFG_MMU_ENABLE = 1; + else if (strcmp("CONFIG_MMU_DIAG", lbuf) == 0) + CFG_MMU_DIAG = true; + else if (strcmp("CONFIG_MMU_SPLIT", lbuf) == 0) CFG_MMU_TYPE = "splittlb"; - else if (strcmp("CONFIG_MMU_COMBINED", lbuf) == 0) - CFG_MMU_TYPE = "combinedtlb"; - else if (strcmp("CONFIG_MMU_REPARRAY", lbuf) == 0) - CFG_MMU_REP = "replruarray"; - else if (strcmp("CONFIG_MMU_REPINCREMENT", lbuf) == 0) - CFG_MMU_REP = "repincrement"; - else if (strcmp("CONFIG_MMU_I2", lbuf) == 0) - CFG_MMU_I = 2; - else if (strcmp("CONFIG_MMU_I4", lbuf) == 0) - CFG_MMU_I = 4; - else if (strcmp("CONFIG_MMU_I8", lbuf) == 0) - CFG_MMU_I = 8; - else if (strcmp("CONFIG_MMU_I16", lbuf) == 0) - CFG_MMU_I = 16; - else if (strcmp("CONFIG_MMU_I32", lbuf) == 0) - CFG_MMU_I = 32; - else if (strcmp("CONFIG_MMU_D1", lbuf) == 0) - CFG_MMU_D = 1; - else if (strcmp("CONFIG_MMU_D2", lbuf) == 0) - CFG_MMU_D = 2; - else if (strcmp("CONFIG_MMU_D4", lbuf) == 0) - CFG_MMU_D = 4; - else if (strcmp("CONFIG_MMU_D8", lbuf) == 0) - CFG_MMU_D = 8; - else if (strcmp("CONFIG_MMU_D16", lbuf) == 0) - CFG_MMU_D = 16; - else if (strcmp("CONFIG_MMU_D32", lbuf) == 0) - CFG_MMU_D = 32; - - /* CP config */ - else if (strcmp("CONFIG_CP_ENABLE", lbuf) == 0) {} - /* Memory controller */ - else if (strcmp("CONFIG_MCTRL_8BIT", lbuf) == 0) - CONFIG_MCTRL_8BIT = true; - else if (strcmp("CONFIG_MCTRL_16BIT", lbuf) == 0) - CONFIG_MCTRL_16BIT = true; - else if (strcmp("CONFIG_MCTRL_5CS", lbuf) == 0) - CONFIG_MCTRL_5CS = true; - else if (strcmp("CONFIG_MCTRL_WFB", lbuf) == 0) - CONFIG_MCTRL_WFB = true; - else if (strcmp("CONFIG_MCTRL_SDRAM", lbuf) == 0) - CONFIG_MCTRL_SDRAM = true; - else if (strcmp("CONFIG_MCTRL_SDRAM_INVCLK", lbuf) == 0) - CONFIG_MCTRL_SDRAM_INVCLK = true; - else if (strcmp("CONFIG_MCTRL_SDRAM_SEPBUS", lbuf) == 0) - CONFIG_MCTRL_SDRAM_SEPBUS = true; - /* Peripherals */ - else if (strcmp("CONFIG_PERI_LCONF", lbuf) == 0) - CONFIG_PERI_LCONF = true; - else if (strcmp("CONFIG_PERI_AHBSTAT", lbuf) == 0) - CONFIG_PERI_AHBSTAT = true; - else if (strcmp("CONFIG_PERI_WPROT", lbuf) == 0) - CONFIG_PERI_WPROT = true; - else if (strcmp("CONFIG_PERI_WDOG", lbuf) == 0) - CONFIG_PERI_WDOG = true; - else if (strcmp("CONFIG_PERI_IRQ2", lbuf) == 0) - CONFIG_PERI_IRQ2 = true; - /* AHB */ - else if (strcmp("CONFIG_AHB_DEFMST", lbuf) == 0) - CONFIG_AHB_DEFMST = VAL(value); - else if (strcmp("CONFIG_AHB_SPLIT", lbuf) == 0) - CONFIG_AHB_SPLIT = true; - else if (strcmp("CONFIG_AHBRAM_ENABLE", lbuf) == 0) - CONFIG_AHBRAM_ENABLE = true; - else if (strcmp("CONFIG_AHBRAM_SZ1", lbuf) == 0) - CFG_AHBRAM_SZ = 1; - else if (strcmp("CONFIG_AHBRAM_SZ2", lbuf) == 0) - CFG_AHBRAM_SZ = 2; - else if (strcmp("CONFIG_AHBRAM_SZ4", lbuf) == 0) - CFG_AHBRAM_SZ = 3; - else if (strcmp("CONFIG_AHBRAM_SZ8", lbuf) == 0) - CFG_AHBRAM_SZ = 4; - else if (strcmp("CONFIG_AHBRAM_SZ16", lbuf) == 0) - CFG_AHBRAM_SZ = 5; - else if (strcmp("CONFIG_AHBRAM_SZ32", lbuf) == 0) - CFG_AHBRAM_SZ = 6; - else if (strcmp("CONFIG_AHBRAM_SZ64", lbuf) == 0) - CFG_AHBRAM_SZ = 7; - /* Debug */ - else if (strcmp("CONFIG_DEBUG_UART", lbuf) == 0) - CONFIG_DEBUG_UART = true; - else if (strcmp("CONFIG_DEBUG_IURF", lbuf) == 0) - CONFIG_DEBUG_IURF = true; - else if (strcmp("CONFIG_DEBUG_FPURF", lbuf) == 0) - CONFIG_DEBUG_FPURF = true; - else if (strcmp("CONFIG_DEBUG_NOHALT", lbuf) == 0) - CONFIG_DEBUG_NOHALT = true; - else if (strcmp("CONFIG_DEBUG_PC32", lbuf) == 0) - CFG_DEBUG_PCLOW = 0; - else if (strcmp("CONFIG_DEBUG_RFERR", lbuf) == 0) - CONFIG_DEBUG_RFERR = true; - else if (strcmp("CONFIG_DEBUG_CACHEMEMERR", lbuf) == 0) - CONFIG_DEBUG_CACHEMEMERR = true; - /* DSU */ - else if (strcmp("CONFIG_DSU_ENABLE", lbuf) == 0) - {CONFIG_DSU_ENABLE = true; ahbmst ++;} - else if (strcmp("CONFIG_DSU_TRACEBUF", lbuf) == 0) - CONFIG_DSU_TRACEBUF = true; - else if (strcmp("CONFIG_DSU_MIXED_TRACE", lbuf) == 0) - CONFIG_DSU_MIXED_TRACE = true; - else if (strcmp("CONFIG_DSU_TRACESZ64", lbuf) == 0) - CFG_DSU_TRACE_SZ = 64; - else if (strcmp("CONFIG_DSU_TRACESZ128", lbuf) == 0) - CFG_DSU_TRACE_SZ = 128; - else if (strcmp("CONFIG_DSU_TRACESZ256", lbuf) == 0) - CFG_DSU_TRACE_SZ = 256; - else if (strcmp("CONFIG_DSU_TRACESZ512", lbuf) == 0) - CFG_DSU_TRACE_SZ = 512; - else if (strcmp("CONFIG_DSU_TRACESZ1024", lbuf) == 0) - CFG_DSU_TRACE_SZ = 1024; - /* Boot */ - else if (strcmp("CONFIG_BOOT_EXTPROM", lbuf) == 0) - CFG_BOOT_SOURCE = "memory"; - else if (strcmp("CONFIG_BOOT_INTPROM", lbuf) == 0) - CFG_BOOT_SOURCE = "prom"; - else if (strcmp("CONFIG_BOOT_MIXPROM", lbuf) == 0) - CFG_BOOT_SOURCE = "dual"; - else if (strcmp("CONFIG_BOOT_RWS", lbuf) == 0) - CONFIG_BOOT_RWS = VAL(value) & 0x3; - else if (strcmp("CONFIG_BOOT_WWS", lbuf) == 0) - CONFIG_BOOT_WWS = VAL(value) & 0x3; - else if (strcmp("CONFIG_BOOT_SYSCLK", lbuf) == 0) - CONFIG_BOOT_SYSCLK = VAL(value); - else if (strcmp("CONFIG_BOOT_BAUDRATE", lbuf) == 0) - CONFIG_BOOT_BAUDRATE = VAL(value) & 0x3fffff; - else if (strcmp("CONFIG_BOOT_EXTBAUD", lbuf) == 0) - CONFIG_BOOT_EXTBAUD = true; - else if (strcmp("CONFIG_BOOT_PROMABITS", lbuf) == 0) - CONFIG_BOOT_PROMABITS = VAL(value) & 0x3f; - /* Ethernet */ - else if (strcmp("CONFIG_ETH_ENABLE", lbuf) == 0) - { CONFIG_ETH_ENABLE = true; ahbmst++;} - else if (strcmp("CONFIG_ETH_TXFIFO", lbuf) == 0) - { CONFIG_ETH_TXFIFO = VAL(value) & 0x0ffff; } - else if (strcmp("CONFIG_ETH_RXFIFO", lbuf) == 0) - { CONFIG_ETH_RXFIFO = VAL(value) & 0x0ffff; } - else if (strcmp("CONFIG_ETH_BURST", lbuf) == 0) - { CONFIG_ETH_BURST = VAL(value) & 0x0ffff; } - /* PCI */ - else if (strcmp("CONFIG_PCI_ENABLE", lbuf) == 0) - CONFIG_PCI_ENABLE = true; - else if (strcmp("CONFIG_PCI_SIMPLE_TARGET", lbuf) == 0) - { - CFG_PCI_CORE = "simple_target"; ahbmst++; pciahbmst = 1; - } - else if (strcmp("CONFIG_PCI_FAST_TARGET", lbuf) == 0) - { - CFG_PCI_CORE = "fast_target"; ahbmst++; pciahbmst = 1; - } - else if (strcmp("CONFIG_PCI_MASTER_TARGET", lbuf) == 0) - { - CFG_PCI_CORE = "master_target"; ahbmst++; pciahbmst = 1; - } - else if (strcmp("CONFIG_PCI_VENDORID", lbuf) == 0) - { - strcpy(tmps, "0x"); strcat(tmps, value); - CONFIG_PCI_VENDORID = VAL(tmps) & 0x0ffff; - } - else if (strcmp("CONFIG_PCI_DEVICEID", lbuf) == 0) - { - strcpy(tmps, "0x"); strcat(tmps, value); - CONFIG_PCI_DEVICEID = VAL(tmps) & 0x0ffff; - } - else if (strcmp("CONFIG_PCI_SUBSYSID", lbuf) == 0) - { - strcpy(tmps, "0x"); strcat(tmps, value); - CONFIG_PCI_SUBSYSID = VAL(tmps) & 0x0ffff; - } - else if (strcmp("CONFIG_PCI_REVID", lbuf) == 0) - { - strcpy(tmps, "0x"); strcat(tmps, value); - CONFIG_PCI_REVID = VAL(tmps) & 0x0ff; - } - else if (strcmp("CONFIG_PCI_CLASSCODE", lbuf) == 0) - { - strcpy(tmps, "0x"); strcat(tmps, value); - CONFIG_PCI_CLASSCODE = VAL(tmps) & 0x0ffffff; - } - else if (strcmp("CONFIG_PCI_TRACE256", lbuf) == 0) - CFG_PCI_TDEPTH = 8; - else if (strcmp("CONFIG_PCI_TRACE512", lbuf) == 0) - CFG_PCI_TDEPTH = 9; - else if (strcmp("CONFIG_PCI_TRACE1024", lbuf) == 0) - CFG_PCI_TDEPTH = 10; - else if (strcmp("CONFIG_PCI_TRACE2048", lbuf) == 0) - CFG_PCI_TDEPTH = 11; - else if (strcmp("CONFIG_PCI_TRACE4096", lbuf) == 0) - CFG_PCI_TDEPTH = 12; - else if (strcmp("CONFIG_PCI_TRACE", lbuf) == 0) - CONFIG_PCI_TRACE = true; - else if (strcmp("CONFIG_PCI_FIFO2", lbuf) == 0) - CFG_PCI_FIFO = 1; - else if (strcmp("CONFIG_PCI_FIFO4", lbuf) == 0) - CFG_PCI_FIFO = 2; - else if (strcmp("CONFIG_PCI_FIFO8", lbuf) == 0) - CFG_PCI_FIFO = 3; - else if (strcmp("CONFIG_PCI_FIFO16", lbuf) == 0) - CFG_PCI_FIFO = 4; - else if (strcmp("CONFIG_PCI_FIFO32", lbuf) == 0) - CFG_PCI_FIFO = 5; - else if (strcmp("CONFIG_PCI_FIFO64", lbuf) == 0) - CFG_PCI_FIFO = 6; - else if (strcmp("CONFIG_PCI_FIFO128", lbuf) == 0) - CFG_PCI_FIFO = 7; - else if (strcmp("CONFIG_PCI_PMEPADS", lbuf) == 0) - CONFIG_PCI_PMEPADS = true; - else if (strcmp("CONFIG_PCI_P66PAD", lbuf) == 0) - CONFIG_PCI_P66PAD = true; - else if (strcmp("CONFIG_PCI_RESETALL", lbuf) == 0) - CONFIG_PCI_RESETALL = true; - else if (strcmp("CONFIG_PCI_ARBEN", lbuf) == 0) - CONFIG_PCI_ARBEN = true; - /* FT */ - else if (strcmp("CONFIG_FT_ENABLE", lbuf) == 0) - CONFIG_FT_ENABLE = 1; - else if (strcmp("CONFIG_FT_RF_ENABLE", lbuf) == 0) - CONFIG_FT_RF_ENABLE = true; - else if (strcmp("CONFIG_FT_RF_PARITY", lbuf) == 0) - CONFIG_FT_RF_PARITY = true; - else if (strcmp("CONFIG_FT_RF_EDAC", lbuf) == 0) - CONFIG_FT_RF_PARBITS = 7; - else if (strcmp("CONFIG_FT_RF_PARBITS", lbuf) == 0) - CONFIG_FT_RF_PARBITS = abs(VAL(value) % 3) ; - else if (strcmp("CONFIG_FT_RF_WRFAST", lbuf) == 0) - CONFIG_FT_RF_WRFAST = true; - else if (strcmp("CONFIG_FT_TMR_REG", lbuf) == 0) - CONFIG_FT_TMR_REG = true; - else if (strcmp("CONFIG_FT_TMR_CLK", lbuf) == 0) - CONFIG_FT_TMR_CLK = true; - else if (strcmp("CONFIG_FT_MC", lbuf) == 0) - CONFIG_FT_MC = true; - else if (strcmp("CONFIG_FT_MEMEDAC", lbuf) == 0) - CONFIG_FT_MEMEDAC = true; - else if (strcmp("CONFIG_FT_CACHEMEM_ENABLE", lbuf) == 0) - CONFIG_FT_CACHEMEM_ENABLE = true; - else if (strcmp("CONFIG_FT_CACHEMEM_PARBITS", lbuf) == 0) - CONFIG_FT_CACHEMEM_PARBITS = abs(VAL(value) % 3) ; - else if (strcmp("CONFIG_FT_CACHEMEM_APAR", lbuf) == 0) - CONFIG_FT_CACHEMEM_APAR = true; - else if (strcmp("CONFIG_FT_CACHEMEM_ENABLE", lbuf) == 0) {} - else - fprintf(stderr, "unknown config option: %s = %s\n", lbuf, value); - - } - } - - fprintf(fp, "\n\ + else if (strcmp("CONFIG_MMU_COMBINED", lbuf) == 0) + CFG_MMU_TYPE = "combinedtlb"; + else if (strcmp("CONFIG_MMU_REPARRAY", lbuf) == 0) + CFG_MMU_REP = "replruarray"; + else if (strcmp("CONFIG_MMU_REPINCREMENT", lbuf) == 0) + CFG_MMU_REP = "repincrement"; + else if (strcmp("CONFIG_MMU_I2", lbuf) == 0) + CFG_MMU_I = 2; + else if (strcmp("CONFIG_MMU_I4", lbuf) == 0) + CFG_MMU_I = 4; + else if (strcmp("CONFIG_MMU_I8", lbuf) == 0) + CFG_MMU_I = 8; + else if (strcmp("CONFIG_MMU_I16", lbuf) == 0) + CFG_MMU_I = 16; + else if (strcmp("CONFIG_MMU_I32", lbuf) == 0) + CFG_MMU_I = 32; + else if (strcmp("CONFIG_MMU_D1", lbuf) == 0) + CFG_MMU_D = 1; + else if (strcmp("CONFIG_MMU_D2", lbuf) == 0) + CFG_MMU_D = 2; + else if (strcmp("CONFIG_MMU_D4", lbuf) == 0) + CFG_MMU_D = 4; + else if (strcmp("CONFIG_MMU_D8", lbuf) == 0) + CFG_MMU_D = 8; + else if (strcmp("CONFIG_MMU_D16", lbuf) == 0) + CFG_MMU_D = 16; + else if (strcmp("CONFIG_MMU_D32", lbuf) == 0) + CFG_MMU_D = 32; + + /* CP config */ + else if (strcmp("CONFIG_CP_ENABLE", lbuf) == 0) { + } + /* Memory controller */ + else if (strcmp("CONFIG_MCTRL_8BIT", lbuf) == 0) + CONFIG_MCTRL_8BIT = true; + else if (strcmp("CONFIG_MCTRL_16BIT", lbuf) == 0) + CONFIG_MCTRL_16BIT = true; + else if (strcmp("CONFIG_MCTRL_5CS", lbuf) == 0) + CONFIG_MCTRL_5CS = true; + else if (strcmp("CONFIG_MCTRL_WFB", lbuf) == 0) + CONFIG_MCTRL_WFB = true; + else if (strcmp("CONFIG_MCTRL_SDRAM", lbuf) == 0) + CONFIG_MCTRL_SDRAM = true; + else if (strcmp("CONFIG_MCTRL_SDRAM_INVCLK", lbuf) == 0) + CONFIG_MCTRL_SDRAM_INVCLK = true; + else if (strcmp("CONFIG_MCTRL_SDRAM_SEPBUS", lbuf) == 0) + CONFIG_MCTRL_SDRAM_SEPBUS = true; + /* Peripherals */ + else if (strcmp("CONFIG_PERI_LCONF", lbuf) == 0) + CONFIG_PERI_LCONF = true; + else if (strcmp("CONFIG_PERI_AHBSTAT", lbuf) == 0) + CONFIG_PERI_AHBSTAT = true; + else if (strcmp("CONFIG_PERI_WPROT", lbuf) == 0) + CONFIG_PERI_WPROT = true; + else if (strcmp("CONFIG_PERI_WDOG", lbuf) == 0) + CONFIG_PERI_WDOG = true; + else if (strcmp("CONFIG_PERI_IRQ2", lbuf) == 0) + CONFIG_PERI_IRQ2 = true; + /* AHB */ + else if (strcmp("CONFIG_AHB_DEFMST", lbuf) == 0) + CONFIG_AHB_DEFMST = VAL(value); + else if (strcmp("CONFIG_AHB_SPLIT", lbuf) == 0) + CONFIG_AHB_SPLIT = true; + else if (strcmp("CONFIG_AHBRAM_ENABLE", lbuf) == 0) + CONFIG_AHBRAM_ENABLE = true; + else if (strcmp("CONFIG_AHBRAM_SZ1", lbuf) == 0) + CFG_AHBRAM_SZ = 1; + else if (strcmp("CONFIG_AHBRAM_SZ2", lbuf) == 0) + CFG_AHBRAM_SZ = 2; + else if (strcmp("CONFIG_AHBRAM_SZ4", lbuf) == 0) + CFG_AHBRAM_SZ = 3; + else if (strcmp("CONFIG_AHBRAM_SZ8", lbuf) == 0) + CFG_AHBRAM_SZ = 4; + else if (strcmp("CONFIG_AHBRAM_SZ16", lbuf) == 0) + CFG_AHBRAM_SZ = 5; + else if (strcmp("CONFIG_AHBRAM_SZ32", lbuf) == 0) + CFG_AHBRAM_SZ = 6; + else if (strcmp("CONFIG_AHBRAM_SZ64", lbuf) == 0) + CFG_AHBRAM_SZ = 7; + /* Debug */ + else if (strcmp("CONFIG_DEBUG_UART", lbuf) == 0) + CONFIG_DEBUG_UART = true; + else if (strcmp("CONFIG_DEBUG_IURF", lbuf) == 0) + CONFIG_DEBUG_IURF = true; + else if (strcmp("CONFIG_DEBUG_FPURF", lbuf) == 0) + CONFIG_DEBUG_FPURF = true; + else if (strcmp("CONFIG_DEBUG_NOHALT", lbuf) == 0) + CONFIG_DEBUG_NOHALT = true; + else if (strcmp("CONFIG_DEBUG_PC32", lbuf) == 0) + CFG_DEBUG_PCLOW = 0; + else if (strcmp("CONFIG_DEBUG_RFERR", lbuf) == 0) + CONFIG_DEBUG_RFERR = true; + else if (strcmp("CONFIG_DEBUG_CACHEMEMERR", lbuf) == 0) + CONFIG_DEBUG_CACHEMEMERR = true; + /* DSU */ + else if (strcmp("CONFIG_DSU_ENABLE", lbuf) == 0) { + CONFIG_DSU_ENABLE = true; + ahbmst++; + } + else if (strcmp("CONFIG_DSU_TRACEBUF", lbuf) == 0) + CONFIG_DSU_TRACEBUF = true; + else if (strcmp("CONFIG_DSU_MIXED_TRACE", lbuf) == 0) + CONFIG_DSU_MIXED_TRACE = true; + else if (strcmp("CONFIG_DSU_TRACESZ64", lbuf) == 0) + CFG_DSU_TRACE_SZ = 64; + else if (strcmp("CONFIG_DSU_TRACESZ128", lbuf) == 0) + CFG_DSU_TRACE_SZ = 128; + else if (strcmp("CONFIG_DSU_TRACESZ256", lbuf) == 0) + CFG_DSU_TRACE_SZ = 256; + else if (strcmp("CONFIG_DSU_TRACESZ512", lbuf) == 0) + CFG_DSU_TRACE_SZ = 512; + else if (strcmp("CONFIG_DSU_TRACESZ1024", lbuf) == 0) + CFG_DSU_TRACE_SZ = 1024; + /* Boot */ + else if (strcmp("CONFIG_BOOT_EXTPROM", lbuf) == 0) + CFG_BOOT_SOURCE = "memory"; + else if (strcmp("CONFIG_BOOT_INTPROM", lbuf) == 0) + CFG_BOOT_SOURCE = "prom"; + else if (strcmp("CONFIG_BOOT_MIXPROM", lbuf) == 0) + CFG_BOOT_SOURCE = "dual"; + else if (strcmp("CONFIG_BOOT_RWS", lbuf) == 0) + CONFIG_BOOT_RWS = VAL(value) & 0x3; + else if (strcmp("CONFIG_BOOT_WWS", lbuf) == 0) + CONFIG_BOOT_WWS = VAL(value) & 0x3; + else if (strcmp("CONFIG_BOOT_SYSCLK", lbuf) == 0) + CONFIG_BOOT_SYSCLK = VAL(value); + else if (strcmp("CONFIG_BOOT_BAUDRATE", lbuf) == 0) + CONFIG_BOOT_BAUDRATE = VAL(value) & 0x3fffff; + else if (strcmp("CONFIG_BOOT_EXTBAUD", lbuf) == 0) + CONFIG_BOOT_EXTBAUD = true; + else if (strcmp("CONFIG_BOOT_PROMABITS", lbuf) == 0) + CONFIG_BOOT_PROMABITS = VAL(value) & 0x3f; + /* Ethernet */ + else if (strcmp("CONFIG_ETH_ENABLE", lbuf) == 0) { + CONFIG_ETH_ENABLE = true; + ahbmst++; + } + else if (strcmp("CONFIG_ETH_TXFIFO", lbuf) == 0) { + CONFIG_ETH_TXFIFO = VAL(value) & 0x0ffff; + } + else if (strcmp("CONFIG_ETH_RXFIFO", lbuf) == 0) { + CONFIG_ETH_RXFIFO = VAL(value) & 0x0ffff; + } + else if (strcmp("CONFIG_ETH_BURST", lbuf) == 0) { + CONFIG_ETH_BURST = VAL(value) & 0x0ffff; + } + /* PCI */ + else if (strcmp("CONFIG_PCI_ENABLE", lbuf) == 0) + CONFIG_PCI_ENABLE = true; + else if (strcmp("CONFIG_PCI_SIMPLE_TARGET", lbuf) == 0) { + CFG_PCI_CORE = "simple_target"; + ahbmst++; + pciahbmst = 1; + } + else if (strcmp("CONFIG_PCI_FAST_TARGET", lbuf) == 0) { + CFG_PCI_CORE = "fast_target"; + ahbmst++; + pciahbmst = 1; + } + else if (strcmp("CONFIG_PCI_MASTER_TARGET", lbuf) == 0) { + CFG_PCI_CORE = "master_target"; + ahbmst++; + pciahbmst = 1; + } + else if (strcmp("CONFIG_PCI_VENDORID", lbuf) == 0) { + strcpy(tmps, "0x"); + strcat(tmps, value); + CONFIG_PCI_VENDORID = VAL(tmps) & 0x0ffff; + } + else if (strcmp("CONFIG_PCI_DEVICEID", lbuf) == 0) { + strcpy(tmps, "0x"); + strcat(tmps, value); + CONFIG_PCI_DEVICEID = VAL(tmps) & 0x0ffff; + } + else if (strcmp("CONFIG_PCI_SUBSYSID", lbuf) == 0) { + strcpy(tmps, "0x"); + strcat(tmps, value); + CONFIG_PCI_SUBSYSID = VAL(tmps) & 0x0ffff; + } + else if (strcmp("CONFIG_PCI_REVID", lbuf) == 0) { + strcpy(tmps, "0x"); + strcat(tmps, value); + CONFIG_PCI_REVID = VAL(tmps) & 0x0ff; + } + else if (strcmp("CONFIG_PCI_CLASSCODE", lbuf) == 0) { + strcpy(tmps, "0x"); + strcat(tmps, value); + CONFIG_PCI_CLASSCODE = VAL(tmps) & 0x0ffffff; + } + else if (strcmp("CONFIG_PCI_TRACE256", lbuf) == 0) + CFG_PCI_TDEPTH = 8; + else if (strcmp("CONFIG_PCI_TRACE512", lbuf) == 0) + CFG_PCI_TDEPTH = 9; + else if (strcmp("CONFIG_PCI_TRACE1024", lbuf) == 0) + CFG_PCI_TDEPTH = 10; + else if (strcmp("CONFIG_PCI_TRACE2048", lbuf) == 0) + CFG_PCI_TDEPTH = 11; + else if (strcmp("CONFIG_PCI_TRACE4096", lbuf) == 0) + CFG_PCI_TDEPTH = 12; + else if (strcmp("CONFIG_PCI_TRACE", lbuf) == 0) + CONFIG_PCI_TRACE = true; + else if (strcmp("CONFIG_PCI_FIFO2", lbuf) == 0) + CFG_PCI_FIFO = 1; + else if (strcmp("CONFIG_PCI_FIFO4", lbuf) == 0) + CFG_PCI_FIFO = 2; + else if (strcmp("CONFIG_PCI_FIFO8", lbuf) == 0) + CFG_PCI_FIFO = 3; + else if (strcmp("CONFIG_PCI_FIFO16", lbuf) == 0) + CFG_PCI_FIFO = 4; + else if (strcmp("CONFIG_PCI_FIFO32", lbuf) == 0) + CFG_PCI_FIFO = 5; + else if (strcmp("CONFIG_PCI_FIFO64", lbuf) == 0) + CFG_PCI_FIFO = 6; + else if (strcmp("CONFIG_PCI_FIFO128", lbuf) == 0) + CFG_PCI_FIFO = 7; + else if (strcmp("CONFIG_PCI_PMEPADS", lbuf) == 0) + CONFIG_PCI_PMEPADS = true; + else if (strcmp("CONFIG_PCI_P66PAD", lbuf) == 0) + CONFIG_PCI_P66PAD = true; + else if (strcmp("CONFIG_PCI_RESETALL", lbuf) == 0) + CONFIG_PCI_RESETALL = true; + else if (strcmp("CONFIG_PCI_ARBEN", lbuf) == 0) + CONFIG_PCI_ARBEN = true; + /* FT */ + else if (strcmp("CONFIG_FT_ENABLE", lbuf) == 0) + CONFIG_FT_ENABLE = 1; + else if (strcmp("CONFIG_FT_RF_ENABLE", lbuf) == 0) + CONFIG_FT_RF_ENABLE = true; + else if (strcmp("CONFIG_FT_RF_PARITY", lbuf) == 0) + CONFIG_FT_RF_PARITY = true; + else if (strcmp("CONFIG_FT_RF_EDAC", lbuf) == 0) + CONFIG_FT_RF_PARBITS = 7; + else if (strcmp("CONFIG_FT_RF_PARBITS", lbuf) == 0) + CONFIG_FT_RF_PARBITS = abs(VAL(value) % 3); + else if (strcmp("CONFIG_FT_RF_WRFAST", lbuf) == 0) + CONFIG_FT_RF_WRFAST = true; + else if (strcmp("CONFIG_FT_TMR_REG", lbuf) == 0) + CONFIG_FT_TMR_REG = true; + else if (strcmp("CONFIG_FT_TMR_CLK", lbuf) == 0) + CONFIG_FT_TMR_CLK = true; + else if (strcmp("CONFIG_FT_MC", lbuf) == 0) + CONFIG_FT_MC = true; + else if (strcmp("CONFIG_FT_MEMEDAC", lbuf) == 0) + CONFIG_FT_MEMEDAC = true; + else if (strcmp("CONFIG_FT_CACHEMEM_ENABLE", lbuf) == 0) + CONFIG_FT_CACHEMEM_ENABLE = true; + else if (strcmp("CONFIG_FT_CACHEMEM_PARBITS", lbuf) == 0) + CONFIG_FT_CACHEMEM_PARBITS = abs(VAL(value) % 3); + else if (strcmp("CONFIG_FT_CACHEMEM_APAR", lbuf) == 0) + CONFIG_FT_CACHEMEM_APAR = true; + else if (strcmp("CONFIG_FT_CACHEMEM_ENABLE", lbuf) == 0) { + } + else + fprintf(stderr, "unknown config option: %s = %s\n", lbuf, value); + } + } + + fprintf(fp, "\n\ ----------------------------------------------------------------------------\n\ -- This file is a part of the LEON VHDL model\n\ -- Copyright (C) 1999 European Space Agency (ESA)\n\ @@ -727,146 +772,160 @@ package device is\n\ -----------------------------------------------------------------------------\n\ "); - if (CONFIG_AHBRAM_ENABLE == true) ahbram = 4; else ahbram = 0; - if (CONFIG_DSU_ENABLE == true) dsuen = 2; else dsuen = 7; - if (CONFIG_PCI_ENABLE == true) pcien = 3; else pcien = 7; - if (CONFIG_ETH_ENABLE == true) ethen = 5; else ethen = 7; + if (CONFIG_AHBRAM_ENABLE == true) ahbram = 4; + else + ahbram = 0; + if (CONFIG_DSU_ENABLE == true) dsuen = 2; + else + dsuen = 7; + if (CONFIG_PCI_ENABLE == true) pcien = 3; + else + pcien = 7; + if (CONFIG_ETH_ENABLE == true) ethen = 5; + else + ethen = 7; - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant syn_%s : syn_config_type := ( \n\ targettech => %s , infer_pads => %s, infer_pci => %s,\n\ infer_ram => %s, infer_regf => %s, infer_rom => %s,\n\ infer_mult => %s, rftype => %d, targetclk => %s,\n\ clk_mul => %d, clk_div => %d, pci_dll => %s, pci_sysclk => %s );\n\ -", CONFIG_CFG_NAME, CFG_SYN_TARGET_TECH, CONFIG_SYN_INFER_PADS, CONFIG_SYN_INFER_PCI_PADS, \ - CONFIG_SYN_INFER_RAM, CONFIG_SYN_INFER_REGF, CONFIG_SYN_INFER_ROM,\ - CONFIG_SYN_INFER_MULT, CONFIG_SYN_RFTYPE, CONFIG_TARGET_CLK, - CONFIG_PLL_CLK_MUL, CONFIG_PLL_CLK_DIV, CONFIG_PCI_CLKDLL, - CONFIG_PCI_SYSCLK); +", + CONFIG_CFG_NAME, CFG_SYN_TARGET_TECH, CONFIG_SYN_INFER_PADS, CONFIG_SYN_INFER_PCI_PADS, + CONFIG_SYN_INFER_RAM, CONFIG_SYN_INFER_REGF, CONFIG_SYN_INFER_ROM, + CONFIG_SYN_INFER_MULT, CONFIG_SYN_RFTYPE, CONFIG_TARGET_CLK, CONFIG_PLL_CLK_MUL, + CONFIG_PLL_CLK_DIV, CONFIG_PCI_CLKDLL, CONFIG_PCI_SYSCLK); - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant iu_%s : iu_config_type := (\n\ nwindows => %d, multiplier => %s, mulpipe => %s, \n\ divider => %s, mac => %s, fpuen => %d, cpen => false, \n\ fastjump => %s, icchold => %s, lddelay => %d, fastdecode => %s, \n\ rflowpow => %s, watchpoints => %d);\n\ -", CONFIG_CFG_NAME, CONFIG_IU_NWINDOWS, CFG_IU_MUL_TYPE, CONFIG_IU_MULPIPE, - CFG_IU_DIVIDER, CONFIG_IU_MUL_MAC, CONFIG_FPU_ENABLE, CONFIG_IU_FASTJUMP, - CONFIG_IU_ICCHOLD, CONFIG_IU_LDELAY, CONFIG_IU_FASTDECODE, CONFIG_IU_RFPOW, - CONFIG_IU_WATCHPOINTS); +", + CONFIG_CFG_NAME, CONFIG_IU_NWINDOWS, CFG_IU_MUL_TYPE, CONFIG_IU_MULPIPE, CFG_IU_DIVIDER, + CONFIG_IU_MUL_MAC, CONFIG_FPU_ENABLE, CONFIG_IU_FASTJUMP, CONFIG_IU_ICCHOLD, + CONFIG_IU_LDELAY, CONFIG_IU_FASTDECODE, CONFIG_IU_RFPOW, CONFIG_IU_WATCHPOINTS); - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant fpu_%s : fpu_config_type := \n\ (core => %s, interface => %s, fregs => %d, version => %d);\n\ -", CONFIG_CFG_NAME, CFG_FPU_CORE, CFG_FPU_IF, CONFIG_FPU_ENABLE*CONFIG_FPU_REGS, - CONFIG_FPU_VER); - - /* - if ((CFG_ICACHE_SZ > 4) && (CFG_MMU_TYPE != false)) { - CFG_ICACHE_SZ = 4; - printf("Warning: maximum iset size 4 kbyte when MMU enabled (fixed)\n"); - } - if ((CFG_DCACHE_SZ > 4) && (CFG_MMU_TYPE != false)) { - CFG_DCACHE_SZ = 4; - printf("Warning: maximum dset size 4 kbyte when MMU enabled (fixed)\n"); - } - */ - - if ((strcmp(CFG_ICACHE_ALGO,"lrr") == 0) && (CFG_ICACHE_ASSO > 2)) - CFG_ICACHE_ALGO = "rnd"; - if ((strcmp(CFG_DCACHE_ALGO,"lrr") == 0) && (CFG_DCACHE_ASSO > 2)) - CFG_DCACHE_ALGO = "rnd"; - - fprintf(fp, "\n\ +", + CONFIG_CFG_NAME, CFG_FPU_CORE, CFG_FPU_IF, CONFIG_FPU_ENABLE * CONFIG_FPU_REGS, + CONFIG_FPU_VER); + + /* + if ((CFG_ICACHE_SZ > 4) && (CFG_MMU_TYPE != false)) { + CFG_ICACHE_SZ = 4; + printf("Warning: maximum iset size 4 kbyte when MMU enabled (fixed)\n"); + } + if ((CFG_DCACHE_SZ > 4) && (CFG_MMU_TYPE != false)) { + CFG_DCACHE_SZ = 4; + printf("Warning: maximum dset size 4 kbyte when MMU enabled (fixed)\n"); + } + */ + + if ((strcmp(CFG_ICACHE_ALGO, "lrr") == 0) && (CFG_ICACHE_ASSO > 2)) CFG_ICACHE_ALGO = "rnd"; + if ((strcmp(CFG_DCACHE_ALGO, "lrr") == 0) && (CFG_DCACHE_ASSO > 2)) CFG_DCACHE_ALGO = "rnd"; + + fprintf(fp, "\n\ constant cache_%s : cache_config_type := (\n\ isets => %d, isetsize => %d, ilinesize => %d, ireplace => %s, ilock => %d,\n\ dsets => %d, dsetsize => %d, dlinesize => %d, dreplace => %s, dlock => %d,\n\ dsnoop => %s, drfast => %s, dwfast => %s, dlram => %s, \n\ dlramsize => %d, dlramaddr => 16#%02X#);\n\ -", CONFIG_CFG_NAME, - CFG_ICACHE_ASSO, CFG_ICACHE_SZ, CFG_ICACHE_LSZ/4, CFG_ICACHE_ALGO, CFG_ICACHE_LOCK, - CFG_DCACHE_ASSO, CFG_DCACHE_SZ, CFG_DCACHE_LSZ/4, CFG_DCACHE_ALGO, CFG_DCACHE_LOCK, - CFG_DCACHE_SNOOP, CFG_DCACHE_RFAST, CFG_DCACHE_WFAST, CFG_DCACHE_LRAM, - CFG_DCACHE_LRSZ, CFG_DCACHE_LRSTART); +", + CONFIG_CFG_NAME, CFG_ICACHE_ASSO, CFG_ICACHE_SZ, CFG_ICACHE_LSZ / 4, CFG_ICACHE_ALGO, + CFG_ICACHE_LOCK, CFG_DCACHE_ASSO, CFG_DCACHE_SZ, CFG_DCACHE_LSZ / 4, CFG_DCACHE_ALGO, + CFG_DCACHE_LOCK, CFG_DCACHE_SNOOP, CFG_DCACHE_RFAST, CFG_DCACHE_WFAST, CFG_DCACHE_LRAM, + CFG_DCACHE_LRSZ, CFG_DCACHE_LRSTART); - fprintf (fp, "\n\ + fprintf(fp, "\n\ constant mmu_%s : mmu_config_type := (\n\ enable => %d, itlbnum => %d, dtlbnum => %d, tlb_type => %s, \n\ tlb_rep => %s, tlb_diag => %s );\n\ -", CONFIG_CFG_NAME, CFG_MMU_ENABLE, CFG_MMU_I, CFG_MMU_D, - CFG_MMU_TYPE, CFG_MMU_REP, CFG_MMU_DIAG); +", + CONFIG_CFG_NAME, CFG_MMU_ENABLE, CFG_MMU_I, CFG_MMU_D, CFG_MMU_TYPE, CFG_MMU_REP, + CFG_MMU_DIAG); - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant ahbrange_config : ahbslv_addr_type := \n\ (0,0,0,0,0,0,%d,0,1,%d,%d,%d,%d,%d,%d,%d);\n\ -", ahbram, dsuen, pcien, ethen, pcien, pcien, pcien, pcien); +", + ahbram, dsuen, pcien, ethen, pcien, pcien, pcien, pcien); - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant ahb_%s : ahb_config_type := ( masters => %d, defmst => %d,\n\ split => %s, testmod => false);\n\ -", CONFIG_CFG_NAME, ahbmst, CONFIG_AHB_DEFMST % ahbmst, CONFIG_AHB_SPLIT); +", + CONFIG_CFG_NAME, ahbmst, CONFIG_AHB_DEFMST % ahbmst, CONFIG_AHB_SPLIT); - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant mctrl_%s : mctrl_config_type := (\n\ bus8en => %s, bus16en => %s, wendfb => %s, ramsel5 => %s,\n\ sdramen => %s, sdinvclk => %s, sdsepbus => %s);\n\ -", CONFIG_CFG_NAME, CONFIG_MCTRL_8BIT, CONFIG_MCTRL_16BIT, CONFIG_MCTRL_WFB, - CONFIG_MCTRL_5CS, - CONFIG_MCTRL_SDRAM, CONFIG_MCTRL_SDRAM_INVCLK, CONFIG_MCTRL_SDRAM_SEPBUS); - - fprintf(fp, "\n\ +", + CONFIG_CFG_NAME, CONFIG_MCTRL_8BIT, CONFIG_MCTRL_16BIT, CONFIG_MCTRL_WFB, + CONFIG_MCTRL_5CS, CONFIG_MCTRL_SDRAM, CONFIG_MCTRL_SDRAM_INVCLK, + CONFIG_MCTRL_SDRAM_SEPBUS); + + fprintf(fp, "\n\ constant peri_%s : peri_config_type := (\n\ cfgreg => %s, ahbstat => %s, wprot => %s, wdog => %s, \n\ irq2en => %s, ahbram => %s, ahbrambits => %d, ethen => %s );\n\ -", CONFIG_CFG_NAME, CONFIG_PERI_LCONF, CONFIG_PERI_AHBSTAT, CONFIG_PERI_WPROT, - CONFIG_PERI_WDOG, CONFIG_PERI_IRQ2, CONFIG_AHBRAM_ENABLE, 7 + CFG_AHBRAM_SZ, - CONFIG_ETH_ENABLE); +", + CONFIG_CFG_NAME, CONFIG_PERI_LCONF, CONFIG_PERI_AHBSTAT, CONFIG_PERI_WPROT, + CONFIG_PERI_WDOG, CONFIG_PERI_IRQ2, CONFIG_AHBRAM_ENABLE, 7 + CFG_AHBRAM_SZ, + CONFIG_ETH_ENABLE); - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant debug_%s : debug_config_type := ( enable => true, uart => %s, \n\ iureg => %s, fpureg => %s, nohalt => %s, pclow => %d,\n\ dsuenable => %s, dsutrace => %s, dsumixed => %s,\n\ dsudpram => %s, tracelines => %d);\n\ -", CONFIG_CFG_NAME, CONFIG_DEBUG_UART, CONFIG_DEBUG_IURF, CONFIG_DEBUG_FPURF, - CONFIG_DEBUG_NOHALT, CFG_DEBUG_PCLOW, CONFIG_DSU_ENABLE, CONFIG_DSU_TRACEBUF, - CONFIG_DSU_MIXED_TRACE, CONFIG_SYN_TRACE_DPRAM, CFG_DSU_TRACE_SZ); +", + CONFIG_CFG_NAME, CONFIG_DEBUG_UART, CONFIG_DEBUG_IURF, CONFIG_DEBUG_FPURF, + CONFIG_DEBUG_NOHALT, CFG_DEBUG_PCLOW, CONFIG_DSU_ENABLE, CONFIG_DSU_TRACEBUF, + CONFIG_DSU_MIXED_TRACE, CONFIG_SYN_TRACE_DPRAM, CFG_DSU_TRACE_SZ); - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant boot_%s : boot_config_type := (boot => %s, ramrws => %d,\n\ ramwws => %d, sysclk => %d, baud => %d, extbaud => %s,\n\ pabits => %d);\n\ -", CONFIG_CFG_NAME, CFG_BOOT_SOURCE, CONFIG_BOOT_RWS, CONFIG_BOOT_WWS, - CONFIG_BOOT_SYSCLK, CONFIG_BOOT_BAUDRATE, CONFIG_BOOT_EXTBAUD, - CONFIG_BOOT_PROMABITS); +", + CONFIG_CFG_NAME, CFG_BOOT_SOURCE, CONFIG_BOOT_RWS, CONFIG_BOOT_WWS, CONFIG_BOOT_SYSCLK, + CONFIG_BOOT_BAUDRATE, CONFIG_BOOT_EXTBAUD, CONFIG_BOOT_PROMABITS); - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant pci_%s : pci_config_type := (\n\ pcicore => %s , ahbmasters => %d, fifodepth => %d,\n\ arbiter => %s, fixpri => false, prilevels => 4, pcimasters => 4,\n\ vendorid => 16#%04X#, deviceid => 16#%04X#, subsysid => 16#%04X#,\n\ revisionid => 16#%02X#, classcode =>16#%06X#, pmepads => %s,\n\ p66pad => %s, pcirstall => %s, trace => %s, tracedepth => %d);\n\ -", CONFIG_CFG_NAME, CFG_PCI_CORE, pciahbmst, CFG_PCI_FIFO, CONFIG_PCI_ARBEN, - CONFIG_PCI_VENDORID, CONFIG_PCI_DEVICEID, CONFIG_PCI_SUBSYSID, - CONFIG_PCI_REVID, CONFIG_PCI_CLASSCODE, CONFIG_PCI_PMEPADS, - CONFIG_PCI_P66PAD, CONFIG_PCI_RESETALL, CONFIG_PCI_TRACE, CFG_PCI_TDEPTH); +", + CONFIG_CFG_NAME, CFG_PCI_CORE, pciahbmst, CFG_PCI_FIFO, CONFIG_PCI_ARBEN, + CONFIG_PCI_VENDORID, CONFIG_PCI_DEVICEID, CONFIG_PCI_SUBSYSID, CONFIG_PCI_REVID, + CONFIG_PCI_CLASSCODE, CONFIG_PCI_PMEPADS, CONFIG_PCI_P66PAD, CONFIG_PCI_RESETALL, + CONFIG_PCI_TRACE, CFG_PCI_TDEPTH); - fprintf(fp, "\n\ + fprintf(fp, "\n\ constant irq2cfg : irq2type := irq2none;\n\ "); - if (CONFIG_FT_ENABLE) - fprintf(fp, "\n\ + if (CONFIG_FT_ENABLE) + fprintf(fp, "\n\ constant ft_%s : ft_config_type := ( rfpbits => %d, tmrreg => %s,\n\ tmrclk => %s, mscheck => %s, memedac => %s, \n\ rfwropt => %s, cparbits => %d, caddrpar => %s, regferr => %s,\n\ cacheerr => %s);\n\ -", CONFIG_CFG_NAME, CONFIG_FT_RF_PARBITS, CONFIG_FT_TMR_REG, CONFIG_FT_TMR_CLK, - CONFIG_FT_MC, CONFIG_FT_MEMEDAC, CONFIG_FT_RF_WRFAST, - CONFIG_FT_CACHEMEM_PARBITS, CONFIG_FT_CACHEMEM_APAR, CONFIG_DEBUG_RFERR, - CONFIG_DEBUG_CACHEMEMERR); +", + CONFIG_CFG_NAME, CONFIG_FT_RF_PARBITS, CONFIG_FT_TMR_REG, CONFIG_FT_TMR_CLK, + CONFIG_FT_MC, CONFIG_FT_MEMEDAC, CONFIG_FT_RF_WRFAST, CONFIG_FT_CACHEMEM_PARBITS, + CONFIG_FT_CACHEMEM_APAR, CONFIG_DEBUG_RFERR, CONFIG_DEBUG_CACHEMEMERR); - fprintf(fp, "\n\ + fprintf(fp, "\n\ \n\ -----------------------------------------------------------------------------\n\ -- end of automatic configuration\n\ @@ -874,21 +933,22 @@ package device is\n\ \n\ end;\n\ "); - close(fp); - fp = fopen("device.v", "w+"); - if (!fp) { - printf("could not open file device.v\n"); - exit(1); - } - fprintf(fp, "\n\ + close(fp); + fp = fopen("device.v", "w+"); + if (!fp) { + printf("could not open file device.v\n"); + exit(1); + } + fprintf(fp, "\n\ `define HEADER_VENDOR_ID 16'h%04X\n\ `define HEADER_DEVICE_ID 16'h%04X\n\ `define HEADER_REVISION_ID 8'h%02X\n\ -", CONFIG_PCI_VENDORID, CONFIG_PCI_DEVICEID, CONFIG_PCI_REVID); +", + CONFIG_PCI_VENDORID, CONFIG_PCI_DEVICEID, CONFIG_PCI_REVID); - if ((CONFIG_SYN_INFER_RAM == false) && (!((strcmp(CFG_SYN_TARGET_TECH, "virtex")) && - (strcmp(CFG_SYN_TARGET_TECH, "virtex2"))))) { - fprintf(fp, "\n\ + if ((CONFIG_SYN_INFER_RAM == false) && + (!((strcmp(CFG_SYN_TARGET_TECH, "virtex")) && (strcmp(CFG_SYN_TARGET_TECH, "virtex2"))))) { + fprintf(fp, "\n\ `define FPGA\n\ `define XILINX\n\ `define WBW_ADDR_LENGTH 7\n\ @@ -898,8 +958,9 @@ end;\n\ `define PCI_FIFO_RAM_ADDR_LENGTH 8 \n\ `define WB_FIFO_RAM_ADDR_LENGTH 8 \n\ "); - } else - fprintf(fp, "\n\ + } + else + fprintf(fp, "\n\ `define WB_RAM_DONT_SHARE\n\ `define PCI_RAM_DONT_SHARE\n\ `define WBW_ADDR_LENGTH %d\n\ @@ -908,10 +969,10 @@ end;\n\ `define PCIR_ADDR_LENGTH %d\n\ `define PCI_FIFO_RAM_ADDR_LENGTH %d \n\ `define WB_FIFO_RAM_ADDR_LENGTH %d \n\ -", CFG_PCI_FIFO, CFG_PCI_FIFO, CFG_PCI_FIFO, CFG_PCI_FIFO, - CFG_PCI_FIFO, CFG_PCI_FIFO); +", + CFG_PCI_FIFO, CFG_PCI_FIFO, CFG_PCI_FIFO, CFG_PCI_FIFO, CFG_PCI_FIFO, CFG_PCI_FIFO); - fprintf(fp, "\n\ + fprintf(fp, "\n\ `define ETH_WISHBONE_B3\n\ \n\ `define ETH_TX_FIFO_CNT_WIDTH %d\n\ @@ -922,10 +983,9 @@ end;\n\ \n\ `define ETH_BURST_CNT_WIDTH %d\n\ `define ETH_BURST_LENGTH %d\n", - log2(CONFIG_ETH_TXFIFO)+1, CONFIG_ETH_TXFIFO, - log2(CONFIG_ETH_RXFIFO)+1, CONFIG_ETH_RXFIFO, - log2(CONFIG_ETH_BURST)+1, CONFIG_ETH_BURST); + log2(CONFIG_ETH_TXFIFO) + 1, CONFIG_ETH_TXFIFO, log2(CONFIG_ETH_RXFIFO) + 1, + CONFIG_ETH_RXFIFO, log2(CONFIG_ETH_BURST) + 1, CONFIG_ETH_BURST); - close(fp); - return(0); + close(fp); + return (0); } diff --git a/utils/scripts/asic/pads_vh_loc.py b/utils/scripts/asic/pads_vh_loc.py index bad9d5399e..39e6fad39d 100755 --- a/utils/scripts/asic/pads_vh_loc.py +++ b/utils/scripts/asic/pads_vh_loc.py @@ -1,7 +1,8 @@ #!/usr/bin/python3 # This script taks the formatted list of pads' location (see utils/scripts/asic/reformat.sh) -# and generates a VHDL package containing constant bit vectors to be passed to the pad wrappers instances. +# and generates a VHDL package containing constant bit vectors to be +# passed to the pad wrappers instances. import os.path import glob @@ -37,9 +38,14 @@ for p in pads: if len(pads[p]) == 1: - fp.write(" constant " + p + "_pad_loc : std_logic := '" + str(pads[p][0]) + "';\n") + fp.write(" constant " + + p + + "_pad_loc : std_logic := '" + + str(pads[p][0]) + + "';\n") else: - s = " constant " + p + "_pad_loc : std_logic_vector(" + str(len(pads[p]) - 1) + " downto 0) := \"" + s = " constant " + p + \ + "_pad_loc : std_logic_vector(" + str(len(pads[p]) - 1) + " downto 0) := \"" pd = collections.OrderedDict(sorted(pads[p].items(), reverse=True)) for k in pd: s += str(pd[k]) diff --git a/utils/scripts/file_handling/bin2txt.py b/utils/scripts/file_handling/bin2txt.py index a901dd949d..ebb8955ee6 100755 --- a/utils/scripts/file_handling/bin2txt.py +++ b/utils/scripts/file_handling/bin2txt.py @@ -10,8 +10,20 @@ arch_bits = 32 -binfile = ["soft-build/" + cpu_arch + "/prom.bin", "soft-build/" + cpu_arch + "/systest.bin"] -txtfile = ["soft-build/" + cpu_arch + "/prom.txt", "soft-build/" + cpu_arch + "/systest.txt"] +binfile = [ + "soft-build/" + + cpu_arch + + "/prom.bin", + "soft-build/" + + cpu_arch + + "/systest.bin"] +txtfile = [ + "soft-build/" + + cpu_arch + + "/prom.txt", + "soft-build/" + + cpu_arch + + "/systest.txt"] for i in range(len(binfile)): @@ -26,6 +38,7 @@ print("Write text file " + txtfile[i]) with open(txtfile[i], "w") as f: - f.write(str(format(len(hexlist), 'x')).zfill(int(arch_bits / 4)) + '\n') + f.write(str(format(len(hexlist), 'x')).zfill( + int(arch_bits / 4)) + '\n') for word in hexlist: f.write(word.zfill(int(arch_bits / 4)) + '\n') diff --git a/utils/scripts/jtag_test/jtag_esplink.py b/utils/scripts/jtag_test/jtag_esplink.py index bb23d87318..ab2359bf52 100755 --- a/utils/scripts/jtag_test/jtag_esplink.py +++ b/utils/scripts/jtag_test/jtag_esplink.py @@ -15,169 +15,179 @@ line = fp.readline() -flag=1 -i=0 -err=0 -ex=0 -op=1 - -of=open("test_mismatches.txt",'w') -i=0 +flag = 1 +i = 0 +err = 0 +ex = 0 +op = 1 + +of = open("test_mismatches.txt", 'w') +i = 0 while line: - line.strip() - - i=i+1 - #convert to binary to split into 3 wr requests - end_length = (len(line)-1) * 4 - - hex_as_int = int(line, 16) - hex_as_binary = bin(hex_as_int) - flit = hex_as_binary[2:].zfill(end_length) - - if flit[-4:]=='0001': - source="100000" - plane=1 - addr1="0xC0010000" - addr2="0xC0010004" - addr3="0xC0010008" - addrr1="0xC0010100" - addrr2="0xC0010104" - addrr3="0xC0010108" - - elif flit[-4:]=='0010': - source="010000" - plane=2 - addr1="0xC0010010" - addr2="0xC0010014" - addr3="0xC0010018" - addrr1="0xC0010110" - addrr2="0xC0010114" - addrr3="0xC0010118" - - elif flit[-4:]=='0011': - source="001000" - plane=3 - addr1="0xC0010020" - addr2="0xC0010024" - addr3="0xC0010028" - addrr1="0xC0010120" - addrr2="0xC0010124" - addrr3="0xC0010128" - - elif flit[-4:]=='0100': - source="000100" - plane=4 - addr1="0xC0010030" - addr2="0xC0010034" - addr3="0xC0010038" - addrr1="0xC0010130" - addrr2="0xC0010134" - addrr3="0xC0010138" - - elif flit[-4:]=='0101': - source="000010" - plane=5 - addr1="0xC0010040" - addr2="0xC0010044" - addr3="0xC0010048" - addrr1="0xC0010140" - addrr2="0xC0010144" - addrr3="0xC0010148" - - elif flit[-4:]=='0110': - source="000001" - plane=6 - addr1="0xC0010050" - addr2="0xC0010054" - addr3="0xC0010058" - addrr1="0xC0010150" - addrr2="0xC0010154" - addrr3="0xC0010158" - - - zeros="" - testin1=zeros.zfill(21)+flit[2:13] - testin2=flit[13:45] - testin3=flit[45:68] + source + "0" + flit[71] + "1" - - expected=flit[:-8]+"0"+source - - #convert back to hexadecimal - dec1 = int(testin1, 2) - flit1 = hex(dec1) - - dec2 = int(testin2, 2) - flit2 = hex(dec2) - - dec3 = int(testin3, 2) - flit3 = hex(dec3) - - exp= hex(int(expected,2)) - - # write to apb2jtag registers - os.system('./socgen/esp/esplink-fpga-proxy --regw -a %s -d %s' % (addr1,flit1)) - os.system('./socgen/esp/esplink-fpga-proxy --regw -a %s -d %s' % (addr2,flit2)) - os.system('./socgen/esp/esplink-fpga-proxy --regw -a %s -d %s' % (addr3,flit3)) - - # print('./socgen/esp/esplink-fpga-proxy --regw -a '+addr1+' -d '+flit1) - # print('./socgen/esp/esplink-fpga-proxy --regw -a '+addr2+' -d '+flit2) - # print('./socgen/esp/esplink-fpga-proxy --regw -a '+addr3+' -d '+flit3) - - rsp="000000000000000000000000" - - # #read from jtag2apb registers - if (flit[71]=='0') : - ex=ex+1 - - a=os.popen('./socgen/esp/esplink-fpga-proxy --regr -a %s' %(addrr1)).read() - print(a) - a.strip() - atok= a.split() - b=os.popen('./socgen/esp/esplink-fpga-proxy --regr -a %s' %(addrr2)).read() - b.strip() - btok= b.split() - print(b) - c=os.popen('./socgen/esp/esplink-fpga-proxy --regr -a %s' %(addrr3)).read() - c.strip() - ctok= c.split() - print(c) - rsp=ctok[4]+btok[4]+atok[4] - - # if done==1: - # print(" Exiting at flit "+str(i)) - # break - - exp_rsp=exp[2:].zfill(24) - - print("\n Expected response: "+exp_rsp+"\n") - print(" Obtained response: "+rsp+"\n") - if rsp!=exp_rsp : - print(" *** MISMATCH ***") - - exp_rsp1=(str(hex(int(flit[:-8],2)))[2:]).zfill(17) - rsp1=(bin(int(rsp,16))[2:]).zfill(1) - if rsp1!="0" : - rsp1=rsp1[:-7] - - rsp1=hex(int(rsp1,2)) - rsp1=str(rsp1)[2:].zfill(17) - - if rsp1!=exp_rsp1 : - err = err+1 - of.write(str(i)+" :Mismatch plane:"+ str(plane)+" \n") - of.write("Expected response: "+exp_rsp1+"\n") - of.write("Obtained response: "+rsp1+"\n\n\n") - print("***MISMATCH***") - flag=0 - - line = fp.readline() - # time.sleep(1) - -if flag==1: - print("TEST PASSED !") + line.strip() + + i = i + 1 + # convert to binary to split into 3 wr requests + end_length = (len(line) - 1) * 4 + + hex_as_int = int(line, 16) + hex_as_binary = bin(hex_as_int) + flit = hex_as_binary[2:].zfill(end_length) + + if flit[-4:] == '0001': + source = "100000" + plane = 1 + addr1 = "0xC0010000" + addr2 = "0xC0010004" + addr3 = "0xC0010008" + addrr1 = "0xC0010100" + addrr2 = "0xC0010104" + addrr3 = "0xC0010108" + + elif flit[-4:] == '0010': + source = "010000" + plane = 2 + addr1 = "0xC0010010" + addr2 = "0xC0010014" + addr3 = "0xC0010018" + addrr1 = "0xC0010110" + addrr2 = "0xC0010114" + addrr3 = "0xC0010118" + + elif flit[-4:] == '0011': + source = "001000" + plane = 3 + addr1 = "0xC0010020" + addr2 = "0xC0010024" + addr3 = "0xC0010028" + addrr1 = "0xC0010120" + addrr2 = "0xC0010124" + addrr3 = "0xC0010128" + + elif flit[-4:] == '0100': + source = "000100" + plane = 4 + addr1 = "0xC0010030" + addr2 = "0xC0010034" + addr3 = "0xC0010038" + addrr1 = "0xC0010130" + addrr2 = "0xC0010134" + addrr3 = "0xC0010138" + + elif flit[-4:] == '0101': + source = "000010" + plane = 5 + addr1 = "0xC0010040" + addr2 = "0xC0010044" + addr3 = "0xC0010048" + addrr1 = "0xC0010140" + addrr2 = "0xC0010144" + addrr3 = "0xC0010148" + + elif flit[-4:] == '0110': + source = "000001" + plane = 6 + addr1 = "0xC0010050" + addr2 = "0xC0010054" + addr3 = "0xC0010058" + addrr1 = "0xC0010150" + addrr2 = "0xC0010154" + addrr3 = "0xC0010158" + + zeros = "" + testin1 = zeros.zfill(21) + flit[2:13] + testin2 = flit[13:45] + testin3 = flit[45:68] + source + "0" + flit[71] + "1" + + expected = flit[:-8] + "0" + source + + # convert back to hexadecimal + dec1 = int(testin1, 2) + flit1 = hex(dec1) + + dec2 = int(testin2, 2) + flit2 = hex(dec2) + + dec3 = int(testin3, 2) + flit3 = hex(dec3) + + exp = hex(int(expected, 2)) + + # write to apb2jtag registers + os.system( + './socgen/esp/esplink-fpga-proxy --regw -a %s -d %s' % + (addr1, flit1)) + os.system( + './socgen/esp/esplink-fpga-proxy --regw -a %s -d %s' % + (addr2, flit2)) + os.system( + './socgen/esp/esplink-fpga-proxy --regw -a %s -d %s' % + (addr3, flit3)) + + # print('./socgen/esp/esplink-fpga-proxy --regw -a '+addr1+' -d '+flit1) + # print('./socgen/esp/esplink-fpga-proxy --regw -a '+addr2+' -d '+flit2) + # print('./socgen/esp/esplink-fpga-proxy --regw -a '+addr3+' -d '+flit3) + + rsp = "000000000000000000000000" + + # #read from jtag2apb registers + if (flit[71] == '0'): + ex = ex + 1 + + a = os.popen( + './socgen/esp/esplink-fpga-proxy --regr -a %s' % + (addrr1)).read() + print(a) + a.strip() + atok = a.split() + b = os.popen( + './socgen/esp/esplink-fpga-proxy --regr -a %s' % + (addrr2)).read() + b.strip() + btok = b.split() + print(b) + c = os.popen( + './socgen/esp/esplink-fpga-proxy --regr -a %s' % + (addrr3)).read() + c.strip() + ctok = c.split() + print(c) + rsp = ctok[4] + btok[4] + atok[4] + + # if done==1: + # print(" Exiting at flit "+str(i)) + # break + + exp_rsp = exp[2:].zfill(24) + + print("\n Expected response: " + exp_rsp + "\n") + print(" Obtained response: " + rsp + "\n") + if rsp != exp_rsp: + print(" *** MISMATCH ***") + + exp_rsp1 = (str(hex(int(flit[:-8], 2)))[2:]).zfill(17) + rsp1 = (bin(int(rsp, 16))[2:]).zfill(1) + if rsp1 != "0": + rsp1 = rsp1[:-7] + + rsp1 = hex(int(rsp1, 2)) + rsp1 = str(rsp1)[2:].zfill(17) + + if rsp1 != exp_rsp1: + err = err + 1 + of.write(str(i) + " :Mismatch plane:" + str(plane) + " \n") + of.write("Expected response: " + exp_rsp1 + "\n") + of.write("Obtained response: " + rsp1 + "\n\n\n") + print("***MISMATCH***") + flag = 0 + + line = fp.readline() + # time.sleep(1) + +if flag == 1: + print("TEST PASSED !") else: - print("TEST FAILED with "+ str(err) +"mismatches out of "+ str(i)) + print("TEST FAILED with " + str(err) + "mismatches out of " + str(i)) fp.close() - diff --git a/utils/scripts/srec/modify_srec.py b/utils/scripts/srec/modify_srec.py index 432957d18b..be6e701ad0 100644 --- a/utils/scripts/srec/modify_srec.py +++ b/utils/scripts/srec/modify_srec.py @@ -3,12 +3,14 @@ from math import ceil if len(sys.argv) < 4 or len(sys.argv) % 2 == 1: - print("usage: python3 modify_srec.py infile.srec data_file1 [data_file2] ... start_address1 [start_address2] ...") + print( + "usage: python3 modify_srec.py infile.srec data_file1 [data_file2] ... start_address1 [start_address2] ...") exit() srec_path = sys.argv[1] srec_file = open(srec_path, "a") + def calc_checksum(count, address, data): total = 0 total += count @@ -16,12 +18,13 @@ def calc_checksum(count, address, data): total += address & 0xFF address >>= 8 for i in range(16): - total += int(data[i*2:i*2 + 2], 16) + total += int(data[i * 2:i * 2 + 2], 16) return total & 0xFF + for k in range(int((len(sys.argv) - 2) / 2)): - data_path = sys.argv[k+2] - start_addr = int(sys.argv[2+int((len(sys.argv)-2) / 2) + k], 0) + data_path = sys.argv[k + 2] + start_addr = int(sys.argv[2 + int((len(sys.argv) - 2) / 2) + k], 0) if data_path[-3:] == "txt": data_file = open(data_path, "r") @@ -59,7 +62,8 @@ def calc_checksum(count, address, data): if k >= len(data) / 4: word = "0" else: - word = str(hex(int.from_bytes(data[k*4:k*4+4], byteorder='big', signed=False))[2:]) + word = str( + hex(int.from_bytes(data[k * 4:k * 4 + 4], byteorder='big', signed=False))[2:]) string += word.zfill(8) if i == 3: