| 25 | | ProjectSheet = ProjectWorkbook.Sheets("Project") |
| 26 | | SynthesisSheet = ProjectWorkbook.Sheets("Synthesis") |
| 27 | | ConstraintsSheet = ProjectWorkbook.Sheets("Constraints") |
| 28 | | |
| 29 | | top = ProjectSheet.Range("top").Value |
| 30 | | tmpdir = ProjectSheet.Range("tmpdir").Value |
| 31 | | xsthdpdir = ProjectSheet.Range("xsthdpdir").Value |
| 32 | | |
| 33 | | |
| 34 | | |
| | 23 | run, runXST, runNGDBuild, runMAP, runPAR, runBitgen = False, True, False, False, False, False |
| | 24 | getXDL = True |
| | 25 | |
| | 26 | |
| | 27 | |
| | 28 | class XilinxProject: |
| | 29 | ''' |
| | 30 | XilinxProject class accepts a Workbook specifying a Xilinx compilation project |
| | 31 | ''' |
| | 32 | def __init__(self,ProjectWorkbook,ProjectPath): |
| | 33 | |
| | 34 | |
| | 35 | self.ProjectWorkbook = ProjectWorkbook |
| | 36 | self.ProjectSheet = ProjectWorkbook.Sheets("Project") |
| | 37 | self.SynthesisSheet = ProjectWorkbook.Sheets("Synthesis") |
| | 38 | self.TranslationSheet = ProjectWorkbook.Sheets("Translation") |
| | 39 | self.ConstraintsSheet = ProjectWorkbook.Sheets("Constraints") |
| | 40 | self.BitstreamSheet = ProjectWorkbook.Sheets("Bitstream") |
| | 41 | |
| | 42 | self.ProjectPath = self.ProjectSheet.Range("ProjectPath").Value |
| | 43 | self.top = self.ProjectSheet.Range("top").Value |
| | 44 | self.tmpdir = self.ProjectSheet.Range("tmpdir").Value |
| | 45 | self.xsthdpdir = self.ProjectSheet.Range("xsthdpdir").Value |
| | 46 | self.part = self.ProjectSheet.Range("part").Value |
| | 47 | #Make tmp_dir and hdp_dir if necessary |
| | 48 | if (not os.path.exists(tmpdir)): |
| | 49 | os.mkdir(os.path.join(self.ProjectPath,self.tmpdir)) |
| | 50 | if (not os.path.exists(xsthdpdir)): |
| | 51 | os.mkdir(os.path.join(self.ProjectPath,self.xsthdpdir)) |
| | 52 | |
| | 53 | def SetUCF(self,ucf_file_path): |
| | 54 | self.ucf_file = ucf_file_path |
| | 55 | self.ConstraintsSheet.Range("ucffile").Formula = ucf_file_path |
| | 56 | |
| | 57 | def GetUCF(self): |
| | 58 | self.ucf_file = self.ConstraintsSheet.Range("ucffile").Formula |
| | 59 | |
| 38 | | ConstraintsRange = ConstraintsSheet.Range("ConstraintsRange") |
| 39 | | Constraints = ConstraintsSheet.Range(ConstraintsRange).Formula |
| 40 | | |
| 41 | | ucf_file = "%s.ucf"%top |
| 42 | | ucf_fo = open(ucf_file, mode='w') |
| 43 | | for net,loc,iostandard,slew in Constraints: |
| 44 | | line = "NET \"%s\" LOC = \"%s\" | IOSTANDARD = %s" % (net,loc,iostandard) |
| 45 | | if (slew == None): |
| 46 | | line += ";\n" |
| 47 | | else: |
| 48 | | line += " | SLEW = %s;\n" % slew |
| 49 | | ucf_fo.write(line) |
| 50 | | ucf_fo.close() |
| | 63 | def GenerateUCF(self): |
| | 64 | ConstraintsRange = self.ConstraintsSheet.Range("ConstraintsRange") |
| | 65 | Constraints = self.ConstraintsSheet.Range(ConstraintsRange).Formula |
| | 66 | |
| | 67 | self.ucf_file = "%s.ucf"%self.top |
| | 68 | ucf_fo = open(self.ucf_file, mode='w') |
| | 69 | for net,loc,iostandard,slew in Constraints: |
| | 70 | line = "NET \"%s\" LOC = \"%s\" | IOSTANDARD = %s" % (net,loc,iostandard) |
| | 71 | if (slew == None): |
| | 72 | line += ";\n" |
| | 73 | else: |
| | 74 | line += " | SLEW = %s;\n" % slew |
| | 75 | ucf_fo.write(line) |
| | 76 | ucf_fo.close() |
| | 77 | self.SetUCF(ucf_file) |
| | 78 | |
| 66 | | SynthesisParametersRows = SynthesisSheet.Range(SynthesisParametersRange).Rows |
| 67 | | xst_file = open("%s.xst"%top, mode='w') |
| 68 | | xst_file.write("set -tmpdir %s\n"% tmpdir) |
| 69 | | xst_file.write("set -xsthdpdir %s\n"% xsthdpdir) |
| 70 | | xst_file.write("run\n") |
| 71 | | |
| 72 | | |
| 73 | | for row in SynthesisParametersRows: |
| 74 | | Parameter=row.Columns(1).Value |
| 75 | | |
| 76 | | |
| 77 | | if row.Columns(3).HasFormula: |
| 78 | | Setting = row.Columns(3).Value |
| 79 | | else: |
| 80 | | Setting = row.Columns(3).Formula |
| 81 | | |
| 82 | | if row.Columns(2).HasFormula: |
| 83 | | Default = row.Columns(2).Value |
| 84 | | else: |
| 85 | | Default = row.Columns(2).Formula |
| 86 | | |
| 87 | | |
| 88 | | |
| 89 | | if (Setting != None) and (Setting != ""): |
| 90 | | xst_file.write("-%s %s\n"%(Parameter,Setting)) |
| 91 | | elif (Default != None) and (Default != ""): |
| 92 | | xst_file.write("-%s %s\n"%(Parameter,Default)) |
| 93 | | |
| 94 | | xst_file.close() |
| | 94 | SynthesisParametersRows = self.SynthesisSheet.Range(SynthesisParametersRange).Rows |
| | 95 | self.xst_file = "%s.xst"%top |
| | 96 | xst_fo = open(self.xst_file, mode='w') |
| | 97 | xst_fo.write("set -tmpdir %s\n" % self.tmpdir) |
| | 98 | xst_fo.write("set -xsthdpdir %s\n" % self.xsthdpdir) |
| | 99 | xst_fo.write("run\n") |
| | 100 | |
| | 101 | for row in SynthesisParametersRows: |
| | 102 | Parameter=row.Columns(1).Value |
| | 103 | |
| | 104 | if row.Columns(3).HasFormula: |
| | 105 | Setting = row.Columns(3).Value |
| | 106 | else: |
| | 107 | Setting = row.Columns(3).Formula |
| | 108 | |
| | 109 | if row.Columns(2).HasFormula: |
| | 110 | Default = row.Columns(2).Value |
| | 111 | else: |
| | 112 | Default = row.Columns(2).Formula |
| | 113 | |
| | 114 | if (Setting != None) and (Setting != ""): |
| | 115 | xst_fo.write("-%s %s\n"%(Parameter,Setting)) |
| | 116 | elif (Default != None) and (Default != ""): |
| | 117 | xst_fo.write("-%s %s\n"%(Parameter,Default)) |
| | 118 | |
| | 119 | xst_fo.close() |
| 104 | | SrcFilesAddress = ProjectSheet.Range("SrcFiles").Value |
| 105 | | SrcFileArray = ProjectSheet.Range(SrcFilesAddress).Value |
| 106 | | SrcFileList = [] |
| 107 | | for line in SrcFileArray: |
| 108 | | for element in line: |
| 109 | | SrcFileList.append(element) |
| 110 | | |
| 111 | | prj_file = open("%s.prj"%top,mode='w') |
| 112 | | #todo: verilog and vhdl segregation |
| 113 | | for file in SrcFileList: |
| 114 | | line = "vhdl work %s\n" % file #previous version had a path appended... |
| 115 | | prj_file.write(line) |
| 116 | | prj_file.close() |
| | 129 | def GeneratePRJ(self): |
| | 130 | SrcFilesAddress = ProjectSheet.Range("SrcFiles").Value |
| | 131 | SrcFileArray = ProjectSheet.Range(SrcFilesAddress).Value |
| | 132 | SrcFileList = [] |
| | 133 | for line in SrcFileArray: |
| | 134 | for element in line: |
| | 135 | SrcFileList.append(element) |
| | 136 | |
| | 137 | prj_file = open("%s.prj"%top,mode='w') |
| | 138 | #todo: verilog and vhdl segregation |
| | 139 | for file in SrcFileList: |
| | 140 | line = "vhdl work %s\n" % file #previous version had a path appended... |
| | 141 | prj_file.write(line) |
| | 142 | prj_file.close() |
| 121 | | ucf_file = 'CP11-CPU.ucf' |
| 122 | | |
| 123 | | XilinxPath = os.environ["XILINX"] |
| 124 | | XilinxBin = os.path.join(XilinxPath,'bin\\nt') |
| 125 | | |
| 126 | | |
| 127 | | |
| 128 | | |
| 129 | | #Generate LSO file |
| 130 | | lso_file = open ("%s.lso"%top,mode='w') |
| 131 | | lso_file.write('work') |
| 132 | | lso_file.close() |
| 133 | | |
| 134 | | #Make tmp_dir and hdp_dir if necessary |
| 135 | | if (not os.path.exists(tmpdir)): |
| 136 | | os.mkdir(tmpdir) |
| 137 | | if (not os.path.exists(xsthdpdir)): |
| 138 | | os.mkdir(xsthdpdir) |
| 139 | | |
| 140 | | |
| 141 | | |
| 142 | | |
| 143 | | |
| 144 | | bit_gen_g_options = [] |
| 145 | | bit_gen_g_options.append('DebugBitstream:No') |
| 146 | | bit_gen_g_options.append('Binary:no') |
| 147 | | bit_gen_g_options.append('CRC:Enable') |
| 148 | | bit_gen_g_options.append('ConfigRate:6') |
| 149 | | bit_gen_g_options.append('CclkPin:PullUp') |
| 150 | | bit_gen_g_options.append('M0Pin:PullUp') |
| 151 | | bit_gen_g_options.append('M1Pin:PullUp') |
| 152 | | bit_gen_g_options.append('M2Pin:PullUp') |
| 153 | | bit_gen_g_options.append('ProgPin:PullUp') |
| 154 | | bit_gen_g_options.append('DonePin:PullUp') |
| 155 | | bit_gen_g_options.append('TckPin:PullUp') |
| 156 | | bit_gen_g_options.append('TdiPin:PullUp') |
| 157 | | bit_gen_g_options.append('TdoPin:PullUp') |
| 158 | | bit_gen_g_options.append('TmsPin:PullUp') |
| 159 | | bit_gen_g_options.append('UnusedPin:PullDown') |
| 160 | | bit_gen_g_options.append('UserID:0xFFFFFFFF') |
| 161 | | #bit_gen_g_options.append('DCMShutDown:Disable') #not available |
| 162 | | bit_gen_g_options.append('StartUpClk:CClk') |
| 163 | | bit_gen_g_options.append('DONE_cycle:4') |
| 164 | | bit_gen_g_options.append('GTS_cycle:5') |
| 165 | | bit_gen_g_options.append('GWE_cycle:6') |
| 166 | | bit_gen_g_options.append('LCK_cycle:NoWait') |
| 167 | | bit_gen_g_options.append('Match_cycle:Auto') |
| 168 | | bit_gen_g_options.append('Security:None') |
| 169 | | bit_gen_g_options.append('DonePipe:No') |
| 170 | | bit_gen_g_options.append('DriveDone:Yes') |
| 171 | | |
| 172 | | |
| 173 | | |
| 174 | | |
| | 147 | def GenerateLSO(self): |
| | 148 | #Generate LSO file |
| | 149 | lso_file = open ("%s.lso"%top,mode='w') |
| | 150 | lso_file.write('work') |
| | 151 | lso_file.close() |
| | 152 | |
| | 153 | |
| | 154 | def GenerateBitgenOptions(self): |
| | 155 | BitgenParametersRange = self.ConstraintsSheet.Range("ConstraintsRange") |
| | 156 | BitgenParameters = self.ConstraintsSheet.Range(BitgenParametersRange).Formula |
| | 157 | self.bitgen_g_options = [] |
| | 158 | for option,setting in BitgenParameters: |
| | 159 | self.bitgen_g_options.append("%s:%s"%(option,setting)) |
| | 160 | |
| | 161 | |
| | 162 | |
| | 163 | ##bit_gen_g_options.append('DebugBitstream:No') |
| | 164 | ##bit_gen_g_options.append('Binary:no') |
| | 165 | ##bit_gen_g_options.append('CRC:Enable') |
| | 166 | ##bit_gen_g_options.append('ConfigRate:6') |
| | 167 | ##bit_gen_g_options.append('CclkPin:PullUp') |
| | 168 | ##bit_gen_g_options.append('M0Pin:PullUp') |
| | 169 | ##bit_gen_g_options.append('M1Pin:PullUp') |
| | 170 | ##bit_gen_g_options.append('M2Pin:PullUp') |
| | 171 | ##bit_gen_g_options.append('ProgPin:PullUp') |
| | 172 | ##bit_gen_g_options.append('DonePin:PullUp') |
| | 173 | ##bit_gen_g_options.append('TckPin:PullUp') |
| | 174 | ##bit_gen_g_options.append('TdiPin:PullUp') |
| | 175 | ##bit_gen_g_options.append('TdoPin:PullUp') |
| | 176 | ##bit_gen_g_options.append('TmsPin:PullUp') |
| | 177 | ##bit_gen_g_options.append('UnusedPin:PullDown') |
| | 178 | ##bit_gen_g_options.append('UserID:0xFFFFFFFF') |
| | 179 | ###bit_gen_g_options.append('DCMShutDown:Disable') #not available |
| | 180 | ##bit_gen_g_options.append('StartUpClk:CClk') |
| | 181 | ##bit_gen_g_options.append('DONE_cycle:4') |
| | 182 | ##bit_gen_g_options.append('GTS_cycle:5') |
| | 183 | ##bit_gen_g_options.append('GWE_cycle:6') |
| | 184 | ##bit_gen_g_options.append('LCK_cycle:NoWait') |
| | 185 | ##bit_gen_g_options.append('Match_cycle:Auto') |
| | 186 | ##bit_gen_g_options.append('Security:None') |
| | 187 | ##bit_gen_g_options.append('DonePipe:No') |
| | 188 | ##bit_gen_g_options.append('DriveDone:Yes') |
| | 189 | |
| | 190 | def RunSynthesis(self): |
| | 191 | xst_path = os.path.join(XilinxBin,"xst") |
| | 192 | self.SynthesisProcess = subprocess.Popen([xst_path,"-ifn", self.xst_file, "-ofn", "%s_xst_log.syr"%self.top],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) |