vendor.quicklogic: enable SoC clock configuration
[nmigen.git] / tests / test_hdl_mem.py
1 # nmigen: UnusedElaboratable=no
2
3 from nmigen.hdl.ast import *
4 from nmigen.hdl.mem import *
5
6 from .utils import *
7
8
9 class MemoryTestCase(FHDLTestCase):
10 def test_name(self):
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")
17
18 def test_geometry(self):
19 m = Memory(width=8, depth=4)
20 self.assertEqual(m.width, 8)
21 self.assertEqual(m.depth, 4)
22
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)
30
31 def test_init(self):
32 m = Memory(width=8, depth=4, init=range(4))
33 self.assertEqual(m.init, [0, 1, 2, 3])
34
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))
39
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"])
45
46 def test_attrs(self):
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})
51
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)
63
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)
73
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)
83
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)
89
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)
99
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)
109
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)
121
122
123 class DummyPortTestCase(FHDLTestCase):
124 def test_name(self):
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")
131
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)