From: whitequark Date: Fri, 25 Oct 2019 21:30:46 +0000 (+0000) Subject: csr.bus.{Multiplexer↔Decoder} X-Git-Tag: 24jan2021_ls180~34 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7d76126fecd25d4242e64f14728041f760c4fac3;p=nmigen-soc.git csr.bus.{Multiplexer↔Decoder} This reverses the rename done in commit 5520e0d7. Commit 2a634b3a introduced a Multiplexer that doesn't actually do multiplexing, so revert that to make everything less confusing. --- diff --git a/nmigen_soc/csr/bus.py b/nmigen_soc/csr/bus.py index 1f66e09..a8376a7 100644 --- a/nmigen_soc/csr/bus.py +++ b/nmigen_soc/csr/bus.py @@ -153,8 +153,8 @@ class Interface(Record): ], name=name, src_loc_at=1) -class Decoder(Elaboratable): - """CSR bus decoder. +class Multiplexer(Elaboratable): + """CSR register multiplexer. An address-based multiplexer for CSR registers implementing atomic updates. @@ -275,22 +275,22 @@ class Decoder(Elaboratable): return m -class Multiplexer(Elaboratable): - """CSR bus multiplexer. +class Decoder(Elaboratable): + """CSR bus decoder. - An address-based multiplexer for subordinate CSR buses. + An address decoder for subordinate CSR buses. Usage ----- Although there is no functional difference between adding a set of registers directly to - a :class:`Decoder` and adding a set of reigsters to multiple :class:`Decoder`s that are - aggregated with a :class:`Multiplexer`, hierarchical CSR buses are useful for organizing - a hierarchical design. If many peripherals are directly served by a single :class:`Decoder`, - a very large amount of ports will connect the peripheral registers with the decoder, and - the cost of decoding logic would not be attributed to specific peripherals. With a multiplexer, - only five signals per peripheral will be used, and the logic could be kept together with - the peripheral. + a :class:`Multiplexer` and adding a set of registers to multiple :class:`Multiplexer`s that are + aggregated with a :class:`Decoder`, hierarchical CSR buses are useful for organizing + a hierarchical design. If many peripherals are directly served by a single + :class:`Multiplexer`, a very large amount of ports will connect the peripheral registers with + the decoder, and the cost of decoding logic would not be attributed to specific peripherals. + With a decoder, only five signals per peripheral will be used, and the logic could be kept + together with the peripheral. Parameters ---------- @@ -342,7 +342,7 @@ class Multiplexer(Elaboratable): def elaborate(self, platform): m = Module() - # See Decoder.elaborate above. + # See Multiplexer.elaborate above. r_data_fanin = 0 with m.Switch(self.bus.addr): diff --git a/nmigen_soc/test/test_csr_bus.py b/nmigen_soc/test/test_csr_bus.py index 0f9931b..188bdab 100644 --- a/nmigen_soc/test/test_csr_bus.py +++ b/nmigen_soc/test/test_csr_bus.py @@ -82,9 +82,9 @@ class InterfaceTestCase(unittest.TestCase): Interface(addr_width=16, data_width=-1) -class DecoderTestCase(unittest.TestCase): +class MultiplexerTestCase(unittest.TestCase): def setUp(self): - self.dut = Decoder(addr_width=16, data_width=8) + self.dut = Multiplexer(addr_width=16, data_width=8) Fragment.get(self.dut, platform=None) # silence UnusedElaboratable def test_add_4b(self): @@ -195,9 +195,9 @@ class DecoderTestCase(unittest.TestCase): sim.run() -class DecoderAlignedTestCase(unittest.TestCase): +class MultiplexerAlignedTestCase(unittest.TestCase): def setUp(self): - self.dut = Decoder(addr_width=16, data_width=8, alignment=2) + self.dut = Multiplexer(addr_width=16, data_width=8, alignment=2) Fragment.get(self.dut, platform=None) # silence UnusedElaboratable def test_add_two(self): @@ -255,9 +255,9 @@ class DecoderAlignedTestCase(unittest.TestCase): sim.run() -class MultiplexerTestCase(unittest.TestCase): +class DecoderTestCase(unittest.TestCase): def setUp(self): - self.dut = Multiplexer(addr_width=16, data_width=8) + self.dut = Decoder(addr_width=16, data_width=8) Fragment.get(self.dut, platform=None) # silence UnusedElaboratable def test_add_wrong_sub_bus(self): @@ -266,24 +266,24 @@ class MultiplexerTestCase(unittest.TestCase): self.dut.add(1) def test_add_wrong_data_width(self): - decoder = Decoder(addr_width=10, data_width=16) - Fragment.get(decoder, platform=None) # silence UnusedElaboratable + mux = Multiplexer(addr_width=10, data_width=16) + Fragment.get(mux, platform=None) # silence UnusedElaboratable with self.assertRaisesRegex(ValueError, r"Subordinate bus has data width 16, which is not the same as " r"multiplexer data width 8"): - self.dut.add(decoder.bus) + self.dut.add(mux.bus) def test_sim(self): - dec_1 = Decoder(addr_width=10, data_width=8) - self.dut.add(dec_1.bus) + mux_1 = Multiplexer(addr_width=10, data_width=8) + self.dut.add(mux_1.bus) elem_1 = Element(8, "rw") - dec_1.add(elem_1) + mux_1.add(elem_1) - dec_2 = Decoder(addr_width=10, data_width=8) - self.dut.add(dec_2.bus) + mux_2 = Multiplexer(addr_width=10, data_width=8) + self.dut.add(mux_2.bus) elem_2 = Element(8, "rw") - dec_2.add(elem_2, addr=2) + mux_2.add(elem_2, addr=2) elem_1_addr, _, _ = self.dut.bus.memory_map.find_resource(elem_1) elem_2_addr, _, _ = self.dut.bus.memory_map.find_resource(elem_2) @@ -322,7 +322,7 @@ class MultiplexerTestCase(unittest.TestCase): self.assertEqual((yield bus.r_data), 0xaa) m = Module() - m.submodules += self.dut, dec_1, dec_2 + m.submodules += self.dut, mux_1, mux_2 with Simulator(m, vcd_file=open("test.vcd", "w")) as sim: sim.add_clock(1e-6) sim.add_sync_process(sim_test())