OpenCores
URL https://opencores.org/ocsvn/fpu/fpu/trunk

Subversion Repositories fpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/tags/released/FPU.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/released/FPU.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/released/test_vectors/mkall.bat =================================================================== --- tags/released/test_vectors/mkall.bat (nonexistent) +++ tags/released/test_vectors/mkall.bat (revision 7) @@ -0,0 +1,354 @@ + +rem -------------------- fasu round to nearest even + +pg -q -r 0 -m 1 -p 0 -o rtne/fasu_pat0a.hex +pg -q -r 0 -m 2 -p 0 -o rtne/fasu_pat0b.hex + +pg -q -r 0 -m 1 -p 1 -o rtne/fasu_pat1a.hex +pg -q -r 0 -m 2 -p 1 -o rtne/fasu_pat1b.hex + +pg -q -r 0 -m 1 -p 2 -o rtne/fasu_pat2a.hex +pg -q -r 0 -m 2 -p 2 -o rtne/fasu_pat2b.hex + +pg -q -r 0 -m 1 -n 199990 -ll -o rtne/fasu_lga.hex +pg -q -r 0 -m 2 -n 199990 -ll -o rtne/fasu_lgb.hex + +pg -q -r 0 -m 1 -n 199990 -o rtne/fasu_sma.hex +pg -q -r 0 -m 2 -n 199990 -o rtne/fasu_smb.hex + + +rem -------------------- fasu round to zero + +pg -q -r 3 -m 1 -p 0 -o rtzero/fasu_pat0a.hex +pg -q -r 3 -m 2 -p 0 -o rtzero/fasu_pat0b.hex + +pg -q -r 3 -m 1 -p 1 -o rtzero/fasu_pat1a.hex +pg -q -r 3 -m 2 -p 1 -o rtzero/fasu_pat1b.hex + +pg -q -r 3 -m 1 -p 2 -o rtzero/fasu_pat2a.hex +pg -q -r 3 -m 2 -p 2 -o rtzero/fasu_pat2b.hex + +pg -q -r 3 -m 1 -n 199990 -ll -o rtzero/fasu_lga.hex +pg -q -r 3 -m 2 -n 199990 -ll -o rtzero/fasu_lgb.hex + +pg -q -r 3 -m 1 -n 199990 -o rtzero/fasu_sma.hex +pg -q -r 3 -m 2 -n 199990 -o rtzero/fasu_smb.hex + + +rem -------------------- fasu round to inf + (up) + +pg -q -r 2 -m 1 -p 0 -o rup/fasu_pat0a.hex +pg -q -r 2 -m 2 -p 0 -o rup/fasu_pat0b.hex + +pg -q -r 2 -m 1 -p 1 -o rup/fasu_pat1a.hex +pg -q -r 2 -m 2 -p 1 -o rup/fasu_pat1b.hex + +pg -q -r 2 -m 1 -p 2 -o rup/fasu_pat2a.hex +pg -q -r 2 -m 2 -p 2 -o rup/fasu_pat2b.hex + +pg -q -r 2 -m 1 -n 199990 -ll -o rup/fasu_lga.hex +pg -q -r 2 -m 2 -n 199990 -ll -o rup/fasu_lgb.hex + +pg -q -r 2 -m 1 -n 199990 -o rup/fasu_sma.hex +pg -q -r 2 -m 2 -n 199990 -o rup/fasu_smb.hex + + +rem -------------------- fasu round to inf - (down) + +pg -q -r 1 -m 1 -p 0 -o rdown/fasu_pat0a.hex +pg -q -r 1 -m 2 -p 0 -o rdown/fasu_pat0b.hex + +pg -q -r 1 -m 1 -p 1 -o rdown/fasu_pat1a.hex +pg -q -r 1 -m 2 -p 1 -o rdown/fasu_pat1b.hex + +pg -q -r 1 -m 1 -p 2 -o rdown/fasu_pat2a.hex +pg -q -r 1 -m 2 -p 2 -o rdown/fasu_pat2b.hex + +pg -q -r 1 -m 1 -n 199990 -ll -o rdown/fasu_lga.hex +pg -q -r 1 -m 2 -n 199990 -ll -o rdown/fasu_lgb.hex + +pg -q -r 1 -m 1 -n 199990 -o rdown/fasu_sma.hex +pg -q -r 1 -m 2 -n 199990 -o rdown/fasu_smb.hex + + +rem -------------------- fmul round to nearest even + +pg -q -r 0 -m 4 -p 0 -o rtne/fmul_pat0.hex + +pg -q -r 0 -m 4 -p 1 -o rtne/fmul_pat1.hex + +pg -q -r 0 -m 4 -p 2 -o rtne/fmul_pat2.hex + +pg -q -r 0 -m 4 -n 199990 -ll -o rtne/fmul_lg.hex + +pg -q -r 0 -m 4 -n 199990 -o rtne/fmul_sm.hex + + +rem -------------------- fmul round to zero + +pg -q -r 3 -m 4 -p 0 -o rtzero/fmul_pat0.hex + +pg -q -r 3 -m 4 -p 1 -o rtzero/fmul_pat1.hex + +pg -q -r 3 -m 4 -p 2 -o rtzero/fmul_pat2.hex + +pg -q -r 3 -m 4 -n 199990 -ll -o rtzero/fmul_lg.hex + +pg -q -r 3 -m 4 -n 199990 -o rtzero/fmul_sm.hex + + + +rem -------------------- fmul round to inf + (up) + +pg -q -r 2 -m 4 -p 0 -o rup/fmul_pat0.hex + +pg -q -r 2 -m 4 -p 1 -o rup/fmul_pat1.hex + +pg -q -r 2 -m 4 -p 2 -o rup/fmul_pat2.hex + +pg -q -r 2 -m 4 -n 199990 -ll -o rup/fmul_lg.hex + +pg -q -r 2 -m 4 -n 199990 -o rup/fmul_sm.hex + + + +rem -------------------- fmul round to inf - (down) + +pg -q -r 1 -m 4 -p 0 -o rdown/fmul_pat0.hex + +pg -q -r 1 -m 4 -p 1 -o rdown/fmul_pat1.hex + +pg -q -r 1 -m 4 -p 2 -o rdown/fmul_pat2.hex + +pg -q -r 1 -m 4 -n 199990 -ll -o rdown/fmul_lg.hex + +pg -q -r 1 -m 4 -n 199990 -o rdown/fmul_sm.hex + + +rem -------------------- fdiv round to nearest even + +pg -q -r 0 -m 8 -p 0 -o rtne/fdiv_pat0.hex + +pg -q -r 0 -m 8 -p 1 -o rtne/fdiv_pat1.hex + +pg -q -r 0 -m 8 -p 2 -o rtne/fdiv_pat2.hex + +pg -q -r 0 -m 8 -n 199990 -ll -o rtne/fdiv_lg.hex + +pg -q -r 0 -m 8 -n 199990 -o rtne/fdiv_sm.hex + + +rem -------------------- fdiv round to zero + +pg -q -r 3 -m 8 -p 0 -o rtzero/fdiv_pat0.hex + +pg -q -r 3 -m 8 -p 1 -o rtzero/fdiv_pat1.hex + +pg -q -r 3 -m 8 -p 2 -o rtzero/fdiv_pat2.hex + +pg -q -r 3 -m 8 -n 199990 -ll -o rtzero/fdiv_lg.hex + +pg -q -r 3 -m 8 -n 199990 -o rtzero/fdiv_sm.hex + + + +rem -------------------- fdiv round to inf + (up) + +pg -q -r 2 -m 8 -p 0 -o rup/fdiv_pat0.hex + +pg -q -r 2 -m 8 -p 1 -o rup/fdiv_pat1.hex + +pg -q -r 2 -m 8 -p 2 -o rup/fdiv_pat2.hex + +pg -q -r 2 -m 8 -n 199990 -ll -o rup/fdiv_lg.hex + +pg -q -r 2 -m 8 -n 199990 -o rup/fdiv_sm.hex + + + +rem -------------------- fdiv round to inf - (down) + +pg -q -r 1 -m 8 -p 0 -o rdown/fdiv_pat0.hex + +pg -q -r 1 -m 8 -p 1 -o rdown/fdiv_pat1.hex + +pg -q -r 1 -m 8 -p 2 -o rdown/fdiv_pat2.hex + +pg -q -r 1 -m 8 -n 199990 -ll -o rdown/fdiv_lg.hex + +pg -q -r 1 -m 8 -n 199990 -o rdown/fdiv_sm.hex + + +rem -------------------- Combo Tests + +pg -q -m 15 -R -n 499995 -ll -o combo/fpu_combo1.hex + +pg -q -m 15 -R -n 499995 -s 17 -o combo/fpu_combo2.hex + +pg -q -m 63 -R -n 499995 -ll -s 7 -o combo/fpu_combo3.hex + +pg -q -m 63 -R -n 499995 -s 255 -o combo/fpu_combo4.hex + + + +rem -------------------- i2f round to nearest even + +pg -q -r 0 -m 16 -p 0 -o rtne/i2f_pat0.hex + +pg -q -r 0 -m 16 -p 1 -o rtne/i2f_pat1.hex + +pg -q -r 0 -m 16 -p 2 -o rtne/i2f_pat2.hex + +pg -q -r 0 -m 16 -n 199990 -ll -o rtne/i2f_lg.hex + +pg -q -r 0 -m 16 -n 199990 -o rtne/i2f_sm.hex + + +rem -------------------- i2f round to zero + +pg -q -r 3 -m 16 -p 0 -o rtzero/i2f_pat0.hex + +pg -q -r 3 -m 16 -p 1 -o rtzero/i2f_pat1.hex + +pg -q -r 3 -m 16 -p 2 -o rtzero/i2f_pat2.hex + +pg -q -r 3 -m 16 -n 199990 -ll -o rtzero/i2f_lg.hex + +pg -q -r 3 -m 16 -n 199990 -o rtzero/i2f_sm.hex + + + +rem -------------------- i2f round to inf + (up) + +pg -q -r 2 -m 16 -p 0 -o rup/i2f_pat0.hex + +pg -q -r 2 -m 16 -p 1 -o rup/i2f_pat1.hex + +pg -q -r 2 -m 16 -p 2 -o rup/i2f_pat2.hex + +pg -q -r 2 -m 16 -n 199990 -ll -o rup/i2f_lg.hex + +pg -q -r 2 -m 16 -n 199990 -o rup/i2f_sm.hex + + + +rem -------------------- i2f round to inf - (down) + +pg -q -r 1 -m 16 -p 0 -o rdown/i2f_pat0.hex + +pg -q -r 1 -m 16 -p 1 -o rdown/i2f_pat1.hex + +pg -q -r 1 -m 16 -p 2 -o rdown/i2f_pat2.hex + +pg -q -r 1 -m 16 -n 199990 -ll -o rdown/i2f_lg.hex + +pg -q -r 1 -m 16 -n 199990 -o rdown/i2f_sm.hex + + + +rem -------------------- f2i round to nearest even + +pg -q -r 0 -m 32 -p 0 -o rtne/f2i_pat0.hex + +pg -q -r 0 -m 32 -p 1 -o rtne/f2i_pat1.hex + +pg -q -r 0 -m 32 -p 2 -o rtne/f2i_pat2.hex + +pg -q -r 0 -m 32 -n 199990 -ll -o rtne/f2i_lg.hex + +pg -q -r 0 -m 32 -n 199990 -o rtne/f2i_sm.hex + + +rem -------------------- f2i round to zero + +pg -q -r 3 -m 32 -p 0 -o rtzero/f2i_pat0.hex + +pg -q -r 3 -m 32 -p 1 -o rtzero/f2i_pat1.hex + +pg -q -r 3 -m 32 -p 2 -o rtzero/f2i_pat2.hex + +pg -q -r 3 -m 32 -n 199990 -ll -o rtzero/f2i_lg.hex + +pg -q -r 3 -m 32 -n 199990 -o rtzero/f2i_sm.hex + + + +rem -------------------- f2i round to inf + (up) + +pg -q -r 2 -m 32 -p 0 -o rup/f2i_pat0.hex + +pg -q -r 2 -m 32 -p 1 -o rup/f2i_pat1.hex + +pg -q -r 2 -m 32 -p 2 -o rup/f2i_pat2.hex + +pg -q -r 2 -m 32 -n 199990 -ll -o rup/f2i_lg.hex + +pg -q -r 2 -m 32 -n 199990 -o rup/f2i_sm.hex + + + +rem -------------------- f2i round to inf - (down) + +pg -q -r 1 -m 32 -p 0 -o rdown/f2i_pat0.hex + +pg -q -r 1 -m 32 -p 1 -o rdown/f2i_pat1.hex + +pg -q -r 1 -m 32 -p 2 -o rdown/f2i_pat2.hex + +pg -q -r 1 -m 32 -n 199990 -ll -o rdown/f2i_lg.hex + +pg -q -r 1 -m 32 -n 199990 -o rdown/f2i_sm.hex + + +rem -------------------- frem round to nearest even + +pg -q -r 0 -m 64 -p 0 -o rtne/frem_pat0.hex + +pg -q -r 0 -m 64 -p 1 -o rtne/frem_pat1.hex + +pg -q -r 0 -m 64 -p 2 -o rtne/frem_pat2.hex + +pg -q -r 0 -m 64 -n 199990 -ll -o rtne/frem_lg.hex + +pg -q -r 0 -m 64 -n 199990 -o rtne/frem_sm.hex + + +rem -------------------- frem round to zero + +pg -q -r 3 -m 64 -p 0 -o rtzero/frem_pat0.hex + +pg -q -r 3 -m 64 -p 1 -o rtzero/frem_pat1.hex + +pg -q -r 3 -m 64 -p 2 -o rtzero/frem_pat2.hex + +pg -q -r 3 -m 64 -n 199990 -ll -o rtzero/frem_lg.hex + +pg -q -r 3 -m 64 -n 199990 -o rtzero/frem_sm.hex + + + +rem -------------------- frem round to inf + (up) + +pg -q -r 2 -m 64 -p 0 -o rup/frem_pat0.hex + +pg -q -r 2 -m 64 -p 1 -o rup/frem_pat1.hex + +pg -q -r 2 -m 64 -p 2 -o rup/frem_pat2.hex + +pg -q -r 2 -m 64 -n 199990 -ll -o rup/frem_lg.hex + +pg -q -r 2 -m 64 -n 199990 -o rup/frem_sm.hex + + + +rem -------------------- frem round to inf - (down) + +pg -q -r 1 -m 64 -p 0 -o rdown/frem_pat0.hex + +pg -q -r 1 -m 64 -p 1 -o rdown/frem_pat1.hex + +pg -q -r 1 -m 64 -p 2 -o rdown/frem_pat2.hex + +pg -q -r 1 -m 64 -n 199990 -ll -o rdown/frem_lg.hex + +pg -q -r 1 -m 64 -n 199990 -o rdown/frem_sm.hex \ No newline at end of file
tags/released/test_vectors/mkall.bat Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/released/test_vectors/pg.exe =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/released/test_vectors/pg.exe =================================================================== --- tags/released/test_vectors/pg.exe (nonexistent) +++ tags/released/test_vectors/pg.exe (revision 7)
tags/released/test_vectors/pg.exe Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/released/test_vectors/pg-src/fptpg.c =================================================================== --- tags/released/test_vectors/pg-src/fptpg.c (nonexistent) +++ tags/released/test_vectors/pg-src/fptpg.c (revision 7) @@ -0,0 +1,773 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// fptpg.c //// +//// Floating Point Test Pattern Generator //// +//// //// +//// Author: Rudolf Usselmann //// +//// russelmann@hotmail.com //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// russelmann@hotmail.com //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT //// +//// LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND //// +//// FITNESS FOR A PARTICULAR PURPOSE. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +#include "milieu.h" +#include "softfloat.h" + +// Global vars ... +int verb=0; +int quiet=0; +int pat=0; +int large=0; +int append=0; +int rall=0; +char *ofile=0; + +// Prototypes ... +float32 get_fp(); +int arop(int , int ); +float32 get_pat(int ); +float32 get_pat0(int ); +float32 get_pat1(int ); +float32 get_pat2(int ); + + +main(int argc, char **argv) +{ +int i; +int count=25; +int ar = 0; +int seed = 12345678; + +float_rounding_mode = float_round_nearest_even; // Default Rounding Mode + +if(argc<2) { + printf("Usage:\n"); + printf(" -n Specifies the number of tests\n"); + printf(" vectors to generate. Default: 25.\n"); + printf(" -v Verbose\n"); + printf(" -q Quiet\n"); + printf(" -a Append to output file name. Default: Overwrite\n"); + printf(" -l Use large numbers\n"); + printf(" -p N Use built in patterns. N=Patter Number:\n"); + printf(" 0 = Min/Max Bit patters, normalized numbers only (Max 92416 Vectors)\n"); + printf(" 1 = Min/Max Bit patters, including denormalized numbers (Max 92416 Vectors)\n"); + printf(" 2 = Bit patterns test vectors (Max 15376 Vectors)\n"); + printf(" -o Dump patterns to \n"); + printf(" -r N Round Option. Where N is one of:\n"); + printf(" 0 = float_round_nearest_eve (Default)\n"); + printf(" 1 = float_round_down\n"); + printf(" 2 = float_round_up\n"); + printf(" 3 = float_round_to_zero\n"); + printf(" -m N Generate Test patters for operation N.\n"); + printf(" Where N is a combination of:\n"); + printf(" 1 = Add operations\n"); + printf(" 2 = Subtract Operations\n"); + printf(" 4 = Multiply Operations\n"); + printf(" 8 = Divide operations\n"); + printf(" 16 = Integer to Floating Point Conversion\n"); + printf(" 32 = Floating Point to Integer Conversion\n"); + printf(" 64 = Remainder Function\n"); + printf(" -s N Use N as seed for rand() functions.\n"); + printf(" -R Randomize rounding mode.\n"); + return(0); + } + +i=1; + +while((argc-1)>=i) { + + if(strcmp(argv[i],"-v")==0) verb=1; + else + if(strcmp(argv[i],"-q")==0) quiet=1; + else + if(strcmp(argv[i],"-R")==0) rall=1; + else + if(strcmp(argv[i],"-p")==0) { + i++; + pat = atoi(argv[i]) + 1; + if(pat>3 | pat<0) { + printf("ERROR: 'pattern' out of range (%0d), resetting to pattern 0.\n",pat); + pat = 1; + } + } + else + if(strcmp(argv[i],"-l")==0) large=1; + else + if(strcmp(argv[i],"-ll")==0) large=2; + else + if(strcmp(argv[i],"-a")==0) append=1; + else + if(strcmp(argv[i],"-n")==0) { + i++; + count = atoi(argv[i]); + if(count<0 | count>1000000) { + printf("ERROR: 'count' out of range (%0d), resetting to default.\n",count); + count=25; + } + } + else + if(strcmp(argv[i],"-o")==0) { + i++; + ofile = argv[i]; + } + else + if(strcmp(argv[i],"-m")==0) { + i++; + ar = atoi(argv[i]); + } + else + if(strcmp(argv[i],"-r")==0) { + i++; + float_rounding_mode = atoi(argv[i]); + } + else + if(strcmp(argv[i],"-s")==0) { + i++; + seed = atoi(argv[i]); + } + else + printf("Unknown Option: %s\n\n",argv[i]); + i++; + } + +srand( seed ); + +if(!quiet) { + printf("\n Floating Point Test Vector Generation V1.6\n"); + printf("\t by Rudolf Usselmann rudi@asics.ws\n\n"); + + switch(float_rounding_mode) { + case 0: printf("Rounding mode: float_round_nearest_even\n"); break; + case 1: printf("Rounding mode: float_round_down\n"); break; + case 2: printf("Rounding mode: float_round_up\n"); break; + case 3: printf("Rounding mode: float_round_to_zero\n"); break; + + default: printf("Rounding mode: Unknown (%0d)\n", float_rounding_mode ); break; + } + } + +if(count==25) { + + if( (ar & 0x10) | (ar & 0x20) ) { + + if(pat==1) count = 304; + else + if(pat==2) count = 304; + else + if(pat==3) count = 124; + + } else { + + if(pat==1) count = 92416; + else + if(pat==2) count = 92416; + else + if(pat==3) count = 15376; + + } + + } + +if(ar) arop(count,ar); + +return(0); +} + + +int arop(int count, int op) { +float32 f1, f2, f3, f4; +int i; +int fp; +char *mode; +int add=0; +int sub=0; +int mul=0; +int div=0; +int i2f=0; +int f2i=0; +int rem=0; +int oper; +int err; +int err_count=0; +int tmp; + +if(!quiet) printf("\nGenerating %0d Arithmetic test vectors ...\n",count); + +if(append) mode = "a"; +else mode = "w"; +if(ofile==0) ofile = "ar.hex"; + +fp = fopen(ofile,mode); +if(fp == 0) { + printf("ERROR: Could not create file '%s'.\n",ofile); + return(-1); + } + +if(!quiet) { + if(op & 0x01) printf("Add OP\n"); + if(op & 0x02) printf("Sub OP\n"); + if(op & 0x04) printf("Mul OP\n"); + if(op & 0x08) printf("Div OP\n"); + if(op & 0x10) printf("int2float\n"); + if(op & 0x20) printf("float2int\n"); + if(op & 0x40) printf("Remainder\n"); + } + +if(op & 0x01) add=1; +if(op & 0x02) sub=1; +if(op & 0x04) mul=1; +if(op & 0x08) div=1; +if(op & 0x10) i2f=1; +if(op & 0x20) f2i=1; +if(op & 0x40) rem=1; + +f1 = get_pat(0); // Initialize pattern generator ... + +for(i=0;i0) { + f1 = get_pat(1); + f2 = get_pat(2); + } else { + f1 = get_fp(); + f2 = get_fp(); + } + + + if(rall) float_rounding_mode = (rand() % 4); + + + oper = -1; + while(oper == -1) { + float_exception_flags = 0; // Reset Exceptions + + if( (rand() % 8)==6 & rem) { + oper = 0x40; + f3 = float32_rem( f1, f2 ); + float_exception_flags = 0; // Reset Exceptions + f3 = float32_rem( f1, f2 ); + } + + if( (rand() % 8)==5 & f2i) { + oper = 0x20; + f3 = float32_to_int32( f1 ); + float_exception_flags = 0; // Reset Exceptions + f3 = float32_to_int32( f1 ); + f2 = 0; + } + + if( (rand() % 8)==4 & i2f) { + oper = 0x10; + + + tmp = (int) f1; + + + f3 = int32_to_float32( tmp ); + float_exception_flags = 0; // Reset Exceptions + f3 = int32_to_float32( tmp ); + f2 =0; + } + + + if( (rand() % 8)==3 & div) { + oper = 0x08; + f3 = float32_div( f1, f2); + float_exception_flags = 0; // Reset Exceptions + f3 = float32_div( f1, f2); + + //*( (float *) &f4 ) = *( (float *) &f1 ) / *( (float *) &f2 ); + //if( f4 != f3) { + // err = 1; + // printf("FP Div Error: %x - %x: System: %x Lib: %x\n",f1, f2, f4, f3); + // } + } + + if( (rand() % 8)==2 & mul) { + oper = 0x04; + f3 = float32_mul( f1, f2); + float_exception_flags = 0; // Reset Exceptions + f3 = float32_mul( f1, f2); + + //*( (float *) &f4 ) = *( (float *) &f1 ) * *( (float *) &f2 ); + //if( f4 != f3) { + // err = 1; + // printf("FP Mul Error: %x - %x: System: %x Lib: %x\n",f1, f2, f4, f3); + // } + } + + if( (rand() % 8)==1 & sub) { + oper = 0x02; + f3 = float32_sub( f1, f2); + float_exception_flags = 0; // Reset Exceptions + f3 = float32_sub( f1, f2); + + //*( (float *) &f4 ) = *( (float *) &f1 ) - *( (float *) &f2 ); + //if( f4 != f3) { + // err = 1; + // printf("FP Sub Error: %x - %x: System: %x Lib: %x\n",f1, f2, f4, f3); + // } + } + + if( (rand() % 8)==0 & add) { + oper = 0x01; + f3 = float32_add( f1, f2); + float_exception_flags = 0; // Reset Exceptions + f3 = float32_add( f1, f2); + + //*( (float *) &f4 ) = *( (float *) &f1 ) + *( (float *) &f2 ); + //if( f4 != f3) { + // err = 1; + // printf("FP Add Error: %x - %x: System: %x Lib: %x\n",f1, f2, f4, f3); + // } + } + + } + + if(err) err_count++; + + if(!err) { + + //if(float_exception_flags != 0) + // printf("Exceptions: %x\n",float_exception_flags); + + + if(verb) printf("rmode: %01x, except: %02x, oper: %02x opa: %08x, opb: %08x res: %08x\n", float_rounding_mode, float_exception_flags, oper, f1, f2, f3); + fprintf(fp,"%01x%02x%02x%08x%08x%08x\n", float_rounding_mode, float_exception_flags, oper, f1, f2, f3); + } + else { + printf("\t Vecor mismatch between library and system calculations. This Vector\n"); + printf("\t will not be placed in to vector file ...\n"); + } + + } + + +close(fp); + +if(!quiet) { + printf("Found %d errors\n",err_count); + printf("Wrote %d vectors from total %d specified.\n", (count-err_count), count); + + printf("\n ... f2i done.\n"); + } +return(0); +} + +float32 get_fp() { +float32 f1; +int i1, i2, e; + + if(large>0) i2 = rand(); + else i2 = 0; + + if(large>1) i1 = rand() | (i2<<16); + else i1 = rand() | (i2<<10); + + i1 = i1 & 0x007fffff; + + e = rand(); + e = e & 0x0ff; + + f1 = (e << 23) + i1; + + if( rand() & 0x01) f1 = f1 | 0x80000000; + + return(f1); +} + +static int p0, p1; + +// 0x00800000 Minimum Posetive Number +// 0x7f7fffff Maximum Posetive Number + + +float32 pat0[] = { 0x00800000, 0x00800001, 0x00800002, 0x00800004, + 0x00800008, 0x00880000, 0x00900000, 0x00a00000, + 0x00c00000, 0x00880001, 0x00900001, 0x00a00001, + 0x00c00001, 0x00880002, 0x00900002, 0x00a00002, + 0x00c00002, 0x00880004, 0x00900004, 0x00a00004, + 0x00c00004, 0x00800003, 0x00800007, 0x0080000f, + 0x00f80000, 0x00f00000, 0x00e00000, 0x00f80001, + 0x00f00001, 0x00e00001, 0x00f80003, 0x00f00003, + 0x00e00003, 0x00c00003, 0x00f80007, 0x00f00007, + 0x00e00007, 0x00c00007, 0x00ffffff, 0x00fffffe, + 0x00fffffd, 0x00fffffb, 0x00fffff7, 0x00f7ffff, + 0x00efffff, 0x00dfffff, 0x00bfffff, 0x00f7fffe, + 0x00effffe, 0x00dffffe, 0x00bffffe, 0x00f7fffd, + 0x00effffd, 0x00dffffd, 0x00bffffd, 0x00f7fffb, + 0x00effffb, 0x00dffffb, 0x00bffffb, 0x00fffffc, + 0x00fffff8, 0x00fffff0, 0x0087ffff, 0x008fffff, + 0x009fffff, 0x0087fffe, 0x008ffffe, 0x009ffffe, + 0x0087fffc, 0x008ffffc, 0x009ffffc, 0x00bffffc, + 0x0087fff8, 0x008ffff8, 0x009ffff8, 0x00bffff8, + 0x7f000000, 0x7f000001, 0x7f000002, 0x7f000004, + 0x7f000008, 0x7f080000, 0x7f100000, 0x7f200000, + 0x7f400000, 0x7f080001, 0x7f100001, 0x7f200001, + 0x7f400001, 0x7f080002, 0x7f100002, 0x7f200002, + 0x7f400002, 0x7f080004, 0x7f100004, 0x7f200004, + 0x7f400004, 0x7f000003, 0x7f000007, 0x7f00000f, + 0x7f780000, 0x7f700000, 0x7f600000, 0x7f780001, + 0x7f700001, 0x7f600001, 0x7f780003, 0x7f700003, + 0x7f600003, 0x7f400003, 0x7f780007, 0x7f700007, + 0x7f600007, 0x7f400007, 0x7f7fffff, 0x7f7ffffe, + 0x7f7ffffd, 0x7f7ffffb, 0x7f7ffff7, 0x7f77ffff, + 0x7f6fffff, 0x7f5fffff, 0x7f3fffff, 0x7f77fffe, + 0x7f6ffffe, 0x7f5ffffe, 0x7f3ffffe, 0x7f77fffd, + 0x7f6ffffd, 0x7f5ffffd, 0x7f3ffffd, 0x7f77fffb, + 0x7f6ffffb, 0x7f5ffffb, 0x7f3ffffb, 0x7f7ffffc, + 0x7f7ffff8, 0x7f7ffff0, 0x7f07ffff, 0x7f0fffff, + 0x7f1fffff, 0x7f07fffe, 0x7f0ffffe, 0x7f1ffffe, + 0x7f07fffc, 0x7f0ffffc, 0x7f1ffffc, 0x7f3ffffc, + 0x7f07fff8, 0x7f0ffff8, 0x7f1ffff8, 0x7f3ffff8, + 0x80800000, 0x80800001, 0x80800002, 0x80800004, + 0x80800008, 0x80880000, 0x80900000, 0x80a00000, + 0x80c00000, 0x80880001, 0x80900001, 0x80a00001, + 0x80c00001, 0x80880002, 0x80900002, 0x80a00002, + 0x80c00002, 0x80880004, 0x80900004, 0x80a00004, + 0x80c00004, 0x80800003, 0x80800007, 0x8080000f, + 0x80f80000, 0x80f00000, 0x80e00000, 0x80f80001, + 0x80f00001, 0x80e00001, 0x80f80003, 0x80f00003, + 0x80e00003, 0x80c00003, 0x80f80007, 0x80f00007, + 0x80e00007, 0x80c00007, 0x80ffffff, 0x80fffffe, + 0x80fffffd, 0x80fffffb, 0x80fffff7, 0x80f7ffff, + 0x80efffff, 0x80dfffff, 0x80bfffff, 0x80f7fffe, + 0x80effffe, 0x80dffffe, 0x80bffffe, 0x80f7fffd, + 0x80effffd, 0x80dffffd, 0x80bffffd, 0x80f7fffb, + 0x80effffb, 0x80dffffb, 0x80bffffb, 0x80fffffc, + 0x80fffff8, 0x80fffff0, 0x8087ffff, 0x808fffff, + 0x809fffff, 0x8087fffe, 0x808ffffe, 0x809ffffe, + 0x8087fffc, 0x808ffffc, 0x809ffffc, 0x80bffffc, + 0x8087fff8, 0x808ffff8, 0x809ffff8, 0x80bffff8, + 0xff000000, 0xff000001, 0xff000002, 0xff000004, + 0xff000008, 0xff080000, 0xff100000, 0xff200000, + 0xff400000, 0xff080001, 0xff100001, 0xff200001, + 0xff400001, 0xff080002, 0xff100002, 0xff200002, + 0xff400002, 0xff080004, 0xff100004, 0xff200004, + 0xff400004, 0xff000003, 0xff000007, 0xff00000f, + 0xff780000, 0xff700000, 0xff600000, 0xff780001, + 0xff700001, 0xff600001, 0xff780003, 0xff700003, + 0xff600003, 0xff400003, 0xff780007, 0xff700007, + 0xff600007, 0xff400007, 0xff7fffff, 0xff7ffffe, + 0xff7ffffd, 0xff7ffffb, 0xff7ffff7, 0xff77ffff, + 0xff6fffff, 0xff5fffff, 0xff3fffff, 0xff77fffe, + 0xff6ffffe, 0xff5ffffe, 0xff3ffffe, 0xff77fffd, + 0xff6ffffd, 0xff5ffffd, 0xff3ffffd, 0xff77fffb, + 0xff6ffffb, 0xff5ffffb, 0xff3ffffb, 0xff7ffffc, + 0xff7ffff8, 0xff7ffff0, 0xff07ffff, 0xff0fffff, + 0xff1fffff, 0xff07fffe, 0xff0ffffe, 0xff1ffffe, + 0xff07fffc, 0xff0ffffc, 0xff1ffffc, 0xff3ffffc, + 0xff07fff8, 0xff0ffff8, 0xff1ffff8, 0xff3ffff8 + }; + + +int pat0_cnt = 304; + + +float32 pat1[] = { 0x6c800000, 0x3a000001, 0x69800002, 0x79800004, + 0x37000008, 0x59080000, 0x7d900000, 0x23200000, + 0x59c00000, 0x23880001, 0x5e900001, 0x45a00001, + 0x1f400001, 0x63080002, 0x29100002, 0x15200002, + 0x43c00002, 0x5d880004, 0x29900004, 0x54200004, + 0x09400004, 0x28800003, 0x7f800007, 0x0880000f, + 0x3cf80000, 0x4af00000, 0x58e00000, 0x61780001, + 0x20700001, 0x0fe00001, 0x15780003, 0x73700003, + 0x52e00003, 0x7b400003, 0x10780007, 0x7c700007, + 0x30e00007, 0x3dc00007, 0x5f7fffff, 0x45fffffe, + 0x407ffffd, 0x18fffffb, 0x48fffff7, 0x60f7ffff, + 0x27efffff, 0x145fffff, 0x3e3fffff, 0x5277fffe, + 0x3ceffffe, 0x73dffffe, 0x233ffffe, 0x67f7fffd, + 0x33effffd, 0x4e5ffffd, 0x243ffffd, 0x4f77fffb, + 0x6feffffb, 0x31dffffb, 0x673ffffb, 0x207ffffc, + 0x07fffff8, 0x3dfffff0, 0x6187ffff, 0x7f8fffff, + 0x7f1fffff, 0x1887fffe, 0x170ffffe, 0x011ffffe, + 0x3a87fffc, 0x280ffffc, 0x0a9ffffc, 0x753ffffc, + 0x4187fff8, 0x7b8ffff8, 0x2c1ffff8, 0x40bffff8, + 0x00000000, 0x00000001, 0x00000002, 0x00000004, + 0x00000008, 0x00080000, 0x00100000, 0x00200000, + 0x00400000, 0x00080001, 0x00100001, 0x00200001, + 0x00400001, 0x00080002, 0x00100002, 0x00200002, + 0x00400002, 0x00080004, 0x00100004, 0x00200004, + 0x00400004, 0x00000003, 0x00000007, 0x0000000f, + 0x00780000, 0x00700000, 0x00600000, 0x00780001, + 0x00700001, 0x00600001, 0x00780003, 0x00700003, + 0x00600003, 0x00400003, 0x00780007, 0x00700007, + 0x00600007, 0x00400007, 0x007fffff, 0x007ffffe, + 0x007ffffd, 0x007ffffb, 0x007ffff7, 0x0077ffff, + 0x006fffff, 0x005fffff, 0x003fffff, 0x0077fffe, + 0x006ffffe, 0x005ffffe, 0x003ffffe, 0x0077fffd, + 0x006ffffd, 0x005ffffd, 0x003ffffd, 0x0077fffb, + 0x006ffffb, 0x005ffffb, 0x003ffffb, 0x007ffffc, + 0x007ffff8, 0x007ffff0, 0x0007ffff, 0x000fffff, + 0x001fffff, 0x0007fffe, 0x000ffffe, 0x001ffffe, + 0x0007fffc, 0x000ffffc, 0x001ffffc, 0x003ffffc, + 0x0007fff8, 0x000ffff8, 0x001ffff8, 0x003ffff8, + 0xc7800000, 0xc3800001, 0x84000002, 0xf6800004, + 0x90000008, 0xca880000, 0xee900000, 0xc8200000, + 0xb0c00000, 0xd3080001, 0xa7100001, 0x84a00001, + 0xb6400001, 0xbc880002, 0xee100002, 0xc7a00002, + 0xbec00002, 0xe4880004, 0x90100004, 0xfea00004, + 0x82c00004, 0x9d000003, 0x9b800007, 0xef00000f, + 0xe3780000, 0xadf00000, 0x83e00000, 0xe7f80001, + 0xf9700001, 0xbae00001, 0x81f80003, 0xbef00003, + 0xb8600003, 0x88400003, 0xf7f80007, 0xcbf00007, + 0xa3600007, 0xf2400007, 0x9dffffff, 0xfefffffe, + 0xa27ffffd, 0x8ffffffb, 0xc07ffff7, 0xc3f7ffff, + 0x806fffff, 0xdcdfffff, 0xda3fffff, 0xd3f7fffe, + 0x916ffffe, 0xde5ffffe, 0xd2bffffe, 0x9df7fffd, + 0x97effffd, 0x9cdffffd, 0xa43ffffd, 0xf377fffb, + 0xe0effffb, 0xe9dffffb, 0xb43ffffb, 0x9c7ffffc, + 0xaafffff8, 0xcafffff0, 0xa887ffff, 0xf98fffff, + 0xda1fffff, 0xff87fffe, 0xff0ffffe, 0xe19ffffe, + 0x8287fffc, 0x808ffffc, 0xab1ffffc, 0xddbffffc, + 0xd387fff8, 0xe40ffff8, 0x8d1ffff8, 0xefbffff8, + 0x80000000, 0x80000001, 0x80000002, 0x80000004, + 0x80000008, 0x80080000, 0x80100000, 0x80200000, + 0x80400000, 0x80080001, 0x80100001, 0x80200001, + 0x80400001, 0x80080002, 0x80100002, 0x80200002, + 0x80400002, 0x80080004, 0x80100004, 0x80200004, + 0x80400004, 0x80000003, 0x80000007, 0x8000000f, + 0x80780000, 0x80700000, 0x80600000, 0x80780001, + 0x80700001, 0x80600001, 0x80780003, 0x80700003, + 0x80600003, 0x80400003, 0x80780007, 0x80700007, + 0x80600007, 0x80400007, 0x807fffff, 0x807ffffe, + 0x807ffffd, 0x807ffffb, 0x807ffff7, 0x8077ffff, + 0x806fffff, 0x805fffff, 0x803fffff, 0x8077fffe, + 0x806ffffe, 0x805ffffe, 0x803ffffe, 0x8077fffd, + 0x806ffffd, 0x805ffffd, 0x803ffffd, 0x8077fffb, + 0x806ffffb, 0x805ffffb, 0x803ffffb, 0x807ffffc, + 0x807ffff8, 0x807ffff0, 0x8007ffff, 0x800fffff, + 0x801fffff, 0x8007fffe, 0x800ffffe, 0x801ffffe, + 0x8007fffc, 0x800ffffc, 0x801ffffc, 0x803ffffc, + 0x8007fff8, 0x800ffff8, 0x801ffff8, 0x803ffff8, + }; + + +int pat1_cnt = 304; +int pat2_cnt = 124; + +float32 pat2[] = { 0x00000000, + 0x00000001, + 0x00000002, + 0x00000004, + 0x00000008, + 0x00000010, + 0x00000020, + 0x00000040, + 0x00000080, + 0x00000100, + 0x00000200, + 0x00000400, + 0x00000800, + 0x00001000, + 0x00002000, + 0x00004000, + 0x00008000, + 0x00010000, + 0x00020000, + 0x00040000, + 0x00080000, + 0x00100000, + 0x00200000, + 0x00400000, + 0x00800000, + 0x01000000, + 0x02000000, + 0x04000000, + 0x08000000, + 0x10000000, + 0x20000000, + 0x40000000, + 0x80000000, + 0xC0000000, + 0xE0000000, + 0xF0000000, + 0xF8000000, + 0xFC000000, + 0xFE000000, + 0xFF000000, + 0xFF800000, + 0xFFC00000, + 0xFFE00000, + 0xFFF00000, + 0xFFF80000, + 0xFFFC0000, + 0xFFFE0000, + 0xFFFF0000, + 0xFFFF8000, + 0xFFFFC000, + 0xFFFFE000, + 0xFFFFF000, + 0xFFFFF800, + 0xFFFFFC00, + 0xFFFFFE00, + 0xFFFFFF00, + 0xFFFFFF80, + 0xFFFFFFC0, + 0xFFFFFFE0, + 0xFFFFFFF0, + 0xFFFFFFF8, + 0xFFFFFFFC, + 0xFFFFFFFE, + 0xFFFFFFFF, + 0xFFFFFFFD, + 0xFFFFFFFB, + 0xFFFFFFF7, + 0xFFFFFFEF, + 0xFFFFFFDF, + 0xFFFFFFBF, + 0xFFFFFF7F, + 0xFFFFFEFF, + 0xFFFFFDFF, + 0xFFFFFBFF, + 0xFFFFF7FF, + 0xFFFFEFFF, + 0xFFFFDFFF, + 0xFFFFBFFF, + 0xFFFF7FFF, + 0xFFFEFFFF, + 0xFFFDFFFF, + 0xFFFBFFFF, + 0xFFF7FFFF, + 0xFFEFFFFF, + 0xFFDFFFFF, + 0xFFBFFFFF, + 0xFF7FFFFF, + 0xFEFFFFFF, + 0xFDFFFFFF, + 0xFBFFFFFF, + 0xF7FFFFFF, + 0xEFFFFFFF, + 0xDFFFFFFF, + 0xBFFFFFFF, + 0x7FFFFFFF, + 0x3FFFFFFF, + 0x1FFFFFFF, + 0x0FFFFFFF, + 0x07FFFFFF, + 0x03FFFFFF, + 0x01FFFFFF, + 0x00FFFFFF, + 0x007FFFFF, + 0x003FFFFF, + 0x001FFFFF, + 0x000FFFFF, + 0x0007FFFF, + 0x0003FFFF, + 0x0001FFFF, + 0x0000FFFF, + 0x00007FFF, + 0x00003FFF, + 0x00001FFF, + 0x00000FFF, + 0x000007FF, + 0x000003FF, + 0x000001FF, + 0x000000FF, + 0x0000007F, + 0x0000003F, + 0x0000001F, + 0x0000000F, + 0x00000007, + 0x00000003 +}; + + +float32 get_pat(int mode) { + +if(mode==0) { + p0 = 0; + p1 = 0; + return(0); + } +else +if(pat==1) return(get_pat0(mode)); +else +if(pat==2) return(get_pat1(mode)); +else +if(pat==3) return(get_pat2(mode)); + +else return(0); + +} + + + +float32 get_pat0(int mode) { +float32 x; + +if(mode==1) { + if(p0==pat0_cnt) p0 = 0; + x = pat0[p0]; + p0++; + return(x); + } + +if(mode==2) { + x = pat0[p1]; + if(p0==(pat0_cnt) ) p1++; + if(p1==pat0_cnt) p1 = 0; + return(x); + } + +return(0); +} + + + +float32 get_pat1(int mode) { +float32 x; + +if(mode==1) { + if(p0==pat1_cnt) p0 = 0; + x = pat1[p0]; + p0++; + return(x); + } + +if(mode==2) { + x = pat1[p1]; + if(p0==(pat1_cnt) ) p1++; + if(p1==pat1_cnt) p1 = 0; + return(x); + } + +return(0); +} + + +float32 get_pat2(int mode) { +float32 x; + +if(mode==1) { + if(p0==pat2_cnt) p0 = 0; + x = pat2[p0]; + p0++; + return(x); + } + +if(mode==2) { + x = pat2[p1]; + if(p0==(pat2_cnt) ) p1++; + if(p1==pat2_cnt) p1 = 0; + return(x); + } + +return(0); +} \ No newline at end of file Index: tags/released/test_vectors/pg-src/README =================================================================== --- tags/released/test_vectors/pg-src/README (nonexistent) +++ tags/released/test_vectors/pg-src/README (revision 7) @@ -0,0 +1,17 @@ + +Building PG +=========== + +To build the floating point test pattern generator, you first need +to get a copy of the SoftFloat library from: + +http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html + +Once installed, change directory to SoftFloat-2a/softfloat/bits32, +copy the included source file to this directory and compile +using a command like: + +gcc -I386-Win32-gcc -opg.exe fptpg.c softfloat.c + +This build has been tested on SPARC Solaris systems and WIndows NT +with cygwin and gcc. Index: tags/released/test_vectors/README =================================================================== --- tags/released/test_vectors/README (nonexistent) +++ tags/released/test_vectors/README (revision 7) @@ -0,0 +1,27 @@ + +Test Vectors +============ + +To make all the test vectors you need a program called 'pg'. +The included 'pg' is a Windows executable, build on a NT +system. If you need to compile your own 'pg' see the README +file in pg-src directory. + +The script 'mkall' builds all test vectors and places them +in to the proper directories. + +There are currently two types of tests: + +1) Directed Test. This test, test a specific funstional unit + and a specific rounding mode. They are located in the + directories rtne, rtzero, rup and rdown (Which represent + the different rounding modes). + +2) Completely Random Tests. Here the operation type and rounding + mode are randomly selected and may change every cycle. This + tests are located in the combo directory. + +There are currently 14,808,684 test vectors ! + +WARNING: You need about 470Mb of disk space to build all test +vectors !!! \ No newline at end of file Index: tags/released/verilog/post_norm.v =================================================================== --- tags/released/verilog/post_norm.v (nonexistent) +++ tags/released/verilog/post_norm.v (revision 7) @@ -0,0 +1,676 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// Post Norm //// +//// Floating Point Post Normalisation Unit //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +`timescale 1ns / 100ps + +module post_norm( clk, fpu_op, opas, sign, rmode, fract_in, exp_in, exp_ovf, + opa_dn, opb_dn, rem_00, div_opa_ldz, output_zero, out, + ine, overflow, underflow, f2i_out_sign); +input clk; +input [2:0] fpu_op; +input opas; +input sign; +input [1:0] rmode; +input [47:0] fract_in; +input [1:0] exp_ovf; +input [7:0] exp_in; +input opa_dn, opb_dn; +input rem_00; +input [4:0] div_opa_ldz; +input output_zero; +output [30:0] out; +output ine; +output overflow, underflow; +output f2i_out_sign; + +//////////////////////////////////////////////////////////////////////// +// +// Local Wires and registers +// + +wire [22:0] fract_out; +wire [7:0] exp_out; +wire [30:0] out; +wire exp_out1_co, overflow, underflow; +wire [22:0] fract_out_final; +reg [22:0] fract_out_rnd; +wire [8:0] exp_next_mi; +wire dn; +wire exp_rnd_adj; +wire [7:0] exp_out_final; +reg [7:0] exp_out_rnd; +wire op_dn = opa_dn | opb_dn; +wire op_mul = fpu_op[2:0]==3'b010; +wire op_div = fpu_op[2:0]==3'b011; +wire op_i2f = fpu_op[2:0]==3'b100; +wire op_f2i = fpu_op[2:0]==3'b101; +reg [5:0] fi_ldz; + +wire g, r, s; +wire round, round2, round2a, round2_fasu, round2_fmul; +wire [7:0] exp_out_rnd0, exp_out_rnd1, exp_out_rnd2, exp_out_rnd2a; +wire [22:0] fract_out_rnd0, fract_out_rnd1, fract_out_rnd2, fract_out_rnd2a; +wire exp_rnd_adj0, exp_rnd_adj2a; +wire r_sign; +wire ovf0, ovf1; +wire [23:0] fract_out_pl1; +wire [7:0] exp_out_pl1, exp_out_mi1; +wire exp_out_00, exp_out_fe, exp_out_ff, exp_in_00, exp_in_ff; +wire exp_out_final_ff, fract_out_7fffff; +wire [24:0] fract_trunc; +wire [7:0] exp_out1; +wire grs_sel; +wire fract_out_00, fract_in_00; +wire shft_co; +wire [8:0] exp_in_pl1, exp_in_mi1; +wire [47:0] fract_in_shftr; +wire [47:0] fract_in_shftl; + +wire [7:0] exp_div; +wire [7:0] shft2; +wire [7:0] exp_out1_mi1; +wire div_dn; +wire div_nr; +wire grs_sel_div; + +wire div_inf; +wire [6:0] fi_ldz_2a; +wire [7:0] fi_ldz_2; +wire [7:0] div_shft1, div_shft2, div_shft3, div_shft4; +wire div_shft1_co; +wire [8:0] div_exp1; +wire [7:0] div_exp2, div_exp3; +wire left_right, lr_mul, lr_div; +wire [7:0] shift_right, shftr_mul, shftr_div; +wire [7:0] shift_left, shftl_mul, shftl_div; +wire [7:0] fasu_shift; +wire [7:0] exp_fix_div; + +wire [7:0] exp_fix_diva, exp_fix_divb; +wire [5:0] fi_ldz_mi1; +wire [5:0] fi_ldz_mi22; +wire exp_zero; +wire [6:0] ldz_all; +wire [7:0] ldz_dif; + +wire [8:0] div_scht1a; +wire [7:0] f2i_shft; +wire [55:0] exp_f2i_1; +wire f2i_zero, f2i_max; +wire [7:0] f2i_emin; +wire [7:0] conv_shft; +wire [7:0] exp_i2f, exp_f2i, conv_exp; +wire round2_f2i; + +//////////////////////////////////////////////////////////////////////// +// +// Normalize and Round Logic +// + +// --------------------------------------------------------------------- +// Count Leading zeros in fraction + +always @(fract_in) + casex(fract_in) // synopsys full_case parallel_case + 48'b1???????????????????????????????????????????????: fi_ldz = 1; + 48'b01??????????????????????????????????????????????: fi_ldz = 2; + 48'b001?????????????????????????????????????????????: fi_ldz = 3; + 48'b0001????????????????????????????????????????????: fi_ldz = 4; + 48'b00001???????????????????????????????????????????: fi_ldz = 5; + 48'b000001??????????????????????????????????????????: fi_ldz = 6; + 48'b0000001?????????????????????????????????????????: fi_ldz = 7; + 48'b00000001????????????????????????????????????????: fi_ldz = 8; + 48'b000000001???????????????????????????????????????: fi_ldz = 9; + 48'b0000000001??????????????????????????????????????: fi_ldz = 10; + 48'b00000000001?????????????????????????????????????: fi_ldz = 11; + 48'b000000000001????????????????????????????????????: fi_ldz = 12; + 48'b0000000000001???????????????????????????????????: fi_ldz = 13; + 48'b00000000000001??????????????????????????????????: fi_ldz = 14; + 48'b000000000000001?????????????????????????????????: fi_ldz = 15; + 48'b0000000000000001????????????????????????????????: fi_ldz = 16; + 48'b00000000000000001???????????????????????????????: fi_ldz = 17; + 48'b000000000000000001??????????????????????????????: fi_ldz = 18; + 48'b0000000000000000001?????????????????????????????: fi_ldz = 19; + 48'b00000000000000000001????????????????????????????: fi_ldz = 20; + 48'b000000000000000000001???????????????????????????: fi_ldz = 21; + 48'b0000000000000000000001??????????????????????????: fi_ldz = 22; + 48'b00000000000000000000001?????????????????????????: fi_ldz = 23; + 48'b000000000000000000000001????????????????????????: fi_ldz = 24; + 48'b0000000000000000000000001???????????????????????: fi_ldz = 25; + 48'b00000000000000000000000001??????????????????????: fi_ldz = 26; + 48'b000000000000000000000000001?????????????????????: fi_ldz = 27; + 48'b0000000000000000000000000001????????????????????: fi_ldz = 28; + 48'b00000000000000000000000000001???????????????????: fi_ldz = 29; + 48'b000000000000000000000000000001??????????????????: fi_ldz = 30; + 48'b0000000000000000000000000000001?????????????????: fi_ldz = 31; + 48'b00000000000000000000000000000001????????????????: fi_ldz = 32; + 48'b000000000000000000000000000000001???????????????: fi_ldz = 33; + 48'b0000000000000000000000000000000001??????????????: fi_ldz = 34; + 48'b00000000000000000000000000000000001?????????????: fi_ldz = 35; + 48'b000000000000000000000000000000000001????????????: fi_ldz = 36; + 48'b0000000000000000000000000000000000001???????????: fi_ldz = 37; + 48'b00000000000000000000000000000000000001??????????: fi_ldz = 38; + 48'b000000000000000000000000000000000000001?????????: fi_ldz = 39; + 48'b0000000000000000000000000000000000000001????????: fi_ldz = 40; + 48'b00000000000000000000000000000000000000001???????: fi_ldz = 41; + 48'b000000000000000000000000000000000000000001??????: fi_ldz = 42; + 48'b0000000000000000000000000000000000000000001?????: fi_ldz = 43; + 48'b00000000000000000000000000000000000000000001????: fi_ldz = 44; + 48'b000000000000000000000000000000000000000000001???: fi_ldz = 45; + 48'b0000000000000000000000000000000000000000000001??: fi_ldz = 46; + 48'b00000000000000000000000000000000000000000000001?: fi_ldz = 47; + 48'b00000000000000000000000000000000000000000000000?: fi_ldz = 48; + endcase + + +// --------------------------------------------------------------------- +// Normalize + +wire exp_in_80; +wire rmode_00, rmode_01, rmode_10, rmode_11; + +// Misc common signals +assign exp_in_ff = &exp_in; +assign exp_in_00 = !(|exp_in); +assign exp_in_80 = exp_in[7] & !(|exp_in[6:0]); +assign exp_out_ff = &exp_out; +assign exp_out_00 = !(|exp_out); +assign exp_out_fe = &exp_out[7:1] & !exp_out[0]; +assign exp_out_final_ff = &exp_out_final; + +assign fract_out_7fffff = &fract_out; +assign fract_out_00 = !(|fract_out); +assign fract_in_00 = !(|fract_in); + +assign rmode_00 = (rmode==2'b00); +assign rmode_01 = (rmode==2'b01); +assign rmode_10 = (rmode==2'b10); +assign rmode_11 = (rmode==2'b11); + +// Fasu Output will be denormalized ... +assign dn = !op_mul & !op_div & (exp_in_00 | (exp_next_mi[8] & !fract_in[47]) ); + +// --------------------------------------------------------------------- +// Fraction Normalization +parameter f2i_emax = 8'h9d; + +// Incremented fraction for rounding +assign fract_out_pl1 = fract_out + 1; + +// Special Signals for f2i +assign f2i_emin = rmode_00 ? 8'h7e : 8'h7f; +assign f2i_zero = (!opas & (exp_inf2i_emax)) | (opas & (exp_inf2i_emax)) | (opas & (exp_in8'h16); + +assign f2i_shft = exp_in-8'h7d; + +// Select shifting direction +assign left_right = op_div ? lr_div : op_mul ? lr_mul : 1; + +assign lr_div = (op_dn & !exp_ovf[1] & exp_ovf[0]) ? 1 : + (op_dn & exp_ovf[1]) ? 0 : + (op_dn & div_shft1_co) ? 0 : + (op_dn & exp_out_00) ? 1 : + (!op_dn & exp_out_00 & !exp_ovf[1]) ? 1 : + exp_ovf[1] ? 0 : + 1; +assign lr_mul = (shft_co | (!exp_ovf[1] & exp_in_00) | + (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00) )) ? 1 : + ( exp_ovf[1] | exp_in_00 ) ? 0 : + 1; + +// Select Left and Right shift value +assign fasu_shift = (dn | exp_out_00) ? (exp_in_00 ? 8'h2 : exp_in_pl1[7:0]) : {2'h0, fi_ldz}; +assign shift_right = op_div ? shftr_div : shftr_mul; + +assign conv_shft = op_f2i ? f2i_shft : {2'h0, fi_ldz}; + +assign shift_left = op_div ? shftl_div : op_mul ? shftl_mul : (op_f2i | op_i2f) ? conv_shft : fasu_shift; + +assign shftl_mul = (shft_co | + (!exp_ovf[1] & exp_in_00) | + (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00))) ? exp_in_pl1[7:0] : {2'h0, fi_ldz}; + +assign shftl_div = ( op_dn & exp_out_00 & !(!exp_ovf[1] & exp_ovf[0])) ? div_shft1[7:0] : + (!op_dn & exp_out_00 & !exp_ovf[1]) ? exp_in[7:0] : + {2'h0, fi_ldz}; +assign shftr_div = (op_dn & exp_ovf[1]) ? div_shft3 : + (op_dn & div_shft1_co) ? div_shft4 : + div_shft2; +// Do the actual shifting +assign fract_in_shftr = (|shift_right[7:6]) ? 0 : fract_in>>shift_right[5:0]; +assign fract_in_shftl = (|shift_left[7:6] | (f2i_zero & op_f2i)) ? 0 : fract_in<f2i_emax) ? 0 : opas) : + ((exp_inf2i_emax) ? 1 : opas); + +assign exp_i2f = fract_in_00 ? (opas ? 8'h9e : 0) : (8'h9e-fi_ldz); +assign exp_f2i_1 = {{8{fract_in[47]}}, fract_in }<9'hfe) )) ? div_exp2 : + (opa_dn | (exp_in_00 & !exp_ovf[1]) ) ? 0 : + exp_out1_mi1; + +assign div_inf = opb_dn & !opa_dn & (div_exp1[7:0] < 8'h7f); + +// --------------------------------------------------------------------- +// Round + +// Extract rounding (GRS) bits +assign grs_sel_div = op_div & (exp_ovf[1] | div_dn | exp_out1_co | exp_out_00); + +assign g = grs_sel_div ? fract_out[0] : fract_out[0]; +assign r = grs_sel_div ? (fract_trunc[24] & !div_nr) : fract_trunc[24]; +assign s = grs_sel_div ? |fract_trunc[24:0] : (|fract_trunc[23:0] | (fract_trunc[24] & op_div)); + +// Round to nearest even +assign round = (g & r) | (r & s) ; +assign {exp_rnd_adj0, fract_out_rnd0} = round ? fract_out_pl1 : {1'b0, fract_out}; +assign exp_out_rnd0 = exp_rnd_adj0 ? exp_out_pl1 : exp_out; +assign ovf0 = exp_out_final_ff & !rmode_01 & !op_f2i; + +// round to zero +assign fract_out_rnd1 = (exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out; +assign exp_fix_div = (fi_ldz>22) ? exp_fix_diva : exp_fix_divb; +assign exp_out_rnd1 = (g & r & s & exp_in_ff) ? (op_div ? exp_fix_div : exp_next_mi[7:0]) : + (exp_out_ff & !op_f2i) ? exp_in : exp_out; +assign ovf1 = exp_out_ff & !dn; + +// round to +inf (UP) and -inf (DOWN) +assign r_sign = sign; + +assign round2a = !exp_out_fe | !fract_out_7fffff | (exp_out_fe & fract_out_7fffff); +assign round2_fasu = ((r | s) & !r_sign) & (!exp_out[7] | (exp_out[7] & round2a)); + +assign round2_fmul = !r_sign & + ( + (exp_ovf[1] & !fract_in_00 & + ( ((!exp_out1_co | op_dn) & (r | s | (!rem_00 & op_div) )) | fract_out_00 | (!op_dn & !op_div)) + ) | + ( + (r | s | (!rem_00 & op_div)) & ( + (!exp_ovf[1] & (exp_in_80 | !exp_ovf[0])) | op_div | + ( exp_ovf[1] & !exp_ovf[0] & exp_out1_co) + ) + ) + ); + +assign round2_f2i = rmode_10 & (( |fract_in[23:0] & !opas & (exp_in<8'h80 )) | (|fract_trunc)); +assign round2 = (op_mul | op_div) ? round2_fmul : op_f2i ? round2_f2i : round2_fasu; + +assign {exp_rnd_adj2a, fract_out_rnd2a} = round2 ? fract_out_pl1 : {1'b0, fract_out}; +assign exp_out_rnd2a = exp_rnd_adj2a ? ((exp_ovf[1] & op_mul) ? exp_out_mi1 : exp_out_pl1) : exp_out; + +assign fract_out_rnd2 = (r_sign & exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out_rnd2a; +assign exp_out_rnd2 = (r_sign & exp_out_ff & !op_f2i) ? 8'hfe : exp_out_rnd2a; + + +// Choose rounding mode +always @(rmode or exp_out_rnd0 or exp_out_rnd1 or exp_out_rnd2) + case(rmode) // synopsys full_case parallel_case + 0: exp_out_rnd = exp_out_rnd0; + 1: exp_out_rnd = exp_out_rnd1; + 2,3: exp_out_rnd = exp_out_rnd2; + endcase + +always @(rmode or fract_out_rnd0 or fract_out_rnd1 or fract_out_rnd2) + case(rmode) // synopsys full_case parallel_case + 0: fract_out_rnd = fract_out_rnd0; + 1: fract_out_rnd = fract_out_rnd1; + 2,3: fract_out_rnd = fract_out_rnd2; + endcase + +// --------------------------------------------------------------------- +// Final Output Mux +// Fix Output for denormalized and special numbers +wire max_num, inf_out; + +assign max_num = ( !rmode_00 & (op_mul | op_div ) & ( + ( exp_ovf[1] & exp_ovf[0]) | + (!exp_ovf[1] & !exp_ovf[0] & exp_in_ff & (fi_ldz_2<24) & (exp_out!=8'hfe) ) + ) + ) | + + ( op_div & ( + ( rmode_01 & ( div_inf | + (exp_out_ff & !exp_ovf[1] ) | + (exp_ovf[1] & exp_ovf[0] ) + ) + ) | + + ( rmode[1] & !exp_ovf[1] & ( + ( exp_ovf[0] & exp_in_ff & r_sign & fract_in[47] + ) | + + ( r_sign & ( + (fract_in[47] & div_inf) | + (exp_in[7] & !exp_out_rnd[7] & !exp_in_80 & exp_out!=8'h7f ) | + (exp_in[7] & exp_out_rnd[7] & r_sign & exp_out_ff & op_dn & + div_exp1>9'h0fe ) + ) + ) | + + ( exp_in_00 & r_sign & ( + div_inf | + (r_sign & exp_out_ff & fi_ldz_2<24) + ) + ) + ) + ) + ) + ); + + +assign inf_out = (rmode[1] & (op_mul | op_div) & !r_sign & ( (exp_in_ff & !op_div) | + (exp_ovf[1] & exp_ovf[0] & (exp_in_00 | exp_in[7]) ) + ) + ) | (div_inf & op_div & ( + rmode_00 | + (rmode[1] & !exp_in_ff & !exp_ovf[1] & !exp_ovf[0] & !r_sign ) | + (rmode[1] & !exp_ovf[1] & exp_ovf[0] & exp_in_00 & !r_sign) + ) + ) | (op_div & rmode[1] & exp_in_ff & op_dn & !r_sign & (fi_ldz_2 < 24) & (exp_out_rnd!=8'hfe) ); + +assign fract_out_final = (inf_out | ovf0 | output_zero ) ? 23'h0 : + (max_num | (f2i_max & op_f2i) ) ? 23'h7fffff : + fract_out_rnd; + +assign exp_out_final = ((op_div & exp_ovf[1] & !exp_ovf[0]) | output_zero ) ? 8'h00 : + ((op_div & exp_ovf[1] & exp_ovf[0] & rmode_00) | inf_out | (f2i_max & op_f2i) ) ? 8'hff : + max_num ? 8'hfe : + exp_out_rnd; + + +// --------------------------------------------------------------------- +// Pack Result + +assign out = {exp_out_final, fract_out_final}; + +// --------------------------------------------------------------------- +// Exceptions +wire underflow_fmul; +wire overflow_fdiv; +wire undeflow_div; + +wire z = shft_co | ( exp_ovf[1] | exp_in_00) | + (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00)); + +assign underflow_fmul = ( (|fract_trunc) & z & !exp_in_ff ) | + (fract_out_00 & !fract_in_00 & exp_ovf[1]); + +assign undeflow_div = !(exp_ovf[1] & exp_ovf[0] & rmode_00) & !inf_out & !max_num & exp_out_final!=8'hff & ( + + ((|fract_trunc) & !opb_dn & ( + ( op_dn & !exp_ovf[1] & exp_ovf[0]) | + ( op_dn & exp_ovf[1]) | + ( op_dn & div_shft1_co) | + exp_out_00 | + exp_ovf[1] + ) + + ) | + + ( exp_ovf[1] & !exp_ovf[0] & ( + ( op_dn & exp_in>8'h16 & fi_ldz<23) | + ( op_dn & exp_in<23 & fi_ldz<23 & !rem_00) | + ( !op_dn & (exp_in[7]==exp_div[7]) & !rem_00) | + ( !op_dn & exp_in_00 & (exp_div[7:1]==7'h7f) ) | + ( !op_dn & exp_in<8'h7f & exp_in>8'h20 ) + ) + ) | + + (!exp_ovf[1] & !exp_ovf[0] & ( + ( op_dn & fi_ldz<23 & exp_out_00) | + ( exp_in_00 & !rem_00) | + ( !op_dn & ldz_all<23 & exp_in==1 & exp_out_00 & !rem_00) + ) + ) + + ); + +assign underflow = op_div ? undeflow_div : op_mul ? underflow_fmul : (!fract_in[47] & exp_out1_co) & !dn; + +assign overflow_fdiv = inf_out | + (!rmode_00 & max_num) | + (exp_in[7] & op_dn & exp_out_ff) | + (exp_ovf[0] & (exp_ovf[1] | exp_out_ff) ); + +assign overflow = op_div ? overflow_fdiv : (ovf0 | ovf1); + +wire f2i_ine; + +assign f2i_ine = (f2i_zero & !fract_in_00 & !opas) | + (|fract_trunc) | + (f2i_zero & (exp_in<8'h80) & opas & !fract_in_00) | + (f2i_max & rmode_11 & (exp_in<8'h80)); + + + +assign ine = op_f2i ? f2i_ine : + op_i2f ? (|fract_trunc) : + ((r & !dn) | (s & !dn) | max_num | (op_div & !rem_00)); + +// --------------------------------------------------------------------- +// Debugging Stuff + +// synopsys translate_off + +wire [26:0] fracta_del, fractb_del; +wire [2:0] grs_del; +wire dn_del; +wire [7:0] exp_in_del; +wire [7:0] exp_out_del; +wire [22:0] fract_out_del; +wire [47:0] fract_in_del; +wire overflow_del; +wire [1:0] exp_ovf_del; +wire [22:0] fract_out_x_del, fract_out_rnd2a_del; +wire [24:0] trunc_xx_del; +wire exp_rnd_adj2a_del; +wire [22:0] fract_dn_del; +wire [4:0] div_opa_ldz_del; +wire [23:0] fracta_div_del; +wire [23:0] fractb_div_del; +wire div_inf_del; +wire [7:0] fi_ldz_2_del; +wire inf_out_del, max_out_del; +wire [5:0] fi_ldz_del; +wire rx_del; +wire ez_del; +wire lr; +wire [7:0] shr, shl, exp_div_del; + +delay2 #26 ud000(clk, test.u0.fracta, fracta_del); +delay2 #26 ud001(clk, test.u0.fractb, fractb_del); +delay1 #2 ud002(clk, {g,r,s}, grs_del); +delay1 #0 ud004(clk, dn, dn_del); +delay1 #7 ud005(clk, exp_in, exp_in_del); +delay1 #7 ud007(clk, exp_out_rnd, exp_out_del); +delay1 #47 ud009(clk, fract_in, fract_in_del); +delay1 #0 ud010(clk, overflow, overflow_del); +delay1 #1 ud011(clk, exp_ovf, exp_ovf_del); +delay1 #22 ud014(clk, fract_out, fract_out_x_del); +delay1 #24 ud015(clk, fract_trunc, trunc_xx_del); +delay1 #0 ud017(clk, exp_rnd_adj2a, exp_rnd_adj2a_del); +delay1 #4 ud019(clk, div_opa_ldz, div_opa_ldz_del); +delay3 #23 ud020(clk, test.u0.fdiv_opa[49:26], fracta_div_del); +delay3 #23 ud021(clk, test.u0.fractb_mul, fractb_div_del); +delay1 #0 ud023(clk, div_inf, div_inf_del); +delay1 #7 ud024(clk, fi_ldz_2, fi_ldz_2_del); +delay1 #0 ud025(clk, inf_out, inf_out_del); +delay1 #0 ud026(clk, max_num, max_num_del); +delay1 #5 ud027(clk, fi_ldz, fi_ldz_del); +delay1 #0 ud028(clk, rem_00, rx_del); + +delay1 #0 ud029(clk, left_right, lr); +delay1 #7 ud030(clk, shift_right, shr); +delay1 #7 ud031(clk, shift_left, shl); +delay1 #22 ud032(clk, fract_out_rnd2a, fract_out_rnd2a_del); + +delay1 #7 ud033(clk, exp_div, exp_div_del); + +always @(test.error_event) + begin + + $display("\n----------------------------------------------"); + + $display("ERROR: GRS: %b exp_ovf: %b dn: %h exp_in: %h exp_out: %h, exp_rnd_adj2a: %b", + grs_del, exp_ovf_del, dn_del, exp_in_del, exp_out_del, exp_rnd_adj2a_del); + + $display(" div_opa: %b, div_opb: %b, rem_00: %b, exp_div: %h", + fracta_div_del, fractb_div_del, rx_del, exp_div_del); + + $display(" lr: %b, shl: %h, shr: %h", + lr, shl, shr); + + + $display(" overflow: %b, fract_in=%b fa:%h fb:%h", + overflow_del, fract_in_del, fracta_del, fractb_del); + + $display(" div_opa_ldz: %h, div_inf: %b, inf_out: %b, max_num: %b, fi_ldz: %h, fi_ldz_2: %h", + div_opa_ldz_del, div_inf_del, inf_out_del, max_num_del, fi_ldz_del, fi_ldz_2_del); + + $display(" fract_out_x: %b, fract_out_rnd2a_del: %h, fract_trunc: %b\n", + fract_out_x_del, fract_out_rnd2a_del, trunc_xx_del); + end + + +// synopsys translate_on + +endmodule + +// synopsys translate_off + +module delay1(clk, in, out); +parameter N = 1; +input [N:0] in; +output [N:0] out; +input clk; + +reg [N:0] out; + +always @(posedge clk) + out <= #1 in; + +endmodule + + +module delay2(clk, in, out); +parameter N = 1; +input [N:0] in; +output [N:0] out; +input clk; + +reg [N:0] out, r1; + +always @(posedge clk) + r1 <= #1 in; + +always @(posedge clk) + out <= #1 r1; + +endmodule + +module delay3(clk, in, out); +parameter N = 1; +input [N:0] in; +output [N:0] out; +input clk; + +reg [N:0] out, r1, r2; + +always @(posedge clk) + r1 <= #1 in; + +always @(posedge clk) + r2 <= #1 r1; + +always @(posedge clk) + out <= #1 r2; + +endmodule + +// synopsys translate_on \ No newline at end of file Index: tags/released/verilog/fpu.v =================================================================== --- tags/released/verilog/fpu.v (nonexistent) +++ tags/released/verilog/fpu.v (revision 7) @@ -0,0 +1,560 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// FPU //// +//// Floating Point Unit (Single precision) //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +`timescale 1ns / 100ps + +/* + +FPU Operations (fpu_op): +======================== + +0 = add +1 = sub +2 = mul +3 = div +4 = +5 = +6 = +7 = + +Rounding Modes (rmode): +======================= + +0 = round_nearest_even +1 = round_to_zero +2 = round_up +3 = round_down + +*/ + + +module fpu( clk, rmode, fpu_op, opa, opb, out, inf, snan, qnan, ine, overflow, underflow, zero, div_by_zero); +input clk; +input [1:0] rmode; +input [2:0] fpu_op; +input [31:0] opa, opb; +output [31:0] out; +output inf, snan, qnan; +output ine; +output overflow, underflow; +output zero; +output div_by_zero; + +parameter INF = 31'h7f800000, + QNAN = 31'h7fc00001, + SNAN = 31'h7f800001; + +//////////////////////////////////////////////////////////////////////// +// +// Local Wires +// +reg zero; +reg [31:0] opa_r, opb_r; // Input operand registers +reg [31:0] out; // Output register +reg div_by_zero; // Divide by zero output register +wire signa, signb; // alias to opX sign +wire sign_fasu; // sign output +wire [26:0] fracta, fractb; // Fraction Outputs from EQU block +wire [7:0] exp_fasu; // Exponent output from EQU block +reg [7:0] exp_r; // Exponent output (registerd) +wire [26:0] fract_out_d; // fraction output +wire co; // carry output +reg [27:0] fract_out_q; // fraction output (registerd) +wire [30:0] out_d; // Intermediate final result output +wire overflow_d, underflow_d;// Overflow/Underflow Indicators +reg overflow, underflow; // Output registers for Overflow & Underflow +reg inf, snan, qnan; // Output Registers for INF, SNAN and QNAN +reg ine; // Output Registers for INE +reg [1:0] rmode_r1, rmode_r2, // Pipeline registers for rounding mode + rmode_r3; +reg [2:0] fpu_op_r1, fpu_op_r2, // Pipeline registers for fp opration + fpu_op_r3; +wire mul_inf, div_inf; +wire mul_00, div_00; + +//////////////////////////////////////////////////////////////////////// +// +// Input Registers +// + +always @(posedge clk) + opa_r <= #1 opa; + +always @(posedge clk) + opb_r <= #1 opb; + +always @(posedge clk) + rmode_r1 <= #1 rmode; + +always @(posedge clk) + rmode_r2 <= #1 rmode_r1; + +always @(posedge clk) + rmode_r3 <= #1 rmode_r2; + +always @(posedge clk) + fpu_op_r1 <= #1 fpu_op; + +always @(posedge clk) + fpu_op_r2 <= #1 fpu_op_r1; + +always @(posedge clk) + fpu_op_r3 <= #1 fpu_op_r2; + +//////////////////////////////////////////////////////////////////////// +// +// Exceptions block +// +wire inf_d, ind_d, qnan_d, snan_d, opa_nan, opb_nan; +wire opa_00, opb_00; +wire opa_inf, opb_inf; +wire opa_dn, opb_dn; + +except u0( .clk(clk), + .opa(opa_r), .opb(opb_r), + .inf(inf_d), .ind(ind_d), + .qnan(qnan_d), .snan(snan_d), + .opa_nan(opa_nan), .opb_nan(opb_nan), + .opa_00(opa_00), .opb_00(opb_00), + .opa_inf(opa_inf), .opb_inf(opb_inf), + .opa_dn(opa_dn), .opb_dn(opb_dn) + ); + +//////////////////////////////////////////////////////////////////////// +// +// Pre-Normalize block +// - Adjusts the numbers to equal exponents and sorts them +// - determine result sign +// - determine actual operation to perform (add or sub) +// + +wire nan_sign_d, result_zero_sign_d; +reg sign_fasu_r; +wire [7:0] exp_mul; +wire sign_mul; +reg sign_mul_r; +wire [23:0] fracta_mul, fractb_mul; +wire inf_mul; +reg inf_mul_r; +wire [1:0] exp_ovf; +reg [1:0] exp_ovf_r; +wire sign_exe; +reg sign_exe_r; +wire [2:0] underflow_fmul_d; + + +pre_norm u1(.clk(clk), // System Clock + .rmode(rmode_r2), // Roundin Mode + .add(!fpu_op_r1[0]), // Add/Sub Input + .opa(opa_r), .opb(opb_r), // Registered OP Inputs + .opa_nan(opa_nan), // OpA is a NAN indicator + .opb_nan(opb_nan), // OpB is a NAN indicator + .fracta_out(fracta), // Equalized and sorted fraction + .fractb_out(fractb), // outputs (Registered) + .exp_dn_out(exp_fasu), // Selected exponent output (registered); + .sign(sign_fasu), // Encoded output Sign (registered) + .nan_sign(nan_sign_d), // Output Sign for NANs (registered) + .result_zero_sign(result_zero_sign_d), // Output Sign for zero result (registered) + .fasu_op(fasu_op) // Actual fasu operation output (registered) + ); + +always @(posedge clk) + sign_fasu_r <= #1 sign_fasu; + +pre_norm_fmul u2( + .clk(clk), + .fpu_op(fpu_op_r1), + .opa(opa_r), .opb(opb_r), + .fracta(fracta_mul), + .fractb(fractb_mul), + .exp_out(exp_mul), // FMUL exponent output (registered) + .sign(sign_mul), // FMUL sign output (registered) + .sign_exe(sign_exe), // FMUL exception sign output (registered) + .inf(inf_mul), // FMUL inf output (registered) + .exp_ovf(exp_ovf), // FMUL exponnent overflow output (registered) + .underflow(underflow_fmul_d) + ); + + +always @(posedge clk) + sign_mul_r <= #1 sign_mul; + +always @(posedge clk) + sign_exe_r <= #1 sign_exe; + +always @(posedge clk) + inf_mul_r <= #1 inf_mul; + +always @(posedge clk) + exp_ovf_r <= #1 exp_ovf; + + +//////////////////////////////////////////////////////////////////////// +// +// Add/Sub +// + +add_sub27 u3( + .add(fasu_op), // Add/Sub + .opa(fracta), // Fraction A input + .opb(fractb), // Fraction B Input + .sum(fract_out_d), // SUM output + .co(co_d) ); // Carry Output + +always @(posedge clk) + fract_out_q <= #1 {co_d, fract_out_d}; + +//////////////////////////////////////////////////////////////////////// +// +// Mul +// +wire [47:0] prod; + +mul_r2 u5(.clk(clk), .opa(fracta_mul), .opb(fractb_mul), .prod(prod)); + +//////////////////////////////////////////////////////////////////////// +// +// Divide +// +wire [49:0] quo; +wire [49:0] fdiv_opa; +wire [49:0] remainder; +wire remainder_00; +reg [4:0] div_opa_ldz_d, div_opa_ldz_r1, div_opa_ldz_r2; + +always @(fracta_mul) + casex(fracta_mul[22:0]) + 23'b1??????????????????????: div_opa_ldz_d = 1; + 23'b01?????????????????????: div_opa_ldz_d = 2; + 23'b001????????????????????: div_opa_ldz_d = 3; + 23'b0001???????????????????: div_opa_ldz_d = 4; + 23'b00001??????????????????: div_opa_ldz_d = 5; + 23'b000001?????????????????: div_opa_ldz_d = 6; + 23'b0000001????????????????: div_opa_ldz_d = 7; + 23'b00000001???????????????: div_opa_ldz_d = 8; + 23'b000000001??????????????: div_opa_ldz_d = 9; + 23'b0000000001?????????????: div_opa_ldz_d = 10; + 23'b00000000001????????????: div_opa_ldz_d = 11; + 23'b000000000001???????????: div_opa_ldz_d = 12; + 23'b0000000000001??????????: div_opa_ldz_d = 13; + 23'b00000000000001?????????: div_opa_ldz_d = 14; + 23'b000000000000001????????: div_opa_ldz_d = 15; + 23'b0000000000000001???????: div_opa_ldz_d = 16; + 23'b00000000000000001??????: div_opa_ldz_d = 17; + 23'b000000000000000001?????: div_opa_ldz_d = 18; + 23'b0000000000000000001????: div_opa_ldz_d = 19; + 23'b00000000000000000001???: div_opa_ldz_d = 20; + 23'b000000000000000000001??: div_opa_ldz_d = 21; + 23'b0000000000000000000001?: div_opa_ldz_d = 22; + 23'b0000000000000000000000?: div_opa_ldz_d = 23; + endcase + +assign fdiv_opa = !(|opa_r[30:23]) ? {(fracta_mul< expb; // expa is larger than expb + +// --------------------------------------------------------------------- +// Normalize + +assign expa_dn = !(|expa); // opa denormalized +assign expb_dn = !(|expb); // opb denormalized + +// --------------------------------------------------------------------- +// Calculate the difference between the smaller and larger exponent + +wire [7:0] exp_diff1, exp_diff1a, exp_diff2; + +assign exp_small = expa_lt_expb ? expb : expa; +assign exp_large = expa_lt_expb ? expa : expb; +assign exp_diff1 = exp_large - exp_small; +assign exp_diff1a = exp_diff1-1; +assign exp_diff2 = (expa_dn | expb_dn) ? exp_diff1a : exp_diff1; +assign exp_diff = (expa_dn & expb_dn) ? 8'h0 : exp_diff2; + +always @(posedge clk) // If numbers are equal we should return zero + exp_dn_out <= #1 (!add_d & expa==expb & fracta==fractb) ? 8'h0 : exp_large; + +// --------------------------------------------------------------------- +// Adjust the smaller fraction + + +assign op_dn = expa_lt_expb ? expb_dn : expa_dn; +assign adj_op = expa_lt_expb ? fractb : fracta; +assign adj_op_tmp = { ~op_dn, adj_op, 3'b0 }; // recover hidden bit (op_dn) + +// adj_op_out is 27 bits wide, so can only be shifted 27 bits to the right +assign exp_lt_27 = exp_diff > 8'd27; +assign exp_diff_sft = exp_lt_27 ? 5'd27 : exp_diff[4:0]; +assign adj_op_out_sft = adj_op_tmp >> exp_diff_sft; +assign adj_op_out = {adj_op_out_sft[26:1], adj_op_out_sft[0] | sticky }; + +// --------------------------------------------------------------------- +// Get truncated portion (sticky bit) + +always @(exp_diff_sft or adj_op_tmp) + case(exp_diff_sft) // synopsys full_case parallel_case + 00: sticky = 1'h0; + 01: sticky = adj_op_tmp[0]; + 02: sticky = |adj_op_tmp[01:0]; + 03: sticky = |adj_op_tmp[02:0]; + 04: sticky = |adj_op_tmp[03:0]; + 05: sticky = |adj_op_tmp[04:0]; + 06: sticky = |adj_op_tmp[05:0]; + 07: sticky = |adj_op_tmp[06:0]; + 08: sticky = |adj_op_tmp[07:0]; + 09: sticky = |adj_op_tmp[08:0]; + 10: sticky = |adj_op_tmp[09:0]; + 11: sticky = |adj_op_tmp[10:0]; + 12: sticky = |adj_op_tmp[11:0]; + 13: sticky = |adj_op_tmp[12:0]; + 14: sticky = |adj_op_tmp[13:0]; + 15: sticky = |adj_op_tmp[14:0]; + 16: sticky = |adj_op_tmp[15:0]; + 17: sticky = |adj_op_tmp[16:0]; + 18: sticky = |adj_op_tmp[17:0]; + 19: sticky = |adj_op_tmp[18:0]; + 20: sticky = |adj_op_tmp[19:0]; + 21: sticky = |adj_op_tmp[20:0]; + 22: sticky = |adj_op_tmp[21:0]; + 23: sticky = |adj_op_tmp[22:0]; + 24: sticky = |adj_op_tmp[23:0]; + 25: sticky = |adj_op_tmp[24:0]; + 26: sticky = |adj_op_tmp[25:0]; + 27: sticky = |adj_op_tmp[26:0]; + endcase + +// --------------------------------------------------------------------- +// Select operands for add/sub (recover hidden bit) + +assign fracta_n = expa_lt_expb ? {~expa_dn, fracta, 3'b0} : adj_op_out; +assign fractb_n = expa_lt_expb ? adj_op_out : {~expb_dn, fractb, 3'b0}; + +// --------------------------------------------------------------------- +// Sort operands (for sub only) + +assign fractb_lt_fracta = fractb_n > fracta_n; // fractb is larger than fracta +assign fracta_s = fractb_lt_fracta ? fractb_n : fracta_n; +assign fractb_s = fractb_lt_fracta ? fracta_n : fractb_n; + +always @(posedge clk) + fracta_out <= #1 fracta_s; + +always @(posedge clk) + fractb_out <= #1 fractb_s; + +// --------------------------------------------------------------------- +// Determine sign for the output + +// sign: 0=Positive Number; 1=Negative Number +always @(signa or signb or add or fractb_lt_fracta) + case({signa, signb, add}) // synopsys full_case parallel_case + + // Add + 3'b0_0_1: sign_d = 0; + 3'b0_1_1: sign_d = fractb_lt_fracta; + 3'b1_0_1: sign_d = !fractb_lt_fracta; + 3'b1_1_1: sign_d = 1; + + // Sub + 3'b0_0_0: sign_d = fractb_lt_fracta; + 3'b0_1_0: sign_d = 0; + 3'b1_0_0: sign_d = 1; + 3'b1_1_0: sign_d = !fractb_lt_fracta; + endcase + +always @(posedge clk) + sign <= #1 sign_d; + +// Fix sign for ZERO result +always @(posedge clk) + signa_r <= #1 signa; + +always @(posedge clk) + signb_r <= #1 signb; + +always @(posedge clk) + add_r <= #1 add; + +always @(posedge clk) + result_zero_sign <= #1 ( add_r & signa_r & signb_r) | + (!add_r & signa_r & !signb_r) | + ( add_r & (signa_r | signb_r) & (rmode==3)) | + (!add_r & (signa_r == signb_r) & (rmode==3)); + +// Fix sign for NAN result +always @(posedge clk) + fracta_lt_fractb <= #1 fracta < fractb; + +always @(posedge clk) + fracta_eq_fractb <= #1 fracta == fractb; + +assign nan_sign1 = fracta_eq_fractb ? (signa_r & signb_r) : fracta_lt_fractb ? signb_r : signa_r; + +always @(posedge clk) + nan_sign <= #1 (opa_nan & opb_nan) ? nan_sign1 : opb_nan ? signb_r : signa_r; + +//////////////////////////////////////////////////////////////////////// +// +// Decode Add/Sub operation +// + +// add: 1=Add; 0=Subtract +always @(signa or signb or add) + case({signa, signb, add}) // synopsys full_case parallel_case + + // Add + 3'b0_0_1: add_d = 1; + 3'b0_1_1: add_d = 0; + 3'b1_0_1: add_d = 0; + 3'b1_1_1: add_d = 1; + + // Sub + 3'b0_0_0: add_d = 0; + 3'b0_1_0: add_d = 1; + 3'b1_0_0: add_d = 1; + 3'b1_1_0: add_d = 0; + endcase + +always @(posedge clk) + fasu_op <= #1 add_d; + +endmodule Index: tags/released/verilog/pre_norm_fmul.v =================================================================== --- tags/released/verilog/pre_norm_fmul.v (nonexistent) +++ tags/released/verilog/pre_norm_fmul.v (revision 7) @@ -0,0 +1,150 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// Pre Normalize //// +//// Floating Point Pre Normalization Unit for FMUL //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +`timescale 1ns / 100ps + +module pre_norm_fmul(clk, fpu_op, opa, opb, fracta, fractb, exp_out, sign, + sign_exe, inf, exp_ovf, underflow); +input clk; +input [2:0] fpu_op; +input [31:0] opa, opb; +output [23:0] fracta, fractb; +output [7:0] exp_out; +output sign, sign_exe; +output inf; +output [1:0] exp_ovf; +output [2:0] underflow; + +//////////////////////////////////////////////////////////////////////// +// +// Local Wires and registers +// + +reg [7:0] exp_out; +wire signa, signb; +reg sign, sign_d; +reg sign_exe; +reg inf; +wire [1:0] exp_ovf_d; +reg [1:0] exp_ovf; +wire [7:0] expa, expb; +wire [7:0] exp_tmp1, exp_tmp2; +wire co1, co2; +wire expa_dn, expb_dn; +wire [7:0] exp_out_a; +wire opa_00, opb_00, fracta_00, fractb_00; +wire [7:0] exp_tmp3, exp_tmp4, exp_tmp5; +wire [2:0] underflow_d; +reg [2:0] underflow; +wire op_div = (fpu_op == 3'b011); +wire [7:0] exp_out_mul, exp_out_div; + +//////////////////////////////////////////////////////////////////////// +// +// Aliases +// + +assign signa = opa[31]; +assign signb = opb[31]; +assign expa = opa[30:23]; +assign expb = opb[30:23]; + +//////////////////////////////////////////////////////////////////////// +// +// Calculate Exponenet +// + +assign expa_dn = !(|expa); +assign expb_dn = !(|expb); +assign opa_00 = !(|opa[30:0]); +assign opb_00 = !(|opb[30:0]); +assign fracta_00 = !(|opa[22:0]); +assign fractb_00 = !(|opb[22:0]); + +assign fracta = {!expa_dn,opa[22:0]}; // Recover hidden bit +assign fractb = {!expb_dn,opb[22:0]}; // Recover hidden bit + +assign {co1,exp_tmp1} = op_div ? (expa - expb) : (expa + expb); +assign {co2,exp_tmp2} = op_div ? ({co1,exp_tmp1} + 8'h7f) : ({co1,exp_tmp1} - 8'h7f); + +assign exp_tmp3 = exp_tmp2 + 1; +assign exp_tmp4 = 8'h7f - exp_tmp1; +assign exp_tmp5 = op_div ? (exp_tmp4+1) : (exp_tmp4-1); + + +always@(posedge clk) + exp_out <= #1 op_div ? exp_out_div : exp_out_mul; + +assign exp_out_div = (expa_dn | expb_dn) ? (co2 ? exp_tmp5 : exp_tmp3 ) : co2 ? exp_tmp4 : exp_tmp2; +assign exp_out_mul = exp_ovf_d[1] ? exp_out_a : (expa_dn | expb_dn) ? exp_tmp3 : exp_tmp2; +assign exp_out_a = (expa_dn | expb_dn) ? exp_tmp5 : exp_tmp4; +assign exp_ovf_d[0] = op_div ? (expa[7] & !expb[7]) : (co2 & expa[7] & expb[7]); +assign exp_ovf_d[1] = op_div ? co2 : ((!expa[7] & !expb[7] & exp_tmp2[7]) | co2); + +always @(posedge clk) + exp_ovf <= #1 exp_ovf_d; + +assign underflow_d[0] = (exp_tmp1 < 8'h7f) & !co1 & !(opa_00 | opb_00 | expa_dn | expb_dn); +assign underflow_d[1] = ((expa[7] | expb[7]) & !opa_00 & !opb_00) | + (expa_dn & !fracta_00) | (expb_dn & !fractb_00); +assign underflow_d[2] = !opa_00 & !opb_00 & (exp_tmp1 == 8'h7f); + +always @(posedge clk) + underflow <= #1 underflow_d; + +always @(posedge clk) + inf <= #1 op_div ? (expb_dn & !expa[7]) : ({co1,exp_tmp1} > 9'h17e) ; + + +//////////////////////////////////////////////////////////////////////// +// +// Determine sign for the output +// + +// sign: 0=Posetive Number; 1=Negative Number +always @(signa or signb) + case({signa, signb}) // synopsys full_case parallel_case + 2'b0_0: sign_d = 0; + 2'b0_1: sign_d = 1; + 2'b1_0: sign_d = 1; + 2'b1_1: sign_d = 0; + endcase + +always @(posedge clk) + sign <= #1 sign_d; + +always @(posedge clk) + sign_exe <= #1 signa & signb; + +endmodule \ No newline at end of file Index: tags/released/verilog/except.v =================================================================== --- tags/released/verilog/except.v (nonexistent) +++ tags/released/verilog/except.v (revision 7) @@ -0,0 +1,153 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// EXCEPT //// +//// Floating Point Exception/Special Numbers Unit //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +`timescale 1ns / 100ps + + +module except( clk, opa, opb, inf, ind, qnan, snan, opa_nan, opb_nan, + opa_00, opb_00, opa_inf, opb_inf, opa_dn, opb_dn); +input clk; +input [31:0] opa, opb; +output inf, ind, qnan, snan, opa_nan, opb_nan; +output opa_00, opb_00; +output opa_inf, opb_inf; +output opa_dn; +output opb_dn; + +//////////////////////////////////////////////////////////////////////// +// +// Local Wires and registers +// + +wire [7:0] expa, expb; // alias to opX exponent +wire [22:0] fracta, fractb; // alias to opX fraction +reg expa_ff, infa_f_r, qnan_r_a, snan_r_a; +reg expb_ff, infb_f_r, qnan_r_b, snan_r_b; +reg inf, ind, qnan, snan; // Output registers +reg opa_nan, opb_nan; +reg expa_00, expb_00, fracta_00, fractb_00; +reg opa_00, opb_00; +reg opa_inf, opb_inf; +reg opa_dn, opb_dn; + +//////////////////////////////////////////////////////////////////////// +// +// Aliases +// + +assign expa = opa[30:23]; +assign expb = opb[30:23]; +assign fracta = opa[22:0]; +assign fractb = opb[22:0]; + +//////////////////////////////////////////////////////////////////////// +// +// Determine if any of the input operators is a INF or NAN or any other special number +// + +always @(posedge clk) + expa_ff <= #1 &expa; + +always @(posedge clk) + expb_ff <= #1 &expb; + +always @(posedge clk) + infa_f_r <= #1 !(|fracta); + +always @(posedge clk) + infb_f_r <= #1 !(|fractb); + +always @(posedge clk) + qnan_r_a <= #1 fracta[22]; + +always @(posedge clk) + snan_r_a <= #1 !fracta[22] & |fracta[21:0]; + +always @(posedge clk) + qnan_r_b <= #1 fractb[22]; + +always @(posedge clk) + snan_r_b <= #1 !fractb[22] & |fractb[21:0]; + +always @(posedge clk) + ind <= #1 (expa_ff & infa_f_r) & (expb_ff & infb_f_r); + +always @(posedge clk) + inf <= #1 (expa_ff & infa_f_r) | (expb_ff & infb_f_r); + +always @(posedge clk) + qnan <= #1 (expa_ff & qnan_r_a) | (expb_ff & qnan_r_b); + +always @(posedge clk) + snan <= #1 (expa_ff & snan_r_a) | (expb_ff & snan_r_b); + +always @(posedge clk) + opa_nan <= #1 &expa & (|fracta[22:0]); + +always @(posedge clk) + opb_nan <= #1 &expb & (|fractb[22:0]); + +always @(posedge clk) + opa_inf <= #1 (expa_ff & infa_f_r); + +always @(posedge clk) + opb_inf <= #1 (expb_ff & infb_f_r); + +always @(posedge clk) + expa_00 <= #1 !(|expa); + +always @(posedge clk) + expb_00 <= #1 !(|expb); + +always @(posedge clk) + fracta_00 <= #1 !(|fracta); + +always @(posedge clk) + fractb_00 <= #1 !(|fractb); + +always @(posedge clk) + opa_00 <= #1 expa_00 & fracta_00; + +always @(posedge clk) + opb_00 <= #1 expb_00 & fractb_00; + +always @(posedge clk) + opa_dn <= #1 expa_00; + +always @(posedge clk) + opb_dn <= #1 expb_00; + +endmodule + Index: tags/released/README =================================================================== --- tags/released/README (nonexistent) +++ tags/released/README (revision 7) @@ -0,0 +1,42 @@ +FPU Notes +--------- + +1) The FPU will never generate a SNAN output +1a) The SNAN output is asserted when one of the operands + was a signaling NAN (output will be a quiet NAN). +1b) The QNAN output is asserted whenever the OUTPUT of + the FPU is NAN (always a quiet NAN). + + + + +The FPU consists of the following files: + + verilog/fpu.v + verilog/pre_norm.v + verilog/primitives.v + verilog/post_norm.v + verilog/except.v", + verilog/pre_norm_fmul.v + +(fpu.v is the top level) + +The testbench is in: test_bench/test_top.v + +To simulate the FPU using the included test bench +us a comand like: + +verilog test_bench/test_top.v \ + verilog/fpu.v \ + verilog/pre_norm.v \ + verilog/primitives.v \ + verilog/post_norm.v \ + verilog/except.v \ + verilog/pre_norm_fmul.v + + +Do not change the directory structure, the testbench +depends on it ! + +Please also read the README file in the test_vectors +directory. Index: tags/released/test_bench/test_top.v =================================================================== --- tags/released/test_bench/test_top.v (nonexistent) +++ tags/released/test_bench/test_top.v (revision 7) @@ -0,0 +1,434 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// FPU //// +//// Floating Point Unit (Single precision) //// +//// //// +//// TEST BENCH //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +`timescale 1ns / 100ps + +module test; + +reg clk; +reg [31:0] opa; +reg [31:0] opb; +wire [31:0] sum; +wire inf, snan, qnan; +wire div_by_zero; + +reg [31:0] exp, exp1, exp2, exp3, exp4; +reg [31:0] opa1, opa2, opa3, opa4; +reg [31:0] opb1, opb2, opb3, opb4; +reg [2:0] fpu_op, fpu_op1, fpu_op2, fpu_op3, fpu_op4, fpu_op5; +reg [3:0] rmode, rmode1, rmode2, rmode3, rmode4, rmode5; +reg start, s1, s2, s3, s4; +reg [115:0] tmem[0:500000]; +reg [115:0] tmp; +reg [7:0] oper; +reg [7:0] exc, exc1, exc2, exc3, exc4; +integer i; +wire ine; +reg match; +wire overflow, underflow; +wire zero; +reg exc_err; +reg m0, m1, m2; +reg [1:0] fpu_rmode; +reg [3:0] test_rmode; +reg [4:0] test_sel; +reg fp_fasu; +reg fp_mul; +reg fp_div; +reg fp_combo; +reg fp_i2f; +reg fp_f2i; +reg test_exc; +reg show_prog; +event error_event; + +integer error, vcount; + +always #50 clk = ~clk; + +initial + begin + $display ("\n\nFloating Point Unit Version 1.5\n\n"); + clk = 0; + start = 0; + s1 = 0; + s2 = 0; + s3 = 0; + s4 = 0; + error = 0; + vcount = 0; + + show_prog = 0; + + fp_combo = 0; + fp_fasu = 0; + fp_mul = 0; + fp_div = 0; + fp_i2f = 1; + fp_f2i = 1; + + test_exc = 1; + test_sel = 5'b01111; + test_rmode = 4'b1111; + + //test_sel = 5'b00110; + //test_rmode = 4'b01110; + + fp_combo = 1; + fp_fasu = 1; + fp_mul = 1; + fp_div = 1; + fp_i2f = 1; + fp_f2i = 1; + + test_sel = 5'b11111; + test_rmode = 4'b1111; + + @(posedge clk); + +`include "test_bench/sel_test.vh" + + repeat (4) @(posedge clk); + $display("\n\n"); + + $display("\n\nAll test Done !\n\n"); + $display("Run %0d vecors, found %0d errors.\n\n",vcount, error); + + $finish; + end + + +task run_test; +begin + @(posedge clk); + #1; + opa = 32'hx; + opb = 32'hx; + fpu_rmode = 2'hx; + fpu_op = 3'hx; + + repeat(4) @(posedge clk); + #1; + + oper = 1; + i=0; + while( |oper == 1'b1 ) + begin + + @(posedge clk); + #1; + start = 1; + tmp = tmem[i]; + rmode = tmp[115:112]; + exc = tmp[111:104]; + oper = tmp[103:96]; + opa = tmp[95:64]; + opb = tmp[63:32]; + exp = tmp[31:00]; + + // FPU rounding mode + // 0: float_round_nearest_even + // 1: float_round_down + // 2: float_round_up + // 3: float_round_to_zero + + case(rmode) + 0: fpu_rmode = 0; + 1: fpu_rmode = 3; + 2: fpu_rmode = 2; + 3: fpu_rmode = 1; + default: fpu_rmode=2'hx; + endcase + + // oper fpu operation + // 1 add + // 2 sub + // 4 mul + // 8 div + // ... + + case(oper) + 8'b00000001: fpu_op=3'b000; // Add + 8'b00000010: fpu_op=3'b001; // Sub + 8'b00000100: fpu_op=3'b010; // Mul + 8'b00001000: fpu_op=3'b011; // Div + 8'b00010000: fpu_op=3'b100; // i2f + 8'b00100000: fpu_op=3'b101; // f2i + 8'b01000000: fpu_op=3'b110; // rem + default: fpu_op=3'bx; + endcase + + if(show_prog) $write("Vector: %d\015",i); + + //if(oper==1) $write("+"); + //else + //if(oper==2) $write("-"); + //else + //if(oper==4) $write("*"); + //else + //if(oper==8) $write("/"); + //else $write("Unknown Operation (%d)",oper); + + i= i+1; + end + start = 0; + + @(posedge clk); + #1; + opa = 32'hx; + opb = 32'hx; + fpu_rmode = 2'hx; + fpu_op = 2'hx; + + repeat(4) @(posedge clk); + #1; + + for(i=0;i<500000;i=i+1) // Clear Memory + tmem[i] = 112'hxxxxxxxxxxxxxxxxx; + + end +endtask + +always @(posedge clk) + begin + s1 <= #1 start; + s2 <= #1 s1; + s3 <= #1 s2; + s4 <= #1 s3; + exp1 <= #1 exp; + exp2 <= #1 exp1; + exp3 <= #1 exp2; + exp4 <= #1 exp3; + opa1 <= #1 opa; + opa2 <= #1 opa1; + opa3 <= #1 opa2; + opa4 <= #1 opa3; + opb1 <= #1 opb; + opb2 <= #1 opb1; + opb3 <= #1 opb2; + opb4 <= #1 opb3; + fpu_op1 <= #1 fpu_op; + fpu_op2 <= #1 fpu_op1; + fpu_op3 <= #1 fpu_op2; + fpu_op4 <= #1 fpu_op3; + fpu_op5 <= #1 fpu_op4; + rmode1 <= #1 rmode; + rmode2 <= #1 rmode1; + rmode3 <= #1 rmode2; + rmode4 <= #1 rmode3; + rmode5 <= #1 rmode4; + exc1 <= #1 exc; + exc2 <= #1 exc1; + exc3 <= #1 exc2; + exc4 <= #1 exc3; + + #3; + + // Floating Point Exceptions ( exc4 ) + // ------------------------- + // float_flag_invalid = 1, + // float_flag_divbyzero = 4, + // float_flag_overflow = 8, + // float_flag_underflow = 16, + // float_flag_inexact = 32 + + exc_err=0; + + if(test_exc) + begin + + if(div_by_zero !== exc4[2]) + begin + exc_err=1; + $display("\nERROR: DIV_BY_ZERO Exception: Expected: %h, Got %h\n",exc4[2],div_by_zero); + end + + + if(ine !== exc4[5]) + begin + exc_err=1; + $display("\nERROR: INE Exception: Expected: %h, Got %h\n",exc4[5],ine); + end + + if(overflow !== exc4[3]) + begin + exc_err=1; + $display("\nERROR: Overflow Exception Expected: %h, Got %h\n",exc4[3],overflow); + end + + + if(underflow !== exc4[4]) + begin + exc_err=1; + $display("\nERROR: Underflow Exception Expected: %h, Got %h\n",exc4[4],underflow); + end + + + if(zero !== !(|sum[30:0])) + begin + exc_err=1; + $display("\nERROR: Zero Detection Failed. ZERO: %h, Sum: %h\n", zero, sum); + end + + if(inf !== ( (sum[30:23] == 8'hff) & ((|sum[22:0]) == 1'b0) ) ) + begin + exc_err=1; + $display("\nERROR: INF Detection Failed. INF: %h, Sum: %h\n", inf, sum); + end + + + if(qnan !== ( &sum[30:23] & |sum[22:0] ) & !(fpu_op4==5) ) + begin + exc_err=1; + $display("\nERROR: QNAN Detection Failed. QNAN: %h, Sum: %h\n", qnan, sum); + end + + + if(snan !== ( ( &opa4[30:23] & !opa4[22] & |opa4[21:0]) | ( &opb4[30:23] & !opb4[22] & |opb4[21:0]) ) ) + begin + exc_err=1; + $display("\nERROR: SNAN Detection Failed. SNAN: %h, OpA: %h, OpB: %h\n", snan, opa4, opb4); + end + + end + + + m0 = ( (|sum) !== 1'b1) & ( (|sum) !== 1'b0); // result unknown (ERROR) + //m0 = ( (|sum) === 1'bx) & 0; + m1 = (exp4 === sum); // results are equal + + // NAN *** Ignore Fraction Detail *** + m2 = (sum[31] == exp4[31]) & + (sum[30:23] == 8'hff) & (exp4[30:23] == 8'hff) & + (sum[22] == exp4[22]) & + ( (|sum[22:0]) == 1'b1) & ((|exp4[22:0]) == 1'b1); + + match = m1 | m2; + + if( (exc_err | !match | m0) & s4 ) + begin + -> error_event; + #0.6; + $display("\n%t: ERROR: output mismatch. Expected %h, Got %h (%h)", $time, exp4, sum, {opa4, opb4, exp4} ); + $write("opa:\t"); disp_fp(opa4); + $display("opa:\t%h",opa4[30:0]); + case(fpu_op4) + 0: $display("\t+"); + 1: $display("\t-"); + 2: $display("\t*"); + 3: $display("\t/"); + default: $display("\t Unknown Operation "); + endcase + $write("opb:\t"); disp_fp(opb4); + $write("EXP:\t"); disp_fp(exp4); + $write("GOT:\t"); disp_fp(sum); + +$display("\nThis rmode: %h fpop: %h; Previous: rmode: %h fpop: %h; Next: rmode: %h fpop: %h\n", +rmode4, fpu_op4, rmode5, fpu_op5, rmode3, fpu_op3); + + $display("\n"); + error = error + 1; + end + + if(s4) vcount = vcount + 1; + + if(error > 10) + begin + @(posedge clk); + $display("\n\nFound to many errors, aborting ...\n\n"); + $display("Run %0d vecors, found %0d errors.\n\n",vcount, error); + $finish; + end + end + + +fpu u0(clk, fpu_rmode, fpu_op, opa, opb, sum, inf, snan, qnan, ine, overflow, underflow, zero, div_by_zero); + + +task disp_fp; +input [31:0] fp; + +reg [63:0] x; +reg [7:0] exp; + + begin + + exp = fp[30:23]; + if(exp==8'h7f) $write("(%h %h ( 00 ) %h) ",fp[31], exp, fp[22:0]); + else + if(exp>8'h7f) $write("(%h %h (+%d ) %h) ",fp[31], exp, exp-8'h7f, fp[22:0]); + else $write("(%h %h (-%d ) %h) ",fp[31], exp, 8'h7f-exp, fp[22:0]); + + + x[51:0] = {fp[22:0], 29'h0}; + x[63] = fp[31]; + x[62] = fp[30]; + x[61:59] = {fp[29], fp[29], fp[29]}; + x[58:52] = fp[29:23]; + + $display("\t%f",$bitstoreal(x)); + end + +endtask + +endmodule + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/released/test_bench/sel_test.vh =================================================================== --- tags/released/test_bench/sel_test.vh (nonexistent) +++ tags/released/test_bench/sel_test.vh (revision 7) @@ -0,0 +1,1026 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// FPU //// +//// Floating Point Unit (Single precision) //// +//// //// +//// TEST BENCH //// +//// //// +//// Author: Rudolf Usselmann //// +//// russelmann@hotmail.com //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// russelmann@hotmail.com //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT //// +//// LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND //// +//// FITNESS FOR A PARTICULAR PURPOSE. //// +//// //// +///////////////////////////////////////////////////////////////////// + + + + if(fp_combo) + begin + $display("\n\nTesting FPU \n"); + + $display("\nRunning Combo Test 1 ...\n"); + $readmemh ("test_vectors/combo/fpu_combo1.hex", tmem); + run_test; + + $display("\nRunning Combo Test 2 ...\n"); + $readmemh ("test_vectors/combo/fpu_combo2.hex", tmem); + run_test; + + $display("\nRunning Combo Test 3 ...\n"); + $readmemh ("test_vectors/combo/fpu_combo3.hex", tmem); + run_test; + + $display("\nRunning Combo Test 4 ...\n"); + $readmemh ("test_vectors/combo/fpu_combo4.hex", tmem); + run_test; + + end + + if(fp_fasu) + begin + $display("\n\nTesting FP Add/Sub Unit\n"); + if(test_rmode[0]) + begin + $display("\n+++++ ROUNDING MODE: Nearest Even\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Add Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_pat0a.hex", tmem); + run_test; + end + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Sub Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_pat0b.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Add Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_pat1a.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Sub Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_pat1b.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Add Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_pat2a.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Sub Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_pat2b.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Add Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_lga.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Sub Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_lgb.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Add Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_sma.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Sub Test ...\n"); + $readmemh ("test_vectors/rtne/fasu_smb.hex", tmem); + run_test; + end + end + + + if(test_rmode[1]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards Zero\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Add Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_pat0a.hex", tmem); + run_test; + end + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Sub Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_pat0b.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Add Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_pat1a.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Sub Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_pat1b.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Add Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_pat2a.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Sub Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_pat2b.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Add Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_lga.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Sub Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_lgb.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Add Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_sma.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Sub Test ...\n"); + $readmemh ("test_vectors/rtzero/fasu_smb.hex", tmem); + run_test; + end + end + + if(test_rmode[2]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF+ (UP)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Add Test ...\n"); + $readmemh ("test_vectors/rup/fasu_pat0a.hex", tmem); + run_test; + end + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Sub Test ...\n"); + $readmemh ("test_vectors/rup/fasu_pat0b.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Add Test ...\n"); + $readmemh ("test_vectors/rup/fasu_pat1a.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Sub Test ...\n"); + $readmemh ("test_vectors/rup/fasu_pat1b.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Add Test ...\n"); + $readmemh ("test_vectors/rup/fasu_pat2a.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Sub Test ...\n"); + $readmemh ("test_vectors/rup/fasu_pat2b.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Add Test ...\n"); + $readmemh ("test_vectors/rup/fasu_lga.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Sub Test ...\n"); + $readmemh ("test_vectors/rup/fasu_lgb.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Add Test ...\n"); + $readmemh ("test_vectors/rup/fasu_sma.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Sub Test ...\n"); + $readmemh ("test_vectors/rup/fasu_smb.hex", tmem); + run_test; + end + end + + if(test_rmode[3]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF- (DOWN)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Add Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_pat0a.hex", tmem); + run_test; + end + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Sub Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_pat0b.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Add Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_pat1a.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Sub Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_pat1b.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Add Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_pat2a.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Sub Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_pat2b.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Add Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_lga.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Sub Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_lgb.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Add Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_sma.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Sub Test ...\n"); + $readmemh ("test_vectors/rdown/fasu_smb.hex", tmem); + run_test; + end + end + end + + if(fp_mul) + begin + + $display("\n\nTesting FP MUL Unit\n"); + + if(test_rmode[0]) + begin + $display("\n+++++ ROUNDING MODE: Nearest Even\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rtne/fmul_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rtne/fmul_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rtne/fmul_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rtne/fmul_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rtne/fmul_sm.hex", tmem); + run_test; + end + end + + if(test_rmode[1]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards Zero\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rtzero/fmul_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rtzero/fmul_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rtzero/fmul_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rtzero/fmul_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rtzero/fmul_sm.hex", tmem); + run_test; + end + end + + if(test_rmode[2]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF+ (UP)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rup/fmul_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rup/fmul_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rup/fmul_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rup/fmul_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rup/fmul_sm.hex", tmem); + run_test; + end + + end + + if(test_rmode[3]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF- (DOWN)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rdown/fmul_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rdown/fmul_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rdown/fmul_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rdown/fmul_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rdown/fmul_sm.hex", tmem); + run_test; + end + end + end + + if(fp_div) + begin + + $display("\n\nTesting FP DIV Unit\n"); + + if(test_rmode[0]) + begin + $display("\n+++++ ROUNDING MODE: Nearest Even\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rtne/fdiv_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rtne/fdiv_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rtne/fdiv_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rtne/fdiv_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rtne/fdiv_sm.hex", tmem); + run_test; + end + end + + if(test_rmode[1]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards Zero\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rtzero/fdiv_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rtzero/fdiv_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rtzero/fdiv_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rtzero/fdiv_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rtzero/fdiv_sm.hex", tmem); + run_test; + end + end + + if(test_rmode[2]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF+ (UP)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rup/fdiv_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rup/fdiv_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rup/fdiv_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rup/fdiv_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rup/fdiv_sm.hex", tmem); + run_test; + end + + end + + if(test_rmode[3]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF- (DOWN)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rdown/fdiv_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rdown/fdiv_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rdown/fdiv_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rdown/fdiv_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rdown/fdiv_sm.hex", tmem); + run_test; + end + end + end + + + + if(fp_i2f) + begin + + $display("\n\nTesting FP I2F Unit\n"); + + if(test_rmode[0]) + begin + $display("\n+++++ ROUNDING MODE: Nearest Even\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rtne/i2f_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rtne/i2f_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rtne/i2f_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rtne/i2f_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rtne/i2f_sm.hex", tmem); + run_test; + end + end + + if(test_rmode[1]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards Zero\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rtzero/i2f_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rtzero/i2f_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rtzero/i2f_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rtzero/i2f_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rtzero/i2f_sm.hex", tmem); + run_test; + end + end + + if(test_rmode[2]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF+ (UP)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rup/i2f_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rup/i2f_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rup/i2f_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rup/i2f_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rup/i2f_sm.hex", tmem); + run_test; + end + + end + + if(test_rmode[3]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF- (DOWN)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rdown/i2f_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rdown/i2f_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rdown/i2f_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rdown/i2f_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rdown/i2f_sm.hex", tmem); + run_test; + end + end + end + + + if(fp_f2i) + begin + + $display("\n\nTesting FP F2I Unit\n"); + + if(test_rmode[0]) + begin + $display("\n+++++ ROUNDING MODE: Nearest Even\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rtne/f2i_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rtne/f2i_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rtne/f2i_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rtne/f2i_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rtne/f2i_sm.hex", tmem); + run_test; + end + end + + if(test_rmode[1]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards Zero\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rtzero/f2i_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rtzero/f2i_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rtzero/f2i_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rtzero/f2i_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rtzero/f2i_sm.hex", tmem); + run_test; + end + end + + if(test_rmode[2]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF+ (UP)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rup/f2i_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rup/f2i_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rup/f2i_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rup/f2i_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rup/f2i_sm.hex", tmem); + run_test; + end + + end + + if(test_rmode[3]) + begin + $display("\n\n+++++ ROUNDING MODE: Towards INF- (DOWN)\n\n"); + + if(test_sel[0]) + begin + $display("\nRunning Pat 0 Test ...\n"); + $readmemh ("test_vectors/rdown/f2i_pat0.hex", tmem); + run_test; + end + + if(test_sel[1]) + begin + $display("\nRunning Pat 1 Test ...\n"); + $readmemh ("test_vectors/rdown/f2i_pat1.hex", tmem); + run_test; + end + + if(test_sel[2]) + begin + $display("\nRunning Pat 2 Test ...\n"); + $readmemh ("test_vectors/rdown/f2i_pat2.hex", tmem); + run_test; + end + + if(test_sel[3]) + begin + $display("\nRunning Random Lg. Num Test ...\n"); + $readmemh ("test_vectors/rdown/f2i_lg.hex", tmem); + run_test; + end + + if(test_sel[4]) + begin + $display("\nRunning Random Sm. Num Test ...\n"); + $readmemh ("test_vectors/rdown/f2i_sm.hex", tmem); + run_test; + end + end + end

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.