root/XilinxTools/xilinx_compile.py

Revision 75, 11.0 KB (checked in by amirh, 23 months ago)
Line 
1import os
2import subprocess
3import win32com.client
4
5
6ProjectName = "CP11U"
7XilinxPath = os.environ["XILINX"]
8XilinxBin = os.path.join(XilinxPath,'bin\\nt')
9
10ProjectDirectory = os.getcwd()
11WorkbookPath = os.path.join(ProjectDirectory,WorkbookFilename)
12WorkbookFilename = "%s.xlsx" % ProjectName
13
14Excel = win32com.client.Dispatch("Excel.Application")
15try:
16    ProjectWorkbook = Excel.Workbooks(WorkbookFilename) #check if it's already open
17except Exception,e:
18    try:
19        ProjectWorkbook = Excel.Workbooks.Open(WorkbookPath) #open it
20    except Exception,ex:
21        print ex
22
23run, runXST, runNGDBuild, runMAP, runPAR, runBitgen = False, True, False, False, False, False
24getXDL = True
25
26
27
28class 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       
60#------------------------------------------------------------------------
61#UCF Generation
62#------------------------------------------------------------------------
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       
79#------------------------------------------------------------------------
80#End UCF Generation
81#------------------------------------------------------------------------
82
83
84#------------------------------------------------------------------------
85#XST file Generation
86#------------------------------------------------------------------------
87    def GenerateXST(self):
88        SynthesisParametersRange = self.SynthesisSheet.Range("SynthParams").Value
89
90#There is a problem with integer values turning into Floats when accessed using Range("xx:xx").Value, use Formula instead
91#SynthesisParameters = SynthesisSheet.Range(SynthesisParametersRange).Value 
92#this xst writer used to have the style "for param,default,setting in SynthesisParameters:"
93
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()
120#------------------------------------------------------------------------
121#End of XST file Generation
122#------------------------------------------------------------------------   
123
124
125
126#------------------------------------------------------------------------
127#PRJ file Generation
128#------------------------------------------------------------------------
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()
143#------------------------------------------------------------------------
144#End of PRJ file Generation
145#------------------------------------------------------------------------
146
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)
193# xst -ifn CPU_TOP.xst -ofn CPU_TOP_xst_log.syr
194
195    def RunTranslate(self):
196        ngdbuild_path = os.path.join(XilinxBin,"ngdbuild")
197        TranslationSheet
198       
199        self.TranslateProcess = subprocess.Popen([ngdbuild_path,"-dd", self.tmpdir, "-aul", "-uc", self.ucf_file, "-p", self.part, '%s.ngc'%self.top, '%s.ngd'%self.top])
200
201# ngdbuild -dd tmp -aul -uc CP11-CPU.ucf -p xc5vlx85-ff676-1 CPU_TOP.ngc CPU_TOP.ngd
202# map -p xc5vlx85-ff676-1 -cm area -pr b -k 4 -c 100 -tx off -o CPU_TOP_map.ncd CPU_TOP.ngd CPU_TOP.pcf
203# par -w -ol std -t 1 CPU_TOP_map.ncd CPU_TOP_par.ncd CPU_TOP.pcf
204
205
206class XSTFile:
207    def __init__(self,name):
208        if os.path.exists(name):
209            self.File = open(name)
210       
211
212class Synthesizer:
213    def __init__(self):
214        self.xst_path = os.path.join(XilinxBin,"xst")
215        self.XST_Attr_Map = {}
216       
217        self.InputFileName
218        self.XST_Attr       
219        self.InputFormat
220
221       
222    def Run(self):
223        RunReq = [self.xst_path,"-ifn", "%s.xst"%top, "-ofn", "%s_xst_log.syr"%top]
224        print "Invoking Synthesis Tool: " + RunReq
225        self.retcode = subprocess.call(RunReq)
226 
227def LogPrint(Port,File):
228    ln = Port.readline()
229    print ln
230    File.write(ln)
231
232def HyperlinkSelection(Excel):
233    for cell in Excel.Selection:
234        cell.Hyperlinks.Add(cell,cell.Value)
235   
236#todo: define classes for each of the synthesis and placement files
237#create XML-RPC interface to marshal and demarshal components and invoke toolchain
238if __name__ == "__main__":
239    if run:
240        if runXST:
241            #Invoke XST
242            xst_path = os.path.join(XilinxBin,"xst")
243            retcode = subprocess.call([xst_path,"-ifn", "%s.xst"%top, "-ofn", "%s_xst_log.syr"%top])
244        if runNGDBuild:   
245            #Invoke NGDBuild
246            part = '%(device)s-%(package)s-%(speed)s'%globals()
247            ngdbuild_path = os.path.join(XilinxBin,"ngdbuild")
248            retcode = subprocess.call([ngdbuild_path,"-dd", tmpdir, "-aul", "-uc", ucf_file, "-p", part, '%s.ngc'%top, '%s.ngd'%top])
249
250        if runMAP:
251            #Invoke MAP
252            map_path = os.path.join(XilinxBin,"map")
253            retcode = subprocess.call([map_path, '-p', part, '-cm', 'area', '-pr', 'b', '-k', '4', '-c', '100', '-tx', 'off', '-o', '%s_map.ncd'%top, '%s.ngd'%top, '%s.pcf'%top])
254            if genXDL:
255                xdl_path = os.path.join(XilinxBin,"xdl")
256                retcode = subprocess.call([xdl_path,'-ncd2xdl','%s_map.ncd'%top])
257        if runPAR:
258            #Invoke PAR
259            par_path = os.path.join(XilinxBin,"par")
260            retcode = subprocess.call([par_path, '-w', '-ol', 'std', '-t', '1', '%s_map.ncd'%top, '%s_par.ncd'%top, '%s.pcf'%top])
261            if genXDL:
262                xdl_path = os.path.join(XilinxBin,"xdl")
263                retcode = subprocess.call([xdl_path,'-ncd2xdl','%s_par.ncd'%top])
264        if runBitgen:
265            #Invoke Bitgen
266            bitgen_path = os.path.join(XilinxBin,"bitgen")
267            bitgen_arglist = [bitgen_path, '%s_par.ncd'%top,'%s.bit'%top, '-w']
268            for opt in bit_gen_g_options:
269                bitgen_arglist.append('-g')
270                bitgen_arglist.append('%s'%opt)
271            retcode = subprocess.call(bitgen_arglist)
Note: See TracBrowser for help on using the browser.