[SI-LIST] Re: Creaging Pseudo Random Bit Sequence (PRBS) stimuli for Hspice

  • From: "Macomson, Wis" <wis.macomson@xxxxxxxxx>
  • To: si-list@xxxxxxxxxxxxx
  • Date: Fri, 22 Nov 2002 13:01:19 -0800

All,

For the 'cc'/'gcc' challenged -- but 'perl' enabled -- amongst us,
I shamelessly pinched the PRBS subroutines (many thanks) and came
up with the following HSPICE PRBS generator.

It only defines transitions in the PWL waveform (for shorter
netlists) and repeats the sequence cleanly (often a problem with
PWL waveforms).

The script uses Perl 5.  I checked it on Windoze 2K (DOS window)
and on HPUX (adjust the #! to local conditions).  I got the expected
waveforms when I ran the output through HSPICE.

Problems, questions, or comments are welcome.  If there is a huge
outpouring of demand, I might consider adding an input parameter
to define the polynomial.  OTOH, you who are concerned with such
things, likely you will prefer to do it yourself...

Regards,

-wis
--
Wis Macomson

NB: watch out for line breaks added by unfriendly mailers.

----- cut here -----
#!/usr/bin/perl
use Getopt::Std ;
getopts('hvw:p:b:d:t:l:u:s:x:') ;

$ver = 0 ; $rev = 0 ; $ver_date = "Thu Nov 21 16:42:32 PST 2002" ;
$version = "prbs ver. $ver.$rev, $ver_date\n" ;

$usage = '
Create PRBS PWL voltage waveform for HSPICE

Usage: prbs { -hv -w<poly_len> -p<num_bits> -b<bit_time> -t<rise/fall_time>
              -l<Vol> -u<Voh> -s<gen_seed> -x<dbg_lev> }

   -h  prints this message
   -v  prints the version
   -w  sequence length (127 or 32767, default 127)
   -p  number of bits, default 1.500)
   -b  bit time (in ns, default 1.500)
   -d  delay time (in ns, default 0.100)
   -t  rise and fall time (in ns, default 0.150)
   -l  output low level (in Volts, default 0.000)
   -u  output low level (in Volts, default 1.500)
   -s  output low level (0 <= seed <= 127, default 0 -- random)
   -x  debug level

   The bit stream repeats from 0 if simulation time exceeds the
   pattern length.

   Output to standard out.

' ;

# opt_x function
# ----- --------
# 0x01  <none implemented>

# version and help display

if ( $opt_h || $opt_v ) {
  print $version ;
  exit 0 if $opt_v ;
  print $usage ;
  exit 0
  }

# set defaults

$points   = $opt_p ? $opt_p : 32 ;
$bit_time = $opt_b ? $opt_b * 1e-9 : 1.500e-09 ;
$tr_tf    = $opt_t ? $opt_t * 1e-9 : 0.150e-09 ;
$delay    = $opt_d ? $opt_d * 1e-9 : 0.100e-09 ;
$Vol      = $opt_l ? $opt_l : 0 ;
$Voh      = $opt_u ? $opt_u : 1.5 ;
$seed     = $opt_s ? $opt_s : 0 ;               # default 0 is random
$seq_len  = ( ( $opt_w == 127 ) || ( $opt_w == 32767 ) ) ? $opt_w : 127 ;
 
@data = PRBS7($points,$seed) ;                  # get bit stream

$t         = 0 ;
$data_prev = $data[-1] ;
$v         = ( $data[-1] ? "VOH" : "VOL" ) ;    # set initial level

print "* PRBS($seq_len), seed=$seed, $points bits\n" ;
print "* @data\n" ;
print "* bit time=$bit_time sec, rise/fall=$tr_tf sec\n\n" ;
print ".PARAM VOL=$Vol VOH=$Voh\n" ;
print "Vn IN+ IN- PWL (\n" ;

# if no transition between last and first bit (on repeat), set initial level
printf("+ %6.4e  %s\n", $t, $v) if ( $data[$i] == $data_prev ) ;

for ( $i = 0 ; $i < $points ; $i++ ) {
  if ( $data[$i] != $data_prev ) {              # transition? (skip if not)
    printf("+ %6.4e  %s\n", $t, $v) ;           # set beginning level
    $v = ( $data[$i] ? "VOH" : "VOL" ) ;
    printf("+ %6.4e  %s\n", $t + $tr_tf, $v) ;  # set ending level
    $data_prev = $data[$i]
    }
  $t += $bit_time
  }
printf("+ %6.4e  %s\n", $t, $v) ;               # set final level

print "+ R=0 TD=$delay )\n" ;


#-------------------------------------------------------------------------
# PRBS7(length,seed): Generates a PRBS 2^7-1 data stream  
#       length>0: number of bits to generate
#       seed==0:  generates PRBS from a random starting value
#       seed>0:   generates a repeatable PRBS from the given seed value
#-------------------------------------------------------------------------

# 2^7-1 pseudo random sequence

sub PRBS7
{
 my ($len, $seed) = @_ ;                #Get passed params
 # if seed == 0, get a random int between 1-126
 ($seed == 0) && ($seed = int(rand(126)+.5)) ;
 ($seed > 127) && ($seed = 127) ;       # ceil (seed) = 127
 my @q ;
 my @d = &dec2bin($seed) ;                      #Get the binary of the seed
 #print("binary state = @d\n") ;
 while($#d < 6)
 {
  push(@d,0) ;                                  #Pad with 0s
 }
 #print("binary state = @d\n") ;
 while ($len--)
 {
  push(@d, $d[1] ^ $d[0]) ;                     #^ is the bitwise xor
operator
 #print("binary state = @d\n") ;
  push(@q, shift(@d)) ;
 }
 return(@q) ;
}


# dec2bin subroutine  

sub dec2bin {
( $_[0] < 0 ) && ( $_[0] *= -1) ;               # insure arg >= 0
my @bin ;
while ($_[0]>0) {
  push(@bin, ($_[0] % 2)) ;
  $_[0] = int($_[0] *= 0.5)
 }
 return(@bin) ;
}

#-------------------------------------------------------------------------
# PRBS15(length,seed): Generates a PRBS 2^15-1 data stream  
#       Written by Steve Currie
#       length>0: number of bits to generate
#       seed==0:  generates PRBS from a random starting value
#       seed>0:   generates a repeatable PRBS from the given seed value
#-------------------------------------------------------------------------


#2^15-1 pseudo random sequence
#REQUIRES the dec2bin() subroutine listed above

sub PRBS15
{
 my ($len, $seed) = @_ ;                        #Get passed params
 ($seed == 0) && ($seed = int(rand(32767)+.5)) ;#If seed == 0, get a random
int between 1-32767
 ($seed >32767) && ($seed = 32767) ;            # ceil (seed) = 127
 my @q ;
 my @d = &dec2bin($seed) ;                      #Get the binary of the seed
 #print("binary state = @d\n") ;
 while($#d < 14)
 {
  push(@d,0) ;                                  #Pad with 0s
 }
 #print("binary state = @d\n") ;
 while ($len--)
 {
  push(@d, $d[14] ^ $d[0]) ;                    # bitwise xor
 #print("binary state = @d\n") ;
  push(@q, shift(@d)) ;
 }
 return(@q) ;
}
__END__
------------------------------------------------------------------
To unsubscribe from si-list:
si-list-request@xxxxxxxxxxxxx with 'unsubscribe' in the Subject field

or to administer your membership from a web page, go to:
//www.freelists.org/webpage/si-list

For help:
si-list-request@xxxxxxxxxxxxx with 'help' in the Subject field

List archives are viewable at:     
                //www.freelists.org/archives/si-list
or at our remote archives:
                http://groups.yahoo.com/group/si-list/messages 
Old (prior to June 6, 2001) list archives are viewable at:
                http://www.qsl.net/wb6tpu
  

Other related posts: