From 3c79893217bc632c9b0efa815091bef3c779490c Mon Sep 17 00:00:00 2001 From: alexander Date: Fri, 26 Mar 2021 21:42:19 +0000 Subject: Opensource ML embedded evaluation kit Change-Id: I12e807f19f5cacad7cef82572b6dd48252fd61fd --- scripts/py/gen_fpga_mem_map.py | 192 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 scripts/py/gen_fpga_mem_map.py (limited to 'scripts/py/gen_fpga_mem_map.py') diff --git a/scripts/py/gen_fpga_mem_map.py b/scripts/py/gen_fpga_mem_map.py new file mode 100644 index 0000000..6a2d1d2 --- /dev/null +++ b/scripts/py/gen_fpga_mem_map.py @@ -0,0 +1,192 @@ +# Copyright (c) 2021 Arm Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +import os +from argparse import ArgumentParser + +""" +This file is used as part of post build steps to generate 'images.txt' file +which can be copied over onto the MPS3 board's SD card. The purpose is to +limit having to manually edit the file based on different load regions that +the build scatter file might dictate. +""" + +def is_commented(line): + if (line.startswith(";")): + return True + else: + return False + + +def is_load_rom(line): + load_region_specifiers = ['LOAD_ROM', 'LD_ROM', 'LOAD_REGION'] + + for load_specifier in load_region_specifiers: + if line.startswith(load_specifier): + return True + + return False + + +class TargetSubsystem: + + def __init__(self, target_subsystem_name: str): + """ + Constructor for target class. + Arguments: + target_subsystem_name: name of the target subsystem + """ + # Dict with mem map and binary names we expect + self.subsystems = { + "sse-200": { + "mmap_mcc" : { + # FPGA addr | MCC addr | + "0x00000000": "0x00000000", # ITCM (NS) + "0x10000000": "0x01000000", # ITCM (S) + "0x20000000": "0x02000000", # DTCM (NS) + "0x30000000": "0x03000000", # DTCM (S) + "0x60000000": "0x08000000" # DDR (NS) + }, + "bin_names": { + 0: "itcm.bin", + 1: "dram.bin" + } + }, + "sse-300": { + "mmap_mcc" : { + # FPGA addr | MCC addr | + "0x00000000": "0x00000000", # ITCM (NS) + "0x01000000": "0x02000000", # BRAM or FPGA's data SRAM (NS) + "0x60000000": "0x08000000", # DDR (NS) + "0x70000000": "0x0c000000" # DDR (S) + }, + "bin_names": { + 0: "itcm.bin", + 1: "dram.bin" + } + } + } + + self.name = target_subsystem_name + + + def is_supported(self, target_subsystem: str) -> bool: + """ + Checks if the target subsystem exists within systems + supported by this script + """ + if target_subsystem in self.subsystems.keys(): + return True + + print(f"Platforms supported: {self.subsystems.keys()}") + return False + + + def mps3_mappings(self) -> dict: + """ + Returns the FPGA <--> MCC address translations + as a dict + """ + if self.is_supported(self.name): + return self.subsystems[self.name]['mmap_mcc'] + return {} + + + def mps3_bin_names(self) -> dict: + """ + Returns expected binary names for the executable built + for Cortex-M55 or Cortex-M55+Ethos-U55 targets in the + form of a dict with index and name + """ + if self.is_supported(self.name): + return self.subsystems[self.name]['bin_names'] + + return {} + + +def main(args): + """ + Generates the output txt file with MCC to FPGA address mapping used + that is used by the MCC on FPGA to load executable regions into + correct regions in memory. + """ + # List out arguments used: + scatter_file_path = args.scatter_file_path + target_subsystem_name = args.target_subsystem + output_file_path = args.output_file_path + + target = TargetSubsystem(target_subsystem_name=target_subsystem_name) + + if target.is_supported(target_subsystem_name) != True: + print(f'Target {target_subsystem_name} not supported.') + return + + with open(scatter_file_path,'r') as scatter_file: + lines_read = scatter_file.readlines() + str_list = [] + + bin_names = None + mem_map = None + + mem_map = target.mps3_mappings() + bin_names = target.mps3_bin_names() + + str_list.append("TITLE: Arm MPS3 FPGA prototyping board Images Configuration File\n") + str_list.append("[IMAGES]\n\n") + + cnt = 0 + for line in lines_read: + if is_commented(line) or is_load_rom(line) != True: + continue + + addr = line.split()[1] + + if mem_map.get(addr, None) == None: + raise RuntimeError( + 'Translation for this address unavailable') + if cnt > len(bin_names): + raise RuntimeError( + f"bin names len exceeded: {cnt}") + + str_list.append("IMAGE" + str(cnt) + "ADDRESS: " + + mem_map[addr] + " ; MCC@" + mem_map[addr] + + " <=> FPGA@" + addr + "\n") + str_list.append("IMAGE" + str(cnt) + "UPDATE: AUTO\n") + str_list.append("IMAGE" + str(cnt) + "FILE: \SOFTWARE\\" + + bin_names[cnt] + "\n\n") + cnt += 1 + + if cnt > 0 and cnt < 33: + str_list.insert(2, + "TOTALIMAGES: {} ;Number of Images (Max: 32)\n\n".format( + cnt)) + else: + raise RuntimeError('Invalid image count') + + if os.path.exists(output_file_path): + os.remove(output_file_path) + print(''.join(str_list), file=open(output_file_path, "a")) + + +if __name__ == "__main__": + parser = ArgumentParser() + parser.add_argument("--scatter_file_path", type=str, required=True, + help="Path to the scatter file") + parser.add_argument("--target_subsystem", type=str, required=True, + help="Target subsystem in use") + parser.add_argument("--output_file_path", type=str, required=True, + help="Output file path") + args = parser.parse_args() + main(args) -- cgit v1.2.1