Ejemplo n.º 1
0
  def __init__(self, moduleList):

    fpga_part_xilinx = moduleList.env['DEFS']['FPGA_PART_XILINX']
    xilinx_apm_name = moduleList.compileDirectory + '/' + moduleList.apmName

    # Generate the signature for the FPGA image
    signature = moduleList.env.Command(
      'config/signature.sh',
      moduleList.getAllDependencies('BIT'),
      [ '@echo \'#!/bin/sh\' > $TARGET',
        '@echo signature=\\"' + moduleList.apmName + '-`md5sum $SOURCE | sed \'s/ .*//\'`\\" >> $TARGET' ])
    
    moduleList.topModule.moduleDependency['SIGNATURE'] = [signature]

    if (model.getBuildPipelineDebug(moduleList) != 0):
        print  moduleList.swExeOrTarget + "\n"

    ##
    ## Generate a script for loading bitfiles onto an FPGA.
    ##
    def leap_xilinx_loader(xilinx_apm_name):
      try:
        fpga_pos = moduleList.getAWBParam(['physical_platform_config', 'physical_platform'], 'FPGA_POSITION')
      except:
        fpga_pos = None

      def leap_xilinx_loader_closure(target, source, env):
        lf = open(str(target[0]), 'w')

        lf.write('#!/usr/bin/perl\n')
        lf.write('\n')
        lf.write('my $retval = 0;\n')
        if fpga_pos != None:
          lf.write('use Getopt::Long;\n')
          lf.write('my $dev_id = undef;\n')
          lf.write('GetOptions(\'device-id=i\', \$dev_id);\n')
          lf.write('\n')

          lf.write('# Check for existance of expected bitfile.\n') 
          lf.write('if ( ! -e  "' + xilinx_apm_name + '_par.bit" ) {\n')
          lf.write('  die "Could not find bitfile ' + xilinx_apm_name + '_par.bit";\n')
          lf.write('}\n')

          lf.write('# Specify specific cable if device database includes a cable ID\n')
          lf.write('my $setCable = \'setCable -p auto\';\n')
          lf.write('if (defined($dev_id)) {\n')
          lf.write('  my $cable_cfg = `leap-fpga-ctrl --device-id=${dev_id} --getconfig prog_cable_id`;\n')
          lf.write('  chomp($cable_cfg);\n')
          lf.write('  $setCable = "setCable $cable_cfg" if ($cable_cfg ne "");\n')
          lf.write('}\n')
          lf.write('\n')
          lf.write('open (BATCH,">batch.opt");\n')
          lf.write('print BATCH "setMode -bscan\n')
          lf.write('${setCable}\n')
          lf.write('identify\n')
          lf.write('assignfile -p ' + str(fpga_pos) + ' -file ' + xilinx_apm_name + '_par.bit\n')
          lf.write('program -p ' + str(fpga_pos) + '\n')
          lf.write('quit\n')
          lf.write('EOF\n')
          lf.write('";\n')
          lf.write('close(BATCH);\n')
          lf.write('open (STDOUT, ">$ARGV[0]");\n')
          lf.write('open (STDERR, ">$ARGV[0]");\n')
          lf.write('$retval = system("impact -batch batch.opt");\n')
        lf.write('if($retval != 0) {\n')
        lf.write('    exit(257);\n') # some perl installs only return an 8 bit value
        lf.write('}\n')

        lf.close()
        os.chmod(str(target[0]), stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
                                 stat.S_IRGRP | stat.S_IXGRP |
                                 stat.S_IROTH | stat.S_IXOTH)

      return leap_xilinx_loader_closure
 
    loader = moduleList.env.Command(
      'config/' + moduleList.apmName + '.download',
      [],
      leap_xilinx_loader(xilinx_apm_name))

    dependOnSW = moduleList.getAWBParam(['xilinx_loader'], 'DEPEND_ON_SW')
    summary = 0
    if(dependOnSW):   
      summary = moduleList.env.Command(
        moduleList.apmName + '_hw.errinfo',
        moduleList.getAllDependencies('SIGNATURE') + moduleList.swExe,
        [ '@ln -fs ' + moduleList.swExeOrTarget + ' ' + moduleList.apmName,
          SCons.Script.Delete(moduleList.apmName + '_hw.exe'),
          SCons.Script.Delete(moduleList.apmName + '_hw.vexe'),
          '@echo "++++++++++++ Post-Place & Route ++++++++"',
          synthesis_library.leap_physical_summary(xilinx_apm_name + '.par.twr', moduleList.apmName + '_hw.errinfo', '^Slack \(MET\)', '^Slack \(VIOLATED\)') ])
    else:
      summary = moduleList.env.Command(
        moduleList.apmName + '_hw.errinfo',
        moduleList.getAllDependencies('SIGNATURE'),
        [ SCons.Script.Delete(moduleList.apmName + '_hw.exe'),
          SCons.Script.Delete(moduleList.apmName + '_hw.vexe'),
          '@echo "++++++++++++ Post-Place & Route ++++++++"',
          synthesis_library.leap_physical_summary(xilinx_apm_name + '.par.twr', moduleList.apmName + '_hw.errinfo', '^Slack \(MET\)', '^Slack \(VIOLATED\)') ])



    moduleList.env.Depends(summary, loader)

    moduleList.topModule.moduleDependency['LOADER'] = [summary]
    moduleList.topDependency = moduleList.topDependency + [summary]     
Ejemplo n.º 2
0
    def __init__(self, moduleList):

        fpga_part_xilinx = moduleList.env['DEFS']['FPGA_PART_XILINX']
        xilinx_apm_name = moduleList.compileDirectory + '/' + moduleList.apmName

        # Generate the signature for the FPGA image
        signature = moduleList.env.Command(
            'config/signature.sh', moduleList.getAllDependencies('BIT'), [
                '@echo \'#!/bin/sh\' > $TARGET',
                '@echo signature=\\"' + moduleList.apmName +
                '-`md5sum $SOURCE | sed \'s/ .*//\'`\\" >> $TARGET'
            ])

        moduleList.topModule.moduleDependency['SIGNATURE'] = [signature]

        if (model.getBuildPipelineDebug(moduleList) != 0):
            print moduleList.swExeOrTarget + "\n"

        ##
        ## Generate a script for loading bitfiles onto an FPGA.
        ##
        def leap_xilinx_loader(xilinx_apm_name):
            try:
                fpga_pos = moduleList.getAWBParam(
                    ['physical_platform_config', 'physical_platform'],
                    'FPGA_POSITION')
            except:
                fpga_pos = None

            def leap_xilinx_loader_closure(target, source, env):
                lf = open(str(target[0]), 'w')

                lf.write('#!/usr/bin/perl\n')
                lf.write('\n')
                lf.write('my $retval = 0;\n')
                if fpga_pos != None:
                    lf.write('use Getopt::Long;\n')
                    lf.write('my $dev_id = undef;\n')
                    lf.write('GetOptions(\'device-id=i\', \$dev_id);\n')
                    lf.write('\n')

                    lf.write('# Check for existance of expected bitfile.\n')
                    lf.write('if ( ! -e  "' + xilinx_apm_name +
                             '_par.bit" ) {\n')
                    lf.write('  die "Could not find bitfile ' +
                             xilinx_apm_name + '_par.bit";\n')
                    lf.write('}\n')

                    lf.write(
                        '# Specify specific cable if device database includes a cable ID\n'
                    )
                    lf.write('my $setCable = \'setCable -p auto\';\n')
                    lf.write('if (defined($dev_id)) {\n')
                    lf.write(
                        '  my $cable_cfg = `leap-fpga-ctrl --device-id=${dev_id} --getconfig prog_cable_id`;\n'
                    )
                    lf.write('  chomp($cable_cfg);\n')
                    lf.write(
                        '  $setCable = "setCable $cable_cfg" if ($cable_cfg ne "");\n'
                    )
                    lf.write('}\n')
                    lf.write('\n')
                    lf.write('open (BATCH,">batch.opt");\n')
                    lf.write('print BATCH "setMode -bscan\n')
                    lf.write('${setCable}\n')
                    lf.write('identify\n')
                    lf.write('assignfile -p ' + str(fpga_pos) + ' -file ' +
                             xilinx_apm_name + '_par.bit\n')
                    lf.write('program -p ' + str(fpga_pos) + '\n')
                    lf.write('quit\n')
                    lf.write('EOF\n')
                    lf.write('";\n')
                    lf.write('close(BATCH);\n')
                    lf.write('open (STDOUT, ">$ARGV[0]");\n')
                    lf.write('open (STDERR, ">$ARGV[0]");\n')
                    lf.write('$retval = system("impact -batch batch.opt");\n')
                lf.write('if($retval != 0) {\n')
                lf.write('    exit(257);\n'
                         )  # some perl installs only return an 8 bit value
                lf.write('}\n')

                lf.close()
                os.chmod(
                    str(target[0]),
                    stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP
                    | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)

            return leap_xilinx_loader_closure

        loader = moduleList.env.Command(
            'config/' + moduleList.apmName + '.download', [],
            leap_xilinx_loader(xilinx_apm_name))

        dependOnSW = moduleList.getAWBParam(['xilinx_loader'], 'DEPEND_ON_SW')
        summary = 0
        if (dependOnSW):
            summary = moduleList.env.Command(
                moduleList.apmName + '_hw.errinfo',
                moduleList.getAllDependencies('SIGNATURE') + moduleList.swExe,
                [
                    '@ln -fs ' + moduleList.swExeOrTarget + ' ' +
                    moduleList.apmName,
                    SCons.Script.Delete(moduleList.apmName + '_hw.exe'),
                    SCons.Script.Delete(moduleList.apmName + '_hw.vexe'),
                    '@echo "++++++++++++ Post-Place & Route ++++++++"',
                    synthesis_library.leap_physical_summary(
                        xilinx_apm_name + '.par.twr', moduleList.apmName +
                        '_hw.errinfo', '^Slack \(MET\)', '^Slack \(VIOLATED\)')
                ])
        else:
            summary = moduleList.env.Command(
                moduleList.apmName + '_hw.errinfo',
                moduleList.getAllDependencies('SIGNATURE'), [
                    SCons.Script.Delete(moduleList.apmName + '_hw.exe'),
                    SCons.Script.Delete(moduleList.apmName + '_hw.vexe'),
                    '@echo "++++++++++++ Post-Place & Route ++++++++"',
                    synthesis_library.leap_physical_summary(
                        xilinx_apm_name + '.par.twr', moduleList.apmName +
                        '_hw.errinfo', '^Slack \(MET\)', '^Slack \(VIOLATED\)')
                ])

        moduleList.env.Depends(summary, loader)

        moduleList.topModule.moduleDependency['LOADER'] = [summary]
        moduleList.topDependency = moduleList.topDependency + [summary]
    def __init__(self, moduleList):
        altera_apm_name = moduleList.compileDirectory + "/" + moduleList.apmName
        qsf_src_dir = moduleList.env["DEFS"]["ROOT_DIR_HW_MODEL"]

        # If the compilation directory doesn't exist, create it.
        if not os.path.exists(moduleList.compileDirectory):
            os.mkdir(moduleList.compileDirectory)

        rel_qsf_src_dir = model.rel_if_not_abspath(qsf_src_dir, moduleList.compileDirectory)

        # pick up awb parameters.
        paramTclFile = moduleList.topModule.moduleDependency["PARAM_TCL"][0]

        ## QA build expects to build sys_cfg_pkg.svh in the build directory
        if os.path.exists(qsf_src_dir + "/sys_cfg_pkg.svh") and not os.path.exists(
            moduleList.compileDirectory + "/sys_cfg_pkg.svh"
        ):
            os.symlink(rel_qsf_src_dir + "/sys_cfg_pkg.svh", moduleList.compileDirectory + "/sys_cfg_pkg.svh")

        altera_qsf = altera_apm_name + ".tcl"
        altera_qpf = altera_apm_name + ".qpf"

        prjFile = open(altera_qsf, "w")

        prjFile.write("package require ::quartus::project\n")
        prjFile.write("package require ::quartus::flow\n")
        prjFile.write("package require ::quartus::incremental_compilation\n")

        # Check for the existence of a project here, so that we can
        # make use of incremental compilation.
        prjFile.write("set created_project [project_exists " + moduleList.apmName + "]\n")
        prjFile.write("if $created_project {\n")
        prjFile.write("    project_open " + moduleList.apmName + " \n")
        prjFile.write("} else  {\n")
        prjFile.write("    project_new " + moduleList.apmName + "\n")
        prjFile.write("}\n\n")

        ##
        ## Define which version of CCI is in use for SystemVerilog packages
        ## imported from outside LEAP.
        ##
        if moduleList.getAWBParamSafe("qa_platform_libs", "CCI_S_IFC"):
            prjFile.write('set_global_assignment -name VERILOG_MACRO "MPF_PLATFORM_OME=1"\n')
        if moduleList.getAWBParamSafe("qa_platform_libs", "CCI_P_IFC"):
            prjFile.write('set_global_assignment -name VERILOG_MACRO "MPF_PLATFORM_BDX=1"\n')
            prjFile.write('set_global_assignment -name VERILOG_MACRO "BSV_POSITIVE_RESET=1"\n')

        prjFile.write("source " + rel_qsf_src_dir + "/ome2_ivt.qsf\n")
        prjFile.write("source " + rel_qsf_src_dir + "/qsf_env_settings.qsf\n")
        prjFile.write("source " + rel_qsf_src_dir + "/qsf_qph_PAR_files.qsf\n")

        # Include file path
        inc_dirs = ["hw/include"]
        for inc in inc_dirs:
            inc = model.rel_if_not_abspath(inc, moduleList.compileDirectory)
            prjFile.write("set_global_assignment -name SEARCH_PATH " + inc + "\n")

        # Include SDC (Tcl) files. These must be included in a specific order to honor dependencies among them.
        sdcs = (
            map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths("GIVEN_TCL_HEADERS"))
            + map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths("GIVEN_SDCS"))
            + map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths("GIVEN_SDC_ALGEBRAS"))
        )

        for tcl_header in [paramTclFile] + sdcs:
            prjFile.write(
                "set_global_assignment -name SDC_FILE "
                + model.rel_if_not_abspath(tcl_header, moduleList.compileDirectory)
                + "\n"
            )

        # List SystemVerilog packages first
        for pkg in moduleList.getAllDependenciesWithPaths("GIVEN_VERILOG_PKGS"):
            v = model.rel_if_not_abspath(pkg, moduleList.compileDirectory)
            prjFile.write("set_global_assignment -name SYSTEMVERILOG_FILE " + v + "\n")

        # Add in all the verilog here.
        [globalVerilogs, globalVHDs] = synthesis_library.globalRTLs(moduleList, moduleList.moduleList)

        # gather verilog for LI Modules.
        for module in [mod for mod in moduleList.synthBoundaries()] + [moduleList.topModule]:
            globalVerilogs += [model.get_temp_path(moduleList, module) + module.wrapperName() + ".v"]

        for v in globalVerilogs:
            t = "VERILOG"
            if (v[-2:] == "sv") or (v[-2:] == "vh"):
                t = "SYSTEMVERILOG"
            v = model.rel_if_not_abspath(v, moduleList.compileDirectory)
            prjFile.write("set_global_assignment -name " + t + "_FILE " + v + "\n")

        for v in globalVHDs:
            v = model.rel_if_not_abspath(v, moduleList.compileDirectory)
            prjFile.write("set_global_assignment -name VHDL_FILE " + v + "\n")

        # add the verilogs of the files generated by quartus system builder
        for v in model.Utils.clean_split(moduleList.env["DEFS"]["GIVEN_ALTERAVS"], sep=" "):
            v = model.rel_if_not_abspath(v, moduleList.compileDirectory)
            prjFile.write("set_global_assignment -name VERILOG_FILE " + v + "\n")

        fullCompilePath = os.path.abspath(moduleList.compileDirectory)

        # elaborate the design.
        prjFile.write(
            'execute_module  -tool map -args "--verilog_macro=\\"QUARTUS_COMPILATION=1\\" --lib_path '
            + fullCompilePath
            + '--incremental_compilation=full_incremental_compilation --analysis_and_elaboration " \n'
        )

        prjFile.write('puts "Elaboration Complete"\n')
        # create a partition for leap and the QA driver if they don't exist already.
        prjFile.write("if $created_project { \n")
        prjFile.write('    puts "Reusing existing LEAP partitions"\n')
        prjFile.write("} else  { \n")
        prjFile.write(
            "    create_partition -contents cci_std_afu:cci_std_afu|mk_model_Wrapper:model_wrapper|mk_platform_platform_Wrapper:m_sys_sys_vp_m_mod|mkQADeviceSynth:llpi_phys_plat_qa_device -partition qa_cci_part \n"
        )
        prjFile.write("} \n")

        ## Hack to meet timing -- turning off LEAP partition
        partition_mode = moduleList.getAWBParamSafe("qa_device", "CCI_LOOPBACK_HACK")
        if partition_mode < 2:
            prjFile.write('set_partition -partition qa_cci_part -netlist_type "Post-Fit"\n')
        else:
            prjFile.write('set_partition -partition qa_cci_part -netlist_type "Empty"\n')

        #        if (partition_mode < 1):
        #            prjFile.write('set_partition -partition leap_part -netlist_type "Post-Fit"\n')
        #        else:
        #            prjFile.write('set_partition -partition leap_part -netlist_type "Empty"\n')

        prjFile.write(
            'execute_module  -tool map -args "--verilog_macro=\\"QUARTUS_COMPILATION=1\\" --incremental_compilation=full_incremental_compilation --lib_path '
            + fullCompilePath
            + ' " \n'
        )
        prjFile.write('execute_module  -tool cdb -args "--merge"  \n')
        prjFile.write("execute_module  -tool fit \n")
        prjFile.write("execute_module  -tool sta \n")
        prjFile.write('execute_module  -tool sta -args "--do_report_timing"\n')
        prjFile.write("execute_module  -tool asm  \n")

        prjFile.write("project_close \n")
        prjFile.close()

        altera_sof = moduleList.env.Command(
            altera_apm_name + ".sof",
            globalVerilogs + globalVHDs + [altera_apm_name + ".tcl"] + [paramTclFile] + sdcs,
            ["cd " + moduleList.compileDirectory + "; quartus_sh -t " + moduleList.apmName + ".tcl"],
        )

        moduleList.topModule.moduleDependency["BIT"] = [altera_sof]

        # generate the download program
        newDownloadFile = open("config/" + moduleList.apmName + ".download.temp", "w")
        newDownloadFile.write("#!/bin/sh\n")
        newDownloadFile.write("nios2-configure-sof " + altera_apm_name + ".sof\n")
        newDownloadFile.close()

        altera_download = moduleList.env.Command(
            "config/" + moduleList.apmName + ".download",
            "config/" + moduleList.apmName + ".download.temp",
            ["cp $SOURCE $TARGET", "chmod 755 $TARGET"],
        )

        altera_loader = moduleList.env.Command(
            moduleList.apmName + "_hw.errinfo",
            moduleList.swExe + moduleList.topModule.moduleDependency["BIT"] + altera_download,
            [
                "@ln -fs " + moduleList.swExeOrTarget + " " + moduleList.apmName,
                SCons.Script.Delete(moduleList.apmName + "_hw.exe"),
                SCons.Script.Delete(moduleList.apmName + "_hw.vexe"),
                '@echo "++++++++++++ Post-Place & Route ++++++++"',
                synthesis_library.leap_physical_summary(
                    altera_apm_name + ".sta.rpt",
                    moduleList.apmName + "_hw.errinfo",
                    "Timing Analyzer was successful",
                    "Timing requirements not met",
                ),
            ],
        )

        moduleList.topModule.moduleDependency["LOADER"] = [altera_loader]
        moduleList.topDependency = moduleList.topDependency + [altera_loader]
Ejemplo n.º 4
0
    def __init__(self, moduleList):
        altera_apm_name = moduleList.compileDirectory + '/' + moduleList.apmName

        # pick up awb parameters.
        paramTclFile = moduleList.topModule.moduleDependency['PARAM_TCL'][0]

        # If the compilation directory doesn't exist, create it. 
        if(not os.path.exists(moduleList.compileDirectory)):
            os.mkdir(moduleList.compileDirectory)

        newPrjFile = open(altera_apm_name + '.tcl', 'w')

        newPrjFile.write('package require ::quartus::project\n')
        newPrjFile.write('package require ::quartus::flow\n')

        # do we want to check for the existence of a project here?
        newPrjFile.write('project_new ' + moduleList.apmName +' -overwrite\n')

        # Add in all the verilog here. 
        [globalVerilogs, globalVHDs] = synthesis_library.globalRTLs(moduleList, moduleList.moduleList)
         

        # gather verilog for LI Modules. 
        for module in [ mod for mod in moduleList.synthBoundaries()] + [moduleList.topModule]:
            globalVerilogs += [model.get_temp_path(moduleList,module) + module.wrapperName() + '.v']

        # Write files to the quartus project file. Due to a bug in the STA tool, we need to execute 
        # Quartus from the compileDirectory. This means we have to rebase all of the files.

        for v in globalVerilogs:
            newPrjFile.write('set_global_assignment -name VERILOG_FILE ' +  model.rel_if_not_abspath(v, moduleList.compileDirectory) + '\n'); 


        for v in globalVHDs:
            newPrjFile.write('set_global_assignment -name VHDL_FILE ' + model.rel_if_not_abspath(v, moduleList.compileDirectory) + '\n'); 

        for sysVerilogFile in  map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths('GIVEN_SYSTEM_VERILOGS')):
            newPrjFile.write('set_global_assignment -name SYSTEMVERILOG_FILE ' + model.rel_if_not_abspath(sysVerilogFile, moduleList.compileDirectory)+ '\n')

        # Altera flows appear to accept some kinds of memory intialization files. 
        # incorporate them here.
        for memFile in map(model.modify_path_hw,moduleList.getAllDependenciesWithPaths('GIVEN_MIFS') + moduleList.getAllDependenciesWithPaths('GIVEN_MIFS')):
            newPrjFile.write('set_global_assignment -name SOURCE_FILE ' + model.rel_if_not_abspath(memFile, moduleList.compileDirectory)+ '\n')

        print " Compile directory : " + moduleList.compileDirectory

        # add the verilogs of the files generated by quartus system builder
        for v in model.Utils.clean_split(moduleList.env['DEFS']['GIVEN_ALTERAVS'], sep = ' ') :
            newPrjFile.write('set_global_assignment -name VERILOG_FILE ' +  model.rel_if_not_abspath(v, moduleList.compileDirectory) + '\n'); 

        # Include SDC (Tcl) files. These must be included in a specific order to honor dependencies among them.
        sdcs = map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths('GIVEN_TCL_HEADERS')) + map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths('GIVEN_SDCS')) + map(model.modify_path_hw, moduleList.getAllDependenciesWithPaths('GIVEN_SDC_ALGEBRAS'))      

        for tcl_header in [paramTclFile] + sdcs:
            newPrjFile.write('set_global_assignment -name SDC_FILE ' + model.rel_if_not_abspath(tcl_header, moduleList.compileDirectory)+ '\n')

        newPrjFile.write('set_global_assignment -name TOP_LEVEL_ENTITY ' + moduleList.topModule.wrapperName() + '\n')

        for qsf in map(model.modify_path_hw,moduleList.getAllDependenciesWithPaths('GIVEN_QSFS')):
            newPrjFile.write('source ' + model.rel_if_not_abspath(qsf, moduleList.compileDirectory)+ '\n')

        fullCompilePath = os.path.abspath(moduleList.compileDirectory)

        newPrjFile.write('execute_module  -tool map -args "--verilog_macro=\\"QUARTUS_COMPILATION=1\\" --lib_path ' + fullCompilePath + ' " \n')
        newPrjFile.write('execute_module  -tool fit \n')
        newPrjFile.write('execute_module  -tool sta \n')
        newPrjFile.write('execute_module  -tool sta -args "--do_report_timing"\n')
        newPrjFile.write('execute_module  -tool asm  \n')

        newPrjFile.write('project_close \n')
        newPrjFile.close()

        altera_sof = moduleList.env.Command(altera_apm_name + '.sof',
                                            globalVerilogs + globalVHDs + [altera_apm_name + '.tcl'] + [paramTclFile] + sdcs,
                                            ['cd ' + moduleList.compileDirectory + '; quartus_sh -t ' + moduleList.apmName + '.tcl' ])


        moduleList.topModule.moduleDependency['BIT'] = [altera_sof]

        # generate the download program
        newDownloadFile = open('config/' + moduleList.apmName + '.download.temp', 'w')
        newDownloadFile.write('#!/bin/sh\n')
        
        fpgaPosition = moduleList.getAWBParam('physical_platform_config', 'FPGA_POSITION')
        newDownloadFile.write('nios2-configure-sof --device ' + str(fpgaPosition) + ' ' +  altera_apm_name + '.sof\n')
        newDownloadFile.close()

        altera_download = moduleList.env.Command(
            'config/' + moduleList.apmName + '.download',
            'config/' + moduleList.apmName + '.download.temp',
            ['cp $SOURCE $TARGET',
             'chmod 755 $TARGET'])

        altera_loader = moduleList.env.Command(
            moduleList.apmName + '_hw.errinfo',
            moduleList.swExe + moduleList.topModule.moduleDependency['BIT'] + altera_download,
            ['@ln -fs ' + moduleList.swExeOrTarget + ' ' + moduleList.apmName,
             SCons.Script.Delete(moduleList.apmName + '_hw.exe'),
             SCons.Script.Delete(moduleList.apmName + '_hw.vexe'),
             '@echo "++++++++++++ Post-Place & Route ++++++++"',
             synthesis_library.leap_physical_summary(altera_apm_name + '.sta.rpt', moduleList.apmName + '_hw.errinfo', 'Timing Analyzer was successful', 'Timing requirements not met')])

        moduleList.topModule.moduleDependency['LOADER'] = [altera_loader]
        moduleList.topDependency = moduleList.topDependency + [altera_loader]