1 # nmigen: UnusedElaboratable=no
3 from nmigen
.hdl
.ast
import *
4 from nmigen
.hdl
.mem
import *
9 class MemoryTestCase(FHDLTestCase
):
11 m1
= Memory(width
=8, depth
=4)
12 self
.assertEqual(m1
.name
, "m1")
13 m2
= [Memory(width
=8, depth
=4)][0]
14 self
.assertEqual(m2
.name
, "$memory")
15 m3
= Memory(width
=8, depth
=4, name
="foo")
16 self
.assertEqual(m3
.name
, "foo")
18 def test_geometry(self
):
19 m
= Memory(width
=8, depth
=4)
20 self
.assertEqual(m
.width
, 8)
21 self
.assertEqual(m
.depth
, 4)
23 def test_geometry_wrong(self
):
24 with self
.assertRaisesRegex(TypeError,
25 r
"^Memory width must be a non-negative integer, not -1$"):
26 m
= Memory(width
=-1, depth
=4)
27 with self
.assertRaisesRegex(TypeError,
28 r
"^Memory depth must be a non-negative integer, not -1$"):
29 m
= Memory(width
=8, depth
=-1)
32 m
= Memory(width
=8, depth
=4, init
=range(4))
33 self
.assertEqual(m
.init
, [0, 1, 2, 3])
35 def test_init_wrong_count(self
):
36 with self
.assertRaisesRegex(ValueError,
37 r
"^Memory initialization value count exceed memory depth \(8 > 4\)$"):
38 m
= Memory(width
=8, depth
=4, init
=range(8))
40 def test_init_wrong_type(self
):
41 with self
.assertRaisesRegex(TypeError,
42 (r
"^Memory initialization value at address 1: "
43 r
"'str' object cannot be interpreted as an integer$")):
44 m
= Memory(width
=8, depth
=4, init
=[1, "0"])
47 m1
= Memory(width
=8, depth
=4)
48 self
.assertEqual(m1
.attrs
, {})
49 m2
= Memory(width
=8, depth
=4, attrs
={"ram_block": True})
50 self
.assertEqual(m2
.attrs
, {"ram_block": True})
52 def test_read_port_transparent(self
):
53 mem
= Memory(width
=8, depth
=4)
54 rdport
= mem
.read_port()
55 self
.assertEqual(rdport
.memory
, mem
)
56 self
.assertEqual(rdport
.domain
, "sync")
57 self
.assertEqual(rdport
.transparent
, True)
58 self
.assertEqual(len(rdport
.addr
), 2)
59 self
.assertEqual(len(rdport
.data
), 8)
60 self
.assertEqual(len(rdport
.en
), 1)
61 self
.assertIsInstance(rdport
.en
, Const
)
62 self
.assertEqual(rdport
.en
.value
, 1)
64 def test_read_port_non_transparent(self
):
65 mem
= Memory(width
=8, depth
=4)
66 rdport
= mem
.read_port(transparent
=False)
67 self
.assertEqual(rdport
.memory
, mem
)
68 self
.assertEqual(rdport
.domain
, "sync")
69 self
.assertEqual(rdport
.transparent
, False)
70 self
.assertEqual(len(rdport
.en
), 1)
71 self
.assertIsInstance(rdport
.en
, Signal
)
72 self
.assertEqual(rdport
.en
.reset
, 1)
74 def test_read_port_asynchronous(self
):
75 mem
= Memory(width
=8, depth
=4)
76 rdport
= mem
.read_port(domain
="comb")
77 self
.assertEqual(rdport
.memory
, mem
)
78 self
.assertEqual(rdport
.domain
, "comb")
79 self
.assertEqual(rdport
.transparent
, True)
80 self
.assertEqual(len(rdport
.en
), 1)
81 self
.assertIsInstance(rdport
.en
, Const
)
82 self
.assertEqual(rdport
.en
.value
, 1)
84 def test_read_port_wrong(self
):
85 mem
= Memory(width
=8, depth
=4)
86 with self
.assertRaisesRegex(ValueError,
87 r
"^Read port cannot be simultaneously asynchronous and non-transparent$"):
88 mem
.read_port(domain
="comb", transparent
=False)
90 def test_write_port(self
):
91 mem
= Memory(width
=8, depth
=4)
92 wrport
= mem
.write_port()
93 self
.assertEqual(wrport
.memory
, mem
)
94 self
.assertEqual(wrport
.domain
, "sync")
95 self
.assertEqual(wrport
.granularity
, 8)
96 self
.assertEqual(len(wrport
.addr
), 2)
97 self
.assertEqual(len(wrport
.data
), 8)
98 self
.assertEqual(len(wrport
.en
), 1)
100 def test_write_port_granularity(self
):
101 mem
= Memory(width
=8, depth
=4)
102 wrport
= mem
.write_port(granularity
=2)
103 self
.assertEqual(wrport
.memory
, mem
)
104 self
.assertEqual(wrport
.domain
, "sync")
105 self
.assertEqual(wrport
.granularity
, 2)
106 self
.assertEqual(len(wrport
.addr
), 2)
107 self
.assertEqual(len(wrport
.data
), 8)
108 self
.assertEqual(len(wrport
.en
), 4)
110 def test_write_port_granularity_wrong(self
):
111 mem
= Memory(width
=8, depth
=4)
112 with self
.assertRaisesRegex(TypeError,
113 r
"^Write port granularity must be a non-negative integer, not -1$"):
114 mem
.write_port(granularity
=-1)
115 with self
.assertRaisesRegex(ValueError,
116 r
"^Write port granularity must not be greater than memory width \(10 > 8\)$"):
117 mem
.write_port(granularity
=10)
118 with self
.assertRaisesRegex(ValueError,
119 r
"^Write port granularity must divide memory width evenly$"):
120 mem
.write_port(granularity
=3)
123 class DummyPortTestCase(FHDLTestCase
):
125 p1
= DummyPort(data_width
=8, addr_width
=2)
126 self
.assertEqual(p1
.addr
.name
, "p1_addr")
127 p2
= [DummyPort(data_width
=8, addr_width
=2)][0]
128 self
.assertEqual(p2
.addr
.name
, "dummy_addr")
129 p3
= DummyPort(data_width
=8, addr_width
=2, name
="foo")
130 self
.assertEqual(p3
.addr
.name
, "foo_addr")
132 def test_sizes(self
):
133 p1
= DummyPort(data_width
=8, addr_width
=2)
134 self
.assertEqual(p1
.addr
.width
, 2)
135 self
.assertEqual(p1
.data
.width
, 8)
136 self
.assertEqual(p1
.en
.width
, 1)
137 p2
= DummyPort(data_width
=8, addr_width
=2, granularity
=2)
138 self
.assertEqual(p2
.en
.width
, 4)