⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 nios中自定义指令集实现三角函数的软件部分。
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
  This application requires stdout only.
*/
/*
These are the possible C flags that you may wish to compile with, if you have
the appropriate hardware for these instructions.  The opcode values shown are
the default opcode offset from the opcode base of the SPDP Floating Point
instructions.  If your instruction isn't based at ZERO, then you must alter
these values.

Required for Double Precision:

-mcustom-fwrx=0xF
-mcustom-fwry=0xE
-mcustom-frdxlo=0xC
-mcustom-frdxhi=0xD
-mcustom-frdy=0xB
-mcustom-faddd=0xA
-mcustom-fsubd=0x9
-mcustom-fmuld=0x8
-mcustom-fdivd=0x7

Required for Single Precision:

-mcustom-fadds=0x6
-mcustom-fsubs=0x5
-mcustom-fmuls=0x4
-mcustom-fdivs=0x3

This is what these things do:

double none write X none -mcustom-fwrx=N nios2_fwrx 
float none write Y none -mcustom-fwry=N nios2_fwry 
none none read low half of X float -mcustom-frdxlo=N nios2_frdxlo 
none none read high half of X float -mcustom-frdxhi=N nios2_frdxhi 
none none read Y float -mcustom-frdy=N nios2_frdy 

double double + double -mcustom-faddd=N __adddf3 
double double - double -mcustom-fsubd=N __subdf3 
double double * double -mcustom-fmuld=N __muldf3 
double double / double -mcustom-fdivd=N __divdf3 

single single + single -mcustom-fadds=N __addsf3 
single single - single -mcustom-fsubs=N __subsf3 
single single * single -mcustom-fmuls=N __mulsf3 
single single / single -mcustom-fdivs=N __divsf3 

*/

/*
casting and comparison compiler flags

-mcustom-ftruncds=0x1B
-mcustom-fextsd=0x1A
-mcustom-fixdu=0x19
-mcustom-fixdi=0x18
-mcustom-floatud=0x17
-mcustom-floatid=0x16
-mcustom-fcmpned=0x15
-mcustom-fcmpeqd=0x14
-mcustom-fcmpged=0x13
-mcustom-fcmpgtd=0x12
-mcustom-fcmpled=0x11
-mcustom-fcmpltd=0x10

*/

// These pragmas will prevent the custom instruction opcode from being used in
// this source file it forces the software libraries to be called instead.
#pragma no_custom_faddd
#pragma no_custom_fsubd
#pragma no_custom_fmuld
#pragma no_custom_fdivd
#pragma no_custom_fadds
#pragma no_custom_fsubs
#pragma no_custom_fmuls
#pragma no_custom_fdivs
#pragma no_custom_ftruncds
#pragma no_custom_fextsd
#pragma no_custom_fixdu
#pragma no_custom_fixdi
#pragma no_custom_floatud
#pragma no_custom_floatid
#pragma no_custom_fcmpned
#pragma no_custom_fcmpeqd
#pragma no_custom_fcmpged
#pragma no_custom_fcmpgtd
#pragma no_custom_fcmpled
#pragma no_custom_fcmpltd

// These macros select various tests to compile into the application
#define DOUBLE_TESTS
#define SINGLE_TESTS

//#define EXPONENT_SWEEP_TEST
//#define MANTISSA_SWEEP_TEST
//#define SINGLE_BIT_SWEEP_TEST
#define RANDOM_ARRAY_TEST
#define SPECIAL_NUMBERS_TEST

#define ADD_TEST
#define SUB_TEST
#define MUL_TEST
#define DIV_TEST
#define NON_ARITHMETIC_TEST

// Include files for the application.
#include <stdio.h>
#include "io.h"
#include "alt_types.h"
#include "system.h"
#include "dpfp_test.h"
#include "float.h"
#include "math.h"

// Simple compile time check for the presence of the custom instruction.
//#ifndef __SP_DP_FLOATING_POINT
//#error "This code requires the SP_DP_FLOATING_POINT custom instructions."
//#endif

// Externally defined sub routines.
extern double dpfp_hw_addition(double a, double b);
extern double dpfp_hw_subtraction(double a, double b);
extern double dpfp_hw_multiplication(double a, double b);
extern double dpfp_hw_division(double a, double b);
extern float spfp_hw_addition(float a, float b);
extern float spfp_hw_subtraction(float a, float b);
extern float spfp_hw_multiplication(float a, float b);
extern float spfp_hw_division(float a, float b);
extern float double_to_float(double x);
extern double float_to_double(float x);
extern int double_agtb(double a, double b);
extern int double_altb(double a, double b);
extern int double_ageb(double a, double b);
extern int double_aleb(double a, double b);
extern int double_aeqb(double a, double b);
extern int double_aneb(double a, double b);
extern double uint_to_double(unsigned int x);
extern double int_to_double(int x);
extern int double_to_int(double x);
extern unsigned int double_to_uint(double x);

// this macro accesses the ID register built into the custom instruction
#define ALT_CI_SPDP_FPOINT1_N 0x00000000
#define ALT_CI_SPDP_FPOINT1_N_MASK ((1<<4)-1)
#define ALT_CI_SPDP_FPOINT1(n,A,B) __builtin_custom_inii(ALT_CI_SPDP_FPOINT1_N+(n&ALT_CI_SPDP_FPOINT1_N_MASK),(A),(B))

int main()
{  
  printf("\nFloating Point Test Suite...\n\n");

  int i;

  unsigned long sig_test;
  
  sig_test = ALT_CI_SPDP_FPOINT1(0,0,0);
  printf("Custom Instruction signature = 0x%08lX\n", sig_test);
  
  for(i=0;i<1000;i++)
  {
    negated_double_array[(i*2)] = my_double_test_array[(i*2)];
    negated_double_array[(i*2) + 1] = my_double_test_array[(i*2) + 1] ^ 0x80000000;

    negated_single_array[i] = my_single_test_array[i] ^ 0x80000000;
  }
    
  volatile double double_result;
  volatile unsigned long *my_long_ptr_to_double_result;
  volatile double double_operand_a;
  volatile unsigned long *my_long_ptr_to_double_operand_a;
  volatile double double_operand_b;
  volatile unsigned long *my_long_ptr_to_double_operand_b;

  volatile float float_result;
  volatile unsigned long *my_long_ptr_to_float_result;
  volatile float float_operand_a;
  volatile unsigned long *my_long_ptr_to_float_operand_a;
  volatile float float_operand_b;
  volatile unsigned long *my_long_ptr_to_float_operand_b;

  unsigned long sweep_index_a;
  unsigned long sweep_index_b;
  
  unsigned long cusp_result_lo;
  unsigned long cusp_result_hi;
  
  unsigned long calc_result_lo;
  unsigned long calc_result_hi;
  
  unsigned long mantissa_a_lo;
  unsigned long mantissa_a_hi;
  unsigned long exponent_a;
  unsigned long sign_a;
  
  unsigned long mantissa_b_lo;
  unsigned long mantissa_b_hi;
  unsigned long exponent_b;
  unsigned long sign_b;

  int denormal_result = 0;
  int round_off_by_one = 0;
  int count_correct = 0;
  int count_incorrect = 0;
  int j;
  
  j = 0;
  
  my_long_ptr_to_double_result = (unsigned long *)&double_result;
  my_long_ptr_to_double_operand_a = (unsigned long *)&double_operand_a;
  my_long_ptr_to_double_operand_b = (unsigned long *)&double_operand_b;

  my_long_ptr_to_float_result = (unsigned long *)&float_result;
  my_long_ptr_to_float_operand_a = (unsigned long *)&float_operand_a;
  my_long_ptr_to_float_operand_b = (unsigned long *)&float_operand_b;

#ifdef SINGLE_TESTS
#ifdef RANDOM_ARRAY_TEST
// full random array test
#ifdef ADD_TEST
    // addition
    count_correct = 0;
    count_incorrect = 0;
    denormal_result = 0;
    round_off_by_one = 0;

    printf("\nSingle Precision Random Array Addition Test...\n\n");
    for( j = 0 ; j < SINGLE_TEST_ARRAY_SIZE_IN_FLOATS ; j++)
    {
      for( i = 0 ; i < SINGLE_TEST_ARRAY_SIZE_IN_FLOATS ; i++)
      {
        *(my_long_ptr_to_float_operand_a) = my_single_test_array[(j)];
        *(my_long_ptr_to_float_operand_b) = negated_single_array[(i)];
        
        float_result = float_operand_a + float_operand_b;
  
        calc_result_array[(i)] = *(my_long_ptr_to_float_result);
        
        float_result = spfp_hw_addition(float_operand_a, float_operand_b);
        
        cusp_result_array[(i)] = *(my_long_ptr_to_float_result);
  
//        if((cusp_result_array[(i*2)] == calc_result_array[(i*2)]) && (cusp_result_array[(i*2)+1] == calc_result_array[(i*2)+1]))
//        {
//          printf("%d - 0x%08lX %08lX - 0x%08lX %08lX C\n", i, cusp_result_array[(i*2) + 1], cusp_result_array[(i*2)], calc_result_array[(i*2) + 1], calc_result_array[(i*2)]);
//        }
//        else
//        {
//          printf("%d - 0x%08lX %08lX - 0x%08lX %08lX I\n", i, cusp_result_array[(i*2) + 1], cusp_result_array[(i*2)], calc_result_array[(i*2) + 1], calc_result_array[(i*2)]);
//        }
  
      }
      
      for( i = 0 ; i < SINGLE_TEST_ARRAY_SIZE_IN_FLOATS ; i++)
      {
        if((cusp_result_array[(i)] == calc_result_array[(i)]))
        {
          //printf("j=%d i=%d - 0x%08lX %08lX - 0x%08lX %08lX C\n", j, i, cusp_result_array[(i*2) + 1], cusp_result_array[(i*2)], calc_result_array[(i*2) + 1], calc_result_array[(i*2)]);
          count_correct++;
        }
        else
        {
          if(((cusp_result_array[i] & 0xFF800000) == (calc_result_array[i] & 0xFF800000)) && ((cusp_result_array[i] & 0x7F800000) == 0x0))
          {
            //printf("denormal j=%d i=%d - 0x%08lX %08lX - 0x%08lX %08lX I\n", j, i, cusp_result_array[(i*2) + 1], cusp_result_array[(i*2)], calc_result_array[(i*2) + 1], calc_result_array[(i*2)]);
            denormal_result++;
            count_correct++;
          }
          else if(((cusp_result_array[i] - calc_result_array[i]) == 1) || ((calc_result_array[i] - cusp_result_array[i]) == 1))
          {
            //printf("lsb only j=%d i=%d - 0x%08lX %08lX - 0x%08lX %08lX I\n", j, i, cusp_result_array[(i*2) + 1], cusp_result_array[(i*2)], calc_result_array[(i*2) + 1], calc_result_array[(i*2)]);
            round_off_by_one++;
            count_correct++;
          }
          else
          {
            printf("j=%d i=%d - 0x%08lX - 0x%08lX I\n", j, i, cusp_result_array[i], calc_result_array[i]);
            count_incorrect++;
          }
        }
      }
    }

    printf("Correct = %d\n", count_correct);
    printf("Incorrect = %d\n", count_incorrect);
    printf("Denormal Result = %d\n", denormal_result);
    printf("Round off by one = %d\n", round_off_by_one);
#endif //ADD_TEST
#ifdef SUB_TEST
    // Subtraction
    count_correct = 0;
    count_incorrect = 0;
    denormal_result = 0;
    round_off_by_one = 0;

    printf("\nSingle Precision Random Array Subtraction Test...\n\n");
    for( j = 0 ; j < SINGLE_TEST_ARRAY_SIZE_IN_FLOATS ; j++)
    {
      for( i = 0 ; i < SINGLE_TEST_ARRAY_SIZE_IN_FLOATS ; i++)
      {
        *(my_long_ptr_to_float_operand_a) = my_single_test_array[(j)];
        *(my_long_ptr_to_float_operand_b) = negated_single_array[(i)];
        
        float_result = float_operand_a - float_operand_b;
  
        calc_result_array[(i)] = *(my_long_ptr_to_float_result);
        
        float_result = spfp_hw_subtraction(float_operand_a, float_operand_b);
        
        cusp_result_array[(i)] = *(my_long_ptr_to_float_result);
  
//        if((cusp_result_array[(i*2)] == calc_result_array[(i*2)]) && (cusp_result_array[(i*2)+1] == calc_result_array[(i*2)+1]))
//        {
//          printf("%d - 0x%08lX %08lX - 0x%08lX %08lX C\n", i, cusp_result_array[(i*2) + 1], cusp_result_array[(i*2)], calc_result_array[(i*2) + 1], calc_result_array[(i*2)]);
//        }
//        else
//        {
//          printf("%d - 0x%08lX %08lX - 0x%08lX %08lX I\n", i, cusp_result_array[(i*2) + 1], cusp_result_array[(i*2)], calc_result_array[(i*2) + 1], calc_result_array[(i*2)]);
//        }
  
      }
      
      for( i = 0 ; i < SINGLE_TEST_ARRAY_SIZE_IN_FLOATS ; i++)
      {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -