#!/usr/bin/env perl

# Copyright (c) The University of Cincinnati. All rights reserved.
# UC MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
# THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
# TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE, OR NON-INFRINGEMENT.  UC SHALL NOT BE LIABLE
# FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
# RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
# DERIVATIVES.
# By using or copying this Software, Licensee agrees to abide by the
# intellectual property laws, and all other applicable laws of the
# U.S., and the terms of this license.

# Author : Antarpreet Singh

#Script to convert flat gate level verilog netlist to Spice

use Getopt::Long;
use warnings;
use strict;

my $help = 0;
my $cdl = "/home/manchaas/research/work/libraries/saed90nm.cdl /home/manchaas/research/work/libraries/saed90nm_sdmlp.cdl";
my $lib = "/home/manchaas/research/work/libraries/SAED90nm.lib";
my $out = "./des10_spice.sp";
my $Opt = GetOptions('cdl=s' => \$cdl,
        'out=s' => \$out,
        'lib=s' => \$lib,
        'help' => \$help,
        );

print_usage("") if ($help);
print("-E- Please enter the full path of verilog gate netlist!\n\n") if ($#ARGV != 0);

my $verilog_netlist = $ARGV[0];

my %cell_hash;
my $cell_name;
my $line;
my $prev_line = "";
my $done = 0;
my $cell_found = 0;
my $cell;
my @all_cells;
my @cell_array;
my $file;
my @files;

@files = split(/ /,$cdl);

foreach $file (@files)
{
open(SUBCKT_FILE,$file) or die "Can't open $file for read\n\n";

while (<SUBCKT_FILE>)
{
  chomp;

  if(/^[ ]*.subckt[ ]*([^ ]*)(.*)/)
  {
    $cell_name = $1;
    push @cell_array,$cell_name;
    $line = $2;
    $cell_found = 1; 
  }

  while($cell_found and $line =~ /^[ ]*([^ ]*)(.*)$/ and $line ne "")
  {
    $cell_found = 1;
    $cell_hash{$cell_name} .= $1." ";
    $line = $2;
  }

  $cell_found = 0;
}
close(SUBCKT_FILE);

}

#foreach my $cell (@cell_array) {
#print $cell."\t".$cell_hash{$cell}."\n";
#}


open(FILE,$verilog_netlist) or die "Can't open $verilog_netlist for read\n\n";

while (<FILE>)
{
	chomp;
  $line = $_;

  if ($prev_line =~ /[ ]*,[ ]*\.([^ ]*)[ ]*\([ ]*/) {
    $cell .= $1." ";
    if($line =~ /^[ ]*([^ ()]*)[ ]*\)(.*)/) {
      $cell .= $1." ";
      $prev_line = "";
      $cell_found = 1; 	
      $line = $2;
    }
    else { print(" -E- Error Syntax mismatch"); }
  }

  
  if ($prev_line =~ /[ ]*,[ ]*/) {
    if($line =~ /^[ ]*\.([^ ]*)[ ]*\([ ]*([^ ()]*)[ ]*\)(.*)/) {
      $cell .= $1." ".$2." ";
      $prev_line = "";
      $cell_found = 1; 	
      $line = $3;
    }
    else { print(" -E- Error Syntax mismatch"); }
  }

	if ($line =~ /^[ ]*([^ ]*)[ ]*([^ ]*)[ ]*\([ ]*\.([^ ]*)[ ]*\([ ]*([^ ]*)[ ]*\)(.*)/) {
	  $cell .= $1." ".$2." ".$3." ".$4." ";
    $line = $5;
    $cell_found = 1; 	
	}

  while ($line =~ /[ ]*,[ ]*.([^ ]*)[ ]*\([ ]*([^ ()]*)[ ]*\)(.*)/)
  {
    $cell .= $1." ".$2." ";
    $cell_found = 1; 	
    $line = $3;
  }
  
  if ($cell_found) {
    if ($line =~ /^[ ]*\)[ ]*;/) {
      $done = 1;
      push @all_cells,$cell;
      $cell = "";
      $cell_found = 0;
    } else {
      $done = 0;
      $prev_line = $line;
    }
  }
}

close(FILE);

#foreach $cell (@all_cells) {
#print $cell."\n";
#}

my @sp_out;
my $temp_index = 0;

foreach my $cell (@all_cells){
  my @parts = split(/ /,$cell);
  $line = $cell_hash{$parts[0]};
  my $inst_name = $parts[1];
  $inst_name =~ tr/\\//d;

  my @ports = split(/ /,$line);
  my $length = scalar(@parts);
  
  my $line .= "X".$inst_name." ";

  foreach my $portname (@ports) {
    if($portname eq "VDD")
    {
      $line .= "dummy"." ";
    }
    elsif ($portname eq "VSS") {
      $line .= "Gnd"." ";
    } else {
      $done = 0;
      my $i;
      for($i=2; $i < $length; $i=$i+2) {
        if($portname eq $parts[$i]) {
          if ($parts[$i+1] ne "1'b1" and $parts[$i+1] ne "1'b0") {
            $parts[$i+1] =~ tr/\\//d;
            $line .= $parts[$i+1]." ";
          } 
          elsif ($parts[$i+1] eq "1'b1") {
            $line .= "dummy"." ";
          }
          elsif ($parts[$i+1] eq "1'b0") {
            $line .= "Gnd"." ";
          }
          $i = $length;
          $done = 1;
        }    
      }
      if($i == $length and !$done) {
        $line .= "temp".$temp_index." ";
        $temp_index = $temp_index+1;
      }
    }
  }

  $line .= $parts[0];
  push @sp_out,$line;
  $line = "";
}


open(SP_FILE,">$out") or die "Can't open $out for write\n\n";

print SP_FILE "\n";
print SP_FILE ".include $cdl"."\n\n";
print SP_FILE ".lib $lib TT_12"."\n\n";
#print SP_FILE ".option scale=90n"."\n\n";

foreach my $out (@sp_out) {
  print SP_FILE $out."\n";
}

print SP_FILE ".option post runlvl=0"."\n\n";
print SP_FILE ".include ./stimuli.sp"."\n\n";
print SP_FILE "VDD x3 Gnd 1.2"."\n";
print SP_FILE "Vtstp x3 dummy 0"."\n";
print SP_FILE "fp 0 9 Vtstp 0.01"."\n";
print SP_FILE "rp 9 0 100K"."\n";
print SP_FILE "Cp 9 0 100pF"."\n";
#print SP_FILE ".print i(Vtstp)"."\n";
#print SP_FILE ".tran 0.01ns 220ns"."\n";
print SP_FILE ".end";

close(SP_FILE);

   sub print_usage { 
	my $message = shift;
	print <<P_USAGE;
USAGE:
	gate2spice.pl <verilog_netlist> [options]

		OPTIONS:
		<verilog_netlist>      Full path and filename of verilog netlist.  

		-cdl=s                 Path of CDL file, Default : $cdl  
		-lib=s                 Path of .lib file, Default : $lib  
		-out=s                 Name of Output Spice file, Default : $out  
		-help                  Print this help message

		EXAMPLES:

		$message
P_USAGE
		exit;
}



