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