7.3 Use newlib

7.3.1 Compiler Construction

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.

  1. Download sources
  2. Build binutils
  3. Build bootstrap gcc
  4. Build newlib
  5. Build gcc again with newlib

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.