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.