| #!/usr/bin/python |
| |
| #import standard modules |
| import os |
| import sys |
| |
| #import custom modules |
| import ODIN_CONFIG as odin |
| |
| #import functions from standard modules |
| from optparse import OptionGroup |
| from optparse import OptionParser |
| from os.path import abspath |
| from string import rstrip |
| |
| |
| #import functions from custom modules |
| from odin_script_util import isVerilog |
| |
| def main(argv=None): |
| |
| if argv is None: |
| argv = sys.argv |
| |
| parser = configOptParse() |
| (options, args) = parser.parse_args(argv) |
| |
| #Check our options for input errors |
| if not options.arch: |
| print "\tDid not get an architecture file; use odin_config_maker.py -h for help." |
| return -1 |
| if options.individual is None and options.directory is None and options.files is None: |
| print "\tDid not get any input options; use odin_config_maker.py -h for help." |
| return -1 |
| if options.individual is not None and options.directory is not None: |
| print "\tThe -i and -d options are mutually exclusive; use odin_config_maker.py -h for help." |
| return -1 |
| |
| #Create our Config Files |
| if options.individual: #Create a collection of configs |
| path = abspath(args.pop()) + "/" |
| base = None |
| file_list = map(lambda file: abspath(file), options.files) if options.files else [] |
| if options.individual: |
| file_list.extend(filter(isVerilog, map(lambda file: abspath(options.individual) + "/" + file, os.listdir(options.individual)))) |
| |
| for file in file_list: |
| print file[file.rfind("/") + 1:file.rfind(".v")] |
| base = file[file.rfind("/") + 1:file.rfind(".v")] |
| create_odin_projects(options, [file], base, path) |
| |
| elif options.directory or options.files and len(args) == 3: #Create a single project based on a directory or file list |
| base = args.pop() |
| path = abspath(args.pop()) + "/" |
| |
| file_list = map(lambda file: abspath(file), options.files) if options.files else [] |
| if options.directory: |
| file_list.extend(filter(isVerilog, map(lambda file: abspath(options.directory) + "/" + file, os.listdir(options.directory)))) |
| |
| create_odin_projects(options, file_list, base, path) |
| else: |
| print "Something Failed!" |
| return -1 |
| |
| def create_odin_projects(options, file_list, base, path): |
| soft = base + ".soft." if options.soft else None |
| hard_mem = base + ".hard_mem." if options.mem or options.both else None |
| hard_mult = base + ".hard_mult." if options.mult or options.both else None |
| hard = base + ".hard." if options.both else None |
| output = abspath(options.output) + "/" |
| |
| config = odin.config(verilog_files=create_common_verilog(file_list), debug_outputs= create_common_debug(options)) |
| if soft: |
| config.set_output(create_common_output(options, output + soft)) |
| config.export(open(path + soft + "xml", "w"), 0) |
| |
| if hard_mem or hard_mult or hard: |
| if hard: |
| config.set_output(create_common_output(options, output + hard)) |
| config.set_optimizations(create_common_optimizations(options)) |
| config.export(open(path + hard + "xml", "w"), 0) |
| if hard_mem: |
| config.set_output(create_common_output(options, output + hard_mem)) |
| config.set_optimizations(create_common_optimizations(options)) |
| config.optimizations.set_multiply(None) |
| config.export(open(path + hard_mem + "xml", "w"), 0) |
| if hard_mult: |
| config.set_output(create_common_output(options, output + hard_mult)) |
| config.set_optimizations(create_common_optimizations(options)) |
| config.optimizations.set_memory(None) |
| config.export(open(path + hard_mult + "xml", "w"), 0) |
| |
| def create_common_verilog(file_list): |
| verilog_files = odin.verilog_files() |
| verilog_files.set_verilog_file(file_list) |
| return verilog_files |
| |
| def create_common_output(options, outfile): |
| output = odin.output() |
| target = odin.target() |
| target.set_arch_file(abspath(options.arch)) |
| output.set_output_type("blif") |
| output.set_output_path_and_name(outfile + output.get_output_type()) |
| output.set_target(target) |
| return output |
| |
| def create_common_optimizations(options): |
| optimizations = odin.optimizations() |
| if options.mem or options.both: |
| mem = odin.memory() |
| if options.split_width or options.split_depth: |
| mem.set_split_memory_width(1 if options.split_width or options.split_depth else 0) |
| mem.set_split_memory_depth(1 if options.split_depth else 0) |
| else: |
| mem = None |
| optimizations.set_memory(mem) |
| |
| |
| if options.mult or options.both: |
| mult = odin.multiply() |
| if options.size: |
| mult.set_size(int(options.size)) |
| mult.set_fracture(1 if options.fracture else 0) |
| mult.set_fixed(1 if options.fixed else 0) |
| else: |
| mult = None |
| optimizations.set_multiply(mult) |
| |
| return optimizations |
| |
| def create_common_debug(options): |
| debug = odin.debug_outputs() |
| debug.set_debug_output_path(abspath(options.debug_path)) |
| debug.set_output_ast_graphs(1 if options.ast_graph else 0) |
| debug.set_output_netlist_graphs(1 if options.netlist_graph else 0) |
| return debug |
| |
| def configOptParse(): |
| parser = OptionParser(usage="odin_config_maker.py [options] [output_path] [base_filename]", |
| prog="odin_config_maker.py", |
| description="[output_path] specifies where configuration files will be written. [base_filename] is used to create the appropriate configuration files, [base_filename].soft.xml, [base_filename].hard_mem.xml, [base_filename].hard_mult.xml, [base_filename].hard.xml") |
| |
| #Input options |
| input = OptionGroup(parser, "Input Options", "These options specify what input options are available. At least one of these must be specified.") |
| input.add_option("-a", help="The ODIN_II architecture file to use", action="store", dest="arch", metavar="ARCH_FILE") |
| input.add_option("-i", help="Treat each verilog file in the given directory as a seperate ODIN_II project. The -i and -d options cannot be used together.", action="store", dest="individual", metavar="DIRECTORY") |
| input.add_option("-d", help="Treat the given directory as a single ODIN_II project and include all verilog files within it. The -i and -d options cannot be used together.", action="store", dest="directory") |
| input.add_option("-v", help="Add the given file to an ODIN_II project. This option can be used to create a project with files in different locations or in conjunction with -i and -d", |
| action="append", dest="files", metavar="FILE") |
| parser.add_option_group(input) |
| |
| #Output Options |
| output = OptionGroup(parser, "Output Options", "These options specify the different output options available, if more than one is specified multiple configs will be created.") |
| output.add_option("-o", help="The blif output path to be used in the configuration file. Defaults to ./", action="store", dest="output", metavar="OUTPUT_PATH") |
| output.add_option("--soft", help="Generate a blif using all soft logic.", action="store_true") |
| output.add_option("--both", help="Generate a blif that uses both hard block multiliers and memories.", action="store_true") |
| output.add_option("--mult", help="Generate a blif that uses hard block multiliers.", action="store_true") |
| output.add_option("--mem", help="Generate a blif that uses hard block memories.", action="store_true") |
| parser.add_option_group(output) |
| parser.set_defaults(output="./", soft=True, both=False, mult=False, mem=False) |
| |
| |
| #Muliplier Hard Block Options |
| mult = OptionGroup(parser, "Hard Block Multiplier Options", "Configure how ODIN will use hard block multipliers.") |
| mult.add_option("--size", help="Specify the minimum size of a multiplier.", action="store", dest="size") |
| mult.add_option("--fixed", help="Pad any extra pins on the multiplier.", action="store_true", dest="fixed") |
| mult.add_option("--no_fixed", help="Remove any extra pins on the multiplier.", action="store_false", dest="fixed") |
| mult.add_option("--fracture", help="split the multiplier if neccesary.", action="store_true", dest="fracture") |
| mult.add_option("--no_fracture", help="split the multiplier if neccesary.", action="store_true", dest="fracture") |
| parser.add_option_group(mult) |
| parser.set_defaults(fixed=True, fracture=False, mult=False) |
| |
| |
| #Memory Hard Block Options |
| mem = OptionGroup(parser, "Hard Block Memory Options", "Configure how ODIN will use hard block memories.") |
| mem.add_option("--split_width", help="Split memories on width.", action="store_true") |
| mem.add_option("--split_depth", help="Split memories on width and depth.", action="store_true") |
| parser.add_option_group(mem) |
| parser.set_defaults(split_width=False, split_depth=False) |
| |
| |
| #Debug Options |
| debug = OptionGroup(parser, "ODIN_II Debug Options", "Configure what type of bebug information ODIN_II will produce and where to put it.") |
| debug.add_option("--debug_path", help="Set the path where debug info will be put.", action="store") |
| debug.add_option("--no_ast_graph", help="Do not output an AST graph", action="store_false", dest="ast_graph") |
| debug.add_option("--no_netlist_graph", help="Do not output a netlist graph", action="store_false", dest="netlist_graph") |
| parser.add_option_group(debug) |
| parser.set_defaults(debug_path="./", ast_graph=True, netlist_graph=True) |
| |
| return parser |
| |
| if __name__ == "__main__": |
| sys.exit(main()) |