From 0ddd4002f9cf59e72a6f2ec1645c2b4569b3ebc3 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Thu, 24 Sep 2015 23:16:50 -0400 Subject: Git rid of commas in config language, add some comments. --- config/config.cfg | 6 +-- config/config.py | 117 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 83 insertions(+), 40 deletions(-) diff --git a/config/config.cfg b/config/config.cfg index 360988e..65659f7 100644 --- a/config/config.cfg +++ b/config/config.cfg @@ -4,7 +4,7 @@ default = rsa [hash-only] -cores = sha1, sha256, sha512 +cores = sha1 sha256 sha512 [trng-only] cores = trng @@ -13,7 +13,7 @@ cores = trng cores = modexp [rsa] -cores = sha256, aes, trng, modexp +cores = sha256 aes trng modexp [multi-test] -cores = sha256, aes, aes, chacha, aes +cores = sha256 aes aes chacha aes diff --git a/config/config.py b/config/config.py index 29179e4..74a9007 100755 --- a/config/config.py +++ b/config/config.py @@ -1,48 +1,67 @@ #!/usr/bin/env python -# -# Generate core_selector.v for a set of cores - -import argparse -import re -import ConfigParser +""" +Generate core_selector.v for a set of cores. +""" def main(): - parser = argparse.ArgumentParser() - parser.add_argument("--cores", help = "comma-delimited list of cores") - parser.add_argument("-c", "--config", default = "config.cfg", help = "config file") + """ + Parse arguments and config file, generate core list, generate output. + """ + + from argparse import ArgumentParser, FileType, ArgumentDefaultsHelpFormatter + from ConfigParser import RawConfigParser + from sys import exit + + parser = ArgumentParser(description = __doc__, formatter_class = ArgumentDefaultsHelpFormatter) + parser.add_argument("-c", "--config", help = "config file", default = "config.cfg", type = FileType("r")) + parser.add_argument("-d", "--debug", help = "enable debugging", action = "store_true") + parser.add_argument("-o", "--outfile", help = "output file", default = "core_selector.v", type = FileType("w")) parser.add_argument("-s", "--section", help = "config file section") - parser.add_argument("-o", "--outfile", default = "core_selector.v", help = "output file") + parser.add_argument("core", help = "name(s) of core(s)", nargs = "*") args = parser.parse_args() - cores = args.cores - - if not cores: - try: - cfg = ConfigParser.RawConfigParser() - with open(args.config, "r") as f: - cfg.readfp(f) + try: + if args.core: + cores = args.core + else: + cfg = RawConfigParser() + cfg.readfp(args.config) section = args.section or cfg.get("default", "default") - cores = cfg.get(section, "cores") - except (IOError, ConfigParser.MissingSectionHeaderError,ConfigParser.NoSectionError, configparser.NoOptionError) as e: - exit(str(e)) + cores = cfg.get(section, "cores").split() - cores = re.split(r",\s*", cores) + cores.insert(0, "board_regs") + cores.insert(1, "comm_regs") - cores = [Core.new(core) for core in ["board_regs", "comm_regs"] + cores] - core_number = 0 - for core in cores: - core_number = core.assign_core_number(core_number) + cores = [Core.new(core) for core in cores] + core_number = 0 + for core in cores: + core_number = core.assign_core_number(core_number) - with open(args.outfile, "w") as f: - f.write(createModule_template.format( + args.outfile.write(createModule_template.format( addrs = "".join(core.createAddr() for core in cores), insts = "".join(core.createInstance() for core in cores), muxes = "".join(core.createMux() for core in cores))) + except Exception, e: + if args.debug: + raise + exit(str(e)) + class Core(object): + """ + Data and methods for a generic core. We can use this directly for + most cores, a few are weird and require subclassing to override + particular methods. + """ + + # Class variable tracking how many times a particular core has + # been instantiated. This controls instance numbering. _instance_count = {} + + # Map from core name to subclass for the special case cores. + special_class = {} def __init__(self, name): @@ -70,12 +89,8 @@ class Core(object): def upper_instance_name(self): return self.instance_name.upper() - @property - def createInstance_template(self): - return createInstance_template_generic - def createInstance(self): - return self.createInstance_template.format(core = self) + return createInstance_template_generic.format(core = self) def createAddr(self): return createAddr_template.format(core = self) @@ -85,6 +100,9 @@ class Core(object): class SubCore(Core): + """" + Override mux handling for TRNG's sub-cores. + """ def __init__(self, name, parent): super(SubCore, self).__init__(name) @@ -95,6 +113,12 @@ class SubCore(Core): class TRNGCore(Core): + """ + The TRNG core has an internal mux and a collection of sub-cores. + Mostly this means that our method calls have to iterate over all + of the subcores after handling the base TRNG core, but we also use + a different instance template in the hope that it is easier to read. + """ def __init__(self, name): super(TRNGCore, self).__init__(name) @@ -106,9 +130,8 @@ class TRNGCore(Core): n = subcore.assign_core_number(n) return n - @property - def createInstance_template(self): - return createInstance_template_TRNG + def createInstance(self): + return createInstance_template_TRNG.format(core = self) def createAddr(self): return super(TRNGCore, self).createAddr() + "".join(subcore.createAddr() for subcore in self.subcores) @@ -116,13 +139,26 @@ class TRNGCore(Core): def createMux(self): return super(TRNGCore, self).createMux() + "".join(subcore.createMux() for subcore in self.subcores) +# Hook TRNGCore in as the handler for "trng" core instances. + Core.special_class["trng"] = TRNGCore +# Add other special cases here as needed. + + +# Templates (format strings), here instead of inline in the functions +# that use them, both because some of these are shared between +# multiple functions and because it's easier to read these (and get +# the indentation right) when the're separate. + +# Template used by .createAddr() methods. createAddr_template = """\ localparam CORE_ADDR_{core.upper_instance_name:21s} = 9'h{core.core_number:02x}; """ +# Template used by Core.createInstance(). + createInstance_template_generic = """\ //---------------------------------------------------------------- // {core.upper_instance_name} @@ -147,6 +183,10 @@ createInstance_template_generic = """\ """ +# Template used by TRNGCore.createInstance(); this is different enough +# from the generic template that it's (probably) clearer to have this +# separate. + createInstance_template_TRNG = """\ //---------------------------------------------------------------- // {core.upper_instance_name} @@ -175,6 +215,8 @@ createInstance_template_TRNG = """\ """ +# Template for .createMux() methods. + createMux_template = """\ CORE_ADDR_{core.upper_instance_name}: begin @@ -183,6 +225,8 @@ createMux_template = """\ end """ +# Top-level (createModule) template. + createModule_template = """\ // NOTE: This file is generated; do not edit by hand. @@ -246,8 +290,7 @@ endmodule //====================================================================== """ -# main - +# Run main program. if __name__ == "__main__": main() -- cgit v1.2.3