diff options
author | Paul Selkirk <paul@psgd.org> | 2017-01-17 23:43:46 -0500 |
---|---|---|
committer | Paul Selkirk <paul@psgd.org> | 2017-01-17 23:43:46 -0500 |
commit | 8fd190d498cc68a8b51b4141c1ed6f12ef2ec2dd (patch) | |
tree | 0127422845da6f4fca9799ba5a1ff95b04e82cf9 | |
parent | 2f4a3aaf057b21a830112461d77bd4717ac41737 (diff) |
Rename and rewrite the core_selector generator.
By moving most of the domain-specific knowledge from the script to the
config file, we can a) merge back the fork in platform/alpha, and b) remove
the special-case code that has to know about the modexp and trng cores.
-rw-r--r-- | config/config.cfg | 140 | ||||
-rw-r--r-- | config/core.cfg | 255 | ||||
-rwxr-xr-x | config/core_config.py (renamed from config/config.py) | 357 | ||||
-rw-r--r-- | config/core_selector.v | 278 | ||||
-rw-r--r-- | config/core_vfiles.mk | 42 |
5 files changed, 384 insertions, 688 deletions
diff --git a/config/config.cfg b/config/config.cfg deleted file mode 100644 index d3834d6..0000000 --- a/config/config.cfg +++ /dev/null @@ -1,140 +0,0 @@ -# Config file for the Cryptech Novena FPGA framework. -# -# Variables used in this file: -# -# default-section: Name of the configuration to build if the user -# doesn't specify one. Only meaningful in the default section. -# -# cores: A list of cores to build. Use with the --section option. -# -# vfiles: A list of Verilog files to include in the vfiles list when -# including a particular core. All (optional) cores must have a -# vfiles option, so that the configuration program knows what to put -# into core_vfiles.mk. -# -# requires: A list of other cores whose vfiles must be loaded to build -# this core. This has no effect on the generated core_selector.v -# file, and has no effect at all if an instance of a core named here -# is already included in the build. -# -# error_wire: boolean indicating whether the core wants a error wire. -# -# block_memory: boolean indicating whether the core uses block memory. -# Effect of this is a bit strange: setting it triggers generation of -# a one-cycle timing delay for every core in this build that does -# *not* use block memory. When no cores in the build use block -# memory, the delay isn't necessary and is therefore omitted. - -[default] -default-section = rsa - -# for quick builds to test the bus -[bare] -cores = - -[hash] -cores = sha1 sha256 sha512 - -[trng] -cores = trng - -[modexp] -cores = modexps6 - -[rsa] -cores = sha256 aes trng modexps6 - -[mkmif] -cores = mkmif - -# include multiple of the same core -[multi-test] -cores = sha256 aes aes chacha aes - -[sha1] -vfiles = - hash/sha1/src/rtl/sha1.v - hash/sha1/src/rtl/sha1_core.v - hash/sha1/src/rtl/sha1_w_mem.v - -[sha256] -vfiles = - hash/sha256/src/rtl/sha256.v - hash/sha256/src/rtl/sha256_core.v - hash/sha256/src/rtl/sha256_k_constants.v - hash/sha256/src/rtl/sha256_w_mem.v - -[sha512] -vfiles = - hash/sha512/src/rtl/sha512.v - hash/sha512/src/rtl/sha512_core.v - hash/sha512/src/rtl/sha512_h_constants.v - hash/sha512/src/rtl/sha512_k_constants.v - hash/sha512/src/rtl/sha512_w_mem.v - -[trng] -requires = chacha sha512 -vfiles = - rng/avalanche_entropy/src/rtl/avalanche_entropy.v - rng/avalanche_entropy/src/rtl/avalanche_entropy_core.v - rng/rosc_entropy/src/rtl/rosc.v - rng/rosc_entropy/src/rtl/rosc_entropy.v - rng/rosc_entropy/src/rtl/rosc_entropy_core.v - rng/trng/src/rtl/trng.v - rng/trng/src/rtl/trng_csprng.v - rng/trng/src/rtl/trng_csprng_fifo.v - rng/trng/src/rtl/trng_mixer.v - -[aes] -vfiles = - cipher/aes/src/rtl/aes.v - cipher/aes/src/rtl/aes_core.v - cipher/aes/src/rtl/aes_decipher_block.v - cipher/aes/src/rtl/aes_encipher_block.v - cipher/aes/src/rtl/aes_inv_sbox.v - cipher/aes/src/rtl/aes_key_mem.v - cipher/aes/src/rtl/aes_sbox.v - -[chacha] -vfiles = - cipher/chacha/src/rtl/chacha.v - cipher/chacha/src/rtl/chacha_core.v - cipher/chacha/src/rtl/chacha_qr.v - -[modexps6] -block_memory = yes -error_wire = no -vfiles = - math/modexps6/src/rtl/modexps6_adder64_carry32.v - math/modexps6/src/rtl/modexps6_buffer_core.v - math/modexps6/src/rtl/modexps6_buffer_user.v - math/modexps6/src/rtl/modexps6_modinv32.v - math/modexps6/src/rtl/modexps6_montgomery_coeff.v - math/modexps6/src/rtl/modexps6_montgomery_multiplier.v - math/modexps6/src/rtl/modexps6_top.v - math/modexps6/src/rtl/modexps6_wrapper.v - math/modexps6/src/rtl/ram_1rw_1ro_readfirst.v - math/modexps6/src/rtl/ipcore/multiplier_s6.v - math/modexps6/src/rtl/ipcore/subtractor_s6.v - -[modexp] -error_wire = no -vfiles = - math/modexp/src/rtl/adder.v - math/modexp/src/rtl/blockmem1r1w.v - math/modexp/src/rtl/blockmem2r1wptr.v - math/modexp/src/rtl/blockmem2r1w.v - math/modexp/src/rtl/blockmem2rptr1w.v - math/modexp/src/rtl/modexp.v - math/modexp/src/rtl/modexp_core.v - math/modexp/src/rtl/montprod.v - math/modexp/src/rtl/residue.v - math/modexp/src/rtl/shl.v - math/modexp/src/rtl/shr.v - -[mkmif] -error_wire = no -vfiles = - util/mkmif/src/rtl/mkmif.v - util/mkmif/src/rtl/mkmif_core.v - util/mkmif/src/rtl/mkmif_spi.v diff --git a/config/core.cfg b/config/core.cfg new file mode 100644 index 0000000..48e92ff --- /dev/null +++ b/config/core.cfg @@ -0,0 +1,255 @@ +# Config file for the Cryptech FPGA framework. + +# [default] section. Defines defaults, if not specified on the command line. +# +# board: Name of the default [board] section to build, if the --board +# option is not given. +# +# project: Name of the default [project] section to build, if the +# --project option is not given. + +[default] +board = alpha +project = hsm + +# [board] sections, defining the target device. +# +# bus name: Name of the FPGA communications bus, used by applications to +# read/write the FPGA core registers. +# +# bus width: Width of the FPGA address bus. (The data bus is always 32 bits.) +# +# extra wires: Defines extra I/O ports in the core_selector module definition. +# Note this is a blob of text, not interpreted, so formatting and commas +# will be copied out verbatim. +# +# requires: A list of cores that must be present. This supports a fallback +# scheme so that, for example, if 'mkmif' is not in the project's list +# of cores, it will use 'dummy-mkmif' instead. In this case, there is no +# whitespace around the '/'. + +[board alpha] +# Cryptech Alpha board +bus name = fmc +bus width = 24 +modexp = modexpa7 +extra wires = + output wire mkm_sclk, + output wire mkm_cs_n, + input wire mkm_do, + output wire mkm_di, +requires = mkmif/dummy-mkmif + +[board dev-bridge] +# Cryptech dev-bridge board - a Novena daughterboard that talks to the +# Novena's FPGA through the high-speed connector. +bus name = fmc +bus width = 17 +modexp = modexps6 + +[board novena] +# Novena board +bus name = eim +bus width = 17 +modexp = modexps6 + +# [project] sections +# +# cores: A list of cores to build. + +[project bare] +# for quick builds to test the bus +cores = + +[project hash] +# for testing just the SHA cores +cores = sha1 sha256 sha512 + +[project trng] +# for testing just the True Random Number Generator +cores = trng + +[project modexp] +# for testing just the Modular Exponentiation +cores = modexp + +[project mkmif] +# for testing just the Master Key Memory Interface +cores = mkmif + +[project rsa] +# RSA signing and verification. This is as much as will fit on the +# Novena's Spartan-6 FPGA. +cores = sha256 aes trng modexp + +[project hsm] +# make me one with everything +#cores = sha1 sha256 sha512 aes trng modexp +# super-size it +cores = mkmif trng sha1 sha1 sha1 sha256 sha256 sha256 sha512 sha512 sha512 aes aes aes modexp modexp modexp + +# [core] sections +# +# vfiles: A list of Verilog files to include in the vfiles list when +# including a particular core. All (optional) cores must have a +# vfiles option, so that the configuration program knows what to put +# into core_vfiles.mk. +# +# requires: A list of other cores whose vfiles must be loaded to build +# this core. This has no effect on the generated core_selector.v +# file, and has no effect at all if an instance of a core named here +# is already included in the build. +# +# subcores: The TRNG core has an internal mux with slots for 16 sub-cores +# (although it only uses 4). Unlike 'requires', subcores consume address +# space and have to be accounted for in core_selector.v. +# +# core blocks: By default, each core gets a block of 256 registers. If a +# core needs more address space (e.g. for block memories or subcores), +# set the number of 256-block registers here. +# +# error wire: boolean indicating whether the core wants a error wire. +# +# block memory: boolean indicating whether the core uses block memory. +# Effect of this is a bit strange: setting it triggers generation of +# a one-cycle timing delay for every core in this build that does +# *not* use block memory. When no cores in the build use block +# memory, the delay isn't necessary and is therefore omitted. +# +# extra ports: Extra port definitions in the core instance. +# Note this is a blob of text, not interpreted, so formatting and commas +# will be copied out verbatim. + +[core sha1] +vfiles = + hash/sha1/src/rtl/sha1.v + hash/sha1/src/rtl/sha1_core.v + hash/sha1/src/rtl/sha1_w_mem.v + +[core sha256] +vfiles = + hash/sha256/src/rtl/sha256.v + hash/sha256/src/rtl/sha256_core.v + hash/sha256/src/rtl/sha256_k_constants.v + hash/sha256/src/rtl/sha256_w_mem.v + +[core sha512] +vfiles = + hash/sha512/src/rtl/sha512.v + hash/sha512/src/rtl/sha512_core.v + hash/sha512/src/rtl/sha512_h_constants.v + hash/sha512/src/rtl/sha512_k_constants.v + hash/sha512/src/rtl/sha512_w_mem.v + +[core trng] +requires = chacha sha512 +core blocks = 16 +subcores = + avalanche_entropy + rosc_entropy + trng_mixer + trng_csprng +extra ports = + .avalanche_noise(noise), + .debug(debug), +vfiles = + rng/avalanche_entropy/src/rtl/avalanche_entropy.v + rng/avalanche_entropy/src/rtl/avalanche_entropy_core.v + rng/rosc_entropy/src/rtl/rosc.v + rng/rosc_entropy/src/rtl/rosc_entropy.v + rng/rosc_entropy/src/rtl/rosc_entropy_core.v + rng/trng/src/rtl/trng.v + rng/trng/src/rtl/trng_csprng.v + rng/trng/src/rtl/trng_csprng_fifo.v + rng/trng/src/rtl/trng_mixer.v + +[core aes] +vfiles = + cipher/aes/src/rtl/aes.v + cipher/aes/src/rtl/aes_core.v + cipher/aes/src/rtl/aes_decipher_block.v + cipher/aes/src/rtl/aes_encipher_block.v + cipher/aes/src/rtl/aes_inv_sbox.v + cipher/aes/src/rtl/aes_key_mem.v + cipher/aes/src/rtl/aes_sbox.v + +[core chacha] +vfiles = + cipher/chacha/src/rtl/chacha.v + cipher/chacha/src/rtl/chacha_core.v + cipher/chacha/src/rtl/chacha_qr.v + +[core modexpa7] +# ModExp for Xilinx Artix-7 +core blocks = 4 +block memory = yes +error wire = no +module name = modexpa7_wrapper +vfiles = + math/modexpa7/src/rtl/dsp_multiplier_a7.v + math/modexpa7/src/rtl/dsp_subtractor_a7.v + math/modexpa7/src/rtl/modexpa7_adder64_carry32.v + math/modexpa7/src/rtl/modexpa7_buffer_core.v + math/modexpa7/src/rtl/modexpa7_buffer_user.v + math/modexpa7/src/rtl/modexpa7_modinv32.v + math/modexpa7/src/rtl/modexpa7_montgomery_coeff.v + math/modexpa7/src/rtl/modexpa7_montgomery_multiplier.v + math/modexpa7/src/rtl/modexpa7_top.v + math/modexpa7/src/rtl/modexpa7_wrapper.v + math/modexpa7/src/rtl/ram_1rw_1ro_readfirst.v + +[core modexps6] +# ModExp for Xilinx Spartan-6 +core blocks = 4 +block memory = yes +error wire = no +module name = modexps6_wrapper +vfiles = + math/modexps6/src/rtl/modexps6_adder64_carry32.v + math/modexps6/src/rtl/modexps6_buffer_core.v + math/modexps6/src/rtl/modexps6_buffer_user.v + math/modexps6/src/rtl/modexps6_modinv32.v + math/modexps6/src/rtl/modexps6_montgomery_coeff.v + math/modexps6/src/rtl/modexps6_montgomery_multiplier.v + math/modexps6/src/rtl/modexps6_top.v + math/modexps6/src/rtl/modexps6_wrapper.v + math/modexps6/src/rtl/ram_1rw_1ro_readfirst.v + math/modexps6/src/rtl/ipcore/multiplier_s6.v + math/modexps6/src/rtl/ipcore/subtractor_s6.v + +[core modexp] +# portable ModExp +error wire = no +vfiles = + math/modexp/src/rtl/adder.v + math/modexp/src/rtl/blockmem1r1w.v + math/modexp/src/rtl/blockmem2r1wptr.v + math/modexp/src/rtl/blockmem2r1w.v + math/modexp/src/rtl/blockmem2rptr1w.v + math/modexp/src/rtl/modexp.v + math/modexp/src/rtl/modexp_core.v + math/modexp/src/rtl/montprod.v + math/modexp/src/rtl/residue.v + math/modexp/src/rtl/shl.v + math/modexp/src/rtl/shr.v + +[core mkmif] +# Master Key Memory Interface +error wire = no +extra ports = + .spi_sclk(mkm_sclk), + .spi_cs_n(mkm_cs_n), + .spi_do(mkm_do), + .spi_di(mkm_di), +vfiles = + util/mkmif/src/rtl/mkmif.v + util/mkmif/src/rtl/mkmif_core.v + util/mkmif/src/rtl/mkmif_spi.v + +[core dummy-mkmif] +# Dummy wires if the mkmif core isn't present, so we don't have unsourced +# outputs. +dummy = + assign mkm_sclk = 0; + assign mkm_cs_n = 0; + assign mkm_di = 0; diff --git a/config/config.py b/config/core_config.py index 5ff3ccc..3f75243 100755 --- a/config/config.py +++ b/config/core_config.py @@ -5,7 +5,7 @@ Generate core_selector.v and core_vfiles.mk for a set of cores. """ #======================================================================= -# Copyright (c) 2015, NORDUnet A/S All rights reserved. +# Copyright (c) 2015-2017, NORDUnet A/S All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -34,9 +34,9 @@ Generate core_selector.v and core_vfiles.mk for a set of cores. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #======================================================================= -# The modexps6 core drags in a one clock cycle delay to other cores, +# The modexpa7 core drags in a one clock cycle delay to other cores, # to compensate for the extra clock cycle consumed by the block -# memories used in the modexps6 core. We probably want a general +# memories used in the modexpa7 core. We probably want a general # solution for this, because we're going to run into this problem for # any core that handles arguments big enough to require block memory. @@ -48,9 +48,6 @@ Generate core_selector.v and core_vfiles.mk for a set of cores. # all other cores would get the delay. Slightly tedious but # something we can calculate easily enough, and probably an # improvement over wiring in the delay when nothing needs it. -# -# - Rename script and its config file to something more meaningful. - def main(): """ @@ -62,10 +59,11 @@ def main(): parser = ArgumentParser(description = __doc__, formatter_class = ArgumentDefaultsHelpFormatter) parser.add_argument("-d", "--debug", help = "enable debugging", action = "store_true") - parser.add_argument("-s", "--section", help = "config file section") - parser.add_argument("-c", "--config", help = "configuration file", default = "config.cfg", type = FileType("r")) - parser.add_argument("--verilog", help = "verilog output file", default = "core_selector.v", type = FileType("w")) - parser.add_argument("--makefile", help = "output makefile", default = "core_vfiles.mk", type = FileType("w")) + parser.add_argument("-c", "--config", help = "configuration file", default = "core.cfg", type = FileType("r")) + parser.add_argument("-b", "--board", help = "config file 'board' section") + parser.add_argument("-p", "--project", help = "config file 'project' section") + parser.add_argument("-v", "--verilog", help = "verilog output file",default = "core_selector.v", type = FileType("w")) + parser.add_argument("-m", "--makefile",help = "output makefile", default = "core_vfiles.mk", type = FileType("w")) parser.add_argument("core", help = "name(s) of core(s)", nargs = "*") args = parser.parse_args() @@ -73,23 +71,46 @@ def main(): cfg = RawConfigParser() cfg.readfp(args.config) + board = args.board or cfg.get("default", "board") + board_section = "board " + board + Core.bus_name = cfg.get(board_section, "bus name") + Core.bus_width = int(cfg.get(board_section, "bus width")) + Core.bus_max = Core.bus_width - 1 + Core.addr_width = Core.bus_width - 8 + Core.addr_max = Core.addr_width - 1 + Core.extra_wires = cfg.get(board_section, "extra wires") + Core.modexp = cfg.get(board_section, "modexp") + if Core.extra_wires: + # restore formatting + Core.extra_wires = Core.extra_wires.replace("\n", "\n ") + "\n" + if args.core: cores = args.core else: - section = args.section or cfg.get("default", "default-section") - cores = cfg.get(section, "cores").split() + project = args.project or cfg.get("default", "project") + cores = cfg.get("project " + project, "cores").split() + + for core in cfg.getvalues(board_section, "requires"): + try: + (c1, c2) = core.split("/") + if c1 not in cores and c2 not in cores: + cores.append(c2) + except ValueError: + if core not in cores: + cores.append(core) + cores.insert(0, "board_regs") cores.insert(1, "comm_regs") - cores = tuple(Core.new(core) for core in cores) + cores = tuple(Core(core) for core in cores) - core_number = 0 for core in cores: - core_number = core.assign_core_number(core_number) + core.configure(cfg) + core_number = 0 for core in cores: - core.configure(cfg) + core_number = core.assign_core_number(core_number) if False: @@ -101,10 +122,10 @@ def main(): Core.need_one_cycle_delay = any(core.block_memory for core in cores) args.verilog.write(createModule_template.format( + core = cores[0], addrs = "".join(core.createAddr() for core in cores), insts = "".join(core.createInstance() for core in cores), - muxes = "".join(core.createMux() for core in cores), - ports = "".join(core.createPort() for core in cores) )) + muxes = "".join(core.createMux() for core in cores) )) args.makefile.write(listVfiles_template.format( vfiles = "".join(core.listVfiles() for core in cores))) @@ -137,6 +158,17 @@ class RawConfigParser(configparser.RawConfigParser): for value in self.get(section, option).split(): yield value + def get(self, section, option): + try: + return configparser.RawConfigParser.get(self, section, option) + except configparser.NoSectionError: + if section in ("core board_regs", "core comm_regs"): + return "" + else: + raise + except configparser.NoOptionError: + return "" + class Core(object): """ @@ -150,40 +182,59 @@ class Core(object): _instance_count = {} - # Class variable mapping core name to subclass for special cases. - - special_class = {} - # Class variable recording whether we need a one-cycle delay to # compensate for block memories. need_one_cycle_delay = True def __init__(self, name): + if Core.modexp and name == "modexp": + name = Core.modexp self.name = name + self.cfg_section = "core " + name self.core_number = None self.vfiles = [] self.error_wire = True self.block_memory = False self.instance_number = self._instance_count.get(name, 0) self._instance_count[name] = self.instance_number + 1 - - @classmethod - def new(cls, name): - return cls.special_class.get(name, cls)(name) + self.subcores = [] + self.blocks = 1 + self.dummy = False def assign_core_number(self, n): self.core_number = n - return n + 1 + for i, subcore in enumerate(self.subcores): + subcore.assign_core_number(n + i + 1) + return n + self.blocks def configure(self, cfg): if self.instance_number == 0: - self.vfiles.extend(cfg.getvalues(self.name, "vfiles")) - for required in cfg.getvalues(self.name, "requires"): + self.vfiles.extend(cfg.getvalues(self.cfg_section, "vfiles")) + for required in cfg.getvalues(self.cfg_section, "requires"): if required not in self._instance_count: - self.vfiles.extend(cfg.getvalues(required, "vfiles")) - self.error_wire = cfg.getboolean(self.name, "error_wire", self.error_wire) - self.block_memory = cfg.getboolean(self.name, "block_memory", self.block_memory) + self.vfiles.extend(cfg.getvalues("core " + required, "vfiles")) + self.error_wire = cfg.getboolean(self.cfg_section, "error wire", self.error_wire) + self.block_memory = cfg.getboolean(self.cfg_section, "block memory", self.block_memory) + self.extra_ports = cfg.get(self.cfg_section, "extra ports") + if self.extra_ports: + self.extra_ports = self.extra_ports.replace("\n", "\n ") + "\n" + self.blocks = int(cfg.get(self.cfg_section, "core blocks") or 1) + self.block_max = self.blocks - 1 + if self.blocks > 1: + try: + self.block_bits = {4:2, 8:3, 16:4}[self.blocks] + except KeyError: + raise ValueError, "In [{}]: unexpected value \"core blocks = {}\"".format(self.cfg_section, self.blocks) + self.block_bit_max = self.block_bits - 1 + for subcore in cfg.getvalues(self.cfg_section, "subcores"): + self.subcores.append(SubCore(subcore, self)) + if len(self.subcores) > self.blocks - 1: + raise ValueError, "In [{}]: number of subcores exceeds size of \"core blocks\"".format(self.cfg_section) + self.module_name = cfg.get(self.cfg_section, "module name") or self.name + self.dummy = cfg.get(self.cfg_section, "dummy") + if self.dummy: + self.dummy = self.dummy.replace("\n", "\n ") + "\n" @property def instance_name(self): @@ -197,8 +248,8 @@ class Core(object): return self.instance_name.upper() @property - def reset_pin(self): - return ".reset_n(sys_rst_n)" + def error_wire_decl(self): + return "\n wire error_{core.instance_name};".format(core = self) if self.error_wire else "" @property def error_port(self): @@ -209,6 +260,13 @@ class Core(object): return one_cycle_delay_template.format(core = self) if self.need_one_cycle_delay and not self.block_memory else "" @property + def mux_core_addr(self): + if self.blocks == 1 or self.subcores: + return "CORE_ADDR_{core.upper_instance_name}".format(core=self) + else: + return ",\n ".join("CORE_ADDR_{core.upper_instance_name} + {0}".format(i, core=self) for i in range(self.blocks)) + + @property def mux_data_reg(self): return "read_data_" + self.instance_name + ("_reg" if self.need_one_cycle_delay and not self.block_memory else "") @@ -217,16 +275,18 @@ class Core(object): return "error_" + self.instance_name if self.error_wire else "0" def createInstance(self): - return createInstance_template_generic.format(core = self) + template = createInstance_template_dummy if self.dummy else createInstance_template_generic if self.blocks == 1 else createInstance_template_multi_block + return template.format(core = self) def createAddr(self): - return createAddr_template.format(core = self) + if self.dummy: + return "" + return createAddr_template.format(core = self) + "".join(subcore.createAddr() for subcore in self.subcores) def createMux(self): - return createMux_template.format(core = self, core0 = self) - - def createPort(self): - return "" + if self.dummy: + return "" + return createMux_template.format(core = self, core0 = self) + "".join(subcore.createMux() for subcore in self.subcores) def listVfiles(self): return "".join(" \\\n\t$(CORE_TREE)/" + vfile for vfile in self.vfiles) @@ -245,92 +305,6 @@ class SubCore(Core): return createMux_template.format(core = self, core0 = self.parent) -class TRNGCore(Core): - """ - The TRNG core has an internal mux with slots for 15 sub-cores, - most of which are empty. This is a bit of a mess. - - 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 - different templates, and fiddle with addresses a bit. - - Mux numbers have to be dug out of the TRNG Verilog source. - """ - - # TRNG subcore name -> internal mux number. - subcore_parameters = dict(avalanche_entropy = 0x1, - rosc_entropy = 0x2, - trng_mixer = 0x3, - trng_csprng = 0x4) - - def __init__(self, name): - super(TRNGCore, self).__init__(name) - self.subcores = tuple(SubCore(name, self) - for name in sorted(self.subcore_parameters, - key = lambda x: self.subcore_parameters[x])) - - def assign_core_number(self, n): - n = super(TRNGCore, self).assign_core_number(n) - for subcore in self.subcores: - subcore.assign_core_number(self.core_number + self.subcore_parameters[subcore.name]) - return n + 15 - - @property - def last_subcore_upper_instance_name(self): - return self.subcores[-1].upper_instance_name - - 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) - - def createMux(self): - return super(TRNGCore, self).createMux() + "".join(subcore.createMux() for subcore in self.subcores) - - -class ModExpS6Core(Core): - """ - ModExpS6 core consumes as much space as four ordinary cores, and - uses different templates to handle the differences in timing and - addressing. - """ - - def assign_core_number(self, n): - n = super(ModExpS6Core, self).assign_core_number(n) - return n + 3 - - def createInstance(self): - return createInstance_template_ModExpS6.format(core = self) - - def createMux(self): - return createMux_modexps6_template.format(core = self, core0 = self) - -class MkmifCore(Core): - """ - MKM interface core has extra ports for the SPI signal lines. - """ - - def createPort(self): - return """ \ - - output wire mkm_sclk, - output wire mkm_cs_n, - input wire mkm_do, - output wire mkm_di, - """ - - def createInstance(self): - return createInstance_template_MKMIF.format(core = self) - -# Hook special classes in as handlers for the cores that require them. - -Core.special_class.update( - trng = TRNGCore, - modexps6 = ModExpS6Core, - mkmif = MkmifCore) - - # 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 @@ -339,7 +313,7 @@ Core.special_class.update( # Template used by .createAddr() methods. createAddr_template = """\ - localparam CORE_ADDR_{core.upper_instance_name:21s} = 9'h{core.core_number:02x}; + localparam CORE_ADDR_{core.upper_instance_name:21s} = {core.addr_width}'h{core.core_number:02x}; """ # Template used by Core.createInstance(). @@ -349,16 +323,15 @@ createInstance_template_generic = """\ // {core.upper_instance_name} //---------------------------------------------------------------- wire enable_{core.instance_name} = (addr_core_num == CORE_ADDR_{core.upper_instance_name}); - wire [31: 0] read_data_{core.instance_name}; - wire error_{core.instance_name}; + wire [31: 0] read_data_{core.instance_name};{core.error_wire_decl} - {core.name} {core.instance_name}_inst + {core.module_name} {core.instance_name}_inst ( .clk(sys_clk), - {core.reset_pin}, - - .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), + .reset_n(sys_rst_n), +{core.extra_ports} + .cs(enable_{core.instance_name} & (sys_{core.bus_name}_rd | sys_{core.bus_name}_wr)), + .we(sys_{core.bus_name}_wr), .address(addr_core_reg), .write_data(sys_write_data), @@ -369,97 +342,39 @@ createInstance_template_generic = """\ """ -# Template used by ModExpS6Core.createInstance(). This is different +# Template used for multi-block cores (modexp and trng). This is different # enough from the base template that it's easier to make this separate. -createInstance_template_ModExpS6 = """\ +createInstance_template_multi_block = """\ //---------------------------------------------------------------- // {core.upper_instance_name} //---------------------------------------------------------------- - wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.upper_instance_name} + 9'h03); - wire [31: 0] read_data_{core.instance_name}; - wire [1:0] {core.instance_name}_prefix = addr_core_num[1:0] - CORE_ADDR_{core.upper_instance_name}; + wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.upper_instance_name} + {core.addr_width}'h{core.block_max:02x}); + wire [31: 0] read_data_{core.instance_name};{core.error_wire_decl} + wire [{core.block_bit_max}:0] {core.instance_name}_prefix = addr_core_num[{core.block_bit_max}:0] - CORE_ADDR_{core.upper_instance_name}; - {core.name}_wrapper {core.instance_name}_inst + {core.module_name} {core.instance_name}_inst ( .clk(sys_clk), - {core.reset_pin}, - - .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), + .reset_n(sys_rst_n), +{core.extra_ports} + .cs(enable_{core.instance_name} & (sys_{core.bus_name}_rd | sys_{core.bus_name}_wr)), + .we(sys_{core.bus_name}_wr), .address({{{core.instance_name}_prefix, addr_core_reg}}), .write_data(sys_write_data), - .read_data(read_data_{core.instance_name}) - ); - - -""" - -# 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} - //---------------------------------------------------------------- - wire enable_{core.instance_name} = (addr_core_num >= CORE_ADDR_{core.upper_instance_name}) && (addr_core_num <= CORE_ADDR_{core.upper_instance_name} + 9'h0f); - wire [31: 0] read_data_{core.instance_name}; - wire error_{core.instance_name}; - wire [3:0] {core.instance_name}_prefix = addr_core_num[3:0] - CORE_ADDR_{core.upper_instance_name}; - - {core.name} {core.instance_name}_inst - ( - .clk(sys_clk), - {core.reset_pin}, - - .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), - - .address({{{core.instance_name}_prefix, addr_core_reg}}), - .write_data(sys_write_data), - .read_data(read_data_{core.instance_name}), - .error(error_{core.instance_name}), - - .avalanche_noise(noise), - .debug(debug) + .read_data(read_data_{core.instance_name}){core.error_port} ); {core.one_cycle_delay} """ -# Template used by Mkmif.createInstance(). This is different -# enough from the base template that it's easier to make this separate. - -createInstance_template_MKMIF = """\ +createInstance_template_dummy = """\ //---------------------------------------------------------------- // {core.upper_instance_name} //---------------------------------------------------------------- - wire enable_{core.instance_name} = (addr_core_num == CORE_ADDR_{core.upper_instance_name}); - wire [31: 0] read_data_{core.instance_name}; - - {core.name} {core.instance_name}_inst - ( - .clk(sys_clk), - {core.reset_pin}, - - .spi_sclk(mkm_sclk), - .spi_cs_n(mkm_cs_n), - .spi_do(mkm_do), - .spi_di(mkm_di), - - .cs(enable_{core.instance_name} & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), - - .address(addr_core_reg), - .write_data(sys_write_data), - .read_data(read_data_{core.instance_name}){core.error_port} - ); - -{core.one_cycle_delay} - +{core.dummy} """ # Template for one-cycle delay code. @@ -473,44 +388,30 @@ one_cycle_delay_template = """\ # Template for .createMux() methods. createMux_template = """\ - CORE_ADDR_{core.upper_instance_name}: - begin - sys_read_data_mux = {core0.mux_data_reg}; - sys_error_mux = {core0.mux_error_reg}; - end -""" - -# Template for ModExpS6.createMux() method. - -createMux_modexps6_template = """\ - CORE_ADDR_{core.upper_instance_name} + 0, - CORE_ADDR_{core.upper_instance_name} + 1, - CORE_ADDR_{core.upper_instance_name} + 2, - CORE_ADDR_{core.upper_instance_name} + 3: + {core.mux_core_addr}: begin sys_read_data_mux = {core0.mux_data_reg}; sys_error_mux = {core0.mux_error_reg}; end """ - # Top-level (createModule) template. createModule_template = """\ -// NOTE: This file is generated; do not edit by hand. +// NOTE: This file is generated; do not edit. module core_selector ( input wire sys_clk, input wire sys_rst_n, - input wire [16: 0] sys_eim_addr, - input wire sys_eim_wr, - input wire sys_eim_rd, + input wire [{core.bus_max}: 0] sys_{core.bus_name}_addr, + input wire sys_{core.bus_name}_wr, + input wire sys_{core.bus_name}_rd, output wire [31: 0] sys_read_data, input wire [31: 0] sys_write_data, output wire sys_error, -{ports} +{core.extra_wires} input wire noise, output wire [7 : 0] debug ); @@ -519,10 +420,10 @@ module core_selector //---------------------------------------------------------------- // Address Decoder //---------------------------------------------------------------- - // upper 9 bits specify core being addressed - wire [ 8: 0] addr_core_num = sys_eim_addr[16: 8]; + // upper {core.addr_width} bits specify core being addressed + wire [{core.addr_max:>2}: 0] addr_core_num = sys_{core.bus_name}_addr[{core.bus_max}: 8]; // lower 8 bits specify register offset in core - wire [ 7: 0] addr_core_reg = sys_eim_addr[ 7: 0]; + wire [ 7: 0] addr_core_reg = sys_{core.bus_name}_addr[ 7: 0]; //---------------------------------------------------------------- diff --git a/config/core_selector.v b/config/core_selector.v deleted file mode 100644 index 298c39e..0000000 --- a/config/core_selector.v +++ /dev/null @@ -1,278 +0,0 @@ -// NOTE: This file is generated; do not edit by hand. - -module core_selector - ( - input wire sys_clk, - input wire sys_rst_n, - - input wire [16: 0] sys_eim_addr, - input wire sys_eim_wr, - input wire sys_eim_rd, - output wire [31: 0] sys_read_data, - input wire [31: 0] sys_write_data, - output wire sys_error, - - input wire noise, - output wire [7 : 0] debug - ); - - - //---------------------------------------------------------------- - // Address Decoder - //---------------------------------------------------------------- - // upper 9 bits specify core being addressed - wire [ 8: 0] addr_core_num = sys_eim_addr[16: 8]; - // lower 8 bits specify register offset in core - wire [ 7: 0] addr_core_reg = sys_eim_addr[ 7: 0]; - - - //---------------------------------------------------------------- - // Core Address Table - //---------------------------------------------------------------- - localparam CORE_ADDR_BOARD_REGS = 9'h00; - localparam CORE_ADDR_COMM_REGS = 9'h01; - localparam CORE_ADDR_SHA256 = 9'h02; - localparam CORE_ADDR_AES = 9'h03; - localparam CORE_ADDR_TRNG = 9'h04; - localparam CORE_ADDR_AVALANCHE_ENTROPY = 9'h05; - localparam CORE_ADDR_ROSC_ENTROPY = 9'h06; - localparam CORE_ADDR_TRNG_MIXER = 9'h07; - localparam CORE_ADDR_TRNG_CSPRNG = 9'h08; - localparam CORE_ADDR_MODEXPS6 = 9'h14; - - - //---------------------------------------------------------------- - // BOARD_REGS - //---------------------------------------------------------------- - wire enable_board_regs = (addr_core_num == CORE_ADDR_BOARD_REGS); - wire [31: 0] read_data_board_regs; - wire error_board_regs; - - board_regs board_regs_inst - ( - .clk(sys_clk), - .reset_n(sys_rst_n), - - .cs(enable_board_regs & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), - - .address(addr_core_reg), - .write_data(sys_write_data), - .read_data(read_data_board_regs), - .error(error_board_regs) - ); - - reg [31: 0] read_data_board_regs_reg; - always @(posedge sys_clk) - read_data_board_regs_reg <= read_data_board_regs; - - - //---------------------------------------------------------------- - // COMM_REGS - //---------------------------------------------------------------- - wire enable_comm_regs = (addr_core_num == CORE_ADDR_COMM_REGS); - wire [31: 0] read_data_comm_regs; - wire error_comm_regs; - - comm_regs comm_regs_inst - ( - .clk(sys_clk), - .reset_n(sys_rst_n), - - .cs(enable_comm_regs & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), - - .address(addr_core_reg), - .write_data(sys_write_data), - .read_data(read_data_comm_regs), - .error(error_comm_regs) - ); - - reg [31: 0] read_data_comm_regs_reg; - always @(posedge sys_clk) - read_data_comm_regs_reg <= read_data_comm_regs; - - - //---------------------------------------------------------------- - // SHA256 - //---------------------------------------------------------------- - wire enable_sha256 = (addr_core_num == CORE_ADDR_SHA256); - wire [31: 0] read_data_sha256; - wire error_sha256; - - sha256 sha256_inst - ( - .clk(sys_clk), - .reset_n(sys_rst_n), - - .cs(enable_sha256 & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), - - .address(addr_core_reg), - .write_data(sys_write_data), - .read_data(read_data_sha256), - .error(error_sha256) - ); - - reg [31: 0] read_data_sha256_reg; - always @(posedge sys_clk) - read_data_sha256_reg <= read_data_sha256; - - - //---------------------------------------------------------------- - // AES - //---------------------------------------------------------------- - wire enable_aes = (addr_core_num == CORE_ADDR_AES); - wire [31: 0] read_data_aes; - wire error_aes; - - aes aes_inst - ( - .clk(sys_clk), - .reset_n(sys_rst_n), - - .cs(enable_aes & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), - - .address(addr_core_reg), - .write_data(sys_write_data), - .read_data(read_data_aes), - .error(error_aes) - ); - - reg [31: 0] read_data_aes_reg; - always @(posedge sys_clk) - read_data_aes_reg <= read_data_aes; - - - //---------------------------------------------------------------- - // TRNG - //---------------------------------------------------------------- - wire enable_trng = (addr_core_num >= CORE_ADDR_TRNG) && (addr_core_num <= CORE_ADDR_TRNG + 9'h0f); - wire [31: 0] read_data_trng; - wire error_trng; - wire [3:0] trng_prefix = addr_core_num[3:0] - CORE_ADDR_TRNG; - - trng trng_inst - ( - .clk(sys_clk), - .reset_n(sys_rst_n), - - .cs(enable_trng & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), - - .address({trng_prefix, addr_core_reg}), - .write_data(sys_write_data), - .read_data(read_data_trng), - .error(error_trng), - - .avalanche_noise(noise), - .debug(debug) - ); - - reg [31: 0] read_data_trng_reg; - always @(posedge sys_clk) - read_data_trng_reg <= read_data_trng; - - - //---------------------------------------------------------------- - // MODEXPS6 - //---------------------------------------------------------------- - wire enable_modexps6 = (addr_core_num >= CORE_ADDR_MODEXPS6) && (addr_core_num <= CORE_ADDR_MODEXPS6 + 9'h03); - wire [31: 0] read_data_modexps6; - wire [1:0] modexps6_prefix = addr_core_num[1:0] - CORE_ADDR_MODEXPS6; - - modexps6_wrapper modexps6_inst - ( - .clk(sys_clk), - .reset_n(sys_rst_n), - - .cs(enable_modexps6 & (sys_eim_rd | sys_eim_wr)), - .we(sys_eim_wr), - - .address({modexps6_prefix, addr_core_reg}), - .write_data(sys_write_data), - .read_data(read_data_modexps6) - ); - - - - //---------------------------------------------------------------- - // Output (Read Data) Multiplexer - //---------------------------------------------------------------- - reg [31: 0] sys_read_data_mux; - assign sys_read_data = sys_read_data_mux; - reg sys_error_mux; - assign sys_error = sys_error_mux; - - always @* - - case (addr_core_num) - CORE_ADDR_BOARD_REGS: - begin - sys_read_data_mux = read_data_board_regs_reg; - sys_error_mux = error_board_regs; - end - CORE_ADDR_COMM_REGS: - begin - sys_read_data_mux = read_data_comm_regs_reg; - sys_error_mux = error_comm_regs; - end - CORE_ADDR_SHA256: - begin - sys_read_data_mux = read_data_sha256_reg; - sys_error_mux = error_sha256; - end - CORE_ADDR_AES: - begin - sys_read_data_mux = read_data_aes_reg; - sys_error_mux = error_aes; - end - CORE_ADDR_TRNG: - begin - sys_read_data_mux = read_data_trng_reg; - sys_error_mux = error_trng; - end - CORE_ADDR_AVALANCHE_ENTROPY: - begin - sys_read_data_mux = read_data_trng_reg; - sys_error_mux = error_trng; - end - CORE_ADDR_ROSC_ENTROPY: - begin - sys_read_data_mux = read_data_trng_reg; - sys_error_mux = error_trng; - end - CORE_ADDR_TRNG_MIXER: - begin - sys_read_data_mux = read_data_trng_reg; - sys_error_mux = error_trng; - end - CORE_ADDR_TRNG_CSPRNG: - begin - sys_read_data_mux = read_data_trng_reg; - sys_error_mux = error_trng; - end - CORE_ADDR_MODEXPS6 + 0, - CORE_ADDR_MODEXPS6 + 1, - CORE_ADDR_MODEXPS6 + 2, - CORE_ADDR_MODEXPS6 + 3: - begin - sys_read_data_mux = read_data_modexps6; - sys_error_mux = 0; - end - - default: - begin - sys_read_data_mux = {32{1'b0}}; - sys_error_mux = 1; - end - endcase - - -endmodule - - -//====================================================================== -// EOF core_selector.v -//====================================================================== diff --git a/config/core_vfiles.mk b/config/core_vfiles.mk deleted file mode 100644 index 4020234..0000000 --- a/config/core_vfiles.mk +++ /dev/null @@ -1,42 +0,0 @@ -# NOTE: This file is generated; do not edit by hand. - -vfiles += \ - $(CORE_TREE)/hash/sha256/src/rtl/sha256.v \ - $(CORE_TREE)/hash/sha256/src/rtl/sha256_core.v \ - $(CORE_TREE)/hash/sha256/src/rtl/sha256_k_constants.v \ - $(CORE_TREE)/hash/sha256/src/rtl/sha256_w_mem.v \ - $(CORE_TREE)/cipher/aes/src/rtl/aes.v \ - $(CORE_TREE)/cipher/aes/src/rtl/aes_core.v \ - $(CORE_TREE)/cipher/aes/src/rtl/aes_decipher_block.v \ - $(CORE_TREE)/cipher/aes/src/rtl/aes_encipher_block.v \ - $(CORE_TREE)/cipher/aes/src/rtl/aes_inv_sbox.v \ - $(CORE_TREE)/cipher/aes/src/rtl/aes_key_mem.v \ - $(CORE_TREE)/cipher/aes/src/rtl/aes_sbox.v \ - $(CORE_TREE)/rng/avalanche_entropy/src/rtl/avalanche_entropy.v \ - $(CORE_TREE)/rng/avalanche_entropy/src/rtl/avalanche_entropy_core.v \ - $(CORE_TREE)/rng/rosc_entropy/src/rtl/rosc.v \ - $(CORE_TREE)/rng/rosc_entropy/src/rtl/rosc_entropy.v \ - $(CORE_TREE)/rng/rosc_entropy/src/rtl/rosc_entropy_core.v \ - $(CORE_TREE)/rng/trng/src/rtl/trng.v \ - $(CORE_TREE)/rng/trng/src/rtl/trng_csprng.v \ - $(CORE_TREE)/rng/trng/src/rtl/trng_csprng_fifo.v \ - $(CORE_TREE)/rng/trng/src/rtl/trng_mixer.v \ - $(CORE_TREE)/cipher/chacha/src/rtl/chacha.v \ - $(CORE_TREE)/cipher/chacha/src/rtl/chacha_core.v \ - $(CORE_TREE)/cipher/chacha/src/rtl/chacha_qr.v \ - $(CORE_TREE)/hash/sha512/src/rtl/sha512.v \ - $(CORE_TREE)/hash/sha512/src/rtl/sha512_core.v \ - $(CORE_TREE)/hash/sha512/src/rtl/sha512_h_constants.v \ - $(CORE_TREE)/hash/sha512/src/rtl/sha512_k_constants.v \ - $(CORE_TREE)/hash/sha512/src/rtl/sha512_w_mem.v \ - $(CORE_TREE)/math/modexps6/src/rtl/modexps6_adder64_carry32.v \ - $(CORE_TREE)/math/modexps6/src/rtl/modexps6_buffer_core.v \ - $(CORE_TREE)/math/modexps6/src/rtl/modexps6_buffer_user.v \ - $(CORE_TREE)/math/modexps6/src/rtl/modexps6_modinv32.v \ - $(CORE_TREE)/math/modexps6/src/rtl/modexps6_montgomery_coeff.v \ - $(CORE_TREE)/math/modexps6/src/rtl/modexps6_montgomery_multiplier.v \ - $(CORE_TREE)/math/modexps6/src/rtl/modexps6_top.v \ - $(CORE_TREE)/math/modexps6/src/rtl/modexps6_wrapper.v \ - $(CORE_TREE)/math/modexps6/src/rtl/ram_1rw_1ro_readfirst.v \ - $(CORE_TREE)/math/modexps6/src/rtl/ipcore/multiplier_s6.v \ - $(CORE_TREE)/math/modexps6/src/rtl/ipcore/subtractor_s6.v |