#!/usr/bin/perl
|
#!/usr/bin/perl
|
|
|
#################################################################################################
|
#################################################################################################
|
#
|
#
|
# Copyright 2010 David Fick. All rights reserved.
|
# Copyright 2010 David Fick. All rights reserved.
|
#
|
#
|
# Redistribution and use in source and binary forms, with or without modification, are
|
# Redistribution and use in source and binary forms, with or without modification, are
|
# permitted provided that the following conditions are met:
|
# permitted provided that the following conditions are met:
|
#
|
#
|
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
# conditions and the following disclaimer.
|
# conditions and the following disclaimer.
|
#
|
#
|
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
# of conditions and the following disclaimer in the documentation and/or other materials
|
# of conditions and the following disclaimer in the documentation and/or other materials
|
# provided with the distribution.
|
# provided with the distribution.
|
#
|
#
|
# THIS SOFTWARE IS PROVIDED BY DAVID FICK ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
# THIS SOFTWARE IS PROVIDED BY DAVID FICK ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID FICK OR
|
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID FICK OR
|
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
#
|
#
|
# The views and conclusions contained in the software and documentation are those of the
|
# The views and conclusions contained in the software and documentation are those of the
|
# authors and should not be interpreted as representing official policies, either expressed
|
# authors and should not be interpreted as representing official policies, either expressed
|
# or implied, of David Fick.
|
# or implied, of David Fick.
|
#
|
#
|
#################################################################################################
|
#################################################################################################
|
|
|
|
|
use strict;
|
use strict;
|
use integer;
|
use integer;
|
|
|
my $warning_verilog = "\n\n\n
|
my $warning_verilog = "\n\n\n
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
// !! THIS IS A TEMPORARY FILE GENERATED BY DEPERILFY !!
|
// !! THIS IS A TEMPORARY FILE GENERATED BY DEPERILFY !!
|
// !! DO NOT MODIFY DIRECTLY! !!
|
// !! DO NOT MODIFY DIRECTLY! !!
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
\n";
|
\n";
|
|
|
my $warning_io = "\n\n\n
|
my $warning_io = "\n\n\n
|
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
# !! THIS IS A TEMPORARY FILE GENERATED BY DEPERILFY !!
|
# !! THIS IS A TEMPORARY FILE GENERATED BY DEPERILFY !!
|
# !! DO NOT MODIFY DIRECTLY! !!
|
# !! DO NOT MODIFY DIRECTLY! !!
|
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
\n";
|
\n";
|
|
|
sub max {
|
sub max {
|
my $a = shift;
|
my $a = shift;
|
my $b = shift;
|
my $b = shift;
|
|
|
return $a > $b ? $a : $b;
|
return $a > $b ? $a : $b;
|
}
|
}
|
|
|
|
|
################################################################################################
|
################################################################################################
|
# Grab Defines
|
# Grab Defines
|
|
|
my %defines;
|
my %defines;
|
|
|
sub grab_defines {
|
sub grab_defines {
|
|
|
my @params = @_;
|
my @params = @_;
|
my $file_name = $params[0];
|
my $file_name = $params[0];
|
|
|
# Read the entire file
|
# Read the entire file
|
my $file_contents;
|
my $file_contents;
|
|
|
{
|
{
|
local( $/, *FH ) ;
|
local( $/, *FH ) ;
|
open(FH, "< " . $file_name) or die "Failed to open \"". $file_name . "\" correctly.";
|
open(FH, "< " . $file_name) or die "Failed to open \"". $file_name . "\" correctly.";
|
$file_contents = <FH>;
|
$file_contents = <FH>;
|
close(FH)
|
close(FH)
|
}
|
}
|
|
|
# Remove all comments
|
# Remove all comments
|
$file_contents =~ s-//.*\n-\n-g;
|
$file_contents =~ s-//.*\n-\n-g;
|
$file_contents =~ s-/\*.*\*/- -g;
|
$file_contents =~ s-/\*.*\*/- -g;
|
|
|
# Grab all of the defines
|
# Grab all of the defines
|
while ($file_contents =~ /\`define\s+(\w+)[ \t]+([^\n]*)?\n/g) {
|
while ($file_contents =~ /\`define\s+(\w+)[ \t]+([^\n]*)?\n/g) {
|
|
|
my $macro = $1;
|
my $macro = $1;
|
my $definition = $2;
|
my $definition = $2;
|
|
|
$defines{$macro} = $definition;
|
$defines{$macro} = $definition;
|
}
|
}
|
|
|
return;
|
return;
|
}
|
}
|
|
|
|
|
################################################################################################
|
################################################################################################
|
# Lookup Define
|
# Lookup Define
|
|
|
sub lookup {
|
sub lookup {
|
|
|
my $define = shift;
|
my $define = shift;
|
my $definition = $defines{$define};
|
my $definition = $defines{$define};
|
|
|
$definition = deep_replace($definition);
|
$definition = deep_replace($definition);
|
|
|
return $definition ne "" ? $definition : "undef";
|
return $definition ne "" ? $definition : "undef";
|
}
|
}
|
|
|
################################################################################################
|
################################################################################################
|
# Deep Replace - replaces ` defines with their values
|
# Deep Replace - replaces ` defines with their values
|
|
|
sub deep_replace {
|
sub deep_replace {
|
|
|
no integer;
|
no integer;
|
|
|
my $text = shift;
|
my $text = shift;
|
|
|
# Find and replace all defines
|
# Find and replace all defines
|
$text =~ s-\`LG\(([^()]+?)\)-int(0.99999+log(eval(deep_replace($1)))/log(2))-ge; # Special case for `LG macro
|
$text =~ s-\`LG\(([^()]+?)\)-int(0.99999+log(eval(deep_replace($1)))/log(2))-ge; # Special case for `LG macro
|
$text =~ s-\`MAX\(([^()]+?),([^()]+?)\)-max(eval(deep_replace($1)),eval(deep_replace($2)))-ge; # Special case for `MAX macro
|
$text =~ s-\`MAX\(([^()]+?),([^()]+?)\)-max(eval(deep_replace($1)),eval(deep_replace($2)))-ge; # Special case for `MAX macro
|
|
|
# Check for errors in the eval statement
|
# Check for errors in the eval statement
|
if ($@) {
|
if ($@) {
|
print "Error in perl section:\n" . $text . "\n ERRORS: \n" . $@;
|
print "Error in perl section:\n" . $text . "\n ERRORS: \n" . $@;
|
die;
|
die;
|
}
|
}
|
|
|
# Do additional normal lookups
|
# Do additional normal lookups
|
$text =~ s/\`(\w+)/lookup($1)/ge;
|
$text =~ s/\`(\w+)/lookup($1)/ge;
|
|
|
return $text;
|
return $text;
|
}
|
}
|
|
|
|
|
################################################################################################
|
################################################################################################
|
# Shallow Replace - replaces $` defines with their values
|
# Shallow Replace - replaces $` defines with their values
|
|
|
sub shallow_replace {
|
sub shallow_replace {
|
|
|
my $text = shift;
|
my $text = shift;
|
|
|
# Find and replace all defines
|
# Find and replace all defines
|
$text =~ s/\$\`(\w+)/lookup($1)/ge;
|
$text =~ s/\$\`(\w+)/lookup($1)/ge;
|
|
|
return $text;
|
return $text;
|
}
|
}
|
|
|
|
|
################################################################################################
|
################################################################################################
|
# This function takes a string, executes it, and returns everything that was printed
|
# This function takes a string, executes it, and returns everything that was printed
|
|
|
sub execute_block {
|
sub execute_block {
|
|
|
my $text = shift;
|
my $text = shift;
|
my $generated_text = "";
|
my $generated_text = "";
|
|
|
# Inject the DEPERLIFY_INCLUDE files
|
# Inject the DEPERLIFY_INCLUDE files
|
$text =~ s/DEPERLIFY_INCLUDE\(([^\)]+)\)/`cat $1`/gse;
|
$text =~ s/DEPERLIFY_INCLUDE\(([^\)]+)\)/`cat $1`/gse;
|
|
|
# Find and replace all defines
|
# Find and replace all defines
|
$text = shallow_replace($text);
|
$text = shallow_replace($text);
|
|
|
# Execute the block of text that now has the generate statements
|
# Execute the block of text that now has the generate statements
|
# write perl code to a file
|
# write perl code to a file
|
my $temp_file = `mktemp deperlify.XXXXXXXXX`;
|
my $temp_file = `mktemp deperlify.XXXXXXXXX`;
|
chomp $temp_file;
|
chomp $temp_file;
|
|
|
open (BLOCK_CODE, ">" . $temp_file);
|
open (BLOCK_CODE, ">" . $temp_file);
|
print BLOCK_CODE $text;
|
print BLOCK_CODE $text;
|
|
|
# run perl on block
|
# run perl on block
|
$generated_text = `perl $temp_file`;
|
$generated_text = `perl $temp_file`;
|
`rm $temp_file`;
|
|
|
|
# Check for errors in the eval statement
|
# Stop if there's an error
|
if ($@) {
|
if ($? != 0) {
|
print "Error in perl section:\n" . $text . "\n ERRORS: \n" . $@;
|
|
die;
|
die;
|
}
|
}
|
|
|
|
`rm $temp_file`;
|
|
|
return $generated_text;
|
return $generated_text;
|
}
|
}
|
|
|
|
|
################################################################################################
|
################################################################################################
|
# This function takes a file name and runs the program on that file
|
# This function takes a file name and runs the program on that file
|
|
|
sub convert_file {
|
sub convert_file {
|
|
|
my @params = @_;
|
my @params = @_;
|
|
|
my $file_name = $params[0];
|
my $file_name = $params[0];
|
my $output_file_name = $file_name;
|
my $output_file_name = $file_name;
|
|
|
$output_file_name =~ s/\.perl\./\./;
|
$output_file_name =~ s/\.perl\./\./;
|
|
|
# determine warning based on file type (determines type of comments used)
|
# determine warning based on file type (determines type of comments used)
|
my $warning;
|
my $warning;
|
if ($file_name =~ /\.io/) {
|
if ($file_name =~ /\.io/) {
|
$warning = $warning_io;
|
$warning = $warning_io;
|
} else {
|
} else {
|
$warning = $warning_verilog;
|
$warning = $warning_verilog;
|
}
|
}
|
|
|
# Read the entire file
|
# Read the entire file
|
my $file_contents;
|
my $file_contents;
|
|
|
{
|
{
|
local( $/, *FH ) ;
|
local( $/, *FH ) ;
|
open(FH, "< " . $file_name) or die "Failed to open \"". $file_name . "\" correctly";
|
open(FH, "< " . $file_name) or die "Failed to open \"". $file_name . "\" correctly";
|
$file_contents = <FH>;
|
$file_contents = <FH>;
|
close(FH)
|
close(FH)
|
}
|
}
|
|
|
# Do some operation
|
# Do some operation
|
$file_contents =~ s/[\t ]*PERL\s+begin\s+\/\*(.*?)\*\/\s+end\s*?\n/execute_block($1)/gse;
|
$file_contents =~ s/[\t ]*PERL\s+begin\s+\/\*(.*?)\*\/\s+end\s*?\n/execute_block($1)/gse;
|
|
|
$file_contents = $warning . $file_contents;
|
$file_contents = $warning . $file_contents;
|
|
|
# Write the entire file
|
# Write the entire file
|
{
|
{
|
local( *FH ) ;
|
local( *FH ) ;
|
open(FH, "> " . $output_file_name) or die "Failed to write \"". $output_file_name . "\" correctly";
|
open(FH, "> " . $output_file_name) or die "Failed to write \"". $output_file_name . "\" correctly";
|
print FH $file_contents;
|
print FH $file_contents;
|
close(FH)
|
close(FH)
|
}
|
}
|
|
|
}
|
}
|
|
|
|
|
################################################################################################
|
################################################################################################
|
# Main code
|
# Main code
|
|
|
foreach my $argnum (0 .. $#ARGV) {
|
foreach my $argnum (0 .. $#ARGV) {
|
|
|
grab_defines($ARGV[$argnum]);
|
grab_defines($ARGV[$argnum]);
|
|
|
if ($ARGV[$argnum] =~ /(\.perl\.v)|(\.perl\.io)/) {
|
if ($ARGV[$argnum] =~ /(\.perl\.v)|(\.perl\.io)/) {
|
convert_file($ARGV[$argnum]);
|
convert_file($ARGV[$argnum]);
|
}
|
}
|
}
|
}
|
|
|
|
|
################################################################################################
|
################################################################################################
|
|
|
|
|
|
|