hdl.ast: implement Initial.
[nmigen.git] / nmigen / test / test_hdl_ast.py
1 from enum import Enum
2
3 from ..hdl.ast import *
4 from .tools import *
5
6
7 class ValueTestCase(FHDLTestCase):
8 def test_wrap(self):
9 self.assertIsInstance(Value.wrap(0), Const)
10 self.assertIsInstance(Value.wrap(True), Const)
11 c = Const(0)
12 self.assertIs(Value.wrap(c), c)
13 with self.assertRaises(TypeError,
14 msg="Object ''str'' is not an nMigen value"):
15 Value.wrap("str")
16
17 def test_bool(self):
18 with self.assertRaises(TypeError,
19 msg="Attempted to convert nMigen value to boolean"):
20 if Const(0):
21 pass
22
23 def test_len(self):
24 self.assertEqual(len(Const(10)), 4)
25
26 def test_getitem_int(self):
27 s1 = Const(10)[0]
28 self.assertIsInstance(s1, Slice)
29 self.assertEqual(s1.start, 0)
30 self.assertEqual(s1.end, 1)
31 s2 = Const(10)[-1]
32 self.assertIsInstance(s2, Slice)
33 self.assertEqual(s2.start, 3)
34 self.assertEqual(s2.end, 4)
35 with self.assertRaises(IndexError,
36 msg="Cannot index 5 bits into 4-bit value"):
37 Const(10)[5]
38
39 def test_getitem_slice(self):
40 s1 = Const(10)[1:3]
41 self.assertIsInstance(s1, Slice)
42 self.assertEqual(s1.start, 1)
43 self.assertEqual(s1.end, 3)
44 s2 = Const(10)[1:-2]
45 self.assertIsInstance(s2, Slice)
46 self.assertEqual(s2.start, 1)
47 self.assertEqual(s2.end, 2)
48 s3 = Const(31)[::2]
49 self.assertIsInstance(s3, Cat)
50 self.assertIsInstance(s3.parts[0], Slice)
51 self.assertEqual(s3.parts[0].start, 0)
52 self.assertEqual(s3.parts[0].end, 1)
53 self.assertIsInstance(s3.parts[1], Slice)
54 self.assertEqual(s3.parts[1].start, 2)
55 self.assertEqual(s3.parts[1].end, 3)
56 self.assertIsInstance(s3.parts[2], Slice)
57 self.assertEqual(s3.parts[2].start, 4)
58 self.assertEqual(s3.parts[2].end, 5)
59
60 def test_getitem_wrong(self):
61 with self.assertRaises(TypeError,
62 msg="Cannot index value with 'str'"):
63 Const(31)["str"]
64
65
66 class ConstTestCase(FHDLTestCase):
67 def test_shape(self):
68 self.assertEqual(Const(0).shape(), (1, False))
69 self.assertEqual(Const(1).shape(), (1, False))
70 self.assertEqual(Const(10).shape(), (4, False))
71 self.assertEqual(Const(-10).shape(), (5, True))
72
73 self.assertEqual(Const(1, 4).shape(), (4, False))
74 self.assertEqual(Const(1, (4, True)).shape(), (4, True))
75 self.assertEqual(Const(0, (0, False)).shape(), (0, False))
76
77 def test_shape_bad(self):
78 with self.assertRaises(TypeError,
79 msg="Width must be a non-negative integer, not '-1'"):
80 Const(1, -1)
81
82 def test_normalization(self):
83 self.assertEqual(Const(0b10110, (5, True)).value, -10)
84
85 def test_value(self):
86 self.assertEqual(Const(10).value, 10)
87
88 def test_repr(self):
89 self.assertEqual(repr(Const(10)), "(const 4'd10)")
90 self.assertEqual(repr(Const(-10)), "(const 5'sd-10)")
91
92 def test_hash(self):
93 with self.assertRaises(TypeError):
94 hash(Const(0))
95
96
97 class OperatorTestCase(FHDLTestCase):
98 def test_bool(self):
99 v = Const(0, 4).bool()
100 self.assertEqual(repr(v), "(b (const 4'd0))")
101 self.assertEqual(v.shape(), (1, False))
102
103 def test_invert(self):
104 v = ~Const(0, 4)
105 self.assertEqual(repr(v), "(~ (const 4'd0))")
106 self.assertEqual(v.shape(), (4, False))
107
108 def test_neg(self):
109 v1 = -Const(0, (4, False))
110 self.assertEqual(repr(v1), "(- (const 4'd0))")
111 self.assertEqual(v1.shape(), (5, True))
112 v2 = -Const(0, (4, True))
113 self.assertEqual(repr(v2), "(- (const 4'sd0))")
114 self.assertEqual(v2.shape(), (4, True))
115
116 def test_add(self):
117 v1 = Const(0, (4, False)) + Const(0, (6, False))
118 self.assertEqual(repr(v1), "(+ (const 4'd0) (const 6'd0))")
119 self.assertEqual(v1.shape(), (7, False))
120 v2 = Const(0, (4, True)) + Const(0, (6, True))
121 self.assertEqual(v2.shape(), (7, True))
122 v3 = Const(0, (4, True)) + Const(0, (4, False))
123 self.assertEqual(v3.shape(), (6, True))
124 v4 = Const(0, (4, False)) + Const(0, (4, True))
125 self.assertEqual(v4.shape(), (6, True))
126 v5 = 10 + Const(0, 4)
127 self.assertEqual(v5.shape(), (5, False))
128
129 def test_sub(self):
130 v1 = Const(0, (4, False)) - Const(0, (6, False))
131 self.assertEqual(repr(v1), "(- (const 4'd0) (const 6'd0))")
132 self.assertEqual(v1.shape(), (7, False))
133 v2 = Const(0, (4, True)) - Const(0, (6, True))
134 self.assertEqual(v2.shape(), (7, True))
135 v3 = Const(0, (4, True)) - Const(0, (4, False))
136 self.assertEqual(v3.shape(), (6, True))
137 v4 = Const(0, (4, False)) - Const(0, (4, True))
138 self.assertEqual(v4.shape(), (6, True))
139 v5 = 10 - Const(0, 4)
140 self.assertEqual(v5.shape(), (5, False))
141
142 def test_mul(self):
143 v1 = Const(0, (4, False)) * Const(0, (6, False))
144 self.assertEqual(repr(v1), "(* (const 4'd0) (const 6'd0))")
145 self.assertEqual(v1.shape(), (10, False))
146 v2 = Const(0, (4, True)) * Const(0, (6, True))
147 self.assertEqual(v2.shape(), (10, True))
148 v3 = Const(0, (4, True)) * Const(0, (4, False))
149 self.assertEqual(v3.shape(), (8, True))
150 v5 = 10 * Const(0, 4)
151 self.assertEqual(v5.shape(), (8, False))
152
153 def test_and(self):
154 v1 = Const(0, (4, False)) & Const(0, (6, False))
155 self.assertEqual(repr(v1), "(& (const 4'd0) (const 6'd0))")
156 self.assertEqual(v1.shape(), (6, False))
157 v2 = Const(0, (4, True)) & Const(0, (6, True))
158 self.assertEqual(v2.shape(), (6, True))
159 v3 = Const(0, (4, True)) & Const(0, (4, False))
160 self.assertEqual(v3.shape(), (5, True))
161 v4 = Const(0, (4, False)) & Const(0, (4, True))
162 self.assertEqual(v4.shape(), (5, True))
163 v5 = 10 & Const(0, 4)
164 self.assertEqual(v5.shape(), (4, False))
165
166 def test_or(self):
167 v1 = Const(0, (4, False)) | Const(0, (6, False))
168 self.assertEqual(repr(v1), "(| (const 4'd0) (const 6'd0))")
169 self.assertEqual(v1.shape(), (6, False))
170 v2 = Const(0, (4, True)) | Const(0, (6, True))
171 self.assertEqual(v2.shape(), (6, True))
172 v3 = Const(0, (4, True)) | Const(0, (4, False))
173 self.assertEqual(v3.shape(), (5, True))
174 v4 = Const(0, (4, False)) | Const(0, (4, True))
175 self.assertEqual(v4.shape(), (5, True))
176 v5 = 10 | Const(0, 4)
177 self.assertEqual(v5.shape(), (4, False))
178
179 def test_xor(self):
180 v1 = Const(0, (4, False)) ^ Const(0, (6, False))
181 self.assertEqual(repr(v1), "(^ (const 4'd0) (const 6'd0))")
182 self.assertEqual(v1.shape(), (6, False))
183 v2 = Const(0, (4, True)) ^ Const(0, (6, True))
184 self.assertEqual(v2.shape(), (6, True))
185 v3 = Const(0, (4, True)) ^ Const(0, (4, False))
186 self.assertEqual(v3.shape(), (5, True))
187 v4 = Const(0, (4, False)) ^ Const(0, (4, True))
188 self.assertEqual(v4.shape(), (5, True))
189 v5 = 10 ^ Const(0, 4)
190 self.assertEqual(v5.shape(), (4, False))
191
192 def test_shl(self):
193 v1 = Const(1, 4) << Const(4)
194 self.assertEqual(repr(v1), "(<< (const 4'd1) (const 3'd4))")
195 self.assertEqual(v1.shape(), (11, False))
196 v2 = Const(1, 4) << Const(-3)
197 self.assertEqual(v2.shape(), (7, False))
198
199 def test_shr(self):
200 v1 = Const(1, 4) >> Const(4)
201 self.assertEqual(repr(v1), "(>> (const 4'd1) (const 3'd4))")
202 self.assertEqual(v1.shape(), (4, False))
203 v2 = Const(1, 4) >> Const(-3)
204 self.assertEqual(v2.shape(), (8, False))
205
206 def test_lt(self):
207 v = Const(0, 4) < Const(0, 6)
208 self.assertEqual(repr(v), "(< (const 4'd0) (const 6'd0))")
209 self.assertEqual(v.shape(), (1, False))
210
211 def test_le(self):
212 v = Const(0, 4) <= Const(0, 6)
213 self.assertEqual(repr(v), "(<= (const 4'd0) (const 6'd0))")
214 self.assertEqual(v.shape(), (1, False))
215
216 def test_gt(self):
217 v = Const(0, 4) > Const(0, 6)
218 self.assertEqual(repr(v), "(> (const 4'd0) (const 6'd0))")
219 self.assertEqual(v.shape(), (1, False))
220
221 def test_ge(self):
222 v = Const(0, 4) >= Const(0, 6)
223 self.assertEqual(repr(v), "(>= (const 4'd0) (const 6'd0))")
224 self.assertEqual(v.shape(), (1, False))
225
226 def test_eq(self):
227 v = Const(0, 4) == Const(0, 6)
228 self.assertEqual(repr(v), "(== (const 4'd0) (const 6'd0))")
229 self.assertEqual(v.shape(), (1, False))
230
231 def test_ne(self):
232 v = Const(0, 4) != Const(0, 6)
233 self.assertEqual(repr(v), "(!= (const 4'd0) (const 6'd0))")
234 self.assertEqual(v.shape(), (1, False))
235
236 def test_mux(self):
237 s = Const(0)
238 v1 = Mux(s, Const(0, (4, False)), Const(0, (6, False)))
239 self.assertEqual(repr(v1), "(m (const 1'd0) (const 4'd0) (const 6'd0))")
240 self.assertEqual(v1.shape(), (6, False))
241 v2 = Mux(s, Const(0, (4, True)), Const(0, (6, True)))
242 self.assertEqual(v2.shape(), (6, True))
243 v3 = Mux(s, Const(0, (4, True)), Const(0, (4, False)))
244 self.assertEqual(v3.shape(), (5, True))
245 v4 = Mux(s, Const(0, (4, False)), Const(0, (4, True)))
246 self.assertEqual(v4.shape(), (5, True))
247
248 def test_bool(self):
249 v = Const(0).bool()
250 self.assertEqual(repr(v), "(b (const 1'd0))")
251 self.assertEqual(v.shape(), (1, False))
252
253 def test_hash(self):
254 with self.assertRaises(TypeError):
255 hash(Const(0) + Const(0))
256
257
258 class SliceTestCase(FHDLTestCase):
259 def test_shape(self):
260 s1 = Const(10)[2]
261 self.assertEqual(s1.shape(), (1, False))
262 s2 = Const(-10)[0:2]
263 self.assertEqual(s2.shape(), (2, False))
264
265 def test_start_end_negative(self):
266 c = Const(0, 8)
267 s1 = Slice(c, 0, -1)
268 self.assertEqual((s1.start, s1.end), (0, 7))
269 s1 = Slice(c, -4, -1)
270 self.assertEqual((s1.start, s1.end), (4, 7))
271
272 def test_start_end_wrong(self):
273 with self.assertRaises(TypeError,
274 msg="Slice start must be an integer, not ''x''"):
275 Slice(0, "x", 1)
276 with self.assertRaises(TypeError,
277 msg="Slice end must be an integer, not ''x''"):
278 Slice(0, 1, "x")
279
280 def test_start_end_out_of_range(self):
281 c = Const(0, 8)
282 with self.assertRaises(IndexError,
283 msg="Cannot start slice 10 bits into 8-bit value"):
284 Slice(c, 10, 12)
285 with self.assertRaises(IndexError,
286 msg="Cannot end slice 12 bits into 8-bit value"):
287 Slice(c, 0, 12)
288 with self.assertRaises(IndexError,
289 msg="Slice start 4 must be less than slice end 2"):
290 Slice(c, 4, 2)
291
292 def test_repr(self):
293 s1 = Const(10)[2]
294 self.assertEqual(repr(s1), "(slice (const 4'd10) 2:3)")
295
296
297 class BitSelectTestCase(FHDLTestCase):
298 def setUp(self):
299 self.c = Const(0, 8)
300 self.s = Signal(max=self.c.nbits)
301
302 def test_shape(self):
303 s1 = self.c.bit_select(self.s, 2)
304 self.assertEqual(s1.shape(), (2, False))
305 s2 = self.c.bit_select(self.s, 0)
306 self.assertEqual(s2.shape(), (0, False))
307
308 def test_stride(self):
309 s1 = self.c.bit_select(self.s, 2)
310 self.assertEqual(s1.stride, 1)
311
312 def test_width_bad(self):
313 with self.assertRaises(TypeError):
314 self.c.bit_select(self.s, -1)
315
316 def test_repr(self):
317 s = self.c.bit_select(self.s, 2)
318 self.assertEqual(repr(s), "(part (const 8'd0) (sig s) 2 1)")
319
320
321 class WordSelectTestCase(FHDLTestCase):
322 def setUp(self):
323 self.c = Const(0, 8)
324 self.s = Signal(max=self.c.nbits)
325
326 def test_shape(self):
327 s1 = self.c.word_select(self.s, 2)
328 self.assertEqual(s1.shape(), (2, False))
329
330 def test_stride(self):
331 s1 = self.c.word_select(self.s, 2)
332 self.assertEqual(s1.stride, 2)
333
334 def test_width_bad(self):
335 with self.assertRaises(TypeError):
336 self.c.word_select(self.s, 0)
337 with self.assertRaises(TypeError):
338 self.c.word_select(self.s, -1)
339
340 def test_repr(self):
341 s = self.c.word_select(self.s, 2)
342 self.assertEqual(repr(s), "(part (const 8'd0) (sig s) 2 2)")
343
344
345 class CatTestCase(FHDLTestCase):
346 def test_shape(self):
347 c0 = Cat()
348 self.assertEqual(c0.shape(), (0, False))
349 c1 = Cat(Const(10))
350 self.assertEqual(c1.shape(), (4, False))
351 c2 = Cat(Const(10), Const(1))
352 self.assertEqual(c2.shape(), (5, False))
353 c3 = Cat(Const(10), Const(1), Const(0))
354 self.assertEqual(c3.shape(), (6, False))
355
356 def test_repr(self):
357 c1 = Cat(Const(10), Const(1))
358 self.assertEqual(repr(c1), "(cat (const 4'd10) (const 1'd1))")
359
360
361 class ReplTestCase(FHDLTestCase):
362 def test_shape(self):
363 s1 = Repl(Const(10), 3)
364 self.assertEqual(s1.shape(), (12, False))
365 s2 = Repl(Const(10), 0)
366 self.assertEqual(s2.shape(), (0, False))
367
368 def test_count_wrong(self):
369 with self.assertRaises(TypeError):
370 Repl(Const(10), -1)
371 with self.assertRaises(TypeError):
372 Repl(Const(10), "str")
373
374 def test_repr(self):
375 s = Repl(Const(10), 3)
376 self.assertEqual(repr(s), "(repl (const 4'd10) 3)")
377
378
379 class ArrayTestCase(FHDLTestCase):
380 def test_acts_like_array(self):
381 a = Array([1,2,3])
382 self.assertSequenceEqual(a, [1,2,3])
383 self.assertEqual(a[1], 2)
384 a[1] = 4
385 self.assertSequenceEqual(a, [1,4,3])
386 del a[1]
387 self.assertSequenceEqual(a, [1,3])
388 a.insert(1, 2)
389 self.assertSequenceEqual(a, [1,2,3])
390
391 def test_becomes_immutable(self):
392 a = Array([1,2,3])
393 s1 = Signal(max=len(a))
394 s2 = Signal(max=len(a))
395 v1 = a[s1]
396 v2 = a[s2]
397 with self.assertRaisesRegex(ValueError,
398 regex=r"^Array can no longer be mutated after it was indexed with a value at "):
399 a[1] = 2
400 with self.assertRaisesRegex(ValueError,
401 regex=r"^Array can no longer be mutated after it was indexed with a value at "):
402 del a[1]
403 with self.assertRaisesRegex(ValueError,
404 regex=r"^Array can no longer be mutated after it was indexed with a value at "):
405 a.insert(1, 2)
406
407 def test_repr(self):
408 a = Array([1,2,3])
409 self.assertEqual(repr(a), "(array mutable [1, 2, 3])")
410 s = Signal(max=len(a))
411 v = a[s]
412 self.assertEqual(repr(a), "(array [1, 2, 3])")
413
414
415 class ArrayProxyTestCase(FHDLTestCase):
416 def test_index_shape(self):
417 m = Array(Array(x * y for y in range(1, 4)) for x in range(1, 4))
418 a = Signal(max=3)
419 b = Signal(max=3)
420 v = m[a][b]
421 self.assertEqual(v.shape(), (4, False))
422
423 def test_attr_shape(self):
424 from collections import namedtuple
425 pair = namedtuple("pair", ("p", "n"))
426 a = Array(pair(i, -i) for i in range(10))
427 s = Signal(max=len(a))
428 v = a[s]
429 self.assertEqual(v.p.shape(), (4, False))
430 self.assertEqual(v.n.shape(), (6, True))
431
432 def test_repr(self):
433 a = Array([1, 2, 3])
434 s = Signal(max=3)
435 v = a[s]
436 self.assertEqual(repr(v), "(proxy (array [1, 2, 3]) (sig s))")
437
438
439 class SignalTestCase(FHDLTestCase):
440 def test_shape(self):
441 s1 = Signal()
442 self.assertEqual(s1.shape(), (1, False))
443 s2 = Signal(2)
444 self.assertEqual(s2.shape(), (2, False))
445 s3 = Signal((2, False))
446 self.assertEqual(s3.shape(), (2, False))
447 s4 = Signal((2, True))
448 self.assertEqual(s4.shape(), (2, True))
449 s5 = Signal(max=16)
450 self.assertEqual(s5.shape(), (4, False))
451 s6 = Signal(min=4, max=16)
452 self.assertEqual(s6.shape(), (4, False))
453 s7 = Signal(min=-4, max=16)
454 self.assertEqual(s7.shape(), (5, True))
455 s8 = Signal(min=-20, max=16)
456 self.assertEqual(s8.shape(), (6, True))
457 s9 = Signal(0)
458 self.assertEqual(s9.shape(), (0, False))
459 s10 = Signal(max=1)
460 self.assertEqual(s10.shape(), (0, False))
461
462 def test_shape_bad(self):
463 with self.assertRaises(ValueError,
464 msg="Lower bound 10 should be less or equal to higher bound 4"):
465 Signal(min=10, max=4)
466 with self.assertRaises(ValueError,
467 msg="Only one of bits/signedness or bounds may be specified"):
468 Signal(2, min=10)
469 with self.assertRaises(TypeError,
470 msg="Width must be a non-negative integer, not '-10'"):
471 Signal(-10)
472
473 def test_name(self):
474 s1 = Signal()
475 self.assertEqual(s1.name, "s1")
476 s2 = Signal(name="sig")
477 self.assertEqual(s2.name, "sig")
478
479 def test_name_bad(self):
480 with self.assertRaises(TypeError,
481 msg="Name must be a string, not 'True'"):
482 # A common typo: forgetting to put parens around width and signedness
483 Signal(1, True)
484
485 def test_reset(self):
486 s1 = Signal(4, reset=0b111, reset_less=True)
487 self.assertEqual(s1.reset, 0b111)
488 self.assertEqual(s1.reset_less, True)
489
490 def test_attrs(self):
491 s1 = Signal()
492 self.assertEqual(s1.attrs, {})
493 s2 = Signal(attrs={"no_retiming": True})
494 self.assertEqual(s2.attrs, {"no_retiming": True})
495
496 def test_repr(self):
497 s1 = Signal()
498 self.assertEqual(repr(s1), "(sig s1)")
499
500 def test_like(self):
501 s1 = Signal.like(Signal(4))
502 self.assertEqual(s1.shape(), (4, False))
503 s2 = Signal.like(Signal(min=-15))
504 self.assertEqual(s2.shape(), (5, True))
505 s3 = Signal.like(Signal(4, reset=0b111, reset_less=True))
506 self.assertEqual(s3.reset, 0b111)
507 self.assertEqual(s3.reset_less, True)
508 s4 = Signal.like(Signal(attrs={"no_retiming": True}))
509 self.assertEqual(s4.attrs, {"no_retiming": True})
510 s5 = Signal.like(Signal(decoder=str))
511 self.assertEqual(s5.decoder, str)
512 s6 = Signal.like(10)
513 self.assertEqual(s6.shape(), (4, False))
514 s7 = [Signal.like(Signal(4))][0]
515 self.assertEqual(s7.name, "$like")
516 s8 = Signal.like(s1, name_suffix="_ff")
517 self.assertEqual(s8.name, "s1_ff")
518
519 def test_decoder(self):
520 class Color(Enum):
521 RED = 1
522 BLUE = 2
523 s = Signal(decoder=Color)
524 self.assertEqual(s.decoder(1), "RED/1")
525 self.assertEqual(s.decoder(3), "3")
526
527
528 class ClockSignalTestCase(FHDLTestCase):
529 def test_domain(self):
530 s1 = ClockSignal()
531 self.assertEqual(s1.domain, "sync")
532 s2 = ClockSignal("pix")
533 self.assertEqual(s2.domain, "pix")
534
535 with self.assertRaises(TypeError,
536 msg="Clock domain name must be a string, not '1'"):
537 ClockSignal(1)
538
539 def test_shape(self):
540 self.assertEqual(ClockSignal().shape(), (1, False))
541
542 def test_repr(self):
543 s1 = ClockSignal()
544 self.assertEqual(repr(s1), "(clk sync)")
545
546 def test_wrong_name_comb(self):
547 with self.assertRaises(ValueError,
548 msg="Domain 'comb' does not have a clock"):
549 ClockSignal("comb")
550
551
552 class ResetSignalTestCase(FHDLTestCase):
553 def test_domain(self):
554 s1 = ResetSignal()
555 self.assertEqual(s1.domain, "sync")
556 s2 = ResetSignal("pix")
557 self.assertEqual(s2.domain, "pix")
558
559 with self.assertRaises(TypeError,
560 msg="Clock domain name must be a string, not '1'"):
561 ResetSignal(1)
562
563 def test_shape(self):
564 self.assertEqual(ResetSignal().shape(), (1, False))
565
566 def test_repr(self):
567 s1 = ResetSignal()
568 self.assertEqual(repr(s1), "(rst sync)")
569
570 def test_wrong_name_comb(self):
571 with self.assertRaises(ValueError,
572 msg="Domain 'comb' does not have a reset"):
573 ResetSignal("comb")
574
575
576 class MockUserValue(UserValue):
577 def __init__(self, lowered):
578 super().__init__()
579 self.lower_count = 0
580 self.lowered = lowered
581
582 def lower(self):
583 self.lower_count += 1
584 return self.lowered
585
586
587 class UserValueTestCase(FHDLTestCase):
588 def test_shape(self):
589 uv = MockUserValue(1)
590 self.assertEqual(uv.shape(), (1, False))
591 uv.lowered = 2
592 self.assertEqual(uv.shape(), (1, False))
593 self.assertEqual(uv.lower_count, 1)
594
595
596 class SampleTestCase(FHDLTestCase):
597 def test_const(self):
598 s = Sample(1, 1, "sync")
599 self.assertEqual(s.shape(), (1, False))
600
601 def test_signal(self):
602 s1 = Sample(Signal(2), 1, "sync")
603 self.assertEqual(s1.shape(), (2, False))
604 s2 = Sample(ClockSignal(), 1, "sync")
605 s3 = Sample(ResetSignal(), 1, "sync")
606
607 def test_wrong_value_operator(self):
608 with self.assertRaises(TypeError,
609 "Sampled value may only be a signal or a constant, not "
610 "(+ (sig $signal) (const 1'd1))"):
611 Sample(Signal() + 1, 1, "sync")
612
613 def test_wrong_clocks_neg(self):
614 with self.assertRaises(ValueError,
615 "Cannot sample a value 1 cycles in the future"):
616 Sample(Signal(), -1, "sync")
617
618
619 class InitialTestCase(FHDLTestCase):
620 def test_initial(self):
621 i = Initial()
622 self.assertEqual(i.shape(), (1, False))