#! /usr/bin/perl -n

# (c) Copyright 2004, Cadence Design Systems, Inc.  All rights reserved. 
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, or sublicense, the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# USE OF THE SOFTWARE IS AT YOUR SOLE RISK AND EXPENSE. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, OF ANY TYPE, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
# THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# bdnet2v : convert a .bdnet netlist to structural verilog

sub clean($) {
  my $t = shift;
  $t =~ s'.*/'';
  $t =~ s/\W/_/g;
  return $t;
}

sub netlookup($) {
  my $t = shift;
  if (not exists $netmap{$t}) {
    $netmap{$t} = sprintf("n_%d", $netnum++);
  }
  $t = $netmap{$t};
  return $t;
}

sub printinst() {
  printf("%s i_%d(", $insttype, $instnum++);
  print (join ",\n  ", @pinlist);
  print ");\n";
}

if (/^MODEL\s+"([^"]+)"/) {
  $modname = clean($1);
  push @modports, "clk_net";
  push @modsigs, "input clk_net;\n";
}
elsif (/^INPUT/) {
  $section = 1;
}
elsif (/^OUTPUT/) {
  $section = 2;
}
elsif (/^INSTANCE\s+"([^"]+)"/) {
  if ($section) {
    print "module $modname(".(join ",\n  ", @modports).");\n";
    print (join '', @modsigs);
    print (join '', @assigns);
    $section = 0;
  }
  else {
    printinst();
  }
  $insttype = $1;
  @pinlist = ();
}
elsif (/"([^"]+)"\s*:\s*"([^"]+)"/) {
  $pinname = clean($1);
  $netname = $2;
  if ($section) {
    push @modports, $pinname;
    if (exists $netmap{$netname}) {
      $srcpin = $netmap{$netname};
      push @assigns, "assign $pinname = $srcpin;\n";
    }
    else {
      $netmap{$netname} = $pinname;
    }
    if ($section == 1) {
      push @modsigs, "input $pinname;\n";
    }
    else
    {
      push @modsigs, "output $pinname;\n";
    }
  }
  else {
    $netname = netlookup($netname);
    push @pinlist, ".$pinname($netname)";
  }
}
elsif (/"(\S+)"\s*:\s*UNCONNECTED/) {
  push @pinlist, ".$1(clk_net)";
}
elsif (/^ENDMODEL/) {
  printinst() if $insttype;
  print "endmodule\n";
}
