From a5ee995ed46d86d0af6a30cb9fdffd47c4c50814 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Tue, 4 Apr 2023 12:22:44 -0700 Subject: [PATCH 1/2] New Scala-based Config Finder --- build.sbt | 7 ++++++- common.mk | 10 +++------- docs/Customization/Keys-Traits-Configs.rst | 3 +-- .../src/main/scala/ConfigFinder.scala | 19 +++++++++++++++++++ 4 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 generators/chipyard/src/main/scala/ConfigFinder.scala diff --git a/build.sbt b/build.sbt index 0f065836..4e9656bc 100644 --- a/build.sbt +++ b/build.sbt @@ -149,7 +149,12 @@ lazy val chipyard = (project in file("generators/chipyard")) gemmini, icenet, tracegen, cva6, nvdla, sodor, ibex, fft_generator, constellation, mempress) .settings(libraryDependencies ++= rocketLibDeps.value) - .settings(commonSettings) + .settings( + libraryDependencies ++= Seq( + "org.reflections" % "reflections" % "0.10.2" + ) + ) + .settings(commonSettings) lazy val mempress = (project in file("generators/mempress")) .dependsOn(rocketchip, midasTargetUtils) diff --git a/common.mk b/common.mk index 6cebf335..a4668075 100644 --- a/common.mk +++ b/common.mk @@ -50,7 +50,7 @@ HELP_COMMANDS += \ " run-tests = run all assembly and benchmark tests" \ " launch-sbt = start sbt terminal" \ " {shutdown,start}-sbt-server = shutdown or start sbt server if using ENABLE_SBT_THIN_CLIENT" \ -" find-config-fragments = list all config. fragments and their locations (recursive up to CONFIG_FRAG_LEVELS=$(CONFIG_FRAG_LEVELS))" +" find-config-fragments = list all config. fragments" ######################################################################################### # include additional subproject make fragments @@ -406,13 +406,9 @@ define \n endef -CONFIG_FRAG_LEVELS ?= 3 .PHONY: find-config-fragments -find-config-fragments: private IN_F := $(shell mktemp -d -t cy-XXXXXXXX)/scala_files.f -find-config-fragments: $(SCALA_SOURCES) - @$(foreach file,$(SCALA_SOURCES),echo $(file) >> $(IN_F)${\n}) - $(base_dir)/scripts/config-finder.py -l $(CONFIG_FRAG_LEVELS) $(IN_F) - @rm -rf $(dir $(IN_F)) +find-config-fragments: + $(call run_scala_main,chipyard,chipyard.ConfigFinder,) .PHONY: help help: diff --git a/docs/Customization/Keys-Traits-Configs.rst b/docs/Customization/Keys-Traits-Configs.rst index 364f31cb..7b6d565b 100644 --- a/docs/Customization/Keys-Traits-Configs.rst +++ b/docs/Customization/Keys-Traits-Configs.rst @@ -79,5 +79,4 @@ We can use this config fragment when composing our configs. Chipyard Config Fragments ------------------------- -For discoverability, users can run ``make find-config-fragments`` to see a list of config. fragments -(config. fragments that match "class NAME extends CONFIG\n" on a single line and a subset of their children) and their file path in a fully initialized Chipyard repository. +For discoverability, users can run ``make find-config-fragments`` to see a list of config. fragments. diff --git a/generators/chipyard/src/main/scala/ConfigFinder.scala b/generators/chipyard/src/main/scala/ConfigFinder.scala new file mode 100644 index 00000000..1c83c3d1 --- /dev/null +++ b/generators/chipyard/src/main/scala/ConfigFinder.scala @@ -0,0 +1,19 @@ +package chipyard + +import org.reflections.Reflections +import org.reflections.scanners.Scanners.SubTypes +import scala.jdk.CollectionConverters._ +import scala.collection.{SortedSet} + +import freechips.rocketchip.config.{Config} + +object ConfigFinder { + def main(args: Array[String]) = { + val reflections = new Reflections() + val classes = reflections.get(SubTypes.of(classOf[Config]).asClass()).asScala + val sortedClasses = SortedSet[String]() ++ classes.map(_.getName) + for (cls <- sortedClasses) { + println(cls) + } + } +} From ee9ee109109baad6971c9cafe99507768e9b9cb8 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Tue, 4 Apr 2023 12:26:02 -0700 Subject: [PATCH 2/2] Remove old config-finder.py --- scripts/config-finder.py | 76 ---------------------------------------- 1 file changed, 76 deletions(-) delete mode 100755 scripts/config-finder.py diff --git a/scripts/config-finder.py b/scripts/config-finder.py deleted file mode 100755 index a7377939..00000000 --- a/scripts/config-finder.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import subprocess -from collections import defaultdict -import re -from copy import deepcopy -import os - -cy_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - -# from https://gist.github.com/angstwad/bf22d1822c38a92ec0a9 -def deep_merge(a: dict, b: dict) -> dict: - """Merge two dicts and return a singular dict""" - result = deepcopy(a) - for bk, bv in b.items(): - av = result.get(bk) - if isinstance(av, dict) and isinstance(bv, dict): - result[bk] = deep_merge(av, bv) - else: - result[bk] = deepcopy(bv) - return result - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Pretty print all configs given a filelist of scala files') - parser.add_argument('FILE', type=str, help='Filelist of scala files to search within') - parser.add_argument('-l', '--levels', default=0, type=int, help='Number of levels to recursively look for configs') - args = parser.parse_args() - - files = [] - with open(args.FILE, 'r') as f: - files = f.read().splitlines() - - cmd = ['grep', '-o', r"class \+.* \+extends \+Config"] + files - r = subprocess.run(cmd, check=True, capture_output=True) - - base_file_path_dict = defaultdict(list) - for l in r.stdout.decode("UTF-8").splitlines(): - match = re.match(r"^(.*):class +([a-zA-Z_$][a-zA-Z\d_$]*).* +extends", l) - if match: - base_file_path_dict[match.group(1)].append(match.group(2)) - - levels = [] - for level in range(args.levels): - if level == 0: - # use the base - dict_to_use = base_file_path_dict - else: - # use the level-1 dict - assert len(levels) > 0 - dict_to_use = levels[-1] - - file_path_dict = defaultdict(list) - - for configs in dict_to_use.values(): - for config in configs: - cmd = ['grep', '-o', r"class \+.* \+extends \+" + f"{config}"] + files - r = subprocess.run(cmd, capture_output=True) - - for l in r.stdout.decode("UTF-8").splitlines(): - match = re.match(r"^(.*):class +([a-zA-Z_$][a-zA-Z\d_$]*).* +extends", l) - if match: - file_path_dict[match.group(1)].append(match.group(2)) - - levels.append(file_path_dict) - - final_dict = base_file_path_dict - for dct in levels: - final_dict = deep_merge(final_dict, dct) - - print(f"Finding all one-line config. fragments (up to {args.levels} levels)\n") - for k, v in final_dict.items(): - print(f"{k.replace(cy_path, 'chipyard')}:") - for e in v: - print(f" {e}") - print("")