-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
221 additions
and
3 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
# This file is part of the M2-ISA-R project: https://github.com/tum-ei-eda/M2-ISA-R | ||
# | ||
# Copyright (C) 2022 | ||
# Chair of Electrical Design Automation | ||
# Technical University of Munich | ||
|
||
"""Clean M2-ISA-R/Seal5 metamodel to .core_desc file.""" | ||
|
||
import argparse | ||
import logging | ||
import pathlib | ||
import pickle | ||
from typing import Union | ||
|
||
from mako.template import Template | ||
|
||
from m2isar.metamodel import arch | ||
|
||
from seal5.index import NamedPatch, write_index_yaml | ||
from seal5.settings import ExtensionsSettings | ||
|
||
logger = logging.getLogger("riscv_isa_info") | ||
|
||
|
||
MAKO_TEMPLATE = " {\"${arch}\", RISCVExtensionVersion{${version_major}, ${version_minor}}}," | ||
|
||
|
||
def gen_riscv_isa_info_str(name: str, ext_settings: ExtensionsSettings): | ||
print("name", name) | ||
print("ext_settings", ext_settings) | ||
arch = ext_settings.get_arch(name=name) | ||
version = ext_settings.get_version() | ||
assert isinstance(version, float) | ||
version_major, version_minor = str(version).split(".", 1) | ||
|
||
content_template = Template(MAKO_TEMPLATE) | ||
content_text = content_template.render(arch=arch, version_major=version_major, version_minor=version_minor) | ||
# content_text = content_text.rstrip("\n") | ||
return content_text | ||
|
||
|
||
def main(): | ||
"""Main app entrypoint.""" | ||
|
||
# read command line args | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument("top_level", help="A .m2isarmodel or .seal5model file.") | ||
parser.add_argument("--log", default="info", choices=["critical", "error", "warning", "info", "debug"]) | ||
parser.add_argument("--output", "-o", type=str, default=None) | ||
parser.add_argument("--splitted", action="store_true", help="Split per set") | ||
parser.add_argument("--formats", action="store_true", help="Also generate instruction formats") | ||
parser.add_argument("--metrics", default=None, help="Output metrics to file") | ||
parser.add_argument("--index", default=None, help="Output index to file") | ||
parser.add_argument("--ext", type=str, default="td", help="Default file extension (if using --splitted)") | ||
args = parser.parse_args() | ||
|
||
# initialize logging | ||
logging.basicConfig(level=getattr(logging, args.log.upper())) | ||
|
||
# resolve model paths | ||
top_level = pathlib.Path(args.top_level) | ||
# abs_top_level = top_level.resolve() | ||
|
||
is_seal5_model = False | ||
# print("top_level", top_level) | ||
# print("suffix", top_level.suffix) | ||
if top_level.suffix == ".seal5model": | ||
is_seal5_model = True | ||
if args.output is None: | ||
assert top_level.suffix in [".m2isarmodel", ".seal5model"], "Can not infer model type from file extension." | ||
raise NotImplementedError | ||
|
||
# out_path = top_level.parent / (top_level.stem + ".core_desc") | ||
else: | ||
out_path = pathlib.Path(args.output) | ||
|
||
logger.info("loading models") | ||
if not is_seal5_model: | ||
raise NotImplementedError | ||
|
||
# load models | ||
with open(top_level, "rb") as f: | ||
# models: "dict[str, arch.CoreDef]" = pickle.load(f) | ||
if is_seal5_model: | ||
model: "dict[str, Union[arch.InstructionSet, ...]]" = pickle.load(f) | ||
model["cores"] = {} | ||
else: # TODO: core vs. set! | ||
temp: "dict[str, Union[arch.InstructionSet, arch.CoreDef]]" = pickle.load(f) | ||
assert len(temp) > 0, "Empty model!" | ||
if isinstance(list(temp.values())[0], arch.CoreDef): | ||
model = {"cores": temp, "sets": {}} | ||
elif isinstance(list(temp.values())[0], arch.InstructionSet): | ||
model = {"sets": temp, "cores": {}} | ||
else: | ||
assert False | ||
|
||
metrics = { | ||
"n_sets": 0, | ||
"n_skipped": 0, | ||
"n_failed": 0, | ||
"n_success": 0, | ||
} | ||
# preprocess model | ||
# print("model", model) | ||
artifacts = {} | ||
artifacts[None] = [] # used for global artifacts | ||
if args.splitted: | ||
raise NotImplementedError | ||
else: | ||
content = "" | ||
# errs = [] | ||
for set_name, set_def in model["sets"].items(): | ||
artifacts[set_name] = [] | ||
metrics["n_sets"] += 1 | ||
ext_settings = set_def.settings | ||
if ext_settings is None: | ||
metrics["n_skipped"] += 1 | ||
continue | ||
metrics["n_success"] += 1 | ||
content += gen_riscv_isa_info_str(set_name, ext_settings) | ||
if len(content) > 0: | ||
with open(out_path, "w") as f: | ||
f.write(content) | ||
if ext_settings.experimental: | ||
key = "riscv_isa_info_experimental" | ||
else: | ||
key = "riscv_isa_info" | ||
riscv_isa_info_patch = NamedPatch( | ||
"llvm/lib/Support/RISCVISAInfo.cpp", key=key, src_path=out_path | ||
) | ||
artifacts[None].append(riscv_isa_info_patch) | ||
if args.metrics: | ||
metrics_file = args.metrics | ||
with open(metrics_file, "w") as f: | ||
f.write(",".join(metrics.keys())) | ||
f.write("\n") | ||
f.write(",".join(map(str, metrics.values()))) | ||
f.write("\n") | ||
if args.index: | ||
if sum(map(lambda x: len(x), artifacts.values())) > 0: | ||
global_artifacts = artifacts.get(None, []) | ||
set_artifacts = {key: value for key, value in artifacts.items() if key is not None} | ||
index_file = args.index | ||
write_index_yaml(index_file, global_artifacts, set_artifacts, content=True) | ||
else: | ||
logger.warning("No patches generated. No index file will be written.") | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters