# # Copyright © 2017-2019 Eric Matthews, Lesley Shannon # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Initial code developed under the supervision of Dr. Lesley Shannon, # Reconfigurable Computing Lab, Simon Fraser University. # # Author(s): # Eric Matthews # import argparse import re import sys import subprocess import tempfile def stringByteSwap(s): pairs = [s[i:i+2] for i in range(0, len(s), 2)] return ''.join(pairs[::-1]) parser = argparse.ArgumentParser(description='Converts binary into init files for simulation and BRAMs') #objdump prefix parser.add_argument('toolPrefix', help='the prefix for objdump') #base adder required parser.add_argument('baseAddr', help='the base address') #ram size required parser.add_argument('ramSize', help='the ram size') # input file required parser.add_argument('inputFile', help='The executable') # output file names parser.add_argument('outputFile', help='The ram init file') parser.add_argument('simFile', help='The sim data file') parser.add_argument('--quiet', '-q', help='Suppresses diagnostic output ', action="store_true") args = parser.parse_args() # open input file print(args.inputFile) subprocess.run([args.toolPrefix + 'objcopy', '--gap-fill=0x00', '-O', 'binary', args.inputFile, args.inputFile + '.rawbinary']) subprocess.run([args.toolPrefix + 'objdump', '-fd', '--prefix-addresses', args.inputFile], stdout=open(args.inputFile + '.dissasembled', "w")) try: program_input = open(args.inputFile + '.rawbinary', 'rb') opcode_input = open(args.inputFile + '.dissasembled', 'r') except IOError: print('Could not open files: ', args.inputFile + '.raw ', args.inputFile + '.dissasembled') sys.exit() program_output = args.inputFile + '.bin' sim_output = args.inputFile + '.sim' if (args.outputFile) : program_output = args.outputFile if (args.simFile) : sim_output = args.simFile # open output file try: program_output = open(program_output, 'w') sim_output = open(sim_output, 'w') except IOError: print('Could not create files: ', program_output, sim_output) sys.exit() print('array size ', int(int(args.ramSize)/4)) #Initialize with zero ramData = ['00000000'] * int((int(args.ramSize)/4)); instLineRegex = re.compile(r'\s+') isInstLine = re.compile(r'[a-f0-9]{8}\s+<\S+') #pattern hexaddress instruction #parses the block output format addressRegex = re.compile(r'0x[a-f0-9]{8}') hexRegex = re.compile(r'[a-f0-9]{8}') #Find start address and lowest address in dissasembly file index = 0 lowestAddress = sys.maxsize for line in opcode_input: if (isInstLine.match(line)) : addressMatch = hexRegex.match(line) if (int(addressMatch[0],16) < lowestAddress) : lowestAddress = int(addressMatch[0],16) index = int(lowestAddress/4) - int(int(args.baseAddr,16)/4) if (line.find('start address') != -1) : addressMatch = addressRegex.search(line) print('start address: ', addressMatch[0]) #Reads binary 4 bytes at a time and converts to Verilog readmemh format word = program_input.read(4) while word != b"": ramData[index] = stringByteSwap(word.hex()) index+=1 word = program_input.read(4) program_output.write('\n'.join(str(line) for line in ramData)) #append instruction details to data opcode_input.seek(0) for line in opcode_input: if (isInstLine.match(line)) : lineContents = list(filter(None, instLineRegex.split(line))) #split line and remove empty strings index = int((int(lineContents[0],16) - int(args.baseAddr,16))/4) ramData[index] += ' ' + ' '.join(lineContents[1:]) sim_output.write(' --\n'.join(str(line) for line in ramData)) sim_output.write(' --') print('Done')