pyvado 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyvado/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+
2
+ from .pyvado import Pyvado
3
+ from .pyvado_error import PyvadoError
4
+ from .pyvado_session import PyvadoSession
5
+ from .pyvado_process import PyvadoProcess
pyvado/pyvado.py ADDED
@@ -0,0 +1,157 @@
1
+ """
2
+ File name: pyvado
3
+ Author: aureliesa
4
+ Version: 1.0.0
5
+ License: GPL-3.0-or-later
6
+ Dependencies: pyvado_process, pyvado_session, pyvado_manager
7
+ Descriptions: Vivado Python API wrapper
8
+ """
9
+
10
+ from .pyvado_process import PyvadoProcess
11
+ from .pyvado_session import PyvadoSession
12
+ from .pyvado_manager import *
13
+ import os
14
+
15
+ class Pyvado:
16
+ """
17
+ Python vivado API wrapper
18
+
19
+ Attributes
20
+ ----------
21
+ session : PyvadoSession
22
+ pyvado session data structure
23
+ project : ProjectManager
24
+ pyvado project manager
25
+ flow : FlowManager
26
+ pyvado synthesis flow manager
27
+ files : FilesManager
28
+ project file manager
29
+ hardware : HardwareManager
30
+ vivado hardware manager
31
+ report : ReportManager
32
+ vivado report manager
33
+ simulator : SimulatorManager
34
+ vivado simulator
35
+ tcl : TCLManager
36
+ direct tcl command
37
+ """
38
+
39
+ def __init__(self,
40
+ project_path : str = "",
41
+ vivado_command : str = "vivado",
42
+ process_timeout : int = 600
43
+ ):
44
+ """
45
+ PyVado constructor
46
+
47
+ Parameters
48
+ ----------
49
+ project_path : str = ""
50
+ vivado project path
51
+ vivado_command : str = "vivado"
52
+ vivado command line
53
+ process_timeout : int = 600
54
+ vivado command timeout
55
+ """
56
+
57
+ if not os.path.exists(".pyvadoLog"):
58
+ os.makedirs(".pyvadoLog")
59
+
60
+
61
+ self.__vivado_process = PyvadoProcess(
62
+ vivado_command = vivado_command,
63
+ timeout = process_timeout
64
+ )
65
+
66
+ self.__session = PyvadoSession(
67
+ project_path = project_path
68
+ )
69
+
70
+ self.__project = ProjectManager(
71
+ vivado_process = self.__vivado_process,
72
+ pyvado_session = self.session
73
+ )
74
+
75
+ self.__flow = FlowManager(
76
+ vivado_process = self.__vivado_process,
77
+ pyvado_session = self.session
78
+ )
79
+
80
+ self.__files = FileManager(
81
+ vivado_process = self.__vivado_process,
82
+ pyvado_session = self.session
83
+ )
84
+
85
+ self.__hardware = HardwareManager(
86
+ vivado_process = self.__vivado_process,
87
+ pyvado_session = self.session
88
+ )
89
+
90
+ self.__report = ReportManager(
91
+ vivado_process = self.__vivado_process,
92
+ pyvado_session = self.session
93
+ )
94
+
95
+ self.__simulator = SimulationManager(
96
+ vivado_process = self.__vivado_process,
97
+ pyvado_session = self.session
98
+ )
99
+
100
+ self.__tcl = TCLManager(
101
+ vivado_process = self.__vivado_process,
102
+ pyvado_session = self.session
103
+ )
104
+
105
+ @property
106
+ def session(self) -> PyvadoSession:
107
+ return self.__session
108
+
109
+ @property
110
+ def project(self) -> ProjectManager:
111
+ return self.__project
112
+
113
+ @property
114
+ def flow(self) -> FlowManager:
115
+ return self.__flow
116
+
117
+ @property
118
+ def files(self) -> FileManager:
119
+ return self.__files
120
+
121
+ @property
122
+ def hardware(self) -> HardwareManager:
123
+ return self.__hardware
124
+
125
+ @property
126
+ def report(self) -> ReportManager:
127
+ return self.__report
128
+
129
+ @property
130
+ def simulator(self) -> SimulationManager:
131
+ return self.__simulator
132
+
133
+ @property
134
+ def tcl(self) -> TCLManager:
135
+ return self.__tcl
136
+
137
+ def __enter__(self):
138
+ return self
139
+
140
+ def __exit__(self, exc_type, exc, tb):
141
+
142
+ if self.__session.target.is_open():
143
+ self.hardware.close_target()
144
+
145
+ if self.__session.hw_server.is_open():
146
+ self.hardware.disconnect_server()
147
+
148
+ if self.__session.hardware.is_open():
149
+ self.hardware.close_hardware()
150
+
151
+ if self.__session.project.is_open():
152
+ self.project.close()
153
+
154
+ if self.__session.simulator.is_open():
155
+ self.simulator.close()
156
+
157
+ self.__vivado_process.close()
pyvado/pyvado_error.py ADDED
@@ -0,0 +1,23 @@
1
+ """
2
+ File name: pyvado_error
3
+ Author: aureliesa
4
+ Version: 1.0.0
5
+ License: GPL-3.0-or-later
6
+ Contact: aurelie.saulq@proton.me
7
+ Dependencies:
8
+ Descriptions: Pyvado error
9
+ """
10
+
11
+ class PyvadoError(Exception):
12
+ """
13
+ Pyvado internal error class
14
+
15
+ Attributes
16
+ ----------
17
+
18
+ Methods
19
+ -------
20
+ """
21
+
22
+ def __init__(self, message : str):
23
+ super().__init__(message)
@@ -0,0 +1,9 @@
1
+
2
+ from .project_manager import ProjectManager
3
+ from .pyvado_manager import PyvadoManager
4
+ from .flow_manager import FlowManager
5
+ from .file_manager import FileManager
6
+ from .hardware_manager import HardwareManager
7
+ from .report_manager import ReportManager
8
+ from .simulation_manager import SimulationManager
9
+ from .tcl_manager import TCLManager
@@ -0,0 +1,358 @@
1
+ """
2
+ File name: file_manager
3
+ Author: aureliesa
4
+ Version: 1.0.0
5
+ License: GPL-3.0-or-later
6
+ Dependencies: pyvado_process, pyvado_session, pyvado_manager, pyvado_error, pathlib, shlex
7
+ Descriptions: Pyvado synthesis flow manager
8
+ """
9
+
10
+ from .pyvado_manager import PyvadoManager
11
+ from ..pyvado_process import PyvadoProcess
12
+ from ..pyvado_session import PyvadoSession
13
+ from ..pyvado_error import PyvadoError
14
+ from pathlib import Path
15
+ import shlex
16
+
17
+ class FileManager(PyvadoManager):
18
+ """
19
+ File system manager
20
+
21
+ Attributes
22
+ ----------
23
+ SUPPORTED_FILE_EXTENSIONS : list[str] (static)
24
+ list of supported file extensions
25
+
26
+ Methods
27
+ -------
28
+ add_file(file_path : str | list[str], used_in_synth : bool = True, used_in_sim : bool = True, import_file : bool =False, force : bool =True)
29
+ Add file(s) on vivado project. Function detect if the file is a constraint file
30
+ change_property(file_path : str | list[str], used_in_synth : bool = True, used_in_sim : bool = True)
31
+ change file property
32
+ add_directory(directory_path : str, used_in_synth : bool = True, used_in_sim : bool = True, import_file : bool =False, force : bool =True)
33
+ Add all files in directory and subdirectory
34
+ add_simulation_file(self, file_path : str, import_file : bool = False, force : bool = True)
35
+ Add simulation only file
36
+ add_constraint_file(file_path : str, import_file : bool = False, force : bool = True)
37
+ Add constraint file
38
+ remove_file(file_name : str, delete_from_disk : bool = False)
39
+ remove file from vivado projectt
40
+ get_files(self) -> list[str]
41
+ get files in vivado project
42
+ """
43
+
44
+ SUPPORTED_FILE_EXTENSIONS = [
45
+ ".nky", ".nkz", ".dcp", ".vho", ".vhd",
46
+ ".vhdl", ".vhf", ".vhdp", ".sv", ".svp",
47
+ ".v", ".veo", ".svo", ".vf", ".verilog",
48
+ ".vr", ".vg", ".vb", ".tf", ".vlog",
49
+ ".vp", ".vm", ".sveo", ".veo", ".svo"
50
+ ".vh", ".h", ".svh", ".vhp", ".svhp",
51
+ ".edn", ".edf", ".edif", ".ngc", ".bnx",
52
+ ".bmm", ".mif", ".mem", ".bd", ".wcfg",
53
+ ".coe", ".sdc", ".xdc", ".tcl"
54
+ ]
55
+
56
+ def __init__(self,
57
+ vivado_process : PyvadoProcess,
58
+ pyvado_session : PyvadoSession
59
+ ):
60
+ """
61
+ Pyvado file manager
62
+
63
+ Parameters
64
+ ----------
65
+ vivado_process : PyvadoProcess
66
+ vivado process
67
+ pyvado_session : PyvadoSession
68
+ pyvado project session
69
+ """
70
+
71
+ super().__init__(
72
+ vivado_process = vivado_process,
73
+ pyvado_session = pyvado_session
74
+ )
75
+
76
+ def add_file(self, file_path : str | list[str], used_in_synth : bool = True, used_in_sim : bool = True, import_file : bool =False, force : bool =True):
77
+ """
78
+ Add file(s) on vivado project. Function detect if the file is a constraint file
79
+
80
+ Parameters
81
+ ----------
82
+ file_path : str | [str]
83
+ path of file to add
84
+ used_in_synth : bool = Trie
85
+ the added file will be available for synthesis
86
+ used_in_sim : bool = True
87
+ the added file will be available for simulation
88
+ import_file : bool = False
89
+ the added file will be copy in the vivado project repo
90
+ force : bool = True+
91
+ force the file to be add if the file already exist
92
+
93
+ Errors
94
+ ------
95
+ ValueError
96
+ file must be available at least for synhtesis or simulation
97
+ PyvadoError
98
+ project is not open
99
+ """
100
+
101
+ if not used_in_synth and not used_in_sim:
102
+ raise ValueError("a file must be at least in simulation or synthesis")
103
+
104
+ if not self._pyvado_session.project.is_open():
105
+ raise PyvadoError("Project must be open to add files")
106
+
107
+ if not isinstance(file_path, list):
108
+ file_path = [file_path]
109
+
110
+ design_files = []
111
+ constrainst_files = []
112
+
113
+ file_path = [Path(f).resolve() for f in file_path]
114
+
115
+ for f in file_path:
116
+
117
+ if not f.suffix in self.SUPPORTED_FILE_EXTENSIONS:
118
+ raise PyvadoError(f"{f.suffix} extension is not supported")
119
+
120
+ if not f.exists():
121
+ raise PyvadoError(f"{f} does not exists")
122
+
123
+ if f.suffix == ".xdc" or f.suffix == ".sdc":
124
+ constrainst_files.append(str(f))
125
+ else:
126
+ design_files.append(str(f))
127
+
128
+ force = '-force' if force else ''
129
+ file = "import_files" if import_file else "add_files"
130
+
131
+ cmd = []
132
+
133
+ if design_files != []:
134
+ files = ' '.join(design_files)
135
+ cmd.append(f"{file} -norecurse {force} {files}")
136
+
137
+ if constrainst_files != []:
138
+ files = ' '.join(constrainst_files)
139
+ cmd.append(f"{file} -fileset constrs_1 -norecurse {force} {files}")
140
+
141
+
142
+ cmd.append("update_compile_order")
143
+
144
+
145
+ self._vivado_process.send(
146
+ cmd = cmd,
147
+ blocking = True
148
+ )
149
+
150
+ if design_files != []:
151
+ files = self.get_files()
152
+
153
+ file_name = [f.name for f in file_path]
154
+
155
+ new_files = ' '.join([f for f in files if Path(f).resolve().name in file_name and not Path(f).suffix in [".xdc", ".sdc"] ])
156
+
157
+ self._vivado_process.send(cmd=[
158
+ f"set_property used_in_synthesis {used_in_synth} [get_files {{{new_files}}}]",
159
+ f"set_property used_in_simulation {used_in_sim} [get_files {{{new_files}}}]"
160
+ ])
161
+
162
+ def change_property(self, file_path : str | list[str], used_in_synth : bool = True, used_in_sim : bool = True):
163
+ """
164
+ change file property
165
+
166
+ Parameters
167
+ ----------
168
+ file_path : str | list[str]
169
+ file path
170
+ used_in_synth : bool = True
171
+ file will be available for synthesis
172
+ used_in_sim : bool = True
173
+ file will be available for simulation
174
+
175
+ Errors
176
+ ------
177
+ ValueError
178
+ file must be available at least for synhtesis or simulation
179
+ PyvadoError
180
+ project is not open
181
+ """
182
+
183
+ if not used_in_synth and not used_in_sim:
184
+ raise ValueError("a file must be at least in simulation or synthesis")
185
+
186
+ if not self._pyvado_session.project.is_open():
187
+ raise PyvadoError("Project must be open to add files")
188
+
189
+ files = self.get_files()
190
+
191
+ if not isinstance(file_path, list):
192
+ file_path = [file_path]
193
+
194
+ file_path = [Path(f).resolve() for f in file_path]
195
+
196
+ if any(f.suffix == ".xdc" for f in file_path):
197
+ return
198
+
199
+ for f in file_path:
200
+ if not str(f) in files:
201
+ raise PyvadoError(f"{f} is not into the project")
202
+
203
+ files = ' '.join([f.as_posix() for f in file_path])
204
+
205
+ self._vivado_process.send([
206
+ f"set_property used_in_synthesis {used_in_synth} [get_files {{{files}}}]",
207
+ f"set_property used_in_simulation {used_in_sim} [get_files {{{files}}}]"
208
+ ])
209
+
210
+ def add_directory(self, directory_path : str, used_in_synth : bool = True, used_in_sim : bool = True, import_file : bool =False, force : bool =True):
211
+ """
212
+ Add all files in directory and subdirectory
213
+
214
+ Parameters
215
+ ----------
216
+ directory_path : str
217
+ directoy path
218
+ used_in_synth : bool = True
219
+ files will be available for synthesis
220
+ used_in_sim : bool = Truee
221
+ files will be available for simulation
222
+ import_file : bool = False
223
+ files will be copy on loval project
224
+ force : bool = True
225
+ if files already exist, files will be replace
226
+
227
+ Errors
228
+ ------
229
+ ValueError
230
+ directory path deos not exist
231
+ ValueError
232
+ directory_path is not a directory
233
+ """
234
+
235
+ directory_path = Path(directory_path).resolve()
236
+
237
+ if not directory_path.exists():
238
+ raise ValueError(f"{directory_path} does not exist")
239
+
240
+ if not directory_path.is_dir():
241
+ raise ValueError(f"{directory_path} is not a directory")
242
+
243
+ files = [f for f in directory_path.rglob("*") if f.is_file() and f.suffix in self.SUPPORTED_FILE_EXTENSIONS]
244
+
245
+ self.add_file(file_path=files, used_in_synth=used_in_synth, used_in_sim=used_in_sim, force=force, import_file=import_file)
246
+
247
+ def add_simulation_file(self, file_path : str, import_file : bool = False, force : bool = True):
248
+ """
249
+ Add simulation only file
250
+
251
+ Parameters
252
+ ----------
253
+ file_path : str
254
+ path of file to add
255
+ import_file : bool
256
+ the added file will be copy in the vivado project repo
257
+ force : bool
258
+ force the file to be add if the file already exist
259
+ """
260
+
261
+ self.add_file(
262
+ file_path=file_path,
263
+ used_in_synth=False,
264
+ used_in_sim=True,
265
+ import_file=import_file,
266
+ force=force
267
+ )
268
+
269
+ def add_constraint_file(self, file_path : str, import_file : bool = False, force : bool = True):
270
+ """
271
+ Add constraint file
272
+
273
+ Parameters
274
+ ----------
275
+ file_path : str
276
+ path of file to add
277
+ import_file : bool
278
+ the added file will be copy in the vivado project repo
279
+ force : bool
280
+ force the file to be add if the file already exist
281
+
282
+ Errors
283
+ ------
284
+ ValueError
285
+ extension must be .xdc or .sdc
286
+ """
287
+
288
+ sfx = Path(file_path).suffix
289
+ if sfx != ".xdc" and sfx != ".sdc":
290
+ raise ValueError(f"{sfx} constrainst file extension must be xdc or sdc")
291
+
292
+ self.add_file(
293
+ file_path=file_path,
294
+ used_in_sim=True,
295
+ used_in_synth=True,
296
+ import_file=import_file,
297
+ force=force
298
+ )
299
+
300
+ def remove_file(self, file_name : str, delete_from_disk : bool = False):
301
+ """
302
+ remove file from vivado project
303
+
304
+ Parameters
305
+ ----------
306
+ file_name : str
307
+ name of file to remove
308
+ delete_from_disk : bool = False
309
+ if file has been imported into the vivado project, set to true to delete this copy.
310
+
311
+ Errors
312
+ ------
313
+ PyvadoError
314
+ vivado project must be open
315
+ """
316
+
317
+ if not self._pyvado_session.project.is_open():
318
+ raise PyvadoError("Project must be open to add files")
319
+
320
+ cmd = [f"remove_files {file_name}"]
321
+
322
+ if delete_from_disk:
323
+ proj_source = f"{self._pyvado_session.project_name}.srcs/"
324
+ files = self.get_files()
325
+ for f in files:
326
+ if proj_source in str(f):
327
+ cmd.append(f"file delete -force {f}")
328
+ break
329
+
330
+ cmd.append("update_compile_order")
331
+
332
+ self._vivado_process.send(cmd=cmd)
333
+
334
+ def get_files(self) -> list[str]:
335
+ """
336
+ get files in vivado project
337
+
338
+ Returns
339
+ -------
340
+ list[str]
341
+ list of files
342
+
343
+ Errors
344
+ ------
345
+ PyvadoError
346
+ vivado project must be open
347
+ """
348
+
349
+ if not self._pyvado_session.project.is_open():
350
+ raise PyvadoError("Project must be open to add files")
351
+
352
+ self._vivado_process.send("puts [get_files]", blocking=False)
353
+ files = self._vivado_process.read()
354
+
355
+ if "No files matched" in files:
356
+ return []
357
+
358
+ return shlex.split(files)