#!/usr/bin/perl die "\nPlease give me a name and a number, like:\n% ./base10to32bitandQscale.pl a0= 0.02345\n" if (! $ARGV[0]) ; $COEFFbase10 = join ('',@ARGV) ; if ($COEFFbase10 !~ /\s*(\S+)\s*=\s*(.*)/) { die "\nPlease give me a name and a number, like:\n% ./base10to32bitandQscale.pl a0= 0.02345\n" ; } $NAME = $1 ; $COEFFbase10 = $2 ; chomp $COEFFbase10 ; # Get the coefficient, note if negative, strip minus sign chomp $COEFFbase10 ; $isneg = ($COEFFbase10 =~ /-/) ? "-" : "" ; $COEFFbase10 =~ s/-// ; $orig = $COEFFbase10 ; # Multiply up by 2 until the value is 1023 or more. 1/1023 gives better # than 0.1% accuracy. Record the multiplier. $m = 0 ; while ($COEFFbase10 < 1023) { $COEFFbase10 = 2 * $COEFFbase10 ; $m++ ; } $n = $m ; # Ignore (truncate) the fractional part that did not get multiplied up to # the left of the decimal point, and return the coefficient * 2^n in base 2. $AA = &dec2bin(int($COEFFbase10)) ; # This is for presenting the base 2 representation of the original # fractional number. @c = split //,$AA ; @c = reverse @c ; $j = 0 ; for ($i=0;$i < 31;$i++) { if ($m == 0) {$f[$i] = '.' ;} else { if (defined $c[$i]) {$f[$i] = $c[$j] ; $j++ ; } else {$f[$i] = '0' ; } } $m-- ; } @f = reverse @f ; $line = join ('',@f) ; while (length $AA < 16) {$AA = "0"."$AA" ; } # and in base 2 : $isneg"."$line" ; # print "\n\/\/ Q = $n" ; # print "\n\/\/ after being multiplied up by 2^$n" ; # print "\n\/\/ in base 10 is : $isneg"."$COEFFbase10" ; # print "\n\/\/ in 16-bits in base 2 is : $isneg"."$AA" ; # Turn in into a string to do the 2's complement. while (length $AA < 16) {$AA = "0"."$AA" ; } @f = split //,$AA ; if ($isneg) { for ($i=0; $i <= $#f ; $i++) { $f[$i] = ($f[$i] eq "1") ? '0' : '1' ;} $line = join @f ; for ($i=$#f ; $i >= 0; $i--) { if ($f[$i] eq '0') { $f[$i] = '1' ; last ; } else { $f[$i] = '0' ; } } } $line = join ('',@f) ; print "\n\/\/-------------------------------------------------------------" ; print "\n Mult16bitByConstFixed $NAME"."_inst ( \t// $NAME = $isneg"."$orig" ; print "\n .Q ('d$n), \t//" ; print "\n .coeff (16'b$line),\t// ($NAME"."base2) x 2^$n" ; print "\n .B (BBBBBBB$NAME), \t//" ; print "\n .y (yyyyyyy$NAME) \t// y = coeff*B >>> Q" ; print "\n ) ;\n" ; # print "\n\/\/ and as a 32-bit 2's complement: $line\n" ; #-------------------------------------------------------------------- sub dec2bin { my $str = unpack("B32", pack("N", shift)); $str =~ s/^0+(?=\d)//; # remove leading zeros return $str; }