blob: c142d0835080976e9b845ba55f34db8f33a49f2f [file] [log] [blame]
#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
"""Script used to reduce the size of design for smaller FPGA devices.
This script modifies two source files to reduce the size of the design and then regenerates
all auto-generated files. The flash size is reduced in a way that does not impact the register
interface of the flash controller and is thus more or less transparent to software.
"""
import argparse
import hjson
import textwrap
import logging as log
import subprocess
import sys
hdr = '''// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------//
'''
orighdr = hdr + '''
// This file has been automatically created from top_earlgrey.hjson.
// This is a reformatted copy of top_earlgrey.hjson
'''
genhdr = hdr + '''
// This file has been automatically modified to reduce the size of the flash.
// To see what has been changed, please compare to top_earlgrey.original.hjson.
'''
def wrapped_docstring():
'''Return a text-wrapped version of the module docstring'''
paras = []
para = []
for line in __doc__.strip().split('\n'):
line = line.strip()
if not line:
if para:
paras.append('\n'.join(para))
para = []
else:
para.append(line)
if para:
paras.append('\n'.join(para))
return '\n\n'.join(textwrap.fill(p) for p in paras)
def _nexysvideo_reduce(cfg):
log.info("Updating target to nexysvideo settings")
log.info("Flash to 128 pages")
log.info("Memory to 64KB")
for mem in cfg["memory"]:
if mem['name'] == 'eflash':
mem['pages_per_bank'] = 128
if mem['name'] == 'ram_main':
mem['size'] = '0x10000'
def main():
# Display INFO log messages and up.
log.basicConfig(level=log.INFO, format="%(levelname)s: %(message)s")
parser = argparse.ArgumentParser(
prog="fpga_size_reduce",
description=wrapped_docstring(),
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument(
'--toppath',
'-t',
default='.',
help='provide top path.')
parser.add_argument(
'--target',
'-g',
default='nexysvideo',
choices=['nexysvideo'],
help='fpga reduction target')
parser.add_argument(
'--build',
'-b',
default=False,
action='store_true',
help='Build ROM based on reduced design')
args = parser.parse_args()
# Get path to top-level directory
top_path = args.toppath
top_hjson = top_path + '/hw/top_earlgrey/data/top_earlgrey.hjson'
orig_hjson = top_hjson + '.orig'
# Modify hjson to change flash size
with open(top_hjson, "r") as hjson_file:
cfg = hjson.load(hjson_file,
use_decimal=True)
# write out original version reformatted
with open(orig_hjson, "w") as hjson_file:
hjson_file.write(orighdr + hjson.dumps(cfg, hjson_file))
# update value based on target selection
globals()["_{}_reduce".format(args.target)](cfg)
# write back updated hjson
with open(top_hjson, "w") as hjson_file:
hjson_file.write(genhdr + hjson.dumps(cfg, hjson_file))
# Regenerate auto-generated files
print("Regenerating all auto-generated files...")
cmd = ["make", "-C", top_path + "/hw"]
try:
subprocess.run(cmd,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
except subprocess.CalledProcessError as e:
log.error("Failed to regenerate auto-generated files: " + str(e))
log.error(e.stdout)
sys.exit(1)
# Regenerate boot ROM
if (args.build):
log.info("Regenerating boot ROM...")
cmd = ["ninja", "-C", top_path + "/build-out",
"sw/device/lib/testing/test_rom/test_rom_export_fpga_nexysvideo"]
try:
subprocess.run(cmd,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
except subprocess.CalledProcessError as e:
log.error("Failed to regenerate boot ROM: " + str(e))
log.error(e.stdout)
sys.exit(1)
return 0
if __name__ == "__main__":
sys.exit(main())