Skip to content

Instantly share code, notes, and snippets.

@tako2
Created February 1, 2025 07:40
Show Gist options
  • Save tako2/3ac600937053801e67c5df4c18c5af10 to your computer and use it in GitHub Desktop.
Save tako2/3ac600937053801e67c5df4c18c5af10 to your computer and use it in GitHub Desktop.
Translate binary file to .mi file (for GOWIN FPGA Designer)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from optparse import OptionParser
#==============================================================================
def dump_bin(out_fp, top_addr, data, size):
for addr in range(0, size, 16):
out_fp.write('{:04X}:'.format(top_addr + addr))
end_addr = (addr + 16) if (addr + 16) < size else size
for idx in range(addr, end_addr):
if data is None:
out_fp.write(' 00')
else:
out_fp.write(' {:02X}'.format(data[idx]))
out_fp.write(';\n')
#==============================================================================
def write(fp, string):
b = bytes(string, 'utf-8')
fp.write(b)
#==============================================================================
def bin2mi(in_file, padding_size, total_size):
out_file = in_file.split('.')[0] + '.mi'
print(in_file, '=>', out_file)
with open(in_file, 'rb') as in_fp:
data = in_fp.read()
if total_size < len(data) + padding_size:
total_size = len(data) + padding_size
remain_size = 0
else:
remain_size = total_size - (len(data) + padding_size)
with open(out_file, 'wb') as out_fp:
write(out_fp, '#File_format=Hex\012')
write(out_fp, '#Address_depth={}\012'.format(total_size))
write(out_fp, '#Data_width=8\012')
if padding_size > 0:
for _ in range(padding_size):
write(out_fp, '00\012')
for ch in data:
write(out_fp, '{:02X}\012'.format(ch))
if remain_size > 0:
for _ in range(remain_size):
write(out_fp, '00\012')
#==============================================================================
def main(options, args):
try:
if options.padding.startswith('0x'):
padding_size = int(options.padding[2:], 16)
else:
padding_size = int(options.padding)
except:
padding_size = 0
try:
if options.total.startswith('0x'):
total_size = int(options.total[2:], 16)
else:
total_size = int(options.total)
except:
total_size = 0
bin2mi(args[0], padding_size, total_size)
#==============================================================================
if __name__ == '__main__':
parser = OptionParser(usage='Usage: %prog [options] binary_file')
parser.add_option('-p', '--padding',
type='str', dest='padding', default='0',
help='spacing PADDING bytes', metavar='PADDING')
parser.add_option('-t', '--total',
type='str', dest='total', default='0',
help='file TOTAL bytes', metavar='TOTAL')
options, args = parser.parse_args()
if len(args) < 1:
parser.print_help()
exit()
main(options, args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment