• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Nic30 / hwtLib / b469f1f6-6a00-4958-bfb0-f9fbf427a589

06 Jun 2024 06:38PM UTC coverage: 93.399% (-0.03%) from 93.431%
b469f1f6-6a00-4958-bfb0-f9fbf427a589

push

circleci

Nic30
docs

8040 of 9100 branches covered (88.35%)

39136 of 41902 relevant lines covered (93.4%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.62
/hwtLib/amba/axis_comp/frame_parser/_parser.py
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3

4
from typing import Optional, List, Union, Tuple
1✔
5

6
from hwt.code import If, Or
1✔
7
from hwt.code_utils import connect_optional, rename_signal
1✔
8
from hwt.hdl.frameTmpl import FrameTmpl
1✔
9
from hwt.hdl.frameTmplUtils import ChoicesOfFrameParts
1✔
10
from hwt.hdl.transPart import TransPart
1✔
11
from hwt.hdl.transTmpl import TransTmpl
1✔
12
from hwt.hdl.types.bits import HBits
1✔
13
from hwt.hdl.types.defs import BIT
1✔
14
from hwt.hdl.types.hdlType import HdlType
1✔
15
from hwt.hdl.types.stream import HStream
1✔
16
from hwt.hdl.types.struct import HStruct, HStructField
1✔
17
from hwt.hdl.types.union import HUnion
1✔
18
from hwt.hdl.types.utils import is_only_padding
1✔
19
from hwt.hwIOs.std import HwIODataRdVld, HwIOSignal, HwIODataVld
1✔
20
from hwt.hwIOs.hwIOStruct import HwIOStruct
1✔
21
from hwt.hwIOs.hwIOUnion import HwIOUnionSource
1✔
22
from hwt.hwIOs.utils import addClkRstn, propagateClkRstn
1✔
23
from hwt.math import log2ceil
1✔
24
from hwt.serializer.mode import serializeParamsUniq
1✔
25
from hwt.hObjList import HObjList
1✔
26
from hwt.hwParam import HwParam
1✔
27
from hwt.synthesizer.rtlLevel.rtlSignal import RtlSignal
1✔
28
from hwtLib.abstract.frame_utils.alignment_utils import next_frame_offsets
1✔
29
from hwtLib.abstract.template_configured import TemplateConfigured, \
1✔
30
    HdlType_separate
31
from hwtLib.amba.axi4s import Axi4Stream
1✔
32
from hwtLib.amba.axis_comp.base import Axi4SCompBase
1✔
33
from hwtLib.amba.axis_comp.frame_deparser.utils import drill_down_in_HStruct_fields
1✔
34
from hwtLib.amba.axis_comp.frame_join._join import Axi4S_FrameJoin
1✔
35
from hwtLib.amba.axis_comp.frame_parser.field_connector import Axi4S_frameParserFieldConnector
1✔
36
from hwtLib.amba.axis_comp.frame_parser.footer_split import Axi4S_footerSplit
1✔
37
from hwtLib.amba.axis_comp.frame_parser.word_factory import WordFactory
1✔
38
from hwtLib.handshaked.streamNode import StreamNode
1✔
39
from hwt.pyUtils.typingFuture import override
1✔
40

41

42
def is_non_const_stream(t: HdlType):
1✔
43
    if isinstance(t, HStream):
1✔
44
        try:
1✔
45
            t.bit_length()
1✔
46
        except TypeError:
1✔
47
            return True
1✔
48

49
    return False
1✔
50

51

52
def can_be_zero_sized(t: HdlType):
1✔
53
    while isinstance(t, HStruct) and len(t.fields) == 1:
1✔
54
        t = t.fields[0].dtype
1✔
55

56
    if isinstance(t, HStream):
1!
57
        return t.len_min == 0
1✔
58
    return isinstance(t, HStruct) and not t.fields
×
59

60

61
class _Axi4S_frameParserChildMeta():
1✔
62

63
    def __init__(self, t: HdlType, is_padding: bool, is_const_sized: bool):
1✔
64
        self.t = t
1✔
65
        self.is_padding = is_padding
1✔
66
        self.is_const_sized = is_const_sized
1✔
67
        self.can_be_zero_len = not is_const_sized and can_be_zero_sized(t)
1✔
68

69

70
def connect_with_clear(clear: RtlSignal, din: RtlSignal, dout: RtlSignal):
1✔
71
    If(clear,
1✔
72
       dout(0)
73
    ).Else(
74
       dout(din)
75
    )
76

77

78
@serializeParamsUniq
1✔
79
class Axi4S_frameParser(Axi4SCompBase, TemplateConfigured):
1✔
80
    """
81
    Parse frame specified by HType (HStruct, HUnion, ...) into fields
82

83
    :note: if special frame format is required,
84
        it can be specified by TransTmpl instance and list of FrameTmpl
85
        (Output data structure can be splited into multiple frames as required)
86

87
    .. figure:: ./_static/Axi4S_frameParser.png
88

89
    :note: names in the figure are just illustrative
90

91
    :ivar ~.dataIn: the Axi4Stream interface for input frame
92
    :ivar ~.dataOut: output field interface generated from input type description
93
    :ivar ~.children: List[Axi4S_frameParser] which contains a list of children components
94
        in the cases where this component works only as a wrapper of pipeline composed from actual parsers
95
    :ivar ~.children_meta: List[_Axi4S_frameParserChildMeta] additional info for children list
96

97
    .. hwt-autodoc:: _example_Axi4S_frameParser
98
    """
99

100
    def __init__(self, structT: HdlType,
1✔
101
                 tmpl: Optional[TransTmpl]=None,
102
                 frames: Optional[List[FrameTmpl]]=None):
103
        """
104
        :param structT: instance of HStruct which specifies
105
            data format to download
106
        :param tmpl: instance of TransTmpl for this structT
107
        :param frames: list of FrameTmpl instances for this tmpl
108
        :note: if tmpl and frames are None they are resolved
109
            from structT parseTemplate
110
        :note: this unit can parse sequence of frames,
111
            if they are specified by "frames"
112
        :attention: structT can not contain fields with variable size
113
            like HStream
114
        """
115
        TemplateConfigured.__init__(self, structT, tmpl, frames)
1✔
116
        Axi4SCompBase.__init__(self)
1✔
117

118
    @override
1✔
119
    def hwConfig(self):
1✔
120
        self.hwIOCls.hwConfig(self)
1✔
121
        self.T = HwParam(self._structT)
1✔
122
        self.TRANSACTION_TEMPLATE = HwParam(self._tmpl)
1✔
123
        self.FRAME_TEMPLATES = HwParam(None if self._frames is None else tuple(self._frames))
1✔
124
        # if this is true field interfaces will be of type HwIODataVld
125
        # and single ready signal will be used for all
126
        # else every interface will be instance of HwIODataRdVld and it will
127
        # have it's own ready(rd) signal
128
        self.SHARED_READY = HwParam(False)
1✔
129
        # if true, a new state for overflow will be created in FSM
130
        self.OVERFLOW_SUPPORT = HwParam(False)
1✔
131
        # if True, a frame shorter than expected will cause the reset of main FSM
132
        self.UNDERFLOW_SUPPORT = HwParam(False)
1✔
133

134
    def _mkFieldHwIO(self, parent: Union[HwIOStruct, HwIOUnionSource],
1✔
135
                     structField: HStructField):
136
        """
137
        Create an interface to export the data specified by the member of the structure
138
        """
139
        t = structField.dtype
1✔
140
        path = parent._field_path / structField.name
1✔
141
        if isinstance(t, HUnion):
1✔
142
            i = HwIOUnionSource(t, path, parent._instantiateFieldFn)
1✔
143
            i._fieldsToHwIOs = parent._fieldsToHwIOs
1✔
144
            return i
1✔
145
        elif isinstance(t, HStruct):
1✔
146
            i = HwIOStruct(t, path, parent._instantiateFieldFn)
1✔
147
            i._fieldsToHwIOs = parent._fieldsToHwIOs
1✔
148
            return i
1✔
149
        elif isinstance(t, HStream):
1✔
150
            if self.SHARED_READY:
1✔
151
                raise NotImplementedError("SHARED_READY=True and HStream field", structField)
152
            else:
153
                i = Axi4Stream()
1✔
154
                i._updateHwParamsFrom(self)
1✔
155
                return i
1✔
156
        else:
157
            if self.SHARED_READY:
1!
158
                i = HwIODataVld()
×
159
            else:
160
                i = HwIODataRdVld()
1✔
161
            i.DATA_WIDTH = structField.dtype.bit_length()
1✔
162
            return i
1✔
163

164
    @override
1✔
165
    def hwDeclr(self):
1✔
166
        if self.ID_WIDTH:
1✔
167
            raise NotImplementedError(self.ID_WIDTH)
168
        if self.DEST_WIDTH:
1✔
169
            raise NotImplementedError(self.DEST_WIDTH)
170

171
        addClkRstn(self)
1✔
172

173
        t = self._structT
1✔
174
        if isinstance(t, HStruct):
1✔
175
            hwIOCls = HwIOStruct
1✔
176
        elif isinstance(t, HUnion):
1!
177
            hwIOCls = HwIOUnionSource
1✔
178
        else:
179
            raise TypeError(t)
×
180

181
        # input stream
182
        with self._hwParamsShared():
1✔
183
            self.dataIn = self.hwIOCls()
1✔
184
            if self.SHARED_READY:
1!
185
                self.dataOut_ready = HwIOSignal()
×
186

187
        # parsed data
188
        if is_only_padding(t):
1✔
189
            self.dataOut = None
1✔
190
        else:
191
            self.dataOut = hwIOCls(t, tuple(), self._mkFieldHwIO)._m()
1✔
192

193
        self.parseTemplate()
1✔
194
        if self.OVERFLOW_SUPPORT:
1✔
195
            # flag which is 1 if we are behind the data which
196
            # we described by type in configuration
197
            # :note: if the data is unaligned this may be 1 in last parsed word
198
            #        as well
199
            self.parsing_overflow: HwIOSignal = HwIOSignal()._m()
1✔
200

201
        if self.UNDERFLOW_SUPPORT:
1✔
202
            # flag which is 1 if the input stream ended prematurely
203
            # and main FSM will be restarted
204
            self.error_underflow: HwIOSignal = HwIOSignal()._m()
1✔
205

206
    def parseTemplate(self):
1✔
207
        """
208
        Load the configuration from the parameters
209
        """
210
        t = self._structT
1✔
211
        try:
1✔
212
            t.bit_length()
1✔
213
            is_const_size_frame = True
1✔
214
        except TypeError:
1✔
215
            is_const_size_frame = False
1✔
216

217
        self.children_meta: List[_Axi4S_frameParserChildMeta] = []
1✔
218
        if is_const_size_frame:
1✔
219
            self.children = []
1✔
220
            super(Axi4S_frameParser, self).parseTemplate()
1✔
221
        else:
222
            if self._tmpl or self._frames:
1✔
223
                raise NotImplementedError("Dynamic input size and the redefinition of the placement of fields in the data")
224

225
            children_meta = self.children_meta
1✔
226
            # try to cut the data type on const and variable size chunks
227
            # to simplify the parsing logic as these chunks can be handled
228
            # as usuall and only code specific to this case is handling of overlaps
229
            # of such a segments
230
            children = HObjList()
1✔
231
            separated = list(HdlType_separate(t, is_non_const_stream))
1✔
232
            if len(separated) > 1 or separated[0][0]:
1!
233
                # it may be required to delegate this on children
234
                first = True
1✔
235
                for is_non_const_sized, s_t in separated:
1✔
236
                    _is_padding = is_only_padding(s_t)
1✔
237
                    if is_non_const_sized or (not first and _is_padding):
1✔
238
                        c = None
1✔
239
                    else:
240
                        c = self.__class__(s_t)
1✔
241

242
                    first = False
1✔
243
                    children.append(c)
1✔
244
                    cmeta = _Axi4S_frameParserChildMeta(s_t, _is_padding, not is_non_const_sized)
1✔
245
                    children_meta.append(cmeta)
1✔
246

247
                if len(children_meta) >= 2 and \
1✔
248
                        children_meta[0].is_const_sized and\
249
                        not children_meta[1].is_const_sized:
250
                    # we will parse const-size prefix and
251
                    # then there will be a variable size suffix
252
                    children[0].OVERFLOW_SUPPORT = True
1✔
253

254
                with self._hwParamsShared(exclude=({"OVERFLOW_SUPPORT", "T"}, {})):
1✔
255
                    self.children = children
1✔
256

257
    def parser_fsm(self, words: List[Tuple[int, List[Union[TransPart, ChoicesOfFrameParts]], bool]]):
1✔
258
        din = self.dataIn
1✔
259
        maxWordIndex = words[-1][0]
1✔
260

261
        word_index_max_val = maxWordIndex
1✔
262
        if self.OVERFLOW_SUPPORT:
1✔
263
            word_index_max_val += 1
1✔
264
        hasMultipleWords = word_index_max_val > 0
1✔
265
        if hasMultipleWords:
1✔
266
            wordIndex = self._reg("wordIndex", HBits(
1✔
267
                log2ceil(word_index_max_val + 1)), 0)
268
        else:
269
            wordIndex = None
1✔
270

271
        allOutNodes = WordFactory(wordIndex)
1✔
272
        if not is_only_padding(self._structT):
1✔
273
            fc = Axi4S_frameParserFieldConnector(self, self.dataIn, self.dataOut)
1✔
274
            fc.connectParts(allOutNodes, words, wordIndex)
1✔
275

276
        in_vld = din.valid
1✔
277
        if self.SHARED_READY:
1!
278
            out_ready = self.dataOut_ready
×
279
            din.ready(out_ready)
×
280
        else:
281
            out_ready = self._sig("out_ready")
1✔
282
            out_ready(allOutNodes.ack())
1✔
283
            out_en = BIT.from_py(1)
1✔
284
            if self.OVERFLOW_SUPPORT:
1✔
285
                out_en = out_en & ~self.parsing_overflow
1✔
286
            allOutNodes.sync(out_en, in_vld)
1✔
287

288
        if self.OVERFLOW_SUPPORT:
1✔
289
            out_ready = out_ready | self.parsing_overflow
1✔
290
        din.ready(out_ready)
1✔
291

292
        if hasMultipleWords:
1✔
293
            incr = wordIndex(wordIndex + 1)
1✔
294
            data_ack = rename_signal(self, in_vld & out_ready, "data_ack")
1✔
295
            aligned = self._structT.bit_length() % self.DATA_WIDTH == 0
1✔
296

297
            if self.UNDERFLOW_SUPPORT:
1✔
298
                last = din.last
1✔
299
                self.error_underflow(data_ack & last & (
1✔
300
                    (wordIndex < maxWordIndex) if not aligned else wordIndex != maxWordIndex)
301
                )
302
            else:
303
                last = wordIndex._eq(maxWordIndex)
1✔
304

305
            if self.OVERFLOW_SUPPORT:
1✔
306
                last = din.last
1✔
307
                incr = If(wordIndex != word_index_max_val,
1✔
308
                   incr
309
                )
310
                if aligned:
1✔
311
                    overflow = wordIndex._eq(word_index_max_val)
1✔
312
                else:
313
                    overflow = wordIndex >= maxWordIndex
1✔
314

315
                self.parsing_overflow(overflow)
1✔
316

317
            If(data_ack,
1✔
318
                If(last,
319
                   wordIndex(0)
320
                ).Else(
321
                   incr
322
                )
323
            )
324

325
    def delegate_to_children(self):
1✔
326
        """
327
        After parsing task was split on some subtasks
328
        we are instantiating the child components to handle them
329
        and on this level we need to handle the synchronization between them
330
        """
331
        if self.SHARED_READY:
1✔
332
            raise NotImplementedError()
333
        assert len(self.children_meta) == len(self.children), \
1✔
334
            (self.children_meta, self.children)
335
        if self.OVERFLOW_SUPPORT:
1✔
336
            raise NotImplementedError()
337

338
        din = self.dataIn
1✔
339
        # :note: the children tasks are produced by disolving of original
340
        # parsed data type on const and non-const sized segments
341
        if len(self.children) == 2:
1✔
342
            c0, c1 = self.children
1✔
343
            cm0, cm1 = self.children_meta
1✔
344

345
            if not cm0.is_const_sized and cm1.is_const_sized:
1✔
346
                # suffix parser, split suffix and parse it in child sub component
347
                if cm0.can_be_zero_len:
1✔
348
                    assert self.USE_KEEP or self.USE_STRB, "keep or strb signal on Axi4Stream is required to mark 0 length packets"
1✔
349

350
                fs = Axi4S_footerSplit()
1✔
351
                fs._updateHwParamsFrom(self)
1✔
352
                fs.FOOTER_WIDTH = cm1.t.bit_length()
1✔
353
                self.footer_split = fs
1✔
354

355
                fs.dataIn(din)
1✔
356

357
                prefix_t, prefix = drill_down_in_HStruct_fields(cm0.t, self.dataOut)
1✔
358
                if cm0.is_padding:
1✔
359
                    # padding
360
                    fs.dataOut[0].ready(1)
1✔
361
                else:
362
                    assert isinstance(prefix_t, HStream), prefix_t
1✔
363
                    prefix(fs.dataOut[0])
1✔
364

365
                suffix = fs.dataOut[1]
1✔
366
                if cm1.is_padding:
1✔
367
                    # ignore suffix entirely
368
                    suffix.ready(1)
1✔
369
                else:
370
                    # parse suffix in child component
371
                    suffix_offsets = next_frame_offsets(prefix_t, self.DATA_WIDTH)
1✔
372
                    if suffix_offsets != [0, ]:
1✔
373
                        # add aligment logic
374
                        align = Axi4S_FrameJoin()
1✔
375
                        align._updateHwParamsFrom(
1✔
376
                            self,
377
                            exclude=({"T"}, {}))
378
                        align.USE_KEEP = True
1✔
379
                        align.USE_STRB = False
1✔
380
                        align.OUT_OFFSET = 0
1✔
381
                        align.T = HStruct(
1✔
382
                            (HStream(cm1.t, frame_len=1,
383
                                     start_offsets=[x // 8 for x in suffix_offsets]),
384
                             "f0"))
385
                        self.suffix_align = align
1✔
386
                        align.dataIn[0](suffix, exclude=[suffix.strb, align.dataIn[0].keep])
1✔
387
                        align.dataIn[0].keep(suffix.strb)
1✔
388
                        suffix = align.dataOut
1✔
389
                        c1.dataIn(suffix, exclude=[suffix.keep,
1✔
390
                                                   c1.dataIn.strb])
391
                        c1.dataIn.strb(suffix.keep)
1✔
392
                    else:
393
                        c1.dataIn(suffix)
1✔
394

395
                if not cm1.is_padding:
1✔
396
                    connect_optional(c1.dataOut, self.dataOut)
1✔
397

398
            elif cm0.is_const_sized and not cm1.is_const_sized:
1✔
399
                # prefix parser, parser prefix in subcomponent
400
                # and let rest to a suffix
401
                if not cm0.is_padding:
1✔
402
                    connect_optional(c0.dataOut, self.dataOut)
1✔
403
                masters = [din]
1✔
404
                if cm1.is_padding:
1✔
405
                    slaves = [c0.dataIn, ]
1✔
406
                    extraConds = None
1✔
407
                    skipWhen = None
1✔
408
                else:
409
                    suffix_t, suffix = drill_down_in_HStruct_fields(cm1.t, self.dataOut)
1✔
410
                    assert isinstance(suffix_t, HStream), suffix_t
1✔
411
                    t1_offset = c0._structT.bit_length() % self.DATA_WIDTH
1✔
412
                    if t1_offset == 0:
1✔
413
                        slaves = [c0.dataIn, suffix]
1✔
414
                        if cm1.can_be_zero_len:
1✔
415
                            assert suffix.USE_KEEP or suffix.USE_STRB, "keep or strb signal on Axi4Stream is required to mark 0 length packets"
1✔
416
                            is_zero_len = ~c0.parsing_overflow & din.valid & din.last
1✔
417
                            # this is a stream after some header, we need to assert that we
418
                            # output the 0B packet (valid=1, ready=1, last=1, keep=0) at the end
419
                            extraConds = {
1✔
420
                               # c0.dataIn:~c0.parsing_overflow,
421
                               suffix: c0.parsing_overflow | (din.valid & din.last),
422
                            }
423
                            skipWhen = {
1✔
424
                               suffix:~c0.parsing_overflow & ~(din.valid & din.last),
425
                            }
426
                            control_signals = [din.valid, din.ready]
1✔
427
                            if suffix.USE_KEEP:
1✔
428
                                control_signals.append(suffix.keep)
1✔
429
                                connect_with_clear(is_zero_len, din.keep, suffix.keep)
1✔
430
                            if suffix.USE_STRB:
1✔
431
                                control_signals.append(suffix.strb)
1✔
432
                                connect_with_clear(is_zero_len, din.strb, suffix.strb)
1✔
433

434
                            suffix(din, exclude=control_signals)
1✔
435

436
                        else:
437
                            # t1 is aligned on word boundary
438
                            # and does not require any first word mask modification
439

440
                            # We enable the input to c1 once the c0 is finished with the parsing (parsing_overflow=1)
441
                            extraConds = {
1✔
442
                               # c0.dataIn:~c0.parsing_overflow,
443
                               suffix: c0.parsing_overflow,
444
                            }
445
                            skipWhen = {
1✔
446
                               suffix:~c0.parsing_overflow,
447
                            }
448
                            suffix(din, exclude=[din.valid, din.ready])
1✔
449

450
                    else:
451
                        raise NotImplementedError("prefix parser- modify mask for suffix first word")
452

453
                StreamNode(masters, slaves,
1✔
454
                           extraConds=extraConds,
455
                           skipWhen=skipWhen).sync()
456
                c0.dataIn(din, exclude=[din.valid, din.ready])
1✔
457
            else:
458
                raise NotImplementedError("multiple(2) non-constant size segments in parsed datastructure, do parse frame incrementally instead")
459
        else:
460
            raise NotImplementedError("multiple non-constant size segments in parsed datastructure, do parse frame incrementally instead")
461
        if self.UNDERFLOW_SUPPORT:
1✔
462
            self.error_underflow(Or(*(c.error_underflow for c in self.children if c is not None)))
1✔
463

464
        propagateClkRstn(self)
1✔
465

466
    @override
1✔
467
    def hwImpl(self):
1✔
468
        """
469
        Output data signals are directly connected to input in most of the cases,
470
        exceptions are:
471

472
        * Delayed parts of fields which were parsed in some previous input word
473
          for fields wich are crossing input word boundaries
474
        * Streams may have alignment logic if required
475
        """
476

477
        if self.children_meta:
1✔
478
            self.delegate_to_children()
1✔
479
        else:
480
            words = list(self.chainFrameWords())
1✔
481
            self.parser_fsm(words)
1✔
482

483

484
def _example_Axi4S_frameParser():
1✔
485
    from hwtLib.types.ctypes import uint8_t, uint16_t, uint32_t, uint64_t
×
486
    # t = HStruct(
487
    #  (uint64_t, "item0"),  # tuples (type, name) where type has to be instance of HBits type
488
    #  (uint64_t, None),  # name = None means this field will be ignored
489
    #  (uint64_t, "item1"),
490
    #  (uint64_t, None),
491
    #  (uint16_t, "item2"),
492
    #  (uint16_t, "item3"),
493
    #  (uint32_t, "item4"),
494
    #  (uint32_t, None),
495
    #  (uint64_t, "item5"),  # this word is split on two bus words
496
    #  (uint32_t, None),
497

498
    #  (uint64_t, None),
499
    #  (uint64_t, None),
500
    #  (uint64_t, None),
501
    #  (uint64_t, "item6"),
502
    #  (uint64_t, "item7"),
503
    #  (HStruct(
504
    #      (uint64_t, "item0"),
505
    #      (uint64_t, "item1"),
506
    #   ),
507
    #   "struct0")
508
    #  )
509
    # t = HUnion(
510
    #   (uint32_t, "a"),
511
    #   (uint32_t, "b")
512
    #   )
513

514
    # t = HUnion(
515
    #     (HStruct(
516
    #         (uint64_t, "itemA0"),
517
    #         (uint64_t, "itemA1")
518
    #     ), "frameA"),
519
    #     (HStruct(
520
    #         (uint32_t, "itemB0"),
521
    #         (uint32_t, "itemB1"),
522
    #         (uint32_t, "itemB2"),
523
    #         (uint32_t, "itemB3")
524
    #     ), "frameB")
525
    # )
526
    t = HStruct(
×
527
        (HStream(uint8_t, frame_len=(0, 1)), "frame0"),
528
        (uint16_t, "footer")
529
    )
530

531
    m = Axi4S_frameParser(t)
×
532
    m.USE_STRB = True
×
533
    m.DATA_WIDTH = 32
×
534
    return m
×
535

536

537
if __name__ == "__main__":
538
    from hwt.synth import to_rtl_str
539
    m = _example_Axi4S_frameParser()
540

541
    print(to_rtl_str(m))
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc