4 from ..hdl
.ast
import *
8 class UnsignedEnum(Enum
):
14 class SignedEnum(Enum
):
20 class StringEnum(Enum
):
25 class ValueTestCase(FHDLTestCase
):
27 self
.assertIsInstance(Value
.wrap(0), Const
)
28 self
.assertIsInstance(Value
.wrap(True), Const
)
30 self
.assertIs(Value
.wrap(c
), c
)
31 with self
.assertRaises(TypeError,
32 msg
="Object ''str'' is not an nMigen value"):
35 def test_wrap_enum(self
):
36 e1
= Value
.wrap(UnsignedEnum
.FOO
)
37 self
.assertIsInstance(e1
, Const
)
38 self
.assertEqual(e1
.shape(), (2, False))
39 e2
= Value
.wrap(SignedEnum
.FOO
)
40 self
.assertIsInstance(e2
, Const
)
41 self
.assertEqual(e2
.shape(), (2, True))
43 def test_wrap_enum_wrong(self
):
44 with self
.assertRaises(TypeError,
45 msg
="Only enumerations with integer values can be converted to nMigen values"):
46 Value
.wrap(StringEnum
.FOO
)
49 with self
.assertRaises(TypeError,
50 msg
="Attempted to convert nMigen value to boolean"):
55 self
.assertEqual(len(Const(10)), 4)
57 def test_getitem_int(self
):
59 self
.assertIsInstance(s1
, Slice
)
60 self
.assertEqual(s1
.start
, 0)
61 self
.assertEqual(s1
.end
, 1)
63 self
.assertIsInstance(s2
, Slice
)
64 self
.assertEqual(s2
.start
, 3)
65 self
.assertEqual(s2
.end
, 4)
66 with self
.assertRaises(IndexError,
67 msg
="Cannot index 5 bits into 4-bit value"):
70 def test_getitem_slice(self
):
72 self
.assertIsInstance(s1
, Slice
)
73 self
.assertEqual(s1
.start
, 1)
74 self
.assertEqual(s1
.end
, 3)
76 self
.assertIsInstance(s2
, Slice
)
77 self
.assertEqual(s2
.start
, 1)
78 self
.assertEqual(s2
.end
, 2)
80 self
.assertIsInstance(s3
, Cat
)
81 self
.assertIsInstance(s3
.parts
[0], Slice
)
82 self
.assertEqual(s3
.parts
[0].start
, 0)
83 self
.assertEqual(s3
.parts
[0].end
, 1)
84 self
.assertIsInstance(s3
.parts
[1], Slice
)
85 self
.assertEqual(s3
.parts
[1].start
, 2)
86 self
.assertEqual(s3
.parts
[1].end
, 3)
87 self
.assertIsInstance(s3
.parts
[2], Slice
)
88 self
.assertEqual(s3
.parts
[2].start
, 4)
89 self
.assertEqual(s3
.parts
[2].end
, 5)
91 def test_getitem_wrong(self
):
92 with self
.assertRaises(TypeError,
93 msg
="Cannot index value with 'str'"):
97 class ConstTestCase(FHDLTestCase
):
99 self
.assertEqual(Const(0).shape(), (1, False))
100 self
.assertEqual(Const(1).shape(), (1, False))
101 self
.assertEqual(Const(10).shape(), (4, False))
102 self
.assertEqual(Const(-10).shape(), (5, True))
104 self
.assertEqual(Const(1, 4).shape(), (4, False))
105 self
.assertEqual(Const(1, (4, True)).shape(), (4, True))
106 self
.assertEqual(Const(0, (0, False)).shape(), (0, False))
108 def test_shape_bad(self
):
109 with self
.assertRaises(TypeError,
110 msg
="Width must be a non-negative integer, not '-1'"):
113 def test_normalization(self
):
114 self
.assertEqual(Const(0b10110, (5, True)).value
, -10)
116 def test_value(self
):
117 self
.assertEqual(Const(10).value
, 10)
120 self
.assertEqual(repr(Const(10)), "(const 4'd10)")
121 self
.assertEqual(repr(Const(-10)), "(const 5'sd-10)")
124 with self
.assertRaises(TypeError):
128 class OperatorTestCase(FHDLTestCase
):
130 v
= Const(0, 4).bool()
131 self
.assertEqual(repr(v
), "(b (const 4'd0))")
132 self
.assertEqual(v
.shape(), (1, False))
134 def test_invert(self
):
136 self
.assertEqual(repr(v
), "(~ (const 4'd0))")
137 self
.assertEqual(v
.shape(), (4, False))
140 v1
= -Const(0, (4, False))
141 self
.assertEqual(repr(v1
), "(- (const 4'd0))")
142 self
.assertEqual(v1
.shape(), (5, True))
143 v2
= -Const(0, (4, True))
144 self
.assertEqual(repr(v2
), "(- (const 4'sd0))")
145 self
.assertEqual(v2
.shape(), (4, True))
148 v1
= Const(0, (4, False)) + Const(0, (6, False))
149 self
.assertEqual(repr(v1
), "(+ (const 4'd0) (const 6'd0))")
150 self
.assertEqual(v1
.shape(), (7, False))
151 v2
= Const(0, (4, True)) + Const(0, (6, True))
152 self
.assertEqual(v2
.shape(), (7, True))
153 v3
= Const(0, (4, True)) + Const(0, (4, False))
154 self
.assertEqual(v3
.shape(), (6, True))
155 v4
= Const(0, (4, False)) + Const(0, (4, True))
156 self
.assertEqual(v4
.shape(), (6, True))
157 v5
= 10 + Const(0, 4)
158 self
.assertEqual(v5
.shape(), (5, False))
161 v1
= Const(0, (4, False)) - Const(0, (6, False))
162 self
.assertEqual(repr(v1
), "(- (const 4'd0) (const 6'd0))")
163 self
.assertEqual(v1
.shape(), (7, False))
164 v2
= Const(0, (4, True)) - Const(0, (6, True))
165 self
.assertEqual(v2
.shape(), (7, True))
166 v3
= Const(0, (4, True)) - Const(0, (4, False))
167 self
.assertEqual(v3
.shape(), (6, True))
168 v4
= Const(0, (4, False)) - Const(0, (4, True))
169 self
.assertEqual(v4
.shape(), (6, True))
170 v5
= 10 - Const(0, 4)
171 self
.assertEqual(v5
.shape(), (5, False))
174 v1
= Const(0, (4, False)) * Const(0, (6, False))
175 self
.assertEqual(repr(v1
), "(* (const 4'd0) (const 6'd0))")
176 self
.assertEqual(v1
.shape(), (10, False))
177 v2
= Const(0, (4, True)) * Const(0, (6, True))
178 self
.assertEqual(v2
.shape(), (10, True))
179 v3
= Const(0, (4, True)) * Const(0, (4, False))
180 self
.assertEqual(v3
.shape(), (8, True))
181 v5
= 10 * Const(0, 4)
182 self
.assertEqual(v5
.shape(), (8, False))
185 v1
= Const(0, (4, False)) & Const(0, (6, False))
186 self
.assertEqual(repr(v1
), "(& (const 4'd0) (const 6'd0))")
187 self
.assertEqual(v1
.shape(), (6, False))
188 v2
= Const(0, (4, True)) & Const(0, (6, True))
189 self
.assertEqual(v2
.shape(), (6, True))
190 v3
= Const(0, (4, True)) & Const(0, (4, False))
191 self
.assertEqual(v3
.shape(), (5, True))
192 v4
= Const(0, (4, False)) & Const(0, (4, True))
193 self
.assertEqual(v4
.shape(), (5, True))
194 v5
= 10 & Const(0, 4)
195 self
.assertEqual(v5
.shape(), (4, False))
198 v1
= Const(0, (4, False)) |
Const(0, (6, False))
199 self
.assertEqual(repr(v1
), "(| (const 4'd0) (const 6'd0))")
200 self
.assertEqual(v1
.shape(), (6, False))
201 v2
= Const(0, (4, True)) |
Const(0, (6, True))
202 self
.assertEqual(v2
.shape(), (6, True))
203 v3
= Const(0, (4, True)) |
Const(0, (4, False))
204 self
.assertEqual(v3
.shape(), (5, True))
205 v4
= Const(0, (4, False)) |
Const(0, (4, True))
206 self
.assertEqual(v4
.shape(), (5, True))
207 v5
= 10 |
Const(0, 4)
208 self
.assertEqual(v5
.shape(), (4, False))
211 v1
= Const(0, (4, False)) ^
Const(0, (6, False))
212 self
.assertEqual(repr(v1
), "(^ (const 4'd0) (const 6'd0))")
213 self
.assertEqual(v1
.shape(), (6, False))
214 v2
= Const(0, (4, True)) ^
Const(0, (6, True))
215 self
.assertEqual(v2
.shape(), (6, True))
216 v3
= Const(0, (4, True)) ^
Const(0, (4, False))
217 self
.assertEqual(v3
.shape(), (5, True))
218 v4
= Const(0, (4, False)) ^
Const(0, (4, True))
219 self
.assertEqual(v4
.shape(), (5, True))
220 v5
= 10 ^
Const(0, 4)
221 self
.assertEqual(v5
.shape(), (4, False))
224 v1
= Const(1, 4) << Const(4)
225 self
.assertEqual(repr(v1
), "(<< (const 4'd1) (const 3'd4))")
226 self
.assertEqual(v1
.shape(), (11, False))
227 v2
= Const(1, 4) << Const(-3)
228 self
.assertEqual(v2
.shape(), (7, False))
231 v1
= Const(1, 4) >> Const(4)
232 self
.assertEqual(repr(v1
), "(>> (const 4'd1) (const 3'd4))")
233 self
.assertEqual(v1
.shape(), (4, False))
234 v2
= Const(1, 4) >> Const(-3)
235 self
.assertEqual(v2
.shape(), (8, False))
238 v
= Const(0, 4) < Const(0, 6)
239 self
.assertEqual(repr(v
), "(< (const 4'd0) (const 6'd0))")
240 self
.assertEqual(v
.shape(), (1, False))
243 v
= Const(0, 4) <= Const(0, 6)
244 self
.assertEqual(repr(v
), "(<= (const 4'd0) (const 6'd0))")
245 self
.assertEqual(v
.shape(), (1, False))
248 v
= Const(0, 4) > Const(0, 6)
249 self
.assertEqual(repr(v
), "(> (const 4'd0) (const 6'd0))")
250 self
.assertEqual(v
.shape(), (1, False))
253 v
= Const(0, 4) >= Const(0, 6)
254 self
.assertEqual(repr(v
), "(>= (const 4'd0) (const 6'd0))")
255 self
.assertEqual(v
.shape(), (1, False))
258 v
= Const(0, 4) == Const(0, 6)
259 self
.assertEqual(repr(v
), "(== (const 4'd0) (const 6'd0))")
260 self
.assertEqual(v
.shape(), (1, False))
263 v
= Const(0, 4) != Const(0, 6)
264 self
.assertEqual(repr(v
), "(!= (const 4'd0) (const 6'd0))")
265 self
.assertEqual(v
.shape(), (1, False))
269 v1
= Mux(s
, Const(0, (4, False)), Const(0, (6, False)))
270 self
.assertEqual(repr(v1
), "(m (const 1'd0) (const 4'd0) (const 6'd0))")
271 self
.assertEqual(v1
.shape(), (6, False))
272 v2
= Mux(s
, Const(0, (4, True)), Const(0, (6, True)))
273 self
.assertEqual(v2
.shape(), (6, True))
274 v3
= Mux(s
, Const(0, (4, True)), Const(0, (4, False)))
275 self
.assertEqual(v3
.shape(), (5, True))
276 v4
= Mux(s
, Const(0, (4, False)), Const(0, (4, True)))
277 self
.assertEqual(v4
.shape(), (5, True))
281 self
.assertEqual(repr(v
), "(b (const 1'd0))")
282 self
.assertEqual(v
.shape(), (1, False))
285 v
= Const(0b101).any()
286 self
.assertEqual(repr(v
), "(r| (const 3'd5))")
289 v
= Const(0b101).all()
290 self
.assertEqual(repr(v
), "(r& (const 3'd5))")
293 v
= Const(0b101).xor()
294 self
.assertEqual(repr(v
), "(r^ (const 3'd5))")
296 def test_matches(self
):
298 self
.assertRepr(s
.matches(), "(const 1'd0)")
299 self
.assertRepr(s
.matches(1), """
300 (== (sig s) (const 1'd1))
302 self
.assertRepr(s
.matches(0, 1), """
303 (r| (cat (== (sig s) (const 1'd0)) (== (sig s) (const 1'd1))))
305 self
.assertRepr(s
.matches("10--"), """
306 (== (& (sig s) (const 4'd12)) (const 4'd8))
309 def test_matches_enum(self
):
310 s
= Signal
.enum(SignedEnum
)
311 self
.assertRepr(s
.matches(SignedEnum
.FOO
), """
312 (== (& (sig s) (const 2'd3)) (const 2'd3))
315 def test_matches_width_wrong(self
):
317 with self
.assertRaises(SyntaxError,
318 msg
="Match pattern '--' must have the same width as match value (which is 4)"):
320 with self
.assertWarns(SyntaxWarning,
321 msg
="Match pattern '10110' is wider than match value (which has width 4); "
322 "comparison will never be true"):
325 def test_matches_bits_wrong(self
):
327 with self
.assertRaises(SyntaxError,
328 msg
="Match pattern 'abc' must consist of 0, 1, and - (don't care) bits"):
331 def test_matches_pattern_wrong(self
):
333 with self
.assertRaises(SyntaxError,
334 msg
="Match pattern must be an integer, a string, or an enumeration, not 1.0"):
338 with self
.assertRaises(TypeError):
339 hash(Const(0) + Const(0))
342 class SliceTestCase(FHDLTestCase
):
343 def test_shape(self
):
345 self
.assertEqual(s1
.shape(), (1, False))
347 self
.assertEqual(s2
.shape(), (2, False))
349 def test_start_end_negative(self
):
352 self
.assertEqual((s1
.start
, s1
.end
), (0, 7))
353 s1
= Slice(c
, -4, -1)
354 self
.assertEqual((s1
.start
, s1
.end
), (4, 7))
356 def test_start_end_wrong(self
):
357 with self
.assertRaises(TypeError,
358 msg
="Slice start must be an integer, not ''x''"):
360 with self
.assertRaises(TypeError,
361 msg
="Slice end must be an integer, not ''x''"):
364 def test_start_end_out_of_range(self
):
366 with self
.assertRaises(IndexError,
367 msg
="Cannot start slice 10 bits into 8-bit value"):
369 with self
.assertRaises(IndexError,
370 msg
="Cannot end slice 12 bits into 8-bit value"):
372 with self
.assertRaises(IndexError,
373 msg
="Slice start 4 must be less than slice end 2"):
378 self
.assertEqual(repr(s1
), "(slice (const 4'd10) 2:3)")
381 class BitSelectTestCase(FHDLTestCase
):
384 self
.s
= Signal
.range(self
.c
.width
)
386 def test_shape(self
):
387 s1
= self
.c
.bit_select(self
.s
, 2)
388 self
.assertEqual(s1
.shape(), (2, False))
389 s2
= self
.c
.bit_select(self
.s
, 0)
390 self
.assertEqual(s2
.shape(), (0, False))
392 def test_stride(self
):
393 s1
= self
.c
.bit_select(self
.s
, 2)
394 self
.assertEqual(s1
.stride
, 1)
396 def test_width_bad(self
):
397 with self
.assertRaises(TypeError):
398 self
.c
.bit_select(self
.s
, -1)
401 s
= self
.c
.bit_select(self
.s
, 2)
402 self
.assertEqual(repr(s
), "(part (const 8'd0) (sig s) 2 1)")
405 class WordSelectTestCase(FHDLTestCase
):
408 self
.s
= Signal
.range(self
.c
.width
)
410 def test_shape(self
):
411 s1
= self
.c
.word_select(self
.s
, 2)
412 self
.assertEqual(s1
.shape(), (2, False))
414 def test_stride(self
):
415 s1
= self
.c
.word_select(self
.s
, 2)
416 self
.assertEqual(s1
.stride
, 2)
418 def test_width_bad(self
):
419 with self
.assertRaises(TypeError):
420 self
.c
.word_select(self
.s
, 0)
421 with self
.assertRaises(TypeError):
422 self
.c
.word_select(self
.s
, -1)
425 s
= self
.c
.word_select(self
.s
, 2)
426 self
.assertEqual(repr(s
), "(part (const 8'd0) (sig s) 2 2)")
429 class CatTestCase(FHDLTestCase
):
430 def test_shape(self
):
432 self
.assertEqual(c0
.shape(), (0, False))
434 self
.assertEqual(c1
.shape(), (4, False))
435 c2
= Cat(Const(10), Const(1))
436 self
.assertEqual(c2
.shape(), (5, False))
437 c3
= Cat(Const(10), Const(1), Const(0))
438 self
.assertEqual(c3
.shape(), (6, False))
441 c1
= Cat(Const(10), Const(1))
442 self
.assertEqual(repr(c1
), "(cat (const 4'd10) (const 1'd1))")
445 class ReplTestCase(FHDLTestCase
):
446 def test_shape(self
):
447 s1
= Repl(Const(10), 3)
448 self
.assertEqual(s1
.shape(), (12, False))
449 s2
= Repl(Const(10), 0)
450 self
.assertEqual(s2
.shape(), (0, False))
452 def test_count_wrong(self
):
453 with self
.assertRaises(TypeError):
455 with self
.assertRaises(TypeError):
456 Repl(Const(10), "str")
459 s
= Repl(Const(10), 3)
460 self
.assertEqual(repr(s
), "(repl (const 4'd10) 3)")
463 class ArrayTestCase(FHDLTestCase
):
464 def test_acts_like_array(self
):
466 self
.assertSequenceEqual(a
, [1,2,3])
467 self
.assertEqual(a
[1], 2)
469 self
.assertSequenceEqual(a
, [1,4,3])
471 self
.assertSequenceEqual(a
, [1,3])
473 self
.assertSequenceEqual(a
, [1,2,3])
475 def test_becomes_immutable(self
):
477 s1
= Signal
.range(len(a
))
478 s2
= Signal
.range(len(a
))
481 with self
.assertRaisesRegex(ValueError,
482 regex
=r
"^Array can no longer be mutated after it was indexed with a value at "):
484 with self
.assertRaisesRegex(ValueError,
485 regex
=r
"^Array can no longer be mutated after it was indexed with a value at "):
487 with self
.assertRaisesRegex(ValueError,
488 regex
=r
"^Array can no longer be mutated after it was indexed with a value at "):
493 self
.assertEqual(repr(a
), "(array mutable [1, 2, 3])")
494 s
= Signal
.range(len(a
))
496 self
.assertEqual(repr(a
), "(array [1, 2, 3])")
499 class ArrayProxyTestCase(FHDLTestCase
):
500 def test_index_shape(self
):
501 m
= Array(Array(x
* y
for y
in range(1, 4)) for x
in range(1, 4))
505 self
.assertEqual(v
.shape(), (4, False))
507 def test_attr_shape(self
):
508 from collections
import namedtuple
509 pair
= namedtuple("pair", ("p", "n"))
510 a
= Array(pair(i
, -i
) for i
in range(10))
511 s
= Signal
.range(len(a
))
513 self
.assertEqual(v
.p
.shape(), (4, False))
514 self
.assertEqual(v
.n
.shape(), (6, True))
520 self
.assertEqual(repr(v
), "(proxy (array [1, 2, 3]) (sig s))")
523 class SignalTestCase(FHDLTestCase
):
524 def test_shape(self
):
526 self
.assertEqual(s1
.shape(), (1, False))
528 self
.assertEqual(s2
.shape(), (2, False))
529 s3
= Signal((2, False))
530 self
.assertEqual(s3
.shape(), (2, False))
531 s4
= Signal((2, True))
532 self
.assertEqual(s4
.shape(), (2, True))
534 self
.assertEqual(s5
.shape(), (0, False))
535 s6
= Signal
.range(16)
536 self
.assertEqual(s6
.shape(), (4, False))
537 s7
= Signal
.range(4, 16)
538 self
.assertEqual(s7
.shape(), (4, False))
539 s8
= Signal
.range(-4, 16)
540 self
.assertEqual(s8
.shape(), (5, True))
541 s9
= Signal
.range(-20, 16)
542 self
.assertEqual(s9
.shape(), (6, True))
543 s10
= Signal
.range(0)
544 self
.assertEqual(s10
.shape(), (1, False))
545 s11
= Signal
.range(1)
546 self
.assertEqual(s11
.shape(), (1, False))
548 with warnings
.catch_warnings():
549 warnings
.filterwarnings(action
="ignore", category
=DeprecationWarning)
551 self
.assertEqual(d6
.shape(), (4, False))
552 d7
= Signal(min=4, max=16)
553 self
.assertEqual(d7
.shape(), (4, False))
554 d8
= Signal(min=-4, max=16)
555 self
.assertEqual(d8
.shape(), (5, True))
556 d9
= Signal(min=-20, max=16)
557 self
.assertEqual(d9
.shape(), (6, True))
559 self
.assertEqual(d10
.shape(), (0, False))
561 def test_shape_bad(self
):
562 with self
.assertRaises(TypeError,
563 msg
="Width must be a non-negative integer, not '-10'"):
566 def test_min_max_deprecated(self
):
567 with self
.assertWarns(DeprecationWarning,
568 msg
="instead of `Signal(min=0, max=10)`, use `Signal.range(0, 10)`"):
570 with warnings
.catch_warnings():
571 warnings
.filterwarnings(action
="ignore", category
=DeprecationWarning)
572 with self
.assertRaises(ValueError,
573 msg
="Lower bound 10 should be less or equal to higher bound 4"):
574 Signal(min=10, max=4)
575 with self
.assertRaises(ValueError,
576 msg
="Only one of bits/signedness or bounds may be specified"):
581 self
.assertEqual(s1
.name
, "s1")
582 s2
= Signal(name
="sig")
583 self
.assertEqual(s2
.name
, "sig")
585 def test_reset(self
):
586 s1
= Signal(4, reset
=0b111, reset_less
=True)
587 self
.assertEqual(s1
.reset
, 0b111)
588 self
.assertEqual(s1
.reset_less
, True)
590 def test_reset_narrow(self
):
591 with self
.assertWarns(SyntaxWarning,
592 msg
="Reset value 8 requires 4 bits to represent, but the signal only has 3 bits"):
594 with self
.assertWarns(SyntaxWarning,
595 msg
="Reset value 4 requires 4 bits to represent, but the signal only has 3 bits"):
596 Signal((3, True), reset
=4)
597 with self
.assertWarns(SyntaxWarning,
598 msg
="Reset value -5 requires 4 bits to represent, but the signal only has 3 bits"):
599 Signal((3, True), reset
=-5)
601 def test_attrs(self
):
603 self
.assertEqual(s1
.attrs
, {})
604 s2
= Signal(attrs
={"no_retiming": True})
605 self
.assertEqual(s2
.attrs
, {"no_retiming": True})
609 self
.assertEqual(repr(s1
), "(sig s1)")
612 s1
= Signal
.like(Signal(4))
613 self
.assertEqual(s1
.shape(), (4, False))
614 s2
= Signal
.like(Signal
.range(-15, 1))
615 self
.assertEqual(s2
.shape(), (5, True))
616 s3
= Signal
.like(Signal(4, reset
=0b111, reset_less
=True))
617 self
.assertEqual(s3
.reset
, 0b111)
618 self
.assertEqual(s3
.reset_less
, True)
619 s4
= Signal
.like(Signal(attrs
={"no_retiming": True}))
620 self
.assertEqual(s4
.attrs
, {"no_retiming": True})
621 s5
= Signal
.like(Signal(decoder
=str))
622 self
.assertEqual(s5
.decoder
, str)
624 self
.assertEqual(s6
.shape(), (4, False))
625 s7
= [Signal
.like(Signal(4))][0]
626 self
.assertEqual(s7
.name
, "$like")
627 s8
= Signal
.like(s1
, name_suffix
="_ff")
628 self
.assertEqual(s8
.name
, "s1_ff")
630 def test_decoder(self
):
634 s
= Signal(decoder
=Color
)
635 self
.assertEqual(s
.decoder(1), "RED/1")
636 self
.assertEqual(s
.decoder(3), "3")
639 s1
= Signal
.enum(UnsignedEnum
)
640 self
.assertEqual(s1
.shape(), (2, False))
641 s2
= Signal
.enum(SignedEnum
)
642 self
.assertEqual(s2
.shape(), (2, True))
643 self
.assertEqual(s2
.decoder(SignedEnum
.FOO
), "FOO/-1")
646 class ClockSignalTestCase(FHDLTestCase
):
647 def test_domain(self
):
649 self
.assertEqual(s1
.domain
, "sync")
650 s2
= ClockSignal("pix")
651 self
.assertEqual(s2
.domain
, "pix")
653 with self
.assertRaises(TypeError,
654 msg
="Clock domain name must be a string, not '1'"):
657 def test_shape(self
):
658 self
.assertEqual(ClockSignal().shape(), (1, False))
662 self
.assertEqual(repr(s1
), "(clk sync)")
664 def test_wrong_name_comb(self
):
665 with self
.assertRaises(ValueError,
666 msg
="Domain 'comb' does not have a clock"):
670 class ResetSignalTestCase(FHDLTestCase
):
671 def test_domain(self
):
673 self
.assertEqual(s1
.domain
, "sync")
674 s2
= ResetSignal("pix")
675 self
.assertEqual(s2
.domain
, "pix")
677 with self
.assertRaises(TypeError,
678 msg
="Clock domain name must be a string, not '1'"):
681 def test_shape(self
):
682 self
.assertEqual(ResetSignal().shape(), (1, False))
686 self
.assertEqual(repr(s1
), "(rst sync)")
688 def test_wrong_name_comb(self
):
689 with self
.assertRaises(ValueError,
690 msg
="Domain 'comb' does not have a reset"):
694 class MockUserValue(UserValue
):
695 def __init__(self
, lowered
):
698 self
.lowered
= lowered
701 self
.lower_count
+= 1
705 class UserValueTestCase(FHDLTestCase
):
706 def test_shape(self
):
707 uv
= MockUserValue(1)
708 self
.assertEqual(uv
.shape(), (1, False))
710 self
.assertEqual(uv
.shape(), (1, False))
711 self
.assertEqual(uv
.lower_count
, 1)
714 class SampleTestCase(FHDLTestCase
):
715 def test_const(self
):
716 s
= Sample(1, 1, "sync")
717 self
.assertEqual(s
.shape(), (1, False))
719 def test_signal(self
):
720 s1
= Sample(Signal(2), 1, "sync")
721 self
.assertEqual(s1
.shape(), (2, False))
722 s2
= Sample(ClockSignal(), 1, "sync")
723 s3
= Sample(ResetSignal(), 1, "sync")
725 def test_wrong_value_operator(self
):
726 with self
.assertRaises(TypeError,
727 "Sampled value must be a signal or a constant, not "
728 "(+ (sig $signal) (const 1'd1))"):
729 Sample(Signal() + 1, 1, "sync")
731 def test_wrong_clocks_neg(self
):
732 with self
.assertRaises(ValueError,
733 "Cannot sample a value 1 cycles in the future"):
734 Sample(Signal(), -1, "sync")
736 def test_wrong_domain(self
):
737 with self
.assertRaises(TypeError,
738 "Domain name must be a string or None, not 0"):
739 Sample(Signal(), 1, 0)
742 class InitialTestCase(FHDLTestCase
):
743 def test_initial(self
):
745 self
.assertEqual(i
.shape(), (1, False))