Exemple #1
0
def main(argv):

	# Parse command line arguments
        opts, args = slop.parse([
            ("e", "entity",          "Change output entity name.",          True),
            ("p", "pr_instance",     "Name of reconfigurable module",       True),
            ("l", "layout",          "Name of the layout file. Mandatory.", True, {"optional" : False}),
            (None, "no-slot-bufg",   "Do not instantiate BUFGs for the slot's clocks")],
            args=argv, banner="%prog [-e <entitiy>] [-p pr_inst] -l <layout.lyt> <in.vhd>")
	
	layout = opts["layout"]
	PRInstName = opts["pr_instance"]
	outputEntityName = opts["entity"]
	PRSignalSuffix = "_module"
        doBufg = opts["no-slot-bufg"]

	if not layout or len(args) != 1:
		usage()
		sys.exit(1)
			
	for s in layout.slots:
                print "Processing slot '" + s.name + "'..."
        	maketop(args[0], s.name, outputEntityName, PRSignalSuffix + "_" + s.name, s,
                        doBufg)

	insertBusMacroLib(args[0], layout)
Exemple #2
0
def main(arguments):

    opts, args = slop.parse(
        [("p", "parameter", "parameter to set in hw thread wrapper", True, {
            "as": "list",
            "default": []
        })],
        banner="%prog [options] num_thread num_osifs [first_task_num]",
        args=arguments)

    parameters = opts["parameter"]

    if len(args) < 2:
        opts.help()
        sys.exit(2)

    first_task = 0
    if len(args) == 3:
        first_task = int(args[2])

    num_thread = int(args[0])
    num_osifs = int(args[1])

    print "PARAMETER VERSION = 2.1.0"
    print
    print
    for i in range(num_osifs):
        print "BEGIN hw_task"
        print "\tPARAMETER INSTANCE = hw_task_%d" % (i + first_task)
        print "\tPARAMETER HW_VER = 1.%02d.b" % num_thread
        for p in parameters:
            print "\tPARAMETER %s" % p
        print "END"
        print
Exemple #3
0
def main(arguments):

    opts, args = slop.parse([
        ("p", "parameter", "parameter to set in hw thread wrapper", True,
            {"as" : "list", "default" : []})], 
        banner = "%prog [options] num_thread num_osifs [first_task_num]",
        args=arguments)

    parameters = opts["parameter"]

    if len(args) < 2:
        opts.help()
        sys.exit(2)
	
    first_task = 0
    if len(args) == 3:
        first_task = int(args[2])
    
    num_thread = int(args[0])
    num_osifs = int(args[1])
    
    print "PARAMETER VERSION = 2.1.0"
    print
    print
    for i in range(num_osifs):
	print "BEGIN hw_task"
        print "\tPARAMETER INSTANCE = hw_task_%d" % (i + first_task)
        print "\tPARAMETER HW_VER = 1.%02d.b" % num_thread
        for p in parameters:
            print "\tPARAMETER %s" % p
        print "END"
        print
Exemple #4
0
def main(argv):

        # Parse command line arguments
        opts, args = slop.parse([
            ("s", "static",  "Generate UCF file for the static design"),
            ("o", "outfile", "Output UCF file. Omit for stdout.",                 True),
            ("l", "layout",  "Name of layout file",                               True, {"optional" : False}),
            ("t", "top",     "Top level UCF (after addition of bus macros etc.)", True, {"optional" : False})],
            args=argv, banner="%prog [options] -l <layout.lyt> -t <top.vhd> <in.ucf>")

        layout = LayoutParser.read(open(opts["layout"],"r"))
        outputFileName = opts["outfile"]
        topFileName = opts["top"]
        static = opts["static"]

        if not layout or not topFileName or len(args) != 1:
                opts.help()
                sys.exit(2)
                
        inputFileName = args[0]

        # open UCF file and read in the lines
        ucfFile = open(inputFileName, "r")
        ucfLines = ucfFile.readlines()
	ucfFile.close()

        # open VHDL file and read in the lines
        vhdlFile = open(topFileName, "r")
        vhdlLines = vhdlFile.readlines()
        vhdlFile.close()

	makeucf(ucfLines, vhdlLines, outputFileName, layout, static)
Exemple #5
0
def main(argv):

    # Parse command line arguments
    opts, args = slop.parse(
        [("e", "entity", "Change output entity name.", True),
         ("p", "pr_instance", "Name of reconfigurable module", True),
         ("l", "layout", "Name of the layout file. Mandatory.", True, {
             "optional": False
         }),
         (None, "no-slot-bufg",
          "Do not instantiate BUFGs for the slot's clocks")],
        args=argv,
        banner="%prog [-e <entitiy>] [-p pr_inst] -l <layout.lyt> <in.vhd>")

    layout = opts["layout"]
    PRInstName = opts["pr_instance"]
    outputEntityName = opts["entity"]
    PRSignalSuffix = "_module"
    doBufg = opts["no-slot-bufg"]

    if not layout or len(args) != 1:
        usage()
        sys.exit(1)

    for s in layout.slots:
        print "Processing slot '" + s.name + "'..."
        maketop(args[0], s.name, outputEntityName,
                PRSignalSuffix + "_" + s.name, s, doBufg)

    insertBusMacroLib(args[0], layout)
def main(arguments):
	
    opts, args = slop.parse([
        ("l", "link", "link files instead of copying"),
        ("g", "generic", "set generic of hw thread", True, 
            {"as" : "array", "default" : []}),
        ("p", "parameter", "set parameter for hw thread WRAPPER. "
            "NOTE: use '=' instead of '=>'.", True,
            {"as" : "array", "default" : []}),
        ("a", "architecture", "target FPGA architecture (default:"
            "virtex6)", True, {"default" : "virtex6"})],
        banner = "%prog [options] <hwthread_name> <user_logic_entity> "
        "[<first file> <second_file> ...]")

    generics = opts["generic"]
    parameters = opts["parameter"]
    link = opts["link"]
    arch = opts["architecture"]

    if len(args) < 2:
        print "not enough arguments"
        opts.help()
        sys.exit(2)

    # unpack cmd line arguments
    hwthread_name, user_logic_entity = args[0:2]
    if len(args) > 2:
        files = args[2:]
    else:
        files = []

    # create hw thread directory
    os.mkdir(hwthread_name)

    # copy or link thread files
    for f in files:
        if link:
            os.symlink(os.path.abspath(f), hwthread_name + "/" + os.path.basename(f))
        else:
            shutil.copy(f, hwthread_name)

    # set up substitutions for Makefile template
    subst = [ 
        ('\$template:vhdl_files\$', string.join([ os.path.basename(f) for f in files ], ' ')),
        ('\$template:user_logic_entity\$', user_logic_entity),
        ('\$template:architecture\$', arch)
    ]
    if len(generics) > 0:
        subst.append(('\$template:generics\$', "\"" + ",".join(generics) + "\""))
    else:
        subst.append(('\$template:generics\$', ""))
    if len(parameters) > 0:
        subst.append(('\$template:wrapper_parameters\$', "\"" + ",".join(parameters) + "\""))
    else:
        subst.append(('\$template:wrapper_parameters\$', ""))

    templ_name = os.environ['RECONOS'] + '/tools/makefiles/templates/Makefile_hw_hwthreads_thread.template'
    makefile_name = os.path.join(hwthread_name, 'Makefile')
    reconos.tools.make_file_from_template(templ_name, makefile_name, subst)
Exemple #7
0
def main(arguments):

    opts, args = slop.parse(
        [("g", "generic", "generics to set. "
          "If your generic's value includes quotes (e.g. X\"DEADBEEF\"), "
          "you need to escape it twice: '-g SOME_GENERIC => X\\\\\\\"DEADBEEF\\\\\\\"'.",
          True, {
              "as": "list",
              "default": []
          })],
        banner=
        "%prog [options] user_logic_entity thread_num [ vhdl_files ... ] [ netlist_files ... ]",
        args=arguments)

    # TODO: catch invalid generics?
    generics = opts["generic"]

    if len(args) < 2:
        opts.help()
        sys.exit(2)

    if os.environ["RECONOS"] == "":
        sys.stderr.write("RECONOS environment variable not set.\n")
        sys.exit(1)

    user_logic_name = args[0]
    task_number = int(args[1])
    files = args[2:]
    vhdl_files = filter(lambda x: x[-4:] == ".vhd", files)
    # FIXME: this matches all files _containing_ .edn or .ngc, not just the suffixes (lazy me)
    netlist_files = filter(lambda x: x[-4:] == ".edn" or x[-4:] == ".ngc",
                           files)
    pcore_name = task_name + "_v1_%02i_b" % task_number
    header = "generated at " + datetime.datetime.today().isoformat(
        " ") + " by '%s %s %s" % (os.path.basename(
            sys.argv[0]), user_logic_name, task_number)
    for i in vhdl_files:
        header = header + " " + i
    for n in netlist_files:
        header = header + " " + n
    header = header + "'"

    reconos.pcore.createPCore(
        user_logic_name, task_number, vhdl_files, task_name, [
            os.environ["RECONOS"] +
            "/support/templates/coregen/burst_ram/burst_ram.edn"
        ] + netlist_files, header, generics)

    print "pcore generated."
    print "Don't forget to put any additional user logic files into the %s directory." % (
        pcore_name + "/hdl/vhdl")
    print "Add a line in %s/data/%s_v2_1_0.pao for each file (before the last %s line)." % (
        pcore_name, task_name, task_name)
Exemple #8
0
def main(argv):

    opts, args = slop.parse(
        [
            (
                "o",
                "osif_clk",
                "use a separate OSIF clock. " "If -c is not specified, this is also used as the thread clock.",
                True,
            ),
            ("c", "thread_clk", "use a thread clock different from the OSIF's sys_clk.", True),
        ],
        args=argv,
        banner="%prog [options] mhs_file",
    )

    thread_clk = opts["thread_clk"]
    osif_clk = opts["osif_clk"]

    if len(args) != 1:
        opts.help()
        sys.exit(2)

    mhs_orig = args[0]

    # parse mhs file
    a = reconos.mhs.MHS(mhs_orig)

    # get the number of reconos slots
    num_slots = len(a.getPcores("osif"))
    num_slots += len(a.getPcores("plb_osif"))
    num_slots += len(a.getPcores("xps_osif"))

    # we need at least one slot
    if num_slots == 0:
        print "error: no reconos slot in file '%s'" % mhs_orig
        sys.exit(2)

        # abort if there are already hw_tasks in the design
    if len(a.getPcores("hw_task")) > 0:
        print "error: file '%s' already contains %i hw_task instances" % (mhs_orig, len(a.getPcores("hw_task")))
        sys.exit(3)

        # add threads
    a = addThreads(a, num_slots, thread_clk, osif_clk)

    # ouput resulting mhs file
    print a
Exemple #9
0
def main(argv): 

    opts, args = slop.parse([
        ("o", "osif_clk", "use a separate OSIF clock. " 
                          "If -c is not specified, this is also used as the thread clock.", True),
        ("c", "thread_clk", "use a thread clock different from the OSIF's sys_clk.", True)], 
        args=argv, banner="%prog [options] mhs_file")

    thread_clk = opts["thread_clk"]
    osif_clk = opts["osif_clk"]

    if len(args) != 1:
        opts.help()
        sys.exit(2)
    
    mhs_orig = args[0]
    
    
    # parse mhs file
    a = reconos.mhs.MHS(mhs_orig)
    
    # get the number of reconos slots
    num_slots = len(a.getPcores("osif"))
    num_slots += len(a.getPcores("plb_osif"))
    num_slots += len(a.getPcores("xps_osif"))
    
    # we need at least one slot
    if num_slots == 0:
		print "error: no reconos slot in file '%s'" % mhs_orig
		sys.exit(2)
    
    # abort if there are already hw_tasks in the design
    if len(a.getPcores("hw_task")) > 0:
		print "error: file '%s' already contains %i hw_task instances" % (mhs_orig,len(a.getPcores("hw_task")))
		sys.exit(3)
    
    # add threads
    a = addThreads(a, num_slots, thread_clk, osif_clk)
        
    # ouput resulting mhs file
    print a
Exemple #10
0
def main(arguments):
    
    opts, args = slop.parse([
        ("g", "generic", "generics to set. "
                         "If your generic's value includes quotes (e.g. X\"DEADBEEF\"), "
                         "you need to escape it twice: '-g SOME_GENERIC => X\\\\\\\"DEADBEEF\\\\\\\"'.", True,
            {"as" : "list", "default" : []})],
        banner = "%prog [options] user_logic_entity thread_num [ vhdl_files ... ] [ netlist_files ... ]", 
        args = arguments)

    # TODO: catch invalid generics?
    generics = opts["generic"]

    if len(args) < 2:
        opts.help()
        sys.exit(2)
    
    if os.environ["RECONOS"] == "":
        sys.stderr.write("RECONOS environment variable not set.\n")
        sys.exit(1)
    
    user_logic_name = args[0]
    task_number = int(args[1])
    files = args[2:]
    vhdl_files = filter(lambda x: x[-4:] == ".vhd", files)
    # FIXME: this matches all files _containing_ .edn or .ngc, not just the suffixes (lazy me)
    netlist_files = filter(lambda x: x[-4:] == ".edn" or x[-4:] ==".ngc", files)
    pcore_name = task_name + "_v1_%02i_b" % task_number
    header = "generated at " + datetime.datetime.today().isoformat(" ") + " by '%s %s %s" % (os.path.basename(sys.argv[0]), user_logic_name, task_number)
    for i in vhdl_files:
        header = header + " " + i
    for n in netlist_files:
        header = header + " " + n
    header = header + "'" 
    
    reconos.pcore.createPCore(user_logic_name,task_number,vhdl_files,task_name,[os.environ["RECONOS"] + "/support/templates/coregen/burst_ram/burst_ram.edn"] + netlist_files,header,generics)

    print "pcore generated."
    print "Don't forget to put any additional user logic files into the %s directory." % (pcore_name + "/hdl/vhdl")
    print "Add a line in %s/data/%s_v2_1_0.pao for each file (before the last %s line)." % (pcore_name,task_name,task_name)
Exemple #11
0

### MAIN PROGRAM ###

# set cleanup handler
atexit.register(cleanup)

# exit normally when killed, thanks to
# http://code.activestate.com/recipes/533117/
signal.signal(signal.SIGTERM, lambda signum, stack_frame: sys.exit(1))


# parse command line arguments
opts, args = slop.parse([
    ("p", "port", "port to listen on (default: 42424)", True, {"default" :
        42424}),
    ("c", "chainpos", "JTAG chain position (default: 2)", True, {"default" :
        2})])

port = int(opts["port"])
chainpos = int(opts["chainpos"])
	
print "using JTAG chain position", chainpos

# create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# allow address reuse (thanks to [email protected] on python-list)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# associate with port
Exemple #12
0
        defaultISELib = None
    try:
        defaultEDKLib = os.environ["EDK_LIB"]
    except KeyError:
        defaultEDKLib = None

    # parse command line arguments
    opts, args = slop.parse([
        ("e", "user_logic_entity", "Name of thread entity to simulate", True, {
            "optional": False
        }),
        ("X", "ise_simlib_dir", "Location of ISE simulation libraries "
         "(default: $ISE_LIB)", True, {
             "default": defaultISELib
         }),
        ("E", "edk_simlib_dir", "Location of EDK simulation libraries "
         "(default: $EDK_LIB)", True, {
             "default": defaultEDKLib
         }),
        ("V", "plb_version", "Version of PLB to use for simulation. "
         "Possible values: " + str(supportedPLBVersions), True, {
             "default": '46'
         }), ("v", None, "Verbose output")
    ],
                            banner="%prog -e entity [options] vhdl_files ...")

    # retrieve options from parsed arguments
    userLogicName = opts["user_logic_entity"]
    PLBVersion = opts["plb_version"]
    verbose = opts["v"]
    ISELib = opts["ise_simlib_dir"]
    EDKLib = opts["edk_simlib_dir"]
def main(args):
            
    if os.environ["RECONOS"] == "":
        sys.stderr.write("RECONOS environment variable not set.\n")
        sys.exit(1)
    
    #parsing args
    opts, args = slop.parse([
        ("n", "name",        "the name of the hw-task dir in HWTHREADS",                             True , {"optional" : False}),
        ("t", "cpu_type",    "which kind of CPU (PPC405|MICROBLAZE)",                                True , {"optional" : False}),
        ("i", "include_dir", "if there is another include dir except of the sw-dir use this option", True ),
        ("a", "address",     "address for CPU_HWTHREAD program",                                     True ),
        ("s", "size",        "size for CPU_HWTHREAD program. "
        "With these args you can specifiy the location in RAM and the size reserved in RAM "
        "for the CPU_HWTHREAD program(HEX-VALS: e.g. 0x02000000). By default the first 32MB are "
        "for ecos and 4MB for each CPU_HWTHREAD program are reserved. If you add "
        "these args, you have to check manually for overlapping regions with other programs!!!",     True ),
        ("e", "ecos_size",   "if eCos should be greater than 32MB define the size in HEX",           True ),
        ("p", "platform",    "which FPGA. "
        "This Parameter is for the PPC405. If virtex4 is used then use \"-p virtex4\" "
        "In case of virtex2 no parameter has to be set, this is used as standard.",                  True )],
        banner="%prog [options] -n <name> -t <cpu_type> <source_file(s)>", args=args)

    hwthread_name = opts["name"]
    cpu_type = opts["cpu_type"]
    files = args
    #optional args
    include_dir = opts["include_dir"]
    thread_addr = opts["address"]
    thread_size = opts["size"]
    ecos_size = opts["ecos_size"]
    platform = opts["platform"]
            
    #check if needed args are set
    if hwthread_name == None:
        sys.stderr.write("No hwthread name!\n")
        opts.help()
	sys.exit(2)
    if cpu_type == None:
        sys.stderr.write("No CPU_TYPE!\n")
        opts.help()
	sys.exit(2)
    if (files == None) or (len(files) == 0):
        sys.stderr.write("No Sourcefile!\n")
        opts.help()
	sys.exit(2)
    #check if size AND addr arg are set
    if ( (thread_addr == None) ^ (thread_size == None) ):
        sys.stderr.write("Arguments for thread_size and address are not set correctly\n")
        opts.help() 
	sys.exit(2)
    #check platform argument
    if(platform != None):
        if (platform != "virtex4"):
            sys.stderr.write("Unknown platform\n")
            opts.help() 
	    sys.exit(2)
    else:
        platform = "virtex2"

    # create hw thread directory
    os.mkdir(hwthread_name)
   
    # identify cpu type
    if cpu_type == 'PPC405':
        if (platform == "virtex2"):
            cpuhwt_pcore = 'ppc405_v2_00_d'
        elif (platform == "virtex4"):
            cpuhwt_pcore = 'ppc405_virtex4_v1_01_d'
    else:
        sys.stderr.write('Wrong CPUTYPE! CPUTYPES are: PPC405\n')
        sys.exit(1)
    #set optional args string
    opt_args = ''
    if include_dir != None:
        opt_args += "-i " + include_dir +" "
    if thread_addr != None:
        opt_args += "-a " + thread_addr + " -s " + thread_size +" "
    if ecos_size != None:
        opt_args += "-e " + ecos_size + " "
        
    # copy sourcecode files
    #for f in files:
    #    shutil.copy(f, hwthread_name)

    # set up substitutions for Makefile template
    subst = [ 
        ('\$template:source_files\$', string.join([ os.path.basename(f) for f in files ], ' ')), 
        ('\$template:architecture\$', platform),
        ('\$template:cpuhwt_type\$', cpu_type),
        ('\$template:cpuhwt_pcore\$', cpuhwt_pcore), 
        ('\$template:opt_args\$', opt_args)
        
    ]
    templ_name = os.environ['RECONOS'] + '/tools/makefiles/templates/Makefile_hw_cpuhwthreads_thread.template'
    makefile_name = os.path.join(hwthread_name, 'Makefile')
    reconos.tools.make_file_from_template(templ_name, makefile_name, subst)
Exemple #14
0
if __name__ == '__main__':

    # parse options
    mode = None

    optlist, rem_args = slop.parse(
        [
            ("i", "infile", "input file (stdin if not specified)", True),
            ("o", "outfile", "output file (stdout if not specified). "
             "'infile' and 'outfile' can be the same.", True),
            ("t", "token", "token to replace (token will vanish)", True),
            ("s", "start", "replace between this and end token"
             "(tokens may remain in output with -k)", True),
            ("e", "end", "replace between start token and this"
             "(tokens may remain in output with -k)", True),
            ("r", "text", "text to replace tokens with", True),
            ("f", "file", "file to replace tokens with. "
             "If neither text nor file are specified, replacement text "
             "is read from stdin.", True),
            ("k", "keep", "keep 'start' and 'end' tokens in output"),
            ("P", "prefix", "when replacing between 'start' and 'end' tokens, "
             "do not retain the prefix in the line before 'start'. "
             "This is useful for C-style commented start/end tokens. "
             "Ignored when using '-t'."),
        ],
        banner="%prog [options] <-t token | -s start -e end> ")

    infilename = optlist["infile"]
    outfilename = optlist["outfile"]
    keep_tokens = optlist["keep"]
    with_prefix = not optlist["prefix"]
Exemple #15
0
        defaultISELib = os.environ["ISE_LIB"]
    except KeyError:
        defaultISELib = None
    try:
        defaultEDKLib = os.environ["EDK_LIB"]
    except KeyError:
        defaultEDKLib = None


    # parse command line arguments
    opts, args = slop.parse([
        ("e", "user_logic_entity", "Name of thread entity to simulate", True, {"optional" : False}),
        ("X", "ise_simlib_dir", "Location of ISE simulation libraries "
                                "(default: $ISE_LIB)",                  True, {"default" : defaultISELib}),
        ("E", "edk_simlib_dir", "Location of EDK simulation libraries "
                                "(default: $EDK_LIB)",                  True, {"default" : defaultEDKLib}),
        ("V", "plb_version",    "Version of PLB to use for simulation. "
                                "Possible values: " + str(supportedPLBVersions),
                                                                        True, {"default" : '46'}),
        ("v", None,             "Verbose output")],
        banner = "%prog -e entity [options] vhdl_files ...") 

    # retrieve options from parsed arguments
    userLogicName = opts["user_logic_entity"]
    PLBVersion = opts["plb_version"]
    verbose = opts["v"]
    ISELib = opts["ise_simlib_dir"]
    EDKLib = opts["edk_simlib_dir"]
    
    # remaining arguments are task VHDL files
    taskVhdFiles = args
Exemple #16
0
if __name__ == '__main__':

    # parse options
    mode = None

    optlist, rem_args = slop.parse([
        ("i", "infile", "input file (stdin if not specified)", True),
        ("o", "outfile", "output file (stdout if not specified). "
                         "'infile' and 'outfile' can be the same.", True),
        ("t", "token", "token to replace (token will vanish)", True),
        ("s", "start", "replace between this and end token"
            "(tokens may remain in output with -k)", True),
        ("e", "end", "replace between start token and this"
            "(tokens may remain in output with -k)", True),
        ("r", "text", "text to replace tokens with", True),
        ("f", "file", "file to replace tokens with. "
            "If neither text nor file are specified, replacement text "
            "is read from stdin.", True),
        ("k", "keep", "keep 'start' and 'end' tokens in output"),
        ("P", "prefix", "when replacing between 'start' and 'end' tokens, "
            "do not retain the prefix in the line before 'start'. "
            "This is useful for C-style commented start/end tokens. "
            "Ignored when using '-t'."),
        ], banner="%prog [options] <-t token | -s start -e end> ")

    infilename = optlist["infile"]
    outfilename = optlist["outfile"]
    keep_tokens = optlist["keep"]
    with_prefix = not optlist["prefix"]
    textfilename = optlist["file"]
Exemple #17
0
                ("launch_runs", launchOtherRuns),
                ("verify_configurations", verifyConfigurations),
                ("generate_other_bitstreams", generateOtherBitstreams),
                ("remove_other_runs", removeOtherRuns),
                ("remove_other_reconfig_modules", removeOtherReconfigModules)
            ],
            "canCreate" : False
        }
    }

    # parse command line arguments
    opts, args = slop.parse([
        ("p", "reconos_project", "ReconOS project file (*.rprj)", True, {"optional" : False}),
        ("P", "pa_project", "PlanAhead project name (may include subdirectories, no extension. E.g., \"build/planahead\")", True, {"default" : "project_reconos_1"}),
        ("o", "output", "Output TCL script (omit for stdout)", True),
        ("l", "list", "List all available steps and recipes and exit"),
        ("r", "recipe", "Recipe (aka workflow) to execute", True, {"default" : "complete"}),
        ("b", "begin", "Open existing project and begin with step BEGIN (omit to create a new project)", True),
        ("e", "end", "Only execute up to (and including) step END", True)
    ], banner="%prog [options] -p <project>")

    projectFileName = opts["reconos_project"]
    outputFileName = opts["output"]
    firstStep = opts["begin"]
    lastStep = opts["end"]
    paProjectDir = opts["pa_project"]
    recipeName = opts["recipe"]

    if opts.list:
        # list all available recipes
        for r in recipes.keys():