mirror of
https://github.com/TinyTapeout/tt-support-tools.git
synced 2026-11-03 04:36:09 +01:00
115 lines
4.9 KiB
Python
115 lines
4.9 KiB
Python
import logging
|
|
import os
|
|
import yaml
|
|
import json
|
|
import glob
|
|
import shutil
|
|
|
|
def copy_print(src: str, dest: str):
|
|
logging.info(f" -> {dest}")
|
|
shutil.copy2(src, dest)
|
|
|
|
|
|
def copy_print_glob(pattern: str, dest_dir: str):
|
|
for file in glob.glob(pattern):
|
|
copy_print(file, os.path.join(dest_dir, os.path.basename(file)))
|
|
|
|
class CaravelConfig():
|
|
|
|
def __init__(self, config, projects, modules_yaml_name: str):
|
|
self.config = config
|
|
self.projects = projects
|
|
self.script_dir = os.path.dirname(os.path.realpath(__file__))
|
|
self.modules_yaml_name = modules_yaml_name
|
|
|
|
def write_gl_config(self):
|
|
with open('verilog/includes/includes.gl.caravel_user_project', 'w') as fh:
|
|
fh.write('-v $(USER_PROJECT_VERILOG)/gl/user_project_wrapper.v\n')
|
|
fh.write('-v $(USER_PROJECT_VERILOG)/gl/tt_ctrl.v\n')
|
|
fh.write('-v $(USER_PROJECT_VERILOG)/gl/tt_mux.v\n')
|
|
for project in self.projects:
|
|
fh.write(f'-v $(USER_PROJECT_VERILOG)/../projects/{project.top_module}/{project.get_gl_verilog_filename()}\n')
|
|
|
|
def configure_mux(self):
|
|
with open(self.modules_yaml_name, 'r') as modules_file:
|
|
module_config = yaml.safe_load(modules_file)
|
|
configured_macros = set(map(lambda mod: mod['name'], module_config['modules']))
|
|
logging.info(f"found {len(configured_macros)} preconfigured macros: {configured_macros}")
|
|
for project in self.projects:
|
|
if project.unprefixed_name not in configured_macros:
|
|
module_config['modules'].append({'name': project.unprefixed_name})
|
|
|
|
with open('tt-multiplexer/cfg/modules.yaml', 'w') as mux_modules_file:
|
|
yaml.dump(module_config, mux_modules_file)
|
|
|
|
res = os.system("make -C tt-multiplexer gensrc")
|
|
if res != 0:
|
|
logging.error("Failed to generate multiplexer placement configuration")
|
|
exit(1)
|
|
|
|
mux_index = {}
|
|
mux_index_reverse = {}
|
|
with open('tt-multiplexer/cfg/modules_placed.yaml') as placed_modules_file:
|
|
placed_modules = yaml.safe_load(placed_modules_file)
|
|
for module in placed_modules['modules']:
|
|
mux_address = (module['y'] << 5) + module['x']
|
|
module_name = 'tt_um_' + module['name']
|
|
mux_index[mux_address] = module_name
|
|
mux_index_reverse[module_name] = mux_address
|
|
|
|
for project in self.projects:
|
|
if project.top_module not in mux_index_reverse:
|
|
logging.error(f"no placement found for {project}!")
|
|
exit(1)
|
|
project.mux_address = mux_index_reverse[project.top_module]
|
|
|
|
with open('mux_index.json', 'w') as mux_index_file:
|
|
json.dump(mux_index, mux_index_file)
|
|
|
|
def list(self):
|
|
for project in self.projects:
|
|
logging.info(project)
|
|
|
|
|
|
def find_last_run(self, macro: str):
|
|
runs = f"tt-multiplexer/ol2/{macro}/runs/"
|
|
runlist = sorted(
|
|
[r for r in os.listdir(runs) if r.startswith("RUN_") and os.path.isdir(os.path.join(runs, r))]
|
|
)
|
|
if len(runlist) == 0:
|
|
print(f"Error: no runs found for {macro}")
|
|
exit(1)
|
|
|
|
return os.path.join(runs, runlist[-1])
|
|
|
|
|
|
def copy_macros(self):
|
|
logging.info('copying macros to tt_top:')
|
|
copy_print_glob("projects/*/*.gds", "tt-multiplexer/ol2/tt_top/gds")
|
|
copy_print_glob("projects/*/*.lef", "tt-multiplexer/ol2/tt_top/lef")
|
|
copy_print_glob("projects/*/*.v", "tt-multiplexer/ol2/tt_top/verilog")
|
|
macros = ["tt_ctrl", "tt_mux"]
|
|
for macro in macros:
|
|
lastrun = self.find_last_run(macro)
|
|
copy_print(f"{lastrun}/final/gds/{macro}.magic.gds", f"tt-multiplexer/ol2/tt_top/gds/{macro}.gds")
|
|
copy_print(f"{lastrun}/final/lef/{macro}.lef", f"tt-multiplexer/ol2/tt_top/lef/{macro}.lef")
|
|
|
|
|
|
def copy_final_results(self):
|
|
macros = ["tt_ctrl", "tt_mux", "tt_top"]
|
|
|
|
logging.info('copying final results:')
|
|
for macro in macros:
|
|
lastrun = self.find_last_run(macro)
|
|
macro_name = macro if macro != "tt_top" else "user_project_wrapper"
|
|
logging.info(f"** {macro_name} **")
|
|
logging.info(f" FROM {lastrun}")
|
|
copy_print(f"{lastrun}/final/gds/{macro_name}.magic.gds", f"gds/{macro_name}.gds")
|
|
copy_print(f"{lastrun}/final/lef/{macro_name}.lef", f"lef/{macro_name}.lef")
|
|
copy_print(f"{lastrun}/final/pnl/{macro_name}.pnl.v", f"verilog/gl/{macro_name}.v")
|
|
copy_print(f"{lastrun}/final/nl/{macro_name}.nl.v", f"verilog/gl/{macro_name}.nl.v")
|
|
shutil.copytree(
|
|
f"{lastrun}/final/spef", f"spef/", copy_function=copy_print, dirs_exist_ok=True
|
|
)
|
|
copy_print(f"{lastrun}/final/spef/nom_/{macro_name}.nom.spef", f"spef/{macro_name}.spef")
|