fhdl.ast: bits_sign→shape.
[nmigen.git] / nmigen / test / test_fhdl.py
1 import unittest
2
3 from nmigen.fhdl.ast import *
4
5
6 class ValueTestCase(unittest.TestCase):
7 def test_wrap(self):
8 self.assertIsInstance(Value.wrap(0), Const)
9 self.assertIsInstance(Value.wrap(True), Const)
10 c = Const(0)
11 self.assertIs(Value.wrap(c), c)
12 with self.assertRaises(TypeError):
13 Value.wrap("str")
14
15 def test_bool(self):
16 with self.assertRaises(TypeError):
17 if Const(0):
18 pass
19
20 def test_len(self):
21 self.assertEqual(len(Const(10)), 4)
22
23 def test_getitem_int(self):
24 s1 = Const(10)[0]
25 self.assertIsInstance(s1, Slice)
26 self.assertEqual(s1.start, 0)
27 self.assertEqual(s1.end, 1)
28 s2 = Const(10)[-1]
29 self.assertIsInstance(s2, Slice)
30 self.assertEqual(s2.start, 3)
31 self.assertEqual(s2.end, 4)
32 with self.assertRaises(IndexError):
33 Const(10)[5]
34
35 def test_getitem_slice(self):
36 s1 = Const(10)[1:3]
37 self.assertIsInstance(s1, Slice)
38 self.assertEqual(s1.start, 1)
39 self.assertEqual(s1.end, 3)
40 s2 = Const(10)[1:-2]
41 self.assertIsInstance(s2, Slice)
42 self.assertEqual(s2.start, 1)
43 self.assertEqual(s2.end, 2)
44 s3 = Const(31)[::2]
45 self.assertIsInstance(s3, Cat)
46 self.assertIsInstance(s3.operands[0], Slice)
47 self.assertEqual(s3.operands[0].start, 0)
48 self.assertEqual(s3.operands[0].end, 1)
49 self.assertIsInstance(s3.operands[1], Slice)
50 self.assertEqual(s3.operands[1].start, 2)
51 self.assertEqual(s3.operands[1].end, 3)
52 self.assertIsInstance(s3.operands[2], Slice)
53 self.assertEqual(s3.operands[2].start, 4)
54 self.assertEqual(s3.operands[2].end, 5)
55
56 def test_getitem_wrong(self):
57 with self.assertRaises(TypeError):
58 Const(31)["str"]
59
60
61 class ConstTestCase(unittest.TestCase):
62 def test_shape(self):
63 self.assertEqual(Const(0).shape(), (0, False))
64 self.assertEqual(Const(1).shape(), (1, False))
65 self.assertEqual(Const(10).shape(), (4, False))
66 self.assertEqual(Const(-10).shape(), (4, True))
67
68 self.assertEqual(Const(1, 4).shape(), (4, False))
69 self.assertEqual(Const(1, (4, True)).shape(), (4, True))
70
71 with self.assertRaises(TypeError):
72 Const(1, -1)
73
74 def test_value(self):
75 self.assertEqual(Const(10).value, 10)
76
77 def test_repr(self):
78 self.assertEqual(repr(Const(10)), "(const 4'd10)")
79 self.assertEqual(repr(Const(-10)), "(const 4'sd-10)")
80
81 def test_hash(self):
82 with self.assertRaises(TypeError):
83 hash(Const(0))
84
85
86 class OperatorTestCase(unittest.TestCase):
87 def test_invert(self):
88 v = ~Const(0, 4)
89 self.assertEqual(repr(v), "(~ (const 4'd0))")
90 self.assertEqual(v.shape(), (4, False))
91
92 def test_neg(self):
93 v1 = -Const(0, (4, False))
94 self.assertEqual(repr(v1), "(- (const 4'd0))")
95 self.assertEqual(v1.shape(), (5, True))
96 v2 = -Const(0, (4, True))
97 self.assertEqual(repr(v2), "(- (const 4'sd0))")
98 self.assertEqual(v2.shape(), (4, True))
99
100 def test_add(self):
101 v1 = Const(0, (4, False)) + Const(0, (6, False))
102 self.assertEqual(repr(v1), "(+ (const 4'd0) (const 6'd0))")
103 self.assertEqual(v1.shape(), (7, False))
104 v2 = Const(0, (4, True)) + Const(0, (6, True))
105 self.assertEqual(v2.shape(), (7, True))
106 v3 = Const(0, (4, True)) + Const(0, (4, False))
107 self.assertEqual(v3.shape(), (6, True))
108 v4 = Const(0, (4, False)) + Const(0, (4, True))
109 self.assertEqual(v4.shape(), (6, True))
110 v5 = 10 + Const(0, 4)
111 self.assertEqual(v5.shape(), (5, False))
112
113 def test_sub(self):
114 v1 = Const(0, (4, False)) - Const(0, (6, False))
115 self.assertEqual(repr(v1), "(- (const 4'd0) (const 6'd0))")
116 self.assertEqual(v1.shape(), (7, False))
117 v2 = Const(0, (4, True)) - Const(0, (6, True))
118 self.assertEqual(v2.shape(), (7, True))
119 v3 = Const(0, (4, True)) - Const(0, (4, False))
120 self.assertEqual(v3.shape(), (6, True))
121 v4 = Const(0, (4, False)) - Const(0, (4, True))
122 self.assertEqual(v4.shape(), (6, True))
123 v5 = 10 - Const(0, 4)
124 self.assertEqual(v5.shape(), (5, False))
125
126 def test_mul(self):
127 v1 = Const(0, (4, False)) * Const(0, (6, False))
128 self.assertEqual(repr(v1), "(* (const 4'd0) (const 6'd0))")
129 self.assertEqual(v1.shape(), (10, False))
130 v2 = Const(0, (4, True)) * Const(0, (6, True))
131 self.assertEqual(v2.shape(), (9, True))
132 v3 = Const(0, (4, True)) * Const(0, (4, False))
133 self.assertEqual(v3.shape(), (8, True))
134 v5 = 10 * Const(0, 4)
135 self.assertEqual(v5.shape(), (8, False))
136
137 def test_and(self):
138 v1 = Const(0, (4, False)) & Const(0, (6, False))
139 self.assertEqual(repr(v1), "(& (const 4'd0) (const 6'd0))")
140 self.assertEqual(v1.shape(), (6, False))
141 v2 = Const(0, (4, True)) & Const(0, (6, True))
142 self.assertEqual(v2.shape(), (6, True))
143 v3 = Const(0, (4, True)) & Const(0, (4, False))
144 self.assertEqual(v3.shape(), (5, True))
145 v4 = Const(0, (4, False)) & Const(0, (4, True))
146 self.assertEqual(v4.shape(), (5, True))
147 v5 = 10 & Const(0, 4)
148 self.assertEqual(v5.shape(), (4, False))
149
150 def test_or(self):
151 v1 = Const(0, (4, False)) | Const(0, (6, False))
152 self.assertEqual(repr(v1), "(| (const 4'd0) (const 6'd0))")
153 self.assertEqual(v1.shape(), (6, False))
154 v2 = Const(0, (4, True)) | Const(0, (6, True))
155 self.assertEqual(v2.shape(), (6, True))
156 v3 = Const(0, (4, True)) | Const(0, (4, False))
157 self.assertEqual(v3.shape(), (5, True))
158 v4 = Const(0, (4, False)) | Const(0, (4, True))
159 self.assertEqual(v4.shape(), (5, True))
160 v5 = 10 | Const(0, 4)
161 self.assertEqual(v5.shape(), (4, False))
162
163 def test_xor(self):
164 v1 = Const(0, (4, False)) ^ Const(0, (6, False))
165 self.assertEqual(repr(v1), "(^ (const 4'd0) (const 6'd0))")
166 self.assertEqual(v1.shape(), (6, False))
167 v2 = Const(0, (4, True)) ^ Const(0, (6, True))
168 self.assertEqual(v2.shape(), (6, True))
169 v3 = Const(0, (4, True)) ^ Const(0, (4, False))
170 self.assertEqual(v3.shape(), (5, True))
171 v4 = Const(0, (4, False)) ^ Const(0, (4, True))
172 self.assertEqual(v4.shape(), (5, True))
173 v5 = 10 ^ Const(0, 4)
174 self.assertEqual(v5.shape(), (4, False))
175
176 def test_lt(self):
177 v = Const(0, 4) < Const(0, 6)
178 self.assertEqual(repr(v), "(< (const 4'd0) (const 6'd0))")
179 self.assertEqual(v.shape(), (1, False))
180
181 def test_le(self):
182 v = Const(0, 4) <= Const(0, 6)
183 self.assertEqual(repr(v), "(<= (const 4'd0) (const 6'd0))")
184 self.assertEqual(v.shape(), (1, False))
185
186 def test_gt(self):
187 v = Const(0, 4) > Const(0, 6)
188 self.assertEqual(repr(v), "(> (const 4'd0) (const 6'd0))")
189 self.assertEqual(v.shape(), (1, False))
190
191 def test_ge(self):
192 v = Const(0, 4) >= Const(0, 6)
193 self.assertEqual(repr(v), "(>= (const 4'd0) (const 6'd0))")
194 self.assertEqual(v.shape(), (1, False))
195
196 def test_eq(self):
197 v = Const(0, 4) == Const(0, 6)
198 self.assertEqual(repr(v), "(== (const 4'd0) (const 6'd0))")
199 self.assertEqual(v.shape(), (1, False))
200
201 def test_ne(self):
202 v = Const(0, 4) != Const(0, 6)
203 self.assertEqual(repr(v), "(!= (const 4'd0) (const 6'd0))")
204 self.assertEqual(v.shape(), (1, False))
205
206 def test_mux(self):
207 s = Const(0)
208 v1 = Mux(s, Const(0, (4, False)), Const(0, (6, False)))
209 self.assertEqual(repr(v1), "(m (const 0'd0) (const 4'd0) (const 6'd0))")
210 self.assertEqual(v1.shape(), (6, False))
211 v2 = Mux(s, Const(0, (4, True)), Const(0, (6, True)))
212 self.assertEqual(v2.shape(), (6, True))
213 v3 = Mux(s, Const(0, (4, True)), Const(0, (4, False)))
214 self.assertEqual(v3.shape(), (5, True))
215 v4 = Mux(s, Const(0, (4, False)), Const(0, (4, True)))
216 self.assertEqual(v4.shape(), (5, True))
217
218 def test_bool(self):
219 v = Const(0).bool()
220 self.assertEqual(repr(v), "(b (const 0'd0))")
221 self.assertEqual(v.shape(), (1, False))
222
223 def test_hash(self):
224 with self.assertRaises(TypeError):
225 hash(Const(0) + Const(0))
226
227
228 class SliceTestCase(unittest.TestCase):
229 def test_shape(self):
230 s1 = Const(10)[2]
231 self.assertEqual(s1.shape(), (1, False))
232 s2 = Const(-10)[0:2]
233 self.assertEqual(s2.shape(), (2, False))
234
235 def test_repr(self):
236 s1 = Const(10)[2]
237 self.assertEqual(repr(s1), "(slice (const 4'd10) 2:3)")
238
239
240 class CatTestCase(unittest.TestCase):
241 def test_shape(self):
242 c1 = Cat(Const(10))
243 self.assertEqual(c1.shape(), (4, False))
244 c2 = Cat(Const(10), Const(1))
245 self.assertEqual(c2.shape(), (5, False))
246 c3 = Cat(Const(10), Const(1), Const(0))
247 self.assertEqual(c3.shape(), (5, False))
248
249 def test_repr(self):
250 c1 = Cat(Const(10), Const(1))
251 self.assertEqual(repr(c1), "(cat (const 4'd10) (const 1'd1))")
252
253
254 class ReplTestCase(unittest.TestCase):
255 def test_shape(self):
256 r1 = Repl(Const(10), 3)
257 self.assertEqual(r1.shape(), (12, False))
258
259 def test_count_wrong(self):
260 with self.assertRaises(TypeError):
261 Repl(Const(10), -1)
262 with self.assertRaises(TypeError):
263 Repl(Const(10), "str")
264
265 def test_repr(self):
266 r1 = Repl(Const(10), 3)
267 self.assertEqual(repr(r1), "(repl (const 4'd10) 3)")
268
269
270 class SignalTestCase(unittest.TestCase):
271 def test_shape(self):
272 s1 = Signal()
273 self.assertEqual(s1.shape(), (1, False))
274 s2 = Signal(2)
275 self.assertEqual(s2.shape(), (2, False))
276 s3 = Signal((2, False))
277 self.assertEqual(s3.shape(), (2, False))
278 s4 = Signal((2, True))
279 self.assertEqual(s4.shape(), (2, True))
280 s5 = Signal(max=16)
281 self.assertEqual(s5.shape(), (4, False))
282 s6 = Signal(min=4, max=16)
283 self.assertEqual(s6.shape(), (4, False))
284 s7 = Signal(min=-4, max=16)
285 self.assertEqual(s7.shape(), (5, True))
286 s8 = Signal(min=-20, max=16)
287 self.assertEqual(s8.shape(), (6, True))
288
289 with self.assertRaises(ValueError):
290 Signal(min=10, max=4)
291 with self.assertRaises(ValueError):
292 Signal(2, min=10)
293 with self.assertRaises(TypeError):
294 Signal(-10)
295
296 def test_name(self):
297 s1 = Signal()
298 self.assertEqual(s1.name, "s1")
299 s2 = Signal(name="sig")
300 self.assertEqual(s2.name, "sig")
301
302 def test_reset(self):
303 s1 = Signal(4, reset=0b111, reset_less=True)
304 self.assertEqual(s1.reset, 0b111)
305 self.assertEqual(s1.reset_less, True)
306
307 def test_attrs(self):
308 s1 = Signal()
309 self.assertEqual(s1.attrs, {})
310 s2 = Signal(attrs={"no_retiming": True})
311 self.assertEqual(s2.attrs, {"no_retiming": True})
312
313 def test_repr(self):
314 s1 = Signal()
315 self.assertEqual(repr(s1), "(sig s1)")
316
317 def test_like(self):
318 s1 = Signal.like(Signal(4))
319 self.assertEqual(s1.shape(), (4, False))
320 s2 = Signal.like(Signal(min=-15))
321 self.assertEqual(s2.shape(), (5, True))
322 s3 = Signal.like(Signal(4, reset=0b111, reset_less=True))
323 self.assertEqual(s3.reset, 0b111)
324 self.assertEqual(s3.reset_less, True)
325 s4 = Signal.like(Signal(attrs={"no_retiming": True}))
326 self.assertEqual(s4.attrs, {"no_retiming": True})
327 s5 = Signal.like(10)
328 self.assertEqual(s5.shape(), (4, False))
329
330
331 class ClockSignalTestCase(unittest.TestCase):
332 def test_domain(self):
333 s1 = ClockSignal()
334 self.assertEqual(s1.domain, "sync")
335 s2 = ClockSignal("pix")
336 self.assertEqual(s2.domain, "pix")
337
338 with self.assertRaises(TypeError):
339 ClockSignal(1)
340
341 def test_repr(self):
342 s1 = ClockSignal()
343 self.assertEqual(repr(s1), "(clk sync)")
344
345
346 class ResetSignalTestCase(unittest.TestCase):
347 def test_domain(self):
348 s1 = ResetSignal()
349 self.assertEqual(s1.domain, "sync")
350 s2 = ResetSignal("pix")
351 self.assertEqual(s2.domain, "pix")
352
353 with self.assertRaises(TypeError):
354 ResetSignal(1)
355
356 def test_repr(self):
357 s1 = ResetSignal()
358 self.assertEqual(repr(s1), "(reset sync)")