From f141a79d805acbab07876d9f007e8809603718b5 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 10 Jun 2015 12:30:58 -0400 Subject: generate core_selector, probe FPGA for cores at software startup --- config/config.cfg | 19 ++++ config/config.py | 212 +++++++++++++++++++++++++++++++++++++++++ config/core_selector.v | 250 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 481 insertions(+) create mode 100644 config/config.cfg create mode 100755 config/config.py create mode 100644 config/core_selector.v (limited to 'config') diff --git a/config/config.cfg b/config/config.cfg new file mode 100644 index 0000000..360988e --- /dev/null +++ b/config/config.cfg @@ -0,0 +1,19 @@ +# Config file for the Cryptech Novena FPGA framework. + +[default] +default = rsa + +[hash-only] +cores = sha1, sha256, sha512 + +[trng-only] +cores = trng + +[modexp-only] +cores = modexp + +[rsa] +cores = sha256, aes, trng, modexp + +[multi-test] +cores = sha256, aes, aes, chacha, aes diff --git a/config/config.py b/config/config.py new file mode 100755 index 0000000..86c8615 --- /dev/null +++ b/config/config.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# +# Generate core_selector.v for a set of cores + +import argparse +import re +import sys +if sys.version > '3': + import configparser +else: + import ConfigParser as configparser + +# defaults +config = 'config.cfg' +outfile = 'core_selector.v' +section = '' +cores = [] + +# added cores for TRNG, muxed through trng.v +trng_cores = ['avalanche_entropy', 'rosc_entropy', 'trng_mixer', 'trng_csprng'] + +# parse the command line +def cmdParse(): + global config, outfile, section, cores + + parser = argparse.ArgumentParser() + parser.add_argument('--cores', help='comma-delimited list of cores') + parser.add_argument('-c', '--config', default=config, + help='config file (default "%s")' % config) + parser.add_argument('-s', '--section', help='config file section') + parser.add_argument('-o', '--outfile', + help='output file (default "%s")' % outfile) + args = parser.parse_args() + + if args.cores: + cores = re.split(',\s*', args.cores) + if args.config: + config = args.config + if args.outfile: + outfile = args.outfile + if args.section: + section = args.section + +# parse the config file +def configParse(section): + cfg = configparser.ConfigParser() + try: + with open(config, 'r') as f: + cfg.readfp(f) + except (IOError, configparser.MissingSectionHeaderError) as e: + print e + exit(1); + + try: + if not section: + section = cfg.get('default', 'default') + cores = cfg.get(section, 'cores') + except (configparser.NoSectionError, configparser.NoOptionError) as e: + print e + exit(1); + + return re.split(r',\s*', cores) + +# create an entry in the Core Address Table +def createAddr(core, corenum): + return " localparam CORE_ADDR_{:21s} = 9'h{:02x};\n".format(core.upper(), corenum) + +# create an instantiation of the core +# This is complicated because TRNG is a mux for 5 cores. +def createInstance(core): + core_stripped = re.sub('_\d+$', '', core) + if core_stripped == 'trng': + s3 = "(addr_core_num >= CORE_ADDR_TRNG) && (addr_core_num <= CORE_ADDR_TRNG_CSPRNG)" + s4 = " wire [3:0] trng_prefix = addr_core_num[3:0] - CORE_ADDR_TRNG;\n" + s5 = "{trng_prefix, addr_core_reg}" + s6 = ",\n\n .avalanche_noise(noise),\n .debug(debug)" + else: + s3 = "(addr_core_num == CORE_ADDR_{0})".format(core.upper()) + s4 = "" + s5 = "addr_core_reg" + s6 = "" + + return "\ + //----------------------------------------------------------------\n\ + // {1}\n\ + //----------------------------------------------------------------\n\ + wire enable_{0} = {3};\n\ + wire [31: 0] read_data_{0};\n\ + wire error_{0};\n\ +{4}\n\ + {2} {0}_inst\n\ + (\n\ + .clk(sys_clk),\n\ + .reset_n(~sys_rst),\n\ +\n\ + .cs(enable_{0} & (sys_eim_rd | sys_eim_wr)),\n\ + .we(sys_eim_wr),\n\ +\n\ + .address({5}),\n\ + .write_data(sys_write_data),\n\ + .read_data(read_data_{0}){6}\n\ + );\n\n\n".format(core, core.upper(), core_stripped, s3, s4, s5, s6) + +# create an entry in the Output (Read Data) Multiplexer +def createMux(core, core0): + return "\ + CORE_ADDR_{0}:\n\ + begin\n\ + sys_read_data_mux = read_data_{1};\n\ + sys_error_mux = error_{1};\n\ + end\n".format(core.upper(), core0) + +# create the core_selector module +def createModule(cores): + cores = ['board_regs', 'comm_regs'] + cores + + # if multiple instances of a core, number them + for a in set([x for x in cores if cores.count(x) > 1]): + i = 0 + j = 0 + while (1): + try: + j = cores.index(a, j) + except ValueError: + break + cores[j] += '_' + str(i) + i += 1 + j += 1 + + addrs = "" + insts = "" + muxs = "" + corenum = 0 + for core in cores: + addrs += createAddr(core, corenum) + insts += createInstance(core) + muxs += createMux(core, core) + corenum += 1 + if core == 'trng': + for tcore in trng_cores: + addrs += createAddr(tcore, corenum) + muxs += createMux(tcore, core) + corenum += 1 + + # write the boilerplate and all per-core bits + with open(outfile, 'w') as f: + f.write("\ +// NOTE: This file is generated; do not edit by hand.\n\ +\n\ +module core_selector\n\ + (\n\ + input wire sys_clk,\n\ + input wire sys_rst,\n\ +\n\ + input wire [16: 0] sys_eim_addr,\n\ + input wire sys_eim_wr,\n\ + input wire sys_eim_rd,\n\ + output wire [31: 0] sys_read_data,\n\ + input wire [31: 0] sys_write_data,\n\ + output wire sys_error,\n\ +\n\ + input wire noise,\n\ + output wire [7 : 0] debug\n\ + );\n\ +\n\ +\n\ + //----------------------------------------------------------------\n\ + // Address Decoder\n\ + //----------------------------------------------------------------\n\ + // upper 9 bits specify core being addressed\n\ + wire [ 8: 0] addr_core_num = sys_eim_addr[16: 8];\n\ + // lower 8 bits specify register offset in core\n\ + wire [ 7: 0] addr_core_reg = sys_eim_addr[ 7: 0];\n\ +\n\n\ + //----------------------------------------------------------------\n\ + // Core Address Table\n\ + //----------------------------------------------------------------\n\ +{0}\n\ +\n\ +{1}\n\ + //----------------------------------------------------------------\n\ + // Output (Read Data) Multiplexer\n\ + //----------------------------------------------------------------\n\ + reg [31: 0] sys_read_data_mux;\n\ + assign sys_read_data = sys_read_data_mux;\n\ + reg sys_error_mux;\n\ + assign sys_error = sys_error_mux;\n\ +\n\ + always @*\n\ +\n\ + case (addr_core_num)\n\ +{2}\n\ + default:\n\ + begin\n\ + sys_read_data_mux = {{32{{1'b0}}}};\n\ + sys_error_mux = 1;\n\ + end\n\ + endcase\n\ +\n\ +\n\ +endmodule\n\ +\n\ +\n\ +//======================================================================\n\ +// EOF core_selector.v\n\ +//======================================================================\n".format(addrs, insts, muxs)) + +# main +cmdParse() +if not cores: + cores = configParse(section) +createModule(cores) diff --git a/config/core_selector.v b/config/core_selector.v new file mode 100644 index 0000000..4debd60 --- /dev/null +++ b/config/core_selector.v @@ -0,0 +1,250 @@ +// NOTE: This file is generated; do not edit by hand. + +module core_selector + ( + input wire sys_clk, + input wire sys_rst, + + 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_MODEXP = 9'h09; + + + //---------------------------------------------------------------- + // 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), + + .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) + ); + + + //---------------------------------------------------------------- + // 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), + + .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) + ); + + + //---------------------------------------------------------------- + // 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), + + .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) + ); + + + //---------------------------------------------------------------- + // 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), + + .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) + ); + + + //---------------------------------------------------------------- + // TRNG + //---------------------------------------------------------------- + wire enable_trng = (addr_core_num >= CORE_ADDR_TRNG) && (addr_core_num <= CORE_ADDR_TRNG_CSPRNG); + 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), + + .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), + + .avalanche_noise(noise), + .debug(debug) + ); + + + //---------------------------------------------------------------- + // MODEXP + //---------------------------------------------------------------- + wire enable_modexp = (addr_core_num == CORE_ADDR_MODEXP); + wire [31: 0] read_data_modexp; + wire error_modexp; + + modexp modexp_inst + ( + .clk(sys_clk), + .reset_n(~sys_rst), + + .cs(enable_modexp & (sys_eim_rd | sys_eim_wr)), + .we(sys_eim_wr), + + .address(addr_core_reg), + .write_data(sys_write_data), + .read_data(read_data_modexp) + ); + + + + //---------------------------------------------------------------- + // 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; + sys_error_mux = error_board_regs; + end + CORE_ADDR_COMM_REGS: + begin + sys_read_data_mux = read_data_comm_regs; + sys_error_mux = error_comm_regs; + end + CORE_ADDR_SHA256: + begin + sys_read_data_mux = read_data_sha256; + sys_error_mux = error_sha256; + end + CORE_ADDR_AES: + begin + sys_read_data_mux = read_data_aes; + sys_error_mux = error_aes; + end + CORE_ADDR_TRNG: + begin + sys_read_data_mux = read_data_trng; + sys_error_mux = error_trng; + end + CORE_ADDR_AVALANCHE_ENTROPY: + begin + sys_read_data_mux = read_data_trng; + sys_error_mux = error_trng; + end + CORE_ADDR_ROSC_ENTROPY: + begin + sys_read_data_mux = read_data_trng; + sys_error_mux = error_trng; + end + CORE_ADDR_TRNG_MIXER: + begin + sys_read_data_mux = read_data_trng; + sys_error_mux = error_trng; + end + CORE_ADDR_TRNG_CSPRNG: + begin + sys_read_data_mux = read_data_trng; + sys_error_mux = error_trng; + end + CORE_ADDR_MODEXP: + begin + sys_read_data_mux = read_data_modexp; + sys_error_mux = error_modexp; + end + + default: + begin + sys_read_data_mux = {32{1'b0}}; + sys_error_mux = 1; + end + endcase + + +endmodule + + +//====================================================================== +// EOF core_selector.v +//====================================================================== -- cgit v1.2.3