#!/usr/bin/perl
#
# xdlfixes - Pro-process a Xilinx .xdl file such that xdl -xdl2ncd accepts it
#
# Written 2011 by Werner Almesberger
# Copyright 2011 by Werner Almesberger
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#


sub usage
{
	print STDERR "usage: $0 [infile]\n";
	exit(1);
}


&usage if $ARGV[0] =~ /^-/;

while (<>) {
	#
	# BUG: identifiers containing commas are generated by xdl -ncd2xdl
	# but cannot be parsed by xdl -xdl2ncd. We therefore replace all the
	# commas in identifiers with underscores.
	#

	$t = $_;
	$s = "";
	while ($t =~ /[^\\]"\S+"/) {
		$s .= $`;
		($q = $&) =~ y/,/_/;
		$t = $';
		$s .= $q;
	}
	$s .= $t;

	#
	# BUG: xdl -xdl2ncd does not seem to understand that inputs are not
	# outputs. We have two choices here: define the output standard as
	# "#OFF" or define it as "LVCMOS33".
	#
	# With "LVCMOS33", xdl will also insist on the slew rate and the drive
	# strength.
	#
	# In any case, we end up with something the DRC of bitgen will reject.
	# Luckily, bitgen has the option -d to turn off the DRC. It then
	# cheerfully announces
	#
	#   ERROR:Bitgen - Could not find programming information for I/O
	#   standard #OFF [...]
  	#   The programming of the output buffers will not be correct.
	#
	# but the resulting mess appears to work regardless.
	#

	if ($_ =~ /^inst /) {
		$s = $_;
		while (!/;\s*$/) {
			$_ = <>;
			$s .= $_;
		}
#		$s =~ s/\bISTANDARD::LVCMOS33\b/$& OSTANDARD::LVCMOS33/;
#		$s =~ s/\bISTANDARD::LVCMOS33\b/$& OSTANDARD::#OFF/;
		$s =~ s/\bISTANDARD::LVCMOS33\b/$& OSTANDARD::#OFF/ unless
		    $s =~ /\bOSTANDARD:/;
#		$s =~ s/\bINBUF:/OUTBUF::#OFF $&/;
#		if ($s =~ /\bISTANDARD::LVCMOS33\b/) {
#			$s =~ s/\bSLEW::#OFF\b/SLEW::SLOW/g;
#			$s =~ s/\bDRIVEATTRBOX::#OFF\b/DRIVEATTRBOX::12/g;
#		}
	}

	print $s || die "write: $!";
}