From f141a79d805acbab07876d9f007e8809603718b5 Mon Sep 17 00:00:00 2001
From: Paul Selkirk <paul@psgd.org>
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