7.3 Use newlib
Let's make cross-compiler under cygwin.
Entire process to build will take a whole day! You may skip this section
since the package includes binary.
Basically, all you have to do is to follow the following 5 steps.
7.3.1.1.What do you need?
First, you have to obtain the following source codes
7.3.1.2. Build binutils
% tar xjfv binutils-2.16.tar.bz2 % mkdir build-binutils % cd build-binutils % export TARGET=mips-elf % export PREFIX=/usr/local/$TARGET % export PATH=$PATH:$PREFIX/bin % ../binutils-2.16/configure --target=$TARGET --prefix=$PREFIX % make all % make install
7.3.1.3. Build bootstrap gcc
% tar xjfv gcc-3.4.4.tar.bz2 % mkdir build-gcc % cd build-gcc % sh config_first_stage.sh config_first_stage.sh is bash script shown below. #!/bin/sh export TARGET=mips-elf export PREFIX=/usr/local/$TARGET export PATH=$PATH:$PREFIX/bin ../gcc-3.4.4/configure --target=$TARGET --prefix=$PREFIX --without-headers --with-newlib --with-gnu-as --with-gnu-ld --without-fp make all make install
7.3.1.4. Build newlib
Newlib provides standard C library for embedded systems
% tar xzfv newlib-1.13.0.tar.gz % mkdir build-newlib % cd build-newlib % sh config.sh config.sh is bash-script shown below. #!/bin/sh export TARGET=mips-elf export PREFIX=/usr/local/$TARGET export PATH=$PATH:$PREFIX/bin export CFLAGS="-msoft-float -O2" ../newlib-1.13.0/configure --target=$TARGET --prefix=$PREFIX --without-fp make all make install
7.3.1.5. Build gcc with newlib
%cd build-gcc sh config.sh config.sh is bash-script shown below. #!/bin/sh export TARGET=mips-elf export PREFIX=/usr/local/$TARGET export PATH=$PATH:$PREFIX/bin ../gcc-3.4.4/configure --target=$TARGET --prefix=$PREFIX --with-newlib --with-gnu-as --with-gnu-ld --without-fp make all make install
7.3.2 Build convert_mips2.exe
It is necessary to set $gp after gcc compilation. This work is done by convert_mips2.exe, originally written by Steve Rhoads, added by tak.sugawara. convert_mips2.exe also generates hex/coe/mif files.
gcc -o convert_mips2.exe convert_mips2.c
7.3.3 Compilation Examples
You can see compilation bat files and source files in c_src/double folder.
Section | Bat Name | C source |
---|---|---|
7.3.3.1 | compile_double | double_check.c |
7.3.3.2 | compile_double2 | double_check2.c |
7.3.3.3 | compile_double3 | double_check3.c |
7.3.3.4 | compile_gause | gause.c |
7.3.3.1 RTL Simulation on MAC Floating Operation
Here is a simple c source program floating MAC operation.
/*First Check program of double*/ void putchar(char); #ifndef RAM32K//16KB #define print_port 0x3ff0 #define print_char_port 0x3ff1 #define print_int_port 0x3ff2 #define print_long_port 0x3ff4 #define uart_port 0x03ffc //for 16KRAM #define uart_wport uart_port #define uart_rport uart_port #define int_set_address 0x03ff8 //for 16KRAM #else// RAM32K #define print_port 0x7ff0 #define print_char_port 0x7ff1 #define print_int_port 0x7ff2 #define print_long_port 0x7ff4 #define uart_port 0x07ffc //for 16KRAM #define uart_wport uart_port #define uart_rport uart_port #define int_set_address 0x07ff8 //for 16KRAM #endif void print(unsigned char* ptr)//Verilog Test Bench Use { #ifndef DOS while (*ptr) { *(volatile unsigned char*)print_port=*(ptr++); } *(volatile unsigned char*)print_port=0x00;//Write Done #else printf("%s",ptr); #endif } void print_char(unsigned char val)//Little Endian write out 16bit number { #ifndef DOS *(volatile unsigned char*)print_port=(unsigned char)val ; #else printf("%c",val); #endif } void print_long(long val)//Little Endian write out 16bit number { #ifndef DOS *(volatile long*)print_long_port=val ; #else printf("%x",val); #endif } static const double wtab[128] = { 1.62318314817e-08, 2.16291505214e-08, 2.54246305087e-08, 2.84579525938e-08, 3.10340022482e-08, 3.33011726243e-08, 3.53439060345e-08, 3.72152672658e-08, 3.8950989572e-08, 4.05763964764e-08, 4.21101548915e-08, 4.35664624904e-08, 4.49563968336e-08, 4.62887864029e-08, 4.75707945735e-08, 4.88083237257e-08, 5.00063025384e-08, 5.11688950428e-08, 5.22996558616e-08, 5.34016475624e-08, 5.44775307871e-08, 5.55296344581e-08, 5.65600111659e-08, 5.75704813695e-08, 5.85626690412e-08, 5.95380306862e-08, 6.04978791776e-08, 6.14434034901e-08, 6.23756851626e-08, 6.32957121259e-08, 6.42043903937e-08, 6.51025540077e-08, 6.59909735447e-08, 6.68703634341e-08, 6.77413882848e-08, 6.8604668381e-08, 6.94607844804e-08, 7.03102820203e-08, 7.11536748229e-08, 7.1991448372e-08, 7.2824062723e-08, 7.36519550992e-08, 7.44755422158e-08, 7.52952223703e-08, 7.61113773308e-08, 7.69243740467e-08, 7.77345662086e-08, 7.85422956743e-08, 7.93478937793e-08, 8.01516825471e-08, 8.09539758128e-08, 8.17550802699e-08, 8.25552964535e-08, 8.33549196661e-08, 8.41542408569e-08, 8.49535474601e-08, 8.57531242006e-08, 8.65532538723e-08, 8.73542180955e-08, 8.8156298059e-08, 8.89597752521e-08, 8.97649321908e-08, 9.05720531451e-08, 9.138142487e-08, 9.21933373471e-08, 9.30080845407e-08, 9.38259651738e-08, 9.46472835298e-08, 9.54723502847e-08, 9.63014833769e-08, 9.71350089201e-08, 9.79732621669e-08, 9.88165885297e-08, 9.96653446693e-08, 1.00519899658e-07, 1.0138063623e-07, 1.02247952126e-07, 1.03122261554e-07, 1.04003996769e-07, 1.04893609795e-07, 1.05791574313e-07, 1.06698387725e-07, 1.07614573423e-07, 1.08540683296e-07, 1.09477300508e-07, 1.1042504257e-07, 1.11384564771e-07, 1.12356564007e-07, 1.13341783071e-07, 1.14341015475e-07, 1.15355110887e-07, 1.16384981291e-07, 1.17431607977e-07, 1.18496049514e-07, 1.19579450872e-07, 1.20683053909e-07, 1.21808209468e-07, 1.2295639141e-07, 1.24129212952e-07, 1.25328445797e-07, 1.26556042658e-07, 1.27814163916e-07, 1.29105209375e-07, 1.30431856341e-07, 1.31797105598e-07, 1.3320433736e-07, 1.34657379914e-07, 1.36160594606e-07, 1.37718982103e-07, 1.39338316679e-07, 1.41025317971e-07, 1.42787873535e-07, 1.44635331499e-07, 1.4657889173e-07, 1.48632138436e-07, 1.50811780719e-07, 1.53138707402e-07, 1.55639532047e-07, 1.58348931426e-07, 1.61313325908e-07, 1.64596952856e-07, 1.68292495203e-07, 1.72541128694e-07, 1.77574279496e-07, 1.83813550477e-07, 1.92166040885e-07, 2.05295471952e-07, 2.22600839893e-07 }; //Refer to //http://www1.linkclub.or.jp/~zhidao/zlab/computing/rtlinux.html // /*Convert Integer to String */ char *itoa(int val, char *buf) { register int i; int fig, base; char *cp; cp = buf; if( val < 0 ){ *cp++ = '-'; val = -val; } fig = (int)floor(log10(val)) + 1; for( base=10, i=1; i<fig; base*=10, i++ ); for( i=0; i<fig; base/=10, i++ ) *cp++ = val % base / (base/10) + '0'; *cp = '\0'; return buf; } /* Convert foating to ASCII*/ char *ftoa(double val, char *buf) { #define Z_FTOA_FLOATSIZE 6 #define _ftoa_fig1(val) ( (int)val % 10 + '0' ) register int i; int fig; char *cp; cp = buf; if( val < 0 ){ *cp++ = '-'; val = -val; } if( val == 0 ) strcpy( buf, "0" ); else if( val >= 1.0 ){ if( ( fig = (int)floor(log10(val)) + 1 ) <= Z_FTOA_FLOATSIZE ){ for( i=1; i<fig; val*=0.1, i++ ); for( i=0; i<fig+Z_FTOA_FLOATSIZE; val*=10, i++ ){ if( i == fig ) *cp++ = '.'; *cp++ = _ftoa_fig1(val); } *cp = '\0'; } else { for( i=1; i<fig; val*=0.1, i++ ); *cp++ = _ftoa_fig1(val); *cp++ = '.'; for( val*=10, i=0; i<Z_FTOA_FLOATSIZE; val*=10, i++ ) *cp++ = _ftoa_fig1(val); *cp++ = 'e'; itoa( fig-1, cp ); } } else { if( ( fig = -(int)floor(log10(val)) ) < Z_FTOA_FLOATSIZE ){ *cp++ = '0'; *cp++ = '.'; for( i=1; i<fig; val*=10, i++ ) *cp++='0'; for( val*=10, i=0; i<=Z_FTOA_FLOATSIZE-fig; val*=10, i++ ) *cp++ = _ftoa_fig1(val); *cp = '\0'; } else { for( i=0; i<fig; val*=10, i++ ); *cp++ = _ftoa_fig1(val); *cp++ = '.'; for( val*=10, i=0; i<Z_FTOA_FLOATSIZE; val*=10, i++ ) *cp++ = _ftoa_fig1(val); *cp++ = 'e'; *cp++ = '-'; itoa( fig, cp ); } } return buf; } char str_buffer[30]; void main() { double ad,ab; int i,j; #ifdef RTL_SIM print("Measure 128points floating multiply/add operations.\n"); #endif ad=0; j=sizeof(wtab)/sizeof(double)-1; for (i=0;i<sizeof(wtab)/sizeof(double);i++){ ad +=wtab[i]*wtab[j--];//MAC Operation. } ftoa(ad,str_buffer); print(str_buffer); print("\n"); print_char('\n'); print(""); #ifdef RTL_SIM print("$finish"); #endif }
Use following bash script to compile this c source,.
convert_mips2.exe sets $gp by looking at map file generated by linker,
and also generates hex/coe/mif files as a result.
Please note generated hex/coe/mif files are moved to your RTL sources.(
Change destinations to your RTL sources)
#!/bin/sh export TARGET=mips-elf export PREFIX=/usr/local/$TARGET export PATH=$PATH:$PREFIX/bin mips-elf-as -o boot.o ../plasmaboot.asm mips-elf-gcc -msoft-float -O2 -O -DRAM32K -DRTL_SIM -Dmain=main2 -Wall -S double_check.c mips-elf-gcc -msoft-float -O2 -O -DRAM32K -DRTL_SIM -Dmain=main2 -Wall -c -s double_check.c mips-elf-gcc -msoft-float -O2 -O -DRAM32K -DRTL_SIM -Dmain=main2 -Wall -c -s fp-bit.c mips-elf-ld.exe -static -Ttext 0 -eentry -Map test.map -s -N -o test.exe boot.o double_check.o fp-bit.o /usr/local/mips-elf/lib/gcc/mips-elf/3.4.4/libgcc.a -lm -lc mips-elf-objdump.exe --disassemble test.exe > list.txt convert_mips2.exe -sp32k cp *.hex f:/yacc/rtl/generic cp *.hex f:/yacc/rtl/altera cp *.coe f:/yacc/rtl/xilinx cp *.mif f:/yacc/rtl/xilinx
Results
C:\yacc_float\bench\verilog\yacc_test_uart_echo.v(7)::yacc_test Verilog Simulation Ready. Press Go button to start simulation. ------------- Simulation Starts.-------------------- Measure 128points floating multiply/add operations. 9.624591e-13 C:\yacc_float\bench\verilog\yacc_test_uart_echo.v(65):: paused by $stop time=2855810 ,instance name:yacc_test
The result is identical value by PC calculation.
7.3.3.2 RTL Simulation on exp/log Floating Operation
Here is a source.
for (i=12;i< 20;i+=1) { print("Exp("); print_long(i);//Display i as Hex String print(")="); ad=exp(i);//Calculation of Exp ftoa(ad,str_buffer);//Convert the result(double) to string print(str_buffer);//Display String print(" Inverse operation(log)="); ab=log(ad);//Invert log ftoa(ab,str_buffer);//Convert the result(double) to string print(str_buffer);//Display. If we can get restored value.it means success! print("\n"); }
Result
C:\yacc_float\bench\verilog\yacc_test_uart_echo.v(7)::yacc_test Verilog Simulation Ready. Press Go button to start simulation. ------------- Simulation Starts.-------------------- This is first double check program Nov.28.2005. Exp(0000000c )=162754.791477 Inverse operation(log)=12.000000 Exp(0000000d )=442413.392777 Inverse operation(log)=13.000000 Exp(0000000e )=1.202604e6 Inverse operation(log)=14.000000 Exp(0000000f )=3.269017e6 Inverse operation(log)=15.000000 Exp(00000010 )=8.886110e6 Inverse operation(log)=16.000000 Exp(00000011 )=2.415495e7 Inverse operation(log)=17.000000 Exp(00000012 )=6.565996e7 Inverse operation(log)=18.000000 Exp(00000013 )=1.784823e8 Inverse operation(log)=19.000000 C:\yacc_float\bench\verilog\yacc_test_uart_echo.v(65):: paused by $stop time=13037470 ,instance name:yacc_test
7.3.3.3 RTL Simulation on sin/cos Floating Operation
for (i=0;i< 10;i+=1) { theta=2*M_PI*i*0.1; print("Theta="); ftoa(theta,str_buffer); print(str_buffer); print(" rad : sin^2+cos^2="); as=sin(theta);//calculation of sin ac=cos(theta);//calculation of cos sum=as*as+ac*ac;//we got 1 ? ftoa(sum,str_buffer);//Convert the result(double) to String print(str_buffer);//Display print("\n"); }
Result
C:\yacc_float\bench\verilog\yacc_test_uart_echo.v(7)::yacc_test Verilog Simulation Ready. Press Go button to start simulation. ------------- Simulation Starts.-------------------- sin/cos check program Nov.28.2005. Theta=0 rad : sin^2+cos^2=1.000000000 Theta=0.628318530 rad : sin^2+cos^2=1.000000000 Theta=1.256637061 rad : sin^2+cos^2=0.999999999 Theta=1.884955592 rad : sin^2+cos^2=1.000000000 Theta=2.513274127 rad : sin^2+cos^2=1.000000000 Theta=3.141592657 rad : sin^2+cos^2=1.000000000 Theta=3.769911187 rad : sin^2+cos^2=0.999999999 Theta=4.398229717 rad : sin^2+cos^2=1.000000000 Theta=5.026548247 rad : sin^2+cos^2=1.000000000 Theta=5.654866777 rad : sin^2+cos^2=1.000000000 C:\yacc_float\bench\verilog\yacc_test_uart_echo.v(65):: paused by $stop time=10846490 ,instance name:yacc_test
7.3.3.4 RTL Simulation on AWGN Floating Operation
Here is a source for generating fast gause noise.
/* Nov.29.2005 Tak.Sugawara :Use taus88 as uniform random generator. gauss.c - gaussian random numbers, using the Ziggurat method * * Copyright (C) 2005 Jochen Voss. * * For details see the following article. * * George Marsaglia, Wai Wan Tsang * The Ziggurat Method for Generating Random Variables * Journal of Statistical Software, vol. 5 (2000), no. 8 * http://www.jstatsoft.org/v05/i08/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: gauss.c 6509 2005-07-07 18:31:10Z voss $ */ #include <math.h> //#include <assert.h> //#include <gsl/gsl_rng.h> /* position of right-most step */ #define PARAM_R 3.44428647676 #ifndef RAM32K//16KB #define print_port 0x3ff0 #define print_char_port 0x3ff1 #define print_int_port 0x3ff2 #define print_long_port 0x3ff4 #define uart_port 0x03ffc //for 16KRAM #define uart_wport uart_port #define uart_rport uart_port #define int_set_address 0x03ff8 //for 16KRAM #else// RAM32K #define print_port 0x7ff0 #define print_char_port 0x7ff1 #define print_int_port 0x7ff2 #define print_long_port 0x7ff4 #define uart_port 0x07ffc //for 16KRAM #define uart_wport uart_port #define uart_rport uart_port #define int_set_address 0x07ff8 //for 16KRAM #endif void print(unsigned char* ptr)//Verilog Test Bench Use { #ifndef DOS while (*ptr) { *(volatile unsigned char*)print_port=*(ptr++); } *(volatile unsigned char*)print_port=0x00;//Write Done #else printf("%s",ptr); #endif } void print_char(unsigned char val)//Little Endian write out 16bit number { #ifndef DOS *(volatile unsigned char*)print_port=(unsigned char)val ; #else printf("%c",val); #endif } void print_long(long val)//Little Endian write out 16bit number { #ifndef DOS *(volatile long*)print_long_port=val ; #else printf("%x",val); #endif } /* tabled values for the heigt of the Ziggurat levels */ static const double ytab[128] = { 1, 0.963598623011, 0.936280813353, 0.913041104253, 0.892278506696, 0.873239356919, 0.855496407634, 0.838778928349, 0.822902083699, 0.807732738234, 0.793171045519, 0.779139726505, 0.765577436082, 0.752434456248, 0.739669787677, 0.727249120285, 0.715143377413, 0.703327646455, 0.691780377035, 0.68048276891, 0.669418297233, 0.65857233912, 0.647931876189, 0.637485254896, 0.62722199145, 0.617132611532, 0.607208517467, 0.597441877296, 0.587825531465, 0.578352913803, 0.569017984198, 0.559815170911, 0.550739320877, 0.541785656682, 0.532949739145, 0.524227434628, 0.515614886373, 0.507108489253, 0.498704867478, 0.490400854812, 0.482193476986, 0.47407993601, 0.466057596125, 0.458123971214, 0.450276713467, 0.442513603171, 0.434832539473, 0.427231532022, 0.419708693379, 0.41226223212, 0.404890446548, 0.397591718955, 0.390364510382, 0.383207355816, 0.376118859788, 0.369097692334, 0.362142585282, 0.355252328834, 0.348425768415, 0.341661801776, 0.334959376311, 0.328317486588, 0.321735172063, 0.31521151497, 0.308745638367, 0.302336704338, 0.29598391232, 0.289686497571, 0.283443729739, 0.27725491156, 0.271119377649, 0.265036493387, 0.259005653912, 0.253026283183, 0.247097833139, 0.241219782932, 0.235391638239, 0.229612930649, 0.223883217122, 0.218202079518, 0.212569124201, 0.206983981709, 0.201446306496, 0.195955776745, 0.190512094256, 0.185114984406, 0.179764196185, 0.174459502324, 0.169200699492, 0.1639876086, 0.158820075195, 0.153697969964, 0.148621189348, 0.143589656295, 0.138603321143, 0.133662162669, 0.128766189309, 0.123915440582, 0.119109988745, 0.114349940703, 0.10963544023, 0.104966670533, 0.100343857232, 0.0957672718266, 0.0912372357329, 0.0867541250127, 0.082318375932, 0.0779304915295, 0.0735910494266, 0.0693007111742, 0.065060233529, 0.0608704821745, 0.056732448584, 0.05264727098, 0.0486162607163, 0.0446409359769, 0.0407230655415, 0.0368647267386, 0.0330683839378, 0.0293369977411, 0.0256741818288, 0.0220844372634, 0.0185735200577, 0.0151490552854, 0.0118216532614, 0.00860719483079, 0.00553245272614, 0.00265435214565 }; /* tabled values for 2^24 times x[i]/x[i+1], * used to accept for U*x[i+1]<=x[i] without any floating point operations */ static const unsigned long ktab[128] = { 0, 12590644, 14272653, 14988939, 15384584, 15635009, 15807561, 15933577, 16029594, 16105155, 16166147, 16216399, 16258508, 16294295, 16325078, 16351831, 16375291, 16396026, 16414479, 16431002, 16445880, 16459343, 16471578, 16482744, 16492970, 16502368, 16511031, 16519039, 16526459, 16533352, 16539769, 16545755, 16551348, 16556584, 16561493, 16566101, 16570433, 16574511, 16578353, 16581977, 16585398, 16588629, 16591685, 16594575, 16597311, 16599901, 16602354, 16604679, 16606881, 16608968, 16610945, 16612818, 16614592, 16616272, 16617861, 16619363, 16620782, 16622121, 16623383, 16624570, 16625685, 16626730, 16627708, 16628619, 16629465, 16630248, 16630969, 16631628, 16632228, 16632768, 16633248, 16633671, 16634034, 16634340, 16634586, 16634774, 16634903, 16634972, 16634980, 16634926, 16634810, 16634628, 16634381, 16634066, 16633680, 16633222, 16632688, 16632075, 16631380, 16630598, 16629726, 16628757, 16627686, 16626507, 16625212, 16623794, 16622243, 16620548, 16618698, 16616679, 16614476, 16612071, 16609444, 16606571, 16603425, 16599973, 16596178, 16591995, 16587369, 16582237, 16576520, 16570120, 16562917, 16554758, 16545450, 16534739, 16522287, 16507638, 16490152, 16468907, 16442518, 16408804, 16364095, 16301683, 16207738, 16047994, 15704248, 15472926 }; /* tabled values of 2^{-24}*x[i] */ static const double wtab[128] = { 1.62318314817e-08, 2.16291505214e-08, 2.54246305087e-08, 2.84579525938e-08, 3.10340022482e-08, 3.33011726243e-08, 3.53439060345e-08, 3.72152672658e-08, 3.8950989572e-08, 4.05763964764e-08, 4.21101548915e-08, 4.35664624904e-08, 4.49563968336e-08, 4.62887864029e-08, 4.75707945735e-08, 4.88083237257e-08, 5.00063025384e-08, 5.11688950428e-08, 5.22996558616e-08, 5.34016475624e-08, 5.44775307871e-08, 5.55296344581e-08, 5.65600111659e-08, 5.75704813695e-08, 5.85626690412e-08, 5.95380306862e-08, 6.04978791776e-08, 6.14434034901e-08, 6.23756851626e-08, 6.32957121259e-08, 6.42043903937e-08, 6.51025540077e-08, 6.59909735447e-08, 6.68703634341e-08, 6.77413882848e-08, 6.8604668381e-08, 6.94607844804e-08, 7.03102820203e-08, 7.11536748229e-08, 7.1991448372e-08, 7.2824062723e-08, 7.36519550992e-08, 7.44755422158e-08, 7.52952223703e-08, 7.61113773308e-08, 7.69243740467e-08, 7.77345662086e-08, 7.85422956743e-08, 7.93478937793e-08, 8.01516825471e-08, 8.09539758128e-08, 8.17550802699e-08, 8.25552964535e-08, 8.33549196661e-08, 8.41542408569e-08, 8.49535474601e-08, 8.57531242006e-08, 8.65532538723e-08, 8.73542180955e-08, 8.8156298059e-08, 8.89597752521e-08, 8.97649321908e-08, 9.05720531451e-08, 9.138142487e-08, 9.21933373471e-08, 9.30080845407e-08, 9.38259651738e-08, 9.46472835298e-08, 9.54723502847e-08, 9.63014833769e-08, 9.71350089201e-08, 9.79732621669e-08, 9.88165885297e-08, 9.96653446693e-08, 1.00519899658e-07, 1.0138063623e-07, 1.02247952126e-07, 1.03122261554e-07, 1.04003996769e-07, 1.04893609795e-07, 1.05791574313e-07, 1.06698387725e-07, 1.07614573423e-07, 1.08540683296e-07, 1.09477300508e-07, 1.1042504257e-07, 1.11384564771e-07, 1.12356564007e-07, 1.13341783071e-07, 1.14341015475e-07, 1.15355110887e-07, 1.16384981291e-07, 1.17431607977e-07, 1.18496049514e-07, 1.19579450872e-07, 1.20683053909e-07, 1.21808209468e-07, 1.2295639141e-07, 1.24129212952e-07, 1.25328445797e-07, 1.26556042658e-07, 1.27814163916e-07, 1.29105209375e-07, 1.30431856341e-07, 1.31797105598e-07, 1.3320433736e-07, 1.34657379914e-07, 1.36160594606e-07, 1.37718982103e-07, 1.39338316679e-07, 1.41025317971e-07, 1.42787873535e-07, 1.44635331499e-07, 1.4657889173e-07, 1.48632138436e-07, 1.50811780719e-07, 1.53138707402e-07, 1.55639532047e-07, 1.58348931426e-07, 1.61313325908e-07, 1.64596952856e-07, 1.68292495203e-07, 1.72541128694e-07, 1.77574279496e-07, 1.83813550477e-07, 1.92166040885e-07, 2.05295471952e-07, 2.22600839893e-07 }; unsigned long s1=0xffffffff,s2=0xffffffff,s3=0xffffffff,b; double taus88 () {/*Generates numbers between 0 and 1.*/ b =(((s1 <<13)^s1)>>19); s1 =(((s1 &4294967294)<<12)^b); b =(((s2 <<2)^s2)>>25); s2 =(((s2 &4294967288)<<4)^b); b =(((s3 <<3)^s3)>>11); s3 =(((s3 &4294967280)<<17)^b); return ((s1 ^s2 ^s3)*2.3283064365e-10); } unsigned long taus88_int () {/*Generates numbers between 0 and 1.*/ b =(((s1 <<13)^s1)>>19); s1 =(((s1 &4294967294)<<12)^b); b =(((s2 <<2)^s2)>>25); s2 =(((s2 &4294967288)<<4)^b); b =(((s3 <<3)^s3)>>11); s3 =(((s3 &4294967280)<<17)^b); return ((s1 ^s2 ^s3)); } double gsl_ran_gaussian_ziggurat (double sigma) { unsigned long U, sign, i, j; double x, y; while (1) { U = taus88_int(); i = U & 0x0000007F; /* 7 bit to choose the step */ sign = U & 0x00000080; /* 1 bit for the sign */ j = U>>8; /* 24 bit for the x-value */ x = j*wtab[i]; if (j < ktab[i]) break; if (i<127) { double y0, y1; y0 = ytab[i]; y1 = ytab[i+1]; y = y1+(y0-y1)*taus88(); } else { x = PARAM_R - log(1.0-taus88())/PARAM_R; y = exp(-PARAM_R*(x-0.5*PARAM_R))*taus88(); } if (y < exp(-0.5*x*x)) break; } return sign ? sigma*x : -sigma*x; } //Refer to //http://www1.linkclub.or.jp/~zhidao/zlab/computing/rtlinux.html // /*Convert Integer to String */ char *itoa(int val, char *buf) { register int i; int fig, base; char *cp; cp = buf; if( val < 0 ){ *cp++ = '-'; val = -val; } fig = (int)floor(log10(val)) + 1; for( base=10, i=1; i<fig; base*=10, i++ ); for( i=0; i<fig; base/=10, i++ ) *cp++ = val % base / (base/10) + '0'; *cp = '\0'; return buf; } /* Convert foating to ASCII*/ char *ftoa(double val, char *buf) { #define Z_FTOA_FLOATSIZE 9 #define _ftoa_fig1(val) ( (int)val % 10 + '0' ) register int i; int fig; char *cp; cp = buf; if( val < 0 ){ *cp++ = '-'; val = -val; } if( val == 0 ) strcpy( buf, "0" ); else if( val >= 1.0 ){ if( ( fig = (int)floor(log10(val)) + 1 ) <= Z_FTOA_FLOATSIZE ){ for( i=1; i<fig; val*=0.1, i++ ); for( i=0; i<fig+Z_FTOA_FLOATSIZE; val*=10, i++ ){ if( i == fig ) *cp++ = '.'; *cp++ = _ftoa_fig1(val); } *cp = '\0'; } else { for( i=1; i<fig; val*=0.1, i++ ); *cp++ = _ftoa_fig1(val); *cp++ = '.'; for( val*=10, i=0; i<Z_FTOA_FLOATSIZE; val*=10, i++ ) *cp++ = _ftoa_fig1(val); *cp++ = 'e'; itoa( fig-1, cp ); } } else { if( ( fig = -(int)floor(log10(val)) ) < Z_FTOA_FLOATSIZE ){ *cp++ = '0'; *cp++ = '.'; for( i=1; i<fig; val*=10, i++ ) *cp++='0'; for( val*=10, i=0; i<=Z_FTOA_FLOATSIZE-fig; val*=10, i++ ) *cp++ = _ftoa_fig1(val); *cp = '\0'; } else { for( i=0; i<fig; val*=10, i++ ); *cp++ = _ftoa_fig1(val); *cp++ = '.'; for( val*=10, i=0; i<Z_FTOA_FLOATSIZE; val*=10, i++ ) *cp++ = _ftoa_fig1(val); *cp++ = 'e'; *cp++ = '-'; itoa( fig, cp ); } } return buf; } #define No 1000 double array[No]; char str_buffer[30]; void main() { double sum,avg,a,target_sd,sd; int i; int n=No; #ifdef RTL_SIM print("The Ziggurat Method for Generating Random Variables. Nov.29.2005.\n"); #endif target_sd=1.0; sum=0; for (i=0;i <No;i++){ array[i]=gsl_ran_gaussian_ziggurat(target_sd); sum +=array[i]; } avg=sum/No; sum=0; for (i=0;i<No;i=i+1){ a=array[i]-avg; sum=sum+a*a; } sd=sqrt(sum/No); #ifdef DOS printf("Done %d samples. avg=%f target_sd=%f sd=%f",n,avg,target_sd,sd); #else print("Done "); print_long(n); print(" samples. avg="); ftoa(avg,str_buffer);//Convert print(str_buffer);//Display print(" target_sd="); ftoa(target_sd,str_buffer);//Convert print(str_buffer);//Display print(" sd="); ftoa(sd,str_buffer);//Convert print(str_buffer);//Display print("$finish");//$finish #endif }
Result
C:\yacc_float\bench\verilog\yacc_test_uart_echo.v(7)::yacc_test Verilog Simulation Ready. Press Go button to start simulation. ------------- Simulation Starts.-------------------- The Ziggurat Method for Generating Random Variables. Nov.29.2005. Done 000003e8 samples. avg=-0.029747417 target_sd=1.000000000 sd=1.028135177C:\yacc_float\bench\verilog\yacc_test_uart_echo.v(65):: paused by $stop time=71196170 ,instance name:yacc_test
The result is identical value by PC calculation.