blob: c5e68329da74665bd3444f9b4109305323ca806e [file] [log] [blame]
//////////////////////////////////////////////////////////////////////////////
// SPDX-FileCopyrightText: 2021, Dinesh Annayya
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
// //////////////////////////////////////////////////////////////////////////
#define SC_SIM_OUTPORT (0xf0000000)
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "int_reg_map.h"
#include "common_misc.h"
#include "common_bthread.h"
#define CMD_FPU_SP_ADD 0x1 // Single Precision (32 bit) Adder
#define CMD_FPU_SP_MUL 0x2 // Single Precision (32 bit) Multipler
#define CMD_FPU_SP_DIV 0x3 // Single Precision (32 bit) Divider
#define CMD_FPU_SP_F2I 0x4 // Single Precision (32 bit) Float to Integer
#define CMD_FPU_SP_I2F 0x5 // Single Precision (32 bit) Integer to Float
#define CMD_FPU_DP_ADD 0x9 // Double Precision (64 bit) Adder
#define CMD_FPU_DP_MUL 0xA // Double Precision (64 bit) Multipler
#define CMD_FPU_DP_DIV 0xB // Double Precision (64 bit) Divider
int fpu_check(uint8_t Cmd, uint32_t Din1, uint32_t Din2, uint32_t Result);
int main(void)
{
int exit;
//printf("\nTesting FPU CORE LOGIC\n\n");
reg_glbl_cfg0 |= 0x1F; // Remove Reset for UART
reg_glbl_multi_func &=0x7FFFFFFF; // Disable UART Master Bit[31] = 0
reg_glbl_multi_func |=0x100; // Enable UART Multi func
reg_gpio_dsel =0xFF00; // Enable PORT B As output
reg_uart0_ctrl = 0x07; // Enable Uart Access {3'h0,2'b00,1'b1,1'b1,1'b1}
//// GLBL_CFG_MAIL_BOX used as mail box, each core update boot up handshake at 8 bit
//// bit[7:0] - core-0
//// bit[15:8] - core-1
//// bit[23:16] - core-2
//// bit[31:24] - core-3
reg_glbl_mail_box = 0x1 << (bthread_get_core_id() * 8); // Start of Main
reg_gpio_odata = 0x00000100;
reg_glbl_soft_reg_0 = 0x00000000;
//--------------------------------------
// Floating Point Addition
//--------------------------------------
// TEST-1: Addition: Din1: 0.500000 Din2: 1.500000 Res: 2.000000
exit = fpu_check(CMD_FPU_SP_ADD,0x3f000000,0x3fc00000,0x40000000);
reg_glbl_soft_reg_0 = exit;
// TEST-2: Addition: Din1: 0.500000 Din2: 1.250000 Res: 1.750000
exit += fpu_check(CMD_FPU_SP_ADD,0x3f000000,0x3fa00000,0x3fe00000);
reg_glbl_soft_reg_0 = exit;
// TEST-3: Addition: Din1: 0.500000 Din2: 0.250000 Res: 0.750000
exit += fpu_check(CMD_FPU_SP_ADD,0x3f000000,0x3e800000,0x3f400000);
reg_glbl_soft_reg_0 = exit;
// TEST-4: Addition: Din1: 2.000000 Din2: -2.000000 Res: 0.000000
exit += fpu_check(CMD_FPU_SP_ADD,0x40000000,0xc0000000,0x00000000);
reg_glbl_soft_reg_0 = exit;
// TEST-5: Addition: Din1: -0.000000 Din2: 0.000000 Res: 0.000000
exit += fpu_check(CMD_FPU_SP_ADD,0x83e73d5c,0x1c800000,0x1c800000);
reg_glbl_soft_reg_0 = exit;
// TEST-6: Addition: Din1: -1.211871 Din2: -2.889479 Res: -4.101350
exit += fpu_check(CMD_FPU_SP_ADD,0xbf9b1e94,0xc038ed3a,0xc0833e42);
reg_glbl_soft_reg_0 = exit;
//--------------------------------------
// Floating Point Multiplication
//--------------------------------------
// TEST-1: Multiplier: Din1: 0.500000 Din2: 1.500000 Res: 0.750000
exit += fpu_check(CMD_FPU_SP_MUL,0x3f000000,0x3fc00000,0x3f400000);
reg_glbl_soft_reg_0 = exit;
// TEST-2: Multiplier: Din1: 0.500000 Din2: 1.250000 Res: 0.625000
exit += fpu_check(CMD_FPU_SP_MUL,0x3f000000,0x3fa00000,0x3f200000);
reg_glbl_soft_reg_0 = exit;
// TEST-3: Multiplier: Din1: 0.500000 Din2: 0.250000 Res: 0.125000
exit += fpu_check(CMD_FPU_SP_MUL,0x3f000000,0x3e800000,0x3e000000);
reg_glbl_soft_reg_0 = exit;
// TEST-4: Multiplier: Din1: 0.000000 Din2: -0.000000 Res: -0.000000
exit += fpu_check(CMD_FPU_SP_MUL,0x22cb525a,0xadd79efa,0x912b406d);
reg_glbl_soft_reg_0 = exit;
// TEST-5: Multiplier: Din1: 2.000000 Din2: -2.000000 Res: -4.000000
exit += fpu_check(CMD_FPU_SP_MUL,0x40000000,0xc0000000,0xc0800000);
reg_glbl_soft_reg_0 = exit;
// TEST-6: Multiplier: Din1: -1.211871 Din2: -2.889479 Res: 3.501675
exit += fpu_check(CMD_FPU_SP_MUL,0xbf9b1e94,0xc038ed3a,0x40601b72);
reg_glbl_soft_reg_0 = exit;
//--------------------------------------
// Floating Point Division
//--------------------------------------
// TEST-1: Division: Din1: 0.500000 Din2: 1.500000 Res: 0.750000
exit += fpu_check(CMD_FPU_SP_DIV,0x3f000000,0x3fc00000,0x3eaaaaab);
reg_glbl_soft_reg_0 = exit;
// TEST-2: Division: Din1: 0.500000 Din2: 1.250000 Res: 0.400000
exit += fpu_check(CMD_FPU_SP_DIV,0x3f000000,0x3fa00000,0x3ecccccd);
reg_glbl_soft_reg_0 = exit;
// TEST-3: Division: Din1: 0.500000 Din2: 0.250000 Res: 2.000000
exit += fpu_check(CMD_FPU_SP_DIV,0x3f000000,0x3e800000,0x40000000);
reg_glbl_soft_reg_0 = exit;
// TEST-4: Division: Din1: 0.000000 Din2: -0.000000 Res: 0.000000
exit += fpu_check(CMD_FPU_SP_DIV,0x22cb525a,0xadd79efa,0xb47165bd);
reg_glbl_soft_reg_0 = exit;
// TEST-5: Division: Din1: 2.000000 Din2: -2.000000 Res: -1.000000
exit += fpu_check(CMD_FPU_SP_DIV,0x40000000,0xc0000000,0xbf800000);
reg_glbl_soft_reg_0 = exit;
// TEST-6: Division: Din1: -1.211871 Din2: -2.889479 Res: 0.419408
exit += fpu_check(CMD_FPU_SP_DIV,0xbf9b1e94,0xc038ed3a,0x3ed6bca5);
reg_glbl_soft_reg_0 = exit;
//--------------------------------------
// Intger To Floating Point
//--------------------------------------
// TEST-1: I2F: Input: 1069547520 Result: 1069547520.000000
exit += fpu_check(CMD_FPU_SP_I2F,0x3fc00000,0x0,0x4e7f0000);
reg_glbl_soft_reg_0 = exit;
// TEST-2: I2F: Input: 1067450368 Result: 1067450368.000000
exit += fpu_check(CMD_FPU_SP_I2F,0x3fa00000,0x0,0x4e7e8000);
reg_glbl_soft_reg_0 = exit;
// TEST-3: I2F: Input: 1048576000 Result: 1048576000.000000
exit += fpu_check(CMD_FPU_SP_I2F,0x3e800000,0x0,0x4e7a0000);
reg_glbl_soft_reg_0 = exit;
// TEST-4: I2F: Input: 1075838976 Result: 1075838976.000000
exit += fpu_check(CMD_FPU_SP_I2F,0x40200000,0x0,0x4e804000);
reg_glbl_soft_reg_0 = exit;
// TEST-5: I2F: Input: 1084017869 Result: 1084017920.000000
exit += fpu_check(CMD_FPU_SP_I2F,0x409ccccd,0x0,0x4e81399a);
reg_glbl_soft_reg_0 = exit;
// TEST-6: I2F: Input: -1071644672 Result: -1071644672.000000
exit += fpu_check(CMD_FPU_SP_I2F,0xc0200000,0x0,0xce7f8000);
reg_glbl_soft_reg_0 = exit;
//--------------------------------------
// Floating To Integer Point
//--------------------------------------
// TEST-1: F2I: Input: 1.500000 Result: 1
exit += fpu_check(CMD_FPU_SP_F2I,0x3fc00000,0x0,0x00000001);
reg_glbl_soft_reg_0 = exit;
// TEST-2: F2I: Input: 1.250000 Result: 1
exit += fpu_check(CMD_FPU_SP_F2I,0x3fa00000,0x0,0x00000001);
reg_glbl_soft_reg_0 = exit;
// TEST-3: F2I: Input: 0.250000 Result: 0
exit += fpu_check(CMD_FPU_SP_F2I,0x3e800000,0x0,0x00000000);
reg_glbl_soft_reg_0 = exit;
// TEST-4: F2I: Input: 2.500000 Result: 2
exit += fpu_check(CMD_FPU_SP_F2I,0x40200000,0x0,0x00000002);
reg_glbl_soft_reg_0 = exit;
// TEST-5: F2I: Input: -2.500000 Result: -2
exit += fpu_check(CMD_FPU_SP_F2I,0xc0200000,0x0,0xfffffffe);
reg_glbl_soft_reg_0 = exit;
// TEST-6: F2I: Input: -222.800003 Result: -222
exit += fpu_check(CMD_FPU_SP_F2I,0xc35ecccd,0x0,0xffffff22);
reg_glbl_soft_reg_0 = exit;
if(exit == 0) {
reg_gpio_odata = 0x00001800;
} else {
reg_gpio_odata = 0x0000A800;
}
return exit;
}
int fpu_check(uint8_t Cmd, uint32_t Din1, uint32_t Din2, uint32_t Result){
reg_fpu_din1 = Din1;
reg_fpu_din2 = Din2;
reg_fpu_ctrl = Cmd | 0x80000000;
while(reg_fpu_ctrl & 0x80000000); // Wait for FPU completion
reg_glbl_soft_reg_1 = reg_fpu_res;
reg_glbl_soft_reg_2 = Result;
if(reg_fpu_res != Result) return 1;
else return 0;
}