#!/usr/bin/perl use strict; use integer; our %consts; require '../iodevs.conf'; my $ramaddr = $consts{'SDRAM_ADDR'}; my $flashcmd = 0xabc80046; my $flashpfx = 0xabc80fed; my $maxdatalen = 16 << 20; my($svfload, $rptfile, $binfile, $svffile) = @ARGV; open(my $in, '<', $rptfile) or die "$0: $rptfile: $!\n"; my @vjif; while (defined(my $l = <$in>)) { my @lf = split(/\s*\;\s*/, $l); if ($lf[8] =~ /\|vjtag\:vjtag\|/) { @vjif = @lf; } } close($in); # [0] - blank # [1] - instance index # [2] - auto index # [3] - index changed # [4] - IR width # [5] - VIR base address # [6] - USER1 DR length # [7] - VIR capture command # [8] - hierarchial entity name my $virbits = $vjif[6]; my $virbase = hex $vjif[5]; my $vircap = hex $vjif[7]; open(my $bin, '<', $binfile) or die "$0: $binfile: $!\n"; binmode($bin); my $bindata; my $binlen = read($bin, $bindata, $maxdatalen); close($bin); open(my $svf, '>', $svffile) or die "$0: $svffile: $!\n"; # SVF file for the transient load image open(my $in, '<', $svfload) or die "$0: $svfload: $!\n"; while (defined(my $l = <$in>)) { print $svf $l; } close($in); sub print_bitstring($$$) { my($svf, $len, $data) = @_; my $lenbytes = ($len+7) >> 3; if (length($data) < $lenbytes) { $data = ("\0" x ($len - $lenbytes)) . $data; } my $b = -1 - (length($data)-$lenbytes); my $bytes = 0; while ($len > 7) { printf $svf "%02X", unpack("C", substr($data, $b--, 1)); if (!(++$bytes & 63)) { print $svf "\n\t"; } $len -= 8; } if ($len) { my $lb = unpack("C", substr($data, $b--, 1)); $lb &= (1 << $len)-1; printf $svf "%0".(($len+3)>>2)."X", $lb; } } sub virt_sir($$) { my($svf, $cmd) = @_; print $svf "SIR 10 TDI (00E);\n"; printf $svf "SDR %d TDI (", $virbits; print_bitstring($svf, $virbits, pack("V", $virbase | $cmd)); print $svf ");\n"; print $svf "SIR 10 TDI (00C);\n"; } # Set address command my $ramaddr = 0x40000000; virt_sir($svf, 0x12); printf $svf "SDR 32 TDI (%08X);\n", $ramaddr; # Write data to SDRAM virt_sir($svf, 0x16); # Prepend ABC80FED synchronization word $bindata = pack("V", $flashpfx) . $bindata; # Pad to a full 32-bit word (the JTAG command writes full 32-bit words only) $bindata .= "\0" x ((4 - (length($bindata) & 3)) & 3); my $binbits = length($bindata) << 3; printf $svf "SDR %d\n TDI (", $binbits; print_bitstring($svf, $binbits, $bindata); print $svf ");\n"; # Trigger flash command to firmware virt_sir($svf, 0x1a); printf $svf "SDR 32 TDI (%08X);\n", $flashcmd; # Idle JTAG print $svf "SIR 10 TDI (3FF);\n"; print $svf "STATE IDLE;\n";