1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-27 23:30:38 +02:00
wernermisc/m1/tools/xdltap

118 lines
2.5 KiB
Perl
Executable File

#!/usr/bin/perl
#
# xdltap - Route nets from inside the FPGA to I/O pads
#
# 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 change
{
local ($s, $v, $from, $to) = @_;
if (defined $from) {
die "${v}::$from not found in\n$s"
unless $s =~ /\b${v}::$from/;
return "$`${v}::$to$'";
} else {
die "${v}::... not found in\n$s"
unless $s =~ /\b${v}::\S+/;
return "$`${v}::$to$'";
}
}
sub change_var
{
local ($s, $from, $to) = @_;
die "${from}::... not found in\n$s"
unless $s =~ /\b${from}::/;
return "$`${to}::$'";
}
sub reassign
{
local ($s, $from, $to) = @_;
$s =~ s/\bINBUF:${to}_IBUF:/OUTBUF:${to}_OBUF:/ ||
die "INBUF:${to}_IBUF: not found in\n$s";
$s =~ s/\bPULL:${to}_PULLDOWN:// ||
die "PULL:${to}_PULLDOWN: not found in\n$s";
$s =~ s/\bIMUX:[^:]+:I/IMUX::#OFF/ ||
die "IMUX:...:I not found in\n$s";
$s = &change($s, "BYPASS_MUX", "I", "#OFF");
$s = &change($s, "DRIVEATTRBOX", "#OFF", "12");
$s = &change($s, "OUSED", "#OFF", "0");
$s = &change($s, "PULLTYPE", "PULLDOWN", "#OFF");
$s = &change($s, "SLEW", "#OFF", "SLOW");
$s = &change($s, "SUSPEND", "#OFF", "3STATE");
$s = &change_var($s, "ISTANDARD", "OSTANDARD");
return $s;
}
sub usage
{
print STDERR <<"END"
usage: $0 [net=output ...] [file]
net fully qualified path to the signal in question, e.g.,
usb/sie/rx_pending
output name of the (input) connected to the output pin, e.g., exp<8>
For better shell compatibility, { and } can be used instead of < and >
END
;
exit(1);
}
&usage if $ARGV[0] =~ /^-/;
while ($ARGV[0] =~ /=/) {
($from, $to) = ($`, $');
$to =~ tr/{}/<>/;
$from{$from} = $to;
$to{$to} = $from;
$need{$from} = $need{$to} = 1;
shift @ARGV;
}
while (<>) {
if ($_ =~ /^inst "([^"]*)"/ && defined $to{$1}) {
die "" unless $need{$1};
delete $need{$1};
$s = $_;
while (!/;\s*$/) {
$_ = <>;
$s .= $_;
}
print &reassign($s, $to{$1}, $1) || die "write: $!";
next;
}
if (/^net "([^"]*)_IBUF"/ && defined $to{$1}) {
next if /;\s*$/;
while (<>) {
last if /;\s*$/;
}
next;
}
print || die "write: $!";
if (/^net "([^"]*)"/) {
next unless defined $from{$1};
die unless $need{$1};
delete $need{$1};
print " inpin \"$from{$1}\" O,\n" || die "write: $!";
}
}
die "not found: ".join(", ", sort keys %need) if %need;