• 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

88.64
/hwtLib/structManipulators/structReader.py
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3

4
from math import ceil
1✔
5

6
from hwt.code import StaticForEach
1✔
7
from hwt.hdl.frameTmpl import FrameTmpl
1✔
8
from hwt.hdl.transTmpl import TransTmpl
1✔
9
from hwt.hdl.types.struct import HStruct
1✔
10
from hwt.hwIOs.hwIOStruct import HwIOStruct
1✔
11
from hwt.hwIOs.std import HwIODataRdVld, HwIOSignal
1✔
12
from hwt.hwIOs.utils import propagateClkRstn, addClkRstn
1✔
13
from hwt.hwModule import HwModule
1✔
14
from hwt.hwParam import HwParam
1✔
15
from hwt.pyUtils.typingFuture import override
1✔
16
from hwtLib.abstract.template_configured import TemplateConfigured
1✔
17
from hwtLib.amba.axis_comp.frame_parser import Axi4S_frameParser
1✔
18
from hwtLib.amba.datapump.intf import HwIOAxiRDatapump, AddrSizeHs
1✔
19
from hwtLib.handshaked.builder import HsBuilder
1✔
20
from hwtLib.handshaked.streamNode import StreamNode
1✔
21

22

23
class StructReader(Axi4S_frameParser):
1✔
24
    """
25
    This unit downloads required structure fields over rDatapump
26
    interface from address specified by get interface
27

28
    :ivar ~.ID: HwParam, id for transactions on bus
29
    :ivar ~.READ_ACK: HwParam, if true ready on "get" will be set only
30
        when component is in idle (if false "get"
31
        is regular handshaked interface)
32
    :ivar ~.SHARED_READY: HwParam, if this is true field interfaces
33
        will be of type VldSynced and single ready signal
34
        will be used for all else every interface
35
        will be instance of HwIODataRdVld and it
36
        will have it's own ready(rd) signal
37
    :attention: interfaces of field will not send data in same time
38

39

40
    .. figure:: ./_static/StructReader.png
41

42
    :note: names in the picture are just illustrative
43

44
    .. hwt-autodoc:: _example_StructReader
45
    """
46

47
    def __init__(self, structT, tmpl=None, frames=None):
1✔
48
        """
49
        :param structT: instance of HStruct which specifies data format to download
50
        :param tmpl: instance of TransTmpl for this structT
51
        :param frames: list of FrameTmpl instances for this tmpl
52
        :note: if tmpl and frames are None they are resolved from structT parseTemplate
53
        :note: this unit can parse sequence of frames, if they are specified by "frames"
54
        :attention: interfaces for each field in struct will be dynamically created
55
        :attention: structT can not contain fields with variable size like HStream
56
        """
57
        HwModule.__init__(self)
1✔
58
        assert isinstance(structT, HStruct)
1✔
59
        TemplateConfigured.__init__(self, structT, tmpl=tmpl, frames=frames)
1✔
60

61
    @override
1✔
62
    def hwConfig(self):
1✔
63
        self.ID = HwParam(0)
1✔
64
        HwIOAxiRDatapump.hwConfig(self)
1✔
65
        self.USE_STRB = False
1✔
66
        self.READ_ACK = HwParam(False)
1✔
67
        self.SHARED_READY = HwParam(False)
1✔
68

69
    def maxWordIndex(self):
1✔
70
        return max(f.endBitAddr - 1 for f in self._frames) // self.DATA_WIDTH
×
71

72
    def maxBytesInTransaction(self):
1✔
73
        return ceil(max(
1✔
74
                    [f.parts[-1].endOfPart - f.startBitAddr for f in self._frames]
75
                    ) / 8)
76

77
    def parseTemplate(self):
1✔
78
        if self._tmpl is None:
1✔
79
            self._tmpl = TransTmpl(self._structT)
1✔
80
        if self._frames is None:
1✔
81
            DW = self.DATA_WIDTH
1✔
82
            frames = FrameTmpl.framesFromTransTmpl(
1✔
83
                        self._tmpl,
84
                        DW,
85
                        trimPaddingWordsOnStart=True,
86
                        trimPaddingWordsOnEnd=True)
87

88
            self._frames = list(frames)
1✔
89

90
    @override
1✔
91
    def hwDeclr(self):
1✔
92
        addClkRstn(self)
1✔
93
        self.dataOut = HwIOStruct(self._structT,
1✔
94
                                  tuple(),
95
                                  self._mkFieldHwIO)._m()
96

97
        g = self.get = HwIODataRdVld()  # data signal is addr of structure to download
1✔
98
        g.DATA_WIDTH = self.ADDR_WIDTH
1✔
99
        self.parseTemplate()
1✔
100

101
        with self._hwParamsShared():
1✔
102
            # interface for communication with datapump
103
            self.rDatapump = HwIOAxiRDatapump()._m()
1✔
104
            self.rDatapump.MAX_BYTES = self.maxBytesInTransaction()
1✔
105

106
        with self._hwParamsShared(exclude=({"ID_WIDTH"}, set())):
1✔
107
            self.parser = Axi4S_frameParser(self._structT,
1✔
108
                                           tmpl=self._tmpl,
109
                                           frames=self._frames)
110
            self.parser.SYNCHRONIZE_BY_LAST = False
1✔
111

112
        if self.SHARED_READY:
1!
113
            self.ready = HwIOSignal()
×
114

115
    def driveReqRem(self, req: AddrSizeHs, MAX_BITS: int):
1✔
116
        return req.rem(ceil((MAX_BITS % self.DATA_WIDTH) / 8))
1✔
117

118
    @override
1✔
119
    def hwImpl(self):
1✔
120
        propagateClkRstn(self)
1✔
121
        req = self.rDatapump.req
1✔
122

123
        if self.READ_ACK:
1!
124
            get = self.get
×
125
        else:
126
            get = HsBuilder(self, self.get).buff().end
1✔
127

128
        def propagateRequest(frame, indx):
1✔
129
            isLastFrame = indx == len(self._frames) - 1
1✔
130
            s = [
1✔
131
                req.addr(get.data + frame.startBitAddr // 8),
132
                req.len(frame.getWordCnt() - 1),
133
                self.driveReqRem(req, frame.parts[-1].endOfPart - frame.startBitAddr),
134
                req.vld(get.vld),
135
                get.rd(req.rd if isLastFrame else 0)
136
            ]
137

138
            ack = StreamNode(masters=[get], slaves=[self.rDatapump.req]).ack()
1✔
139
            return s, ack
1✔
140

141
        StaticForEach(self, self._frames, propagateRequest)
1✔
142

143
        r = self.rDatapump.r
1✔
144
        data_sig_to_exclude = []
1✔
145
        if self.ID_WIDTH:
1!
146
            req.id(self.ID)
×
147
        if hasattr(r, "id"):
1!
148
            data_sig_to_exclude.append(r.id)
×
149
        if hasattr(r, "strb"):
1!
150
            data_sig_to_exclude.append(r.strb)
×
151

152
        self.parser.dataIn(r, exclude=data_sig_to_exclude)
1✔
153

154
        for _, field in self._tmpl.HwIO_walkFlatten():
1✔
155
            p = field.getFieldPath()
1✔
156
            fieldHwIO = self.dataOut._fieldsToHwIOs[p]
1✔
157
            parserHwIO = self.parser.dataOut._fieldsToHwIOs[p]
1✔
158
            fieldHwIO(parserHwIO)
1✔
159

160

161
def _example_StructReader():
1✔
162
    from hwtLib.types.ctypes import uint16_t, uint32_t, uint64_t
×
163

164
    s = HStruct(
×
165
        (uint64_t, "item0"),  # tuples (type, name) where type has to be instance of Bits type
166
        (uint64_t, None),  # name = None means this field will be ignored
167
        (uint64_t, "item1"),
168
        (uint64_t, None),
169
        (uint16_t, "item2"),
170
        (uint16_t, "item3"),
171
        (uint32_t, "item4"),
172

173
        (uint32_t, None),
174
        (uint64_t, "item5"),  # this word is split on two bus words
175
        (uint32_t, None),
176

177
        (uint64_t, None),
178
        (uint64_t, None),
179
        (uint64_t, None),
180
        (uint64_t, "item6"),
181
        (uint64_t, "item7"),
182
        )
183

184
    m = StructReader(s)
×
185
    return m
×
186

187

188
if __name__ == "__main__":
189
    from hwt.synth import to_rtl_str
190
    
191
    m = _example_StructReader()
192
    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