aboutsummaryrefslogtreecommitdiff
path: root/recipes-demo/de10-nano-fftsw-apps/files/overhead.c
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-demo/de10-nano-fftsw-apps/files/overhead.c')
-rw-r--r--recipes-demo/de10-nano-fftsw-apps/files/overhead.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/recipes-demo/de10-nano-fftsw-apps/files/overhead.c b/recipes-demo/de10-nano-fftsw-apps/files/overhead.c
new file mode 100644
index 0000000..fbb7ab4
--- /dev/null
+++ b/recipes-demo/de10-nano-fftsw-apps/files/overhead.c
@@ -0,0 +1,219 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <error.h>
+#include <errno.h>
+
+#include "NE10.h"
+
+/*
+ * PERIPHBASE and Global Timer offset
+ */
+#define PERIPHBASE (0xFFFEC000)
+#define GLOBAL_TIMER_OFFSET (0x200)
+
+extern const char *g_test;
+extern const char *g_description;
+
+int g_mpuclk_rate;
+int g_mpu_periph_clk_rate;
+int g_fft_sub_clk_0_clk_rate;
+char *g_input_filename = NULL;
+char *g_output_filename = NULL;
+int g_devmem_fd;
+void *g_periphbase_map;
+uint32_t g_gt_samples_ave;
+volatile uint32_t *g_global_timer_ptr;
+uint64_t g_start_time;
+uint64_t g_end_time;
+
+void print_usage(char **argv)
+{
+ error(0, 0, " ");
+ error(0, 0, "USAGE: %s --input=<input file> --output=<output file>", argv[0]);
+ error(1, 0, " ");
+}
+
+uint64_t get_gt_value(void)
+{
+ uint32_t gt_lo;
+ uint32_t gt_hi_0;
+ uint32_t gt_hi_1;
+ uint64_t gt_value;
+
+ do {
+ gt_hi_0 = g_global_timer_ptr[1];
+ gt_lo = g_global_timer_ptr[0];
+ gt_hi_1 = g_global_timer_ptr[1];
+
+ } while(gt_hi_0 != gt_hi_1);
+
+ gt_value = ((uint64_t)gt_hi_0 << 32) | ((uint64_t)gt_lo & (uint64_t)0xFFFFFFFF);
+
+ return gt_value;
+}
+
+void initialize_everything(int argc, char **argv)
+{
+ int i;
+ int fd;
+ int result;
+ long periph_size;
+ char in_str[16];
+ const char *input_option_str = "--input=";
+ const char *output_option_str = "--output=";
+ int input_option_str_len = strlen(input_option_str);
+ int output_option_str_len = strlen(output_option_str);
+ uint64_t gt_samples[10];
+ uint64_t gt_samples_sum;
+ ne10_result_t status;
+
+ /* validate input arguments */
+ if (argc != 3)
+ print_usage(argv);
+
+ if(strncmp(input_option_str, argv[1], input_option_str_len) == 0) {
+ g_input_filename = argv[1] + input_option_str_len;
+
+ if(strncmp(output_option_str, argv[2], output_option_str_len) == 0) {
+ g_output_filename = argv[2] + output_option_str_len;
+ } else {
+ error(0, 0, " ");
+ error(0, 0, "ERROR: no --output option found on command line");
+ print_usage(argv);
+ }
+ } else {
+ if(strncmp(input_option_str, argv[2], input_option_str_len) == 0) {
+ g_input_filename = argv[2] + input_option_str_len;
+
+ if(strncmp(output_option_str, argv[1], output_option_str_len) == 0) {
+ g_output_filename = argv[1] + output_option_str_len;
+ } else {
+ error(0, 0, " ");
+ error(0, 0, "ERROR: no --output option found on command line");
+ print_usage(argv);
+ }
+ } else {
+ error(0, 0, " ");
+ error(0, 0, "ERROR: no --input option found on command line");
+ print_usage(argv);
+ }
+ }
+
+ /* initialize the NE10 NEON library */
+ status = ne10_init();
+ if (status != NE10_OK)
+ error(1, 0, "NE10 init failed.");
+
+ status = ne10_HasNEON();
+ if (status != NE10_OK)
+ error(1, 0, "NEON is not available.");
+
+ /* gather system info */
+ fd = open("/sys/kernel/debug/clk/mpuclk/clk_rate", O_RDONLY);
+ if(fd < 0)
+ error(1, errno, "opening sysfs mpuclk/clk_rate");
+
+ result = read(fd, in_str, 16);
+ if (result < 0)
+ error(1, errno, "reading sysfs mpuclk/clk_rate");
+
+ close(fd);
+ g_mpuclk_rate = atoi(in_str);
+
+ fd = open("/sys/kernel/debug/clk/mpu_periph_clk/clk_rate", O_RDONLY);
+ if(fd < 0)
+ error(1, errno, "opening sysfs mpu_periph_clk/clk_rate");
+
+ result = read(fd, in_str, 16);
+ if (result < 0)
+ error(1, errno, "reading sysfs mpu_periph_clk/clk_rate");
+
+ close(fd);
+ g_mpu_periph_clk_rate = atoi(in_str);
+
+ fd = open("/sys/firmware/devicetree/base/soc/base-fpga-region/fft_sub_clk_0/clock-frequency", O_RDONLY);
+ if(fd < 0)
+ error(1, errno, "opening sysfs fft_sub_clk_0/clock-frequency");
+
+ result = read(fd, in_str, 16);
+ if (result < 0)
+ error(1, errno, "reading sysfs fft_sub_clk_0/clock-frequency");
+
+ close(fd);
+ g_fft_sub_clk_0_clk_rate = atoi(in_str);
+
+ /* open the /dev/mem device */
+ g_devmem_fd = open("/dev/mem", O_RDWR | O_SYNC);
+ if(g_devmem_fd < 0)
+ error(1, errno, "open /dev/mem");
+
+ /* mmap periphbase */
+ periph_size = sysconf(_SC_PAGE_SIZE);
+ if(periph_size >= 0) {
+ g_periphbase_map = mmap(NULL, periph_size, PROT_READ|PROT_WRITE, MAP_SHARED, g_devmem_fd, PERIPHBASE);
+ if(g_periphbase_map == MAP_FAILED)
+ error(1, errno, "mmap /dev/mem");
+ }
+ else
+ error(1, errno, "mmap /dev/mem");
+
+ /* calculate global timer pointer */
+ g_global_timer_ptr = (uint32_t*)((uint32_t)g_periphbase_map + GLOBAL_TIMER_OFFSET);
+
+ /* calibrate get_gt_value */
+ gt_samples[0] = get_gt_value();
+ gt_samples[1] = get_gt_value();
+ gt_samples[2] = get_gt_value();
+ gt_samples[3] = get_gt_value();
+ gt_samples[4] = get_gt_value();
+ gt_samples[5] = get_gt_value();
+ gt_samples[6] = get_gt_value();
+ gt_samples[7] = get_gt_value();
+ gt_samples[8] = get_gt_value();
+ gt_samples[9] = get_gt_value();
+
+ gt_samples_sum = 0;
+ for(i = 0 ; i < 9 ; i++) {
+ gt_samples_sum += gt_samples[i + 1] - gt_samples[i];
+ }
+ g_gt_samples_ave = gt_samples_sum / 9;
+}
+
+void release_everything(void)
+{
+ int result = 0;
+ long periph_size;
+
+ periph_size = sysconf(_SC_PAGE_SIZE);
+
+ /* munmap and close /dev/mem */
+ if(periph_size >= 0)
+ result = munmap(g_periphbase_map, periph_size);
+ if((result < 0) | (periph_size < 0))
+ error(1, errno, "munmap /dev/mem");
+
+ close(g_devmem_fd);
+}
+
+void print_results(void)
+{
+ uint32_t tick_count = (g_end_time - g_start_time) - g_gt_samples_ave;
+ float sec_time = ((float)1 / (float)g_mpu_periph_clk_rate) * (float)tick_count;
+ float us_time = sec_time * 1000000;
+
+ printf(" Test: %s\n", g_test);
+ printf(" Description: %s\n", g_description);
+ printf(" Input file: '%s'\n", g_input_filename);
+ printf(" Output file: '%s'\n", g_output_filename);
+ printf(" CPU Frequency: %d hertz\n", g_mpuclk_rate);
+ printf(" GT Frequency: %d hertz\n", g_mpu_periph_clk_rate);
+ printf(" FPGA FFT Frequency: %d hertz\n", g_fft_sub_clk_0_clk_rate);
+ printf("Computation (GT ticks): %d\n", tick_count);
+ printf(" Computation (us): %f\n", us_time);
+}
+