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

Nic30 / hdlConvertorAst / f74f4419-a0c6-4e38-b28c-86a5e8965982

21 Nov 2024 12:00PM UTC coverage: 56.424%. Remained the same
f74f4419-a0c6-4e38-b28c-86a5e8965982

push

circleci

Nic30
test: update test files for new imports in to.basic_hdl_sim_model

794 of 1664 branches covered (47.72%)

Branch coverage included in aggregate %.

2860 of 4812 relevant lines covered (59.43%)

0.59 hits per line

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

69.14
/hdlConvertorAst/to/vhdl/expr.py
1
from hdlConvertorAst.hdlAst._expr import HdlOpType, HdlValueId, HdlValueInt, \
1✔
2
    HdlAll, HdlOp, HdlOthers
3
from hdlConvertorAst.py_ver_compatibility import is_str
1✔
4
from hdlConvertorAst.to.common import ToHdlCommon, ASSOCIATIVITY
1✔
5
from hdlConvertorAst.to.hdlUtils import iter_with_last, Indent
1✔
6
from copy import copy
1✔
7

8
L = ASSOCIATIVITY.L_TO_R
1✔
9
R = ASSOCIATIVITY.R_TO_L
1✔
10

11

12
# https://www.csee.umbc.edu/portal/help/VHDL/operator.html
13
class ToVhdl2008Expr(ToHdlCommon):
1✔
14
    GENERIC_UNARY_OPS = copy(ToHdlCommon.GENERIC_UNARY_OPS)
1✔
15
    GENERIC_UNARY_OPS.update({
1✔
16
        HdlOpType.NEG: "NOT ",
17
        HdlOpType.NEG_LOG: "NOT ",
18
        HdlOpType.RANGE: "RANGE ",  # used in HdlPhysicalDef
19
    })
20
    BITWISE_BIN_OPS = {
1✔
21
        HdlOpType.AND, HdlOpType.AND_LOG,
22
        HdlOpType.OR, HdlOpType.OR_LOG,
23
        HdlOpType.XOR, HdlOpType.NAND,
24
        HdlOpType.NOR, HdlOpType.XNOR
25
    }
26
    GENERIC_BIN_OPS = {
1✔
27
        HdlOpType.AND: " AND ",
28
        HdlOpType.AND_LOG: " AND ",
29
        HdlOpType.OR: " OR ",
30
        HdlOpType.OR_LOG: " OR ",
31
        HdlOpType.DIV: " / ",
32
        HdlOpType.MOD: " MOD ",
33
        HdlOpType.REM: " REM ",
34
        HdlOpType.POW: " ** ",
35
        HdlOpType.NAND: " NAND ",
36
        HdlOpType.NOR: " NOR ",
37
        HdlOpType.XOR: " XOR ",
38
        HdlOpType.XNOR: " XNOR ",
39
        HdlOpType.EQ: ' = ',
40
        HdlOpType.NE: " /= ",
41
        HdlOpType.EQ_MATCH: ' ?= ',
42
        HdlOpType.NE_MATCH: ' ?/= ',
43
        HdlOpType.LT_MATCH: ' ?< ',
44
        HdlOpType.LE_MATCH: ' ?<= ',
45
        HdlOpType.GT_MATCH: ' ?> ',
46
        HdlOpType.GE_MATCH: ' ?>= ',
47
        HdlOpType.TO: " TO ",
48
        HdlOpType.DOWNTO: " DOWNTO ",
49
        HdlOpType.ARROW: " => ",
50
        HdlOpType.MAP_ASSOCIATION: " => ",
51
        HdlOpType.RANGE: " RANGE ",
52
        HdlOpType.CONCAT: " & ",
53
        HdlOpType.ROL: " ROL ",
54
        HdlOpType.ROR: " ROR ",
55
        HdlOpType.SLA: " SLA ",
56
        HdlOpType.SRA: " SRA ",
57
        HdlOpType.SLL: " SLL ",
58
        HdlOpType.SRL: " SRL ",
59
        HdlOpType.UNIT_SPEC: " ",
60
    }
61
    EQ_NEQ_OPS = (
1✔
62
        HdlOpType.EQ,
63
        HdlOpType.NE
64
    )
65
    GENERIC_BIN_OPS.update(ToHdlCommon.GENERIC_BIN_OPS)
1✔
66
    NUM_BASES = {
1✔
67
        2: "",
68
        8: "O",
69
        16: "X",
70
        256: "",  # 'X' literals
71
    }
72
    # https://vhdlwhiz.com/operator-precedence-in-vhdl/
73
    OP_PRECEDENCE = {
1✔
74
        HdlOpType.UNIT_SPEC: (0, L),
75
        HdlOpType.DOT: (1, L),
76
        HdlOpType.CALL: (1, L),
77
        HdlOpType.INDEX: (1, L),
78
        HdlOpType.RISING: (1, L),
79
        HdlOpType.FALLING: (1, L),
80
        HdlOpType.APOSTROPHE: (1, L),
81

82
        HdlOpType.POW: (2, R),
83
        HdlOpType.ABS: (2, L),
84
        HdlOpType.NEG: (2, R),
85
        HdlOpType.NEG_LOG: (2, R),
86

87
        HdlOpType.MUL: (3, L),
88
        HdlOpType.DIV: (3, L),
89
        HdlOpType.MOD: (3, L),
90
        HdlOpType.REM: (3, L),
91

92
        HdlOpType.PLUS_UNARY: (4, R),
93
        HdlOpType.MINUS_UNARY: (4, R),
94

95
        HdlOpType.CONCAT: (5, L),
96
        HdlOpType.ADD: (5, L),
97
        HdlOpType.SUB: (5, L),
98

99
        HdlOpType.SLL: (6, L),
100
        HdlOpType.SRL: (6, L),
101
        HdlOpType.SLA: (6, L),
102
        HdlOpType.SRA: (6, L),
103
        HdlOpType.ROL: (6, L),
104
        HdlOpType.ROR: (6, L),
105

106
        HdlOpType.EQ: (7, L),
107
        HdlOpType.NE: (7, L),
108
        HdlOpType.GT: (7, L),
109
        HdlOpType.LT: (7, L),
110
        HdlOpType.GE: (7, L),
111
        HdlOpType.LE: (7, L),
112
        HdlOpType.EQ_MATCH: (7, L),
113
        HdlOpType.NE_MATCH: (7, L),
114
        HdlOpType.LT_MATCH: (7, L),
115
        HdlOpType.LE_MATCH: (7, L),
116
        HdlOpType.GT_MATCH: (7, L),
117
        HdlOpType.GE_MATCH: (7, L),
118

119
        HdlOpType.AND: (8, L),
120
        HdlOpType.OR: (8, L),
121
        HdlOpType.NAND: (8, ASSOCIATIVITY.NONE),
122
        HdlOpType.NOR: (8, ASSOCIATIVITY.NONE),
123
        HdlOpType.XOR: (8, L),
124
        HdlOpType.XNOR: (8, ASSOCIATIVITY.NONE),
125

126
        HdlOpType.DOWNTO: (9, L),
127
        HdlOpType.TO: (9, L),
128
        HdlOpType.TERNARY: (9, R),
129

130
        HdlOpType.RANGE: (10, L),
131
        HdlOpType.ARROW: (11, L),
132
        HdlOpType.MAP_ASSOCIATION: (11, L),
133
    }
134

135
    def visit_HdlValueInt(self, o):
1✔
136
        w = self.out.write
1✔
137
        v = o.val
1✔
138
        bits = o.bits
1✔
139
        if is_str(v):
1✔
140
            v = v.upper()
1✔
141
            if o.base == 256:
1✔
142
                w("'%s'" % v)
1✔
143
            else:
144
                w('%s"%s"' % (self.NUM_BASES[o.base], v))
1✔
145
            return
1✔
146

147
        if bits is None:
1!
148
            if o.base is not None:
1!
149
                b = self.NUM_BASES[o.base]
×
150
                if o.base == 256:
×
151
                    w("'%d'" % v)
×
152
                elif o.base == 16:
×
153
                    w('%s"%X"' % (b, v))
×
154
                elif o.base == 8:
×
155
                    w('%s"%o"' % (b, v))
×
156
                elif o.base == 2:
×
157
                    w('{0}"{1:b}"'.format(b, v))
×
158
                else:
159
                    raise NotImplementedError(o.base)
160
            else:
161
                w(str(v))
1✔
162
            return
1✔
163
        elif bits % 8 == 0:
×
164
            f = 'X"{0:0%dx}"' % (bits / 8)
×
165
        else:
166
            f = '"{0:0%db}"' % (bits)
×
167
        w(f.format(v))
×
168

169
    def _visit_operand_parentheses_extra_check(self, op_my, precedence_my, asoc_my,
1✔
170
                                               op_parent, precedence_parent, asoc_parent,
171
                                               left, right):
172
        if super(ToVhdl2008Expr, self)._visit_operand_parentheses_extra_check(
1!
173
                op_my, precedence_my, asoc_my,
174
                op_parent, precedence_parent, asoc_parent, left, right):
175
            return True
×
176
        elif op_my in self.BITWISE_BIN_OPS and\
1✔
177
                op_parent in self.BITWISE_BIN_OPS and\
178
                op_my != op_parent:
179
            return True
1✔
180
        else:
181
            return False
1✔
182

183
    def _visit_operand(self, operand, i,
1✔
184
        parent,
185
        expr_requires_parenthesis,
186
        cancel_parenthesis):
187
        if parent.fn in self.EQ_NEQ_OPS and isinstance(operand, HdlOp) and operand.fn in self.EQ_NEQ_OPS:
1!
188
            # handle the case (a = b) = (c = d) where to boolean conversion is applied during a = b evaluation
189
            expr_requires_parenthesis = True
×
190

191
        return ToHdlCommon._visit_operand(self, operand, i, parent, expr_requires_parenthesis, cancel_parenthesis)
1✔
192

193
    def visit_HdlOp(self, o):
1✔
194
        """
195
        :type o: HdlOp
196
        """
197
        fn = o.ops[0]
1✔
198
        if fn == HdlValueId("assert"):
1✔
199
            self.visit_assert(o.ops[1:])
1✔
200
            return
1✔
201
        elif fn == HdlValueId("report"):
1!
202
            self.visit_report(o.ops[1:])
×
203
            return
×
204

205
        w = self.out.write
1✔
206
        op = o.fn
1✔
207
        if op == HdlOpType.RISING:
1✔
208
            w("RISING_EDGE(")
1✔
209
            self.visit_iHdlExpr(o.ops[0])
1✔
210
            w(")")
1✔
211
        elif op == HdlOpType.FALLING:
1✔
212
            w("FALLING_EDGE(")
1✔
213
            self.visit_iHdlExpr(o.ops[0])
1✔
214
            w(")")
1✔
215
        elif op == HdlOpType.INDEX or op == HdlOpType.CALL:
1✔
216
            self._visit_operand(o.ops[0], 0, o, False, False)
1✔
217
            w("(")
1✔
218
            for isLast, (o_i, _o) in iter_with_last(enumerate(o.ops[1:])):
1✔
219
                self._visit_operand(_o, o_i + 1, o, False, True)
1✔
220
                if not isLast:
1!
221
                    w(", ")
×
222
            w(")")
1✔
223
        elif op == HdlOpType.TERNARY:
1✔
224
            has_3_ops = len(o.ops) == 3
1✔
225
            if has_3_ops:
1!
226
                cond, o0, o1 = o.ops
1✔
227
            else:
228
                cond, o0 = o.ops
×
229

230
            self._visit_operand(o0, 1, o, True, False)
1✔
231
            w(" WHEN ")
1✔
232
            self._visit_operand(cond, 0, o, True, False)
1✔
233
            if has_3_ops:
1!
234
                if isinstance(o1, HdlOp) and o1.fn == HdlOpType.TERNARY:
1!
235
                    w(" ELSE\n")
×
236
                    self.visit_iHdlExpr(o1)  # must not have parenthesis
×
237
                else:
238
                    w(" ELSE ")
1✔
239
                    self._visit_operand(o1, 2, o, False, False)
1✔
240
        elif op == HdlOpType.APOSTROPHE:
1✔
241
            self._visit_operand(o.ops[0], 0, o, True, False)
1✔
242
            w("'")
1✔
243
            args = o.ops[1]
1✔
244
            if isinstance(args, list):
1!
245
                self.visit_iHdlExpr(args)
×
246
            elif isinstance(args, HdlValueId):
1!
247
                # normal attribute
248
                self.visit_iHdlExpr(args)
×
249
            else:
250
                w("(")
1✔
251
                self._visit_operand(args, 0, o, False, True)
1✔
252
                w(")")
1✔
253
        elif op == HdlOpType.ABS:
1!
254
            w("ABS(")
×
255
            self.visit_iHdlExpr(o.ops[0])
×
256
            w(")")
×
257
        elif op == HdlOpType.DEFINE_RESOLVER:
1!
258
            assert self.in_typedef
×
259
            self.visit_iHdlExpr(o.ops[0])
×
260
            w(" ")
×
261
            self.visit_iHdlExpr(o.ops[1])
×
262
        else:
263
            return ToHdlCommon.visit_HdlOp(self, o)
1✔
264

265
    def visit_str(self, o):
1✔
266
        """
267
        :type o: str
268
        """
269
        w = self.out.write
1✔
270
        if o == "":
1!
271
            w('""')
×
272
        else:
273
            ESCAPES = {
1✔
274
                '\n': 'LF\n',
275
                '\r': 'CR'
276
            }
277
            CONC = self.GENERIC_BIN_OPS[HdlOpType.CONCAT]
1✔
278
            first = True
1✔
279
            in_string_lit = False
1✔
280
            for c in o:
1✔
281
                esc = ESCAPES.get(c, None)
1✔
282
                if esc is None:
1!
283
                    if not in_string_lit:
1✔
284
                        if not first:
1!
285
                            # first character after escape sequence
286
                            w(CONC)
×
287
                        w('"')  # string start "
1✔
288
                        in_string_lit = True
1✔
289
                    # character inside ""
290
                    w(c)
1✔
291
                else:
292
                    if not first:
×
293
                        if in_string_lit:
×
294
                            w('"')  # string end "
×
295
                            # escape sequence behind string
296
                        w(CONC)
×
297
                    in_string_lit = False
×
298
                    # escape name
299
                    w(esc)
×
300
                first = False
1✔
301

302
            if in_string_lit:
1!
303
                w('"')  # string end "
1✔
304

305
    def visit_iHdlExpr(self, expr):
1✔
306
        w = self.out.write
1✔
307
        if expr is HdlAll:
1✔
308
            w("ALL")
1✔
309
        elif expr is HdlOthers:
1!
310
            w("OTHERS")
×
311
        elif expr is None:
1!
312
            if self.in_typedef:
×
313
                w("<>")
×
314
            else:
315
                w("OPEN")
×
316
        elif is_str(expr):
1✔
317
            self.visit_str(expr)
1✔
318
        elif isinstance(expr, list):
1✔
319
            with_nl = len(expr) > 3
1✔
320
            if with_nl:
1!
321
                w("(\n")
1✔
322
            else:
323
                w("(")
×
324
            with Indent(self.out):
1✔
325
                for is_last, elem in iter_with_last(expr):
1✔
326
                    self.visit_iHdlExpr(elem)
1✔
327
                    if not is_last:
1✔
328
                        if with_nl:
1!
329
                            w(",\n")
1✔
330
                        else:
331
                            w(", ")
×
332
            w(")")
1✔
333
        else:
334
            ToHdlCommon.visit_iHdlExpr(self, expr)
1✔
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

© 2025 Coveralls, Inc