mmserv

Minimum Mean Square Error detection on RISC-V Vector Extention
git clone https://git.ea.contact/mmserv
Log | Files | Refs | README

main.c (4776B)


      1 #include "include/common.h"
      2 
      3 #include <stddef.h> /* for size_t */
      4 
      5 
      6 /*
      7  * Defines
      8  */
      9 
     10 /* Got from https://elm-chan.org/junk/32bit/binclude.html */
     11 /* Import a binary file */
     12 #define IMPORT_BIN(sect, file, sym) __asm__ (\
     13     ".section " #sect "\n"                  /* Change section */\
     14     ".balign 4\n"                           /* Word alignment */\
     15     ".global " #sym "\n"                    /* Export the object address */\
     16     #sym ":\n"                              /* Define the object label */\
     17     ".incbin \"" file "\"\n"                /* Import the file */\
     18     ".global _sizeof_" #sym "\n"            /* Export the object size */\
     19     ".set _sizeof_" #sym ", . - " #sym "\n" /* Define the object size */\
     20     ".balign 4\n"                           /* Word alignment */\
     21     ".section \".text\"\n")                 /* Restore section */
     22 
     23 
     24 /*
     25  * Global variables
     26  */
     27 
     28 /* Import data from binary files */
     29 IMPORT_BIN(.rodata, "data/x_re.bin", x_re);
     30 IMPORT_BIN(.rodata, "data/x_im.bin", x_im);
     31 IMPORT_BIN(.rodata, "data/H_re.bin", H_re);
     32 IMPORT_BIN(.rodata, "data/H_im.bin", H_im);
     33 IMPORT_BIN(.rodata, "data/R_re.bin", R_re);
     34 IMPORT_BIN(.rodata, "data/R_im.bin", R_im);
     35 IMPORT_BIN(.rodata, "data/y_re.bin", y_re);
     36 IMPORT_BIN(.rodata, "data/y_im.bin", y_im);
     37 
     38 /* Allocate space for MMSE raw data */
     39 data_t G_re[NUM_TX * NUM_TX * NUM_SC];
     40 data_t G_im[NUM_TX * NUM_TX * NUM_SC];
     41 data_t L_re[NUM_TX * NUM_TX * NUM_SC];
     42 data_t L_im[NUM_TX * NUM_TX * NUM_SC];
     43 data_t g_D[NUM_TX * NUM_SC]; /* no imaginary part in D */
     44 data_t HHy_re[NUM_TX * NUM_SC];
     45 data_t HHy_im[NUM_TX * NUM_SC];
     46 data_t z_re[NUM_TX * NUM_SC];
     47 data_t z_im[NUM_TX * NUM_SC];
     48 data_t x_MMSE_re[NUM_TX * NUM_SC];
     49 data_t x_MMSE_im[NUM_TX * NUM_SC];
     50 
     51 /* Initialize data */
     52 vcomplex g_x = { .re = (data_t *)x_re, .im = (data_t *)x_im };
     53 vcomplex g_H = { .re = (data_t *)H_re, .im = (data_t *)H_im };
     54 vcomplex g_R = { .re = (data_t *)R_re, .im = (data_t *)R_im };
     55 vcomplex g_y = { .re = (data_t *)y_re, .im = (data_t *)y_im };
     56 vcomplex g_G = { .re = (data_t *)G_re, .im = (data_t *)G_im };
     57 vcomplex g_L = { .re = (data_t *)L_re, .im = (data_t *)L_im };
     58 vcomplex g_HHy = { .re = (data_t *)HHy_re, .im = (data_t *)HHy_im };
     59 vcomplex g_z = { .re = (data_t *)z_re, .im = (data_t *)z_im };
     60 vcomplex g_x_MMSE = { .re = (data_t *)x_MMSE_re, .im = (data_t *)x_MMSE_im };
     61 
     62 
     63 /*
     64  * Read cycles macro and function
     65  */
     66 
     67 /** Read and return the cycle counter value */
     68 uint64_t readcycle() {
     69 #if defined(ARCH_rvv) || defined(ARCH_rv)
     70   uint64_t val;
     71   __asm__ volatile("rdcycle %0" : "=r"(val));
     72   return val;
     73 #elif defined(ARCH_x86)
     74   unsigned int hi, lo;
     75   __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
     76   return ((uint64_t)hi << 32) | lo;
     77 #else
     78 #error "Unknown architecture"
     79 #endif
     80 }
     81 
     82 /** Read cycles for a function call and store the result in out */
     83 #define FUNC_CYCLES(func, out) \
     84   do { \
     85     uint64_t start = readcycle(); \
     86     func; \
     87     uint64_t end = readcycle(); \
     88     out = end - start; \
     89   } while (0)
     90 
     91 
     92 /*
     93  * Printf function
     94  */
     95 
     96 #if defined(PLATFORM_ara)
     97 #include "../../common/printf.h"
     98 
     99 #elif defined(PLATFORM_linux)
    100 #include <stdio.h>
    101 
    102 #elif defined(PLATFORM_baremetal)
    103 #include <common.h> /* This is U-Boot's common.h, not our "include/common.h" */
    104 #include <asm/io.h>
    105 
    106 /* UART registers for SpacemiT K1 */
    107 #define UART_BASE       0x1510000000ULL
    108 #define UART_THR        (UART_BASE + 0x00)  /* Transmit Holding Register */
    109 #define UART_LSR        (UART_BASE + 0x14)  /* Line Status Register */
    110 #define UART_LSR_THRE   (1 << 5)            /* Transmit Holding Register Empty */
    111 
    112 static void uart_putc(char c) {
    113     while (!(readl(UART_LSR) & UART_LSR_THRE)); /* Wait for THR empty */
    114     writel(c, UART_THR);
    115 }
    116 static void print_ulong(unsigned long num) {
    117     char buf[20];
    118     int i = 0;
    119     if (num == 0) {
    120         uart_putc('0');
    121         return;
    122     }
    123     while (num > 0) {
    124         buf[i++] = (num % 10) + '0';
    125         num /= 10;
    126     }
    127     while (i > 0) {
    128         uart_putc(buf[--i]);
    129     }
    130 }
    131 /* U-Boot printf for %lu,%lu,%lu,%lu,%lu, */
    132 void printf(const char *fmt, unsigned long t1, unsigned long t2, unsigned long t3,
    133             unsigned long t4, unsigned long t5) {
    134     if (strcmp(fmt, "%lu,%lu,%lu,%lu,%lu,") != 0)
    135         return;
    136     print_ulong(t1);
    137     uart_putc(',');
    138     print_ulong(t2);
    139     uart_putc(',');
    140     print_ulong(t3);
    141     uart_putc(',');
    142     print_ulong(t4);
    143     uart_putc(',');
    144     print_ulong(t5);
    145     uart_putc(',');
    146 }
    147 
    148 #else
    149 #error "Unknown platform"
    150 #endif
    151 
    152 
    153 /*
    154  * Main
    155  */
    156 
    157 int main() {
    158   uint64_t start, end;
    159   uint64_t t1,t2,t3,t4,t5;
    160 
    161   FUNC_CYCLES(cmatgram(), t1);
    162   FUNC_CYCLES(ccholesky(), t2);
    163   FUNC_CYCLES(cmatvecmul(), t3);
    164   FUNC_CYCLES(cforwardsub(), t4);
    165   FUNC_CYCLES(cbackwardsub(), t5);
    166   printf("%lu,%lu,%lu,%lu,%lu,", t1, t2, t3, t4, t5);
    167 
    168   return 0;
    169 }