zuspec-dataclasses 0.0.1.18247677360rc0__py3-none-any.whl → 0.0.1.18517051305rc0__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.
- zuspec/dataclasses/__init__.py +10 -18
- zuspec/dataclasses/__version__.py +1 -1
- zuspec/dataclasses/api/visitor.py +0 -5
- zuspec/dataclasses/decorators.py +61 -219
- zuspec/dataclasses/std/clock_reset.py +1 -2
- zuspec/dataclasses/std/timebase.py +1 -2
- zuspec/dataclasses/types.py +204 -0
- {zuspec_dataclasses-0.0.1.18247677360rc0.dist-info → zuspec_dataclasses-0.0.1.18517051305rc0.dist-info}/METADATA +1 -1
- zuspec_dataclasses-0.0.1.18517051305rc0.dist-info/RECORD +19 -0
- zuspec/dataclasses/action.py +0 -40
- zuspec/dataclasses/bit.py +0 -38
- zuspec/dataclasses/bundle.py +0 -49
- zuspec/dataclasses/component.py +0 -62
- zuspec/dataclasses/ports.py +0 -56
- zuspec/dataclasses/py.typed +0 -1
- zuspec/dataclasses/struct.py +0 -49
- zuspec/dataclasses/util/__init__.py +0 -0
- zuspec/dataclasses/util/extract_cpp_embedded_dsl.py +0 -197
- zuspec/dataclasses/util/gen_cpp_dt_defs/__main__.py +0 -102
- zuspec/impl/__init__.py +0 -1
- zuspec_dataclasses-0.0.1.18247677360rc0.dist-info/RECORD +0 -29
- {zuspec_dataclasses-0.0.1.18247677360rc0.dist-info → zuspec_dataclasses-0.0.1.18517051305rc0.dist-info}/WHEEL +0 -0
- {zuspec_dataclasses-0.0.1.18247677360rc0.dist-info → zuspec_dataclasses-0.0.1.18517051305rc0.dist-info}/licenses/LICENSE +0 -0
- {zuspec_dataclasses-0.0.1.18247677360rc0.dist-info → zuspec_dataclasses-0.0.1.18517051305rc0.dist-info}/top_level.txt +0 -0
zuspec/dataclasses/__init__.py
CHANGED
@@ -14,23 +14,15 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#****************************************************************************
|
16
16
|
# from .activity_stmts import *
|
17
|
-
from
|
18
|
-
from .
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
from . import api
|
26
|
-
from . import std
|
17
|
+
from asyncio import Event
|
18
|
+
from .decorators import (
|
19
|
+
dataclass, field, export, extern, mirror, process, input, output,
|
20
|
+
sync, const, port, export, bind, Exec, ExecKind, ExecSync,
|
21
|
+
Output, FSM, ExecState, fsm, binder
|
22
|
+
)
|
23
|
+
from .types import *
|
24
|
+
#from .tlm import *
|
27
25
|
|
28
|
-
from .
|
29
|
-
from .
|
30
|
-
from .std.clock_reset import ClockReset
|
31
|
-
from .component import Component
|
32
|
-
from .exec import ExecSync, Exec
|
33
|
-
from .struct import Struct, ZuspecTypeBase
|
34
|
-
from .ports import Input, Output, Port
|
26
|
+
#from . import api
|
27
|
+
#from . import std
|
35
28
|
|
36
|
-
from asyncio import Event
|
@@ -18,11 +18,6 @@ import logging
|
|
18
18
|
from dataclasses import Field, MISSING
|
19
19
|
from typing import Callable, ClassVar, Dict, Type, List, Tuple
|
20
20
|
from ..annotation import Annotation
|
21
|
-
from ..bit import Bit
|
22
|
-
from ..component import Component
|
23
|
-
from ..exec import Exec, ExecKind, ExecSync
|
24
|
-
from ..ports import Input, Output
|
25
|
-
from ..struct import Extern, Struct
|
26
21
|
import inspect
|
27
22
|
import ast
|
28
23
|
import textwrap
|
zuspec/dataclasses/decorators.py
CHANGED
@@ -19,9 +19,7 @@
|
|
19
19
|
import dataclasses
|
20
20
|
import dataclasses as dc
|
21
21
|
import enum
|
22
|
-
import
|
23
|
-
import typing
|
24
|
-
from typing import Any, Callable, Dict, Optional, Self, TypeVar, TYPE_CHECKING, Union
|
22
|
+
from typing import Any, Callable, Dict, Optional, Self, TypeVar, TYPE_CHECKING, Union, TypeVarTuple, Generic
|
25
23
|
from .annotation import Annotation, AnnotationSync
|
26
24
|
|
27
25
|
|
@@ -38,7 +36,7 @@ def dataclass(cls, **kwargs):
|
|
38
36
|
print("TODO: annotate field")
|
39
37
|
cls_annotations[name] = int
|
40
38
|
|
41
|
-
cls_t = dc.dataclass(cls, **kwargs)
|
39
|
+
cls_t = dc.dataclass(cls, kw_only=True, **kwargs)
|
42
40
|
|
43
41
|
setattr(cls_t, "__base_init__", getattr(cls_t, "__init__"))
|
44
42
|
def local_init(self, tp : 'TypeProcessor', *args, **kwargs):
|
@@ -53,7 +51,6 @@ def dataclass(cls, **kwargs):
|
|
53
51
|
return tp.new(c, *args, **kwargs)
|
54
52
|
setattr(cls_t, "__new__", local_new)
|
55
53
|
|
56
|
-
|
57
54
|
return cls_t
|
58
55
|
|
59
56
|
def bundle():
|
@@ -62,76 +59,28 @@ def bundle():
|
|
62
59
|
def mirror():
|
63
60
|
return dc.field()
|
64
61
|
|
65
|
-
|
66
|
-
|
67
|
-
def __getitem__(self, v) -> 'BitLiteral':
|
68
|
-
return self
|
69
|
-
pass
|
70
|
-
pass
|
62
|
+
def monitor():
|
63
|
+
return dc.field()
|
71
64
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
def
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
# unique case (instr_i[1:0])
|
87
|
-
# // C0
|
88
|
-
# 2'b00: begin
|
89
|
-
# unique case (instr_i[15:13])
|
90
|
-
# 3'b000: begin
|
91
|
-
# // c.addi4spn -> addi rd', x2, imm
|
92
|
-
# instr_o = {2'b0, instr_i[10:7], instr_i[12:11], instr_i[5],
|
93
|
-
# instr_i[6], 2'b00, 5'h02, 3'b000, 2'b01, instr_i[4:2], {OPCODE_OP_IMM}};
|
94
|
-
# if (instr_i[12:5] == 8'b0) illegal_instr_o = 1'b1;
|
95
|
-
# end
|
96
|
-
|
97
|
-
# 3'b010: begin
|
98
|
-
# // c.lw -> lw rd', imm(rs1')
|
99
|
-
# instr_o = {5'b0, instr_i[5], instr_i[12:10], instr_i[6],
|
100
|
-
# 2'b00, 2'b01, instr_i[9:7], 3'b010, 2'b01, instr_i[4:2], {OPCODE_LOAD}};
|
101
|
-
# end
|
102
|
-
|
103
|
-
# 3'b110: begin
|
104
|
-
# // c.sw -> sw rs2', imm(rs1')
|
105
|
-
# instr_o = {5'b0, instr_i[5], instr_i[12], 2'b01, instr_i[4:2],
|
106
|
-
# 2'b01, instr_i[9:7], 3'b010, instr_i[11:10], instr_i[6],
|
107
|
-
# 2'b00, {OPCODE_STORE}};
|
108
|
-
# end
|
109
|
-
|
110
|
-
# 3'b001,
|
111
|
-
# 3'b011,
|
112
|
-
# 3'b100,
|
113
|
-
# 3'b101,
|
114
|
-
# 3'b111: begin
|
115
|
-
# illegal_instr_o = 1'b1;
|
116
|
-
# end
|
117
|
-
|
118
|
-
# default: begin
|
119
|
-
# illegal_instr_o = 1'b1;
|
120
|
-
# end
|
121
|
-
# endcase
|
122
|
-
|
123
|
-
a = bit(20)[3:4]
|
124
|
-
|
125
|
-
SelfT = TypeVar('SelfT')
|
126
|
-
T = TypeVar('T')
|
127
|
-
|
128
|
-
class bind[T]:
|
129
|
-
def __init__(self, c : Callable[[T],Dict[Any,Any]]):
|
65
|
+
BindT = TypeVarTuple('BindT')
|
66
|
+
|
67
|
+
#class bind(Generic[*BindT]):
|
68
|
+
# """Helper class for specifying binds. Ensures that the parameter
|
69
|
+
# passed to the lambda is identified as the class type
|
70
|
+
# """
|
71
|
+
# def __init__(self, c : Callable[[*BindT],Dict[Any,Any]]):
|
72
|
+
# self._c = c
|
73
|
+
|
74
|
+
class bind[Ts,Ti]:
|
75
|
+
"""Helper class for specifying binds. Ensures that the parameter
|
76
|
+
passed to the lambda is identified as the class type.
|
77
|
+
"""
|
78
|
+
def __init__(self, c : Callable[[Ts,Ti],Dict[Any,Any]]):
|
130
79
|
self._c = c
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
80
|
+
|
81
|
+
class binder(object):
|
82
|
+
def __init__(self, c : Callable):
|
83
|
+
pass
|
135
84
|
|
136
85
|
def field(
|
137
86
|
rand=False,
|
@@ -189,9 +138,13 @@ def field(
|
|
189
138
|
# # TODO:
|
190
139
|
# return dc.field()
|
191
140
|
|
192
|
-
class Input(object):
|
141
|
+
class Input(object):
|
142
|
+
"""Marker type for 'input' dataclass fields"""
|
143
|
+
...
|
193
144
|
|
194
|
-
class Output(object):
|
145
|
+
class Output(object):
|
146
|
+
"""Marker type for 'output' dataclass fields"""
|
147
|
+
...
|
195
148
|
|
196
149
|
def input(*args, **kwargs):
|
197
150
|
"""
|
@@ -231,9 +184,9 @@ class ExecKind(enum.Enum):
|
|
231
184
|
@dc.dataclass
|
232
185
|
class Exec(object):
|
233
186
|
method : Callable = dc.field()
|
234
|
-
kind : ExecKind = dc.field()
|
235
|
-
timebase : Optional[Callable] = field(default=None)
|
236
|
-
t : Optional[Callable] = field(default=None)
|
187
|
+
# kind : ExecKind = dc.field()
|
188
|
+
# timebase : Optional[Callable] = field(default=None)
|
189
|
+
# t : Optional[Callable] = field(default=None)
|
237
190
|
|
238
191
|
def extern(
|
239
192
|
typename,
|
@@ -251,12 +204,14 @@ def extern(
|
|
251
204
|
files=files,
|
252
205
|
params=params))
|
253
206
|
|
207
|
+
class ExecProc(Exec): pass
|
208
|
+
|
254
209
|
def process(T):
|
255
210
|
"""
|
256
211
|
Marks an always-running process. The specified
|
257
212
|
method must be `async` and take no arguments
|
258
213
|
"""
|
259
|
-
return
|
214
|
+
return ExecProc(T)
|
260
215
|
|
261
216
|
def reg(offset=0):
|
262
217
|
return dc.field()
|
@@ -293,7 +248,7 @@ def sync(clock : Callable, reset : Callable):
|
|
293
248
|
each time _update is evaluated.
|
294
249
|
"""
|
295
250
|
def __call__(T):
|
296
|
-
return ExecSync(method=T,
|
251
|
+
return ExecSync(method=T, clock=clock, reset=reset)
|
297
252
|
return __call__
|
298
253
|
|
299
254
|
def comb(latch : bool=False):
|
@@ -305,147 +260,34 @@ def comb(latch : bool=False):
|
|
305
260
|
return Exec(method=T, kind=ExecKind.Comb, )
|
306
261
|
return __call__
|
307
262
|
|
263
|
+
@dc.dataclass
|
264
|
+
class ExecState(Exec): pass
|
265
|
+
|
266
|
+
class FSM(object):
|
267
|
+
"""Declares a method-based FSM"""
|
268
|
+
state : ExecState = field(default_factory=ExecState)
|
269
|
+
|
270
|
+
class fsm(object):
|
271
|
+
|
272
|
+
def __new__(cls,
|
273
|
+
initial : ExecState,
|
274
|
+
clock : Optional[Callable] = None,
|
275
|
+
reset : Optional[Callable] = None) -> dc.Field:
|
276
|
+
"""Defines the parameters of an FSM field"""
|
277
|
+
return dc.field(
|
278
|
+
metadata=dict(initial=initial, clock=clock, reset=reset),
|
279
|
+
default_factory=FSM)
|
280
|
+
|
281
|
+
@staticmethod
|
282
|
+
def state(T):
|
283
|
+
"""Decorates an FSM state method. A state method is automatically
|
284
|
+
invoked on an active clock edge when the state machine that this
|
285
|
+
method is a member of is in the appropriate state. FSM state
|
286
|
+
methods are non-blocking assignment regions just like sync exec blocks.
|
287
|
+
State methods cannot be called directly"""
|
288
|
+
return ExecState(method=T)
|
308
289
|
|
309
|
-
# def action(*args, **kwargs):
|
310
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
311
|
-
# # No-argument form
|
312
|
-
# return ActionDecoratorImpl([], {})(args[0])
|
313
|
-
# else:
|
314
|
-
# # Argument form
|
315
|
-
# return ActionDecoratorImpl(args, kwargs)
|
316
|
-
|
317
|
-
# def activity(*args, **kwargs):
|
318
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
319
|
-
# # No-argument form
|
320
|
-
# return ActivityDecoratorImpl([], {})(args[0])
|
321
|
-
# else:
|
322
|
-
# return ActivityDecoratorImpl(args, kwargs)
|
323
|
-
|
324
|
-
# def component(*args, **kwargs):
|
325
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
326
|
-
# # No-argument form
|
327
|
-
# return ComponentDecoratorImpl([], {})(args[0])
|
328
|
-
# else:
|
329
|
-
# return ComponentDecoratorImpl(args, kwargs)
|
330
290
|
|
331
291
|
def constraint(T):
|
332
292
|
setattr(T, "__constraint__", True)
|
333
293
|
return T
|
334
|
-
|
335
|
-
# def constraint(*args, **kwargs):
|
336
|
-
# # if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
337
|
-
# # # No-argument form
|
338
|
-
# # return ConstraintDecoratorImpl({})(args[0])
|
339
|
-
# # else:
|
340
|
-
# # return ConstraintDecoratorImpl(kwargs)
|
341
|
-
|
342
|
-
# def buffer(*args, **kwargs):
|
343
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
344
|
-
# # No-argument form
|
345
|
-
# return StructDecoratorImpl(StructKindE.Buffer, [], {})(args[0])
|
346
|
-
# else:
|
347
|
-
# return ActionDecoratorImpl(StructKindE.Buffer, args, kwargs)
|
348
|
-
|
349
|
-
# def resource(*args, **kwargs):
|
350
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
351
|
-
# # No-argument form
|
352
|
-
# return StructDecoratorImpl(StructKindE.Resource, [], {})(args[0])
|
353
|
-
# else:
|
354
|
-
# return StructDecoratorImpl(StructKindE.Resource, [], kwargs)
|
355
|
-
|
356
|
-
# def state(*args, **kwargs):
|
357
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
358
|
-
# # No-argument form
|
359
|
-
# return StructDecoratorImpl(StructKindE.State, {})(args[0])
|
360
|
-
# else:
|
361
|
-
# return ActionDecoratorImpl(StructKindE.State, kwargs)
|
362
|
-
|
363
|
-
# def stream(*args, **kwargs):
|
364
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
365
|
-
# # No-argument form
|
366
|
-
# return StructDecoratorImpl(StructKindE.Stream, {})(args[0])
|
367
|
-
# else:
|
368
|
-
# return ActionDecoratorImpl(StructKindE.Stream, kwargs)
|
369
|
-
|
370
|
-
# def struct(*args, **kwargs):
|
371
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
372
|
-
# # No-argument form
|
373
|
-
# return StructDecoratorImpl(StructKindE.Struct, [], {})(args[0])
|
374
|
-
# else:
|
375
|
-
# return ActionDecoratorImpl(StructKindE.Struct, args, kwargs)
|
376
|
-
|
377
|
-
# class exec(object):
|
378
|
-
# @staticmethod
|
379
|
-
# def body(*args, **kwargs):
|
380
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
381
|
-
# # No-argument form
|
382
|
-
# return ExecDecoratorImpl(ExecKindE.Body, [], {})(args[0])
|
383
|
-
# else:
|
384
|
-
# return ExecDecoratorImpl(ExecKindE.Body, args, kwargs)
|
385
|
-
|
386
|
-
# @staticmethod
|
387
|
-
# def init_down(*args, **kwargs):
|
388
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
389
|
-
# # No-argument form
|
390
|
-
# return ExecDecoratorImpl(ExecKindE.InitDown, [], {})(args[0])
|
391
|
-
# else:
|
392
|
-
# return ExecDecoratorImpl(ExecKindE.InitDown, args, kwargs)
|
393
|
-
|
394
|
-
# @staticmethod
|
395
|
-
# def init_up(*args, **kwargs):
|
396
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
397
|
-
# # No-argument form
|
398
|
-
# return ExecDecoratorImpl(ExecKindE.InitUp, [], {})(args[0])
|
399
|
-
# else:
|
400
|
-
# return ExecDecoratorImpl(ExecKindE.InitUp, args, kwargs)
|
401
|
-
|
402
|
-
# @staticmethod
|
403
|
-
# def pre_solve(*args, **kwargs):
|
404
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
405
|
-
# # No-argument form
|
406
|
-
# return ExecDecoratorImpl(ExecKindE.PreSolve, [], {})(args[0])
|
407
|
-
# else:
|
408
|
-
# return ExecDecoratorImpl(ExecKindE.PreSolve, args, kwargs)
|
409
|
-
|
410
|
-
# @staticmethod
|
411
|
-
# def post_solve(*args, **kwargs):
|
412
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
413
|
-
# # No-argument form
|
414
|
-
# return ExecDecoratorImpl(ExecKindE.PostSolve, [], {})(args[0])
|
415
|
-
# else:
|
416
|
-
# return ExecDecoratorImpl(ExecKindE.PostSolve, args, kwargs)
|
417
|
-
|
418
|
-
# class extend(object):
|
419
|
-
# @staticmethod
|
420
|
-
# def action(target, *args, **kwargs):
|
421
|
-
# return ExtendActionDecoratorImpl(target, args, kwargs)
|
422
|
-
|
423
|
-
# @staticmethod
|
424
|
-
# def component(target, *args, **kwargs):
|
425
|
-
# return ExtendComponentDecoratorImpl(target, args, kwargs)
|
426
|
-
|
427
|
-
# class extern(object):
|
428
|
-
|
429
|
-
# # TODO:
|
430
|
-
# @staticmethod
|
431
|
-
# def action(*args, **kwargs):
|
432
|
-
# raise NotImplementedError("extern.action not implemented")
|
433
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
434
|
-
# # No-argument form
|
435
|
-
# return ExecDecoratorImpl(ExecKindE.PreSolve, {})(args[0])
|
436
|
-
# else:
|
437
|
-
# return ExecDecoratorImpl(ExecKindE.PreSolve, kwargs)
|
438
|
-
|
439
|
-
# def fn(*args, **kwargs):
|
440
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
441
|
-
# # No-argument form
|
442
|
-
# return FnDecoratorImpl(False, {})(args[0])
|
443
|
-
# else:
|
444
|
-
# return FnDecoratorImpl(False, kwargs)
|
445
|
-
|
446
|
-
# def import_fn(*args, **kwargs):
|
447
|
-
# if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
|
448
|
-
# # No-argument form
|
449
|
-
# return FnDecoratorImpl(True, {})(args[0])
|
450
|
-
# else:
|
451
|
-
# return FnDecoratorImpl(True, kwargs)
|
@@ -14,9 +14,8 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#****************************************************************************
|
16
16
|
import abc
|
17
|
-
from ..
|
17
|
+
from ..types import Bit, Component
|
18
18
|
from ..decorators import dataclass, field, output
|
19
|
-
from ..bit import Bit
|
20
19
|
|
21
20
|
@dataclass
|
22
21
|
class ClockReset(Component):
|
@@ -0,0 +1,204 @@
|
|
1
|
+
#****************************************************************************
|
2
|
+
# Copyright 2019-2025 Matthew Ballance and contributors
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#****************************************************************************
|
16
|
+
import abc
|
17
|
+
from typing import Dict, Generic, Optional, TypeVar, Literal, Type
|
18
|
+
from .decorators import dataclass, field
|
19
|
+
|
20
|
+
@dataclass
|
21
|
+
class TypeBase(object):
|
22
|
+
"""Marker for all Zuspec types"""
|
23
|
+
pass
|
24
|
+
|
25
|
+
class BitMeta(type):
|
26
|
+
"""
|
27
|
+
The BitMeta class is a constructor for Bit types.
|
28
|
+
Bit[12], for example, produces a Bit type where
|
29
|
+
W=12.
|
30
|
+
"""
|
31
|
+
|
32
|
+
def __new__(cls, name, bases, attrs):
|
33
|
+
return super().__new__(cls, name, bases, attrs)
|
34
|
+
|
35
|
+
def __init__(self, name, bases, attrs):
|
36
|
+
super().__init__(name, bases, attrs)
|
37
|
+
self.type_m : Dict = {}
|
38
|
+
|
39
|
+
def __getitem__(self, W : int):
|
40
|
+
if W in self.type_m.keys():
|
41
|
+
return self.type_m[W]
|
42
|
+
else:
|
43
|
+
t = type("bit[%d]" % W, (Bit,), {
|
44
|
+
"W" : W
|
45
|
+
})
|
46
|
+
self.type_m[W] = t
|
47
|
+
return t
|
48
|
+
|
49
|
+
# class BitLiteral(int):
|
50
|
+
# W : int = 1
|
51
|
+
|
52
|
+
# def __new__(cls, )
|
53
|
+
|
54
|
+
# def __getitem__(self, v) -> 'BitLiteral':
|
55
|
+
# return self
|
56
|
+
# pass
|
57
|
+
# pass
|
58
|
+
|
59
|
+
class Bit(int, metaclass=BitMeta):
|
60
|
+
"""
|
61
|
+
Variables of 'Bit' type represent unsigned W-bit values.
|
62
|
+
The value of the variables is automatically masked. For
|
63
|
+
example, assigning 20 (b10100) to a 4-bit variable will
|
64
|
+
result in 4 (b0100) being stored in the variable.
|
65
|
+
"""
|
66
|
+
W : int = 1
|
67
|
+
|
68
|
+
def __new__(cls, val : int=0):
|
69
|
+
return super(Bit, cls).__new__(cls, val)
|
70
|
+
|
71
|
+
class Bits(int, metaclass=BitMeta):
|
72
|
+
W : int = -1
|
73
|
+
|
74
|
+
def __new__(cls, val : int=0):
|
75
|
+
return super(Bits, cls).__new__(cls, val)
|
76
|
+
|
77
|
+
class IntMeta(type):
|
78
|
+
"""
|
79
|
+
The IntMeta class is a constructor for Int types.
|
80
|
+
Int[12], for example, produces a Int type where
|
81
|
+
W=12.
|
82
|
+
"""
|
83
|
+
|
84
|
+
def __new__(cls, name, bases, attrs):
|
85
|
+
return super().__new__(cls, name, bases, attrs)
|
86
|
+
|
87
|
+
def __init__(self, name, bases, attrs):
|
88
|
+
super().__init__(name, bases, attrs)
|
89
|
+
self.type_m : Dict = {}
|
90
|
+
|
91
|
+
def __getitem__(self, W : int):
|
92
|
+
if W in self.type_m.keys():
|
93
|
+
return self.type_m[W]
|
94
|
+
else:
|
95
|
+
t = type("bit[%d]" % W, (Bit,), {
|
96
|
+
"W" : W
|
97
|
+
})
|
98
|
+
self.type_m[W] = t
|
99
|
+
return t
|
100
|
+
|
101
|
+
class Int(TypeBase, metaclass=IntMeta):
|
102
|
+
"""
|
103
|
+
Variables of 'Int' type represent signed W-bit values.
|
104
|
+
The value of the variables is automatically masked. For
|
105
|
+
example, assigning 20 (b10100) to a 4-bit variable will
|
106
|
+
result in 4 (b0100) being stored in the variable. Note
|
107
|
+
that this may change the size of the variable.
|
108
|
+
"""
|
109
|
+
W : int = -1
|
110
|
+
|
111
|
+
@dataclass
|
112
|
+
class Bundle(TypeBase):
|
113
|
+
"""
|
114
|
+
A bundle type collects one or more ports, exports,
|
115
|
+
inputs, outputs, or bundles.
|
116
|
+
|
117
|
+
Bundle fields are created with field(). Bundle-mirror
|
118
|
+
fields are created with mirror() or field(mirror=True)
|
119
|
+
Bundle-monitor fields are created with monitor() or
|
120
|
+
field(monitor=True)
|
121
|
+
|
122
|
+
A bundle field can be connected to a mirror field.
|
123
|
+
A bundle monitor field can be connected to both a
|
124
|
+
bundle and a bundle mirror.
|
125
|
+
- Bundle
|
126
|
+
- Bundle Mirror
|
127
|
+
- Bundle Monitor (all are inputs / exports)
|
128
|
+
"""
|
129
|
+
pass
|
130
|
+
|
131
|
+
@dataclass
|
132
|
+
class StructPacked(TypeBase):
|
133
|
+
"""
|
134
|
+
StructPacked types are fixed-size data structures.
|
135
|
+
Fields may only be of a fixed size.
|
136
|
+
|
137
|
+
Valid sub-regions
|
138
|
+
- constraint
|
139
|
+
- pre_solve / post_solve
|
140
|
+
"""
|
141
|
+
pass
|
142
|
+
|
143
|
+
@dataclass
|
144
|
+
class Struct(TypeBase):
|
145
|
+
"""
|
146
|
+
Struct types are data structures that may contain
|
147
|
+
variable-size fields.
|
148
|
+
|
149
|
+
Valid sub-regions
|
150
|
+
- constraint
|
151
|
+
- pre_solve / post_solve
|
152
|
+
- method
|
153
|
+
"""
|
154
|
+
|
155
|
+
@dataclass
|
156
|
+
class Component(Struct):
|
157
|
+
"""
|
158
|
+
Component classes are structural in nature.
|
159
|
+
The lifecycle of a component tree is as follows:
|
160
|
+
- The root component and fields of component type are constructed
|
161
|
+
- The 'init_down' method is invoked in a depth-first manner
|
162
|
+
- The 'init_up' method is invoked
|
163
|
+
|
164
|
+
A Component class supports the following decorated methods:
|
165
|
+
- sync
|
166
|
+
- constraint
|
167
|
+
- activity
|
168
|
+
"""
|
169
|
+
|
170
|
+
def __bind__(self) -> Optional[Dict]: ...
|
171
|
+
|
172
|
+
@abc.abstractmethod
|
173
|
+
async def wait(self, amt : float, units : int = 0):
|
174
|
+
"""
|
175
|
+
Uses the default timebase to suspend execution of the
|
176
|
+
calling coroutine for the specified time.
|
177
|
+
"""
|
178
|
+
pass
|
179
|
+
|
180
|
+
CompT = TypeVar('CompT', bound=Component)
|
181
|
+
|
182
|
+
@dataclass
|
183
|
+
class ComponentExtern(Component):
|
184
|
+
"""
|
185
|
+
Extern components are used to interface with existing descriptions,
|
186
|
+
such as existing Verilog RTL.
|
187
|
+
"""
|
188
|
+
|
189
|
+
@dataclass
|
190
|
+
class Action[CompT](Struct):
|
191
|
+
"""
|
192
|
+
Action-derived types
|
193
|
+
|
194
|
+
Valid fields
|
195
|
+
- All Struct fields
|
196
|
+
- Input / Output fields of Buffer, Stream, and State types
|
197
|
+
- Lock / Share fields of Resource types
|
198
|
+
Valid sub-regions
|
199
|
+
- All Struct sub-regions
|
200
|
+
- activity
|
201
|
+
"""
|
202
|
+
comp : Type[CompT] = field()
|
203
|
+
|
204
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
zuspec/dataclasses/__init__.py,sha256=bWpgkedG2klldv4QG6_LlX0ysWBdtrwcWzcFEpmOXQk,1100
|
2
|
+
zuspec/dataclasses/__version__.py,sha256=YXHa4lcuY_JblUMJXjV69-R6oAZpC_gQsBPNCi1SG7o,829
|
3
|
+
zuspec/dataclasses/addr_reg.py,sha256=yKENXgCf9E5VEbfj0qCcJS-fwnQGdSaXG7t00aqA784,2759
|
4
|
+
zuspec/dataclasses/annotation.py,sha256=m_3h065RAR81skrq39wxsJ1V0BxpwiyAWzdTrvW51Gg,1086
|
5
|
+
zuspec/dataclasses/decorators.py,sha256=VLP2Rfw9nB-5fcsyrI_d-DQiF9P3y1_PGzc5ymAIF_o,8943
|
6
|
+
zuspec/dataclasses/dependency.py,sha256=LukfqqvTUfShrtYdidqZeVMie-l50oAzkpYqo_bqie0,1289
|
7
|
+
zuspec/dataclasses/tlm.py,sha256=sbAlnkYhVidinbiMKBT_mbe5yr1dDU9F_6aKBAXZjjE,431
|
8
|
+
zuspec/dataclasses/types.py,sha256=K-mRJ80vtppaqbZJTS4FUxm_F6pkXlJD0g_sEP-7W9s,5581
|
9
|
+
zuspec/dataclasses/api/__init__.py,sha256=UZY5lg-DjxtE0ixosJGpHFCBMshT8a0nZ8I0rIv75Ag,869
|
10
|
+
zuspec/dataclasses/api/type_processor.py,sha256=4VqIbj-Uo_DqNJpENSq8k5ll5TxhRFlLjq5Psi0Ss7I,956
|
11
|
+
zuspec/dataclasses/api/visitor.py,sha256=2XB19_xk2M0DQ5ZDCcrWSLiO-IVDlGr6LZizk1P4KxI,11682
|
12
|
+
zuspec/dataclasses/std/__init__.py,sha256=7xOZCDuEikfg5NRpC0eFGIvgj3hHz7ibtJawzroU4nY,839
|
13
|
+
zuspec/dataclasses/std/clock_reset.py,sha256=WzvcuaeVe1XI2u18puUZfHO73esSX7BHJ9XNTELVIqg,1184
|
14
|
+
zuspec/dataclasses/std/timebase.py,sha256=euNa9Jsu1xq31JPnyzUlkmXgsGtv_7rWfmN5sTL_6hs,1299
|
15
|
+
zuspec_dataclasses-0.0.1.18517051305rc0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
16
|
+
zuspec_dataclasses-0.0.1.18517051305rc0.dist-info/METADATA,sha256=gWcSF8r9r-m7dFi74hfyZWfr5nnUruoz8sJ-71QCRBY,121
|
17
|
+
zuspec_dataclasses-0.0.1.18517051305rc0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
18
|
+
zuspec_dataclasses-0.0.1.18517051305rc0.dist-info/top_level.txt,sha256=3WM_V5g1RvpI4_z1TPY_AmroKhWIp6QJo4Vz5Tqbgak,7
|
19
|
+
zuspec_dataclasses-0.0.1.18517051305rc0.dist-info/RECORD,,
|
zuspec/dataclasses/action.py
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
#****************************************************************************
|
2
|
-
# Copyright 2019-2025 Matthew Ballance and contributors
|
3
|
-
#
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
-
# you may not use this file except in compliance with the License.
|
6
|
-
# You may obtain a copy of the License at
|
7
|
-
#
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
-
#
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
-
# See the License for the specific language governing permissions and
|
14
|
-
# limitations under the License.
|
15
|
-
#****************************************************************************
|
16
|
-
from typing import Self, Type, TypeVar
|
17
|
-
from .decorators import dataclass, field
|
18
|
-
from .component import Component
|
19
|
-
from .struct import Struct
|
20
|
-
|
21
|
-
CompT = TypeVar('CompT', bound=Component)
|
22
|
-
|
23
|
-
@dataclass
|
24
|
-
class Action[CompT](Struct):
|
25
|
-
"""
|
26
|
-
Action-derived types
|
27
|
-
|
28
|
-
Valid fields
|
29
|
-
- All Struct fields
|
30
|
-
- Input / Output fields of Buffer, Stream, and State types
|
31
|
-
- Lock / Share fields of Resource types
|
32
|
-
Valid sub-regions
|
33
|
-
- All Struct sub-regions
|
34
|
-
- activity
|
35
|
-
"""
|
36
|
-
comp : Type[CompT] = field()
|
37
|
-
|
38
|
-
@dataclass
|
39
|
-
class MyAction(Action[Component]):
|
40
|
-
pass
|
zuspec/dataclasses/bit.py
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
import dataclasses as dc
|
2
|
-
from typing import Dict, Generic, TypeVar, Literal, Type
|
3
|
-
|
4
|
-
class BitMeta(type):
|
5
|
-
"""
|
6
|
-
The BitMeta class is a constructor for Bit types.
|
7
|
-
Bit[12], for example, produces a Bit type where
|
8
|
-
W=12.
|
9
|
-
"""
|
10
|
-
|
11
|
-
def __new__(cls, name, bases, attrs):
|
12
|
-
return super().__new__(cls, name, bases, attrs)
|
13
|
-
|
14
|
-
def __init__(self, name, bases, attrs):
|
15
|
-
super().__init__(name, bases, attrs)
|
16
|
-
self.type_m : Dict = {}
|
17
|
-
|
18
|
-
def __getitem__(self, W : int):
|
19
|
-
if W in self.type_m.keys():
|
20
|
-
return self.type_m[W]
|
21
|
-
else:
|
22
|
-
t = type("bit[%d]" % W, (Bit,), {
|
23
|
-
"W" : W
|
24
|
-
})
|
25
|
-
self.type_m[W] = t
|
26
|
-
return t
|
27
|
-
|
28
|
-
class Bit(metaclass=BitMeta):
|
29
|
-
"""
|
30
|
-
Variables of 'Bit' type represent unsigned W-bit values.
|
31
|
-
The value of the variables is automatically masked. For
|
32
|
-
example, assigning 20 (b10100) to a 4-bit variable will
|
33
|
-
result in 4 (b0100) being stored in the variable.
|
34
|
-
"""
|
35
|
-
W : int = 1
|
36
|
-
|
37
|
-
class Bits(metaclass=BitMeta):
|
38
|
-
W : int = -1
|
zuspec/dataclasses/bundle.py
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
#****************************************************************************
|
2
|
-
# Copyright 2019-2025 Matthew Ballance and contributors
|
3
|
-
#
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
-
# you may not use this file except in compliance with the License.
|
6
|
-
# You may obtain a copy of the License at
|
7
|
-
#
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
-
#
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
-
# See the License for the specific language governing permissions and
|
14
|
-
# limitations under the License.
|
15
|
-
#****************************************************************************
|
16
|
-
from typing import Annotated, Type, TypeVar
|
17
|
-
from .decorators import dataclass
|
18
|
-
|
19
|
-
@dataclass
|
20
|
-
class Bundle(object):
|
21
|
-
"""
|
22
|
-
A bundle type collects one or more ports, exports,
|
23
|
-
inputs, outputs, or bundles.
|
24
|
-
|
25
|
-
Bundle fields are created with field(). Bundle-mirror
|
26
|
-
fields are created with mirror() or field(mirror=True)
|
27
|
-
|
28
|
-
A bundle field can be connected to a mirror field.
|
29
|
-
A bundle monitor field can be connected to both a
|
30
|
-
bundle and a bundle mirror.
|
31
|
-
- Bundle
|
32
|
-
- Bundle Mirror
|
33
|
-
- Bundle Monitor (all are inputs / exports)
|
34
|
-
"""
|
35
|
-
pass
|
36
|
-
|
37
|
-
#BundleT=TypeVar('BundleT', bound=Bundle)
|
38
|
-
|
39
|
-
#class Mirror[BundleT](Annotated[Type[BundleT], "is mirror"]): pass
|
40
|
-
|
41
|
-
# class MirrorMeta[BundleT](type):
|
42
|
-
|
43
|
-
# def __getitem__(self, t : BundleT) -> BundleT:
|
44
|
-
# pass
|
45
|
-
|
46
|
-
# @dataclass
|
47
|
-
# class Mirror[BundleT](metaclass=MirrorMeta[BundleT]):
|
48
|
-
# pass
|
49
|
-
|
zuspec/dataclasses/component.py
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
#****************************************************************************
|
2
|
-
# Copyright 2019-2025 Matthew Ballance and contributors
|
3
|
-
#
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
-
# you may not use this file except in compliance with the License.
|
6
|
-
# You may obtain a copy of the License at
|
7
|
-
#
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
-
#
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
-
# See the License for the specific language governing permissions and
|
14
|
-
# limitations under the License.
|
15
|
-
#****************************************************************************
|
16
|
-
import abc
|
17
|
-
from typing import TYPE_CHECKING
|
18
|
-
from .decorators import dataclass, field
|
19
|
-
from .struct import Struct
|
20
|
-
|
21
|
-
if TYPE_CHECKING:
|
22
|
-
from .std.timebase import TimeBase
|
23
|
-
|
24
|
-
@dataclass
|
25
|
-
class Component(Struct):
|
26
|
-
"""
|
27
|
-
Component classes are structural in nature.
|
28
|
-
The lifecycle of a component tree is as follows:
|
29
|
-
- The root component and fields of component type are constructed
|
30
|
-
- The 'init_down' method is invoked in a depth-first manner
|
31
|
-
- The 'init_up' method is invoked
|
32
|
-
|
33
|
-
A Component class supports the following decorated methods:
|
34
|
-
- sync
|
35
|
-
- constraint
|
36
|
-
- activity
|
37
|
-
"""
|
38
|
-
# def build(self): pass
|
39
|
-
|
40
|
-
@abc.abstractmethod
|
41
|
-
async def wait(self, amt : float, units):
|
42
|
-
"""
|
43
|
-
Uses the default timebase to suspend execution of the
|
44
|
-
calling coroutine for the specified time.
|
45
|
-
"""
|
46
|
-
pass
|
47
|
-
|
48
|
-
@abc.abstractmethod
|
49
|
-
async def wait_next(self, count : int = 1):
|
50
|
-
"""
|
51
|
-
Uses the default timebase to suspend execution of the
|
52
|
-
calling coroutine for the specified number of domain
|
53
|
-
evaluation events (eg clock cycles).
|
54
|
-
"""
|
55
|
-
pass
|
56
|
-
|
57
|
-
@dataclass
|
58
|
-
class ComponentExtern(Component):
|
59
|
-
"""
|
60
|
-
Extern components are used to interface with existing descriptions,
|
61
|
-
such as existing Verilog RTL.
|
62
|
-
"""
|
zuspec/dataclasses/ports.py
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
import dataclasses as dc
|
2
|
-
from typing import ClassVar, Dict, Generic, Type
|
3
|
-
from abc import abstractmethod
|
4
|
-
|
5
|
-
|
6
|
-
class Port[T]():
|
7
|
-
|
8
|
-
@abstractmethod
|
9
|
-
def __call__(self) -> T:
|
10
|
-
pass
|
11
|
-
|
12
|
-
# # Bundle is a collection of ports/exports
|
13
|
-
# class WishboneI():
|
14
|
-
# valid : Output[bool]
|
15
|
-
# ready : Input[bool]
|
16
|
-
# pass
|
17
|
-
|
18
|
-
# class ReverseT(type):
|
19
|
-
# def __new__(cls, name, bases, attrs):
|
20
|
-
# return super().__new__(cls, name, bases, attrs)
|
21
|
-
|
22
|
-
# def __getitem__(self, T : type):
|
23
|
-
# pass
|
24
|
-
|
25
|
-
|
26
|
-
# class Reverse[T](metaclass=ReverseT):
|
27
|
-
|
28
|
-
# def __class_getitem__(cls):
|
29
|
-
# pass
|
30
|
-
|
31
|
-
# pass
|
32
|
-
|
33
|
-
# WishboneIM=Reverse[WishboneI]
|
34
|
-
|
35
|
-
# class Api[T](ABC):
|
36
|
-
|
37
|
-
# @abstractmethod
|
38
|
-
# def put(self, val : T):
|
39
|
-
# pass
|
40
|
-
|
41
|
-
# @abstractmethod
|
42
|
-
# def get(self) -> T:
|
43
|
-
# pass
|
44
|
-
|
45
|
-
# class MyModule:
|
46
|
-
# init_o : Port[WishboneI]
|
47
|
-
# dat_o : Port[Api[int]]
|
48
|
-
|
49
|
-
# def doit(self):
|
50
|
-
# self.init_o().ready = 1
|
51
|
-
# if self.init_o().valid:
|
52
|
-
# pass
|
53
|
-
|
54
|
-
# a = self.dat_o().get()
|
55
|
-
# self.dat_o().put(5)
|
56
|
-
|
zuspec/dataclasses/py.typed
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
|
zuspec/dataclasses/struct.py
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
import abc
|
2
|
-
from typing import Dict, Optional, Type
|
3
|
-
from .decorators import dataclass
|
4
|
-
|
5
|
-
@dataclass
|
6
|
-
class ZuspecTypeBase(object):
|
7
|
-
pass
|
8
|
-
|
9
|
-
@dataclass
|
10
|
-
class StructPacked(ZuspecTypeBase):
|
11
|
-
"""
|
12
|
-
StructPacked types are fixed-size data structures.
|
13
|
-
Fields may only be of a fixed size.
|
14
|
-
|
15
|
-
Valid sub-regions
|
16
|
-
- constraint
|
17
|
-
- pre_solve / post_solve
|
18
|
-
"""
|
19
|
-
pass
|
20
|
-
|
21
|
-
@dataclass
|
22
|
-
class Struct(ZuspecTypeBase):
|
23
|
-
"""
|
24
|
-
Struct types are data structures that may contain
|
25
|
-
variable-size fields.
|
26
|
-
|
27
|
-
Valid sub-regions
|
28
|
-
- constraint
|
29
|
-
- pre_solve / post_solve
|
30
|
-
- method
|
31
|
-
"""
|
32
|
-
|
33
|
-
|
34
|
-
# @abc.abstractmethod
|
35
|
-
# def bind[T](self, t : T):
|
36
|
-
# t : Type[T],
|
37
|
-
# init : Optional[Dict]=None,
|
38
|
-
# bind : Optional[Dict]=None) -> T:
|
39
|
-
# """
|
40
|
-
# Public API
|
41
|
-
# Applies service Creates a new instance of the specified class.
|
42
|
-
# - Resolves service claims relative to the context
|
43
|
-
# object and any bind specifications.
|
44
|
-
# """
|
45
|
-
# pass
|
46
|
-
|
47
|
-
pass
|
48
|
-
|
49
|
-
class Extern(ZuspecTypeBase): pass
|
File without changes
|
@@ -1,197 +0,0 @@
|
|
1
|
-
#****************************************************************************
|
2
|
-
#* extract_cpp_embedded_dsl.py
|
3
|
-
#*
|
4
|
-
#* Copyright 2022 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
|
-
from typing import List
|
23
|
-
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# ZSP_DATACLASSES(TestSuite_testname, RootComp, RootAction, R"(
|
27
|
-
# @vdc.randclass
|
28
|
-
# class MyC(object):
|
29
|
-
# a : vdc.rand_uint32_t
|
30
|
-
# )")
|
31
|
-
#
|
32
|
-
#
|
33
|
-
|
34
|
-
class DSLContent(object):
|
35
|
-
def __init__(self,
|
36
|
-
name,
|
37
|
-
root_comp,
|
38
|
-
root_action,
|
39
|
-
content):
|
40
|
-
self.name = name
|
41
|
-
self.root_comp = root_comp
|
42
|
-
self.root_action = root_action
|
43
|
-
self.content = content
|
44
|
-
|
45
|
-
class ExtractCppEmbeddedDSL(object):
|
46
|
-
|
47
|
-
def __init__(self,
|
48
|
-
file_or_fp,
|
49
|
-
name=None,
|
50
|
-
macro_name="ZSP_DATACLASSES"):
|
51
|
-
self._macro_name = macro_name
|
52
|
-
if hasattr(file_or_fp, "read"):
|
53
|
-
# This is a stream-like object
|
54
|
-
self._fp = file_or_fp
|
55
|
-
if name is None:
|
56
|
-
self._name = self._fp.name()
|
57
|
-
else:
|
58
|
-
self._fp = open(file_or_fp, "r")
|
59
|
-
self._name = file_or_fp
|
60
|
-
|
61
|
-
self._lineno = 0
|
62
|
-
self._unget_ch = None
|
63
|
-
self._last_ch = None
|
64
|
-
self._buffer = ""
|
65
|
-
self._buffer_i = 0
|
66
|
-
|
67
|
-
def extract(self) -> List[DSLContent]:
|
68
|
-
ret = []
|
69
|
-
|
70
|
-
while self.find_macro():
|
71
|
-
|
72
|
-
lineno = self._lineno
|
73
|
-
while True:
|
74
|
-
ch = self.getch()
|
75
|
-
|
76
|
-
if ch is None or ch == '(':
|
77
|
-
break
|
78
|
-
|
79
|
-
if ch is None:
|
80
|
-
raise Exception("Failed to parse embedded DSL @ %s:%d" % (self._name, self._lineno))
|
81
|
-
|
82
|
-
# Now, collect the complete content of the macro
|
83
|
-
content = ""
|
84
|
-
count_b = 1
|
85
|
-
while count_b > 0:
|
86
|
-
ch = self.getch()
|
87
|
-
|
88
|
-
if ch is None:
|
89
|
-
break
|
90
|
-
content += ch
|
91
|
-
|
92
|
-
if ch == '(':
|
93
|
-
count_b += 1
|
94
|
-
elif ch == ')':
|
95
|
-
count_b -= 1
|
96
|
-
|
97
|
-
if count_b > 0:
|
98
|
-
raise Exception("Unbalanced parens")
|
99
|
-
content = content[:-2]
|
100
|
-
|
101
|
-
# We now have text from a macro invocation
|
102
|
-
start = 0
|
103
|
-
count_b = 0
|
104
|
-
params = []
|
105
|
-
|
106
|
-
for i in range(len(content)):
|
107
|
-
if content[i] == "," and count_b == 0:
|
108
|
-
params.append(content[start:i].strip())
|
109
|
-
start = i+1
|
110
|
-
elif content[i] == '(':
|
111
|
-
count_b += 1
|
112
|
-
elif content[i] == ')':
|
113
|
-
count_b -= 1
|
114
|
-
|
115
|
-
if count_b != 0:
|
116
|
-
raise Exception("Unbalanced parens while tokenizing")
|
117
|
-
|
118
|
-
if start < len(content):
|
119
|
-
params.append(content[start:].strip())
|
120
|
-
|
121
|
-
if len(params) != 4:
|
122
|
-
raise Exception("Expected 3 params; received %d" % len(params))
|
123
|
-
|
124
|
-
if params[-1].startswith('R"('):
|
125
|
-
params[-1] = params[-1][3:-2]
|
126
|
-
|
127
|
-
content = params[-1].split("\n")
|
128
|
-
min_ws = 10000
|
129
|
-
|
130
|
-
for l in content:
|
131
|
-
l_strip = l.strip()
|
132
|
-
if l_strip != "":
|
133
|
-
ws_l = len(l) - len(l_strip)
|
134
|
-
if ws_l < min_ws:
|
135
|
-
min_ws = ws_l
|
136
|
-
|
137
|
-
for i in range(len(content)):
|
138
|
-
content[i] = content[i][min_ws:]
|
139
|
-
|
140
|
-
vsc_content = "\n".join(content)
|
141
|
-
|
142
|
-
root_comp = params[1]
|
143
|
-
root_action = params[2]
|
144
|
-
|
145
|
-
info = DSLContent(params[0], root_comp, root_action, vsc_content)
|
146
|
-
ret.append(info)
|
147
|
-
|
148
|
-
self._fp.close()
|
149
|
-
return ret
|
150
|
-
|
151
|
-
def find_macro(self):
|
152
|
-
|
153
|
-
while True:
|
154
|
-
line = self._fp.readline()
|
155
|
-
self._lineno += 1
|
156
|
-
|
157
|
-
if line == "":
|
158
|
-
break
|
159
|
-
|
160
|
-
idx = line.find(self._macro_name)
|
161
|
-
|
162
|
-
if idx >= 0:
|
163
|
-
self._buffer = line
|
164
|
-
self._buffer_i = idx + len(self._macro_name)
|
165
|
-
return True
|
166
|
-
|
167
|
-
return False
|
168
|
-
|
169
|
-
def getch(self):
|
170
|
-
if self._buffer is None:
|
171
|
-
return None
|
172
|
-
|
173
|
-
if self._buffer_i >= len(self._buffer):
|
174
|
-
try:
|
175
|
-
self._buffer = self._fp.readline()
|
176
|
-
self._buffer_i = 0
|
177
|
-
self._lineno += 1
|
178
|
-
if self._buffer == "":
|
179
|
-
self._buffer = None
|
180
|
-
return None
|
181
|
-
except Exception:
|
182
|
-
self._buffer = None
|
183
|
-
return None
|
184
|
-
|
185
|
-
ret = self._buffer[self._buffer_i]
|
186
|
-
self._buffer_i += 1
|
187
|
-
return ret
|
188
|
-
|
189
|
-
def ungetch(self, ch):
|
190
|
-
if self._buffer is None:
|
191
|
-
self._buffer = ch
|
192
|
-
elif self._buffer_i > 0:
|
193
|
-
self._buffer_i -= 1
|
194
|
-
self._buffer[self._buffer_i] = ch
|
195
|
-
else:
|
196
|
-
self._buffer.insert(0, ch)
|
197
|
-
|
@@ -1,102 +0,0 @@
|
|
1
|
-
#****************************************************************************
|
2
|
-
#* __main__.py
|
3
|
-
#*
|
4
|
-
#* zsp_dataclasses.util.gen_cpp_dt_defs
|
5
|
-
#*
|
6
|
-
#* Copyright 2022 Matthew Ballance and Contributors
|
7
|
-
#*
|
8
|
-
#* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
9
|
-
#* not use this file except in compliance with the License.
|
10
|
-
#* You may obtain a copy of the License at:
|
11
|
-
#*
|
12
|
-
#* http://www.apache.org/licenses/LICENSE-2.0
|
13
|
-
#*
|
14
|
-
#* Unless required by applicable law or agreed to in writing, software
|
15
|
-
#* distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
-
#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
-
#* See the License for the specific language governing permissions and
|
18
|
-
#* limitations under the License.
|
19
|
-
#*
|
20
|
-
#* Created on:
|
21
|
-
#* Author:
|
22
|
-
#*
|
23
|
-
#****************************************************************************
|
24
|
-
|
25
|
-
import argparse
|
26
|
-
import os
|
27
|
-
import zuspec as zdc
|
28
|
-
from zuspec.impl.ctor import Ctor
|
29
|
-
from zuspec.impl.pyctxt.context import Context
|
30
|
-
from zuspec.impl.generators.zsp_data_model_cpp_gen import ZspDataModelCppGen
|
31
|
-
from ..extract_cpp_embedded_dsl import ExtractCppEmbeddedDSL
|
32
|
-
|
33
|
-
def get_parser():
|
34
|
-
parser = argparse.ArgumentParser()
|
35
|
-
parser.add_argument("-o","--outdir", default="zspdefs",
|
36
|
-
help="Specifies the output directory")
|
37
|
-
parser.add_argument("-d", "--depfile",
|
38
|
-
help="Specifies a dependency file")
|
39
|
-
parser.add_argument("files", nargs='+')
|
40
|
-
|
41
|
-
return parser
|
42
|
-
|
43
|
-
def main():
|
44
|
-
parser = get_parser()
|
45
|
-
args = parser.parse_args()
|
46
|
-
|
47
|
-
deps_ts = None
|
48
|
-
if args.depfile is not None and os.path.isfile(args.depfile):
|
49
|
-
deps_ts = os.path.getmtime(args.depfile)
|
50
|
-
|
51
|
-
fragment_m = {}
|
52
|
-
for file in args.files:
|
53
|
-
print("Process %s" % file)
|
54
|
-
if deps_ts is not None:
|
55
|
-
file_ts = os.path.getmtime(file)
|
56
|
-
if file_ts <= deps_ts:
|
57
|
-
print("Skip due to deps")
|
58
|
-
continue
|
59
|
-
|
60
|
-
fragments = ExtractCppEmbeddedDSL(file).extract()
|
61
|
-
print("fragments: %s" % str(fragments))
|
62
|
-
|
63
|
-
for f in fragments:
|
64
|
-
if f.name in fragment_m.keys():
|
65
|
-
raise Exception("Duplicate fragment-name %s" % f.name)
|
66
|
-
fragment_m[f.name] = f
|
67
|
-
|
68
|
-
if not os.path.isdir(args.outdir):
|
69
|
-
os.makedirs(args.outdir, exist_ok=True)
|
70
|
-
|
71
|
-
for fn in fragment_m.keys():
|
72
|
-
Ctor.init(Context())
|
73
|
-
|
74
|
-
print("--> Process Fragment %s" % fn)
|
75
|
-
_globals = globals().copy()
|
76
|
-
exec(fragment_m[fn].content, _globals)
|
77
|
-
print("<-- Process Fragment %s" % fn)
|
78
|
-
|
79
|
-
Ctor.inst().elab()
|
80
|
-
|
81
|
-
header_path = os.path.join(args.outdir, "%s.h" % fn)
|
82
|
-
root_comp = Ctor.inst().ctxt().findDataTypeComponent(fragment_m[fn].root_comp)
|
83
|
-
if root_comp is None:
|
84
|
-
raise Exception("Failed to find root component %s" % fragment_m[fn].root_comp)
|
85
|
-
root_action = Ctor.inst().ctxt().findDataTypeAction(fragment_m[fn].root_action)
|
86
|
-
if root_action is None:
|
87
|
-
raise Exception("Failed to find root action %s" % fragment_m[fn].root_action)
|
88
|
-
gen = ZspDataModelCppGen()
|
89
|
-
gen._ctxt = "m_ctxt"
|
90
|
-
with open(header_path, "w") as fp:
|
91
|
-
fp.write(gen.generate(
|
92
|
-
root_comp,
|
93
|
-
root_action,
|
94
|
-
Ctor.inst().ctxt().getDataTypeFunctions()))
|
95
|
-
|
96
|
-
if args.depfile is not None:
|
97
|
-
with open(args.depfile, "w") as fp:
|
98
|
-
fp.write("\n")
|
99
|
-
|
100
|
-
if __name__ == "__main__":
|
101
|
-
main()
|
102
|
-
|
zuspec/impl/__init__.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
# Package marker for zuspec.impl
|
@@ -1,29 +0,0 @@
|
|
1
|
-
zuspec/dataclasses/__init__.py,sha256=WSYClXn7Bugmg6tHtQpENpZpW7Lphful7VPJ0kXEv2I,1369
|
2
|
-
zuspec/dataclasses/__version__.py,sha256=qpoQf4-C62LT9mSY4ODlfF-aPnPyWJ9VfJeyX8-6SeM,829
|
3
|
-
zuspec/dataclasses/action.py,sha256=12n8lihUhX0BFPcW370IlPgyEXLUMDSDQ_h_-rZr7ik,1328
|
4
|
-
zuspec/dataclasses/addr_reg.py,sha256=yKENXgCf9E5VEbfj0qCcJS-fwnQGdSaXG7t00aqA784,2759
|
5
|
-
zuspec/dataclasses/annotation.py,sha256=m_3h065RAR81skrq39wxsJ1V0BxpwiyAWzdTrvW51Gg,1086
|
6
|
-
zuspec/dataclasses/bit.py,sha256=qBTt8mj_S4WK6VeRaaqeNzzuvy3P12WigKaeU2Gr0mw,1072
|
7
|
-
zuspec/dataclasses/bundle.py,sha256=YIuEQS_4oS3LWQ3Zv3Ib78L6V6QzhDsd2S89BP0dsl8,1626
|
8
|
-
zuspec/dataclasses/component.py,sha256=yXSmg87uj_1TaazO99mLv72Z0lAlzzQiBTmn0wI5alo,2056
|
9
|
-
zuspec/dataclasses/decorators.py,sha256=A8vqoenJ8XkhMLZm7JcKw6BCC9uTG8lQIVh9XtPuvTQ,14528
|
10
|
-
zuspec/dataclasses/dependency.py,sha256=LukfqqvTUfShrtYdidqZeVMie-l50oAzkpYqo_bqie0,1289
|
11
|
-
zuspec/dataclasses/ports.py,sha256=OydeAfPIAef8pCp_3FhL87fq7mrbhiNLa9qfPHkCK1E,1044
|
12
|
-
zuspec/dataclasses/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
13
|
-
zuspec/dataclasses/struct.py,sha256=_7Lgf2BbF_WQXSpdKmowR6mATBjqZtqK6VoPPc1tdLg,1077
|
14
|
-
zuspec/dataclasses/tlm.py,sha256=sbAlnkYhVidinbiMKBT_mbe5yr1dDU9F_6aKBAXZjjE,431
|
15
|
-
zuspec/dataclasses/api/__init__.py,sha256=UZY5lg-DjxtE0ixosJGpHFCBMshT8a0nZ8I0rIv75Ag,869
|
16
|
-
zuspec/dataclasses/api/type_processor.py,sha256=4VqIbj-Uo_DqNJpENSq8k5ll5TxhRFlLjq5Psi0Ss7I,956
|
17
|
-
zuspec/dataclasses/api/visitor.py,sha256=CduJ6k11xY81_nFl8k0dVSRJt88a21mHem64Yeg6sDI,11852
|
18
|
-
zuspec/dataclasses/std/__init__.py,sha256=7xOZCDuEikfg5NRpC0eFGIvgj3hHz7ibtJawzroU4nY,839
|
19
|
-
zuspec/dataclasses/std/clock_reset.py,sha256=AveFnqB-OAgWfVr2eA7v9XfAPuE12WtQpSbbE1zhwME,1205
|
20
|
-
zuspec/dataclasses/std/timebase.py,sha256=v-GIdpVP_hIAGt3-oC-PikQQmYCG5ODTCu7syIzQNjE,1320
|
21
|
-
zuspec/dataclasses/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
-
zuspec/dataclasses/util/extract_cpp_embedded_dsl.py,sha256=SyMMLumZD6fsubj40hyekYzWyrcoUGTijJH3NmK1ihY,5630
|
23
|
-
zuspec/dataclasses/util/gen_cpp_dt_defs/__main__.py,sha256=t3CnHJKcN_N33sxCsDH-R36ghCcQ7xjMcjUrzUT2SGM,3447
|
24
|
-
zuspec/impl/__init__.py,sha256=GZWCeBPdVzLR0RNPkmXNXPgdS-2vg5dMC1goTYJs3yI,33
|
25
|
-
zuspec_dataclasses-0.0.1.18247677360rc0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
26
|
-
zuspec_dataclasses-0.0.1.18247677360rc0.dist-info/METADATA,sha256=8xpE3C-I2pfZniWyfIMjdqjqu8N7raPMZEE8WliWlA0,121
|
27
|
-
zuspec_dataclasses-0.0.1.18247677360rc0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
28
|
-
zuspec_dataclasses-0.0.1.18247677360rc0.dist-info/top_level.txt,sha256=3WM_V5g1RvpI4_z1TPY_AmroKhWIp6QJo4Vz5Tqbgak,7
|
29
|
-
zuspec_dataclasses-0.0.1.18247677360rc0.dist-info/RECORD,,
|
File without changes
|
File without changes
|