#!/usr/bin/perl use strict; use integer; my($infile,$outfile,$depth,$width,$stride) = @ARGV; $stride = 1 unless (defined($stride)); my $bytesperword = ($width+7) >> 3; open(my $in, '<:raw', $infile) or die; my $data; my $dlen = read($in,$data,$depth*$bytesperword*$stride); close($in); my $sdig = 1; while ((1 << ($sdig*4)) < $stride) { $sdig++; } my $adig = 1; while ((1 << ($adig*4)) < $depth) { $adig++; } for (my $s = 0; $s < $stride; $s++) { my $ofname = $outfile; if ($stride > 1) { $outfile =~ /^(.*?)(\.\w+)?$/; $ofname = sprintf("%s.%d%s", $1, $s, $2); } open(my $out, '>', $ofname) or die; printf $out "-- generated from %s\n", $infile; if ($stride > 1) { printf $out "-- array %d/%d (hex %0${sdig}X of [%0${sdig}X..%0${sdig}X])\n", $s+1, $stride, $s, 0, $stride-1; } printf $out "DEPTH = %d;\n", $depth; printf $out "WIDTH = %d;\n", $width; printf $out "ADDRESS_RADIX = HEX;\n"; printf $out "DATA_RADIX = HEX;\n"; printf $out "CONTENT BEGIN\n"; my $addr; for ($addr = 0; $addr < $depth; $addr++) { my $offs = ($addr*$stride+$s)*$bytesperword; last if ($offs >= $dlen); printf $out "%0${adig}X : ", $addr; # Emitting data byte by byte avoids need for bigint for (my $b = $bytesperword-1; $b >= 0; $b--) { if ($offs+$b < $dlen) { printf $out "%02X", unpack("C", substr($data,$offs+$b,1)); } } printf $out ";\n"; } if ($addr < $depth) { printf $out "[%0${adig}X..%0${adig}X] : 00;\n", $addr, $depth-1; } printf $out "END;\n"; close($out); } if ($stride > 1) { # Create an empty file for the benefit of make open(my $out, '>', $outfile) or die; close($out); } exit 0;