1 from ..hdl
.ast
import *
3 from ..hdl
.dsl
import *
7 class DSLTestCase(FHDLTestCase
):
17 def test_d_comb(self
):
19 m
.d
.comb
+= self
.c1
.eq(1)
21 self
.assertEqual(m
._driving
[self
.c1
], None)
22 self
.assertRepr(m
._statements
, """(
23 (eq (sig c1) (const 1'd1))
26 def test_d_sync(self
):
28 m
.d
.sync
+= self
.c1
.eq(1)
30 self
.assertEqual(m
._driving
[self
.c1
], "sync")
31 self
.assertRepr(m
._statements
, """(
32 (eq (sig c1) (const 1'd1))
37 m
.d
.pix
+= self
.c1
.eq(1)
39 self
.assertEqual(m
._driving
[self
.c1
], "pix")
40 self
.assertRepr(m
._statements
, """(
41 (eq (sig c1) (const 1'd1))
44 def test_d_index(self
):
46 m
.d
["pix"] += self
.c1
.eq(1)
48 self
.assertEqual(m
._driving
[self
.c1
], "pix")
49 self
.assertRepr(m
._statements
, """(
50 (eq (sig c1) (const 1'd1))
53 def test_d_no_conflict(self
):
55 m
.d
.comb
+= self
.w1
[0].eq(1)
56 m
.d
.comb
+= self
.w1
[1].eq(1)
58 def test_d_conflict(self
):
60 with self
.assertRaises(SyntaxError,
61 msg
="Driver-driver conflict: trying to drive (sig c1) from d.sync, but it "
62 "is already driven from d.comb"):
63 m
.d
.comb
+= self
.c1
.eq(1)
64 m
.d
.sync
+= self
.c1
.eq(1)
66 def test_d_wrong(self
):
68 with self
.assertRaises(AttributeError,
69 msg
="Cannot assign 'd.pix' attribute; did you mean 'd.pix +='?"):
72 def test_d_asgn_wrong(self
):
74 with self
.assertRaises(SyntaxError,
75 msg
="Only assignments may be appended to d.sync"):
76 m
.d
.sync
+= Switch(self
.s1
, {})
78 def test_comb_wrong(self
):
80 with self
.assertRaises(AttributeError,
81 msg
="'Module' object has no attribute 'comb'; did you mean 'd.comb'?"):
82 m
.comb
+= self
.c1
.eq(1)
84 def test_sync_wrong(self
):
86 with self
.assertRaises(AttributeError,
87 msg
="'Module' object has no attribute 'sync'; did you mean 'd.sync'?"):
88 m
.sync
+= self
.c1
.eq(1)
90 def test_attr_wrong(self
):
92 with self
.assertRaises(AttributeError,
93 msg
="'Module' object has no attribute 'nonexistentattr'"):
99 m
.d
.comb
+= self
.c1
.eq(1)
101 self
.assertRepr(m
._statements
, """
103 (switch (cat (sig s1))
104 (case 1 (eq (sig c1) (const 1'd1)))
109 def test_If_Elif(self
):
112 m
.d
.comb
+= self
.c1
.eq(1)
113 with m
.Elif(self
.s2
):
114 m
.d
.sync
+= self
.c2
.eq(0)
116 self
.assertRepr(m
._statements
, """
118 (switch (cat (sig s1) (sig s2))
119 (case -1 (eq (sig c1) (const 1'd1)))
120 (case 1- (eq (sig c2) (const 1'd0)))
125 def test_If_Elif_Else(self
):
128 m
.d
.comb
+= self
.c1
.eq(1)
129 with m
.Elif(self
.s2
):
130 m
.d
.sync
+= self
.c2
.eq(0)
132 m
.d
.comb
+= self
.c3
.eq(1)
134 self
.assertRepr(m
._statements
, """
136 (switch (cat (sig s1) (sig s2))
137 (case -1 (eq (sig c1) (const 1'd1)))
138 (case 1- (eq (sig c2) (const 1'd0)))
139 (case -- (eq (sig c3) (const 1'd1)))
144 def test_If_If(self
):
147 m
.d
.comb
+= self
.c1
.eq(1)
149 m
.d
.comb
+= self
.c2
.eq(1)
151 self
.assertRepr(m
._statements
, """
153 (switch (cat (sig s1))
154 (case 1 (eq (sig c1) (const 1'd1)))
156 (switch (cat (sig s2))
157 (case 1 (eq (sig c2) (const 1'd1)))
162 def test_If_nested_If(self
):
165 m
.d
.comb
+= self
.c1
.eq(1)
167 m
.d
.comb
+= self
.c2
.eq(1)
169 self
.assertRepr(m
._statements
, """
171 (switch (cat (sig s1))
172 (case 1 (eq (sig c1) (const 1'd1))
173 (switch (cat (sig s2))
174 (case 1 (eq (sig c2) (const 1'd1)))
181 def test_If_dangling_Else(self
):
184 m
.d
.comb
+= self
.c1
.eq(1)
186 m
.d
.comb
+= self
.c2
.eq(1)
188 m
.d
.comb
+= self
.c3
.eq(1)
190 self
.assertRepr(m
._statements
, """
192 (switch (cat (sig s1))
194 (eq (sig c1) (const 1'd1))
195 (switch (cat (sig s2))
196 (case 1 (eq (sig c2) (const 1'd1)))
200 (eq (sig c3) (const 1'd1))
206 def test_Elif_wrong(self
):
208 with self
.assertRaises(SyntaxError,
209 msg
="Elif without preceding If"):
210 with m
.Elif(self
.s2
):
213 def test_Else_wrong(self
):
215 with self
.assertRaises(SyntaxError,
216 msg
="Else without preceding If/Elif"):
220 def test_If_wide(self
):
223 m
.d
.comb
+= self
.c1
.eq(1)
225 self
.assertRepr(m
._statements
, """
227 (switch (cat (b (sig w1)))
228 (case 1 (eq (sig c1) (const 1'd1)))
233 def test_Switch(self
):
235 with m
.Switch(self
.w1
):
237 m
.d
.comb
+= self
.c1
.eq(1)
239 m
.d
.comb
+= self
.c2
.eq(1)
241 self
.assertRepr(m
._statements
, """
244 (case 0011 (eq (sig c1) (const 1'd1)))
245 (case 11-- (eq (sig c2) (const 1'd1)))
250 def test_Switch_default(self
):
252 with m
.Switch(self
.w1
):
254 m
.d
.comb
+= self
.c1
.eq(1)
256 m
.d
.comb
+= self
.c2
.eq(1)
258 self
.assertRepr(m
._statements
, """
261 (case 0011 (eq (sig c1) (const 1'd1)))
262 (case ---- (eq (sig c2) (const 1'd1)))
267 def test_Switch_const_test(self
):
271 m
.d
.comb
+= self
.c1
.eq(1)
273 self
.assertRepr(m
._statements
, """
276 (case 1 (eq (sig c1) (const 1'd1)))
281 def test_Case_width_wrong(self
):
283 with m
.Switch(self
.w1
):
284 with self
.assertRaises(SyntaxError,
285 msg
="Case value '--' must have the same width as test (which is 4)"):
289 def test_Case_outside_Switch_wrong(self
):
291 with self
.assertRaises(SyntaxError,
292 msg
="Case is not permitted outside of Switch"):
296 def test_If_inside_Switch_wrong(self
):
298 with m
.Switch(self
.s1
):
299 with self
.assertRaises(SyntaxError,
300 msg
="If is not permitted inside of Switch"):
304 def test_auto_pop_ctrl(self
):
307 m
.d
.comb
+= self
.c1
.eq(1)
308 m
.d
.comb
+= self
.c2
.eq(1)
309 self
.assertRepr(m
._statements
, """
311 (switch (cat (b (sig w1)))
312 (case 1 (eq (sig c1) (const 1'd1)))
314 (eq (sig c2) (const 1'd1))
318 def test_submodule_anon(self
):
322 self
.assertEqual(m1
._submodules
, [(m2
, None)])
324 def test_submodule_anon_multi(self
):
328 m1
.submodules
+= m2
, m3
329 self
.assertEqual(m1
._submodules
, [(m2
, None), (m3
, None)])
331 def test_submodule_named(self
):
334 m1
.submodules
.foo
= m2
335 self
.assertEqual(m1
._submodules
, [(m2
, "foo")])
337 def test_submodule_wrong(self
):
339 with self
.assertRaises(TypeError,
340 msg
="Trying to add '1', which does not implement .get_fragment(), as a submodule"):
342 with self
.assertRaises(TypeError,
343 msg
="Trying to add '1', which does not implement .get_fragment(), as a submodule"):
346 def test_domain_named_implicit(self
):
348 m
.domains
+= ClockDomain("sync")
349 self
.assertEqual(len(m
._domains
), 1)
351 def test_domain_named_explicit(self
):
353 m
.domains
.foo
= ClockDomain()
354 self
.assertEqual(len(m
._domains
), 1)
355 self
.assertEqual(m
._domains
[0].name
, "foo")
357 def test_lower(self
):
359 m1
.d
.comb
+= self
.c1
.eq(self
.s1
)
361 m2
.d
.comb
+= self
.c2
.eq(self
.s2
)
362 m2
.d
.sync
+= self
.c3
.eq(self
.s3
)
363 m1
.submodules
.foo
= m2
365 f1
= m1
.lower(platform
=None)
366 self
.assertRepr(f1
.statements
, """
368 (eq (sig c1) (sig s1))
371 self
.assertEqual(f1
.drivers
, {
372 None: SignalSet((self
.c1
,))
374 self
.assertEqual(len(f1
.subfragments
), 1)
375 (f2
, f2_name
), = f1
.subfragments
376 self
.assertEqual(f2_name
, "foo")
377 self
.assertRepr(f2
.statements
, """
379 (eq (sig c2) (sig s2))
380 (eq (sig c3) (sig s3))
383 self
.assertEqual(f2
.drivers
, {
384 None: SignalSet((self
.c2
,)),
385 "sync": SignalSet((self
.c3
,))
387 self
.assertEqual(len(f2
.subfragments
), 0)