1 from ..fhdl
.ast
import *
2 from ..fhdl
.dsl
import *
6 class DSLTestCase(FHDLTestCase
):
16 def test_d_comb(self
):
18 m
.d
.comb
+= self
.c1
.eq(1)
20 self
.assertEqual(m
._driving
[self
.c1
], None)
21 self
.assertRepr(m
._statements
, """(
22 (eq (sig c1) (const 1'd1))
25 def test_d_sync(self
):
27 m
.d
.sync
+= self
.c1
.eq(1)
29 self
.assertEqual(m
._driving
[self
.c1
], "sync")
30 self
.assertRepr(m
._statements
, """(
31 (eq (sig c1) (const 1'd1))
36 m
.d
.pix
+= self
.c1
.eq(1)
38 self
.assertEqual(m
._driving
[self
.c1
], "pix")
39 self
.assertRepr(m
._statements
, """(
40 (eq (sig c1) (const 1'd1))
43 def test_d_index(self
):
45 m
.d
["pix"] += self
.c1
.eq(1)
47 self
.assertEqual(m
._driving
[self
.c1
], "pix")
48 self
.assertRepr(m
._statements
, """(
49 (eq (sig c1) (const 1'd1))
52 def test_d_no_conflict(self
):
54 m
.d
.comb
+= self
.w1
[0].eq(1)
55 m
.d
.comb
+= self
.w1
[1].eq(1)
57 def test_d_conflict(self
):
59 with self
.assertRaises(SyntaxError,
60 msg
="Driver-driver conflict: trying to drive (sig c1) from d.sync, but it "
61 "is already driven from d.comb"):
62 m
.d
.comb
+= self
.c1
.eq(1)
63 m
.d
.sync
+= self
.c1
.eq(1)
65 def test_d_wrong(self
):
67 with self
.assertRaises(AttributeError,
68 msg
="Cannot assign 'd.pix' attribute; did you mean 'd.pix +='?"):
71 def test_d_asgn_wrong(self
):
73 with self
.assertRaises(SyntaxError,
74 msg
="Only assignments may be appended to d.sync"):
75 m
.d
.sync
+= Switch(self
.s1
, {})
77 def test_comb_wrong(self
):
79 with self
.assertRaises(AttributeError,
80 msg
="'Module' object has no attribute 'comb'; did you mean 'd.comb'?"):
81 m
.comb
+= self
.c1
.eq(1)
83 def test_sync_wrong(self
):
85 with self
.assertRaises(AttributeError,
86 msg
="'Module' object has no attribute 'sync'; did you mean 'd.sync'?"):
87 m
.sync
+= self
.c1
.eq(1)
89 def test_attr_wrong(self
):
91 with self
.assertRaises(AttributeError,
92 msg
="'Module' object has no attribute 'nonexistentattr'"):
98 m
.d
.comb
+= self
.c1
.eq(1)
100 self
.assertRepr(m
._statements
, """
102 (switch (cat (sig s1))
103 (case 1 (eq (sig c1) (const 1'd1)))
108 def test_If_Elif(self
):
111 m
.d
.comb
+= self
.c1
.eq(1)
112 with m
.Elif(self
.s2
):
113 m
.d
.sync
+= self
.c2
.eq(0)
115 self
.assertRepr(m
._statements
, """
117 (switch (cat (sig s1) (sig s2))
118 (case -1 (eq (sig c1) (const 1'd1)))
119 (case 1- (eq (sig c2) (const 1'd0)))
124 def test_If_Elif_Else(self
):
127 m
.d
.comb
+= self
.c1
.eq(1)
128 with m
.Elif(self
.s2
):
129 m
.d
.sync
+= self
.c2
.eq(0)
131 m
.d
.comb
+= self
.c3
.eq(1)
133 self
.assertRepr(m
._statements
, """
135 (switch (cat (sig s1) (sig s2))
136 (case -1 (eq (sig c1) (const 1'd1)))
137 (case 1- (eq (sig c2) (const 1'd0)))
138 (case -- (eq (sig c3) (const 1'd1)))
143 def test_If_If(self
):
146 m
.d
.comb
+= self
.c1
.eq(1)
148 m
.d
.comb
+= self
.c2
.eq(1)
150 self
.assertRepr(m
._statements
, """
152 (switch (cat (sig s1))
153 (case 1 (eq (sig c1) (const 1'd1)))
155 (switch (cat (sig s2))
156 (case 1 (eq (sig c2) (const 1'd1)))
161 def test_If_nested_If(self
):
164 m
.d
.comb
+= self
.c1
.eq(1)
166 m
.d
.comb
+= self
.c2
.eq(1)
168 self
.assertRepr(m
._statements
, """
170 (switch (cat (sig s1))
171 (case 1 (eq (sig c1) (const 1'd1))
172 (switch (cat (sig s2))
173 (case 1 (eq (sig c2) (const 1'd1)))
180 def test_If_dangling_Else(self
):
183 m
.d
.comb
+= self
.c1
.eq(1)
185 m
.d
.comb
+= self
.c2
.eq(1)
187 m
.d
.comb
+= self
.c3
.eq(1)
189 self
.assertRepr(m
._statements
, """
191 (switch (cat (sig s1))
193 (eq (sig c1) (const 1'd1))
194 (switch (cat (sig s2))
195 (case 1 (eq (sig c2) (const 1'd1)))
199 (eq (sig c3) (const 1'd1))
205 def test_Elif_wrong(self
):
207 with self
.assertRaises(SyntaxError,
208 msg
="Elif without preceding If"):
209 with m
.Elif(self
.s2
):
212 def test_Else_wrong(self
):
214 with self
.assertRaises(SyntaxError,
215 msg
="Else without preceding If/Elif"):
219 def test_If_wide(self
):
222 m
.d
.comb
+= self
.c1
.eq(1)
224 self
.assertRepr(m
._statements
, """
226 (switch (cat (b (sig w1)))
227 (case 1 (eq (sig c1) (const 1'd1)))
232 def test_Switch(self
):
234 with m
.Switch(self
.w1
):
236 m
.d
.comb
+= self
.c1
.eq(1)
238 m
.d
.comb
+= self
.c2
.eq(1)
240 self
.assertRepr(m
._statements
, """
243 (case 0011 (eq (sig c1) (const 1'd1)))
244 (case 11-- (eq (sig c2) (const 1'd1)))
249 def test_Switch_default(self
):
251 with m
.Switch(self
.w1
):
253 m
.d
.comb
+= self
.c1
.eq(1)
255 m
.d
.comb
+= self
.c2
.eq(1)
257 self
.assertRepr(m
._statements
, """
260 (case 0011 (eq (sig c1) (const 1'd1)))
261 (case ---- (eq (sig c2) (const 1'd1)))
266 def test_Switch_const_test(self
):
270 m
.d
.comb
+= self
.c1
.eq(1)
272 self
.assertRepr(m
._statements
, """
275 (case 1 (eq (sig c1) (const 1'd1)))
280 def test_Case_width_wrong(self
):
282 with m
.Switch(self
.w1
):
283 with self
.assertRaises(SyntaxError,
284 msg
="Case value '--' must have the same width as test (which is 4)"):
288 def test_Case_outside_Switch_wrong(self
):
290 with self
.assertRaises(SyntaxError,
291 msg
="Case is not permitted outside of Switch"):
295 def test_If_inside_Switch_wrong(self
):
297 with m
.Switch(self
.s1
):
298 with self
.assertRaises(SyntaxError,
299 msg
="If is not permitted inside of Switch"):
303 def test_auto_pop_ctrl(self
):
306 m
.d
.comb
+= self
.c1
.eq(1)
307 m
.d
.comb
+= self
.c2
.eq(1)
308 self
.assertRepr(m
._statements
, """
310 (switch (cat (b (sig w1)))
311 (case 1 (eq (sig c1) (const 1'd1)))
313 (eq (sig c2) (const 1'd1))
317 def test_submodule_anon(self
):
321 self
.assertEqual(m1
._submodules
, [(m2
, None)])
323 def test_submodule_anon_multi(self
):
327 m1
.submodules
+= m2
, m3
328 self
.assertEqual(m1
._submodules
, [(m2
, None), (m3
, None)])
330 def test_submodule_named(self
):
333 m1
.submodules
.foo
= m2
334 self
.assertEqual(m1
._submodules
, [(m2
, "foo")])
336 def test_submodule_wrong(self
):
338 with self
.assertRaises(TypeError,
339 msg
="Trying to add '1', which does not implement .get_fragment(), as a submodule"):
341 with self
.assertRaises(TypeError,
342 msg
="Trying to add '1', which does not implement .get_fragment(), as a submodule"):
345 def test_lower(self
):
347 m1
.d
.comb
+= self
.c1
.eq(self
.s1
)
349 m2
.d
.comb
+= self
.c2
.eq(self
.s2
)
350 m2
.d
.sync
+= self
.c3
.eq(self
.s3
)
351 m1
.submodules
.foo
= m2
353 f1
= m1
.lower(platform
=None)
354 self
.assertRepr(f1
.statements
, """
356 (eq (sig c1) (sig s1))
359 self
.assertEqual(f1
.drivers
, {
360 None: ValueSet((self
.c1
,))
362 self
.assertEqual(len(f1
.subfragments
), 1)
363 (f2
, f2_name
), = f1
.subfragments
364 self
.assertEqual(f2_name
, "foo")
365 self
.assertRepr(f2
.statements
, """
367 (eq (sig c2) (sig s2))
368 (eq (sig c3) (sig s3))
371 self
.assertEqual(f2
.drivers
, {
372 None: ValueSet((self
.c2
,)),
373 "sync": ValueSet((self
.c3
,))
375 self
.assertEqual(len(f2
.subfragments
), 0)