dv-flow-mgr 0.0.1.12664275031a1__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.
Files changed (35) hide show
  1. dv_flow_mgr/__init__.py +6 -0
  2. dv_flow_mgr/__main__.py +21 -0
  3. dv_flow_mgr/cmds/cmd_run.py +28 -0
  4. dv_flow_mgr/fileset.py +31 -0
  5. dv_flow_mgr/flow.py +59 -0
  6. dv_flow_mgr/fragment_def.py +46 -0
  7. dv_flow_mgr/package.py +79 -0
  8. dv_flow_mgr/package_def.py +97 -0
  9. dv_flow_mgr/parameters.py +27 -0
  10. dv_flow_mgr/session.py +247 -0
  11. dv_flow_mgr/share/flow.json +172 -0
  12. dv_flow_mgr/task.py +225 -0
  13. dv_flow_mgr/task_data.py +77 -0
  14. dv_flow_mgr/task_def.py +45 -0
  15. dv_flow_mgr/task_memento.py +34 -0
  16. dv_flow_mgr/tasklib/hdl/sim/mti_pkg.py +11 -0
  17. dv_flow_mgr/tasklib/hdl/sim/mti_task_sim_image.py +69 -0
  18. dv_flow_mgr/tasklib/hdl/sim/mti_task_sim_run.py +47 -0
  19. dv_flow_mgr/tasklib/hdl/sim/pkg_hdl_sim.py +8 -0
  20. dv_flow_mgr/tasklib/hdl/sim/task_sim_image.py +16 -0
  21. dv_flow_mgr/tasklib/hdl/sim/vl_task_sim_image.py +72 -0
  22. dv_flow_mgr/tasklib/hdl/sim/vlt_pkg.py +14 -0
  23. dv_flow_mgr/tasklib/hdl/sim/vlt_task_sim_image.py +50 -0
  24. dv_flow_mgr/tasklib/hdl/sim/vlt_task_sim_run.py +45 -0
  25. dv_flow_mgr/tasklib/std/fileset.py +5 -0
  26. dv_flow_mgr/tasklib/std/pkg_std.py +15 -0
  27. dv_flow_mgr/tasklib/std/std.dfs +7 -0
  28. dv_flow_mgr/tasklib/std/task_fileset.py +89 -0
  29. dv_flow_mgr/tasklib/std/task_null.py +26 -0
  30. dv_flow_mgr-0.0.1.12664275031a1.dist-info/LICENSE +201 -0
  31. dv_flow_mgr-0.0.1.12664275031a1.dist-info/METADATA +211 -0
  32. dv_flow_mgr-0.0.1.12664275031a1.dist-info/RECORD +35 -0
  33. dv_flow_mgr-0.0.1.12664275031a1.dist-info/WHEEL +5 -0
  34. dv_flow_mgr-0.0.1.12664275031a1.dist-info/entry_points.txt +2 -0
  35. dv_flow_mgr-0.0.1.12664275031a1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,172 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://fvutils.github.io/dv-flow-mgr/flow.json",
4
+ "title": "Flow-specification schema",
5
+ "description": "Flow-specification schema",
6
+ "type": "object",
7
+ "properties": {
8
+ "package": {
9
+ "$ref": "#/defs/package-def"
10
+ },
11
+ "fragment": {
12
+ "$ref": "#/defs/fragment-def"
13
+ },
14
+ "oneOf": [
15
+ {"required": ["package"]},
16
+ {"required": ["fragment"]}
17
+ ]
18
+ },
19
+ "defs": {
20
+
21
+ "package-def": {
22
+ "title": "Package Definition",
23
+ "$$target": "#/defs/package-def",
24
+ "type": "object",
25
+ "properties": {
26
+ "name": {
27
+ "type": "string"
28
+ },
29
+ "imports": {
30
+ "type": "array",
31
+ "items": {
32
+ "$ref": "#/defs/import-def"
33
+ }
34
+ },
35
+ "with": {
36
+ "type": "array",
37
+ "items": {
38
+ "$ref": "#/defs/param"
39
+ }
40
+ },
41
+ "tasks": {
42
+ "type": "array",
43
+ "items": {
44
+ "$ref": "#/defs/task-def"
45
+ }
46
+ },
47
+ "fragments": {
48
+ "type": "array",
49
+ "items": {
50
+ "type": "string"
51
+ }
52
+ }
53
+ }
54
+ },
55
+
56
+ "import-def": {
57
+ "title": "Import Definition",
58
+ "$$target": "#/defs/import-def",
59
+ "type": "object",
60
+ "properties": {
61
+ "name": {
62
+ "type": "string"
63
+ },
64
+ "as": {
65
+ "type": "string"
66
+ },
67
+ "with": {
68
+ "type": "array",
69
+ "items": {
70
+ "$ref": "#/defs/param"
71
+ }
72
+ },
73
+ "from": {
74
+ "type": "string"
75
+ }
76
+ }
77
+ },
78
+
79
+ "fragment-def": {
80
+ "title": "Fragment Definition",
81
+ "$$target": "#/defs/fragment-def",
82
+ "type": "object",
83
+ "properties": {
84
+ "imports": {
85
+ "type": "array",
86
+ "items": {
87
+ "type": "string"
88
+ }
89
+ },
90
+ "tasks": {
91
+ "type": "array",
92
+ "items": {
93
+ "$ref": "#/defs/task-def"
94
+ }
95
+ },
96
+ "fragments": {
97
+ "type": "array",
98
+ "items": {
99
+ "type": "string"
100
+ }
101
+ }
102
+ }
103
+ },
104
+ "param": {
105
+ "title": "Parameter Definition",
106
+ "$$target": "#/defs/param",
107
+ "type": "object",
108
+ "properties": {
109
+ "name": {
110
+ "type": "string"
111
+ },
112
+ "type": {
113
+ "type": "string"
114
+ },
115
+ "value": {
116
+ "type": "string"
117
+ }
118
+ }
119
+ },
120
+ "task-dep": {
121
+ "title": "Task dependency specification",
122
+ "$$target": "#/defs/task-dep",
123
+ "type": "object",
124
+ "properties": {
125
+ "name": {
126
+ "type": "string"
127
+ },
128
+ "with": {
129
+ "type": "array",
130
+ "items": {
131
+ "$ref": "#/defs/param"
132
+ }
133
+ }
134
+ }
135
+ },
136
+ "task-def": {
137
+ "title": "Task Definition",
138
+ "$$target": "#/defs/task-def",
139
+ "type": "object",
140
+ "properties": {
141
+ "name": {
142
+ "type": "string"
143
+ },
144
+ "type": {
145
+ "type": "string"
146
+ },
147
+ "with": {
148
+ "type": "array",
149
+ "items": {
150
+ "$ref": "#/defs/param"
151
+ }
152
+ },
153
+ "depends": {
154
+ "oneOf": [
155
+ {
156
+ "type": "array",
157
+ "items": {
158
+ "$ref": "#/defs/task-dep"
159
+ }
160
+ }, {
161
+ "type": "array",
162
+ "items": {
163
+ "type": "string"
164
+ }
165
+ }
166
+ ]
167
+ }
168
+ }
169
+ }
170
+ }
171
+ }
172
+
dv_flow_mgr/task.py ADDED
@@ -0,0 +1,225 @@
1
+ #****************************************************************************
2
+ #* task.py
3
+ #*
4
+ #* Copyright 2023 Matthew Ballance and Contributors
5
+ #*
6
+ #* Licensed under the Apache License, Version 2.0 (the "License"); you may
7
+ #* not use this file except in compliance with the License.
8
+ #* You may obtain a copy of the License at:
9
+ #*
10
+ #* http://www.apache.org/licenses/LICENSE-2.0
11
+ #*
12
+ #* Unless required by applicable law or agreed to in writing, software
13
+ #* distributed under the License is distributed on an "AS IS" BASIS,
14
+ #* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ #* See the License for the specific language governing permissions and
16
+ #* limitations under the License.
17
+ #*
18
+ #* Created on:
19
+ #* Author:
20
+ #*
21
+ #****************************************************************************
22
+ import os
23
+ import json
24
+ import asyncio
25
+ import dataclasses as dc
26
+ from pydantic import BaseModel
27
+ from typing import Any, Dict, List, Tuple
28
+ from .task_data import TaskData
29
+ from .task_memento import TaskMemento
30
+
31
+ @dc.dataclass
32
+ class TaskSpec(object):
33
+ name : str
34
+
35
+ class TaskParams(BaseModel):
36
+ pass
37
+
38
+ @dc.dataclass
39
+ class TaskCtor(object):
40
+ def mkTaskParams(self) -> TaskParams:
41
+ raise NotImplementedError()
42
+
43
+ def setTaskParams(self, params : TaskParams, pvals : Dict[str,Any]):
44
+ for p in pvals.keys():
45
+ if not hasattr(params, p):
46
+ raise Exception("Unsupported parameter: " + p)
47
+ else:
48
+ setattr(params, p, pvals[p])
49
+
50
+ def mkTask(self, name : str, task_id : int, session : 'Session', params : TaskParams, depends : List['Task']) -> 'Task':
51
+ raise NotImplementedError()
52
+
53
+ @dc.dataclass
54
+ class TaskCtorT(TaskCtor):
55
+ TaskParamsT : TaskParams
56
+ TaskT : 'Task'
57
+
58
+ def mkTaskParams(self) -> TaskParams:
59
+ return self.TaskParamsT()
60
+
61
+ def mkTask(self, name : str, task_id : int, session : 'Session', params : TaskParams, depends : List['Task']) -> 'Task':
62
+ task = self.TaskT(
63
+ name=name,
64
+ task_id=task_id,
65
+ session=session,
66
+ params=params,
67
+ depends=depends)
68
+ task.depends.extend(depends)
69
+ return task
70
+
71
+ @dc.dataclass
72
+ class TaskParamCtor(object):
73
+ base : TaskCtor
74
+ params : Dict[str,Any]
75
+ basedir : str
76
+ depend_refs : List['TaskSpec']
77
+
78
+ def mkTaskParams(self) -> TaskParams:
79
+ params = self.base.mkTaskParams()
80
+ self.base.setTaskParams(params, self.params)
81
+ return params
82
+
83
+ def setTaskParams(self, params : Dict, pvals : Dict[str,Any]):
84
+ pass
85
+
86
+ def mkTask(self, name : str, task_id : int, session : 'Session', params : Dict, depends : List['Task']) -> 'Task':
87
+ task = self.base.mkTask(
88
+ name=name,
89
+ task_id=task_id,
90
+ session=session,
91
+ params=params,
92
+ depends=depends)
93
+ task.basedir = self.basedir
94
+ task.depend_refs.extend(self.depend_refs)
95
+ return task
96
+
97
+ @dc.dataclass
98
+ class PackageTaskCtor(TaskCtor):
99
+ name : str
100
+ pkg : 'Package'
101
+
102
+ def mkTaskParams(self, params : Dict) -> Dict:
103
+ return self.pkg.mkTaskParams(self.name, params)
104
+ def mkTask(self, name : str, task_id : int, session : 'Session', params : Dict, depends : List['Task']) -> 'Task':
105
+ return self.pkg.mkTask(self.name, task_id, session, params, depends)
106
+
107
+ @dc.dataclass
108
+ class Task(object):
109
+ """Executable view of a task"""
110
+ name : str
111
+ task_id : int
112
+ session : 'Session'
113
+ params : TaskParams
114
+ basedir : str
115
+ srcdir : str = None
116
+ memento : TaskMemento = None
117
+ depend_refs : List['TaskSpec'] = dc.field(default_factory=list)
118
+ depends : List[int] = dc.field(default_factory=list)
119
+ running : bool = False
120
+ output_set : bool = False
121
+ output : Any = None
122
+ output_ev : Any = asyncio.Event()
123
+
124
+ # Implementation data below
125
+ basedir : str = dc.field(default=None)
126
+ rundir : str = dc.field(default=None)
127
+ impl : str = None
128
+ body: Dict[str,Any] = dc.field(default_factory=dict)
129
+ impl_t : Any = None
130
+
131
+ def getMemento(self, T) -> TaskMemento:
132
+ if os.path.isfile(os.path.join(self.rundir, "memento.json")):
133
+ with open(os.path.join(self.rundir, "memento.json"), "r") as fp:
134
+ try:
135
+ data = json.load(fp)
136
+ self.memento = T(**data)
137
+ except Exception as e:
138
+ print("Failed to load memento %s: %s" % (
139
+ os.path.join(self.rundir, "memento.json"), str(e)))
140
+ os.unlink(os.path.join(self.rundir, "memento.json"))
141
+ return self.memento
142
+
143
+ def setMemento(self, memento : TaskMemento):
144
+ self.memento = memento
145
+
146
+ async def do_run(self) -> TaskData:
147
+ print("do_run: %s - %d depends" % (self.name, len(self.depends)))
148
+ if len(self.depends) > 0:
149
+ awaitables = [dep.waitOutput() for dep in self.depends]
150
+ deps_o = await asyncio.gather(*awaitables)
151
+
152
+ print("deps_o: %s" % str(deps_o))
153
+
154
+ # Merge the output of the dependencies into a single input data
155
+ # if len(self.depends) > 1:
156
+ # raise Exception("TODO: handle >1 inputs")
157
+
158
+ input = self.depends[0].output.copy()
159
+ else:
160
+ input = TaskData()
161
+
162
+ if not os.path.isdir(self.rundir):
163
+ os.makedirs(self.rundir)
164
+
165
+ result = await self.run(input)
166
+
167
+ if not self.output_set:
168
+ if result is None:
169
+ result = TaskData()
170
+
171
+ # We perform an auto-merge algorithm if the task
172
+ # doesn't take control
173
+ # for dep_o in deps_o:
174
+ # result.deps.append(dep_o.clone())
175
+
176
+ self.setOutput(result)
177
+ else:
178
+ # The task has taken control of the output
179
+ result = self.getOutput()
180
+
181
+ # Write-back the memento, if specified
182
+ if self.memento is not None:
183
+ with open(os.path.join(self.rundir, "memento.json"), "w") as fp:
184
+ fp.write(self.memento.model_dump_json(indent=2))
185
+
186
+ self.running = False
187
+
188
+ # Combine data from the deps to produce a result
189
+ return result
190
+
191
+ async def run(self, input : TaskData) -> TaskData:
192
+ raise NotImplementedError("TaskImpl.run() not implemented")
193
+
194
+ def setOutput(self, output : TaskData):
195
+ self.output_set = True
196
+ output.task_id = self.task_id
197
+ self.output = output
198
+ self.output_ev.set()
199
+
200
+ async def waitOutput(self) -> TaskData:
201
+ if not self.output_set:
202
+ if self.running:
203
+ # Task is already running
204
+ print("wait")
205
+ await self.output_ev.wait()
206
+ else:
207
+ self.running = True
208
+ print("start task")
209
+ await self.do_run()
210
+ return self.output
211
+
212
+ def getOutput(self) -> TaskData:
213
+ return self.output
214
+
215
+ def getField(self, name : str) -> Any:
216
+ if name in self.__dict__.keys():
217
+ return self.__dict__[name]
218
+ elif name in self.__pydantic_extra__.keys():
219
+ return self.__pydantic_extra__[name]
220
+ else:
221
+ raise Exception("No such field %s" % name)
222
+
223
+
224
+
225
+
@@ -0,0 +1,77 @@
1
+ #****************************************************************************
2
+ #* task_data.py
3
+ #*
4
+ #* Copyright 2023 Matthew Ballance and Contributors
5
+ #*
6
+ #* Licensed under the Apache License, Version 2.0 (the "License"); you may
7
+ #* not use this file except in compliance with the License.
8
+ #* You may obtain a copy of the License at:
9
+ #*
10
+ #* http://www.apache.org/licenses/LICENSE-2.0
11
+ #*
12
+ #* Unless required by applicable law or agreed to in writing, software
13
+ #* distributed under the License is distributed on an "AS IS" BASIS,
14
+ #* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ #* See the License for the specific language governing permissions and
16
+ #* limitations under the License.
17
+ #*
18
+ #* Created on:
19
+ #* Author:
20
+ #*
21
+ #****************************************************************************
22
+ import pydantic.dataclasses as dc
23
+ from pydantic import BaseModel
24
+ from typing import Any, Dict, Set, List, Tuple
25
+ from .fileset import FileSet
26
+
27
+ class TaskData(BaseModel):
28
+ task_id : int = -1
29
+ params : Dict[str,Any] = dc.Field(default_factory=dict)
30
+ deps : List['TaskData'] = dc.Field(default_factory=list)
31
+ changed : bool = False
32
+
33
+ def hasParam(self, name: str) -> bool:
34
+ return name in self.params
35
+
36
+ def getParam(self, name: str) -> Any:
37
+ return self.params[name]
38
+
39
+ def setParam(self, name: str, value: Any):
40
+ self.params[name] = value
41
+
42
+ def addFileSet(self, fs : FileSet):
43
+ if "filesets" not in self.params:
44
+ self.params["filesets"] = []
45
+ self.params["filesets"].append(fs)
46
+
47
+ def getFileSets(self, type : (str|Set[str])=None) -> List[FileSet]:
48
+ ret = []
49
+
50
+ if "filesets" in self.params:
51
+ for fs in self.params["filesets"]:
52
+ if type is None or fs.type in type:
53
+ ret.append(fs)
54
+
55
+ return ret
56
+
57
+ def copy(self) -> 'TaskData':
58
+ ret = TaskData()
59
+ ret.task_id = self.task_id
60
+ ret.params = self.params.copy()
61
+ for d in self.deps:
62
+ ret.deps.append(d.clone())
63
+ ret.changed = self.changed
64
+ return ret
65
+
66
+ def merge(self, other):
67
+ for k,v in other.params.items():
68
+ if k not in self.params:
69
+ if hasattr(v, "copy"):
70
+ self.params[k] = v.copy()
71
+ else:
72
+ self.params[k] = v
73
+ elif hasattr(self.params[k], "merge"):
74
+ self.params[k].merge(v)
75
+ elif self.params[k] != v:
76
+ raise Exception("Parameter %s has conflicting values" % k)
77
+
@@ -0,0 +1,45 @@
1
+ #****************************************************************************
2
+ #* task_def.py
3
+ #*
4
+ #* Copyright 2023 Matthew Ballance and Contributors
5
+ #*
6
+ #* Licensed under the Apache License, Version 2.0 (the "License"); you may
7
+ #* not use this file except in compliance with the License.
8
+ #* You may obtain a copy of the License at:
9
+ #*
10
+ #* http://www.apache.org/licenses/LICENSE-2.0
11
+ #*
12
+ #* Unless required by applicable law or agreed to in writing, software
13
+ #* distributed under the License is distributed on an "AS IS" BASIS,
14
+ #* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ #* See the License for the specific language governing permissions and
16
+ #* limitations under the License.
17
+ #*
18
+ #* Created on:
19
+ #* Author:
20
+ #*
21
+ #****************************************************************************
22
+ import pydantic.dataclasses as dc
23
+ from pydantic import BaseModel
24
+ from typing import Any, Dict, List, Tuple
25
+ from .task import Task
26
+
27
+ @dc.dataclass
28
+ class TaskSpec(object):
29
+ name : str
30
+
31
+
32
+ class TaskDef(BaseModel):
33
+ """Holds definition information (ie the YAML view) for a task"""
34
+ name : str
35
+ type : (str|TaskSpec) = dc.Field(default_factory=list)
36
+ depends : List[(str|TaskSpec)] = dc.Field(default_factory=list)
37
+ params: Dict[str,Any] = dc.Field(default_factory=dict, alias="with")
38
+
39
+ def copy(self) -> 'TaskDef':
40
+ ret = TaskDef(
41
+ name=self.name,
42
+ type=self.type,
43
+ depends=self.depends.copy())
44
+ return ret
45
+
@@ -0,0 +1,34 @@
1
+ #****************************************************************************
2
+ #* task_memento.py
3
+ #*
4
+ #* Copyright 2023 Matthew Ballance and Contributors
5
+ #*
6
+ #* Licensed under the Apache License, Version 2.0 (the "License"); you may
7
+ #* not use this file except in compliance with the License.
8
+ #* You may obtain a copy of the License at:
9
+ #*
10
+ #* http://www.apache.org/licenses/LICENSE-2.0
11
+ #*
12
+ #* Unless required by applicable law or agreed to in writing, software
13
+ #* distributed under the License is distributed on an "AS IS" BASIS,
14
+ #* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ #* See the License for the specific language governing permissions and
16
+ #* limitations under the License.
17
+ #*
18
+ #* Created on:
19
+ #* Author:
20
+ #*
21
+ #****************************************************************************
22
+ import pydantic.dataclasses as dc
23
+ from pydantic import BaseModel
24
+ from typing import Any, Dict, List
25
+
26
+ class TaskMemento(BaseModel):
27
+ # dep_ids : List[int] = dc.Field(default_factory=list)
28
+ # params : Dict[str,Any] = dc.Field(default_factory=dict)
29
+
30
+ pass
31
+
32
+
33
+
34
+
@@ -0,0 +1,11 @@
1
+ import dataclasses as dc
2
+ from .pkg_hdl_sim import PackageHdlSim
3
+ from .mti_task_sim_image import TaskMtiSimImageCtor
4
+ from .mti_task_sim_run import TaskMtiSimRunCtor
5
+
6
+ @dc.dataclass
7
+ class MtiPackage(PackageHdlSim):
8
+ def __post_init__(self):
9
+ self.tasks["SimImage"] = TaskMtiSimImageCtor()
10
+ self.tasks["SimRun"] = TaskMtiSimRunCtor()
11
+
@@ -0,0 +1,69 @@
1
+ import os
2
+ import fnmatch
3
+ import dataclasses as dc
4
+ from ....fileset import FileSet
5
+ from ....package import TaskCtor
6
+ from ....task import Task, TaskParams, TaskCtorT
7
+ from ....task_data import TaskData
8
+ from ....task_memento import TaskMemento
9
+ from .vl_task_sim_image import VlTaskSimImage, VlTaskSimImageParams, VlTaskSimImageMemento
10
+ from typing import List, Tuple
11
+
12
+ from svdep import FileCollection, TaskCheckUpToDate, TaskBuildFileCollection
13
+
14
+ @dc.dataclass
15
+ class TaskMtiSimImage(VlTaskSimImage):
16
+
17
+ def getRefTime(self):
18
+ if os.path.isdir(os.path.join(self.rundir, 'work.d')):
19
+ return os.path.getmtime(os.path.join(self.rundir, 'work.d'))
20
+ else:
21
+ raise Exception("work.d not found")
22
+
23
+ async def build(self, files : List[str], incdirs : List[str]):
24
+ if not os.path.isdir(os.path.join(self.rundir, 'work')):
25
+ cmd = ['vlib', 'work']
26
+ proc = await self.session.create_subprocess(*cmd,
27
+ cwd=self.rundir)
28
+ await proc.wait()
29
+ if proc.returncode != 0:
30
+ raise Exception("Questa vlib failed")
31
+
32
+ cmd = ['vlog', '-sv']
33
+
34
+ for incdir in incdirs:
35
+ cmd.append('+incdir+%s' % incdir)
36
+
37
+ cmd.extend(files)
38
+
39
+ proc = await self.session.create_subprocess(*cmd,
40
+ cwd=self.rundir)
41
+ await proc.wait()
42
+ if proc.returncode != 0:
43
+ raise Exception("Questa compile failed")
44
+
45
+ cmd = ['vopt', '-o', 'simv_opt']
46
+
47
+ for top in self.params.top:
48
+ cmd.append(top)
49
+
50
+ proc = await self.session.create_subprocess(*cmd,
51
+ cwd=self.rundir)
52
+
53
+ await proc.wait()
54
+
55
+ with open(os.path.join(self.rundir, 'work.d'), "w") as fp:
56
+ pass
57
+
58
+ if proc.returncode != 0:
59
+ raise Exception("Questa opt failed")
60
+
61
+ class TaskMtiSimImageParams(VlTaskSimImageParams):
62
+ pass
63
+
64
+ class TaskMtiSimImageMemento(VlTaskSimImageMemento):
65
+ pass
66
+
67
+ class TaskMtiSimImageCtor(TaskCtorT):
68
+ def __init__(self):
69
+ super().__init__(TaskMtiSimImageParams, TaskMtiSimImage)
@@ -0,0 +1,47 @@
1
+ import os
2
+ import fnmatch
3
+ import pydantic.dataclasses as dc
4
+ from ....fileset import FileSet
5
+ from ....package import TaskCtor
6
+ from ....task import Task, TaskParams, TaskCtorT
7
+ from ....task_data import TaskData
8
+ from ....task_memento import TaskMemento
9
+ from typing import List, Tuple
10
+
11
+ class TaskMtiSimRun(Task):
12
+
13
+ async def run(self, input : TaskData) -> TaskData:
14
+ vl_fileset = input.getFileSets("verilatorBinary")
15
+
16
+ build_dir = vl_fileset[0].basedir
17
+
18
+ cmd = [
19
+ 'vsim', '-batch', '-do', 'run -all; quit -f',
20
+ '-work', os.path.join(build_dir, 'work'),
21
+ 'simv_opt'
22
+ ]
23
+
24
+ fp = open(os.path.join(self.rundir, 'sim.log'), "w")
25
+ proc = await self.session.create_subprocess(*cmd,
26
+ cwd=self.rundir,
27
+ stdout=fp)
28
+
29
+ await proc.wait()
30
+
31
+ fp.close()
32
+
33
+ output = TaskData()
34
+ output.addFileSet(FileSet(src=self.name, type="simRunDir", basedir=self.rundir))
35
+
36
+ return output
37
+
38
+ class TaskMtiSimRunParams(TaskParams):
39
+ pass
40
+
41
+ class TaskMtiSimRunMemento(TaskMemento):
42
+ pass
43
+
44
+ class TaskMtiSimRunCtor(TaskCtorT):
45
+ def __init__(self):
46
+ super().__init__(TaskMtiSimRunParams, TaskMtiSimRun)
47
+
@@ -0,0 +1,8 @@
1
+ import dataclasses as dc
2
+ from ....package import Package
3
+
4
+ @dc.dataclass
5
+ class PackageHdlSim(Package):
6
+ # TODO: parameter to select proper implementation
7
+ pass
8
+