zuspec-dataclasses 0.0.1.17516204125rc0__py3-none-any.whl → 0.0.1.18247420852rc0__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.
@@ -1,7 +1,20 @@
1
-
2
-
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
+ #****************************************************************************
3
16
  # from .activity_stmts import *
4
- from .decorators import dataclass, field, export, process, input, output, sync, const, port, export, bind
17
+ from .decorators import dataclass, field, export, extern, process, input, output, sync, const, port, export, bind
5
18
  from .tlm import *
6
19
  # from .claims_refs import *
7
20
  # from .shared_stmts import *
@@ -9,9 +22,15 @@ from .tlm import *
9
22
  # from .core_lib import *
10
23
  # from vsc_dataclasses.expr import *
11
24
 
12
- from .bit import Bit, uint64_t
25
+ from . import api
26
+ from . import std
27
+
28
+ from .bit import Bit
29
+ from .action import Action
30
+ from .std.clock_reset import ClockReset
13
31
  from .component import Component
14
- from .struct import Struct
32
+ from .exec import ExecSync, Exec
33
+ from .struct import Struct, ZuspecTypeBase
15
34
  from .ports import Input, Output, Port
16
35
 
17
36
  from asyncio import Event
@@ -1,4 +1,19 @@
1
1
 
2
+ #****************************************************************************
3
+ # Copyright 2019-2025 Matthew Ballance and contributors
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #****************************************************************************
2
17
  BASE="0.0.1"
3
- SUFFIX=".17516204125rc0"
18
+ SUFFIX=".18247420852rc0"
4
19
  VERSION="%s%s" % (BASE, SUFFIX)
@@ -1,3 +1,18 @@
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
+ #****************************************************************************
1
16
  from typing import Self, Type, TypeVar
2
17
  from .decorators import dataclass, field
3
18
  from .component import Component
@@ -1,8 +1,21 @@
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
+ #****************************************************************************
1
16
  import abc
2
17
  import zuspec.dataclasses as zdc
3
- from typing import Annotated, TypeVar, Type, Union
4
- from .bit import BitVal
5
- from .decorators import dataclass, constraint
18
+ from typing import Annotated, Dict, TypeVar, Type, Union
6
19
  from .struct import StructPacked
7
20
 
8
21
  class AddrHandle(): pass
@@ -58,6 +71,8 @@ class Reg[RegT](object):
58
71
  """Writes the value of the register"""
59
72
  pass
60
73
 
74
+ def write_fields(self, fields : Dict[object,int]): pass
75
+
61
76
  class RegGroup(object):
62
77
  @abc.abstractmethod
63
78
  def get_handle(self) -> AddrHandle:
@@ -70,3 +85,17 @@ class RegGroup(object):
70
85
  pass
71
86
 
72
87
 
88
+ class At(object):
89
+ a : zdc.Bit[15] = zdc.field()
90
+ b : zdc.Bit[15] = zdc.field()
91
+
92
+ # def __int__(self) -> int:
93
+ # pass
94
+
95
+ # r : Reg[At] = 5
96
+ # r.read() == 20
97
+ # r.write()
98
+ # r.write_fields({At.a : 5})
99
+ # def reg(offset=)
100
+
101
+ # def reg_array(offset=0, offset_of=lambda i: )
@@ -1,3 +1,18 @@
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
+ #****************************************************************************
1
16
  import dataclasses as dc
2
17
  from typing import Callable, ClassVar
3
18
 
@@ -1,2 +1,20 @@
1
1
 
2
+ #****************************************************************************
3
+ # Copyright 2019-2025 Matthew Ballance and contributors
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #****************************************************************************
17
+ from .type_processor import TypeProcessor
2
18
  from .visitor import Visitor
19
+
20
+ from .factory_exec import FactoryExec
@@ -0,0 +1,26 @@
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
+
18
+ class TypeProcessor(object):
19
+
20
+ @abc.abstractmethod
21
+ def new(self, c, *args, **kwargs):
22
+ pass
23
+
24
+ @abc.abstractmethod
25
+ def init(self, obj, *args, **kwargs):
26
+ pass
@@ -1,14 +1,61 @@
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
+ #****************************************************************************
1
16
  import dataclasses as dc
2
- from typing import Callable, ClassVar, Dict, Type
17
+ import logging
18
+ from dataclasses import Field, MISSING
19
+ from typing import Callable, ClassVar, Dict, Type, List, Tuple
3
20
  from ..annotation import Annotation
21
+ from ..bit import Bit
4
22
  from ..component import Component
23
+ from ..exec import Exec, ExecKind, ExecSync
5
24
  from ..ports import Input, Output
6
- from ..struct import Struct
25
+ from ..struct import Extern, Struct
26
+ import inspect
27
+ import ast
28
+ import textwrap
29
+
30
+ class _BindPathMock:
31
+ def __init__(self, typ, path=None):
32
+ self._typ = typ
33
+ self._path = path or []
34
+
35
+ def __getattribute__(self, name):
36
+ if name in ("_typ", "_path", "__class__"):
37
+ return object.__getattribute__(self, name)
38
+ # Validate field exists
39
+ fields = {f.name for f in dc.fields(self._typ)}
40
+ if name not in fields:
41
+ raise AttributeError(f"Invalid field '{name}' in path {'.'.join(self._path + [name])}")
42
+ # Get field type
43
+ field_type = next(f.type for f in dc.fields(self._typ) if f.name == name)
44
+ # Return new mock for nested access
45
+ return _BindPathMock(field_type, self._path + [name])
46
+
47
+ def __call__(self):
48
+ # For supporting callables if needed
49
+ return self
50
+
51
+ def __repr__(self):
52
+ return f"_BindPathMock({self._typ}, {self._path})"
7
53
 
8
54
  @dc.dataclass
9
55
  class Visitor(object):
10
56
  _type_m : Dict[Type,Callable] = dc.field(default_factory=dict)
11
57
  _field_factory_m : Dict[Type,Callable] = dc.field(default_factory=dict)
58
+ _log : ClassVar = logging.getLogger("Visitor")
12
59
 
13
60
  def __post_init__(self):
14
61
  self._type_m = {
@@ -20,41 +67,274 @@ class Visitor(object):
20
67
  }
21
68
 
22
69
  def visit(self, t):
70
+ # Accept both class and instance
71
+ t_cls = t if isinstance(t, type) else type(t)
23
72
  found = False
24
73
  for base_t,method in self._type_m.items():
25
- if issubclass(t, base_t):
74
+ if issubclass(t_cls, base_t):
26
75
  method(t)
27
76
  found = True
28
77
  break
29
78
  if not found:
30
- raise Exception("Unsupported class %s" % str(type(t)))
79
+ raise Exception("Unsupported class %s" % str(t))
31
80
 
32
81
  def visitComponentType(self, t):
33
- self.visitStructType(t)
82
+ # Always work with the class, not the instance
83
+ t_cls = t if isinstance(t, type) else type(t)
84
+ self.visitStructType(t_cls)
34
85
  pass
35
86
 
36
- def visitStructType(self, t : Struct):
87
+ def _elabBindPath(self, path_lambda, root_type):
88
+ """
89
+ Processes a lambda expression returning a single property path.
90
+ Returns: (field_obj, path_tuple)
91
+ """
92
+ root_mock = _BindPathMock(root_type, ["s"])
93
+ result_mock = path_lambda(root_mock)
94
+ path = getattr(result_mock, "_path", None)
95
+ if path is None:
96
+ raise ValueError("Lambda must return a _BindPathMock instance")
97
+ typ = root_type
98
+ for name in path[1:]: # skip 's'
99
+ field = next(f for f in dc.fields(typ) if f.name == name)
100
+ typ = field.type
101
+ return (field, tuple(path))
102
+
103
+ def _elabBinds(self, bind_lambda, root_type):
104
+ # Instantiate mock for root
105
+ root_mock = _BindPathMock(root_type, ["s"])
106
+ # Evaluate lambda to get mapping
107
+ mapping = bind_lambda(root_mock)
108
+ result = {}
109
+ for k, v in mapping.items():
110
+ # Extract path from mock objects
111
+ k_path = getattr(k, "_path", None)
112
+ v_path = getattr(v, "_path", None)
113
+ if k_path is None or v_path is None:
114
+ raise ValueError("Bind keys/values must be _BindPathMock instances")
115
+ # Get terminal Field for key
116
+ k_typ = root_type
117
+ for name in k_path[1:]: # skip 's'
118
+ field = next(f for f in dc.fields(k_typ) if f.name == name)
119
+ k_typ = field.type
120
+ k_field = field
121
+ # Get terminal Field for value
122
+ v_typ = root_type
123
+ for name in v_path[1:]:
124
+ field = next(f for f in dc.fields(v_typ) if f.name == name)
125
+ v_typ = field.type
126
+ v_field = field
127
+ result[(k_field, tuple(k_path))] = (v_field, tuple(v_path))
128
+ return result
129
+
130
+ def _visitFields(self, t : Struct):
131
+ print("--> visitFields")
37
132
  for f in dc.fields(t):
133
+ print("Field: %s" % f.name)
38
134
  self._dispatchField(f)
135
+
136
+ def _dispatchField(self, f : dc.Field):
137
+ if f.default_factory not in (None, dc.MISSING):
138
+ if issubclass(f.default_factory, Input):
139
+ self.visitFieldInOut(f, False)
140
+ elif issubclass(f.default_factory, Output):
141
+ self.visitFieldInOut(f, True)
142
+ elif issubclass(f.default_factory, Exec):
143
+ self.visitExec(f)
144
+ elif issubclass(f.default_factory, Extern):
145
+ self.visitFieldExtern(f)
146
+ else:
147
+ raise Exception("Unknown factory %s" % f.default_factory)
148
+ pass
149
+ elif f.type in (str, int, float):
150
+ self.visitFieldData(f)
151
+ elif issubclass(f.type, Component):
152
+ print("visitFieldClass: Component %s" % f, flush=True)
153
+ self.visitFieldClass(f)
154
+ else:
155
+ print("visitFieldClass: %s" % f, flush=True)
156
+ self.visitFieldClass(f)
157
+
158
+ def _visitExecs(self, t):
159
+ exec_t = (
160
+ (ExecSync, self.visitExecSync),
161
+ (Exec, self.visitExec)
162
+ )
163
+ for n in dir(t):
164
+ o = getattr(t, n)
165
+ for et, em in exec_t:
166
+ if isinstance(o, et):
167
+ em(o)
168
+ break
169
+
170
+ def _visitFunctions(self, t):
171
+ for e in dir(t):
172
+ if not e.startswith("__") and callable(getattr(t, e)):
173
+ print("Function: %s" % e)
174
+ self.visitFunction(getattr(t, e))
175
+
176
+ def visitFunction(self, f):
177
+ pass
178
+
179
+ def _visitDataType(self, t):
180
+
181
+ if t == int:
182
+ self.visitDataTypeInt()
183
+ elif type(t) is type:
184
+ zsp_base_t = (
185
+ (Component, self.visitDataTypeComponent),
186
+ )
187
+
188
+ v = None
189
+ for tt,vv in zsp_base_t:
190
+ print("t: %s tt: %s vv: %s" % (t, tt, vv))
191
+ if issubclass(t, tt):
192
+ v = vv
193
+ break
194
+
195
+ v(t)
196
+ else:
197
+ raise Exception("Unknown type %s" % str(t))
198
+ pass
199
+
200
+ def visitDataTypeComponent(self, t):
201
+ pass
202
+
203
+ def visitDataTypeInt(self):
204
+ pass
205
+
206
+ def visitField(self, f : dc.Field):
207
+ pass
208
+
209
+ def visitFieldClass(self, f : dc.Field):
210
+ self.visitField(f)
211
+
212
+ def visitFieldInOut(self, f : dc.Field, is_out : bool):
213
+ self.visitField(f)
214
+
215
+ def visitFieldData(self, f : dc.Field):
216
+ self.visitField(f)
217
+ self._visitDataType(f.type)
218
+
219
+ def visitStructType(self, t : Struct):
220
+ self._visitFields(t)
221
+ self._visitExecs(t)
39
222
 
40
223
  for f in dir(t):
41
224
  o = getattr(t, f)
42
- if callable(o) and hasattr(o, Annotation.NAME):
43
- self.visitExec(f, o)
44
- print("Found")
225
+ # if callable(o) and hasattr(o, Annotation.NAME):
226
+ # # Extract source code of the method
227
+ # try:
228
+ # src = inspect.getsource(o)
229
+ # src = textwrap.dedent(src)
230
+ # tree = ast.parse(src)
231
+ # for stmt in tree.body[0].body: # tree.body[0] is the FunctionDef
232
+ # self.visit_statement(stmt)
233
+ # except Exception as e:
234
+ # print(f"Could not process method {f}: {e}")
235
+ # # self.visitExec(f, o)
236
+ # # print("Found")
237
+
238
+ def _findFieldRefs(self, t : Struct, method) -> List[Tuple[bool,dc.Field,Tuple[str]]]:
239
+ """
240
+ Processes the body of a Python method to identify class members
241
+ referenced inside.
242
+ Returns: List of [<is_write>,[path]]
243
+ """
244
+ import inspect, ast, textwrap
245
+
246
+ src = inspect.getsource(method)
247
+ src = textwrap.dedent(src)
248
+ tree = ast.parse(src)
249
+ refs = []
250
+
251
+ # Map field names to Field objects
252
+ field_map = {f.name: f for f in dc.fields(t)}
253
+
254
+ class FieldRefVisitor(ast.NodeVisitor):
255
+ def __init__(self):
256
+ self.refs = []
257
+
258
+ def visit_Assign(self, node):
259
+ # Left-hand side: writes
260
+ for target in node.targets:
261
+ if isinstance(target, ast.Attribute) and isinstance(target.value, ast.Name) and target.value.id == "self":
262
+ field = target.attr
263
+ if field in field_map:
264
+ self.refs.append((True, field_map[field], ("self", field)))
265
+ # Right-hand side: reads
266
+ self.visit(node.value)
267
+
268
+ def visit_Attribute(self, node):
269
+ if isinstance(node.value, ast.Name) and node.value.id == "self":
270
+ field = node.attr
271
+ if field in field_map:
272
+ self.refs.append((False, field_map[field], ("self", field)))
273
+ self.generic_visit(node)
274
+
275
+ visitor = FieldRefVisitor()
276
+ for stmt in tree.body[0].body:
277
+ visitor.visit(stmt)
278
+
279
+ # Remove duplicate refs (e.g., multiple reads/writes)
280
+ unique_refs = []
281
+ seen = set()
282
+ for ref in visitor.refs:
283
+ key = (ref[0], ref[1].name, ref[2])
284
+ if key not in seen:
285
+ unique_refs.append(ref)
286
+ seen.add(key)
287
+ return unique_refs
45
288
 
46
- def visitExec(self, name, m):
289
+ def visitExec(self, e : Exec):
47
290
  pass
48
291
 
49
- def _dispatchField(self, f : dc.Field):
50
- if f.default_factory in self._field_factory_m.keys():
51
- self._field_factory_m[f.default_factory](f)
52
- else:
53
- self.visitField(f)
292
+ def visitExecSync(self, e : ExecSync):
293
+ self.visitExec(e)
54
294
 
55
- def visitField(self, f : dc.Field):
295
+ def visitFieldExtern(self, f : dc.Field):
56
296
  pass
57
297
 
298
+ def visitOutputField(self, f : dc.Field):
299
+ self.visitField(f)
300
+
301
+ def visitIntField(self, f : dc.Field):
302
+ self.visitField(f)
303
+
304
+ def visitStrField(self, f : dc.Field):
305
+ self.visitField(f)
306
+
307
+ def visit_statement(self, stmt):
308
+ method = f"visit_{type(stmt).__name__}"
309
+ visitor = getattr(self, method, self.generic_visit)
310
+ return visitor(stmt)
311
+
312
+ def generic_visit(self, stmt):
313
+ # Recursively visit child statements if present
314
+ for field, value in ast.iter_fields(stmt):
315
+ if isinstance(value, list):
316
+ for item in value:
317
+ if isinstance(item, ast.stmt):
318
+ self.visit_statement(item)
319
+ elif isinstance(value, ast.stmt):
320
+ self.visit_statement(value)
321
+
322
+ def visit_Assign(self, stmt: ast.Assign):
323
+ # Example: handle assignment statements
324
+ # Recursively visit child nodes if needed
325
+ self.generic_visit(stmt)
326
+
327
+ def visit_If(self, stmt: ast.If):
328
+ # Example: handle if statements
329
+ for s in stmt.body:
330
+ self.visit_statement(s)
331
+ for s in stmt.orelse:
332
+ self.visit_statement(s)
333
+
334
+ def visit_Expr(self, stmt: ast.Expr):
335
+ # Example: handle expression statements
336
+ self.generic_visit(stmt)
337
+
58
338
  def visitInput(self, f : dc.Field):
59
339
  self.visitField(f)
60
340
  pass
zuspec/dataclasses/bit.py CHANGED
@@ -2,6 +2,11 @@ import dataclasses as dc
2
2
  from typing import Dict, Generic, TypeVar, Literal, Type
3
3
 
4
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
+ """
5
10
 
6
11
  def __new__(cls, name, bases, attrs):
7
12
  return super().__new__(cls, name, bases, attrs)
@@ -15,60 +20,19 @@ class BitMeta(type):
15
20
  return self.type_m[W]
16
21
  else:
17
22
  t = type("bit[%d]" % W, (Bit,), {
18
- "T" : W
23
+ "W" : W
19
24
  })
20
25
  self.type_m[W] = t
21
26
  return t
22
27
 
23
- T = TypeVar('T')
24
-
25
- class Bit[T]: pass
26
-
27
- class Int[T]: pass
28
-
29
- # T : int = 1
30
-
31
- # def __class_getitem__(cls, W : int) -> 'Bit[T]':
32
- # return "abc"
33
- # return cls
34
- # pass
35
- # pass
36
-
37
-
38
- #W = TypeVar('W')
39
-
40
- #def bit_t(W : int) -> _GenericA[Bit[T]]:
41
- # return Bit[Literal[W]]
42
-
43
- #def int_t(W : int) -> Int:
44
- # return Int[Literal[W]]
45
-
46
- class Bits():
47
- pass
48
-
49
- class IntVal():
50
- pass
51
-
52
- class BitVal(int):
53
- def __new__(cls, v : int, w : int):
54
- ret = super().__new__(cls, v)
55
- setattr(ret, "W", w)
56
- return ret
57
- def __getitem__(self, v):
58
- return 5
59
-
60
- def __add__(self, rhs):
61
- pass
62
-
63
- v = BitVal(5, 16)
64
- v += 5
65
-
66
- def bv(v : int, w : int=1) -> BitVal:
67
- return BitVal(v, w)
68
-
69
- a = bv(5,32)
70
-
71
- def iv(): pass
72
-
73
- uint64_t = Bit[Literal[64]]
74
- #int64_t = Int[Literal[64]]
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
@@ -1,3 +1,18 @@
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
+ #****************************************************************************
1
16
  from typing import Annotated, Type, TypeVar
2
17
  from .decorators import dataclass
3
18
 
@@ -11,6 +26,8 @@ class Bundle(object):
11
26
  fields are created with mirror() or field(mirror=True)
12
27
 
13
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.
14
31
  - Bundle
15
32
  - Bundle Mirror
16
33
  - Bundle Monitor (all are inputs / exports)
@@ -1,6 +1,26 @@
1
- from .decorators import dataclass
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
2
19
  from .struct import Struct
3
20
 
21
+ if TYPE_CHECKING:
22
+ from .std.timebase import TimeBase
23
+
4
24
  @dataclass
5
25
  class Component(Struct):
6
26
  """
@@ -15,6 +35,28 @@ class Component(Struct):
15
35
  - constraint
16
36
  - activity
17
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
18
47
 
19
- def build(self): pass
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
20
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
+ """
@@ -1,33 +1,60 @@
1
- '''
2
- Created on Mar 19, 2022
3
-
4
- @author: mballance
5
- '''
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
+ # Created on Mar 19, 2022
17
+ # @author: mballance
18
+ #****************************************************************************
6
19
  import dataclasses
7
20
  import dataclasses as dc
8
- from typing import Any, Callable, Dict, Self, TypeVar, Generic, Type
9
- # from vsc_dataclasses.decorators import *
10
- # from .impl.action_decorator_impl import ActionDecoratorImpl
11
- # from .impl.exec_decorator_impl import ExecDecoratorImpl
12
- # from .impl.exec_kind_e import ExecKindE
13
- # from .impl.extend_kind_e import ExtendKindE
14
- # from .impl.extend_decorator_impl import ExtendDecoratorImpl
15
- # from .impl.extend_action_decorator_impl import ExtendActionDecoratorImpl
16
- # from .impl.extend_component_decorator_impl import ExtendComponentDecoratorImpl
17
- # from .impl.fn_decorator_impl import FnDecoratorImpl
18
- # from .impl.struct_decorator_impl import StructDecoratorImpl
19
- # from .impl.struct_kind_e import StructKindE
20
- # from .impl.component_decorator_impl import ComponentDecoratorImpl
21
- # from .impl.activity_decorator_impl import ActivityDecoratorImpl
22
- # from .impl.type_kind_e import TypeKindE
21
+ import enum
22
+ import inspect
23
+ import typing
24
+ from typing import Any, Callable, Dict, Optional, Self, TypeVar, TYPE_CHECKING, Union
23
25
  from .annotation import Annotation, AnnotationSync
24
- from .ports import Input, Output
25
- from .clock import Clock
26
- from .component import Component
27
- from .timebase import TimeBase
26
+
27
+
28
+ if TYPE_CHECKING:
29
+ from .api.type_processor import TypeProcessor
28
30
 
29
31
  def dataclass(cls, **kwargs):
30
- return dc.dataclass(cls, **kwargs)
32
+ # TODO: Add type annotations to decorated methods
33
+ cls_annotations = cls.__annotations__
34
+
35
+ for name, value in cls.__dict__.items():
36
+ # print("Name: %s ; Value: %s" % (name, value))
37
+ if isinstance(value, dc.Field) and not name in cls_annotations:
38
+ print("TODO: annotate field")
39
+ cls_annotations[name] = int
40
+
41
+ cls_t = dc.dataclass(cls, **kwargs)
42
+
43
+ setattr(cls_t, "__base_init__", getattr(cls_t, "__init__"))
44
+ def local_init(self, tp : 'TypeProcessor', *args, **kwargs):
45
+ """Only called during type processing"""
46
+ return tp.init(self, *args, **kwargs)
47
+ setattr(cls_t, "__init__", local_init)
48
+
49
+ if not hasattr(cls_t, "__base_new__"):
50
+ setattr(cls_t, "__base_new__", getattr(cls_t, "__new__"))
51
+ def local_new(c, tp : 'TypeProcessor', *args, **kwargs):
52
+ """Always called during user-object construction"""
53
+ return tp.new(c, *args, **kwargs)
54
+ setattr(cls_t, "__new__", local_new)
55
+
56
+
57
+ return cls_t
31
58
 
32
59
  def bundle():
33
60
  return dc.field()
@@ -98,7 +125,7 @@ a = bit(20)[3:4]
98
125
  SelfT = TypeVar('SelfT')
99
126
  T = TypeVar('T')
100
127
 
101
- class bind(Generic[T]):
128
+ class bind[T]:
102
129
  def __init__(self, c : Callable[[T],Dict[Any,Any]]):
103
130
  self._c = c
104
131
  def __call__(self, s) -> Dict[Any,Any]:
@@ -106,14 +133,49 @@ class bind(Generic[T]):
106
133
 
107
134
  #a = bind2(lambda s:{s.}, selfT=Self)
108
135
 
109
- from typing import Optional
110
-
111
136
  def field(
112
137
  rand=False,
113
- width=-1,
114
138
  bind : Optional[Callable[[object],Dict[Any,Any]]] = None,
115
- **kwargs):
116
- pass
139
+ init : Optional[Union[Dict[str,Any], Callable[[object],Dict[Any,Any]]]] = None,
140
+ default_factory : Optional[Any] = None,
141
+ default : Optional[Any] = None):
142
+ args = {}
143
+ metadata = None
144
+
145
+ # # Obtain the location of this call
146
+ # import inspect
147
+ # frame = inspect.currentframe()
148
+ # print("--> ")
149
+ # while frame is not None:
150
+ # modname = frame.f_globals["__name__"]
151
+
152
+ # print("modname: %s" % modname)
153
+ # if not modname.startswith("zuspec.dataclasses") and not modname.startswith("importlib"):
154
+ # break
155
+ # # pass
156
+ # # frame = frame.f_back
157
+ # else:
158
+ # frame = frame.f_back
159
+ # print("<-- ")
160
+
161
+ # if frame is not None:
162
+ # print("Location: %s:%d" % (frame.f_code.co_filename, frame.f_lineno))
163
+
164
+ if default_factory is not None:
165
+ args["default_factory"] = default_factory
166
+
167
+ if bind is not None:
168
+ metadata = {} if metadata is None else metadata
169
+ metadata["bind"] = bind
170
+
171
+ # *Always* specify a default to avoid becoming a required field
172
+ if "default_factory" not in args.keys():
173
+ args["default"] = default
174
+
175
+ if metadata is not None:
176
+ print("metadata: %s" % metadata)
177
+ args["metadata"] = metadata
178
+ return dc.field(**args)
117
179
 
118
180
  # @staticmethod
119
181
  # def __call__(rand=False, bind : Callable[[T],Dict[Any,Any]] = None):
@@ -127,10 +189,26 @@ def field(
127
189
  # # TODO:
128
190
  # return dc.field()
129
191
 
192
+ class Input(object): pass
193
+
194
+ class Output(object): pass
195
+
130
196
  def input(*args, **kwargs):
197
+ """
198
+ Marks an input field. Input fields declared on a
199
+ top-level component are `bound` to an implicit output. Those
200
+ on non-top-level components must explicitly be `bound` to an
201
+ output. An input field sees the value of the output field
202
+ to which it is bound with no delay
203
+ """
131
204
  return dataclasses.field(default_factory=Input)
132
205
 
133
206
  def output(*args, **kwargs):
207
+ """
208
+ Marks an output field. Input fields that are bound to
209
+ an output field always see its current output value
210
+ with no delay.
211
+ """
134
212
  return dc.field(default_factory=Output)
135
213
 
136
214
  def lock(*args, **kwargs):
@@ -145,48 +223,87 @@ def port():
145
223
  def export(*args, bind=None, **kwargs):
146
224
  return dc.field(*args, **kwargs)
147
225
 
226
+ class ExecKind(enum.Enum):
227
+ Comb = enum.auto()
228
+ Sync = enum.auto()
229
+ Proc = enum.auto()
230
+
231
+ @dc.dataclass
232
+ class Exec(object):
233
+ method : Callable = dc.field()
234
+ kind : ExecKind = dc.field()
235
+ timebase : Optional[Callable] = field(default=None)
236
+ t : Optional[Callable] = field(default=None)
237
+
238
+ def extern(
239
+ typename,
240
+ bind,
241
+ files=None,
242
+ params=None):
243
+ """
244
+ Denotes an instance of an external module
245
+ """
246
+ from .struct import Extern
247
+ return dc.field(default_factory=Extern,
248
+ metadata=dict(
249
+ typename=typename,
250
+ bind=bind,
251
+ files=files,
252
+ params=params))
253
+
148
254
  def process(T):
149
- return T
255
+ """
256
+ Marks an always-running process. The specified
257
+ method must be `async` and take no arguments
258
+ """
259
+ return Exec(T, ExecKind.Proc)
150
260
 
151
261
  def reg(offset=0):
152
262
  return dc.field()
153
263
  pass
154
264
 
155
- def const(**kwargs):
265
+ def const(default=None):
156
266
  return dc.field()
157
267
 
158
- SyncHostT = TypeVar('SyncHostT', bound=Component)
159
- SyncMethodT = TypeVar('SyncMethodT', bound=Callable[[SyncHostT],Any])
160
-
161
268
  @dc.dataclass
162
- class Sync(object):
163
- method : Callable[[Component],Any] = dc.field()
164
- timebase : TimeBase = dc.field()
269
+ class ExecSync(Exec):
270
+ clock : Optional[Callable] = field(default=None)
271
+ reset : Optional[Callable] = field(default=None)
165
272
 
166
- ComponentT = TypeVar('ComponentT', bound=Component)
273
+ def sync(clock : Callable, reset : Callable):
274
+ """
275
+ Marks a synchronous-evaluation region, which is evaluated on
276
+ the active edge of either the clock or reset.
277
+
278
+ The semantics of a `sync` method differ from native Python.
279
+ Assignments are delayed/nonblocking: they only take effect after
280
+ evaluation of the method completes. If a variable is assigned multiple times
281
+ within a sync method, only the last assignment to that variable in the method
282
+ is applied for that cycle. Earlier assignments are ignored. Augmented
283
+ assignments (eg +=) are treated the same as regular assignments.
284
+
285
+ @zdc.sync
286
+ def _update(self):
287
+ self.val1 = self.val1 + 1
288
+ self.val1 = self.val1 + 1
289
+ self.val2 += 1
290
+ self.val2 += 1
291
+
292
+ In the example above, both val1 and val2 will only be increased by one
293
+ each time _update is evaluated.
294
+ """
295
+ def __call__(T):
296
+ return ExecSync(method=T, kind=ExecKind.Sync, clock=clock, reset=reset)
297
+ return __call__
167
298
 
168
- def sync(t : Callable[[ComponentT],Any]) -> Sync:
299
+ def comb(latch : bool=False):
169
300
  """
170
- Sync marks a method that has a dependency on a timebase.
171
- The method is automatically evaluated by the timebase at
172
- each timestep (eg clock period) of the timebase. The
173
- timebase will automatically assign the reset value
174
- to variables assigned within the decorated method when
175
- the timebase is reset.
176
- A sync-decorated method may not be directly called.
301
+ Marks a combinational evaluation region that is evaluated
302
+ whenever one of the variables read by the method changes.
177
303
  """
178
- # # TODO: handle two forms
179
- # if len(args) == 0:
180
- # def __call__(T):
181
- # Annotation.apply(T, AnnotationSync(clock=clock, reset=reset))
182
- # return T
183
- # return __call__
184
- # else:
185
- # Annotation.apply(args[0], AnnotationSync(clock=clock, reset=reset))
186
- # return args[0]
187
- ret = Sync(t)
188
- return ret
189
- # return Sync(t)
304
+ def __call__(T):
305
+ return Exec(method=T, kind=ExecKind.Comb, )
306
+ return __call__
190
307
 
191
308
 
192
309
  # def action(*args, **kwargs):
@@ -1,3 +1,18 @@
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
+ #****************************************************************************
1
16
  import abc
2
17
  import dataclasses as dc
3
18
  from typing import List
@@ -19,4 +34,3 @@ class TrackingDependencyProvider[T](DependencyProvider):
19
34
  List of dependencies bound to this provider
20
35
  """
21
36
  pass
22
-
@@ -54,8 +54,3 @@ class Port[T]():
54
54
  # a = self.dat_o().get()
55
55
  # self.dat_o().put(5)
56
56
 
57
- class Input(object):
58
- pass
59
-
60
- class Output(object):
61
- pass
@@ -0,0 +1,18 @@
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
+
17
+ from .clock_reset import ClockReset
18
+ from .timebase import TimeBase, TimebaseSync
@@ -0,0 +1,35 @@
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 ..component import Component
18
+ from ..decorators import dataclass, field, output
19
+ from ..bit import Bit
20
+
21
+ @dataclass
22
+ class ClockReset(Component):
23
+ period : int = field(default=10)
24
+ clock : Bit = output()
25
+ reset : Bit = output()
26
+
27
+ @abc.abstractmethod
28
+ def assert_reset(self): pass
29
+
30
+ @abc.abstractmethod
31
+ def release_reset(self): pass
32
+
33
+ @abc.abstractmethod
34
+ async def next(self, count : int = 1):
35
+ pass
@@ -0,0 +1,39 @@
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 Protocol, TYPE_CHECKING
18
+ from ..decorators import dataclass
19
+ from ..bit import Bit
20
+ from ..component import Component
21
+
22
+ class TimeBase(Protocol):
23
+ """
24
+ TimeBase exposes the notion of design time
25
+ """
26
+
27
+ @abc.abstractmethod
28
+ async def wait(self, amt : float, units):
29
+ """Scales the time to the timebase and waits"""
30
+ ...
31
+
32
+ @dataclass
33
+ class TimebaseSync(TimeBase):
34
+
35
+ @abc.abstractmethod
36
+ async def wait_next(self, count : int = 1):
37
+ """Waits for 'count' timebase events (eg clocks)"""
38
+ ...
39
+
@@ -3,7 +3,11 @@ from typing import Dict, Optional, Type
3
3
  from .decorators import dataclass
4
4
 
5
5
  @dataclass
6
- class StructPacked(object):
6
+ class ZuspecTypeBase(object):
7
+ pass
8
+
9
+ @dataclass
10
+ class StructPacked(ZuspecTypeBase):
7
11
  """
8
12
  StructPacked types are fixed-size data structures.
9
13
  Fields may only be of a fixed size.
@@ -15,7 +19,7 @@ class StructPacked(object):
15
19
  pass
16
20
 
17
21
  @dataclass
18
- class Struct(object):
22
+ class Struct(ZuspecTypeBase):
19
23
  """
20
24
  Struct types are data structures that may contain
21
25
  variable-size fields.
@@ -26,6 +30,7 @@ class Struct(object):
26
30
  - method
27
31
  """
28
32
 
33
+
29
34
  # @abc.abstractmethod
30
35
  # def bind[T](self, t : T):
31
36
  # t : Type[T],
@@ -40,3 +45,5 @@ class Struct(object):
40
45
  # pass
41
46
 
42
47
  pass
48
+
49
+ class Extern(ZuspecTypeBase): pass
@@ -1,5 +1,5 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zuspec-dataclasses
3
- Version: 0.0.1.17516204125rc0
3
+ Version: 0.0.1.18247420852rc0
4
4
  License-File: LICENSE
5
5
  Dynamic: license-file
@@ -0,0 +1,29 @@
1
+ zuspec/dataclasses/__init__.py,sha256=WSYClXn7Bugmg6tHtQpENpZpW7Lphful7VPJ0kXEv2I,1369
2
+ zuspec/dataclasses/__version__.py,sha256=FZjvfuiu1QLTKdM08pAf1-fJnCceQaX8uTFDxkh6YiY,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.18247420852rc0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
26
+ zuspec_dataclasses-0.0.1.18247420852rc0.dist-info/METADATA,sha256=Yiqa1zkAvVp5jOzdWFv5b_kP2e0QivMdAZ3OSzA59BQ,121
27
+ zuspec_dataclasses-0.0.1.18247420852rc0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
+ zuspec_dataclasses-0.0.1.18247420852rc0.dist-info/top_level.txt,sha256=3WM_V5g1RvpI4_z1TPY_AmroKhWIp6QJo4Vz5Tqbgak,7
29
+ zuspec_dataclasses-0.0.1.18247420852rc0.dist-info/RECORD,,
@@ -1,3 +0,0 @@
1
-
2
- class Clock(object):
3
- pass
@@ -1,3 +0,0 @@
1
-
2
- class Reset(object):
3
- pass
@@ -1,27 +0,0 @@
1
- import abc
2
- from .component import Component
3
- from .decorators import dataclass, input
4
- from .bit import Bit
5
-
6
- @dataclass
7
- class TimeBase(object):
8
- """
9
- TimeBase exposes the notion of design time
10
- """
11
-
12
- @abc.abstractmethod
13
- async def wait(self, amt : float, units):
14
- """Scales the time to the timebase and waits"""
15
- pass
16
-
17
- @abc.abstractmethod
18
- def wait_ev(self, amt : float, units):
19
- """Scales the time to the timebase and returns an event"""
20
- pass
21
-
22
- pass
23
-
24
- class TimeBaseSignal(TimeBase,Component):
25
- clock : Bit = input()
26
- reset : Bit = input()
27
-
@@ -1,28 +0,0 @@
1
- zuspec/dataclasses/__init__.py,sha256=-a466Myi0Gs7JWbIm2LiNKkHFuIjoGsjj5aMrAyQuBs,462
2
- zuspec/dataclasses/__version__.py,sha256=2pHn0_iz8uobg16bUlzrP3GDosLHvXeTtklooC9fUFo,71
3
- zuspec/dataclasses/action.py,sha256=z7aMc6e_k_-NCzYDm8K1ymEPfcGeyqlO79of0Gucack,570
4
- zuspec/dataclasses/addr_reg.py,sha256=14dgTvdkyHxzGLOJRqMkAFwKhnRM2iI3B6IdzioJQl8,1728
5
- zuspec/dataclasses/annotation.py,sha256=M41iS93Oi8M-ER_ZIBI8CIWJ1bvEMI0nHa-RxbmWJUs,328
6
- zuspec/dataclasses/bit.py,sha256=PHGjvh-O4k7m-juXQzEMZJIn5k-h1cJaIHmgk0RhofM,1405
7
- zuspec/dataclasses/bundle.py,sha256=6fqjfoTS_-_izl4FlPFgurfOg3tnj_1fmEdSa1FF4C0,781
8
- zuspec/dataclasses/clock.py,sha256=pM0rO-3bp0SGJccxtU-17vIcF9EaSlqD-q1_9O0of1o,30
9
- zuspec/dataclasses/component.py,sha256=oERqTHRdiI2oYW5q8ijYNY9FUMIrqLlqAVfZFipjzPU,524
10
- zuspec/dataclasses/decorators.py,sha256=v6toBLONKbw5dj7DRoH9XEOSNghBNjuRWjc1C66LEHc,10762
11
- zuspec/dataclasses/dependency.py,sha256=kGxdFqKlviUP7qmvN-FbnXIiqCPdgRRel83feuu8OoU,532
12
- zuspec/dataclasses/ports.py,sha256=3pbBwdBzDMAJTZ15Qf6sSXB-XOH5cJ-G5H8kQa5JurQ,1106
13
- zuspec/dataclasses/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
14
- zuspec/dataclasses/reset.py,sha256=DV8tiKq_k-AGUNBbpJCJFx_EEfA07UgUJK2veYli0b0,30
15
- zuspec/dataclasses/struct.py,sha256=vId0487ZJmhnTbTg421B-iN9PtxNexCv9DMqRO8RXBU,973
16
- zuspec/dataclasses/timebase.py,sha256=rjEiGB2lNPMTewE-Z4iX-CHnbx1QVTUbtwEXnKMkesI,599
17
- zuspec/dataclasses/tlm.py,sha256=sbAlnkYhVidinbiMKBT_mbe5yr1dDU9F_6aKBAXZjjE,431
18
- zuspec/dataclasses/api/__init__.py,sha256=HfJhJ_B1RJSpJn5NmWzEK3l2IruubiEKd3xwLDuED6Q,30
19
- zuspec/dataclasses/api/visitor.py,sha256=8-5er0GxAWnvxhDmiR_OBn2iMxtymtol5qM09ucKdLI,1780
20
- zuspec/dataclasses/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- zuspec/dataclasses/util/extract_cpp_embedded_dsl.py,sha256=SyMMLumZD6fsubj40hyekYzWyrcoUGTijJH3NmK1ihY,5630
22
- zuspec/dataclasses/util/gen_cpp_dt_defs/__main__.py,sha256=t3CnHJKcN_N33sxCsDH-R36ghCcQ7xjMcjUrzUT2SGM,3447
23
- zuspec/impl/__init__.py,sha256=GZWCeBPdVzLR0RNPkmXNXPgdS-2vg5dMC1goTYJs3yI,33
24
- zuspec_dataclasses-0.0.1.17516204125rc0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
25
- zuspec_dataclasses-0.0.1.17516204125rc0.dist-info/METADATA,sha256=i1hPXCIb3njC6aXg7B4-7PEyGQFnISQB-cg4W36qFtY,121
26
- zuspec_dataclasses-0.0.1.17516204125rc0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- zuspec_dataclasses-0.0.1.17516204125rc0.dist-info/top_level.txt,sha256=3WM_V5g1RvpI4_z1TPY_AmroKhWIp6QJo4Vz5Tqbgak,7
28
- zuspec_dataclasses-0.0.1.17516204125rc0.dist-info/RECORD,,