csr.bus: split CSRMultiplexer to CSRInterface+CSRDecoder.
[nmigen-soc.git] / nmigen_soc / test / test_csr_bus.py
index ac427b9806f5c78c9a654cc4d0228ace0d158a2c..f54e9350b6741d5d6626389be2225925cbbbdf4d 100644 (file)
@@ -7,7 +7,7 @@ from ..csr.bus import *
 
 
 class CSRElementTestCase(unittest.TestCase):
-    def test_1_ro(self):
+    def test_layout_1_ro(self):
         elem = CSRElement(1, "r")
         self.assertEqual(elem.width, 1)
         self.assertEqual(elem.access, "r")
@@ -16,7 +16,7 @@ class CSRElementTestCase(unittest.TestCase):
             ("r_stb", 1),
         ]))
 
-    def test_8_rw(self):
+    def test_layout_8_rw(self):
         elem = CSRElement(8, access="rw")
         self.assertEqual(elem.width, 8)
         self.assertEqual(elem.access, "rw")
@@ -27,7 +27,7 @@ class CSRElementTestCase(unittest.TestCase):
             ("w_stb", 1),
         ]))
 
-    def test_10_wo(self):
+    def test_layout_10_wo(self):
         elem = CSRElement(10, "w")
         self.assertEqual(elem.width, 10)
         self.assertEqual(elem.access, "w")
@@ -36,7 +36,7 @@ class CSRElementTestCase(unittest.TestCase):
             ("w_stb", 1),
         ]))
 
-    def test_0_rw(self): # degenerate but legal case
+    def test_layout_0_rw(self): # degenerate but legal case
         elem = CSRElement(0, access="rw")
         self.assertEqual(elem.width, 0)
         self.assertEqual(elem.access, "rw")
@@ -58,28 +58,40 @@ class CSRElementTestCase(unittest.TestCase):
             CSRElement(1, "wo")
 
 
-class CSRMultiplexerTestCase(unittest.TestCase):
-    def setUp(self):
-        self.dut = CSRMultiplexer(addr_width=16, data_width=8)
+class CSRInterfaceTestCase(unittest.TestCase):
+    def test_layout(self):
+        iface = CSRInterface(addr_width=12, data_width=8)
+        self.assertEqual(iface.addr_width, 12)
+        self.assertEqual(iface.data_width, 8)
+        self.assertEqual(iface.layout, Layout.cast([
+            ("addr",    12),
+            ("r_data",  8),
+            ("r_stb",   1),
+            ("w_data",  8),
+            ("w_stb",   1),
+        ]))
 
     def test_addr_width_wrong(self):
         with self.assertRaisesRegex(ValueError,
                 r"Address width must be a positive integer, not -1"):
-            CSRMultiplexer(addr_width=-1, data_width=8)
+            CSRInterface(addr_width=-1, data_width=8)
 
     def test_data_width_wrong(self):
         with self.assertRaisesRegex(ValueError,
                 r"Data width must be a positive integer, not -1"):
-            CSRMultiplexer(addr_width=16, data_width=-1)
+            CSRInterface(addr_width=16, data_width=-1)
+
+
+class CSRDecoderTestCase(unittest.TestCase):
+    def setUp(self):
+        self.dut = CSRDecoder(addr_width=16, data_width=8)
 
     def test_alignment_wrong(self):
         with self.assertRaisesRegex(ValueError,
                 r"Alignment must be a non-negative integer, not -1"):
-            CSRMultiplexer(addr_width=16, data_width=8, alignment=-1)
+            CSRDecoder(addr_width=16, data_width=8, alignment=-1)
 
     def test_attrs(self):
-        self.assertEqual(self.dut.addr_width, 16)
-        self.assertEqual(self.dut.data_width, 8)
         self.assertEqual(self.dut.alignment, 0)
 
     def test_add_4b(self):
@@ -117,6 +129,8 @@ class CSRMultiplexerTestCase(unittest.TestCase):
                          (4, 1))
 
     def test_sim(self):
+        bus = self.dut.bus
+
         elem_4_r = CSRElement(4, "r")
         self.dut.add(elem_4_r)
         elem_8_w = CSRElement(8, "w")
@@ -128,55 +142,55 @@ class CSRMultiplexerTestCase(unittest.TestCase):
             yield elem_4_r.r_data.eq(0xa)
             yield elem_16_rw.r_data.eq(0x5aa5)
 
-            yield self.dut.addr.eq(0)
-            yield self.dut.r_stb.eq(1)
+            yield bus.addr.eq(0)
+            yield bus.r_stb.eq(1)
             yield
-            yield self.dut.r_stb.eq(0)
+            yield bus.r_stb.eq(0)
             self.assertEqual((yield elem_4_r.r_stb), 1)
             self.assertEqual((yield elem_16_rw.r_stb), 0)
             yield
-            self.assertEqual((yield self.dut.r_data), 0xa)
+            self.assertEqual((yield bus.r_data), 0xa)
 
-            yield self.dut.addr.eq(2)
-            yield self.dut.r_stb.eq(1)
+            yield bus.addr.eq(2)
+            yield bus.r_stb.eq(1)
             yield
-            yield self.dut.r_stb.eq(0)
+            yield bus.r_stb.eq(0)
             self.assertEqual((yield elem_4_r.r_stb), 0)
             self.assertEqual((yield elem_16_rw.r_stb), 1)
             yield
-            yield self.dut.addr.eq(3) # pipeline a read
-            self.assertEqual((yield self.dut.r_data), 0xa5)
+            yield bus.addr.eq(3) # pipeline a read
+            self.assertEqual((yield bus.r_data), 0xa5)
 
-            yield self.dut.r_stb.eq(1)
+            yield bus.r_stb.eq(1)
             yield
-            yield self.dut.r_stb.eq(0)
+            yield bus.r_stb.eq(0)
             self.assertEqual((yield elem_4_r.r_stb), 0)
             self.assertEqual((yield elem_16_rw.r_stb), 0)
             yield
-            self.assertEqual((yield self.dut.r_data), 0x5a)
+            self.assertEqual((yield bus.r_data), 0x5a)
 
-            yield self.dut.addr.eq(1)
-            yield self.dut.w_data.eq(0x3d)
-            yield self.dut.w_stb.eq(1)
+            yield bus.addr.eq(1)
+            yield bus.w_data.eq(0x3d)
+            yield bus.w_stb.eq(1)
             yield
-            yield self.dut.w_stb.eq(0)
+            yield bus.w_stb.eq(0)
             yield
             self.assertEqual((yield elem_8_w.w_stb), 1)
             self.assertEqual((yield elem_8_w.w_data), 0x3d)
             self.assertEqual((yield elem_16_rw.w_stb), 0)
 
-            yield self.dut.addr.eq(2)
-            yield self.dut.w_data.eq(0x55)
-            yield self.dut.w_stb.eq(1)
+            yield bus.addr.eq(2)
+            yield bus.w_data.eq(0x55)
+            yield bus.w_stb.eq(1)
             yield
             self.assertEqual((yield elem_8_w.w_stb), 0)
             self.assertEqual((yield elem_16_rw.w_stb), 0)
-            yield self.dut.addr.eq(3) # pipeline a write
-            yield self.dut.w_data.eq(0xaa)
+            yield bus.addr.eq(3) # pipeline a write
+            yield bus.w_data.eq(0xaa)
             yield
             self.assertEqual((yield elem_8_w.w_stb), 0)
             self.assertEqual((yield elem_16_rw.w_stb), 0)
-            yield self.dut.w_stb.eq(0)
+            yield bus.w_stb.eq(0)
             yield
             self.assertEqual((yield elem_8_w.w_stb), 0)
             self.assertEqual((yield elem_16_rw.w_stb), 1)
@@ -188,9 +202,9 @@ class CSRMultiplexerTestCase(unittest.TestCase):
             sim.run()
 
 
-class CSRAlignedMultiplexerTestCase(unittest.TestCase):
+class CSRDecoderAlignedTestCase(unittest.TestCase):
     def setUp(self):
-        self.dut = CSRMultiplexer(addr_width=16, data_width=8, alignment=2)
+        self.dut = CSRDecoder(addr_width=16, data_width=8, alignment=2)
 
     def test_attrs(self):
         self.assertEqual(self.dut.alignment, 2)
@@ -216,28 +230,30 @@ class CSRAlignedMultiplexerTestCase(unittest.TestCase):
                          (4, 4))
 
     def test_sim(self):
+        bus = self.dut.bus
+
         elem_20_rw = CSRElement(20, "rw")
         self.dut.add(elem_20_rw)
 
         def sim_test():
-            yield self.dut.w_stb.eq(1)
-            yield self.dut.addr.eq(0)
-            yield self.dut.w_data.eq(0x55)
+            yield bus.w_stb.eq(1)
+            yield bus.addr.eq(0)
+            yield bus.w_data.eq(0x55)
             yield
             self.assertEqual((yield elem_20_rw.w_stb), 0)
-            yield self.dut.addr.eq(1)
-            yield self.dut.w_data.eq(0xaa)
+            yield bus.addr.eq(1)
+            yield bus.w_data.eq(0xaa)
             yield
             self.assertEqual((yield elem_20_rw.w_stb), 0)
-            yield self.dut.addr.eq(2)
-            yield self.dut.w_data.eq(0x33)
+            yield bus.addr.eq(2)
+            yield bus.w_data.eq(0x33)
             yield
             self.assertEqual((yield elem_20_rw.w_stb), 0)
-            yield self.dut.addr.eq(3)
-            yield self.dut.w_data.eq(0xdd)
+            yield bus.addr.eq(3)
+            yield bus.w_data.eq(0xdd)
             yield
             self.assertEqual((yield elem_20_rw.w_stb), 0)
-            yield self.dut.w_stb.eq(0)
+            yield bus.w_stb.eq(0)
             yield
             self.assertEqual((yield elem_20_rw.w_stb), 1)
             self.assertEqual((yield elem_20_rw.w_data), 0x3aa55)