mirror of
git://projects.qi-hardware.com/wernermisc.git
synced 2024-11-23 17:39:30 +02:00
118 lines
2.5 KiB
Plaintext
118 lines
2.5 KiB
Plaintext
|
#!/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;
|