aboutsummaryrefslogtreecommitdiff
path: root/config/config.py
diff options
context:
space:
mode:
Diffstat (limited to 'config/config.py')
-rwxr-xr-xconfig/config.py212
1 files changed, 212 insertions, 0 deletions
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)